@vellumai/assistant 0.8.12 → 0.9.0-staging.2
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 +0 -14
- package/ARCHITECTURE.md +45 -45
- package/README.md +1 -1
- package/bun.lock +200 -154
- package/docs/architecture/integrations.md +3 -3
- package/docs/architecture/memory.md +2 -2
- package/docs/architecture/security.md +10 -10
- package/docs/runbook-trusted-contacts.md +12 -12
- package/docs/skills.md +6 -6
- package/docs/workflows-testing.md +221 -0
- package/docs/workflows.md +510 -0
- package/examples/plugins/echo/README.md +5 -5
- package/knip.json +2 -0
- package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +105 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +12 -0
- package/openapi.yaml +7197 -5708
- package/package.json +8 -4
- package/scripts/generate-openapi.ts +66 -114
- package/src/__tests__/access-request-seed-content-blocks.test.ts +213 -0
- package/src/__tests__/adaptive-thinking-repair.test.ts +32 -3
- package/src/__tests__/agent-loop-output-hooks.test.ts +183 -0
- package/src/__tests__/agent-loop-regrowth-guard.test.ts +506 -0
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +2 -0
- package/src/__tests__/agent-wake-override-profile.test.ts +77 -0
- package/src/__tests__/app-compiler.test.ts +7 -1
- package/src/__tests__/app-dir-path-guard.test.ts +27 -3
- package/src/__tests__/app-executors.test.ts +43 -0
- package/src/__tests__/approval-cascade.test.ts +0 -5
- package/src/__tests__/approval-routes-http.test.ts +91 -0
- package/src/__tests__/assistant-stream-state.test.ts +107 -0
- package/src/__tests__/browser-fill-credential.test.ts +3 -3
- package/src/__tests__/bundled-skill-retrieval-guard.test.ts +1 -1
- package/src/__tests__/compaction-events.test.ts +63 -7
- package/src/__tests__/compaction-trail-store.test.ts +74 -1
- package/src/__tests__/compaction.benchmark.test.ts +63 -41
- package/src/__tests__/compactor-low-watermark-cut.test.ts +349 -0
- package/src/__tests__/context-window-manager-compact-retry.test.ts +64 -0
- package/src/__tests__/conversation-abort-tool-results.test.ts +0 -5
- package/src/__tests__/conversation-confirmation-signals.test.ts +0 -5
- package/src/__tests__/conversation-history-web-search.test.ts +7 -0
- package/src/__tests__/conversation-process-callsite.test.ts +0 -5
- package/src/__tests__/conversation-provider-retry-repair.test.ts +0 -5
- package/src/__tests__/conversation-queue.test.ts +0 -5
- package/src/__tests__/conversation-slash-queue.test.ts +0 -5
- package/src/__tests__/conversation-slash-unknown.test.ts +0 -5
- package/src/__tests__/conversation-speed-override.test.ts +0 -5
- package/src/__tests__/conversation-surfaces-data-persist.test.ts +97 -0
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +67 -0
- package/src/__tests__/conversation-usage.test.ts +2 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +0 -5
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +0 -5
- package/src/__tests__/credential-broker-browser-fill.test.ts +2 -2
- package/src/__tests__/credential-broker-server-use.test.ts +2 -2
- package/src/__tests__/credential-broker.test.ts +1 -1
- package/src/__tests__/credential-prompt-route.test.ts +417 -0
- package/src/__tests__/credential-security-invariants.test.ts +1 -0
- package/src/__tests__/credential-vault.test.ts +37 -0
- package/src/__tests__/db-schedule-syntax-migration.test.ts +24 -0
- package/src/__tests__/dynamic-page-surface.test.ts +219 -0
- package/src/__tests__/empty-state-greeting-cache.test.ts +94 -0
- package/src/__tests__/gateway-flag-listener.test.ts +24 -7
- package/src/__tests__/guardian-action-sweep.test.ts +56 -219
- package/src/__tests__/guardian-routing-invariants.test.ts +138 -0
- package/src/__tests__/helpers/channel-test-adapter.ts +0 -2
- package/src/__tests__/list-messages-hidden-metadata.test.ts +99 -0
- package/src/__tests__/llm-request-log-source-clickhouse.test.ts +87 -1
- package/src/__tests__/llm-resolver.test.ts +115 -0
- package/src/__tests__/managed-profile-guard.test.ts +6 -5
- package/src/__tests__/max-tokens-continue-hook.test.ts +184 -0
- package/src/__tests__/media-generate-image.test.ts +20 -9
- package/src/__tests__/mock-gateway-ipc.ts +23 -0
- package/src/__tests__/model-intents.test.ts +1 -1
- package/src/__tests__/normalize-onboarding.test.ts +26 -0
- package/src/__tests__/notification-decision-strategy.test.ts +4 -2
- package/src/__tests__/notification-telegram-adapter.test.ts +21 -3
- package/src/__tests__/pending-interactions-resolved-event.test.ts +62 -0
- package/src/__tests__/post-turn-tool-result-truncation.test.ts +72 -18
- package/src/__tests__/require-fresh-approval.test.ts +425 -1
- package/src/__tests__/resolve-app-id.test.ts +56 -0
- package/src/__tests__/runtime-events-sse-parity.test.ts +2 -0
- package/src/__tests__/schedule-routes-workflow-validation.test.ts +408 -0
- package/src/__tests__/schedule-routes.test.ts +257 -4
- package/src/__tests__/schedule-store.test.ts +60 -0
- package/src/__tests__/schedule-tools.test.ts +247 -2
- package/src/__tests__/skill-execute-input.test.ts +85 -0
- package/src/__tests__/skill-secret-handling-guard.test.ts +21 -20
- package/src/__tests__/skills.test.ts +3 -3
- package/src/__tests__/slack-app-setup-skill-regression.test.ts +1 -1
- package/src/__tests__/subagent-tool-filtering.test.ts +50 -0
- package/src/__tests__/subagent-tool-gate-mode.test.ts +547 -0
- package/src/__tests__/system-prompt.test.ts +1 -1
- package/src/__tests__/task-progress-nudge-hook.test.ts +372 -0
- package/src/__tests__/task-scheduler.test.ts +299 -0
- package/src/__tests__/tool-approval-seed-content-blocks.test.ts +209 -0
- package/src/__tests__/tool-result-spool.test.ts +3 -1
- package/src/__tests__/workspace-migration-102-preserve-heartbeat-enabled-for-existing-workspaces.test.ts +181 -0
- package/src/__tests__/workspace-migration-103-upgrade-quality-profile-to-opus-4-8.test.ts +174 -0
- package/src/agent/compaction-circuit.ts +11 -0
- package/src/agent/loop.ts +181 -12
- package/src/api/constants/call-sites.ts +12 -0
- package/src/api/events/assistant-thinking-delta.ts +10 -0
- package/src/api/events/usage-update.ts +7 -0
- package/src/api/index.ts +4 -1
- package/src/api/responses/memory-v3-selection-log.ts +18 -11
- package/src/approvals/approval-primitive.ts +2 -2
- package/src/background-wake/background-wake-routes.test.ts +5 -2
- package/src/bundler/compiler-tools.ts +1 -1
- package/src/bundler/package-resolver.ts +0 -1
- package/src/calls/call-domain.ts +1 -1
- package/src/calls/guardian-action-sweep.ts +16 -93
- package/src/cli/AGENTS.md +4 -0
- package/src/cli/commands/__tests__/schedules.test.ts +430 -1
- package/src/cli/commands/credentials.ts +28 -24
- package/src/cli/commands/image-generation.ts +23 -9
- package/src/cli/commands/notifications.ts +1 -1
- package/src/cli/commands/plugins.ts +89 -46
- package/src/cli/commands/schedules.ts +384 -11
- package/src/cli/lib/__tests__/inspect-plugin.test.ts +69 -5
- package/src/cli/lib/__tests__/install-from-github.test.ts +15 -0
- package/src/cli/lib/__tests__/upgrade-plugin.test.ts +81 -4
- package/src/cli/lib/inspect-plugin.ts +62 -1
- package/src/cli/lib/install-from-github.ts +52 -5
- package/src/cli/lib/upgrade-plugin.ts +18 -0
- package/src/config/__tests__/workflows-schema.test.ts +60 -0
- package/src/config/bundled-skills/acp/SKILL.md +2 -2
- package/src/config/bundled-skills/app-builder/SKILL.md +1 -1
- package/src/config/bundled-skills/app-builder/tools/app-create.ts +6 -1
- package/src/config/bundled-skills/app-builder/tools/app-generate-icon.ts +7 -1
- package/src/config/bundled-skills/app-builder/tools/app-refresh.ts +7 -1
- package/src/config/bundled-skills/app-builder/tools/app-update.ts +10 -1
- package/src/config/bundled-skills/image-studio/SKILL.md +66 -19
- package/src/config/bundled-skills/image-studio/TOOLS.json +1 -6
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +22 -3
- package/src/config/bundled-skills/personal-page/SKILL.md +57 -0
- package/src/config/bundled-skills/personal-page/TOOLS.json +27 -0
- package/src/config/bundled-skills/personal-page/tools/app-refresh.ts +17 -0
- package/src/config/bundled-skills/schedule/SKILL.md +7 -2
- package/src/config/bundled-skills/schedule/TOOLS.json +48 -4
- package/src/config/bundled-skills/workflows/SKILL.md +214 -0
- package/src/config/bundled-skills/workflows/TOOLS.json +84 -0
- package/src/config/bundled-skills/workflows/tools/manage-workflows.ts +12 -0
- package/src/config/bundled-skills/workflows/tools/run-workflow.ts +12 -0
- package/src/config/bundled-tool-registry.ts +14 -2
- package/src/config/call-site-defaults.ts +5 -0
- package/src/config/feature-flag-registry.json +12 -4
- package/src/config/llm-context-resolution.ts +8 -0
- package/src/config/llm-resolver.ts +30 -0
- package/src/config/preloaded-apps/personal-page/src/components/About.tsx +22 -0
- package/src/config/preloaded-apps/personal-page/src/components/App.tsx +16 -0
- package/src/config/preloaded-apps/personal-page/src/components/Features.tsx +77 -0
- package/src/config/preloaded-apps/personal-page/src/components/Hero.tsx +57 -0
- package/src/config/preloaded-apps/personal-page/src/components/Pending.tsx +28 -0
- package/src/config/preloaded-apps/personal-page/src/components/animations.tsx +234 -0
- package/src/config/preloaded-apps/personal-page/src/components/icons.tsx +48 -0
- package/src/config/preloaded-apps/personal-page/src/components/media.ts +16 -0
- package/src/config/preloaded-apps/personal-page/src/index.html +20 -0
- package/src/config/preloaded-apps/personal-page/src/main.tsx +7 -0
- package/src/config/preloaded-apps/personal-page/src/profile-data.ts +82 -0
- package/src/config/preloaded-apps/personal-page/src/styles.css +759 -0
- package/src/config/schema.ts +2 -0
- package/src/config/schemas/call-site-catalog.ts +7 -0
- package/src/config/schemas/heartbeat.ts +4 -1
- package/src/config/schemas/llm.ts +33 -26
- package/src/config/schemas/memory-retrospective.ts +19 -0
- package/src/config/schemas/platform.ts +8 -0
- package/src/config/schemas/services.ts +5 -2
- package/src/config/schemas/workflows.ts +42 -0
- package/src/config/skills.ts +3 -3
- package/src/context/compactor.ts +273 -39
- package/src/context/post-turn-tool-result-truncation.ts +23 -6
- package/src/context/tool-result-spool.ts +12 -17
- package/src/credential-execution/executable-discovery.ts +1 -1
- package/src/credential-execution/process-manager.ts +37 -3
- package/src/credential-execution/prompted-credential.ts +205 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +14 -0
- package/src/daemon/conversation-process.ts +11 -2
- package/src/daemon/conversation-surfaces.ts +167 -3
- package/src/daemon/conversation-tool-setup.ts +103 -26
- package/src/daemon/conversation-usage.ts +2 -0
- package/src/daemon/conversation.ts +115 -11
- package/src/daemon/handlers/shared.ts +26 -14
- package/src/daemon/host-cu-proxy.ts +15 -12
- package/src/daemon/host-file-proxy.ts +15 -12
- package/src/daemon/host-transfer-proxy.ts +30 -24
- package/src/daemon/lifecycle.ts +40 -3
- package/src/daemon/message-protocol.ts +3 -0
- package/src/daemon/message-types/messages.ts +2 -10
- package/src/daemon/message-types/workflows.ts +49 -0
- package/src/daemon/parse-actual-tokens-from-error.test.ts +62 -1
- package/src/daemon/parse-actual-tokens-from-error.ts +43 -4
- package/src/daemon/process-message.ts +6 -0
- package/src/daemon/tool-setup-types.ts +57 -0
- package/src/daemon/wake-conversation-ops.ts +18 -0
- package/src/heartbeat/heartbeat-run-store.ts +8 -2
- package/src/home/feed-types.ts +1 -1
- package/src/ipc/gateway-flag-listener.ts +28 -6
- package/src/mcp/mcp-auth-state.ts +8 -20
- package/src/media/__tests__/image-models.test.ts +57 -0
- package/src/media/image-models.ts +66 -0
- package/src/memory/__tests__/auto-analysis-enqueue.test.ts +38 -0
- package/src/memory/__tests__/find-most-recent-retrospective-for.test.ts +12 -2
- package/src/memory/__tests__/memory-retrospective-job.test.ts +911 -34
- package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +227 -5
- package/src/memory/__tests__/memory-retrospective-state.test.ts +195 -0
- package/src/memory/__tests__/preloaded-apps.test.ts +85 -0
- package/src/memory/auto-analysis-enqueue.ts +14 -1
- package/src/memory/compaction-log-store-clickhouse.ts +6 -4
- package/src/memory/conversation-crud.ts +9 -2
- package/src/memory/conversation-disk-view.ts +1 -1
- package/src/memory/conversation-queries.ts +22 -7
- package/src/memory/db-init.ts +20 -0
- package/src/memory/db-maintenance.ts +16 -0
- package/src/memory/embedding-runtime-manager.ts +1 -1
- package/src/memory/llm-request-log-source-clickhouse.ts +112 -14
- package/src/memory/llm-request-log-source-local.ts +19 -1
- package/src/memory/llm-request-log-source.ts +35 -6
- package/src/memory/llm-request-log-store.ts +90 -2
- package/src/memory/memory-retrospective-constants.ts +9 -0
- package/src/memory/memory-retrospective-enqueue.ts +3 -6
- package/src/memory/memory-retrospective-fork-boundary.ts +94 -0
- package/src/memory/memory-retrospective-job.ts +500 -208
- package/src/memory/memory-retrospective-startup-cleanup.ts +97 -19
- package/src/memory/memory-retrospective-state.ts +85 -2
- package/src/memory/migrations/281-memory-retrospective-remembered-log.ts +40 -0
- package/src/memory/migrations/282-schedule-inference-profile.test.ts +77 -0
- package/src/memory/migrations/282-schedule-inference-profile.ts +26 -0
- package/src/memory/migrations/283-memory-v3-selections-message-id-and-sections.test.ts +102 -0
- package/src/memory/migrations/283-memory-v3-selections-message-id-and-sections.ts +53 -0
- package/src/memory/migrations/284-workflow-runs.ts +51 -0
- package/src/memory/migrations/285-schedule-workflow-mode.ts +26 -0
- package/src/memory/migrations/286-workflow-run-trust.ts +27 -0
- package/src/memory/migrations/287-conversation-origin-channel-index.ts +15 -0
- package/src/memory/migrations/288-backfill-origin-channel-from-bindings.ts +43 -0
- package/src/memory/migrations/289-contact-channels-unique-ext-user.ts +115 -0
- package/src/memory/migrations/290-schedule-capabilities.test.ts +77 -0
- package/src/memory/migrations/290-schedule-capabilities.ts +25 -0
- package/src/memory/migrations/__tests__/281-memory-retrospective-remembered-log.test.ts +96 -0
- package/src/memory/migrations/__tests__/289-contact-channels-unique-ext-user.test.ts +571 -0
- package/src/memory/migrations/index.ts +10 -0
- package/src/memory/preloaded-apps.ts +116 -0
- package/src/memory/schema/infrastructure.ts +4 -0
- package/src/memory/schema/memory-core.ts +4 -0
- package/src/memory/v2/__tests__/concept-page-frontmatter-schema.test.ts +45 -0
- package/src/memory/v2/__tests__/frontmatter-sweep.test.ts +11 -7
- package/src/memory/v2/__tests__/page-store.test.ts +13 -2
- package/src/memory/v2/__tests__/qdrant.test.ts +24 -0
- package/src/memory/v2/frontmatter-sweep.ts +7 -6
- package/src/memory/v2/page-store.ts +4 -3
- package/src/memory/v2/qdrant.ts +42 -3
- package/src/memory/v2/types.ts +16 -10
- package/src/messaging/draft-store.ts +1 -1
- package/src/notifications/access-request-copy.ts +200 -113
- package/src/notifications/adapters/slack.ts +250 -111
- package/src/notifications/adapters/telegram.ts +7 -44
- package/src/notifications/approval-card-builder.ts +93 -0
- package/src/notifications/broadcaster.ts +74 -0
- package/src/notifications/conversation-pairing.ts +8 -6
- package/src/notifications/copy-composer.ts +32 -26
- package/src/notifications/decision-engine.ts +59 -7
- package/src/notifications/guardian-question-mode.ts +145 -155
- package/src/notifications/home-feed-side-effect.ts +28 -11
- package/src/notifications/notification-utils.ts +66 -0
- package/src/notifications/signal.ts +6 -0
- package/src/notifications/tool-approval-copy.ts +142 -0
- package/src/notifications/types.ts +19 -0
- package/src/permissions/threshold.ts +11 -0
- package/src/plugin-api/types.ts +16 -4
- package/src/plugins/defaults/compaction/window-manager.ts +44 -0
- package/src/plugins/defaults/index.ts +46 -0
- package/src/plugins/defaults/max-tokens-continue/continue-state-store.ts +53 -0
- package/src/plugins/defaults/max-tokens-continue/hooks/post-model-call.ts +80 -0
- package/src/plugins/defaults/max-tokens-continue/hooks/stop.ts +20 -0
- package/src/plugins/defaults/max-tokens-continue/package.json +14 -0
- package/src/plugins/defaults/memory-retrieval/hooks/__tests__/user-prompt-submit.test.ts +37 -0
- package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit.ts +29 -1
- package/src/plugins/defaults/memory-v3-shadow/__tests__/carry-integration.test.ts +8 -3
- package/src/plugins/defaults/memory-v3-shadow/__tests__/injection.test.ts +4 -2
- package/src/plugins/defaults/memory-v3-shadow/__tests__/pool-select.test.ts +28 -18
- package/src/plugins/defaults/memory-v3-shadow/__tests__/section-dense-store.test.ts +67 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/selection-log-store.test.ts +122 -22
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-integration.test.ts +2 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +63 -1
- package/src/plugins/defaults/memory-v3-shadow/injector.ts +61 -18
- package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +1 -1
- package/src/plugins/defaults/memory-v3-shadow/pool-select.ts +39 -10
- package/src/plugins/defaults/memory-v3-shadow/section-dense-store.ts +34 -1
- package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +112 -47
- package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +78 -15
- package/src/plugins/defaults/task-progress-nudge/hooks/post-tool-use.ts +206 -0
- package/src/plugins/defaults/task-progress-nudge/package.json +15 -0
- package/src/prompts/__tests__/system-prompt.test.ts +100 -1
- package/src/prompts/__tests__/task-progress-hint-section.test.ts +5 -7
- package/src/prompts/normalize-onboarding.ts +2 -0
- package/src/prompts/persona-resolver.ts +3 -0
- package/src/prompts/system-prompt.ts +51 -2
- package/src/prompts/templates/BOOTSTRAP-ACTIVATION-RAIL.md +3 -1
- package/src/prompts/templates/system-sections.ts +8 -3
- package/src/providers/call-site-routing.ts +6 -3
- package/src/providers/fireworks/client.ts +3 -0
- package/src/providers/inference/auth.ts +52 -46
- package/src/providers/model-intents.ts +2 -2
- package/src/providers/openai/__tests__/coerce-object-args.test.ts +105 -0
- package/src/providers/openai/chat-completions-provider.ts +47 -9
- package/src/providers/openai/coerce-object-args.ts +104 -0
- package/src/providers/retry.ts +8 -5
- package/src/providers/types.ts +10 -0
- package/src/runtime/__tests__/agent-wake.test.ts +629 -7
- package/src/runtime/access-request-helper.ts +16 -9
- package/src/runtime/agent-wake.ts +302 -51
- package/src/runtime/assistant-stream-state.ts +141 -8
- package/src/runtime/background-job-runner.ts +9 -0
- package/src/runtime/channel-approval-types.ts +1 -0
- package/src/runtime/channel-invite-transports/telegram.ts +6 -5
- package/src/runtime/channel-invite-transports/voice.ts +2 -2
- package/src/runtime/channel-invite-types.ts +4 -2
- package/src/runtime/channel-retry-sweep.ts +19 -41
- package/src/runtime/finalize-event-delivery.ts +72 -0
- package/src/runtime/guardian-action-message-composer.ts +0 -54
- package/src/runtime/http-server.ts +6 -14
- package/src/runtime/http-types.ts +0 -1
- package/src/runtime/message-composer-types.ts +0 -9
- package/src/runtime/middleware/__tests__/rate-limiter.test.ts +63 -0
- package/src/runtime/middleware/auth.ts +27 -3
- package/src/runtime/middleware/rate-limiter.ts +28 -1
- package/src/runtime/migrations/vbundle-builder.ts +6 -5
- package/src/runtime/pending-interactions.ts +20 -1
- package/src/runtime/routes/__tests__/conversation-compaction-routes.test.ts +232 -173
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +18 -0
- package/src/runtime/routes/__tests__/retrospective-routes.test.ts +436 -0
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +11 -0
- package/src/runtime/routes/approval-routes.ts +35 -8
- package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +2 -1
- package/src/runtime/routes/btw-routes.ts +37 -1
- package/src/runtime/routes/channel-delivery-routes.ts +11 -7
- package/src/runtime/routes/channel-route-definitions.ts +3 -0
- package/src/runtime/routes/channel-route-shared.ts +3 -1
- package/src/runtime/routes/consolidation-routes.ts +17 -13
- package/src/runtime/routes/conversation-compaction-routes.ts +159 -119
- package/src/runtime/routes/conversation-list-routes.ts +41 -4
- package/src/runtime/routes/conversation-query-routes.ts +196 -11
- package/src/runtime/routes/conversation-routes.ts +15 -1
- package/src/runtime/routes/credential-prompt-routes.ts +39 -17
- package/src/runtime/routes/empty-state-greeting-cache.ts +65 -0
- package/src/runtime/routes/heartbeat-routes.ts +18 -13
- package/src/runtime/routes/image-generation-routes.ts +20 -2
- package/src/runtime/routes/inbound-message-handler.ts +13 -12
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +32 -31
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +7 -5
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +7 -21
- package/src/runtime/routes/inbound-stages/escalation-intercept.ts +5 -5
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +6 -15
- package/src/runtime/routes/inbound-stages/secret-ingress-check.ts +1 -1
- package/src/runtime/routes/index.ts +6 -0
- package/src/runtime/routes/log-export/AGENTS.md +1 -1
- package/src/runtime/routes/log-export/workspace-allowlist.ts +1 -1
- package/src/runtime/routes/migration-routes.ts +5 -9
- package/src/runtime/routes/plugins-routes.ts +26 -0
- package/src/runtime/routes/ps-routes.ts +10 -8
- package/src/runtime/routes/retrospective-routes.ts +235 -0
- package/src/runtime/routes/runs-pagination.ts +75 -0
- package/src/runtime/routes/schedule-routes.ts +367 -59
- package/src/runtime/routes/sounds-config-routes.ts +239 -0
- package/src/runtime/routes/surface-action-routes.ts +84 -4
- package/src/runtime/routes/workflow-routes.test.ts +372 -0
- package/src/runtime/routes/workflow-routes.ts +363 -0
- package/src/runtime/routes/workspace-routes.test.ts +61 -1
- package/src/runtime/routes/workspace-routes.ts +26 -1
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +38 -0
- package/src/runtime/services/analyze-conversation.ts +26 -13
- package/src/schedule/inference-profile.ts +28 -0
- package/src/schedule/schedule-store.ts +152 -4
- package/src/schedule/scheduler-types.ts +6 -0
- package/src/schedule/scheduler.ts +96 -0
- package/src/security/secret-allowlist.ts +1 -1
- package/src/skills/path-classifier.ts +1 -1
- package/src/tools/apps/executors.ts +23 -0
- package/src/tools/apps/resolve-app-id.ts +42 -0
- package/src/tools/browser/browser-execution.ts +9 -11
- package/src/tools/credentials/broker.ts +4 -4
- package/src/tools/credentials/vault.ts +26 -137
- package/src/tools/executor.ts +69 -0
- package/src/tools/flag-gated-tools.test.ts +76 -0
- package/src/tools/permission-checker.ts +8 -1
- package/src/tools/registry.ts +51 -0
- package/src/tools/schedule/create.ts +77 -1
- package/src/tools/schedule/list.ts +1 -0
- package/src/tools/schedule/update.ts +73 -1
- package/src/tools/skills/execute.ts +56 -0
- package/src/tools/terminal/shell.ts +1 -1
- package/src/tools/ui-surface/definitions.ts +91 -2
- package/src/tools/workflows/manage-workflows.ts +183 -0
- package/src/tools/workflows/run-workflow.test.ts +442 -0
- package/src/tools/workflows/run-workflow.ts +88 -0
- package/src/types/onboarding-context.ts +2 -0
- package/src/usage/attribution.ts +24 -0
- package/src/util/canonicalize-identity.ts +12 -3
- package/src/util/platform.ts +17 -17
- package/src/watcher/__tests__/engine.test.ts +24 -0
- package/src/watcher/__tests__/telemetry.test.ts +135 -0
- package/src/watcher/engine.ts +7 -0
- package/src/watcher/telemetry.ts +74 -0
- package/src/workflows/capabilities.test.ts +365 -0
- package/src/workflows/capabilities.ts +359 -0
- package/src/workflows/deterministic-stringify.ts +27 -0
- package/src/workflows/engine-integration.test.ts +656 -0
- package/src/workflows/engine.test.ts +1144 -0
- package/src/workflows/engine.ts +1078 -0
- package/src/workflows/fanout-load.test.ts +168 -0
- package/src/workflows/journal-store.test.ts +369 -0
- package/src/workflows/journal-store.ts +470 -0
- package/src/workflows/leaf-runner.test.ts +704 -0
- package/src/workflows/leaf-runner.ts +589 -0
- package/src/workflows/library.test.ts +134 -0
- package/src/workflows/library.ts +124 -0
- package/src/workflows/run-manager.test.ts +711 -0
- package/src/workflows/run-manager.ts +593 -0
- package/src/workflows/sandbox-escape.test.ts +339 -0
- package/src/workflows/sandbox.test.ts +251 -0
- package/src/workflows/sandbox.ts +447 -0
- package/src/workspace/adaptive-thinking-repair.ts +33 -11
- package/src/workspace/migrations/021-move-signals-to-workspace.ts +1 -1
- package/src/workspace/migrations/022-move-hooks-to-workspace.ts +1 -1
- package/src/workspace/migrations/026-backfill-install-meta.ts +1 -1
- package/src/workspace/migrations/030-seed-pkb-autoinject.ts +2 -1
- package/src/workspace/migrations/031-drop-user-md.ts +1 -4
- package/src/workspace/migrations/048-remove-workspace-hooks.ts +1 -1
- package/src/workspace/migrations/056-release-notes-inference-profile-reordering.ts +5 -2
- package/src/workspace/migrations/061-move-backup-key-to-workspace.ts +1 -1
- package/src/workspace/migrations/082-backfill-managed-profile-labels.ts +8 -2
- package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +41 -14
- package/src/workspace/migrations/102-preserve-heartbeat-enabled-for-existing-workspaces.ts +69 -0
- package/src/workspace/migrations/103-upgrade-quality-profile-to-opus-4-8.ts +83 -0
- package/src/workspace/migrations/104-recheck-adaptive-thinking-model-implied-anthropic.ts +133 -0
- package/src/workspace/migrations/registry.ts +6 -0
- package/src/workspace/migrations/runner.ts +1 -1
- package/tsconfig.json +1 -1
- package/src/__tests__/guardian-action-copy-generator.test.ts +0 -200
- package/src/__tests__/guardian-action-grant-mint-consume.test.ts +0 -579
- package/src/__tests__/guardian-action-store.test.ts +0 -106
- package/src/daemon/guardian-action-generators.ts +0 -71
- package/src/memory/guardian-action-store.ts +0 -484
- package/src/runtime/guardian-action-grant-minter.ts +0 -150
|
@@ -98,8 +98,10 @@ describe("schedules command", () => {
|
|
|
98
98
|
expect(schedules).toBeDefined();
|
|
99
99
|
expect(schedules!.commands.map((command) => command.name())).toEqual([
|
|
100
100
|
"list",
|
|
101
|
+
"get",
|
|
101
102
|
"runs",
|
|
102
103
|
"create",
|
|
104
|
+
"update",
|
|
103
105
|
"enable",
|
|
104
106
|
"disable",
|
|
105
107
|
"cancel",
|
|
@@ -252,6 +254,125 @@ describe("schedules list", () => {
|
|
|
252
254
|
});
|
|
253
255
|
});
|
|
254
256
|
|
|
257
|
+
describe("schedules get", () => {
|
|
258
|
+
const scheduleFixture = {
|
|
259
|
+
id: "schedule-1",
|
|
260
|
+
name: "Heartbeat",
|
|
261
|
+
enabled: true,
|
|
262
|
+
syntax: "cron",
|
|
263
|
+
expression: "*/30 * * * *",
|
|
264
|
+
cronExpression: "*/30 * * * *",
|
|
265
|
+
timezone: "UTC",
|
|
266
|
+
message: "run heartbeat",
|
|
267
|
+
script: null,
|
|
268
|
+
nextRunAt: 1_778_800_000_000,
|
|
269
|
+
lastRunAt: 1_778_799_000_000,
|
|
270
|
+
lastStatus: "ok",
|
|
271
|
+
retryCount: 0,
|
|
272
|
+
maxRetries: 3,
|
|
273
|
+
retryBackoffMs: 60_000,
|
|
274
|
+
timeoutMs: null,
|
|
275
|
+
createdFromConversationId: "conv-abc",
|
|
276
|
+
description: "Authored heartbeat check",
|
|
277
|
+
cadenceDescription: "Every 30 minutes",
|
|
278
|
+
mode: "execute",
|
|
279
|
+
status: "active",
|
|
280
|
+
routingIntent: "all_channels",
|
|
281
|
+
reuseConversation: false,
|
|
282
|
+
wakeConversationId: null,
|
|
283
|
+
isOneShot: false,
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
test("calls getSchedule with the schedule ID path param", async () => {
|
|
287
|
+
mockIpcResult = { ok: true, result: { schedule: scheduleFixture } };
|
|
288
|
+
|
|
289
|
+
const { exitCode } = await runCommand(["schedules", "get", "schedule-1"]);
|
|
290
|
+
|
|
291
|
+
expect(exitCode).toBe(0);
|
|
292
|
+
expect(ipcCalls).toEqual([
|
|
293
|
+
{
|
|
294
|
+
method: "getSchedule",
|
|
295
|
+
params: { pathParams: { id: "schedule-1" } },
|
|
296
|
+
},
|
|
297
|
+
]);
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
test("inspect alias resolves to the same getSchedule handler", async () => {
|
|
301
|
+
// GIVEN the daemon returns a schedule for the requested ID
|
|
302
|
+
mockIpcResult = { ok: true, result: { schedule: scheduleFixture } };
|
|
303
|
+
|
|
304
|
+
// WHEN the user invokes the `inspect` alias instead of `get`
|
|
305
|
+
const { exitCode } = await runCommand([
|
|
306
|
+
"schedules",
|
|
307
|
+
"inspect",
|
|
308
|
+
"schedule-1",
|
|
309
|
+
]);
|
|
310
|
+
|
|
311
|
+
// THEN it calls the same getSchedule IPC method with the ID path param
|
|
312
|
+
expect(exitCode).toBe(0);
|
|
313
|
+
expect(ipcCalls).toEqual([
|
|
314
|
+
{
|
|
315
|
+
method: "getSchedule",
|
|
316
|
+
params: { pathParams: { id: "schedule-1" } },
|
|
317
|
+
},
|
|
318
|
+
]);
|
|
319
|
+
// AND it renders the same human-readable detail view
|
|
320
|
+
expect(logLines.join("\n")).toContain("run heartbeat");
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
test("renders a detail view for human output", async () => {
|
|
324
|
+
mockIpcResult = { ok: true, result: { schedule: scheduleFixture } };
|
|
325
|
+
|
|
326
|
+
const { exitCode } = await runCommand(["schedules", "get", "schedule-1"]);
|
|
327
|
+
|
|
328
|
+
expect(exitCode).toBe(0);
|
|
329
|
+
const output = logLines.join("\n");
|
|
330
|
+
expect(output).toContain("ID:");
|
|
331
|
+
expect(output).toContain("schedule-1");
|
|
332
|
+
expect(output).toContain("Heartbeat");
|
|
333
|
+
expect(output).toContain("Authored heartbeat check");
|
|
334
|
+
expect(output).toContain("Every 30 minutes (UTC)");
|
|
335
|
+
expect(output).toContain("run heartbeat");
|
|
336
|
+
expect(output).toContain("all_channels");
|
|
337
|
+
expect(output).toContain("conv-abc");
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
test("emits JSON result when --json is set", async () => {
|
|
341
|
+
mockIpcResult = { ok: true, result: { schedule: scheduleFixture } };
|
|
342
|
+
|
|
343
|
+
const { stdout, exitCode } = await runCommand([
|
|
344
|
+
"schedules",
|
|
345
|
+
"get",
|
|
346
|
+
"schedule-1",
|
|
347
|
+
"--json",
|
|
348
|
+
]);
|
|
349
|
+
|
|
350
|
+
expect(exitCode).toBe(0);
|
|
351
|
+
expect(JSON.parse(stdout)).toEqual({
|
|
352
|
+
schedule: expect.objectContaining({
|
|
353
|
+
id: "schedule-1",
|
|
354
|
+
name: "Heartbeat",
|
|
355
|
+
description: "Authored heartbeat check",
|
|
356
|
+
}),
|
|
357
|
+
});
|
|
358
|
+
expect(logLines).toEqual([]);
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
test("routes IPC failure through exitFromIpcResult", async () => {
|
|
362
|
+
mockIpcResult = { ok: false, error: "Schedule not found" };
|
|
363
|
+
|
|
364
|
+
const { exitCode } = await runCommand([
|
|
365
|
+
"schedules",
|
|
366
|
+
"get",
|
|
367
|
+
"missing-schedule",
|
|
368
|
+
]);
|
|
369
|
+
|
|
370
|
+
expect(exitCode).toBe(10);
|
|
371
|
+
expect(exitFromIpcResultCalls).toEqual([mockIpcResult]);
|
|
372
|
+
expect(errorLines).toEqual([]);
|
|
373
|
+
});
|
|
374
|
+
});
|
|
375
|
+
|
|
255
376
|
describe("schedules runs", () => {
|
|
256
377
|
test("calls listScheduleRuns with the schedule ID path param", async () => {
|
|
257
378
|
mockIpcResult = { ok: true, result: { runs: [] } };
|
|
@@ -343,10 +464,49 @@ describe("schedules runs", () => {
|
|
|
343
464
|
expect(exitCode).toBe(0);
|
|
344
465
|
expect(logLines.join("\n")).toContain("STATUS");
|
|
345
466
|
expect(logLines.join("\n")).toContain("run-1");
|
|
346
|
-
expect(logLines.join("\n")).toContain("
|
|
467
|
+
expect(logLines.join("\n")).toContain("2.5s");
|
|
347
468
|
expect(logLines.join("\n")).toContain("conversation-1");
|
|
348
469
|
});
|
|
349
470
|
|
|
471
|
+
test("formats run durations into human-friendly units", async () => {
|
|
472
|
+
const durations = [
|
|
473
|
+
{ ms: 450, expected: "450ms" },
|
|
474
|
+
{ ms: 29_854, expected: "29.9s" },
|
|
475
|
+
{ ms: 30_000, expected: "30s" },
|
|
476
|
+
{ ms: 90_000, expected: "1m 30s" },
|
|
477
|
+
{ ms: 300_000, expected: "5m" },
|
|
478
|
+
{ ms: 3_600_000, expected: "1h" },
|
|
479
|
+
{ ms: 8_100_000, expected: "2h 15m" },
|
|
480
|
+
{ ms: 93_600_000, expected: "1d 2h" },
|
|
481
|
+
];
|
|
482
|
+
|
|
483
|
+
mockIpcResult = {
|
|
484
|
+
ok: true,
|
|
485
|
+
result: {
|
|
486
|
+
runs: durations.map((d, i) => ({
|
|
487
|
+
id: `run-${i}`,
|
|
488
|
+
jobId: "schedule-1",
|
|
489
|
+
status: "ok",
|
|
490
|
+
startedAt: 1_778_799_000_000,
|
|
491
|
+
finishedAt: 1_778_799_000_000 + d.ms,
|
|
492
|
+
durationMs: d.ms,
|
|
493
|
+
output: "done",
|
|
494
|
+
error: null,
|
|
495
|
+
conversationId: `conversation-${i}`,
|
|
496
|
+
createdAt: 1_778_799_000_000,
|
|
497
|
+
})),
|
|
498
|
+
},
|
|
499
|
+
};
|
|
500
|
+
|
|
501
|
+
const { exitCode } = await runCommand(["schedules", "runs", "schedule-1"]);
|
|
502
|
+
|
|
503
|
+
expect(exitCode).toBe(0);
|
|
504
|
+
const output = logLines.join("\n");
|
|
505
|
+
for (const { expected } of durations) {
|
|
506
|
+
expect(output).toContain(expected);
|
|
507
|
+
}
|
|
508
|
+
});
|
|
509
|
+
|
|
350
510
|
test("prints an empty message when no runs are found", async () => {
|
|
351
511
|
mockIpcResult = { ok: true, result: { runs: [] } };
|
|
352
512
|
|
|
@@ -590,6 +750,275 @@ describe("schedules create", () => {
|
|
|
590
750
|
});
|
|
591
751
|
});
|
|
592
752
|
|
|
753
|
+
describe("schedules update", () => {
|
|
754
|
+
test("calls updateSchedule with only the provided flags", async () => {
|
|
755
|
+
mockIpcResult = { ok: true, result: { schedules: [] } };
|
|
756
|
+
|
|
757
|
+
const { exitCode } = await runCommand([
|
|
758
|
+
"schedules",
|
|
759
|
+
"update",
|
|
760
|
+
"schedule-1",
|
|
761
|
+
"--name",
|
|
762
|
+
"Renamed",
|
|
763
|
+
"--expression",
|
|
764
|
+
"0 9 * * MON-FRI",
|
|
765
|
+
"--timezone",
|
|
766
|
+
"America/New_York",
|
|
767
|
+
]);
|
|
768
|
+
|
|
769
|
+
expect(exitCode).toBe(0);
|
|
770
|
+
expect(ipcCalls).toEqual([
|
|
771
|
+
{
|
|
772
|
+
method: "updateSchedule",
|
|
773
|
+
params: {
|
|
774
|
+
pathParams: { id: "schedule-1" },
|
|
775
|
+
body: {
|
|
776
|
+
name: "Renamed",
|
|
777
|
+
expression: "0 9 * * MON-FRI",
|
|
778
|
+
timezone: "America/New_York",
|
|
779
|
+
},
|
|
780
|
+
},
|
|
781
|
+
},
|
|
782
|
+
]);
|
|
783
|
+
expect(logLines).toEqual(["Updated schedule: schedule-1"]);
|
|
784
|
+
});
|
|
785
|
+
|
|
786
|
+
test("errors when no update flags are provided", async () => {
|
|
787
|
+
const { exitCode } = await runCommand([
|
|
788
|
+
"schedules",
|
|
789
|
+
"update",
|
|
790
|
+
"schedule-1",
|
|
791
|
+
]);
|
|
792
|
+
|
|
793
|
+
expect(exitCode).toBe(1);
|
|
794
|
+
expect(ipcCalls).toEqual([]);
|
|
795
|
+
expect(errorLines.join("\n")).toContain(
|
|
796
|
+
"At least one update flag is required",
|
|
797
|
+
);
|
|
798
|
+
});
|
|
799
|
+
|
|
800
|
+
test("parses numeric retry and timeout flags into numbers", async () => {
|
|
801
|
+
mockIpcResult = { ok: true, result: { schedules: [] } };
|
|
802
|
+
|
|
803
|
+
const { exitCode } = await runCommand([
|
|
804
|
+
"schedules",
|
|
805
|
+
"update",
|
|
806
|
+
"schedule-1",
|
|
807
|
+
"--max-retries",
|
|
808
|
+
"5",
|
|
809
|
+
"--retry-backoff-ms",
|
|
810
|
+
"30000",
|
|
811
|
+
"--timeout-ms",
|
|
812
|
+
"5000",
|
|
813
|
+
]);
|
|
814
|
+
|
|
815
|
+
expect(exitCode).toBe(0);
|
|
816
|
+
expect(ipcCalls).toEqual([
|
|
817
|
+
{
|
|
818
|
+
method: "updateSchedule",
|
|
819
|
+
params: {
|
|
820
|
+
pathParams: { id: "schedule-1" },
|
|
821
|
+
body: { maxRetries: 5, retryBackoffMs: 30_000, timeoutMs: 5000 },
|
|
822
|
+
},
|
|
823
|
+
},
|
|
824
|
+
]);
|
|
825
|
+
});
|
|
826
|
+
|
|
827
|
+
test("rejects a non-integer --max-retries", async () => {
|
|
828
|
+
const { exitCode } = await runCommand([
|
|
829
|
+
"schedules",
|
|
830
|
+
"update",
|
|
831
|
+
"schedule-1",
|
|
832
|
+
"--max-retries",
|
|
833
|
+
"lots",
|
|
834
|
+
]);
|
|
835
|
+
|
|
836
|
+
expect(exitCode).toBe(1);
|
|
837
|
+
expect(ipcCalls).toEqual([]);
|
|
838
|
+
expect(errorLines.join("\n")).toContain("--max-retries must be an integer");
|
|
839
|
+
});
|
|
840
|
+
|
|
841
|
+
test("sends timeoutMs null with --clear-timeout", async () => {
|
|
842
|
+
mockIpcResult = { ok: true, result: { schedules: [] } };
|
|
843
|
+
|
|
844
|
+
const { exitCode } = await runCommand([
|
|
845
|
+
"schedules",
|
|
846
|
+
"update",
|
|
847
|
+
"schedule-1",
|
|
848
|
+
"--clear-timeout",
|
|
849
|
+
]);
|
|
850
|
+
|
|
851
|
+
expect(exitCode).toBe(0);
|
|
852
|
+
expect(ipcCalls).toEqual([
|
|
853
|
+
{
|
|
854
|
+
method: "updateSchedule",
|
|
855
|
+
params: {
|
|
856
|
+
pathParams: { id: "schedule-1" },
|
|
857
|
+
body: { timeoutMs: null },
|
|
858
|
+
},
|
|
859
|
+
},
|
|
860
|
+
]);
|
|
861
|
+
});
|
|
862
|
+
|
|
863
|
+
test("rejects --timeout-ms combined with --clear-timeout", async () => {
|
|
864
|
+
const { exitCode } = await runCommand([
|
|
865
|
+
"schedules",
|
|
866
|
+
"update",
|
|
867
|
+
"schedule-1",
|
|
868
|
+
"--timeout-ms",
|
|
869
|
+
"5000",
|
|
870
|
+
"--clear-timeout",
|
|
871
|
+
]);
|
|
872
|
+
|
|
873
|
+
expect(exitCode).toBe(1);
|
|
874
|
+
expect(ipcCalls).toEqual([]);
|
|
875
|
+
expect(errorLines.join("\n")).toContain("mutually exclusive");
|
|
876
|
+
});
|
|
877
|
+
|
|
878
|
+
test("rejects --mode wake when the schedule has no wake conversation target", async () => {
|
|
879
|
+
mockIpcResult = {
|
|
880
|
+
ok: true,
|
|
881
|
+
result: { schedule: { wakeConversationId: null } },
|
|
882
|
+
};
|
|
883
|
+
|
|
884
|
+
const { exitCode } = await runCommand([
|
|
885
|
+
"schedules",
|
|
886
|
+
"update",
|
|
887
|
+
"schedule-1",
|
|
888
|
+
"--mode",
|
|
889
|
+
"wake",
|
|
890
|
+
]);
|
|
891
|
+
|
|
892
|
+
expect(exitCode).toBe(1);
|
|
893
|
+
expect(ipcCalls).toEqual([
|
|
894
|
+
{ method: "getSchedule", params: { pathParams: { id: "schedule-1" } } },
|
|
895
|
+
]);
|
|
896
|
+
expect(errorLines.join("\n")).toContain("wake conversation target");
|
|
897
|
+
});
|
|
898
|
+
|
|
899
|
+
test("allows --mode wake when the schedule already has a wake target", async () => {
|
|
900
|
+
// The shared mock returns one shape for both IPC calls; satisfy the
|
|
901
|
+
// getSchedule guard and the update response renderer simultaneously.
|
|
902
|
+
mockIpcResult = {
|
|
903
|
+
ok: true,
|
|
904
|
+
result: {
|
|
905
|
+
schedule: { wakeConversationId: "conv-1" },
|
|
906
|
+
schedules: [],
|
|
907
|
+
},
|
|
908
|
+
};
|
|
909
|
+
|
|
910
|
+
const { exitCode } = await runCommand([
|
|
911
|
+
"schedules",
|
|
912
|
+
"update",
|
|
913
|
+
"schedule-1",
|
|
914
|
+
"--mode",
|
|
915
|
+
"wake",
|
|
916
|
+
]);
|
|
917
|
+
|
|
918
|
+
expect(exitCode).toBe(0);
|
|
919
|
+
expect(ipcCalls).toHaveLength(2);
|
|
920
|
+
expect(ipcCalls[0].method).toBe("getSchedule");
|
|
921
|
+
expect(ipcCalls[1]).toEqual({
|
|
922
|
+
method: "updateSchedule",
|
|
923
|
+
params: {
|
|
924
|
+
pathParams: { id: "schedule-1" },
|
|
925
|
+
body: { mode: "wake" },
|
|
926
|
+
},
|
|
927
|
+
});
|
|
928
|
+
});
|
|
929
|
+
|
|
930
|
+
test("sends boolean false for negated flags", async () => {
|
|
931
|
+
mockIpcResult = { ok: true, result: { schedules: [] } };
|
|
932
|
+
|
|
933
|
+
const { exitCode } = await runCommand([
|
|
934
|
+
"schedules",
|
|
935
|
+
"update",
|
|
936
|
+
"schedule-1",
|
|
937
|
+
"--no-quiet",
|
|
938
|
+
"--no-reuse-conversation",
|
|
939
|
+
]);
|
|
940
|
+
|
|
941
|
+
expect(exitCode).toBe(0);
|
|
942
|
+
expect(ipcCalls).toEqual([
|
|
943
|
+
{
|
|
944
|
+
method: "updateSchedule",
|
|
945
|
+
params: {
|
|
946
|
+
pathParams: { id: "schedule-1" },
|
|
947
|
+
body: { quiet: false, reuseConversation: false },
|
|
948
|
+
},
|
|
949
|
+
},
|
|
950
|
+
]);
|
|
951
|
+
});
|
|
952
|
+
|
|
953
|
+
test("emits JSON result when --json is set", async () => {
|
|
954
|
+
mockIpcResult = {
|
|
955
|
+
ok: true,
|
|
956
|
+
result: {
|
|
957
|
+
schedules: [
|
|
958
|
+
{
|
|
959
|
+
id: "schedule-1",
|
|
960
|
+
name: "Renamed",
|
|
961
|
+
enabled: true,
|
|
962
|
+
syntax: "cron",
|
|
963
|
+
expression: "0 9 * * MON-FRI",
|
|
964
|
+
cronExpression: "0 9 * * MON-FRI",
|
|
965
|
+
timezone: "America/New_York",
|
|
966
|
+
message: "run heartbeat",
|
|
967
|
+
script: null,
|
|
968
|
+
nextRunAt: 1_778_800_000_000,
|
|
969
|
+
lastRunAt: null,
|
|
970
|
+
lastStatus: "ok",
|
|
971
|
+
retryCount: 0,
|
|
972
|
+
maxRetries: 3,
|
|
973
|
+
retryBackoffMs: 60_000,
|
|
974
|
+
description: "Authored heartbeat check",
|
|
975
|
+
cadenceDescription: "At 9:00 AM, Monday through Friday",
|
|
976
|
+
mode: "execute",
|
|
977
|
+
status: "active",
|
|
978
|
+
routingIntent: "all_channels",
|
|
979
|
+
reuseConversation: false,
|
|
980
|
+
wakeConversationId: null,
|
|
981
|
+
isOneShot: false,
|
|
982
|
+
},
|
|
983
|
+
],
|
|
984
|
+
},
|
|
985
|
+
};
|
|
986
|
+
|
|
987
|
+
const { stdout, exitCode } = await runCommand([
|
|
988
|
+
"schedules",
|
|
989
|
+
"update",
|
|
990
|
+
"schedule-1",
|
|
991
|
+
"--name",
|
|
992
|
+
"Renamed",
|
|
993
|
+
"--json",
|
|
994
|
+
]);
|
|
995
|
+
|
|
996
|
+
expect(exitCode).toBe(0);
|
|
997
|
+
expect(JSON.parse(stdout)).toEqual({
|
|
998
|
+
schedules: [
|
|
999
|
+
expect.objectContaining({ id: "schedule-1", name: "Renamed" }),
|
|
1000
|
+
],
|
|
1001
|
+
});
|
|
1002
|
+
expect(logLines).toEqual([]);
|
|
1003
|
+
});
|
|
1004
|
+
|
|
1005
|
+
test("routes IPC failure through exitFromIpcResult", async () => {
|
|
1006
|
+
mockIpcResult = { ok: false, error: "Schedule not found" };
|
|
1007
|
+
|
|
1008
|
+
const { exitCode } = await runCommand([
|
|
1009
|
+
"schedules",
|
|
1010
|
+
"update",
|
|
1011
|
+
"missing-schedule",
|
|
1012
|
+
"--name",
|
|
1013
|
+
"Renamed",
|
|
1014
|
+
]);
|
|
1015
|
+
|
|
1016
|
+
expect(exitCode).toBe(10);
|
|
1017
|
+
expect(exitFromIpcResultCalls).toEqual([mockIpcResult]);
|
|
1018
|
+
expect(errorLines).toEqual([]);
|
|
1019
|
+
});
|
|
1020
|
+
});
|
|
1021
|
+
|
|
593
1022
|
describe("schedules enable/disable", () => {
|
|
594
1023
|
test("enable calls toggleSchedule with enabled true", async () => {
|
|
595
1024
|
mockIpcResult = { ok: true, result: { schedules: [] } };
|
|
@@ -5,6 +5,7 @@ import type { CredentialPromptResult } from "../../runtime/routes/credential-pro
|
|
|
5
5
|
import { registerCommand } from "../lib/register-command.js";
|
|
6
6
|
import { log } from "../logger.js";
|
|
7
7
|
import { shouldOutputJson, writeOutput } from "../output.js";
|
|
8
|
+
import { tryResolveConversationId } from "../utils/conversation-id.js";
|
|
8
9
|
|
|
9
10
|
// ---------------------------------------------------------------------------
|
|
10
11
|
// Format-aware error output
|
|
@@ -114,8 +115,7 @@ export function registerCredentialsCommand(program: Command): void {
|
|
|
114
115
|
description:
|
|
115
116
|
"Manage credentials in the encrypted vault (API keys, tokens, passwords)",
|
|
116
117
|
build: (credential) => {
|
|
117
|
-
credential
|
|
118
|
-
.option("--json", "Machine-readable compact JSON output");
|
|
118
|
+
credential.option("--json", "Machine-readable compact JSON output");
|
|
119
119
|
|
|
120
120
|
credential.addHelpText(
|
|
121
121
|
"after",
|
|
@@ -224,9 +224,7 @@ Examples:
|
|
|
224
224
|
|
|
225
225
|
credential
|
|
226
226
|
.command("status")
|
|
227
|
-
.description(
|
|
228
|
-
"Show the active credential backend and its configuration",
|
|
229
|
-
)
|
|
227
|
+
.description("Show the active credential backend and its configuration")
|
|
230
228
|
.addHelpText(
|
|
231
229
|
"after",
|
|
232
230
|
`
|
|
@@ -248,9 +246,8 @@ Examples:
|
|
|
248
246
|
$ assistant credentials status --json`,
|
|
249
247
|
)
|
|
250
248
|
.action(async (_opts: Record<string, unknown>, cmd: Command) => {
|
|
251
|
-
const r =
|
|
252
|
-
"credentials_status"
|
|
253
|
-
);
|
|
249
|
+
const r =
|
|
250
|
+
await cliIpcCall<CredentialsStatusResponse>("credentials_status");
|
|
254
251
|
if (!r.ok) {
|
|
255
252
|
return exitFromIpcResult(
|
|
256
253
|
r as { ok: false; error?: string; statusCode?: number },
|
|
@@ -286,7 +283,10 @@ Examples:
|
|
|
286
283
|
credential
|
|
287
284
|
.command("set <value>")
|
|
288
285
|
.description("Store a secret and create or update its metadata")
|
|
289
|
-
.requiredOption(
|
|
286
|
+
.requiredOption(
|
|
287
|
+
"--service <service>",
|
|
288
|
+
"Service namespace (e.g. google)",
|
|
289
|
+
)
|
|
290
290
|
.requiredOption("--field <field>", "Field name (e.g. client_secret)")
|
|
291
291
|
.option("--label <label>", 'Human-friendly label (e.g. "prod", "work")')
|
|
292
292
|
.option(
|
|
@@ -345,7 +345,8 @@ Examples:
|
|
|
345
345
|
if (!r.ok) {
|
|
346
346
|
writeError(
|
|
347
347
|
cmd,
|
|
348
|
-
r.error ??
|
|
348
|
+
r.error ??
|
|
349
|
+
`Failed to store credential ${opts.service}:${opts.field}`,
|
|
349
350
|
);
|
|
350
351
|
process.exitCode = 1;
|
|
351
352
|
return;
|
|
@@ -397,7 +398,8 @@ Examples:
|
|
|
397
398
|
if (!r.ok) {
|
|
398
399
|
writeError(
|
|
399
400
|
cmd,
|
|
400
|
-
r.error ??
|
|
401
|
+
r.error ??
|
|
402
|
+
`Failed to delete credential ${opts.service}:${opts.field}`,
|
|
401
403
|
);
|
|
402
404
|
process.exitCode = 1;
|
|
403
405
|
return;
|
|
@@ -410,9 +412,7 @@ Examples:
|
|
|
410
412
|
field: opts.field,
|
|
411
413
|
});
|
|
412
414
|
} else {
|
|
413
|
-
log.info(
|
|
414
|
-
`Deleted credential ${opts.service}:${opts.field}`,
|
|
415
|
-
);
|
|
415
|
+
log.info(`Deleted credential ${opts.service}:${opts.field}`);
|
|
416
416
|
}
|
|
417
417
|
},
|
|
418
418
|
);
|
|
@@ -588,6 +588,10 @@ Examples:
|
|
|
588
588
|
.requiredOption("--label <label>", "Display label for the prompt UI")
|
|
589
589
|
.option("--description <description>", "Context shown in the prompt UI")
|
|
590
590
|
.option("--placeholder <placeholder>", "Placeholder text for the input")
|
|
591
|
+
.option(
|
|
592
|
+
"--usage-description <description>",
|
|
593
|
+
"Human-readable description of intended usage, stored in credential metadata and shown as the prompt's purpose",
|
|
594
|
+
)
|
|
591
595
|
.option(
|
|
592
596
|
"--allowed-domains <domains>",
|
|
593
597
|
"Comma-separated domains where this credential may be used",
|
|
@@ -613,6 +617,7 @@ Requires the assistant to be running with at least one connected client.
|
|
|
613
617
|
Examples:
|
|
614
618
|
$ assistant credentials prompt --service sentry --field auth_token \\
|
|
615
619
|
--label "Sentry Auth Token" --placeholder "sntrys_..." \\
|
|
620
|
+
--usage-description "Read Sentry issues and events" \\
|
|
616
621
|
--allowed-domains "sentry.io" \\
|
|
617
622
|
--injection-templates '[{"hostPattern":"sentry.io","injectionType":"header","headerName":"Authorization","valuePrefix":"Bearer "}]'`,
|
|
618
623
|
)
|
|
@@ -624,6 +629,7 @@ Examples:
|
|
|
624
629
|
label: string;
|
|
625
630
|
description?: string;
|
|
626
631
|
placeholder?: string;
|
|
632
|
+
usageDescription?: string;
|
|
627
633
|
allowedDomains?: string;
|
|
628
634
|
allowedTools?: string;
|
|
629
635
|
injectionTemplates?: string;
|
|
@@ -663,9 +669,11 @@ Examples:
|
|
|
663
669
|
label: opts.label,
|
|
664
670
|
description: opts.description,
|
|
665
671
|
placeholder: opts.placeholder,
|
|
672
|
+
usageDescription: opts.usageDescription,
|
|
666
673
|
allowedDomains,
|
|
667
674
|
allowedTools,
|
|
668
675
|
injectionTemplates,
|
|
676
|
+
conversationId: tryResolveConversationId(),
|
|
669
677
|
},
|
|
670
678
|
},
|
|
671
679
|
{ timeoutMs: PROMPT_TIMEOUT_MS },
|
|
@@ -681,22 +689,18 @@ Examples:
|
|
|
681
689
|
}
|
|
682
690
|
|
|
683
691
|
if (!ipc.result?.ok) {
|
|
684
|
-
writeError(
|
|
685
|
-
cmd,
|
|
686
|
-
ipc.result?.error ?? "Credential prompt failed",
|
|
687
|
-
);
|
|
692
|
+
writeError(cmd, ipc.result?.error ?? "Credential prompt failed");
|
|
688
693
|
process.exitCode = 1;
|
|
689
694
|
return;
|
|
690
695
|
}
|
|
691
696
|
|
|
692
697
|
if (shouldOutputJson(cmd)) {
|
|
693
|
-
writeOutput(cmd,
|
|
694
|
-
ok: true,
|
|
695
|
-
service: opts.service,
|
|
696
|
-
field: opts.field,
|
|
697
|
-
});
|
|
698
|
+
writeOutput(cmd, ipc.result);
|
|
698
699
|
} else {
|
|
699
|
-
log.info(
|
|
700
|
+
log.info(
|
|
701
|
+
ipc.result.message ??
|
|
702
|
+
`Stored credential ${opts.service}:${opts.field}`,
|
|
703
|
+
);
|
|
700
704
|
}
|
|
701
705
|
},
|
|
702
706
|
);
|
|
@@ -66,10 +66,13 @@ Modes:
|
|
|
66
66
|
managed — Uses platform-managed credentials (requires login to Vellum).
|
|
67
67
|
your-own — Uses your own Gemini or OpenAI API key depending on the configured model.
|
|
68
68
|
|
|
69
|
-
Supported models:
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
69
|
+
Supported models: pass a tier alias, the assistant resolves it to the
|
|
70
|
+
current model for that tier.
|
|
71
|
+
fast (default) quickest, good quality
|
|
72
|
+
quality higher fidelity, slower
|
|
73
|
+
openai OpenAI's model
|
|
74
|
+
A concrete model ID is also accepted; unknown values return an error
|
|
75
|
+
listing the currently available models.
|
|
73
76
|
|
|
74
77
|
Examples:
|
|
75
78
|
$ assistant image-generation generate --prompt "A sunset over the ocean"
|
|
@@ -113,8 +116,8 @@ Examples:
|
|
|
113
116
|
$ assistant image-generation generate --prompt "A mountain landscape at dawn"
|
|
114
117
|
$ assistant image-generation generate --prompt "Make it darker" --mode edit --source input.png
|
|
115
118
|
$ assistant image-generation generate --prompt "Logo variations" --variants 4 --output-dir ./logos
|
|
116
|
-
$ assistant image-generation generate --prompt "A robot" --model
|
|
117
|
-
$ assistant image-generation generate --prompt "A robot" --model
|
|
119
|
+
$ assistant image-generation generate --prompt "A robot" --model quality --json
|
|
120
|
+
$ assistant image-generation generate --prompt "A robot" --model openai --json`,
|
|
118
121
|
);
|
|
119
122
|
|
|
120
123
|
generate.action(async (opts) => {
|
|
@@ -166,7 +169,10 @@ Examples:
|
|
|
166
169
|
file.type !== "application/octet-stream"
|
|
167
170
|
? file.type
|
|
168
171
|
: mimeForExtension(filePath);
|
|
169
|
-
validImages.push({
|
|
172
|
+
validImages.push({
|
|
173
|
+
mimeType,
|
|
174
|
+
dataBase64: buffer.toString("base64"),
|
|
175
|
+
});
|
|
170
176
|
} catch (err) {
|
|
171
177
|
errors.push(
|
|
172
178
|
`Could not read ${filePath}: ${(err as Error).message}`,
|
|
@@ -191,7 +197,11 @@ Examples:
|
|
|
191
197
|
|
|
192
198
|
// Call daemon via IPC
|
|
193
199
|
const r = await cliIpcCall<{
|
|
194
|
-
images: Array<{
|
|
200
|
+
images: Array<{
|
|
201
|
+
mimeType: string;
|
|
202
|
+
dataBase64: string;
|
|
203
|
+
title?: string;
|
|
204
|
+
}>;
|
|
195
205
|
text?: string;
|
|
196
206
|
resolvedModel: string;
|
|
197
207
|
}>("image_generation_generate", {
|
|
@@ -204,7 +214,11 @@ Examples:
|
|
|
204
214
|
},
|
|
205
215
|
});
|
|
206
216
|
|
|
207
|
-
if (!r.ok)
|
|
217
|
+
if (!r.ok)
|
|
218
|
+
return exitFromIpcResult(
|
|
219
|
+
{ ok: false, error: r.error, statusCode: r.statusCode },
|
|
220
|
+
generate,
|
|
221
|
+
);
|
|
208
222
|
|
|
209
223
|
// Write images to disk (stays in CLI)
|
|
210
224
|
if (!existsSync(outputDir)) {
|
|
@@ -548,7 +548,7 @@ Examples:
|
|
|
548
548
|
.addHelpText(
|
|
549
549
|
"after",
|
|
550
550
|
`
|
|
551
|
-
Reads the home feed at
|
|
551
|
+
Reads the home feed at $VELLUM_WORKSPACE_DIR/data/home-feed.json — the
|
|
552
552
|
user's notification inbox. Items are ordered by priority then recency,
|
|
553
553
|
matching what the user sees in the macOS Home page. The home feed covers
|
|
554
554
|
background/async notifications mirrored from the unified pipeline;
|