@vellumai/assistant 0.8.10 → 0.8.11-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/bun.lock +62 -1
- package/docs/workspace-tools.md +196 -0
- package/examples/plugins/echo/README.md +3 -3
- package/knip.json +1 -0
- package/openapi.yaml +460 -128
- package/package.json +2 -1
- package/scripts/build-plugin-api.ts +299 -0
- package/src/__tests__/agent-loop-callsite-precedence.test.ts +7 -0
- package/src/__tests__/agent-loop-compaction-events.test.ts +197 -0
- package/src/__tests__/agent-loop-exit-reason.test.ts +93 -96
- package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +2 -0
- package/src/__tests__/agent-loop-output-hooks.test.ts +274 -1
- package/src/__tests__/agent-loop-override-profile.test.ts +3 -0
- package/src/__tests__/agent-loop-provider-error-recording.test.ts +4 -0
- package/src/__tests__/agent-loop-thinking.test.ts +4 -0
- package/src/__tests__/agent-loop.test.ts +578 -5
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +0 -1
- package/src/__tests__/approval-cascade.test.ts +1 -0
- package/src/__tests__/background-workers-disk-pressure.test.ts +0 -2
- package/src/__tests__/btw-routes.test.ts +0 -1
- package/src/__tests__/build-persisted-content.test.ts +75 -1
- package/src/__tests__/catalog-install-normalize.test.ts +141 -0
- package/src/__tests__/ces-startup-timeout.test.ts +60 -0
- package/src/__tests__/compaction-events.test.ts +1 -0
- package/src/__tests__/config-managed-gemini-defaults.test.ts +2 -46
- package/src/__tests__/context-overflow-reducer.test.ts +264 -124
- package/src/__tests__/context-window-manager-overflow-rung.test.ts +351 -0
- package/src/__tests__/conversation-abort-tool-results.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +13 -5
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +284 -455
- package/src/__tests__/conversation-agent-loop.test.ts +131 -551
- package/src/__tests__/conversation-app-control-instantiation.test.ts +13 -0
- package/src/__tests__/conversation-confirmation-signals.test.ts +1 -0
- package/src/__tests__/conversation-fork-crud.test.ts +259 -0
- package/src/__tests__/conversation-history-web-search.test.ts +1 -1
- package/src/__tests__/conversation-lifecycle.test.ts +257 -1
- package/src/__tests__/conversation-process-callsite.test.ts +1 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +38 -377
- package/src/__tests__/conversation-queue.test.ts +1 -39
- package/src/__tests__/conversation-runtime-assembly.test.ts +119 -8
- package/src/__tests__/conversation-skill-tools.test.ts +491 -5
- package/src/__tests__/conversation-slash-queue.test.ts +1 -1
- package/src/__tests__/conversation-slash-unknown.test.ts +1 -0
- package/src/__tests__/conversation-speed-override.test.ts +1 -0
- package/src/__tests__/conversation-store.test.ts +74 -0
- package/src/__tests__/conversation-surfaces-app-control.test.ts +4 -1
- package/src/__tests__/conversation-tool-setup-attribution.test.ts +323 -0
- package/src/__tests__/conversation-tool-setup-tools-disabled.test.ts +34 -0
- package/src/__tests__/conversation-workspace-cache-state.test.ts +1 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +1 -1
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +1 -0
- package/src/__tests__/corrected-target.test.ts +93 -0
- package/src/__tests__/credential-execution-feature-gates.test.ts +3 -5
- package/src/__tests__/credential-execution-tools.test.ts +23 -11
- package/src/__tests__/credential-security-invariants.test.ts +6 -1
- package/src/__tests__/db-schedule-syntax-migration.test.ts +80 -0
- package/src/__tests__/device-id.test.ts +70 -1
- package/src/__tests__/embedding-managed-proxy-selection.test.ts +6 -40
- package/src/__tests__/empty-response-hook.test.ts +242 -66
- package/src/__tests__/external-plugin-loader.test.ts +0 -31
- package/src/__tests__/get-skill-detail-audit.test.ts +43 -1
- package/src/__tests__/guardian-routing-invariants.test.ts +91 -0
- package/src/__tests__/history-repair-hook.test.ts +228 -3
- package/src/__tests__/host-app-control-proxy.test.ts +45 -0
- package/src/__tests__/host-browser-proxy.test.ts +254 -9
- package/src/__tests__/identity-routes.test.ts +1 -0
- package/src/__tests__/image-recovery-hook.test.ts +387 -0
- package/src/__tests__/injector-chain.test.ts +5 -4
- package/src/__tests__/injector-v3-suppression.test.ts +373 -47
- package/src/__tests__/intent-routing.test.ts +7 -0
- package/src/__tests__/memory-retrieval-hook.test.ts +117 -15
- package/src/__tests__/notification-decision-strategy.test.ts +3 -3
- package/src/__tests__/oauth-store.test.ts +0 -85
- package/src/__tests__/{context-overflow-policy.test.ts → overflow-policy.test.ts} +1 -1
- package/src/__tests__/parallel-tool.benchmark.test.ts +4 -0
- package/src/__tests__/persist-unsendable-image-downscale.test.ts +29 -9
- package/src/__tests__/persist-unsendable-image.test.ts +4 -4
- package/src/__tests__/persistence-secret-redaction.test.ts +78 -0
- package/src/__tests__/plugin-bootstrap.test.ts +82 -73
- package/src/__tests__/plugin-tool-contribution.test.ts +7 -4
- package/src/__tests__/plugin-types.test.ts +0 -8
- package/src/__tests__/provider-catalog-visibility.test.ts +1 -9
- package/src/__tests__/prune-old-conversations-job.test.ts +99 -0
- package/src/__tests__/registry.test.ts +240 -1
- package/src/__tests__/require-fresh-approval.test.ts +3 -0
- package/src/__tests__/schedule-routes.test.ts +116 -1
- package/src/__tests__/schedule-store.test.ts +28 -0
- package/src/__tests__/schedule-tools.test.ts +94 -1
- package/src/__tests__/server-history-render.test.ts +39 -0
- package/src/__tests__/skill-projection-feature-flag.test.ts +13 -0
- package/src/__tests__/skill-projection.benchmark.test.ts +25 -7
- package/src/__tests__/skills.test.ts +202 -0
- package/src/__tests__/slim-skill-category.test.ts +195 -0
- package/src/__tests__/strip-memory-injections.test.ts +33 -39
- package/src/__tests__/test-support/tool-invocation-seed.ts +79 -0
- package/src/__tests__/title-generate-hook.test.ts +9 -7
- package/src/__tests__/tool-audit-listener.test.ts +264 -1
- package/src/__tests__/tool-error-hook.test.ts +4 -3
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +1 -0
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +273 -0
- package/src/__tests__/tool-result-truncate-hook.test.ts +1 -0
- package/src/__tests__/tool-start-timestamp.test.ts +218 -0
- package/src/__tests__/tools-get-route.test.ts +202 -0
- package/src/__tests__/workspace-tool-loader.test.ts +319 -0
- package/src/__tests__/workspace-tools-watcher-flag.test.ts +70 -0
- package/src/agent/loop.ts +569 -319
- package/src/api/events/tool-result.ts +9 -0
- package/src/api/events/tool-use-start.ts +7 -0
- package/src/api/index.ts +10 -0
- package/src/api/responses/conversation-message.ts +135 -27
- package/src/api/responses/memory-v3-selection-log.ts +4 -4
- package/src/approvals/guardian-request-resolvers.ts +26 -0
- package/src/browser-session/backends/host-bridge.ts +29 -0
- package/src/browser-session/index.ts +1 -0
- package/src/browser-session/types.ts +5 -1
- package/src/cli/commands/__tests__/schedules.test.ts +62 -4
- package/src/cli/commands/__tests__/skills.test.ts +53 -0
- package/src/cli/commands/channel-verification-sessions.ts +6 -6
- package/src/cli/commands/inference-providers.ts +0 -8
- package/src/cli/commands/plugins.ts +2 -2
- package/src/cli/commands/schedules.ts +27 -4
- package/src/cli/commands/skills.ts +187 -146
- package/src/cli/commands/tools.ts +106 -0
- package/src/cli/lib/__tests__/install-from-github.test.ts +256 -328
- package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +6 -2
- package/src/cli/lib/__tests__/plugin-details.test.ts +10 -16
- package/src/cli/lib/__tests__/plugin-marketplace.test.ts +2 -2
- package/src/cli/lib/__tests__/search-plugins.test.ts +145 -240
- package/src/cli/lib/install-from-github.ts +187 -117
- package/src/cli/lib/plugin-catalog-cache.ts +9 -9
- package/src/cli/lib/plugin-details.ts +38 -68
- package/src/cli/lib/plugin-marketplace.ts +42 -14
- package/src/cli/lib/search-plugins.ts +29 -129
- package/src/cli/program.ts +2 -0
- package/src/config/bundled-skills/acp/SKILL.md +1 -0
- package/src/config/bundled-skills/app-builder/SKILL.md +1 -0
- package/src/config/bundled-skills/app-control/SKILL.md +1 -0
- package/src/config/bundled-skills/computer-use/SKILL.md +1 -0
- package/src/config/bundled-skills/contacts/SKILL.md +1 -0
- package/src/config/bundled-skills/document-editor/SKILL.md +1 -0
- package/src/config/bundled-skills/followups/SKILL.md +1 -0
- package/src/config/bundled-skills/image-studio/SKILL.md +1 -0
- package/src/config/bundled-skills/media-processing/SKILL.md +1 -0
- package/src/config/bundled-skills/messaging/SKILL.md +1 -0
- package/src/config/bundled-skills/phone-calls/SKILL.md +1 -0
- package/src/config/bundled-skills/playbooks/SKILL.md +1 -0
- package/src/config/bundled-skills/schedule/SKILL.md +1 -0
- package/src/config/bundled-skills/schedule/TOOLS.json +11 -3
- package/src/config/bundled-skills/sequences/SKILL.md +1 -0
- package/src/config/bundled-skills/settings/SKILL.md +1 -0
- package/src/config/bundled-skills/skill-management/SKILL.md +101 -1
- package/src/config/bundled-skills/subagent/SKILL.md +1 -0
- package/src/config/bundled-skills/transcribe/SKILL.md +1 -0
- package/src/config/env-registry.ts +23 -0
- package/src/config/feature-flag-registry.json +17 -81
- package/src/config/loader.ts +5 -22
- package/src/config/schema.ts +2 -0
- package/src/config/schemas/__tests__/compaction-logs.test.ts +56 -0
- package/src/config/schemas/__tests__/memory-v2.test.ts +0 -1
- package/src/config/schemas/__tests__/memory-v3.test.ts +61 -1
- package/src/config/schemas/compaction-logs.ts +79 -0
- package/src/config/schemas/memory-v2.ts +0 -8
- package/src/config/schemas/memory-v3.ts +104 -33
- package/src/config/seed-inference-profiles.ts +1 -1
- package/src/config/skills.ts +117 -47
- package/src/context/compactor.ts +11 -0
- package/src/context/strip-injections.ts +38 -4
- package/src/credential-execution/feature-gates.ts +0 -21
- package/src/credential-execution/startup-timeout.ts +32 -4
- package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +18 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +140 -91
- package/src/daemon/conversation-agent-loop.ts +123 -658
- package/src/daemon/conversation-error.ts +6 -33
- package/src/daemon/conversation-lifecycle.ts +1 -1
- package/src/daemon/conversation-runtime-assembly.ts +183 -22
- package/src/daemon/conversation-skill-tools.ts +137 -8
- package/src/daemon/conversation-slash.ts +0 -14
- package/src/daemon/conversation-store.ts +2 -19
- package/src/daemon/conversation-tool-setup.ts +87 -1
- package/src/daemon/conversation.ts +119 -50
- package/src/daemon/external-plugins-bootstrap.ts +36 -95
- package/src/daemon/handlers/config-channels.ts +11 -2
- package/src/daemon/handlers/shared.ts +9 -1
- package/src/daemon/handlers/skills.ts +10 -4
- package/src/daemon/host-app-control-proxy.ts +72 -57
- package/src/daemon/host-browser-proxy.ts +117 -22
- package/src/daemon/lifecycle.ts +34 -5
- package/src/daemon/message-protocol.ts +0 -7
- package/src/daemon/message-types/schedules.ts +1 -0
- package/src/daemon/message-types/skills.ts +17 -0
- package/src/daemon/providers-setup.ts +3 -0
- package/src/daemon/server.ts +3 -3
- package/src/daemon/tool-setup-types.ts +9 -3
- package/src/daemon/trust-context.ts +23 -0
- package/src/daemon/workspace-tools-watcher.ts +324 -0
- package/src/events/tool-audit-listener.ts +78 -16
- package/src/events/tool-metrics-listener.ts +2 -5
- package/src/memory/__tests__/compaction-log-writer-clickhouse.test.ts +227 -0
- package/src/memory/__tests__/conversation-queries.test.ts +176 -0
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +20 -32
- package/src/memory/compaction-log-writer-clickhouse.ts +418 -0
- package/src/memory/conversation-crud.ts +134 -3
- package/src/memory/conversation-queries.ts +64 -7
- package/src/memory/db-init.ts +14 -0
- package/src/memory/embedding-backend.test.ts +130 -1
- package/src/memory/embedding-backend.ts +79 -106
- package/src/memory/embedding-gemini.ts +5 -0
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +12 -0
- package/src/memory/graph/__tests__/handle-remember-v2.test.ts +19 -0
- package/src/memory/graph/conversation-graph-memory.ts +36 -25
- package/src/memory/graph/tool-handlers.ts +3 -0
- package/src/memory/job-handlers/cleanup.ts +3 -1
- package/src/memory/jobs-store.ts +0 -28
- package/src/memory/jobs-worker.ts +10 -22
- package/src/memory/memory-marker.ts +29 -0
- package/src/memory/memory-retrospective-startup-cleanup.ts +1 -1
- package/src/memory/migrations/268-add-memory-v3-selections.ts +6 -0
- package/src/memory/migrations/270-schedule-description.ts +36 -0
- package/src/memory/migrations/275-tool-invocations-add-skill-id.test.ts +81 -0
- package/src/memory/migrations/275-tool-invocations-add-skill-id.ts +20 -0
- package/src/memory/migrations/276-tool-invocations-created-at-id-index.test.ts +68 -0
- package/src/memory/migrations/276-tool-invocations-created-at-id-index.ts +20 -0
- package/src/memory/migrations/277-add-memory-v3-ever-injected.ts +29 -0
- package/src/memory/migrations/278-tool-invocations-telemetry-columns.test.ts +96 -0
- package/src/memory/migrations/278-tool-invocations-telemetry-columns.ts +39 -0
- package/src/memory/migrations/279-create-skill-loaded-events.test.ts +84 -0
- package/src/memory/migrations/279-create-skill-loaded-events.ts +26 -0
- package/src/memory/migrations/280-conversations-surfaced-at.test.ts +88 -0
- package/src/memory/migrations/280-conversations-surfaced-at.ts +24 -0
- package/src/memory/migrations/index.ts +10 -0
- package/src/memory/migrations/registry.ts +8 -0
- package/src/memory/schema/conversations.ts +16 -0
- package/src/memory/schema/infrastructure.ts +26 -0
- package/src/memory/skill-loaded-events-store.test.ts +160 -0
- package/src/memory/skill-loaded-events-store.ts +95 -0
- package/src/memory/tool-executed-events-store.test.ts +219 -0
- package/src/memory/tool-executed-events-store.ts +102 -0
- package/src/memory/tool-usage-store.ts +15 -3
- package/src/memory/v2/__tests__/consolidation-job.test.ts +117 -12
- package/src/memory/v2/__tests__/consolidation-prompt-flag-gating-guard.test.ts +189 -0
- package/src/memory/v2/__tests__/injected-block-slugs.test.ts +90 -0
- package/src/memory/v2/__tests__/page-store.test.ts +33 -0
- package/src/memory/v2/__tests__/prompts-consolidation.test.ts +88 -15
- package/src/memory/v2/activation-store.ts +50 -1
- package/src/memory/v2/consolidation-job.ts +113 -29
- package/src/memory/v2/injected-block-slugs.ts +79 -0
- package/src/memory/v2/injection.ts +6 -1
- package/src/memory/v2/prompts/consolidation.ts +414 -13
- package/src/memory/v2/router.ts +2 -28
- package/src/memory/v2/static-context.ts +1 -1
- package/src/memory/v2/types.ts +16 -0
- package/src/notifications/__tests__/copy-composer.test.ts +244 -0
- package/src/notifications/access-request-copy.ts +298 -0
- package/src/notifications/adapters/slack.ts +3 -3
- package/src/notifications/adapters/telegram.ts +2 -1
- package/src/notifications/copy-composer.ts +49 -267
- package/src/notifications/decision-engine.ts +16 -35
- package/src/notifications/home-feed-side-effect.ts +1 -6
- package/src/oauth/oauth-store.ts +0 -9
- package/src/permissions/checker.test.ts +83 -1
- package/src/permissions/checker.ts +25 -2
- package/src/permissions/gateway-threshold-reader.test.ts +182 -0
- package/src/permissions/gateway-threshold-reader.ts +80 -0
- package/src/platform/client.ts +1 -3
- package/src/platform/feature-gate.ts +3 -12
- package/src/plugin-api/constants.ts +4 -2
- package/src/plugin-api/index.ts +63 -11
- package/src/plugin-api/types.ts +236 -71
- package/src/plugins/defaults/compaction/compact.ts +66 -2
- package/src/plugins/defaults/compaction/context-overflow-reducer.ts +240 -32
- package/src/plugins/defaults/compaction/corrected-target.ts +53 -0
- package/src/{daemon/context-overflow-policy.ts → plugins/defaults/compaction/overflow-policy.ts} +1 -1
- package/src/plugins/defaults/compaction/window-manager.ts +303 -1
- package/src/plugins/defaults/empty-response/hooks/post-model-call.ts +173 -0
- package/src/plugins/defaults/empty-response/hooks/stop.ts +11 -115
- package/src/plugins/defaults/empty-response/nudge-state-store.ts +46 -0
- package/src/plugins/defaults/history-repair/hooks/post-model-call.ts +50 -0
- package/src/plugins/defaults/history-repair/hooks/stop.ts +22 -0
- package/src/plugins/defaults/history-repair/repair-state-store.ts +51 -0
- package/src/plugins/defaults/history-repair/terminal.ts +39 -2
- package/src/plugins/defaults/image-recovery/detect.ts +25 -0
- package/src/plugins/defaults/image-recovery/hooks/post-model-call.ts +73 -0
- package/src/plugins/defaults/image-recovery/hooks/stop.ts +22 -0
- package/src/plugins/defaults/image-recovery/image-recovery-state-store.ts +48 -0
- package/src/plugins/defaults/image-recovery/package.json +14 -0
- package/src/{daemon/persist-unsendable-image.ts → plugins/defaults/image-recovery/recover.ts} +67 -14
- package/src/plugins/defaults/index.ts +71 -5
- package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +76 -112
- package/src/plugins/defaults/memory-retrieval/hooks/{user-prompt-submit-temp.ts → user-prompt-submit.ts} +83 -74
- package/src/plugins/defaults/memory-retrieval/injector-chain.ts +14 -8
- package/src/plugins/defaults/memory-retrieval/injectors.ts +2 -18
- package/src/plugins/defaults/memory-retrieval/package.json +14 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/carry-integration.test.ts +1157 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/injection.test.ts +683 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/live-integration.test.ts +161 -140
- package/src/plugins/defaults/memory-v3-shadow/__tests__/maintain-job.test.ts +160 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/orchestrate.test.ts +335 -316
- package/src/plugins/defaults/memory-v3-shadow/__tests__/pool-select.test.ts +145 -53
- package/src/plugins/defaults/memory-v3-shadow/__tests__/render-injection.test.ts +38 -1
- package/src/plugins/defaults/memory-v3-shadow/__tests__/selection-log-store.test.ts +18 -8
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-integration.test.ts +112 -71
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +192 -51
- package/src/plugins/defaults/memory-v3-shadow/__tests__/types.test.ts +4 -16
- package/src/plugins/defaults/memory-v3-shadow/card.test.ts +173 -0
- package/src/plugins/defaults/memory-v3-shadow/card.ts +116 -0
- package/src/plugins/defaults/memory-v3-shadow/core-set.test.ts +104 -0
- package/src/plugins/defaults/memory-v3-shadow/core-set.ts +59 -0
- package/src/plugins/defaults/memory-v3-shadow/ever-injected-store.test.ts +305 -0
- package/src/plugins/defaults/memory-v3-shadow/ever-injected-store.ts +278 -0
- package/src/plugins/defaults/memory-v3-shadow/hot-set.test.ts +138 -0
- package/src/plugins/defaults/memory-v3-shadow/hot-set.ts +85 -0
- package/src/plugins/defaults/memory-v3-shadow/injector.ts +331 -24
- package/src/plugins/defaults/memory-v3-shadow/maintain-job.ts +119 -13
- package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +169 -114
- package/src/plugins/defaults/memory-v3-shadow/page-content.ts +47 -16
- package/src/plugins/defaults/memory-v3-shadow/pool-select.ts +144 -66
- package/src/plugins/defaults/memory-v3-shadow/prune.test.ts +758 -0
- package/src/plugins/defaults/memory-v3-shadow/prune.ts +471 -0
- package/src/plugins/defaults/memory-v3-shadow/render-injection.ts +68 -16
- package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +19 -12
- package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +96 -43
- package/src/plugins/defaults/memory-v3-shadow/types.ts +34 -17
- package/src/plugins/defaults/title-generate/hooks/stop.ts +9 -11
- package/src/plugins/pipeline.ts +8 -5
- package/src/plugins/types.ts +5 -51
- package/src/providers/cache-control.ts +26 -0
- package/src/providers/inference/__tests__/base-url-route-validation.test.ts +1 -2
- package/src/providers/model-catalog.ts +13 -1
- package/src/providers/openai/__tests__/tool-choice-mapping.test.ts +147 -0
- package/src/providers/openai/chat-completions-provider.ts +46 -0
- package/src/providers/openai/responses-provider.ts +45 -0
- package/src/providers/registry.ts +0 -8
- package/src/runtime/__tests__/agent-wake.test.ts +0 -1
- package/src/runtime/agent-wake.ts +13 -0
- package/src/runtime/routes/__tests__/acp-routes.test.ts +151 -0
- package/src/runtime/routes/__tests__/consolidation-routes.test.ts +12 -50
- package/src/runtime/routes/__tests__/conversation-surface-routes.test.ts +322 -0
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +0 -62
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +31 -11
- package/src/runtime/routes/acp-routes.test.ts +106 -0
- package/src/runtime/routes/acp-routes.ts +248 -2
- package/src/runtime/routes/browser-tabs-routes.ts +1 -1
- package/src/runtime/routes/channel-verification-routes.ts +14 -5
- package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +0 -14
- package/src/runtime/routes/consolidation-routes.ts +6 -82
- package/src/runtime/routes/conversation-list-routes.ts +6 -0
- package/src/runtime/routes/conversation-management-routes.ts +71 -0
- package/src/runtime/routes/identity-routes.ts +8 -0
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +33 -34
- package/src/runtime/routes/inference-provider-connection-routes.ts +0 -45
- package/src/runtime/routes/plugins-routes.ts +34 -45
- package/src/runtime/routes/schedule-routes.ts +43 -5
- package/src/runtime/routes/settings-routes.ts +140 -15
- package/src/runtime/routes/skills-routes.ts +18 -6
- package/src/runtime/services/__tests__/conversation-serializer.test.ts +140 -0
- package/src/runtime/services/conversation-serializer.ts +38 -1
- package/src/runtime/verification-outbound-actions.ts +147 -2
- package/src/runtime/verification-templates.ts +29 -3
- package/src/schedule/schedule-store.ts +19 -0
- package/src/skills/catalog-install.ts +77 -13
- package/src/tasks/task-scheduler.ts +1 -0
- package/src/telemetry/types.ts +66 -1
- package/src/telemetry/usage-telemetry-reporter.test.ts +542 -13
- package/src/telemetry/usage-telemetry-reporter.ts +213 -20
- package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +49 -2
- package/src/tools/browser/__tests__/browser-status.test.ts +29 -5
- package/src/tools/browser/browser-execution.ts +27 -9
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +380 -4
- package/src/tools/browser/cdp-client/__tests__/host-bridge-cdp-client.test.ts +107 -0
- package/src/tools/browser/cdp-client/__tests__/types.test.ts +6 -1
- package/src/tools/browser/cdp-client/factory.ts +217 -17
- package/src/tools/browser/cdp-client/host-bridge-cdp-client.ts +67 -0
- package/src/tools/browser/cdp-client/types.ts +22 -2
- package/src/tools/credential-execution/make-authenticated-request.ts +2 -1
- package/src/tools/credential-execution/manage-secure-command-tool.ts +169 -164
- package/src/tools/credential-execution/run-authenticated-command.ts +2 -1
- package/src/tools/executor.ts +39 -7
- package/src/tools/registry.ts +387 -5
- package/src/tools/schedule/create.ts +16 -0
- package/src/tools/schedule/list.ts +12 -4
- package/src/tools/schedule/update.ts +12 -0
- package/src/tools/skills/load.ts +11 -6
- package/src/tools/terminal/safe-env.ts +2 -0
- package/src/tools/types.ts +65 -9
- package/src/tools/workspace-tools/loader.ts +673 -0
- package/src/usage/attribution.ts +28 -0
- package/src/util/device-id.ts +17 -3
- package/src/util/platform.ts +16 -0
- package/tsconfig.plugin-api.json +13 -0
- package/src/__tests__/plugin-external-api.test.ts +0 -68
- package/src/__tests__/plugin-skill-contribution.test.ts +0 -355
- package/src/daemon/message-types/browser.ts +0 -10
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +0 -187
- package/src/plugins/defaults/memory-v3-shadow/__tests__/fixtures/eval-turns.json +0 -36
- package/src/plugins/defaults/memory-v3-shadow/__tests__/fixtures/live-turns.json +0 -37
- package/src/plugins/defaults/memory-v3-shadow/__tests__/working-set-eviction.test.ts +0 -106
- package/src/plugins/defaults/memory-v3-shadow/__tests__/working-set-skeleton.test.ts +0 -44
- package/src/plugins/defaults/memory-v3-shadow/working-set.ts +0 -91
- package/src/plugins/external-api.ts +0 -114
- package/src/plugins/plugin-skill-contributions.ts +0 -292
|
@@ -124,6 +124,15 @@ export const ToolResultEventSchema = z.object({
|
|
|
124
124
|
approvalReason: z.string().optional(),
|
|
125
125
|
riskThreshold: z.string().optional(),
|
|
126
126
|
activityMetadata: ToolActivityMetadataSchema.optional(),
|
|
127
|
+
/**
|
|
128
|
+
* Unix ms when the daemon finished executing the tool. Pairs with
|
|
129
|
+
* `ToolUseStartEvent.startedAt` so clients can render a final duration that
|
|
130
|
+
* stays on the daemon's clock, matching the live elapsed-time counter and
|
|
131
|
+
* avoiding skew between a server-stamped start and a browser-stamped end.
|
|
132
|
+
* Absent on streams from older daemons; clients fall back to their own
|
|
133
|
+
* receipt time.
|
|
134
|
+
*/
|
|
135
|
+
completedAt: z.number().optional(),
|
|
127
136
|
});
|
|
128
137
|
|
|
129
138
|
export type ToolResultEvent = z.infer<typeof ToolResultEventSchema>;
|
|
@@ -25,6 +25,13 @@ export const ToolUseStartEventSchema = z.object({
|
|
|
25
25
|
toolUseId: z.string().optional(),
|
|
26
26
|
messageId: z.string().optional(),
|
|
27
27
|
conversationId: z.string().optional(),
|
|
28
|
+
/**
|
|
29
|
+
* Unix ms when the daemon began executing the tool. Lets clients anchor a
|
|
30
|
+
* live elapsed-time counter to the server clock instead of the moment the
|
|
31
|
+
* event was received over SSE. Absent on streams from older daemons that
|
|
32
|
+
* pre-date this field; clients fall back to their own receipt time.
|
|
33
|
+
*/
|
|
34
|
+
startedAt: z.number().optional(),
|
|
28
35
|
});
|
|
29
36
|
|
|
30
37
|
export type ToolUseStartEvent = z.infer<typeof ToolUseStartEventSchema>;
|
package/src/api/index.ts
CHANGED
|
@@ -325,6 +325,8 @@ export {
|
|
|
325
325
|
DictationRequestSchema,
|
|
326
326
|
} from "./requests/dictation.js";
|
|
327
327
|
export {
|
|
328
|
+
type ConversationAttachmentBlock,
|
|
329
|
+
ConversationAttachmentBlockSchema,
|
|
328
330
|
type ConversationContentBlock,
|
|
329
331
|
ConversationContentBlockSchema,
|
|
330
332
|
type ConversationMessage,
|
|
@@ -339,6 +341,14 @@ export {
|
|
|
339
341
|
ConversationSlackMessageSchema,
|
|
340
342
|
type ConversationSubagentNotification,
|
|
341
343
|
ConversationSubagentNotificationSchema,
|
|
344
|
+
type ConversationSurfaceBlock,
|
|
345
|
+
ConversationSurfaceBlockSchema,
|
|
346
|
+
type ConversationTextBlock,
|
|
347
|
+
ConversationTextBlockSchema,
|
|
348
|
+
type ConversationThinkingBlock,
|
|
349
|
+
ConversationThinkingBlockSchema,
|
|
350
|
+
type ConversationToolUseBlock,
|
|
351
|
+
ConversationToolUseBlockSchema,
|
|
342
352
|
type PendingToolConfirmation,
|
|
343
353
|
PendingToolConfirmationSchema,
|
|
344
354
|
} from "./responses/conversation-message.js";
|
|
@@ -276,6 +276,53 @@ export type ConversationSlackMessage = z.infer<
|
|
|
276
276
|
// Content block (unified ordered content)
|
|
277
277
|
// ---------------------------------------------------------------------------
|
|
278
278
|
|
|
279
|
+
/** A run of assistant prose. */
|
|
280
|
+
export const ConversationTextBlockSchema = z.object({
|
|
281
|
+
type: z.literal("text"),
|
|
282
|
+
text: z.string(),
|
|
283
|
+
});
|
|
284
|
+
export type ConversationTextBlock = z.infer<typeof ConversationTextBlockSchema>;
|
|
285
|
+
|
|
286
|
+
/** A contiguous model reasoning run with its timing. */
|
|
287
|
+
export const ConversationThinkingBlockSchema = z.object({
|
|
288
|
+
type: z.literal("thinking"),
|
|
289
|
+
thinking: z.string(),
|
|
290
|
+
/** Unix ms when the model began emitting this reasoning block. */
|
|
291
|
+
startedAt: z.number().optional(),
|
|
292
|
+
/** Unix ms when this reasoning block completed. */
|
|
293
|
+
completedAt: z.number().optional(),
|
|
294
|
+
});
|
|
295
|
+
export type ConversationThinkingBlock = z.infer<
|
|
296
|
+
typeof ConversationThinkingBlockSchema
|
|
297
|
+
>;
|
|
298
|
+
|
|
299
|
+
/** A tool invocation carrying its paired result (`toolCall.result`). */
|
|
300
|
+
export const ConversationToolUseBlockSchema = z.object({
|
|
301
|
+
type: z.literal("tool_use"),
|
|
302
|
+
toolCall: ConversationMessageToolCallSchema,
|
|
303
|
+
});
|
|
304
|
+
export type ConversationToolUseBlock = z.infer<
|
|
305
|
+
typeof ConversationToolUseBlockSchema
|
|
306
|
+
>;
|
|
307
|
+
|
|
308
|
+
/** A vellum surface projection (no provider analog). */
|
|
309
|
+
export const ConversationSurfaceBlockSchema = z.object({
|
|
310
|
+
type: z.literal("surface"),
|
|
311
|
+
surface: ConversationMessageSurfaceSchema,
|
|
312
|
+
});
|
|
313
|
+
export type ConversationSurfaceBlock = z.infer<
|
|
314
|
+
typeof ConversationSurfaceBlockSchema
|
|
315
|
+
>;
|
|
316
|
+
|
|
317
|
+
/** A vellum attachment projection (no provider analog). */
|
|
318
|
+
export const ConversationAttachmentBlockSchema = z.object({
|
|
319
|
+
type: z.literal("attachment"),
|
|
320
|
+
attachment: ConversationMessageAttachmentSchema,
|
|
321
|
+
});
|
|
322
|
+
export type ConversationAttachmentBlock = z.infer<
|
|
323
|
+
typeof ConversationAttachmentBlockSchema
|
|
324
|
+
>;
|
|
325
|
+
|
|
279
326
|
/**
|
|
280
327
|
* A single ordered content block. `contentBlocks` is the unified, display-ready
|
|
281
328
|
* projection of a message's model-native content — one ordered tagged array so
|
|
@@ -300,20 +347,11 @@ export type ConversationSlackMessage = z.infer<
|
|
|
300
347
|
* it from the positional arrays, so it stays correct once those are retired.
|
|
301
348
|
*/
|
|
302
349
|
export const ConversationContentBlockSchema = z.discriminatedUnion("type", [
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
}),
|
|
309
|
-
z.object({
|
|
310
|
-
type: z.literal("surface"),
|
|
311
|
-
surface: ConversationMessageSurfaceSchema,
|
|
312
|
-
}),
|
|
313
|
-
z.object({
|
|
314
|
-
type: z.literal("attachment"),
|
|
315
|
-
attachment: ConversationMessageAttachmentSchema,
|
|
316
|
-
}),
|
|
350
|
+
ConversationTextBlockSchema,
|
|
351
|
+
ConversationThinkingBlockSchema,
|
|
352
|
+
ConversationToolUseBlockSchema,
|
|
353
|
+
ConversationSurfaceBlockSchema,
|
|
354
|
+
ConversationAttachmentBlockSchema,
|
|
317
355
|
]);
|
|
318
356
|
export type ConversationContentBlock = z.infer<
|
|
319
357
|
typeof ConversationContentBlockSchema
|
|
@@ -350,23 +388,93 @@ export const ConversationMessageSchema = z.object({
|
|
|
350
388
|
*/
|
|
351
389
|
role: z.enum(["user", "assistant"]),
|
|
352
390
|
/**
|
|
353
|
-
* Flat plain-text body (joined
|
|
354
|
-
* `textSegments`/`contentOrder` for clients
|
|
355
|
-
* arrays (web, CLI), but the legacy Swift
|
|
356
|
-
* directly and drops any history row missing it
|
|
357
|
-
* `HistoryReconstructionService` skips rows with empty text). The
|
|
358
|
-
* always emits it — do not remove without updating that client.
|
|
391
|
+
* @deprecated Superseded by `contentBlocks`. Flat plain-text body (joined
|
|
392
|
+
* text segments). Redundant with `textSegments`/`contentOrder` for clients
|
|
393
|
+
* that render from the positional arrays (web, CLI), but the legacy Swift
|
|
394
|
+
* macOS client reads `content` directly and drops any history row missing it
|
|
395
|
+
* (its `HistoryReconstructionService` skips rows with empty text). The
|
|
396
|
+
* serializer always emits it — do not remove without updating that client.
|
|
359
397
|
*/
|
|
360
|
-
content: z
|
|
398
|
+
content: z
|
|
399
|
+
.string()
|
|
400
|
+
.meta({
|
|
401
|
+
deprecated: true,
|
|
402
|
+
description:
|
|
403
|
+
"Deprecated: superseded by contentBlocks. Flat plain-text body (joined text segments).",
|
|
404
|
+
})
|
|
405
|
+
.optional(),
|
|
361
406
|
/** Display timestamp as an ISO-8601 string. */
|
|
362
407
|
timestamp: z.string(),
|
|
408
|
+
/**
|
|
409
|
+
* Flat list of attachment metadata for the row. Not yet supersedable by
|
|
410
|
+
* `contentBlocks`: `renderHistoryContent` emits an `attachment` content
|
|
411
|
+
* block only for file-block refs with an inline placement, so orphan rows
|
|
412
|
+
* (unmatched ids, count mismatch, no DB rows — see `alignAttachments`) ship
|
|
413
|
+
* here alone. Kept non-deprecated until `contentBlocks` reaches attachment
|
|
414
|
+
* parity, so clients that migrate off the positional arrays don't drop those
|
|
415
|
+
* chips.
|
|
416
|
+
*/
|
|
363
417
|
attachments: z.array(ConversationMessageAttachmentSchema),
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
418
|
+
/**
|
|
419
|
+
* @deprecated Superseded by `contentBlocks` (the `tool_use` variant). Flat
|
|
420
|
+
* list of tool calls for the row.
|
|
421
|
+
*/
|
|
422
|
+
toolCalls: z
|
|
423
|
+
.array(ConversationMessageToolCallSchema)
|
|
424
|
+
.meta({
|
|
425
|
+
deprecated: true,
|
|
426
|
+
description:
|
|
427
|
+
"Deprecated: superseded by contentBlocks (the tool_use variant). Flat list of tool calls.",
|
|
428
|
+
})
|
|
429
|
+
.optional(),
|
|
430
|
+
/**
|
|
431
|
+
* @deprecated Superseded by `contentBlocks` (the `surface` variant). Flat
|
|
432
|
+
* list of surfaces for the row.
|
|
433
|
+
*/
|
|
434
|
+
surfaces: z
|
|
435
|
+
.array(ConversationMessageSurfaceSchema)
|
|
436
|
+
.meta({
|
|
437
|
+
deprecated: true,
|
|
438
|
+
description:
|
|
439
|
+
"Deprecated: superseded by contentBlocks (the surface variant). Flat list of surfaces.",
|
|
440
|
+
})
|
|
441
|
+
.optional(),
|
|
442
|
+
/**
|
|
443
|
+
* @deprecated Superseded by `contentBlocks`. Text split by tool-call
|
|
444
|
+
* boundaries; positional sibling of `contentOrder`.
|
|
445
|
+
*/
|
|
446
|
+
textSegments: z
|
|
447
|
+
.array(z.string())
|
|
448
|
+
.meta({
|
|
449
|
+
deprecated: true,
|
|
450
|
+
description:
|
|
451
|
+
"Deprecated: superseded by contentBlocks. Text segments split by tool-call boundaries.",
|
|
452
|
+
})
|
|
453
|
+
.optional(),
|
|
454
|
+
/**
|
|
455
|
+
* @deprecated Superseded by `contentBlocks`. Reasoning text extracted from
|
|
456
|
+
* thinking blocks; positional sibling of `contentOrder`.
|
|
457
|
+
*/
|
|
458
|
+
thinkingSegments: z
|
|
459
|
+
.array(z.string())
|
|
460
|
+
.meta({
|
|
461
|
+
deprecated: true,
|
|
462
|
+
description:
|
|
463
|
+
"Deprecated: superseded by contentBlocks. Reasoning text extracted from thinking blocks.",
|
|
464
|
+
})
|
|
465
|
+
.optional(),
|
|
466
|
+
/**
|
|
467
|
+
* @deprecated Superseded by `contentBlocks`. Positional
|
|
468
|
+
* `"<type>:<index>"` content ordering (e.g. `"text:0"`, `"thinking:1"`).
|
|
469
|
+
*/
|
|
470
|
+
contentOrder: z
|
|
471
|
+
.array(z.string())
|
|
472
|
+
.meta({
|
|
473
|
+
deprecated: true,
|
|
474
|
+
description:
|
|
475
|
+
'Deprecated: superseded by contentBlocks. Positional "<type>:<index>" content ordering (e.g. "text:0", "thinking:1").',
|
|
476
|
+
})
|
|
477
|
+
.optional(),
|
|
370
478
|
/**
|
|
371
479
|
* Unified ordered content blocks — the display-ready projection of the
|
|
372
480
|
* row's model-native content. Ships alongside the positional
|
|
@@ -29,10 +29,10 @@ import { z } from "zod";
|
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
31
|
* One selected page in the v3 set. `source` is the lane that surfaced it —
|
|
32
|
-
* the daemon emits `
|
|
33
|
-
*
|
|
34
|
-
* pre-lane row) doesn't break parsing on
|
|
35
|
-
*
|
|
32
|
+
* the daemon emits `core`, `hot`, `needle`, `dense`, or `edge` (historical
|
|
33
|
+
* rows may carry retired labels) — but the schema stays a permissive string
|
|
34
|
+
* so a new lane label (or a historical pre-lane row) doesn't break parsing on
|
|
35
|
+
* the FE. `pinned` marks a page the turn was centrally about.
|
|
36
36
|
*/
|
|
37
37
|
export const MemoryV3SelectionRowSchema = z.object({
|
|
38
38
|
slug: z.string(),
|
|
@@ -196,6 +196,32 @@ const pendingInteractionResolver: GuardianRequestResolver = {
|
|
|
196
196
|
// resolveConfirmation() owns pendingInteractions deregistration.
|
|
197
197
|
const userDecision: UserDecision =
|
|
198
198
|
decision.action === "reject" ? "deny" : "allow";
|
|
199
|
+
|
|
200
|
+
// Route-owned confirmations (e.g. the ACP spawn/steer approval gate in
|
|
201
|
+
// acp-routes.ts) carry a `directResolve` and are NOT owned by any
|
|
202
|
+
// Conversation.prompter, so handleConfirmationResponse below would no-op
|
|
203
|
+
// and the caller would block until timeout. Resolve them directly, exactly
|
|
204
|
+
// as the POST /v1/confirm route does (see approval-routes.ts).
|
|
205
|
+
if (interaction.directResolve) {
|
|
206
|
+
pendingInteractions.resolve(
|
|
207
|
+
request.id,
|
|
208
|
+
userDecision === "allow" ? "approved" : "rejected",
|
|
209
|
+
);
|
|
210
|
+
interaction.directResolve(userDecision);
|
|
211
|
+
log.info(
|
|
212
|
+
{
|
|
213
|
+
event: "resolver_tool_approval_applied",
|
|
214
|
+
requestId: request.id,
|
|
215
|
+
action: decision.action,
|
|
216
|
+
conversationId: request.conversationId,
|
|
217
|
+
toolName: request.toolName,
|
|
218
|
+
directResolve: true,
|
|
219
|
+
},
|
|
220
|
+
"Tool approval resolver: direct-resolve interaction resolved",
|
|
221
|
+
);
|
|
222
|
+
return { ok: true, applied: true };
|
|
223
|
+
}
|
|
224
|
+
|
|
199
225
|
const conversation = findConversation(interaction.conversationId);
|
|
200
226
|
if (!conversation) {
|
|
201
227
|
return {
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { BrowserBackend, CdpCommand, CdpResult } from "../types.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Host-bridge backend for BrowserSessionManager. Wraps a caller-provided
|
|
5
|
+
* `sendCdp` transport that routes raw CDP commands through the daemon's
|
|
6
|
+
* HostBrowserProxy to the desktop client's SSE bridge, which executes
|
|
7
|
+
* them against the user's Chrome via its local remote-debugging port.
|
|
8
|
+
* Unlike the extension backend, the bridge has no `Vellum.*`
|
|
9
|
+
* pseudo-method support. The factory in
|
|
10
|
+
* `assistant/src/tools/browser/cdp-client/factory.ts` constructs one
|
|
11
|
+
* per tool invocation.
|
|
12
|
+
*/
|
|
13
|
+
export interface HostBridgeBackendDeps {
|
|
14
|
+
/** Sends a raw CDP command via the desktop SSE bridge and returns the CDP result. */
|
|
15
|
+
sendCdp(command: CdpCommand, signal?: AbortSignal): Promise<CdpResult>;
|
|
16
|
+
isAvailable(): boolean;
|
|
17
|
+
dispose(): void;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function createHostBridgeBackend(
|
|
21
|
+
deps: HostBridgeBackendDeps,
|
|
22
|
+
): BrowserBackend {
|
|
23
|
+
return {
|
|
24
|
+
kind: "host-bridge",
|
|
25
|
+
isAvailable: deps.isAvailable,
|
|
26
|
+
send: deps.sendCdp,
|
|
27
|
+
dispose: deps.dispose,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
@@ -151,7 +151,8 @@ describe("schedules list", () => {
|
|
|
151
151
|
retryCount: 0,
|
|
152
152
|
maxRetries: 3,
|
|
153
153
|
retryBackoffMs: 60_000,
|
|
154
|
-
description: "
|
|
154
|
+
description: "Authored heartbeat check",
|
|
155
|
+
cadenceDescription: "Every 30 minutes",
|
|
155
156
|
mode: "execute",
|
|
156
157
|
status: "active",
|
|
157
158
|
routingIntent: "all_channels",
|
|
@@ -175,6 +176,8 @@ describe("schedules list", () => {
|
|
|
175
176
|
expect.objectContaining({
|
|
176
177
|
id: "schedule-1",
|
|
177
178
|
name: "Heartbeat",
|
|
179
|
+
description: "Authored heartbeat check",
|
|
180
|
+
cadenceDescription: "Every 30 minutes",
|
|
178
181
|
}),
|
|
179
182
|
],
|
|
180
183
|
});
|
|
@@ -201,7 +204,8 @@ describe("schedules list", () => {
|
|
|
201
204
|
retryCount: 0,
|
|
202
205
|
maxRetries: 3,
|
|
203
206
|
retryBackoffMs: 60_000,
|
|
204
|
-
description: "
|
|
207
|
+
description: "Authored heartbeat check",
|
|
208
|
+
cadenceDescription: "Every 30 minutes",
|
|
205
209
|
mode: "execute",
|
|
206
210
|
status: "active",
|
|
207
211
|
routingIntent: "all_channels",
|
|
@@ -219,6 +223,7 @@ describe("schedules list", () => {
|
|
|
219
223
|
expect(logLines.join("\n")).toContain("ID");
|
|
220
224
|
expect(logLines.join("\n")).toContain("Heartbeat");
|
|
221
225
|
expect(logLines.join("\n")).toContain("Every 30 minutes (UTC)");
|
|
226
|
+
expect(logLines.join("\n")).not.toContain("Authored heartbeat check");
|
|
222
227
|
});
|
|
223
228
|
|
|
224
229
|
test("sets exit code on IPC failure", async () => {
|
|
@@ -376,6 +381,8 @@ describe("schedules create", () => {
|
|
|
376
381
|
"Heartbeat",
|
|
377
382
|
"--expression",
|
|
378
383
|
"*/30 * * * *",
|
|
384
|
+
"--description",
|
|
385
|
+
"Checks service heartbeat",
|
|
379
386
|
"--message",
|
|
380
387
|
"run heartbeat",
|
|
381
388
|
]);
|
|
@@ -388,6 +395,7 @@ describe("schedules create", () => {
|
|
|
388
395
|
body: {
|
|
389
396
|
name: "Heartbeat",
|
|
390
397
|
expression: "*/30 * * * *",
|
|
398
|
+
description: "Checks service heartbeat",
|
|
391
399
|
message: "run heartbeat",
|
|
392
400
|
enabled: true,
|
|
393
401
|
},
|
|
@@ -397,6 +405,39 @@ describe("schedules create", () => {
|
|
|
397
405
|
expect(logLines).toEqual(["Created schedule: Heartbeat"]);
|
|
398
406
|
});
|
|
399
407
|
|
|
408
|
+
test("requires a description", async () => {
|
|
409
|
+
const { exitCode } = await runCommand([
|
|
410
|
+
"schedules",
|
|
411
|
+
"create",
|
|
412
|
+
"Heartbeat",
|
|
413
|
+
"--expression",
|
|
414
|
+
"*/30 * * * *",
|
|
415
|
+
"--message",
|
|
416
|
+
"run heartbeat",
|
|
417
|
+
]);
|
|
418
|
+
|
|
419
|
+
expect(exitCode).not.toBe(0);
|
|
420
|
+
expect(ipcCalls).toEqual([]);
|
|
421
|
+
});
|
|
422
|
+
|
|
423
|
+
test("rejects an empty description", async () => {
|
|
424
|
+
const { exitCode } = await runCommand([
|
|
425
|
+
"schedules",
|
|
426
|
+
"create",
|
|
427
|
+
"Heartbeat",
|
|
428
|
+
"--expression",
|
|
429
|
+
"*/30 * * * *",
|
|
430
|
+
"--description",
|
|
431
|
+
" ",
|
|
432
|
+
"--message",
|
|
433
|
+
"run heartbeat",
|
|
434
|
+
]);
|
|
435
|
+
|
|
436
|
+
expect(exitCode).not.toBe(0);
|
|
437
|
+
expect(ipcCalls).toEqual([]);
|
|
438
|
+
expect(errorLines).toEqual(["description is required"]);
|
|
439
|
+
});
|
|
440
|
+
|
|
400
441
|
test("passes --timezone through to the request body", async () => {
|
|
401
442
|
mockIpcResult = { ok: true, result: { schedules: [] } };
|
|
402
443
|
|
|
@@ -408,6 +449,8 @@ describe("schedules create", () => {
|
|
|
408
449
|
"0 9 * * MON-FRI",
|
|
409
450
|
"--message",
|
|
410
451
|
"morning summary",
|
|
452
|
+
"--description",
|
|
453
|
+
"Summarizes weekday mornings",
|
|
411
454
|
"--timezone",
|
|
412
455
|
"America/New_York",
|
|
413
456
|
]);
|
|
@@ -421,6 +464,7 @@ describe("schedules create", () => {
|
|
|
421
464
|
name: "Morning",
|
|
422
465
|
expression: "0 9 * * MON-FRI",
|
|
423
466
|
message: "morning summary",
|
|
467
|
+
description: "Summarizes weekday mornings",
|
|
424
468
|
enabled: true,
|
|
425
469
|
timezone: "America/New_York",
|
|
426
470
|
},
|
|
@@ -440,6 +484,8 @@ describe("schedules create", () => {
|
|
|
440
484
|
"0 0 * * *",
|
|
441
485
|
"--message",
|
|
442
486
|
"placeholder",
|
|
487
|
+
"--description",
|
|
488
|
+
"Draft schedule",
|
|
443
489
|
"--no-enabled",
|
|
444
490
|
]);
|
|
445
491
|
|
|
@@ -452,6 +498,7 @@ describe("schedules create", () => {
|
|
|
452
498
|
name: "Drafted",
|
|
453
499
|
expression: "0 0 * * *",
|
|
454
500
|
message: "placeholder",
|
|
501
|
+
description: "Draft schedule",
|
|
455
502
|
enabled: false,
|
|
456
503
|
},
|
|
457
504
|
},
|
|
@@ -480,7 +527,8 @@ describe("schedules create", () => {
|
|
|
480
527
|
retryCount: 0,
|
|
481
528
|
maxRetries: 3,
|
|
482
529
|
retryBackoffMs: 60_000,
|
|
483
|
-
description: "
|
|
530
|
+
description: "Checks service heartbeat",
|
|
531
|
+
cadenceDescription: "Every 30 minutes",
|
|
484
532
|
mode: "execute",
|
|
485
533
|
status: "active",
|
|
486
534
|
routingIntent: "all_channels",
|
|
@@ -500,12 +548,20 @@ describe("schedules create", () => {
|
|
|
500
548
|
"*/30 * * * *",
|
|
501
549
|
"--message",
|
|
502
550
|
"run heartbeat",
|
|
551
|
+
"--description",
|
|
552
|
+
"Checks service heartbeat",
|
|
503
553
|
"--json",
|
|
504
554
|
]);
|
|
505
555
|
|
|
506
556
|
expect(exitCode).toBe(0);
|
|
507
557
|
expect(JSON.parse(stdout)).toEqual({
|
|
508
|
-
schedules: [
|
|
558
|
+
schedules: [
|
|
559
|
+
expect.objectContaining({
|
|
560
|
+
id: "new-schedule-id",
|
|
561
|
+
description: "Checks service heartbeat",
|
|
562
|
+
cadenceDescription: "Every 30 minutes",
|
|
563
|
+
}),
|
|
564
|
+
],
|
|
509
565
|
});
|
|
510
566
|
expect(logLines).toEqual([]);
|
|
511
567
|
});
|
|
@@ -524,6 +580,8 @@ describe("schedules create", () => {
|
|
|
524
580
|
"not-a-cron",
|
|
525
581
|
"--message",
|
|
526
582
|
"noop",
|
|
583
|
+
"--description",
|
|
584
|
+
"Invalid test schedule",
|
|
527
585
|
]);
|
|
528
586
|
|
|
529
587
|
expect(exitCode).toBe(10);
|
|
@@ -146,6 +146,59 @@ describe("skills list", () => {
|
|
|
146
146
|
).toEqual({});
|
|
147
147
|
});
|
|
148
148
|
|
|
149
|
+
test("--json derives source from owner for plugin-resident skills", async () => {
|
|
150
|
+
/**
|
|
151
|
+
* Plugin-resident skills are mapped to kind:bundled/origin:vellum, so
|
|
152
|
+
* their attribution lives on `owner`. The CLI must surface that as
|
|
153
|
+
* `plugin:<id>` instead of collapsing to "bundled".
|
|
154
|
+
*/
|
|
155
|
+
|
|
156
|
+
// GIVEN a plugin-resident skill (owner set) and a plain bundled skill
|
|
157
|
+
mockIpcResults = [
|
|
158
|
+
{
|
|
159
|
+
ok: true,
|
|
160
|
+
result: {
|
|
161
|
+
skills: [
|
|
162
|
+
{
|
|
163
|
+
id: "caveman",
|
|
164
|
+
name: "Caveman",
|
|
165
|
+
description: "Ultra-compressed communication mode",
|
|
166
|
+
origin: "vellum",
|
|
167
|
+
kind: "bundled",
|
|
168
|
+
status: "enabled",
|
|
169
|
+
owner: { kind: "plugin", id: "caveman" },
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
id: "weather",
|
|
173
|
+
name: "Weather",
|
|
174
|
+
description: "Get weather",
|
|
175
|
+
origin: "vellum",
|
|
176
|
+
kind: "bundled",
|
|
177
|
+
status: "enabled",
|
|
178
|
+
},
|
|
179
|
+
],
|
|
180
|
+
},
|
|
181
|
+
},
|
|
182
|
+
];
|
|
183
|
+
|
|
184
|
+
// WHEN listing skills as JSON
|
|
185
|
+
const { stdout } = await runCommand(["skills", "list", "--json"]);
|
|
186
|
+
|
|
187
|
+
// THEN the plugin skill's source is `plugin:<id>` and owner is preserved
|
|
188
|
+
const parsed = JSON.parse(stdout) as {
|
|
189
|
+
ok: boolean;
|
|
190
|
+
skills: Array<{ id: string; source: string; owner?: unknown }>;
|
|
191
|
+
};
|
|
192
|
+
const caveman = parsed.skills.find((s) => s.id === "caveman");
|
|
193
|
+
const weather = parsed.skills.find((s) => s.id === "weather");
|
|
194
|
+
expect(caveman?.source).toBe("plugin:caveman");
|
|
195
|
+
expect(caveman?.owner).toEqual({ kind: "plugin", id: "caveman" });
|
|
196
|
+
|
|
197
|
+
// AND a bundled skill with no owner keeps the "bundled" source label
|
|
198
|
+
expect(weather?.source).toBe("bundled");
|
|
199
|
+
expect(weather?.owner).toBeUndefined();
|
|
200
|
+
});
|
|
201
|
+
|
|
149
202
|
test("IPC failure sets exitCode 1", async () => {
|
|
150
203
|
mockIpcResults = [{ ok: false, error: "Connection refused" }];
|
|
151
204
|
|
|
@@ -79,7 +79,7 @@ export function registerChannelVerificationSessionsCommand(
|
|
|
79
79
|
"after",
|
|
80
80
|
`
|
|
81
81
|
Verification sessions are used to verify guardian bindings and trusted
|
|
82
|
-
contacts across channels (telegram, phone, slack). Three flows exist:
|
|
82
|
+
contacts across channels (telegram, phone, slack, email). Three flows exist:
|
|
83
83
|
|
|
84
84
|
1. Inbound challenge — the assistant generates a secret code and waits
|
|
85
85
|
for the guardian to send it back on the channel. Used when the
|
|
@@ -107,10 +107,10 @@ Examples:
|
|
|
107
107
|
cvs
|
|
108
108
|
.command("create")
|
|
109
109
|
.description("Create a new verification session")
|
|
110
|
-
.option("--channel <channel>", "Channel type (telegram, phone, slack)")
|
|
110
|
+
.option("--channel <channel>", "Channel type (telegram, phone, slack, email)")
|
|
111
111
|
.option(
|
|
112
112
|
"--destination <destination>",
|
|
113
|
-
"Destination address for outbound verification (handle, phone number, or
|
|
113
|
+
"Destination address for outbound verification (handle, phone number, user ID, or email address)",
|
|
114
114
|
)
|
|
115
115
|
.option("--rebind", "Replace existing guardian binding")
|
|
116
116
|
.option(
|
|
@@ -140,7 +140,7 @@ Routes between three creation modes based on the provided options:
|
|
|
140
140
|
|
|
141
141
|
2. Outbound: --channel <ch> --destination <dest>
|
|
142
142
|
Sends a verification code to the given destination. Supports telegram
|
|
143
|
-
(handle or chat ID), phone (E.164 number),
|
|
143
|
+
(handle or chat ID), phone (E.164 number), slack (user ID), and email.
|
|
144
144
|
Use --rebind to replace an existing guardian binding.
|
|
145
145
|
|
|
146
146
|
3. Inbound: --channel <ch> (no --destination)
|
|
@@ -240,7 +240,7 @@ Examples:
|
|
|
240
240
|
)
|
|
241
241
|
.requiredOption(
|
|
242
242
|
"--channel <channel>",
|
|
243
|
-
"Channel type (telegram, phone, slack)",
|
|
243
|
+
"Channel type (telegram, phone, slack, email)",
|
|
244
244
|
)
|
|
245
245
|
.option(
|
|
246
246
|
"--origin-conversation-id <id>",
|
|
@@ -290,7 +290,7 @@ Examples:
|
|
|
290
290
|
.description("Cancel all active verification sessions for a channel")
|
|
291
291
|
.requiredOption(
|
|
292
292
|
"--channel <channel>",
|
|
293
|
-
"Channel type (telegram, phone, slack)",
|
|
293
|
+
"Channel type (telegram, phone, slack, email)",
|
|
294
294
|
)
|
|
295
295
|
.addHelpText(
|
|
296
296
|
"after",
|
|
@@ -16,8 +16,6 @@
|
|
|
16
16
|
|
|
17
17
|
import type { Command } from "commander";
|
|
18
18
|
|
|
19
|
-
import { isAssistantFeatureFlagEnabled } from "../../config/assistant-feature-flags.js";
|
|
20
|
-
import { getConfig } from "../../config/loader.js";
|
|
21
19
|
import { cliIpcCall } from "../../ipc/cli-client.js";
|
|
22
20
|
import type { OAuth2Config } from "../../security/oauth2.js";
|
|
23
21
|
import { startOAuth2Flow } from "../../security/oauth2.js";
|
|
@@ -343,12 +341,6 @@ function attachLoginChatgptSubcommand(providers: Command): void {
|
|
|
343
341
|
.description("Authenticate with ChatGPT via browser OAuth flow")
|
|
344
342
|
.option("--json", "Output as JSON")
|
|
345
343
|
.action(async (opts: { json?: boolean }) => {
|
|
346
|
-
const config = getConfig();
|
|
347
|
-
if (!isAssistantFeatureFlagEnabled("chatgpt-subscription-auth", config)) {
|
|
348
|
-
writeCliError("This feature is not yet available", opts.json);
|
|
349
|
-
return;
|
|
350
|
-
}
|
|
351
|
-
|
|
352
344
|
try {
|
|
353
345
|
// Step 1: Run browser-based PKCE OAuth flow
|
|
354
346
|
process.stdout.write("Opening browser for ChatGPT authentication...\n");
|
|
@@ -55,7 +55,7 @@ Examples:
|
|
|
55
55
|
plugins
|
|
56
56
|
.command("install <name>")
|
|
57
57
|
.description(
|
|
58
|
-
"Install a plugin from
|
|
58
|
+
"Install a plugin from the curated plugins/marketplace.json catalog",
|
|
59
59
|
)
|
|
60
60
|
.option("--force", "Overwrite an existing install")
|
|
61
61
|
.option(
|
|
@@ -150,7 +150,7 @@ Examples:
|
|
|
150
150
|
plugins
|
|
151
151
|
.command("search <query>")
|
|
152
152
|
.description(
|
|
153
|
-
"Search
|
|
153
|
+
"Search the plugins/marketplace.json catalog for plugin names matching <query> (case-insensitive regex)",
|
|
154
154
|
)
|
|
155
155
|
.option("--json", "Emit machine-readable JSON instead of a table")
|
|
156
156
|
.action(async (query: string, opts: { json?: boolean }) => {
|