@vellumai/assistant 0.8.0 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +11 -0
- package/Dockerfile +5 -4
- package/README.md +2 -2
- package/docker-entrypoint.sh +16 -0
- package/eslint-rules/__tests__/cli-no-daemon-internals.test.ts +420 -0
- package/eslint-rules/cli-no-daemon-internals.js +283 -0
- package/eslint.config.mjs +12 -0
- package/knip.json +2 -1
- package/node_modules/@vellumai/skill-host-contracts/src/client.ts +10 -1
- package/openapi.yaml +4847 -1698
- package/package.json +3 -1
- package/scripts/generate-openapi.ts +52 -4
- package/scripts/sync-llm-catalog.ts +165 -0
- package/scripts/sync-web-search-catalog.ts +107 -0
- package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +169 -0
- package/src/__tests__/agent-loop-override-profile.test.ts +26 -1
- package/src/__tests__/anthropic-provider.test.ts +92 -2
- package/src/__tests__/app-control-flow.test.ts +7 -0
- package/src/__tests__/assistant-events-sse-shed.test.ts +232 -0
- package/src/__tests__/avatar-identity-sync.test.ts +87 -0
- package/src/__tests__/background-workers-disk-pressure.test.ts +11 -22
- package/src/__tests__/btw-routes.test.ts +1 -0
- package/src/__tests__/call-site-routing-provider.test.ts +172 -45
- package/src/__tests__/cancel-resolves-conversation-key.test.ts +44 -3
- package/src/__tests__/channel-policy.test.ts +12 -0
- package/src/__tests__/checker.test.ts +89 -0
- package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +35 -7
- package/src/__tests__/compact-event-conversation-id-guard.test.ts +33 -5
- package/src/__tests__/compaction-strip-metadata-clear.test.ts +26 -1
- package/src/__tests__/config-loader-backfill.test.ts +526 -102
- package/src/__tests__/config-loader-corrupt.test.ts +68 -0
- package/src/__tests__/config-loader-platform-defaults.test.ts +77 -23
- package/src/__tests__/config-schema-cmd.test.ts +63 -29
- package/src/__tests__/config-schema.test.ts +14 -3
- package/src/__tests__/config-set-platform-guard.test.ts +75 -152
- package/src/__tests__/config-set-route.test.ts +198 -0
- package/src/__tests__/config-watcher.test.ts +6 -0
- package/src/__tests__/contacts-tools.test.ts +51 -199
- package/src/__tests__/context-search-agent-protocol.test.ts +21 -2
- package/src/__tests__/context-search-agent-runner.test.ts +22 -138
- package/src/__tests__/context-search-conversations-source.test.ts +42 -16
- package/src/__tests__/context-search-fanout.test.ts +20 -157
- package/src/__tests__/context-search-memory-v2-source.test.ts +3 -3
- package/src/__tests__/context-search-types.test.ts +7 -2
- package/src/__tests__/context-window-manager.test.ts +389 -1
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -0
- package/src/__tests__/conversation-crud-inference-profile.test.ts +100 -0
- package/src/__tests__/conversation-error.test.ts +38 -0
- package/src/__tests__/conversation-fork-crud.test.ts +241 -1
- package/src/__tests__/conversation-inference-profile-route.test.ts +14 -14
- package/src/__tests__/conversation-init.benchmark.test.ts +1 -0
- package/src/__tests__/conversation-lifecycle.test.ts +124 -0
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +100 -1
- package/src/__tests__/conversation-process-callsite.test.ts +21 -1
- package/src/__tests__/conversation-runtime-assembly.test.ts +4 -4
- package/src/__tests__/conversation-slash-commands.test.ts +194 -2
- package/src/__tests__/conversation-surfaces-app-control.test.ts +323 -3
- package/src/__tests__/credential-security-invariants.test.ts +5 -6
- package/src/__tests__/daemon-credential-client.test.ts +56 -1
- package/src/__tests__/db-activation-state-fk-cascade.test.ts +132 -0
- package/src/__tests__/db-conversation-inference-profile-migration.test.ts +37 -0
- package/src/__tests__/db-memory-graph-event-date-repair.test.ts +43 -20
- package/src/__tests__/db-proxy-transaction.test.ts +206 -0
- package/src/__tests__/external-plugin-loader.test.ts +458 -0
- package/src/__tests__/filing-service.test.ts +23 -3
- package/src/__tests__/fixtures/mock-chrome-extension.ts +5 -0
- package/src/__tests__/gateway-only-guard.test.ts +0 -1
- package/src/__tests__/graph-extraction-event-date.test.ts +34 -0
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +0 -8
- package/src/__tests__/heartbeat-disk-pressure.test.ts +21 -8
- package/src/__tests__/heartbeat-service.test.ts +50 -233
- package/src/__tests__/history-repair.test.ts +89 -0
- package/src/__tests__/host-app-control-proxy.test.ts +109 -1
- package/src/__tests__/host-app-control-routes.test.ts +247 -1
- package/src/__tests__/host-browser-proxy.test.ts +416 -20
- package/src/__tests__/host-browser-routes.test.ts +325 -33
- package/src/__tests__/host-proxy-preactivation.test.ts +211 -0
- package/src/__tests__/inference-no-mode-boot-e2e.test.ts +246 -0
- package/src/__tests__/inference-profile-reaper.test.ts +154 -0
- package/src/__tests__/inference-profile-session-handler.test.ts +398 -0
- package/src/__tests__/inference-profile-session-ipc.test.ts +236 -0
- package/src/__tests__/inline-skill-load-permissions.test.ts +6 -1
- package/src/__tests__/install-skill-routing.test.ts +2 -2
- package/src/__tests__/lifecycle-memory-v2-seed.test.ts +15 -0
- package/src/__tests__/llm-callsite-catalog.test.ts +20 -1
- package/src/__tests__/llm-catalog-parity.test.ts +146 -0
- package/src/__tests__/llm-request-log-source-clickhouse.test.ts +188 -0
- package/src/__tests__/llm-request-log-source-factory.test.ts +124 -0
- package/src/__tests__/llm-resolver.test.ts +46 -0
- package/src/__tests__/managed-profile-guard.test.ts +131 -2
- package/src/__tests__/mcp-auth-routes.test.ts +1 -0
- package/src/__tests__/mcp-cli.test.ts +182 -220
- package/src/__tests__/mcp-health-check.test.ts +56 -27
- package/src/__tests__/memory-jobs-worker-lanes.test.ts +18 -11
- package/src/__tests__/message-complete-display-id.test.ts +175 -0
- package/src/__tests__/notification-platform-adapter.test.ts +229 -0
- package/src/__tests__/oauth-cli.test.ts +38 -2009
- package/src/__tests__/oauth-commands-routes.test.ts +711 -0
- package/src/__tests__/oauth-connect-routes.test.ts +174 -11
- package/src/__tests__/oauth-providers-routes.test.ts +14 -10
- package/src/__tests__/openai-responses-cutover-guard.test.ts +33 -12
- package/src/__tests__/openai-responses-provider.test.ts +17 -0
- package/src/__tests__/plugin-bootstrap.test.ts +31 -2
- package/src/__tests__/plugin-route-contribution.test.ts +31 -3
- package/src/__tests__/plugin-tool-contribution.test.ts +31 -3
- package/src/__tests__/plugin-types.test.ts +13 -11
- package/src/__tests__/process-message-background-slack.test.ts +46 -0
- package/src/__tests__/profile-entry-status.test.ts +43 -0
- package/src/__tests__/provider-managed-proxy-integration.test.ts +12 -4
- package/src/__tests__/provider-registry-ollama.test.ts +12 -4
- package/src/__tests__/provider-send-message-override-profile.test.ts +10 -4
- package/src/__tests__/relay-server.test.ts +118 -0
- package/src/__tests__/retry-thinking-tool-choice.test.ts +15 -0
- package/src/__tests__/schedule-retry.test.ts +56 -4
- package/src/__tests__/schedule-routes.test.ts +104 -0
- package/src/__tests__/scheduler-disk-pressure.test.ts +0 -4
- package/src/__tests__/scheduler-recurrence.test.ts +87 -34
- package/src/__tests__/scheduler-reuse-conversation.test.ts +161 -5
- package/src/__tests__/scheduler-wake.test.ts +0 -63
- package/src/__tests__/secret-allowlist.test.ts +1 -0
- package/src/__tests__/secret-routes-managed-proxy.test.ts +12 -4
- package/src/__tests__/shell-credential-ref.test.ts +95 -3
- package/src/__tests__/shell-tool-proxy-mode.test.ts +14 -0
- package/src/__tests__/skill-load-feature-flag.test.ts +1 -0
- package/src/__tests__/skill-load-tool.test.ts +2 -4
- package/src/__tests__/subagent-call-site-routing.test.ts +78 -16
- package/src/__tests__/suggestion-routes.test.ts +3 -3
- package/src/__tests__/sync-message-contract.test.ts +63 -0
- package/src/__tests__/task-scheduler.test.ts +88 -23
- package/src/__tests__/update-bulletin-job.test.ts +96 -193
- package/src/__tests__/usage-cli.test.ts +11 -73
- package/src/__tests__/user-plugin-loader.test.ts +145 -0
- package/src/__tests__/vercel-config.test.ts +168 -0
- package/src/__tests__/web-search-catalog-parity.test.ts +86 -0
- package/src/__tests__/web-search.test.ts +303 -2
- package/src/__tests__/workspace-migration-039-drop-legacy-llm-keys.test.ts +1 -21
- package/src/__tests__/workspace-migration-057-repair-stale-gemini-model-ids.test.ts +58 -0
- package/src/__tests__/workspace-migration-069-seed-onboarding-threads.test.ts +53 -20
- package/src/__tests__/workspace-migration-072-seed-reply-suggestion-callsite.test.ts +191 -0
- package/src/__tests__/workspace-migration-076-drop-services-inference-mode.test.ts +211 -0
- package/src/__tests__/workspace-migration-077-seed-memory-router-callsite.test.ts +174 -0
- package/src/__tests__/workspace-migration-079-home-feed-notification-only.test.ts +323 -0
- package/src/__tests__/workspace-migration-080-restrict-vercel-api-token-metadata.test.ts +299 -0
- package/src/__tests__/workspace-migration-081-backfill-bash-allowed-tools.test.ts +410 -0
- package/src/__tests__/workspace-migration-082-backfill-managed-profile-labels.test.ts +268 -0
- package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +3 -3
- package/src/__tests__/workspace-release-notes-feature-flag-guard.test.ts +115 -0
- package/src/acp/__tests__/helpers/which-stub.ts +4 -2
- package/src/acp/resolve-agent.test.ts +25 -0
- package/src/acp/resolve-agent.ts +13 -2
- package/src/acp/session-manager.ts +14 -0
- package/src/approvals/guardian-request-resolvers.ts +32 -87
- package/src/calls/relay-server.ts +35 -0
- package/src/calls/relay-setup-router.ts +36 -0
- package/src/calls/types.ts +1 -0
- package/src/calls/voice-session-bridge.ts +23 -4
- package/src/channels/config.ts +14 -1
- package/src/channels/types.ts +1 -0
- package/src/cli/AGENTS.md +164 -4
- package/src/cli/__tests__/notifications.test.ts +54 -0
- package/src/cli/commands/__tests__/avatar.test.ts +540 -0
- package/src/cli/commands/__tests__/backup.test.ts +236 -776
- package/src/cli/commands/__tests__/cache.test.ts +1 -1
- package/src/cli/commands/__tests__/changelog.test.ts +593 -0
- package/src/cli/commands/__tests__/channel-verification-sessions.test.ts +503 -0
- package/src/cli/commands/__tests__/conversations-import.test.ts +515 -0
- package/src/cli/commands/__tests__/domain-register.test.ts +140 -167
- package/src/cli/commands/__tests__/domain-status.test.ts +137 -76
- package/src/cli/commands/__tests__/email-attachment.test.ts +314 -337
- package/src/cli/commands/__tests__/email-core.test.ts +579 -0
- package/src/cli/commands/__tests__/image-generation.test.ts +87 -824
- package/src/cli/commands/__tests__/inference-send.test.ts +30 -266
- package/src/cli/commands/__tests__/inference-session.test.ts +423 -0
- package/src/cli/commands/__tests__/memory-v2.test.ts +81 -110
- package/src/cli/commands/__tests__/skills.test.ts +563 -0
- package/src/cli/commands/__tests__/status.test.ts +249 -0
- package/src/cli/commands/__tests__/stt.test.ts +320 -0
- package/src/cli/commands/__tests__/tts-synthesize.test.ts +4 -603
- package/src/cli/commands/__tests__/tts.test.ts +321 -0
- package/src/cli/commands/__tests__/webhooks.test.ts +86 -511
- package/src/cli/commands/attachment.ts +8 -3
- package/src/cli/commands/audit.ts +95 -64
- package/src/cli/commands/auth.ts +61 -58
- package/src/cli/commands/avatar.ts +276 -390
- package/src/cli/commands/backup.ts +409 -505
- package/src/cli/commands/bash.ts +9 -5
- package/src/cli/commands/browser.ts +28 -9
- package/src/cli/commands/cache.ts +9 -4
- package/src/cli/commands/changelog.ts +414 -0
- package/src/cli/commands/channel-verification-sessions.ts +238 -317
- package/src/cli/commands/clients.ts +8 -3
- package/src/cli/commands/completions.ts +9 -9
- package/src/cli/commands/config.ts +102 -72
- package/src/cli/commands/contacts.ts +575 -696
- package/src/cli/commands/conversations-defer.ts +17 -69
- package/src/cli/commands/conversations-import.ts +90 -253
- package/src/cli/commands/conversations.ts +346 -436
- package/src/cli/commands/credential-execution.ts +9 -6
- package/src/cli/commands/credentials.ts +456 -736
- package/src/cli/commands/domain.ts +128 -206
- package/src/cli/commands/email.ts +606 -794
- package/src/cli/commands/gateway.ts +8 -1
- package/src/cli/commands/image-generation.ts +157 -205
- package/src/cli/commands/inference-providers.ts +352 -0
- package/src/cli/commands/inference-session.ts +415 -0
- package/src/cli/commands/inference.ts +87 -65
- package/src/cli/commands/keys.ts +8 -3
- package/src/cli/commands/mcp.ts +103 -287
- package/src/cli/commands/memory-v2.ts +162 -516
- package/src/cli/commands/notifications.ts +33 -7
- package/src/cli/commands/oauth/apps.ts +292 -261
- package/src/cli/commands/oauth/connect.ts +176 -297
- package/src/cli/commands/oauth/disconnect.ts +16 -215
- package/src/cli/commands/oauth/index.ts +49 -45
- package/src/cli/commands/oauth/mode.ts +43 -199
- package/src/cli/commands/oauth/ping.ts +17 -125
- package/src/cli/commands/oauth/providers.ts +732 -921
- package/src/cli/commands/oauth/request.ts +60 -350
- package/src/cli/commands/oauth/shared.ts +11 -121
- package/src/cli/commands/oauth/status.ts +31 -121
- package/src/cli/commands/oauth/token.ts +13 -55
- package/src/cli/commands/pending.ts +19 -10
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +133 -183
- package/src/cli/commands/platform/__tests__/connect.test.ts +66 -181
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +71 -227
- package/src/cli/commands/platform/__tests__/status.test.ts +169 -287
- package/src/cli/commands/platform/connect.ts +16 -80
- package/src/cli/commands/platform/disconnect.ts +14 -112
- package/src/cli/commands/platform/index.ts +177 -246
- package/src/cli/commands/routes.ts +153 -336
- package/src/cli/commands/sequence.ts +316 -360
- package/src/cli/commands/skills.ts +449 -671
- package/src/cli/commands/status.ts +58 -37
- package/src/cli/commands/stt.ts +94 -262
- package/src/cli/commands/task.ts +14 -40
- package/src/cli/commands/trust.ts +8 -3
- package/src/cli/commands/tts.ts +162 -167
- package/src/cli/commands/ui.ts +35 -42
- package/src/cli/commands/usage.ts +188 -126
- package/src/cli/commands/watchers.ts +8 -3
- package/src/cli/commands/webhooks.ts +99 -193
- package/src/cli/lib/__tests__/register-command.test.ts +85 -0
- package/src/cli/lib/daemon-credential-client.ts +4 -5
- package/src/cli/lib/nested-value.ts +44 -0
- package/src/cli/lib/open-browser.ts +36 -0
- package/src/cli/lib/register-command.ts +19 -0
- package/src/cli/lib/time-ago.ts +34 -0
- package/src/cli/program.ts +2 -4
- package/src/cli/utils/__tests__/conversation-id.test.ts +66 -0
- package/src/cli/utils/__tests__/parse-duration.test.ts +49 -0
- package/src/cli/utils/conversation-id.ts +30 -0
- package/src/cli/utils/parse-duration.ts +41 -0
- package/src/config/acp-defaults.test.ts +5 -1
- package/src/config/acp-defaults.ts +11 -4
- package/src/config/bundled-skills/acp/TOOLS.json +2 -2
- package/src/config/bundled-skills/app-control/TOOLS.json +32 -0
- package/src/config/bundled-skills/contacts/SKILL.md +12 -45
- package/src/config/bundled-skills/contacts/TOOLS.json +0 -57
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +0 -12
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +0 -58
- package/src/config/bundled-tool-registry.ts +0 -2
- package/src/config/feature-flag-registry.json +16 -0
- package/src/config/llm-resolver.ts +16 -1
- package/src/config/loader.ts +76 -14
- package/src/config/raw-config-utils.ts +2 -30
- package/src/config/schema.ts +4 -0
- package/src/config/schemas/__tests__/memory-v2.test.ts +49 -0
- package/src/config/schemas/call-site-catalog.ts +29 -7
- package/src/config/schemas/llm-request-logs.ts +57 -0
- package/src/config/schemas/llm.ts +52 -2
- package/src/config/schemas/memory-retrospective.ts +48 -0
- package/src/config/schemas/memory-v2.ts +32 -1
- package/src/config/schemas/memory.ts +4 -0
- package/src/config/schemas/services.ts +15 -12
- package/src/config/seed-inference-profiles.ts +195 -134
- package/src/contacts/contact-store.ts +0 -61
- package/src/context/window-manager.ts +191 -5
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +79 -0
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +109 -4
- package/src/daemon/__tests__/daemon-skill-host.test.ts +10 -4
- package/src/daemon/approval-generators.ts +23 -29
- package/src/daemon/config-watcher.ts +2 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +24 -0
- package/src/daemon/conversation-agent-loop.ts +127 -97
- package/src/daemon/conversation-error.ts +21 -0
- package/src/daemon/conversation-lifecycle.ts +46 -5
- package/src/daemon/conversation-process.ts +36 -19
- package/src/daemon/conversation-runtime-assembly.ts +14 -5
- package/src/daemon/conversation-slash.ts +175 -23
- package/src/daemon/conversation-store.ts +17 -10
- package/src/daemon/conversation-surfaces.ts +76 -12
- package/src/daemon/conversation-tool-setup.ts +24 -14
- package/src/daemon/conversation.ts +48 -9
- package/src/daemon/external-plugins-bootstrap.ts +18 -8
- package/src/daemon/guardian-action-generators.ts +7 -22
- package/src/daemon/handlers/config-model.ts +8 -126
- package/src/daemon/handlers/config-slack-channel.ts +10 -7
- package/src/daemon/handlers/config-vercel.ts +3 -1
- package/src/daemon/handlers/skills.ts +84 -5
- package/src/daemon/history-repair.ts +33 -6
- package/src/daemon/host-app-control-proxy.ts +44 -19
- package/src/daemon/host-bash-proxy.ts +85 -158
- package/src/daemon/host-browser-proxy.ts +96 -35
- package/src/daemon/host-proxy-base.ts +13 -1
- package/src/daemon/host-proxy-preactivation.ts +25 -1
- package/src/daemon/identity-helpers.ts +19 -0
- package/src/daemon/lifecycle.ts +42 -43
- package/src/daemon/meet-host-supervisor.ts +15 -15
- package/src/daemon/memory-v2-startup.ts +9 -2
- package/src/daemon/message-protocol.ts +6 -0
- package/src/daemon/message-types/bookmarks.ts +18 -0
- package/src/daemon/message-types/conversations.ts +12 -9
- package/src/daemon/message-types/messages.ts +9 -1
- package/src/daemon/message-types/sync.ts +60 -0
- package/src/daemon/pkb-reminder-builder.test.ts +54 -13
- package/src/daemon/pkb-reminder-builder.ts +21 -7
- package/src/daemon/process-message.ts +56 -23
- package/src/daemon/server.ts +23 -18
- package/src/daemon/shutdown-handlers.ts +0 -2
- package/src/daemon/tool-setup-types.ts +9 -0
- package/src/daemon/tool-side-effects.ts +6 -4
- package/src/daemon/wake-target-adapter.ts +11 -0
- package/src/export/transcript-formatter.ts +61 -2
- package/src/filing/filing-service.ts +40 -53
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +359 -0
- package/src/heartbeat/heartbeat-run-store.ts +2 -1
- package/src/heartbeat/heartbeat-service.ts +148 -127
- package/src/home/__tests__/feed-types.test.ts +63 -131
- package/src/home/__tests__/feed-writer.test.ts +77 -278
- package/src/home/__tests__/post-connect-feed.test.ts +9 -12
- package/src/home/feed-types.ts +19 -73
- package/src/home/feed-writer.ts +25 -156
- package/src/home/post-connect-feed.ts +1 -3
- package/src/ipc/__tests__/cli-ipc.test.ts +2 -0
- package/src/ipc/__tests__/email-ipc.test.ts +506 -0
- package/src/ipc/__tests__/exit-helper.test.ts +104 -0
- package/src/ipc/__tests__/streaming-client.test.ts +237 -0
- package/src/ipc/__tests__/streaming-framing.test.ts +142 -0
- package/src/ipc/assistant-server.ts +55 -6
- package/src/ipc/cli-client.ts +370 -50
- package/src/ipc/routes/db-proxy-transaction.ts +151 -0
- package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +60 -0
- package/src/ipc/skill-routes/events.ts +30 -3
- package/src/live-voice/__tests__/live-voice-session-manager.test.ts +46 -0
- package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +1 -0
- package/src/live-voice/live-voice-session-manager.ts +11 -4
- package/src/live-voice/live-voice-session.ts +14 -6
- package/src/memory/__tests__/bookmark-crud.test.ts +258 -0
- package/src/memory/__tests__/bookmark-schema.test.ts +181 -0
- package/src/memory/__tests__/conversation-types.test.ts +36 -0
- package/src/memory/__tests__/find-most-recent-retrospective-for.test.ts +130 -0
- package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +177 -0
- package/src/memory/__tests__/memory-retrospective-job.test.ts +328 -0
- package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +213 -0
- package/src/memory/__tests__/memory-retrospective-trigger-check.test.ts +90 -0
- package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +69 -0
- package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +3 -0
- package/src/memory/bookmark-crud.ts +179 -0
- package/src/memory/context-search/__tests__/agent-runner-redaction.test.ts +31 -9
- package/src/memory/context-search/agent-protocol.ts +5 -1
- package/src/memory/context-search/agent-runner.ts +60 -85
- package/src/memory/context-search/limits.ts +1 -4
- package/src/memory/context-search/search.ts +23 -113
- package/src/memory/context-search/sources/conversations.ts +18 -6
- package/src/memory/context-search/sources/memory-v2.ts +39 -14
- package/src/memory/context-search/sources/memory.ts +7 -0
- package/src/memory/context-search/sources/workspace.ts +13 -10
- package/src/memory/context-search/types.ts +1 -1
- package/src/memory/conversation-bootstrap.ts +11 -0
- package/src/memory/conversation-crud.ts +312 -10
- package/src/memory/conversation-queries.ts +9 -5
- package/src/memory/conversation-title-service.ts +1 -0
- package/src/memory/conversation-types.ts +16 -0
- package/src/memory/db-init.ts +14 -0
- package/src/memory/embedding-backend.ts +2 -1
- package/src/memory/embedding-runtime-manager.ts +1 -2
- package/src/memory/graph/__tests__/remember-description.test.ts +55 -0
- package/src/memory/graph/conversation-graph-memory.ts +76 -5
- package/src/memory/graph/extraction.ts +4 -0
- package/src/memory/graph/graph-memory-state-store.ts +16 -3
- package/src/memory/graph/tool-handlers.ts +17 -7
- package/src/memory/graph/tools.ts +44 -5
- package/src/memory/indexer.ts +17 -0
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +13 -15
- package/src/memory/jobs/embed-concept-page.ts +45 -9
- package/src/memory/jobs-store.ts +51 -1
- package/src/memory/jobs-worker.ts +52 -3
- package/src/memory/llm-request-log-source-clickhouse.ts +317 -0
- package/src/memory/llm-request-log-source-local.ts +26 -0
- package/src/memory/llm-request-log-source.ts +97 -0
- package/src/memory/llm-request-log-store.ts +1 -1
- package/src/memory/memory-retrospective-constants.ts +13 -0
- package/src/memory/memory-retrospective-enqueue.ts +114 -0
- package/src/memory/memory-retrospective-job.ts +351 -0
- package/src/memory/memory-retrospective-startup-cleanup.ts +108 -0
- package/src/memory/memory-retrospective-state.ts +162 -0
- package/src/memory/memory-retrospective-trigger-check.ts +91 -0
- package/src/memory/memory-v2-activation-log-store.ts +49 -5
- package/src/memory/memory-v2-concept-frequency.ts +4 -0
- package/src/memory/message-content.ts +38 -1
- package/src/memory/migrations/227-add-conversation-inference-profile.ts +6 -1
- package/src/memory/migrations/228-rename-inference-profile-snake-case.ts +20 -7
- package/src/memory/migrations/229-delete-private-conversations.test.ts +70 -1
- package/src/memory/migrations/229-delete-private-conversations.ts +12 -0
- package/src/memory/migrations/231-repair-memory-graph-event-dates.ts +16 -2
- package/src/memory/migrations/240-conversation-inference-profile-session.ts +25 -0
- package/src/memory/migrations/241-activation-state-fk-cascade.ts +50 -0
- package/src/memory/migrations/242-message-bookmarks.ts +38 -0
- package/src/memory/migrations/243-provider-connections.ts +68 -0
- package/src/memory/migrations/244-provider-connection-status-label.ts +23 -0
- package/src/memory/migrations/245-memory-retrospective-state.ts +36 -0
- package/src/memory/migrations/246-backfill-provider-connection-label.ts +81 -0
- package/src/memory/migrations/__tests__/244-provider-connection-status-label.test.ts +84 -0
- package/src/memory/migrations/__tests__/245-memory-retrospective-state.test.ts +125 -0
- package/src/memory/migrations/__tests__/246-backfill-provider-connection-label.test.ts +192 -0
- package/src/memory/migrations/index.ts +7 -0
- package/src/memory/published-pages-store.ts +16 -0
- package/src/memory/schema/bookmarks.ts +38 -0
- package/src/memory/schema/conversations.ts +2 -0
- package/src/memory/schema/index.ts +2 -0
- package/src/memory/schema/inference.ts +29 -0
- package/src/memory/schema/memory-core.ts +9 -0
- package/src/memory/search/semantic.ts +1 -4
- package/src/memory/v2/__tests__/__snapshots__/prompts-router.test.ts.snap +27 -0
- package/src/memory/v2/__tests__/activation-store.test.ts +5 -5
- package/src/memory/v2/__tests__/activation.test.ts +11 -4
- package/src/memory/v2/__tests__/backfill-jobs.test.ts +38 -21
- package/src/memory/v2/__tests__/consolidation-job.test.ts +123 -135
- package/src/memory/v2/__tests__/edge-index.test.ts +1 -1
- package/src/memory/v2/__tests__/frontmatter-sweep.test.ts +111 -0
- package/src/memory/v2/__tests__/injection.test.ts +628 -10
- package/src/memory/v2/__tests__/migration.test.ts +7 -3
- package/src/memory/v2/__tests__/page-index.test.ts +277 -0
- package/src/memory/v2/__tests__/page-store.test.ts +14 -1
- package/src/memory/v2/__tests__/prompts-router.test.ts +257 -0
- package/src/memory/v2/__tests__/qdrant.test.ts +72 -0
- package/src/memory/v2/__tests__/reranker.test.ts +4 -4
- package/src/memory/v2/__tests__/router.test.ts +516 -0
- package/src/memory/v2/__tests__/sim.test.ts +45 -1
- package/src/memory/v2/__tests__/skill-store.test.ts +58 -3
- package/src/memory/v2/__tests__/static-context.test.ts +7 -22
- package/src/memory/v2/__tests__/sweep-job.test.ts +95 -0
- package/src/memory/v2/activation-store.ts +34 -5
- package/src/memory/v2/activation.ts +40 -27
- package/src/memory/v2/backfill-jobs.ts +17 -84
- package/src/memory/v2/consolidation-job.ts +85 -78
- package/src/memory/v2/frontmatter-sweep.ts +91 -0
- package/src/memory/v2/injection.ts +440 -109
- package/src/memory/v2/migration.ts +117 -20
- package/src/memory/v2/page-index.ts +191 -0
- package/src/memory/v2/page-store.ts +3 -0
- package/src/memory/v2/prompts/consolidation.ts +9 -7
- package/src/memory/v2/prompts/router.ts +192 -0
- package/src/memory/v2/qdrant.ts +100 -87
- package/src/memory/v2/reranker.ts +14 -7
- package/src/memory/v2/router.ts +322 -0
- package/src/memory/v2/sim.ts +25 -12
- package/src/memory/v2/skill-store.ts +118 -29
- package/src/memory/v2/static-context.ts +16 -9
- package/src/memory/v2/sweep-job.ts +122 -96
- package/src/memory/v2/types.ts +10 -6
- package/src/memory/validation.ts +13 -0
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +182 -0
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +199 -0
- package/src/notifications/__tests__/signal-registry.test.ts +17 -0
- package/src/notifications/adapters/platform.ts +171 -0
- package/src/notifications/conversation-pairing.ts +2 -2
- package/src/notifications/copy-composer.ts +15 -0
- package/src/notifications/destination-resolver.ts +21 -0
- package/src/notifications/emit-signal.ts +28 -1
- package/src/notifications/home-feed-side-effect.ts +111 -0
- package/src/notifications/signal.ts +5 -0
- package/src/permissions/checker.ts +12 -0
- package/src/permissions/ipc-risk-types.ts +2 -0
- package/src/plugin-api/index.ts +13 -0
- package/src/plugin-api/package.json +12 -0
- package/src/plugin-api/types.ts +62 -0
- package/src/plugins/defaults/injectors.ts +19 -3
- package/src/plugins/external-plugin-loader.ts +294 -0
- package/src/plugins/types.ts +46 -30
- package/src/plugins/user-loader.ts +64 -41
- package/src/proactive-artifact/job.test.ts +12 -4
- package/src/proactive-artifact/job.ts +4 -0
- package/src/proactive-artifact/trigger-state.test.ts +9 -0
- package/src/proactive-artifact/trigger-state.ts +4 -0
- package/src/prompts/__tests__/system-prompt.test.ts +105 -0
- package/src/prompts/system-prompt.ts +22 -1
- package/src/prompts/update-bulletin-job.ts +61 -73
- package/src/providers/__tests__/dispatch-connection-routing.test.ts +279 -0
- package/src/providers/__tests__/inference.test.ts +288 -0
- package/src/providers/__tests__/provider-env-vars.test.ts +6 -0
- package/src/providers/__tests__/provider-secret-catalog.test.ts +6 -0
- package/src/providers/__tests__/retry-callsite.test.ts +14 -32
- package/src/providers/__tests__/satellite-connection-routing.test.ts +510 -0
- package/src/providers/__tests__/search-provider-catalog.test.ts +80 -0
- package/src/providers/anthropic/client.ts +95 -26
- package/src/providers/call-site-routing.ts +94 -16
- package/src/providers/connection-resolution.ts +163 -0
- package/src/providers/inference/__tests__/connections-status-label.test.ts +250 -0
- package/src/providers/inference/adapter-factory.ts +173 -0
- package/src/providers/inference/auth.ts +112 -0
- package/src/providers/inference/backfill.ts +196 -0
- package/src/providers/inference/connections.ts +356 -0
- package/src/providers/inference/resolve-auth.ts +65 -0
- package/src/providers/model-catalog.ts +104 -6
- package/src/providers/openai/responses-provider.ts +4 -2
- package/src/providers/provider-env-vars.ts +17 -7
- package/src/providers/provider-secret-catalog.ts +49 -30
- package/src/providers/provider-send-message.ts +41 -20
- package/src/providers/registry.ts +143 -159
- package/src/providers/retry.ts +18 -10
- package/src/providers/search-provider-catalog.ts +121 -0
- package/src/runtime/AGENTS.md +18 -5
- package/src/runtime/__tests__/background-job-runner.test.ts +357 -0
- package/src/runtime/__tests__/pre-first-message-gate.test.ts +82 -0
- package/src/runtime/actor-trust-resolver.ts +32 -10
- package/src/runtime/agent-wake.ts +35 -6
- package/src/runtime/assistant-event-hub.ts +3 -85
- package/src/runtime/auth/route-policy.ts +303 -8
- package/src/runtime/auth/same-actor.ts +2 -0
- package/src/runtime/background-job-runner.ts +339 -0
- package/src/runtime/btw-sidechain.ts +1 -0
- package/src/runtime/http-router.ts +36 -1
- package/src/runtime/http-server.ts +31 -5
- package/src/runtime/http-types.ts +2 -0
- package/src/runtime/middleware/__tests__/request-logger.test.ts +162 -0
- package/src/runtime/middleware/request-logger.ts +62 -1
- package/src/runtime/pre-first-message-gate.ts +83 -0
- package/src/runtime/routes/__tests__/backup-routes.test.ts +8 -1
- package/src/runtime/routes/__tests__/bookmark-routes.test.ts +251 -0
- package/src/runtime/routes/__tests__/connection-routes-vs-cli-parity.test.ts +142 -0
- package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +315 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +189 -0
- package/src/runtime/routes/__tests__/home-feed-routes.test.ts +15 -136
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +736 -0
- package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +4 -4
- package/src/runtime/routes/__tests__/stt-routes.test.ts +5 -1
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +384 -0
- package/src/runtime/routes/__tests__/tts-routes.test.ts +6 -2
- package/src/runtime/routes/acp-routes.ts +10 -8
- package/src/runtime/routes/app-management-routes.ts +228 -3
- package/src/runtime/routes/approval-routes.ts +0 -18
- package/src/runtime/routes/audit-routes.ts +43 -0
- package/src/runtime/routes/auth-routes.ts +72 -0
- package/src/runtime/routes/avatar-routes.ts +273 -20
- package/src/runtime/routes/backup-routes.ts +406 -2
- package/src/runtime/routes/bookmark-routes.ts +154 -0
- package/src/runtime/routes/channel-verification-routes.ts +2 -1
- package/src/runtime/routes/contact-routes.ts +0 -160
- package/src/runtime/routes/conversation-cli-routes.ts +192 -0
- package/src/runtime/routes/conversation-management-routes.ts +30 -43
- package/src/runtime/routes/conversation-query-routes.ts +334 -86
- package/src/runtime/routes/conversation-routes.ts +31 -10
- package/src/runtime/routes/conversations-import-routes.ts +229 -0
- package/src/runtime/routes/credential-routes.ts +540 -0
- package/src/runtime/routes/debug-routes.ts +2 -2
- package/src/runtime/routes/document-pdf-renderer.ts +5 -1
- package/src/runtime/routes/domain-routes.ts +167 -0
- package/src/runtime/routes/email-routes.ts +603 -0
- package/src/runtime/routes/errors.ts +2 -2
- package/src/runtime/routes/events-routes.ts +192 -0
- package/src/runtime/routes/home-feed-routes.ts +6 -78
- package/src/runtime/routes/host-app-control-routes.ts +44 -2
- package/src/runtime/routes/host-browser-routes.ts +103 -22
- package/src/runtime/routes/http-adapter.ts +2 -0
- package/src/runtime/routes/identity-routes.ts +5 -0
- package/src/runtime/routes/image-generation-routes.ts +99 -0
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +137 -1
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +87 -7
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +156 -0
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +22 -4
- package/src/runtime/routes/index.ts +36 -0
- package/src/runtime/routes/inference-profile-session-handler.ts +312 -0
- package/src/runtime/routes/inference-profile-session-reaper.ts +98 -0
- package/src/runtime/routes/inference-profile-session-routes.ts +146 -0
- package/src/runtime/routes/inference-provider-connection-routes.ts +317 -0
- package/src/runtime/routes/inference-send-routes.ts +115 -0
- package/src/runtime/routes/integrations/twilio.ts +1 -0
- package/src/runtime/routes/mcp-auth-routes.ts +283 -9
- package/src/runtime/routes/memory-v2-routes.ts +13 -398
- package/src/runtime/routes/notification-routes.ts +2 -0
- package/src/runtime/routes/oauth-apps.ts +112 -7
- package/src/runtime/routes/oauth-commands-routes.ts +1007 -0
- package/src/runtime/routes/oauth-connect-routes.ts +67 -5
- package/src/runtime/routes/oauth-providers.ts +298 -8
- package/src/runtime/routes/platform-routes.ts +336 -0
- package/src/runtime/routes/playground/inject-failures.ts +2 -1
- package/src/runtime/routes/playground/reset-circuit.ts +2 -1
- package/src/runtime/routes/playground/state.ts +2 -1
- package/src/runtime/routes/publish-routes.ts +221 -0
- package/src/runtime/routes/schedule-routes.ts +82 -0
- package/src/runtime/routes/sequence-routes.ts +291 -0
- package/src/runtime/routes/settings-routes.ts +2 -10
- package/src/runtime/routes/skills-routes.ts +31 -1
- package/src/runtime/routes/stt-routes.ts +240 -3
- package/src/runtime/routes/surface-action-routes.ts +43 -7
- package/src/runtime/routes/tts-routes.ts +67 -0
- package/src/runtime/routes/types.ts +32 -0
- package/src/runtime/routes/user-routes-cli.ts +243 -0
- package/src/runtime/routes/webhook-routes.ts +165 -0
- package/src/runtime/sync/resource-sync-events.ts +25 -0
- package/src/runtime/sync/sync-publisher.test.ts +105 -0
- package/src/runtime/sync/sync-publisher.ts +21 -0
- package/src/schedule/scheduler.ts +200 -123
- package/src/security/__tests__/provider-key-env-fallback.test.ts +12 -6
- package/src/security/secret-patterns.ts +3 -0
- package/src/sequence/engine.ts +38 -40
- package/src/subagent/manager.ts +20 -15
- package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +206 -0
- package/src/tools/browser/browser-execution.ts +15 -4
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +174 -0
- package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +16 -13
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +24 -1
- package/src/tools/browser/cdp-client/factory.ts +66 -5
- package/src/tools/browser/runtime-check.ts +77 -0
- package/src/tools/memory/register.test.ts +3 -3
- package/src/tools/memory/register.ts +9 -1
- package/src/tools/network/__tests__/web-search.test.ts +156 -0
- package/src/tools/network/web-search.ts +280 -37
- package/src/tools/permission-checker.ts +13 -5
- package/src/tools/subagent/spawn.ts +3 -3
- package/src/tools/terminal/shell.ts +44 -0
- package/src/usage/attribution.ts +3 -2
- package/src/util/pricing.ts +86 -160
- package/src/watcher/__tests__/engine.test.ts +301 -0
- package/src/watcher/constants.ts +7 -0
- package/src/watcher/engine.ts +90 -90
- package/src/workspace/migrations/046-seed-conversation-starters-callsite.ts +6 -9
- package/src/workspace/migrations/054-seed-recall-callsite.ts +10 -1
- package/src/workspace/migrations/057-repair-stale-gemini-model-ids.ts +28 -4
- package/src/workspace/migrations/069-seed-onboarding-threads.ts +8 -2
- package/src/workspace/migrations/072-seed-reply-suggestion-callsite.ts +104 -0
- package/src/workspace/migrations/073-repair-recall-callsite-empty-profile.ts +93 -0
- package/src/workspace/migrations/074-drop-deprecated-secret-detection-keys.ts +117 -0
- package/src/workspace/migrations/075-memory-v2-bm25-b-default-reembed.ts +61 -0
- package/src/workspace/migrations/076-drop-services-inference-mode.ts +62 -0
- package/src/workspace/migrations/077-seed-memory-router-callsite.ts +89 -0
- package/src/workspace/migrations/078-release-notes-tavily-web-search.ts +66 -0
- package/src/workspace/migrations/079-home-feed-notification-only.ts +197 -0
- package/src/workspace/migrations/080-restrict-vercel-api-token-metadata.ts +182 -0
- package/src/workspace/migrations/081-backfill-bash-allowed-tools-for-injection-credentials.ts +160 -0
- package/src/workspace/migrations/082-backfill-managed-profile-labels.ts +154 -0
- package/src/workspace/migrations/registry.ts +22 -0
- package/src/workspace/migrations/runner.ts +13 -2
- package/src/workspace/migrations/types.ts +13 -3
- package/src/workspace/provider-commit-message-generator.ts +3 -2
- package/src/__tests__/context-search-pkb-source.test.ts +0 -498
- package/src/__tests__/credentials-cli.test.ts +0 -1225
- package/src/__tests__/memory-admin-recall.test.ts +0 -213
- package/src/approvals/__tests__/guardian-feed-event.test.ts +0 -303
- package/src/cli/commands/__tests__/email-download.test.ts +0 -260
- package/src/cli/commands/__tests__/email-list.test.ts +0 -216
- package/src/cli/commands/__tests__/email-register.test.ts +0 -186
- package/src/cli/commands/__tests__/email-send.test.ts +0 -416
- package/src/cli/commands/__tests__/email-status.test.ts +0 -185
- package/src/cli/commands/__tests__/email-unregister.test.ts +0 -168
- package/src/cli/commands/__tests__/routes.test.ts +0 -562
- package/src/cli/commands/__tests__/stt-transcribe.test.ts +0 -454
- package/src/cli/commands/autonomy.ts +0 -365
- package/src/cli/commands/memory.ts +0 -424
- package/src/cli/commands/oauth/__tests__/connect.test.ts +0 -947
- package/src/cli/commands/oauth/__tests__/disconnect.test.ts +0 -686
- package/src/cli/commands/oauth/__tests__/mode.test.ts +0 -632
- package/src/cli/commands/oauth/__tests__/ping.test.ts +0 -631
- package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +0 -573
- package/src/cli/commands/oauth/__tests__/providers-register.test.ts +0 -330
- package/src/cli/commands/oauth/__tests__/providers-update.test.ts +0 -521
- package/src/cli/commands/oauth/__tests__/status.test.ts +0 -551
- package/src/cli/commands/oauth/__tests__/token.test.ts +0 -420
- package/src/cli/lib/daemon-avatar-client.ts +0 -37
- package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +0 -87
- package/src/config/bundled-skills/messaging/tools/__tests__/messaging-feed-events.test.ts +0 -207
- package/src/daemon/__tests__/conversation-feed-event.test.ts +0 -304
- package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +0 -233
- package/src/home/__tests__/assistant-feed-authoring.test.ts +0 -156
- package/src/home/__tests__/emit-feed-event.test.ts +0 -169
- package/src/home/__tests__/feed-population-integration.test.ts +0 -312
- package/src/home/__tests__/feed-scheduler.test.ts +0 -222
- package/src/home/__tests__/phase5-exit-criteria.test.ts +0 -229
- package/src/home/__tests__/platform-gmail-digest.test.ts +0 -222
- package/src/home/__tests__/rollup-producer.test.ts +0 -507
- package/src/home/assistant-feed-authoring.ts +0 -135
- package/src/home/emit-feed-event.ts +0 -169
- package/src/home/feed-scheduler.ts +0 -281
- package/src/home/platform-gmail-digest.ts +0 -163
- package/src/home/rewrite-command-preview.ts +0 -66
- package/src/home/rewrite-feed-title.ts +0 -58
- package/src/home/rollup-producer.ts +0 -426
- package/src/memory/admin.ts +0 -326
- package/src/memory/context-search/sources/pkb.ts +0 -476
- package/src/memory/graph/compaction.ts +0 -299
- /package/src/cli/{commands → lib}/cache-fs.ts +0 -0
|
@@ -1,37 +1,8 @@
|
|
|
1
1
|
import type { Command } from "commander";
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
fetchManagedCatalog,
|
|
5
|
-
type ManagedCredentialDescriptor,
|
|
6
|
-
} from "../../credential-execution/managed-catalog.js";
|
|
7
|
-
import { cliIpcCall } from "../../ipc/cli-client.js";
|
|
8
|
-
import { syncManualTokenConnection } from "../../oauth/manual-token-connection.js";
|
|
9
|
-
import {
|
|
10
|
-
disconnectOAuthProvider,
|
|
11
|
-
getConnectionByProvider,
|
|
12
|
-
listConnections,
|
|
13
|
-
type OAuthConnectionRow,
|
|
14
|
-
} from "../../oauth/oauth-store.js";
|
|
3
|
+
import { cliIpcCall, exitFromIpcResult } from "../../ipc/cli-client.js";
|
|
15
4
|
import type { CredentialPromptResult } from "../../runtime/routes/credential-prompt-routes.js";
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
getActiveBackendInfoAsync,
|
|
19
|
-
getSecureKeyAsync,
|
|
20
|
-
getSecureKeyResultAsync,
|
|
21
|
-
} from "../../security/secure-keys.js";
|
|
22
|
-
import {
|
|
23
|
-
assertMetadataWritable,
|
|
24
|
-
type CredentialMetadata,
|
|
25
|
-
deleteCredentialMetadata,
|
|
26
|
-
getCredentialMetadata,
|
|
27
|
-
getCredentialMetadataById,
|
|
28
|
-
listCredentialMetadata,
|
|
29
|
-
upsertCredentialMetadata,
|
|
30
|
-
} from "../../tools/credentials/metadata-store.js";
|
|
31
|
-
import {
|
|
32
|
-
deleteSecureKeyViaDaemon,
|
|
33
|
-
setSecureKeyViaDaemon,
|
|
34
|
-
} from "../lib/daemon-credential-client.js";
|
|
5
|
+
import { registerCommand } from "../lib/register-command.js";
|
|
35
6
|
import { log } from "../logger.js";
|
|
36
7
|
import { shouldOutputJson, writeOutput } from "../output.js";
|
|
37
8
|
|
|
@@ -39,12 +10,6 @@ import { shouldOutputJson, writeOutput } from "../output.js";
|
|
|
39
10
|
// Format-aware error output
|
|
40
11
|
// ---------------------------------------------------------------------------
|
|
41
12
|
|
|
42
|
-
/**
|
|
43
|
-
* Write an error message respecting the output format. In JSON mode, emit a
|
|
44
|
-
* structured `{ ok: false, error }` object to stdout. In human mode, write
|
|
45
|
-
* plain text to stderr so the assistant (LLM) doesn't receive JSON that it
|
|
46
|
-
* might misinterpret as data.
|
|
47
|
-
*/
|
|
48
13
|
function writeError(cmd: Command, message: string): void {
|
|
49
14
|
if (shouldOutputJson(cmd)) {
|
|
50
15
|
writeOutput(cmd, { ok: false, error: message });
|
|
@@ -57,16 +22,10 @@ function writeError(cmd: Command, message: string): void {
|
|
|
57
22
|
// CES shell lockdown guard
|
|
58
23
|
// ---------------------------------------------------------------------------
|
|
59
24
|
|
|
60
|
-
/**
|
|
61
|
-
* Returns true when the current process is running inside an untrusted shell
|
|
62
|
-
* (CES shell lockdown active). CLI commands that reveal raw secrets must
|
|
63
|
-
* check this and fail deterministically.
|
|
64
|
-
*/
|
|
65
25
|
function isUntrustedShell(): boolean {
|
|
66
26
|
return process.env.VELLUM_UNTRUSTED_SHELL === "1";
|
|
67
27
|
}
|
|
68
28
|
|
|
69
|
-
/** Error message for commands blocked by CES shell lockdown. */
|
|
70
29
|
const UNTRUSTED_SHELL_ERROR =
|
|
71
30
|
"This command is not available in untrusted shell mode. " +
|
|
72
31
|
"Raw secret access is restricted when running under CES shell lockdown.";
|
|
@@ -75,89 +34,6 @@ const UNTRUSTED_SHELL_ERROR =
|
|
|
75
34
|
// Shared helpers
|
|
76
35
|
// ---------------------------------------------------------------------------
|
|
77
36
|
|
|
78
|
-
/**
|
|
79
|
-
* Scrub a secret value for display. Shows `****` + last 4 characters for
|
|
80
|
-
* secrets longer than 4 chars, `****` for secrets 4 chars or fewer, and
|
|
81
|
-
* `(not set)` when no secret is stored.
|
|
82
|
-
*/
|
|
83
|
-
function scrubSecret(secret: string | undefined): string {
|
|
84
|
-
if (secret == null || secret.length === 0) return "(not set)";
|
|
85
|
-
if (secret.length <= 4) return "****";
|
|
86
|
-
return "****" + secret.slice(-4);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Safely look up an OAuth connection for a credential service.
|
|
91
|
-
* Returns undefined when the oauth-store has no data or the tables
|
|
92
|
-
* haven't been created yet (pre-migration).
|
|
93
|
-
*/
|
|
94
|
-
function safeGetConnectionByProvider(
|
|
95
|
-
service: string,
|
|
96
|
-
): OAuthConnectionRow | undefined {
|
|
97
|
-
try {
|
|
98
|
-
return getConnectionByProvider(service);
|
|
99
|
-
} catch {
|
|
100
|
-
return undefined;
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Safely list all OAuth connections. Returns an empty array when the
|
|
106
|
-
* oauth-store has no data or the tables haven't been created yet.
|
|
107
|
-
*/
|
|
108
|
-
function safeListConnections(): OAuthConnectionRow[] {
|
|
109
|
-
try {
|
|
110
|
-
return listConnections();
|
|
111
|
-
} catch {
|
|
112
|
-
return [];
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* Build a structured credential output object suitable for both `inspect`
|
|
118
|
-
* and `list` responses. Produces an identical shape for every credential.
|
|
119
|
-
* Optionally enriches with data from the oauth-store when a matching
|
|
120
|
-
* connection exists.
|
|
121
|
-
*/
|
|
122
|
-
function buildCredentialOutput(
|
|
123
|
-
metadata: CredentialMetadata,
|
|
124
|
-
secret: string | undefined,
|
|
125
|
-
connection?: OAuthConnectionRow,
|
|
126
|
-
): Record<string, unknown> {
|
|
127
|
-
const output: Record<string, unknown> = {
|
|
128
|
-
ok: true,
|
|
129
|
-
service: metadata.service,
|
|
130
|
-
field: metadata.field,
|
|
131
|
-
credentialId: metadata.credentialId,
|
|
132
|
-
scrubbedValue: scrubSecret(secret),
|
|
133
|
-
hasSecret: secret != null && secret.length > 0,
|
|
134
|
-
alias: metadata.alias ?? null,
|
|
135
|
-
usageDescription: metadata.usageDescription ?? null,
|
|
136
|
-
allowedTools: metadata.allowedTools,
|
|
137
|
-
allowedDomains: metadata.allowedDomains,
|
|
138
|
-
createdAt: new Date(metadata.createdAt).toISOString(),
|
|
139
|
-
updatedAt: new Date(metadata.updatedAt).toISOString(),
|
|
140
|
-
injectionTemplateCount: metadata.injectionTemplates?.length ?? 0,
|
|
141
|
-
grantedScopes: connection ? JSON.parse(connection.grantedScopes) : null,
|
|
142
|
-
expiresAt: connection?.expiresAt
|
|
143
|
-
? new Date(connection.expiresAt).toISOString()
|
|
144
|
-
: null,
|
|
145
|
-
};
|
|
146
|
-
|
|
147
|
-
if (connection) {
|
|
148
|
-
output.oauthConnectionId = connection.id;
|
|
149
|
-
output.oauthAccountInfo = connection.accountInfo ?? null;
|
|
150
|
-
output.oauthStatus = connection.status;
|
|
151
|
-
output.oauthHasRefreshToken = connection.hasRefreshToken === 1;
|
|
152
|
-
output.oauthLabel = connection.label ?? null;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
return output;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* Print a human-readable view of a single credential to the logger.
|
|
160
|
-
*/
|
|
161
37
|
function printCredentialHuman(output: Record<string, unknown>): void {
|
|
162
38
|
log.info(` ${output.service}:${output.field}`);
|
|
163
39
|
log.info(` ID: ${output.credentialId}`);
|
|
@@ -194,28 +70,6 @@ function printCredentialHuman(output: Record<string, unknown>): void {
|
|
|
194
70
|
}
|
|
195
71
|
}
|
|
196
72
|
|
|
197
|
-
/**
|
|
198
|
-
* Build a structured output object for a platform-managed credential descriptor.
|
|
199
|
-
* Never includes token values — only handle references and non-secret metadata.
|
|
200
|
-
*/
|
|
201
|
-
function buildManagedCredentialOutput(
|
|
202
|
-
descriptor: ManagedCredentialDescriptor,
|
|
203
|
-
): Record<string, unknown> {
|
|
204
|
-
return {
|
|
205
|
-
ok: true,
|
|
206
|
-
source: "platform",
|
|
207
|
-
handle: descriptor.handle,
|
|
208
|
-
provider: descriptor.provider,
|
|
209
|
-
connectionId: descriptor.connectionId,
|
|
210
|
-
accountInfo: descriptor.accountInfo,
|
|
211
|
-
grantedScopes: descriptor.grantedScopes,
|
|
212
|
-
status: descriptor.status,
|
|
213
|
-
};
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
/**
|
|
217
|
-
* Print a human-readable view of a platform-managed credential to the logger.
|
|
218
|
-
*/
|
|
219
73
|
function printManagedCredentialHuman(output: Record<string, unknown>): void {
|
|
220
74
|
log.info(` [platform-managed] ${output.provider}`);
|
|
221
75
|
log.info(` Handle: ${output.handle}`);
|
|
@@ -230,21 +84,42 @@ function printManagedCredentialHuman(output: Record<string, unknown>): void {
|
|
|
230
84
|
);
|
|
231
85
|
}
|
|
232
86
|
|
|
87
|
+
// ---------------------------------------------------------------------------
|
|
88
|
+
// Response types for IPC calls
|
|
89
|
+
// ---------------------------------------------------------------------------
|
|
90
|
+
|
|
91
|
+
interface CredentialsListResponse {
|
|
92
|
+
credentials: Record<string, unknown>[];
|
|
93
|
+
managedCredentials: Record<string, unknown>[];
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
interface CredentialsStatusResponse {
|
|
97
|
+
backend: string;
|
|
98
|
+
storePath?: string;
|
|
99
|
+
storeExists?: boolean;
|
|
100
|
+
storeKeyPath?: string;
|
|
101
|
+
storeKeyExists?: boolean;
|
|
102
|
+
ready?: boolean;
|
|
103
|
+
url?: string;
|
|
104
|
+
}
|
|
105
|
+
|
|
233
106
|
// ---------------------------------------------------------------------------
|
|
234
107
|
// Command registration
|
|
235
108
|
// ---------------------------------------------------------------------------
|
|
236
109
|
|
|
237
110
|
export function registerCredentialsCommand(program: Command): void {
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
111
|
+
registerCommand(program, {
|
|
112
|
+
name: "credentials",
|
|
113
|
+
transport: "ipc",
|
|
114
|
+
description:
|
|
241
115
|
"Manage credentials in the encrypted vault (API keys, tokens, passwords)",
|
|
242
|
-
)
|
|
243
|
-
|
|
116
|
+
build: (credential) => {
|
|
117
|
+
credential
|
|
118
|
+
.option("--json", "Machine-readable compact JSON output");
|
|
244
119
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
120
|
+
credential.addHelpText(
|
|
121
|
+
"after",
|
|
122
|
+
`
|
|
248
123
|
Credentials are identified by --service and --field flags, matching the
|
|
249
124
|
storage convention used internally (credential/{service}/{field}):
|
|
250
125
|
|
|
@@ -264,22 +139,24 @@ Examples:
|
|
|
264
139
|
$ assistant credentials inspect --service twilio --field account_sid
|
|
265
140
|
$ assistant credentials reveal --service twilio --field account_sid
|
|
266
141
|
$ assistant credentials delete --service twilio --field auth_token`,
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
// -----------------------------------------------------------------------
|
|
145
|
+
// list
|
|
146
|
+
// -----------------------------------------------------------------------
|
|
147
|
+
|
|
148
|
+
credential
|
|
149
|
+
.command("list")
|
|
150
|
+
.description(
|
|
151
|
+
"List all stored credentials with metadata and masked values",
|
|
152
|
+
)
|
|
153
|
+
.option(
|
|
154
|
+
"--search <query>",
|
|
155
|
+
"Filter credentials by substring match on service, field, label, or description",
|
|
156
|
+
)
|
|
157
|
+
.addHelpText(
|
|
158
|
+
"after",
|
|
159
|
+
`
|
|
283
160
|
Lists all credentials in the vault. Each entry includes the same fields as
|
|
284
161
|
"inspect" — scrubbed value, timestamps, policy, and metadata.
|
|
285
162
|
|
|
@@ -295,115 +172,64 @@ Examples:
|
|
|
295
172
|
$ assistant credentials list --search twilio
|
|
296
173
|
$ assistant credentials list --search bot_token
|
|
297
174
|
$ assistant credentials list --json`,
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
const alias = (m.alias ?? "").toLowerCase();
|
|
309
|
-
const description = (m.usageDescription ?? "").toLowerCase();
|
|
310
|
-
return (
|
|
311
|
-
service.includes(query) ||
|
|
312
|
-
field.includes(query) ||
|
|
313
|
-
alias.includes(query) ||
|
|
314
|
-
description.includes(query)
|
|
175
|
+
)
|
|
176
|
+
.action(async (opts: { search?: string }, cmd: Command) => {
|
|
177
|
+
const r = await cliIpcCall<CredentialsListResponse>(
|
|
178
|
+
"credentials_list",
|
|
179
|
+
{ body: { search: opts.search } },
|
|
180
|
+
);
|
|
181
|
+
if (!r.ok) {
|
|
182
|
+
return exitFromIpcResult(
|
|
183
|
+
r as { ok: false; error?: string; statusCode?: number },
|
|
184
|
+
cmd,
|
|
315
185
|
);
|
|
316
|
-
});
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
// Build a lookup of oauth connections keyed by provider for enrichment.
|
|
320
|
-
// listConnections() returns rows in no guaranteed order, so we compare
|
|
321
|
-
// createdAt to keep the most recent active connection per provider —
|
|
322
|
-
// matching the behaviour of getConnectionByProvider() used by inspect.
|
|
323
|
-
const allConnections = safeListConnections();
|
|
324
|
-
const connectionsByProvider = new Map<string, OAuthConnectionRow>();
|
|
325
|
-
for (const conn of allConnections) {
|
|
326
|
-
if (conn.status !== "active") continue;
|
|
327
|
-
const existing = connectionsByProvider.get(conn.provider);
|
|
328
|
-
if (!existing || conn.createdAt > existing.createdAt) {
|
|
329
|
-
connectionsByProvider.set(conn.provider, conn);
|
|
330
186
|
}
|
|
331
|
-
}
|
|
332
187
|
|
|
333
|
-
|
|
334
|
-
allMetadata.map(async (m) => {
|
|
335
|
-
const secret = await getSecureKeyAsync(
|
|
336
|
-
credentialKey(m.service, m.field),
|
|
337
|
-
);
|
|
338
|
-
const connection = connectionsByProvider.get(m.service);
|
|
339
|
-
return buildCredentialOutput(m, secret, connection);
|
|
340
|
-
}),
|
|
341
|
-
);
|
|
188
|
+
const { credentials, managedCredentials } = r.result!;
|
|
342
189
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
if (opts.search) {
|
|
350
|
-
const query = opts.search.toLowerCase();
|
|
351
|
-
descriptors = descriptors.filter(
|
|
352
|
-
(d) =>
|
|
353
|
-
d.provider.toLowerCase().includes(query) ||
|
|
354
|
-
d.handle.toLowerCase().includes(query) ||
|
|
355
|
-
(d.accountInfo ?? "").toLowerCase().includes(query),
|
|
356
|
-
);
|
|
357
|
-
}
|
|
358
|
-
managedOutputs = descriptors.map(buildManagedCredentialOutput);
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
if (shouldOutputJson(cmd)) {
|
|
362
|
-
writeOutput(cmd, {
|
|
363
|
-
ok: true,
|
|
364
|
-
credentials,
|
|
365
|
-
managedCredentials: managedOutputs,
|
|
366
|
-
});
|
|
367
|
-
} else {
|
|
368
|
-
const totalCount = credentials.length + managedOutputs.length;
|
|
369
|
-
if (totalCount === 0) {
|
|
370
|
-
log.info("No credentials found");
|
|
190
|
+
if (shouldOutputJson(cmd)) {
|
|
191
|
+
writeOutput(cmd, {
|
|
192
|
+
ok: true,
|
|
193
|
+
credentials,
|
|
194
|
+
managedCredentials,
|
|
195
|
+
});
|
|
371
196
|
} else {
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
197
|
+
const totalCount = credentials.length + managedCredentials.length;
|
|
198
|
+
if (totalCount === 0) {
|
|
199
|
+
log.info("No credentials found");
|
|
200
|
+
} else {
|
|
201
|
+
if (credentials.length > 0) {
|
|
202
|
+
log.info(`${credentials.length} local credential(s):\n`);
|
|
203
|
+
for (const cred of credentials) {
|
|
204
|
+
printCredentialHuman(cred);
|
|
205
|
+
log.info("");
|
|
206
|
+
}
|
|
377
207
|
}
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
208
|
+
if (managedCredentials.length > 0) {
|
|
209
|
+
log.info(
|
|
210
|
+
`${managedCredentials.length} platform-managed credential(s):\n`,
|
|
211
|
+
);
|
|
212
|
+
for (const managed of managedCredentials) {
|
|
213
|
+
printManagedCredentialHuman(managed);
|
|
214
|
+
log.info("");
|
|
215
|
+
}
|
|
386
216
|
}
|
|
387
217
|
}
|
|
388
218
|
}
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
.description("Show the active credential backend and its configuration")
|
|
404
|
-
.addHelpText(
|
|
405
|
-
"after",
|
|
406
|
-
`
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
// -----------------------------------------------------------------------
|
|
222
|
+
// status
|
|
223
|
+
// -----------------------------------------------------------------------
|
|
224
|
+
|
|
225
|
+
credential
|
|
226
|
+
.command("status")
|
|
227
|
+
.description(
|
|
228
|
+
"Show the active credential backend and its configuration",
|
|
229
|
+
)
|
|
230
|
+
.addHelpText(
|
|
231
|
+
"after",
|
|
232
|
+
`
|
|
407
233
|
Shows which credential storage backend this process is using and backend-specific
|
|
408
234
|
path or connection details. Run this to diagnose credential lookup mismatches —
|
|
409
235
|
for example, when the CLI and the daemon are reading from different stores.
|
|
@@ -420,53 +246,60 @@ process is scoped to.
|
|
|
420
246
|
Examples:
|
|
421
247
|
$ assistant credentials status
|
|
422
248
|
$ assistant credentials status --json`,
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
if (info.backend === "encrypted-store") {
|
|
433
|
-
log.info(
|
|
434
|
-
` Store path: ${info.storePath} [${info.storeExists ? "exists" : "missing"}]`,
|
|
435
|
-
);
|
|
436
|
-
log.info(
|
|
437
|
-
` Key path: ${info.storeKeyPath} [${info.storeKeyExists ? "exists" : "missing"}]`,
|
|
249
|
+
)
|
|
250
|
+
.action(async (_opts: Record<string, unknown>, cmd: Command) => {
|
|
251
|
+
const r = await cliIpcCall<CredentialsStatusResponse>(
|
|
252
|
+
"credentials_status",
|
|
253
|
+
);
|
|
254
|
+
if (!r.ok) {
|
|
255
|
+
return exitFromIpcResult(
|
|
256
|
+
r as { ok: false; error?: string; statusCode?: number },
|
|
257
|
+
cmd,
|
|
438
258
|
);
|
|
439
|
-
} else if (info.backend === "ces-rpc") {
|
|
440
|
-
log.info(` RPC ready: ${info.ready}`);
|
|
441
|
-
} else if (info.backend === "ces-http") {
|
|
442
|
-
log.info(` URL: ${info.url}`);
|
|
443
259
|
}
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
260
|
+
|
|
261
|
+
const info = r.result!;
|
|
262
|
+
|
|
263
|
+
if (shouldOutputJson(cmd)) {
|
|
264
|
+
writeOutput(cmd, { ok: true, ...info });
|
|
265
|
+
} else {
|
|
266
|
+
log.info(`Backend: ${info.backend}`);
|
|
267
|
+
if (info.backend === "encrypted-store") {
|
|
268
|
+
log.info(
|
|
269
|
+
` Store path: ${info.storePath} [${info.storeExists ? "exists" : "missing"}]`,
|
|
270
|
+
);
|
|
271
|
+
log.info(
|
|
272
|
+
` Key path: ${info.storeKeyPath} [${info.storeKeyExists ? "exists" : "missing"}]`,
|
|
273
|
+
);
|
|
274
|
+
} else if (info.backend === "ces-rpc") {
|
|
275
|
+
log.info(` RPC ready: ${info.ready}`);
|
|
276
|
+
} else if (info.backend === "ces-http") {
|
|
277
|
+
log.info(` URL: ${info.url}`);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
// -----------------------------------------------------------------------
|
|
283
|
+
// set
|
|
284
|
+
// -----------------------------------------------------------------------
|
|
285
|
+
|
|
286
|
+
credential
|
|
287
|
+
.command("set <value>")
|
|
288
|
+
.description("Store a secret and create or update its metadata")
|
|
289
|
+
.requiredOption("--service <service>", "Service namespace (e.g. google)")
|
|
290
|
+
.requiredOption("--field <field>", "Field name (e.g. client_secret)")
|
|
291
|
+
.option("--label <label>", 'Human-friendly label (e.g. "prod", "work")')
|
|
292
|
+
.option(
|
|
293
|
+
"--description <description>",
|
|
294
|
+
"What this credential is used for",
|
|
295
|
+
)
|
|
296
|
+
.option(
|
|
297
|
+
"--allowed-tools <tools>",
|
|
298
|
+
"Comma-separated tool names that may use this credential",
|
|
299
|
+
)
|
|
300
|
+
.addHelpText(
|
|
301
|
+
"after",
|
|
302
|
+
`
|
|
470
303
|
Arguments:
|
|
471
304
|
value The secret value to store
|
|
472
305
|
|
|
@@ -477,163 +310,127 @@ Examples:
|
|
|
477
310
|
$ assistant credentials set --service twilio --field account_sid AC1234567890
|
|
478
311
|
$ assistant credentials set --service fal --field api_key key_live_abc --label "fal-prod" --description "Image generation"
|
|
479
312
|
$ assistant credentials set --service github --field token ghp_abc --allowed-tools "bash,host_bash"`,
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
const allowedTools = opts.allowedTools
|
|
514
|
-
? opts.allowedTools.split(",").map((t) => t.trim())
|
|
515
|
-
: undefined;
|
|
313
|
+
)
|
|
314
|
+
.action(
|
|
315
|
+
async (
|
|
316
|
+
value: string,
|
|
317
|
+
opts: {
|
|
318
|
+
service: string;
|
|
319
|
+
field: string;
|
|
320
|
+
label?: string;
|
|
321
|
+
description?: string;
|
|
322
|
+
allowedTools?: string;
|
|
323
|
+
},
|
|
324
|
+
cmd: Command,
|
|
325
|
+
) => {
|
|
326
|
+
const allowedTools = opts.allowedTools
|
|
327
|
+
? opts.allowedTools.split(",").map((t) => t.trim())
|
|
328
|
+
: undefined;
|
|
329
|
+
|
|
330
|
+
const r = await cliIpcCall<{
|
|
331
|
+
credentialId: string;
|
|
332
|
+
service: string;
|
|
333
|
+
field: string;
|
|
334
|
+
}>("credentials_set", {
|
|
335
|
+
body: {
|
|
336
|
+
service: opts.service,
|
|
337
|
+
field: opts.field,
|
|
338
|
+
value,
|
|
339
|
+
label: opts.label,
|
|
340
|
+
description: opts.description,
|
|
341
|
+
allowedTools,
|
|
342
|
+
},
|
|
343
|
+
});
|
|
516
344
|
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
345
|
+
if (!r.ok) {
|
|
346
|
+
writeError(
|
|
347
|
+
cmd,
|
|
348
|
+
r.error ?? `Failed to store credential ${opts.service}:${opts.field}`,
|
|
349
|
+
);
|
|
350
|
+
process.exitCode = 1;
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
523
353
|
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
writeError(cmd, message);
|
|
539
|
-
process.exitCode = 1;
|
|
540
|
-
}
|
|
541
|
-
},
|
|
542
|
-
);
|
|
354
|
+
if (shouldOutputJson(cmd)) {
|
|
355
|
+
writeOutput(cmd, {
|
|
356
|
+
ok: true,
|
|
357
|
+
credentialId: r.result!.credentialId,
|
|
358
|
+
service: opts.service,
|
|
359
|
+
field: opts.field,
|
|
360
|
+
});
|
|
361
|
+
} else {
|
|
362
|
+
log.info(
|
|
363
|
+
`Stored credential ${opts.service}:${opts.field} (${r.result!.credentialId})`,
|
|
364
|
+
);
|
|
365
|
+
}
|
|
366
|
+
},
|
|
367
|
+
);
|
|
543
368
|
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
369
|
+
// -----------------------------------------------------------------------
|
|
370
|
+
// delete
|
|
371
|
+
// -----------------------------------------------------------------------
|
|
372
|
+
|
|
373
|
+
credential
|
|
374
|
+
.command("delete")
|
|
375
|
+
.description("Remove a secret and its metadata from the vault")
|
|
376
|
+
.requiredOption("--service <service>", "Service namespace")
|
|
377
|
+
.requiredOption("--field <field>", "Field name")
|
|
378
|
+
.addHelpText(
|
|
379
|
+
"after",
|
|
380
|
+
`
|
|
556
381
|
Deletes both the encrypted secret and all associated metadata (policy,
|
|
557
382
|
timestamps, injection templates). This action cannot be undone.
|
|
558
383
|
|
|
559
384
|
Examples:
|
|
560
385
|
$ assistant credentials delete --service twilio --field auth_token
|
|
561
386
|
$ assistant credentials delete --service github --field token`,
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
387
|
+
)
|
|
388
|
+
.action(
|
|
389
|
+
async (opts: { service: string; field: string }, cmd: Command) => {
|
|
390
|
+
const r = await cliIpcCall<{
|
|
391
|
+
service: string;
|
|
392
|
+
field: string;
|
|
393
|
+
}>("credentials_delete", {
|
|
394
|
+
body: { service: opts.service, field: opts.field },
|
|
395
|
+
});
|
|
566
396
|
|
|
567
|
-
|
|
397
|
+
if (!r.ok) {
|
|
398
|
+
writeError(
|
|
399
|
+
cmd,
|
|
400
|
+
r.error ?? `Failed to delete credential ${opts.service}:${opts.field}`,
|
|
401
|
+
);
|
|
402
|
+
process.exitCode = 1;
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
568
405
|
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
406
|
+
if (shouldOutputJson(cmd)) {
|
|
407
|
+
writeOutput(cmd, {
|
|
408
|
+
ok: true,
|
|
409
|
+
service: opts.service,
|
|
410
|
+
field: opts.field,
|
|
411
|
+
});
|
|
412
|
+
} else {
|
|
413
|
+
log.info(
|
|
414
|
+
`Deleted credential ${opts.service}:${opts.field}`,
|
|
415
|
+
);
|
|
416
|
+
}
|
|
417
|
+
},
|
|
572
418
|
);
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
try {
|
|
589
|
-
oauthResult = await disconnectOAuthProvider(service);
|
|
590
|
-
} catch {
|
|
591
|
-
// Best-effort — OAuth tables may not exist yet
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
if (oauthResult === "error") {
|
|
595
|
-
writeError(
|
|
596
|
-
cmd,
|
|
597
|
-
"Failed to disconnect OAuth provider — please try again",
|
|
598
|
-
);
|
|
599
|
-
process.exitCode = 1;
|
|
600
|
-
return;
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
if (
|
|
604
|
-
deleteResult.result !== "deleted" &&
|
|
605
|
-
!metadataDeleted &&
|
|
606
|
-
oauthResult !== "disconnected"
|
|
607
|
-
) {
|
|
608
|
-
writeError(cmd, "Credential not found");
|
|
609
|
-
process.exitCode = 1;
|
|
610
|
-
return;
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
if (shouldOutputJson(cmd)) {
|
|
614
|
-
writeOutput(cmd, { ok: true, service, field });
|
|
615
|
-
} else {
|
|
616
|
-
log.info(`Deleted credential ${service}:${field}`);
|
|
617
|
-
}
|
|
618
|
-
} catch (err) {
|
|
619
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
620
|
-
writeError(cmd, message);
|
|
621
|
-
process.exitCode = 1;
|
|
622
|
-
}
|
|
623
|
-
});
|
|
624
|
-
|
|
625
|
-
// -------------------------------------------------------------------------
|
|
626
|
-
// inspect
|
|
627
|
-
// -------------------------------------------------------------------------
|
|
628
|
-
|
|
629
|
-
credential
|
|
630
|
-
.command("inspect [id]")
|
|
631
|
-
.description("Show metadata and a masked preview of a stored credential")
|
|
632
|
-
.option("--service <service>", "Service namespace")
|
|
633
|
-
.option("--field <field>", "Field name")
|
|
634
|
-
.addHelpText(
|
|
635
|
-
"after",
|
|
636
|
-
`
|
|
419
|
+
|
|
420
|
+
// -----------------------------------------------------------------------
|
|
421
|
+
// inspect
|
|
422
|
+
// -----------------------------------------------------------------------
|
|
423
|
+
|
|
424
|
+
credential
|
|
425
|
+
.command("inspect [id]")
|
|
426
|
+
.description(
|
|
427
|
+
"Show metadata and a masked preview of a stored credential",
|
|
428
|
+
)
|
|
429
|
+
.option("--service <service>", "Service namespace")
|
|
430
|
+
.option("--field <field>", "Field name")
|
|
431
|
+
.addHelpText(
|
|
432
|
+
"after",
|
|
433
|
+
`
|
|
637
434
|
Arguments:
|
|
638
435
|
id (optional) Credential UUID for lookup by ID
|
|
639
436
|
|
|
@@ -650,127 +447,66 @@ Examples:
|
|
|
650
447
|
$ assistant credentials inspect --service twilio --field account_sid
|
|
651
448
|
$ assistant credentials inspect 7a3b1c2d-4e5f-6789-abcd-ef0123456789
|
|
652
449
|
$ assistant credentials inspect --json --service slack_channel --field bot_token`,
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
if (opts.service && opts.field) {
|
|
667
|
-
service = opts.service;
|
|
668
|
-
field = opts.field;
|
|
669
|
-
metadata = getCredentialMetadata(service, field);
|
|
670
|
-
storageKey = credentialKey(service, field);
|
|
671
|
-
} else if (id) {
|
|
672
|
-
metadata = getCredentialMetadataById(id);
|
|
673
|
-
if (metadata) {
|
|
674
|
-
storageKey = credentialKey(metadata.service, metadata.field);
|
|
675
|
-
service = metadata.service;
|
|
676
|
-
field = metadata.field;
|
|
677
|
-
} else {
|
|
678
|
-
// No metadata found by UUID, and we can't determine the storage key
|
|
679
|
-
writeError(cmd, "Credential not found");
|
|
450
|
+
)
|
|
451
|
+
.action(
|
|
452
|
+
async (
|
|
453
|
+
id: string | undefined,
|
|
454
|
+
opts: { service?: string; field?: string },
|
|
455
|
+
cmd: Command,
|
|
456
|
+
) => {
|
|
457
|
+
if (!opts.service && !opts.field && !id) {
|
|
458
|
+
writeError(
|
|
459
|
+
cmd,
|
|
460
|
+
"Either --service and --field flags or a credential UUID is required",
|
|
461
|
+
);
|
|
680
462
|
process.exitCode = 1;
|
|
681
463
|
return;
|
|
682
464
|
}
|
|
683
|
-
} else {
|
|
684
|
-
writeError(
|
|
685
|
-
cmd,
|
|
686
|
-
"Either --service and --field flags or a credential UUID is required",
|
|
687
|
-
);
|
|
688
|
-
process.exitCode = 1;
|
|
689
|
-
return;
|
|
690
|
-
}
|
|
691
465
|
|
|
692
|
-
|
|
693
|
-
|
|
466
|
+
const r = await cliIpcCall<Record<string, unknown>>(
|
|
467
|
+
"credentials_inspect",
|
|
468
|
+
{
|
|
469
|
+
body: {
|
|
470
|
+
service: opts.service,
|
|
471
|
+
field: opts.field,
|
|
472
|
+
id,
|
|
473
|
+
},
|
|
474
|
+
},
|
|
475
|
+
);
|
|
694
476
|
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
"Credential store is unreachable — ensure the assistant is running",
|
|
700
|
-
);
|
|
701
|
-
} else {
|
|
702
|
-
writeError(cmd, "Credential not found");
|
|
477
|
+
if (!r.ok) {
|
|
478
|
+
writeError(cmd, r.error ?? "Credential not found");
|
|
479
|
+
process.exitCode = 1;
|
|
480
|
+
return;
|
|
703
481
|
}
|
|
704
|
-
process.exitCode = 1;
|
|
705
|
-
return;
|
|
706
|
-
}
|
|
707
482
|
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
// credential set command. Build a minimal output in that case.
|
|
711
|
-
if (!metadata) {
|
|
483
|
+
const output = r.result!;
|
|
484
|
+
|
|
712
485
|
if (shouldOutputJson(cmd)) {
|
|
713
|
-
writeOutput(cmd, {
|
|
714
|
-
ok: true,
|
|
715
|
-
service: service,
|
|
716
|
-
field: field,
|
|
717
|
-
credentialId: null,
|
|
718
|
-
scrubbedValue: scrubSecret(secret),
|
|
719
|
-
hasSecret: secret != null && secret.length > 0,
|
|
720
|
-
alias: null,
|
|
721
|
-
usageDescription: null,
|
|
722
|
-
allowedTools: [],
|
|
723
|
-
allowedDomains: [],
|
|
724
|
-
createdAt: null,
|
|
725
|
-
updatedAt: null,
|
|
726
|
-
injectionTemplateCount: 0,
|
|
727
|
-
});
|
|
486
|
+
writeOutput(cmd, { ok: true, ...output });
|
|
728
487
|
} else {
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
const connection = safeGetConnectionByProvider(metadata.service);
|
|
737
|
-
const output = buildCredentialOutput(metadata, secret, connection);
|
|
738
|
-
|
|
739
|
-
if (unreachable && (secret == null || secret.length === 0)) {
|
|
740
|
-
output.scrubbedValue = "(credential store unreachable)";
|
|
741
|
-
output.brokerUnreachable = true;
|
|
742
|
-
}
|
|
743
|
-
|
|
744
|
-
if (shouldOutputJson(cmd)) {
|
|
745
|
-
writeOutput(cmd, output);
|
|
746
|
-
} else {
|
|
747
|
-
printCredentialHuman(output);
|
|
748
|
-
if (unreachable && (secret == null || secret.length === 0)) {
|
|
749
|
-
log.info(
|
|
750
|
-
" \u26A0 Credential store is unreachable — ensure the assistant is running",
|
|
751
|
-
);
|
|
488
|
+
printCredentialHuman(output);
|
|
489
|
+
if (output.brokerUnreachable) {
|
|
490
|
+
log.info(
|
|
491
|
+
" ⚠ Credential store is unreachable — ensure the assistant is running",
|
|
492
|
+
);
|
|
493
|
+
}
|
|
752
494
|
}
|
|
753
|
-
}
|
|
754
|
-
|
|
755
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
756
|
-
writeError(cmd, message);
|
|
757
|
-
process.exitCode = 1;
|
|
758
|
-
}
|
|
759
|
-
},
|
|
760
|
-
);
|
|
495
|
+
},
|
|
496
|
+
);
|
|
761
497
|
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
498
|
+
// -----------------------------------------------------------------------
|
|
499
|
+
// reveal
|
|
500
|
+
// -----------------------------------------------------------------------
|
|
501
|
+
|
|
502
|
+
credential
|
|
503
|
+
.command("reveal [id]")
|
|
504
|
+
.description("Print the plaintext value of a credential")
|
|
505
|
+
.option("--service <service>", "Service namespace")
|
|
506
|
+
.option("--field <field>", "Field name")
|
|
507
|
+
.addHelpText(
|
|
508
|
+
"after",
|
|
509
|
+
`
|
|
774
510
|
Arguments:
|
|
775
511
|
id (optional) Credential UUID for lookup by ID
|
|
776
512
|
|
|
@@ -787,101 +523,86 @@ Examples:
|
|
|
787
523
|
$ assistant credentials reveal 7a3b1c2d-4e5f-6789-abcd-ef0123456789
|
|
788
524
|
$ assistant credentials reveal --json --service twilio --field account_sid
|
|
789
525
|
$ export TWILIO_TOKEN=$(assistant credentials reveal --service twilio --field auth_token)`,
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
writeError(cmd, UNTRUSTED_SHELL_ERROR);
|
|
801
|
-
process.exitCode = 1;
|
|
802
|
-
return;
|
|
803
|
-
}
|
|
804
|
-
|
|
805
|
-
let storageKey: string;
|
|
806
|
-
|
|
807
|
-
if (opts.service && opts.field) {
|
|
808
|
-
storageKey = credentialKey(opts.service, opts.field);
|
|
809
|
-
} else if (id) {
|
|
810
|
-
const metadata = getCredentialMetadataById(id);
|
|
811
|
-
if (metadata) {
|
|
812
|
-
storageKey = credentialKey(metadata.service, metadata.field);
|
|
813
|
-
} else {
|
|
814
|
-
writeError(cmd, "Credential not found");
|
|
526
|
+
)
|
|
527
|
+
.action(
|
|
528
|
+
async (
|
|
529
|
+
id: string | undefined,
|
|
530
|
+
opts: { service?: string; field?: string },
|
|
531
|
+
cmd: Command,
|
|
532
|
+
) => {
|
|
533
|
+
// CES shell lockdown: deny raw secret reveal in untrusted shells.
|
|
534
|
+
if (isUntrustedShell()) {
|
|
535
|
+
writeError(cmd, UNTRUSTED_SHELL_ERROR);
|
|
815
536
|
process.exitCode = 1;
|
|
816
537
|
return;
|
|
817
538
|
}
|
|
818
|
-
} else {
|
|
819
|
-
writeError(
|
|
820
|
-
cmd,
|
|
821
|
-
"Either --service and --field flags or a credential UUID is required",
|
|
822
|
-
);
|
|
823
|
-
process.exitCode = 1;
|
|
824
|
-
return;
|
|
825
|
-
}
|
|
826
|
-
|
|
827
|
-
const { value: secret, unreachable } =
|
|
828
|
-
await getSecureKeyResultAsync(storageKey);
|
|
829
539
|
|
|
830
|
-
|
|
831
|
-
if (unreachable) {
|
|
540
|
+
if (!opts.service && !opts.field && !id) {
|
|
832
541
|
writeError(
|
|
833
542
|
cmd,
|
|
834
|
-
"
|
|
543
|
+
"Either --service and --field flags or a credential UUID is required",
|
|
835
544
|
);
|
|
836
|
-
|
|
837
|
-
|
|
545
|
+
process.exitCode = 1;
|
|
546
|
+
return;
|
|
838
547
|
}
|
|
839
|
-
process.exitCode = 1;
|
|
840
|
-
return;
|
|
841
|
-
}
|
|
842
548
|
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
549
|
+
const r = await cliIpcCall<{ value: string }>(
|
|
550
|
+
"credentials_reveal",
|
|
551
|
+
{
|
|
552
|
+
body: {
|
|
553
|
+
service: opts.service,
|
|
554
|
+
field: opts.field,
|
|
555
|
+
id,
|
|
556
|
+
},
|
|
557
|
+
},
|
|
558
|
+
);
|
|
559
|
+
|
|
560
|
+
if (!r.ok) {
|
|
561
|
+
writeError(cmd, r.error ?? "Credential not found");
|
|
562
|
+
process.exitCode = 1;
|
|
563
|
+
return;
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
if (shouldOutputJson(cmd)) {
|
|
567
|
+
writeOutput(cmd, { ok: true, value: r.result!.value });
|
|
568
|
+
} else {
|
|
569
|
+
process.stdout.write(r.result!.value + "\n");
|
|
570
|
+
}
|
|
571
|
+
},
|
|
572
|
+
);
|
|
855
573
|
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
574
|
+
// -----------------------------------------------------------------------
|
|
575
|
+
// prompt
|
|
576
|
+
// -----------------------------------------------------------------------
|
|
577
|
+
|
|
578
|
+
credential
|
|
579
|
+
.command("prompt")
|
|
580
|
+
.description(
|
|
581
|
+
"Securely prompt the user for a credential via the app UI and store it",
|
|
582
|
+
)
|
|
583
|
+
.requiredOption(
|
|
584
|
+
"--service <service>",
|
|
585
|
+
"Service namespace (e.g. sentry)",
|
|
586
|
+
)
|
|
587
|
+
.requiredOption("--field <field>", "Field name (e.g. auth_token)")
|
|
588
|
+
.requiredOption("--label <label>", "Display label for the prompt UI")
|
|
589
|
+
.option("--description <description>", "Context shown in the prompt UI")
|
|
590
|
+
.option("--placeholder <placeholder>", "Placeholder text for the input")
|
|
591
|
+
.option(
|
|
592
|
+
"--allowed-domains <domains>",
|
|
593
|
+
"Comma-separated domains where this credential may be used",
|
|
594
|
+
)
|
|
595
|
+
.option(
|
|
596
|
+
"--allowed-tools <tools>",
|
|
597
|
+
"Comma-separated tool names that may use this credential",
|
|
598
|
+
)
|
|
599
|
+
.option(
|
|
600
|
+
"--injection-templates <json>",
|
|
601
|
+
"JSON array of injection template objects",
|
|
602
|
+
)
|
|
603
|
+
.addHelpText(
|
|
604
|
+
"after",
|
|
605
|
+
`
|
|
885
606
|
Opens a secure credential input prompt in the user's connected app (desktop,
|
|
886
607
|
web, etc.). The user enters the secret through the UI — it never passes through
|
|
887
608
|
the conversation or CLI output. On success the credential is stored in the
|
|
@@ -894,92 +615,91 @@ Examples:
|
|
|
894
615
|
--label "Sentry Auth Token" --placeholder "sntrys_..." \\
|
|
895
616
|
--allowed-domains "sentry.io" \\
|
|
896
617
|
--injection-templates '[{"hostPattern":"sentry.io","injectionType":"header","headerName":"Authorization","valuePrefix":"Bearer "}]'`,
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
618
|
+
)
|
|
619
|
+
.action(
|
|
620
|
+
async (
|
|
621
|
+
opts: {
|
|
622
|
+
service: string;
|
|
623
|
+
field: string;
|
|
624
|
+
label: string;
|
|
625
|
+
description?: string;
|
|
626
|
+
placeholder?: string;
|
|
627
|
+
allowedDomains?: string;
|
|
628
|
+
allowedTools?: string;
|
|
629
|
+
injectionTemplates?: string;
|
|
630
|
+
},
|
|
631
|
+
cmd: Command,
|
|
632
|
+
) => {
|
|
633
|
+
const allowedDomains = opts.allowedDomains
|
|
634
|
+
? opts.allowedDomains.split(",").map((d) => d.trim())
|
|
635
|
+
: undefined;
|
|
636
|
+
const allowedTools = opts.allowedTools
|
|
637
|
+
? opts.allowedTools.split(",").map((t) => t.trim())
|
|
638
|
+
: undefined;
|
|
639
|
+
|
|
640
|
+
let injectionTemplates: unknown[] | undefined;
|
|
641
|
+
if (opts.injectionTemplates) {
|
|
642
|
+
try {
|
|
643
|
+
injectionTemplates = JSON.parse(opts.injectionTemplates);
|
|
644
|
+
if (!Array.isArray(injectionTemplates)) {
|
|
645
|
+
writeError(cmd, "--injection-templates must be a JSON array");
|
|
646
|
+
process.exitCode = 1;
|
|
647
|
+
return;
|
|
648
|
+
}
|
|
649
|
+
} catch {
|
|
650
|
+
writeError(cmd, "--injection-templates must be valid JSON");
|
|
926
651
|
process.exitCode = 1;
|
|
927
652
|
return;
|
|
928
653
|
}
|
|
929
|
-
} catch {
|
|
930
|
-
writeError(cmd, "--injection-templates must be valid JSON");
|
|
931
|
-
process.exitCode = 1;
|
|
932
|
-
return;
|
|
933
654
|
}
|
|
934
|
-
}
|
|
935
655
|
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
allowedTools,
|
|
951
|
-
injectionTemplates,
|
|
656
|
+
const PROMPT_TIMEOUT_MS = 310_000; // 5 min + 10s buffer
|
|
657
|
+
const ipc = await cliIpcCall<CredentialPromptResult>(
|
|
658
|
+
"credentials_prompt",
|
|
659
|
+
{
|
|
660
|
+
body: {
|
|
661
|
+
service: opts.service,
|
|
662
|
+
field: opts.field,
|
|
663
|
+
label: opts.label,
|
|
664
|
+
description: opts.description,
|
|
665
|
+
placeholder: opts.placeholder,
|
|
666
|
+
allowedDomains,
|
|
667
|
+
allowedTools,
|
|
668
|
+
injectionTemplates,
|
|
669
|
+
},
|
|
952
670
|
},
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
);
|
|
671
|
+
{ timeoutMs: PROMPT_TIMEOUT_MS },
|
|
672
|
+
);
|
|
956
673
|
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
674
|
+
if (!ipc.ok) {
|
|
675
|
+
writeError(
|
|
676
|
+
cmd,
|
|
677
|
+
ipc.error ?? "Failed to connect to the assistant",
|
|
678
|
+
);
|
|
679
|
+
process.exitCode = 1;
|
|
680
|
+
return;
|
|
681
|
+
}
|
|
962
682
|
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
683
|
+
if (!ipc.result?.ok) {
|
|
684
|
+
writeError(
|
|
685
|
+
cmd,
|
|
686
|
+
ipc.result?.error ?? "Credential prompt failed",
|
|
687
|
+
);
|
|
688
|
+
process.exitCode = 1;
|
|
689
|
+
return;
|
|
690
|
+
}
|
|
968
691
|
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
}
|
|
983
|
-
},
|
|
984
|
-
);
|
|
692
|
+
if (shouldOutputJson(cmd)) {
|
|
693
|
+
writeOutput(cmd, {
|
|
694
|
+
ok: true,
|
|
695
|
+
service: opts.service,
|
|
696
|
+
field: opts.field,
|
|
697
|
+
});
|
|
698
|
+
} else {
|
|
699
|
+
log.info(`Stored credential ${opts.service}:${opts.field}`);
|
|
700
|
+
}
|
|
701
|
+
},
|
|
702
|
+
);
|
|
703
|
+
},
|
|
704
|
+
});
|
|
985
705
|
}
|