@vellumai/assistant 0.6.5 → 0.6.6
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 +9 -1
- package/ARCHITECTURE.md +15 -17
- package/Dockerfile +6 -4
- package/__tests__/permissions/gateway-threshold-reader.test.ts +283 -0
- package/docs/architecture/integrations.md +32 -39
- package/docs/architecture/memory.md +25 -30
- package/docs/architecture/security.md +7 -6
- package/docs/browser-use-architecture-phase2.md +63 -20
- package/docs/plugins.md +761 -0
- package/examples/plugins/echo/README.md +132 -0
- package/examples/plugins/echo/package.json +17 -0
- package/examples/plugins/echo/register.ts +187 -0
- package/node_modules/@vellumai/egress-proxy/src/types.ts +19 -0
- package/openapi.yaml +212 -68
- package/package.json +1 -1
- package/src/__tests__/app-compiler.test.ts +57 -0
- package/src/__tests__/approval-cascade.test.ts +7 -2
- package/src/__tests__/auto-analysis-end-to-end.test.ts +1 -0
- package/src/__tests__/avatar-generator.test.ts +4 -2
- package/src/__tests__/bundled-asset.test.ts +6 -6
- package/src/__tests__/catalog-cache.test.ts +69 -0
- package/src/__tests__/checker.test.ts +459 -171
- package/src/__tests__/circuit-breaker-pipeline.test.ts +406 -0
- package/src/__tests__/compaction-events.test.ts +501 -0
- package/src/__tests__/compaction-pipeline.test.ts +210 -0
- package/src/__tests__/compaction-strip-metadata-clear.test.ts +181 -0
- package/src/__tests__/compaction-timeout-recovery.test.ts +262 -0
- package/src/__tests__/config-model-image-provider.test.ts +110 -0
- package/src/__tests__/config-schema.test.ts +22 -9
- package/src/__tests__/config-watcher-cleanup-throttle.test.ts +0 -4
- package/src/__tests__/contacts-tools.test.ts +26 -0
- package/src/__tests__/context-overflow-policy.test.ts +7 -7
- package/src/__tests__/context-window-manager.test.ts +355 -4
- package/src/__tests__/conversation-abort-tool-results.test.ts +4 -1
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +26 -30
- package/src/__tests__/conversation-agent-loop.test.ts +30 -141
- package/src/__tests__/conversation-confirmation-signals.test.ts +6 -1
- package/src/__tests__/conversation-history-web-search.test.ts +1 -0
- package/src/__tests__/conversation-init.benchmark.test.ts +2 -16
- package/src/__tests__/conversation-pairing.test.ts +174 -10
- package/src/__tests__/conversation-pre-run-repair.test.ts +4 -1
- package/src/__tests__/conversation-process-callsite.test.ts +3 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +16 -7
- package/src/__tests__/conversation-queue.test.ts +29 -14
- package/src/__tests__/conversation-routes-disk-view.test.ts +7 -6
- package/src/__tests__/conversation-runtime-assembly.test.ts +155 -110
- package/src/__tests__/conversation-runtime-workspace.test.ts +23 -38
- package/src/__tests__/conversation-seed-composer.test.ts +2 -2
- package/src/__tests__/conversation-slash-queue.test.ts +7 -2
- package/src/__tests__/conversation-slash-unknown.test.ts +25 -2
- package/src/__tests__/conversation-speed-override.test.ts +6 -1
- package/src/__tests__/conversation-title-service.test.ts +116 -0
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +41 -2
- package/src/__tests__/conversation-usage.test.ts +1 -1
- package/src/__tests__/conversation-workspace-cache-state.test.ts +4 -1
- package/src/__tests__/conversation-workspace-injection.test.ts +3 -0
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +4 -1
- package/src/__tests__/credential-health-service.test.ts +78 -9
- package/src/__tests__/credential-security-invariants.test.ts +2 -2
- package/src/__tests__/db-schedule-syntax-migration.test.ts +1 -0
- package/src/__tests__/empty-response-pipeline.test.ts +305 -0
- package/src/__tests__/extension-id-sync-guard.test.ts +3 -3
- package/src/__tests__/first-greeting.test.ts +247 -5
- package/src/__tests__/headless-browser-mode.test.ts +57 -0
- package/src/__tests__/history-repair-pipeline.test.ts +399 -0
- package/src/__tests__/host-browser-e2e-cloud.test.ts +307 -0
- package/src/__tests__/host-browser-e2e-self-hosted.test.ts +3 -3
- package/src/__tests__/host-proxy-interface.test.ts +36 -2
- package/src/__tests__/image-credentials.test.ts +137 -0
- package/src/__tests__/image-service-dispatcher.test.ts +186 -0
- package/src/__tests__/injector-chain.test.ts +526 -0
- package/src/__tests__/intent-routing.test.ts +0 -26
- package/src/__tests__/llm-call-pipeline.test.ts +285 -0
- package/src/__tests__/llm-schema.test.ts +1 -1
- package/src/__tests__/media-generate-image.test.ts +119 -13
- package/src/__tests__/memory-retrieval-pipeline.test.ts +401 -0
- package/src/__tests__/memory-upsert-concurrency.test.ts +1 -0
- package/src/__tests__/migration-import-from-url.test.ts +5 -68
- package/src/__tests__/model-intents.test.ts +4 -2
- package/src/__tests__/notification-broadcaster.test.ts +3 -3
- package/src/__tests__/notification-decision-strategy.test.ts +0 -11
- package/src/__tests__/notification-schedule-notify-dedup.test.ts +108 -0
- package/src/__tests__/oauth-apps-routes.test.ts +1 -1
- package/src/__tests__/oauth-cli.test.ts +14 -12
- package/src/__tests__/oauth-connect-orchestrator.test.ts +4 -13
- package/src/__tests__/oauth-provider-serializer.test.ts +6 -4
- package/src/__tests__/oauth-provider-visibility.test.ts +3 -5
- package/src/__tests__/oauth-providers-routes.test.ts +3 -2
- package/src/__tests__/oauth-store.test.ts +41 -76
- package/src/__tests__/onboarding-template-contract.test.ts +16 -64
- package/src/__tests__/openai-image-service.test.ts +368 -0
- package/src/__tests__/overflow-reduce-pipeline.test.ts +676 -0
- package/src/__tests__/permission-checker-host-gate.test.ts +0 -24
- package/src/__tests__/persist-onboarding-artifacts.test.ts +266 -0
- package/src/__tests__/persistence-pipeline.test.ts +377 -0
- package/src/__tests__/pipeline-runner.test.ts +565 -0
- package/src/__tests__/platform.test.ts +5 -2
- package/src/__tests__/plugin-bootstrap.test.ts +483 -0
- package/src/__tests__/plugin-registry.test.ts +273 -0
- package/src/__tests__/plugin-route-contribution.test.ts +288 -0
- package/src/__tests__/plugin-skill-contribution.test.ts +367 -0
- package/src/__tests__/plugin-tool-contribution.test.ts +286 -0
- package/src/__tests__/plugin-types.test.ts +320 -0
- package/src/__tests__/pricing.test.ts +44 -12
- package/src/__tests__/proxy-approval-callback.test.ts +69 -8
- package/src/__tests__/reaction-persistence.test.ts +1 -0
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +1 -0
- package/src/__tests__/registry.test.ts +0 -2
- package/src/__tests__/schedule-routes.test.ts +131 -1
- package/src/__tests__/scheduler-recurrence.test.ts +14 -70
- package/src/__tests__/scheduler-reuse-conversation.test.ts +10 -50
- package/src/__tests__/secret-detection-handler.test.ts +0 -10
- package/src/__tests__/shell-identity.test.ts +0 -134
- package/src/__tests__/suggestion-routes.test.ts +103 -4
- package/src/__tests__/task-memory-cleanup.test.ts +1 -0
- package/src/__tests__/task-scheduler.test.ts +3 -15
- package/src/__tests__/test-preload.ts +11 -0
- package/src/__tests__/title-generate-pipeline.test.ts +224 -0
- package/src/__tests__/token-estimate-pipeline.test.ts +431 -0
- package/src/__tests__/tool-error-pipeline.test.ts +244 -0
- package/src/__tests__/tool-execute-pipeline.test.ts +431 -0
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +0 -6
- package/src/__tests__/tool-executor-shell-integration.test.ts +7 -10
- package/src/__tests__/tool-executor.test.ts +141 -0
- package/src/__tests__/tool-result-truncate-pipeline.test.ts +356 -0
- package/src/__tests__/tool-result-truncation.test.ts +0 -110
- package/src/__tests__/user-plugin-loader.test.ts +191 -0
- package/src/__tests__/workspace-migration-046-seed-conversation-starters-callsite.test.ts +185 -0
- package/src/__tests__/workspace-migration-049-release-notes-default-sonnet.test.ts +100 -0
- package/src/__tests__/workspace-migration-050-seed-main-agent-opus-callsite.test.ts +171 -0
- package/src/__tests__/workspace-migration-051-seed-conversation-summarization-callsite.test.ts +252 -0
- package/src/__tests__/workspace-migration-remove-hooks.test.ts +99 -0
- package/src/__tests__/workspace-policy.test.ts +21 -3
- package/src/agent/loop.ts +340 -102
- package/src/approvals/__tests__/guardian-feed-event.test.ts +304 -0
- package/src/approvals/guardian-request-resolvers.ts +80 -0
- package/src/backup/__tests__/backup-worker.test.ts +2 -13
- package/src/backup/backup-worker.ts +3 -15
- package/src/bundler/app-compiler.ts +84 -1
- package/src/calls/call-state.ts +2 -2
- package/src/channels/__tests__/types.test.ts +3 -3
- package/src/channels/types.ts +6 -4
- package/src/cli/__tests__/notifications.test.ts +87 -211
- package/src/cli/commands/__tests__/backup.test.ts +1 -1
- package/src/cli/commands/__tests__/image-generation.test.ts +255 -35
- package/src/cli/commands/__tests__/inference-send.test.ts +12 -0
- package/src/cli/commands/__tests__/tts-synthesize.test.ts +12 -0
- package/src/cli/commands/backup.ts +2 -2
- package/src/cli/commands/clients.ts +138 -0
- package/src/cli/commands/completions.ts +2 -9
- package/src/cli/commands/conversations.ts +55 -7
- package/src/cli/commands/image-generation.ts +33 -34
- package/src/cli/commands/notifications.ts +68 -103
- package/src/cli/commands/oauth/__tests__/providers-register.test.ts +1 -1
- package/src/cli/commands/oauth/__tests__/providers-update.test.ts +1 -1
- package/src/cli/commands/oauth/connect.ts +2 -2
- package/src/cli/commands/oauth/providers.ts +176 -8
- package/src/cli/commands/oauth/status.ts +46 -36
- package/src/cli/commands/skills.ts +3 -4
- package/src/cli/program.ts +25 -29
- package/src/config/__tests__/backup-schema.test.ts +7 -2
- package/src/config/bundled-skills/app-builder/SKILL.md +2 -2
- package/src/config/bundled-skills/app-builder/references/WIDGETS.md +10 -10
- package/src/config/bundled-skills/contacts/tools/contact-merge.ts +66 -87
- package/src/config/bundled-skills/contacts/tools/contact-search.ts +28 -51
- package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +22 -40
- package/src/config/bundled-skills/image-studio/SKILL.md +2 -1
- package/src/config/bundled-skills/image-studio/TOOLS.json +2 -1
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +23 -39
- package/src/config/bundled-skills/messaging/SKILL.md +3 -3
- package/src/config/bundled-skills/messaging/tools/__tests__/messaging-feed-events.test.ts +207 -0
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +12 -0
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +58 -0
- package/src/config/bundled-skills/schedule/SKILL.md +8 -3
- package/src/config/bundled-skills/schedule/TOOLS.json +15 -7
- package/src/config/bundled-skills/schedule/references/SCRIPT_MODE_PATTERNS.md +59 -0
- package/src/config/bundled-tool-registry.ts +0 -15
- package/src/config/feature-flag-registry.json +17 -1
- package/src/config/schema.ts +19 -0
- package/src/config/schemas/backup.ts +1 -1
- package/src/config/schemas/conversations.ts +16 -0
- package/src/config/schemas/llm.ts +2 -3
- package/src/config/schemas/security.ts +6 -6
- package/src/config/schemas/tts.ts +11 -0
- package/src/config/skill-state.ts +6 -2
- package/src/config/skills.ts +94 -5
- package/src/context/__tests__/compact-prompt.test.ts +27 -9
- package/src/context/prompts/compact.md +26 -12
- package/src/context/tool-result-truncation.ts +3 -63
- package/src/context/window-manager.ts +190 -16
- package/src/credential-health/credential-health-service.ts +19 -6
- package/src/daemon/__tests__/conversation-feed-event.test.ts +317 -0
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +4 -12
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +14 -15
- package/src/daemon/config-watcher.ts +0 -2
- package/src/daemon/context-overflow-policy.ts +4 -13
- package/src/daemon/conversation-agent-loop-handlers.ts +83 -22
- package/src/daemon/conversation-agent-loop.ts +984 -683
- package/src/daemon/conversation-history.ts +10 -19
- package/src/daemon/conversation-lifecycle.ts +37 -19
- package/src/daemon/conversation-notifiers.ts +2 -110
- package/src/daemon/conversation-process.ts +14 -7
- package/src/daemon/conversation-runtime-assembly.ts +532 -411
- package/src/daemon/conversation-tool-setup.ts +41 -4
- package/src/daemon/conversation.ts +80 -35
- package/src/daemon/external-plugins-bootstrap.ts +478 -0
- package/src/daemon/first-greeting.ts +191 -14
- package/src/daemon/handlers/config-model.ts +11 -0
- package/src/daemon/handlers/skills.ts +5 -1
- package/src/daemon/lifecycle.ts +33 -68
- package/src/daemon/message-types/computer-use.ts +2 -34
- package/src/daemon/message-types/conversations.ts +49 -0
- package/src/daemon/message-types/messages.ts +12 -0
- package/src/daemon/server.ts +5 -3
- package/src/daemon/shutdown-handlers.ts +2 -12
- package/src/daemon/tool-side-effects.ts +14 -56
- package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +160 -0
- package/src/heartbeat/heartbeat-service.ts +24 -1
- package/src/home/__tests__/feed-population-integration.test.ts +312 -0
- package/src/home/emit-feed-event.ts +7 -0
- package/src/home/feed-types.ts +41 -2
- package/src/home/rewrite-command-preview.ts +66 -0
- package/src/ipc/__tests__/socket-path.test.ts +11 -50
- package/src/ipc/cli-client.ts +1 -1
- package/src/ipc/cli-server.ts +3 -3
- package/src/ipc/gateway-client.ts +4 -1
- package/src/ipc/routes/browser-context.ts +2 -0
- package/src/ipc/routes/browser.ts +1 -0
- package/src/ipc/routes/get-contact.ts +16 -0
- package/src/ipc/routes/index.ts +14 -0
- package/src/ipc/routes/list-clients.ts +31 -0
- package/src/ipc/routes/merge-contacts.ts +17 -0
- package/src/ipc/routes/notification.ts +133 -0
- package/src/ipc/routes/rename-conversation.ts +59 -0
- package/src/ipc/routes/search-contacts.ts +19 -0
- package/src/ipc/routes/upsert-contact.ts +25 -0
- package/src/ipc/socket-path.ts +14 -38
- package/src/media/app-icon-generator.ts +23 -46
- package/src/media/avatar-router.ts +26 -41
- package/src/media/gemini-image-service.ts +8 -41
- package/src/media/image-credentials.ts +73 -0
- package/src/media/image-service.ts +85 -0
- package/src/media/openai-image-service.ts +131 -0
- package/src/media/types.ts +46 -0
- package/src/memory/conversation-crud.ts +48 -18
- package/src/memory/conversation-queries.ts +57 -4
- package/src/memory/conversation-title-service.ts +25 -0
- package/src/memory/db-init.ts +8 -0
- package/src/memory/embedding-gemini.test.ts +41 -2
- package/src/memory/embedding-gemini.ts +6 -1
- package/src/memory/graph/bootstrap.test.ts +282 -0
- package/src/memory/graph/bootstrap.ts +8 -5
- package/src/memory/graph/extraction.ts +10 -2
- package/src/memory/graph/graph-search.test.ts +1 -0
- package/src/memory/graph/inspect.ts +2 -2
- package/src/memory/graph/retriever.ts +10 -3
- package/src/memory/migrations/041-approval-prompt-ts-tracker.ts +26 -0
- package/src/memory/migrations/149-oauth-tables.ts +1 -0
- package/src/memory/migrations/223-schedule-script-column.ts +11 -0
- package/src/memory/migrations/224-oauth-providers-managed-service-is-paid.ts +24 -0
- package/src/memory/migrations/225-oauth-providers-available-scopes.ts +13 -0
- package/src/memory/migrations/index.ts +4 -0
- package/src/memory/pkb/pkb-index.test.ts +1 -0
- package/src/memory/pkb/pkb-reconcile.test.ts +1 -0
- package/src/memory/pkb/pkb-search.test.ts +65 -4
- package/src/memory/pkb/pkb-search.ts +40 -18
- package/src/memory/qdrant-client.test.ts +60 -0
- package/src/memory/qdrant-client.ts +25 -0
- package/src/memory/schema/infrastructure.ts +1 -0
- package/src/memory/schema/oauth.ts +4 -1
- package/src/messaging/providers/slack/render-transcript.test.ts +77 -29
- package/src/messaging/providers/slack/render-transcript.ts +58 -0
- package/src/notifications/conversation-pairing.ts +78 -19
- package/src/notifications/copy-composer.ts +0 -5
- package/src/notifications/emit-signal.ts +1 -1
- package/src/notifications/signal.ts +1 -2
- package/src/oauth/AGENTS.md +1 -1
- package/src/oauth/__tests__/identity-verifier.test.ts +2 -1
- package/src/oauth/connect-orchestrator.ts +8 -34
- package/src/oauth/connect-types.ts +6 -10
- package/src/oauth/manual-token-connection.ts +23 -0
- package/src/oauth/oauth-store.ts +30 -14
- package/src/oauth/provider-serializer.ts +6 -1
- package/src/oauth/seed-providers.ts +56 -108
- package/src/outbound-proxy/http-forwarder.ts +9 -0
- package/src/permissions/approval-policy.test.ts +293 -18
- package/src/permissions/approval-policy.ts +110 -58
- package/src/permissions/arg-parser.test.ts +161 -0
- package/src/permissions/arg-parser.ts +141 -0
- package/src/permissions/bash-risk-classifier.test.ts +414 -2
- package/src/permissions/bash-risk-classifier.ts +303 -60
- package/src/permissions/checker.ts +157 -29
- package/src/permissions/command-registry.test.ts +239 -0
- package/src/permissions/command-registry.ts +234 -54
- package/src/permissions/defaults.ts +5 -4
- package/src/permissions/gateway-threshold-reader.ts +196 -0
- package/src/permissions/prompter.ts +4 -0
- package/src/permissions/risk-types.ts +61 -4
- package/src/permissions/schedule-risk-classifier.test.ts +129 -0
- package/src/permissions/schedule-risk-classifier.ts +85 -0
- package/src/permissions/shell-identity.ts +2 -42
- package/src/permissions/types.ts +2 -0
- package/src/permissions/workspace-policy.ts +8 -3
- package/src/plugins/defaults/circuit-breaker.ts +146 -0
- package/src/plugins/defaults/compaction.ts +145 -0
- package/src/plugins/defaults/empty-response.ts +126 -0
- package/src/plugins/defaults/history-repair.ts +85 -0
- package/src/plugins/defaults/index.ts +116 -0
- package/src/plugins/defaults/injectors.ts +491 -0
- package/src/plugins/defaults/llm-call.ts +82 -0
- package/src/plugins/defaults/memory-retrieval.ts +226 -0
- package/src/plugins/defaults/overflow-reduce.ts +181 -0
- package/src/plugins/defaults/persistence.ts +129 -0
- package/src/plugins/defaults/title-generate.ts +95 -0
- package/src/plugins/defaults/token-estimate.ts +104 -0
- package/src/plugins/defaults/tool-error.ts +126 -0
- package/src/plugins/defaults/tool-execute.ts +89 -0
- package/src/plugins/defaults/tool-result-truncate.ts +88 -0
- package/src/plugins/pipeline.ts +316 -0
- package/src/plugins/plugin-skill-contributions.ts +292 -0
- package/src/plugins/registry.ts +241 -0
- package/src/plugins/types.ts +1134 -0
- package/src/plugins/user-loader.ts +177 -0
- package/src/prompts/templates/BOOTSTRAP.md +27 -77
- package/src/providers/model-catalog.ts +52 -29
- package/src/providers/model-intents.ts +1 -1
- package/src/providers/openrouter/client.ts +5 -1
- package/src/providers/speech-to-text/deepgram-realtime.test.ts +61 -0
- package/src/providers/speech-to-text/deepgram-realtime.ts +57 -0
- package/src/providers/speech-to-text/xai-realtime.test.ts +72 -4
- package/src/providers/speech-to-text/xai-realtime.ts +39 -14
- package/src/runtime/AGENTS.md +25 -16
- package/src/runtime/__tests__/browser-extension-pair-routes.test.ts +3 -3
- package/src/runtime/__tests__/client-registry.test.ts +293 -0
- package/src/runtime/client-registry.ts +261 -0
- package/src/runtime/http-server.ts +77 -8
- package/src/runtime/http-types.ts +0 -2
- package/src/runtime/migrations/vbundle-builder.ts +1 -22
- package/src/runtime/routes/approval-prompt-ts-tracker.ts +51 -31
- package/src/runtime/routes/approval-routes.ts +17 -0
- package/src/runtime/routes/browser-extension-pair-routes.ts +27 -8
- package/src/runtime/routes/conversation-routes.ts +223 -116
- package/src/runtime/routes/inbound-message-handler.ts +88 -13
- package/src/runtime/routes/memory-item-routes.test.ts +1 -0
- package/src/runtime/routes/migration-routes.ts +0 -3
- package/src/runtime/routes/playground/__tests__/force-compact.test.ts +284 -0
- package/src/runtime/routes/playground/__tests__/guard.test.ts +80 -0
- package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +294 -0
- package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +271 -0
- package/src/runtime/routes/playground/__tests__/seed-conversation.test.ts +202 -0
- package/src/runtime/routes/playground/__tests__/seeded-conversations.test.ts +309 -0
- package/src/runtime/routes/playground/__tests__/state.test.ts +224 -0
- package/src/runtime/routes/playground/conversation-not-found.ts +29 -0
- package/src/runtime/routes/playground/deps.ts +56 -0
- package/src/runtime/routes/playground/force-compact.ts +73 -0
- package/src/runtime/routes/playground/guard.ts +37 -0
- package/src/runtime/routes/playground/index.ts +28 -0
- package/src/runtime/routes/playground/inject-failures.ts +159 -0
- package/src/runtime/routes/playground/reset-circuit.ts +115 -0
- package/src/runtime/routes/playground/seed-conversation.ts +139 -0
- package/src/runtime/routes/playground/seeded-conversations.ts +78 -0
- package/src/runtime/routes/playground/state.ts +78 -0
- package/src/runtime/routes/schedule-routes.ts +89 -8
- package/src/runtime/skill-route-registry.ts +75 -15
- package/src/schedule/run-script.ts +68 -0
- package/src/schedule/schedule-store.ts +7 -1
- package/src/schedule/scheduler.ts +48 -8
- package/src/skills/catalog-cache.ts +12 -5
- package/src/tools/browser/__tests__/browser-status.test.ts +189 -0
- package/src/tools/browser/browser-execution.ts +88 -19
- package/src/tools/browser/cdp-client/__tests__/extension-cdp-client.test.ts +230 -0
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +146 -3
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +54 -3
- package/src/tools/browser/cdp-client/factory.ts +15 -4
- package/src/tools/executor.ts +126 -74
- package/src/tools/network/script-proxy/session-manager.ts +37 -1
- package/src/tools/permission-checker.ts +98 -49
- package/src/tools/policy-context.ts +4 -0
- package/src/tools/registry.ts +140 -3
- package/src/tools/schedule/create.ts +23 -8
- package/src/tools/schedule/update.ts +3 -1
- package/src/tools/secret-detection-handler.ts +0 -51
- package/src/tools/system/avatar-generator.ts +6 -2
- package/src/tools/types.ts +28 -2
- package/src/util/platform.ts +7 -2
- package/src/util/pricing.ts +26 -3
- package/src/workspace/migrations/006-services-config.ts +2 -4
- package/src/workspace/migrations/022-move-hooks-to-workspace.ts +2 -3
- package/src/workspace/migrations/041-backfill-google-gmail-settings-scope.ts +3 -4
- package/src/workspace/migrations/046-seed-conversation-starters-callsite.ts +108 -0
- package/src/workspace/migrations/047-remove-watch-callsites.ts +54 -0
- package/src/workspace/migrations/048-remove-workspace-hooks.ts +81 -0
- package/src/workspace/migrations/049-release-notes-default-sonnet.ts +80 -0
- package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +86 -0
- package/src/workspace/migrations/051-seed-conversation-summarization-callsite.ts +128 -0
- package/src/workspace/migrations/registry.ts +12 -0
- package/tsconfig.json +1 -1
- package/hook-templates/debug-prompt-logger/hook.json +0 -7
- package/hook-templates/debug-prompt-logger/run.sh +0 -66
- package/src/__tests__/compaction-circuit-breaker.test.ts +0 -336
- package/src/__tests__/context-overflow-approval.test.ts +0 -156
- package/src/__tests__/hooks-blocking.test.ts +0 -178
- package/src/__tests__/hooks-cli.test.ts +0 -182
- package/src/__tests__/hooks-config.test.ts +0 -108
- package/src/__tests__/hooks-discovery.test.ts +0 -211
- package/src/__tests__/hooks-integration.test.ts +0 -196
- package/src/__tests__/hooks-manager.test.ts +0 -226
- package/src/__tests__/hooks-runner.test.ts +0 -175
- package/src/__tests__/hooks-settings.test.ts +0 -160
- package/src/__tests__/hooks-templates.test.ts +0 -169
- package/src/__tests__/hooks-ts-runner.test.ts +0 -170
- package/src/__tests__/hooks-watch.test.ts +0 -112
- package/src/__tests__/notification-schedule-dedup.test.ts +0 -213
- package/src/__tests__/oauth-scope-policy.test.ts +0 -180
- package/src/__tests__/send-notification-tool.test.ts +0 -83
- package/src/cli/commands/shotgun.ts +0 -266
- package/src/config/bundled-skills/conversations/SKILL.md +0 -20
- package/src/config/bundled-skills/conversations/TOOLS.json +0 -23
- package/src/config/bundled-skills/conversations/tools/rename-conversation.ts +0 -88
- package/src/config/bundled-skills/heartbeat/SKILL.md +0 -43
- package/src/config/bundled-skills/notifications/SKILL.md +0 -40
- package/src/config/bundled-skills/notifications/TOOLS.json +0 -80
- package/src/config/bundled-skills/notifications/tools/send-notification.ts +0 -152
- package/src/config/bundled-skills/notifications/tools/shared.ts +0 -13
- package/src/config/bundled-skills/screen-watch/SKILL.md +0 -27
- package/src/config/bundled-skills/screen-watch/TOOLS.json +0 -35
- package/src/config/bundled-skills/screen-watch/tools/start-screen-watch.ts +0 -12
- package/src/config/bundled-skills/skills-catalog/SKILL.md +0 -84
- package/src/daemon/context-overflow-approval.ts +0 -52
- package/src/daemon/watch-handler.ts +0 -399
- package/src/hooks/cli.ts +0 -253
- package/src/hooks/config.ts +0 -100
- package/src/hooks/discovery.ts +0 -135
- package/src/hooks/manager.ts +0 -179
- package/src/hooks/runner.ts +0 -117
- package/src/hooks/templates.ts +0 -77
- package/src/hooks/types.ts +0 -75
- package/src/oauth/scope-policy.ts +0 -89
- package/src/runtime/gateway-internal-client.ts +0 -94
- package/src/runtime/routes/watch-routes.ts +0 -156
- package/src/signals/shotgun.ts +0 -203
- package/src/tools/watch/screen-watch.ts +0 -144
- package/src/tools/watch/watch-state.ts +0 -142
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
|
|
3
|
+
import { cliIpcCall } from "../../ipc/cli-client.js";
|
|
4
|
+
import type { ClientEntryJSON } from "../../runtime/client-registry.js";
|
|
5
|
+
import { log } from "../logger.js";
|
|
6
|
+
import { writeOutput } from "../output.js";
|
|
7
|
+
|
|
8
|
+
interface ListClientsResponse {
|
|
9
|
+
clients: ClientEntryJSON[];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function registerClientsCommand(program: Command): void {
|
|
13
|
+
const clients = program
|
|
14
|
+
.command("clients")
|
|
15
|
+
.description("Discover connected clients and their capabilities");
|
|
16
|
+
|
|
17
|
+
clients.addHelpText(
|
|
18
|
+
"after",
|
|
19
|
+
`
|
|
20
|
+
Clients are the applications currently connected to the assistant —
|
|
21
|
+
macOS desktop, iOS, web, Chrome extension, or CLI. Each client has a
|
|
22
|
+
set of capabilities (e.g. host_bash, host_file) that determine which
|
|
23
|
+
tools the assistant can route through it.
|
|
24
|
+
|
|
25
|
+
Examples:
|
|
26
|
+
$ assistant clients list List all connected clients
|
|
27
|
+
$ assistant clients list --json Machine-readable JSON output
|
|
28
|
+
$ assistant clients list --capability host_bash Show only clients that can run host commands`,
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
clients
|
|
32
|
+
.command("list")
|
|
33
|
+
.description("List all currently connected clients")
|
|
34
|
+
.option("--json", "Machine-readable compact JSON output")
|
|
35
|
+
.option(
|
|
36
|
+
"--capability <name>",
|
|
37
|
+
"Filter to clients supporting this capability (e.g. host_bash, host_file, host_cu, host_browser)",
|
|
38
|
+
)
|
|
39
|
+
.addHelpText(
|
|
40
|
+
"after",
|
|
41
|
+
`
|
|
42
|
+
Options:
|
|
43
|
+
--json Output as compact JSON instead of a table.
|
|
44
|
+
--capability <name> Only show clients that support the named capability.
|
|
45
|
+
Valid values: host_bash, host_file, host_cu, host_browser.
|
|
46
|
+
|
|
47
|
+
The table shows each client's ID, interface type, capabilities,
|
|
48
|
+
connection timestamps, and host environment (when available).
|
|
49
|
+
Clients are sorted by most recently active first.
|
|
50
|
+
|
|
51
|
+
Examples:
|
|
52
|
+
$ assistant clients list
|
|
53
|
+
$ assistant clients list --capability host_bash
|
|
54
|
+
$ assistant clients list --json | jq '.clients[0].capabilities'`,
|
|
55
|
+
)
|
|
56
|
+
.action(
|
|
57
|
+
async (opts: { json?: boolean; capability?: string }, cmd: Command) => {
|
|
58
|
+
const params: Record<string, unknown> = {};
|
|
59
|
+
if (opts.capability) {
|
|
60
|
+
params.capability = opts.capability;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const result = await cliIpcCall<ListClientsResponse>(
|
|
64
|
+
"list_clients",
|
|
65
|
+
Object.keys(params).length > 0 ? params : undefined,
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
if (!result.ok) {
|
|
69
|
+
log.error(result.error ?? "Failed to list clients");
|
|
70
|
+
process.exitCode = 1;
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const response = result.result!;
|
|
75
|
+
const { clients: entries } = response;
|
|
76
|
+
|
|
77
|
+
if (opts.json) {
|
|
78
|
+
writeOutput(cmd, response);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (entries.length === 0) {
|
|
83
|
+
log.info("No clients connected.");
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Table output
|
|
88
|
+
const header = [
|
|
89
|
+
"CLIENT ID",
|
|
90
|
+
"INTERFACE",
|
|
91
|
+
"CAPABILITIES",
|
|
92
|
+
"CONNECTED",
|
|
93
|
+
"LAST ACTIVE",
|
|
94
|
+
"HOST",
|
|
95
|
+
];
|
|
96
|
+
const rows: string[][] = entries.map((e: ClientEntryJSON) => [
|
|
97
|
+
e.clientId.length > 20 ? `${e.clientId.slice(0, 17)}...` : e.clientId,
|
|
98
|
+
e.interfaceId,
|
|
99
|
+
e.capabilities.length > 0 ? e.capabilities.join(", ") : "—",
|
|
100
|
+
formatRelativeTime(e.connectedAt),
|
|
101
|
+
formatRelativeTime(e.lastActiveAt),
|
|
102
|
+
e.hostUsername
|
|
103
|
+
? `${e.hostUsername}${e.hostHomeDir ? ` (${e.hostHomeDir})` : ""}`
|
|
104
|
+
: "—",
|
|
105
|
+
]);
|
|
106
|
+
|
|
107
|
+
// Calculate column widths
|
|
108
|
+
const colWidths = header.map((h: string, i: number) =>
|
|
109
|
+
Math.max(h.length, ...rows.map((r: string[]) => r[i].length)),
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
const pad = (s: string, w: number) => s.padEnd(w);
|
|
113
|
+
const line = header
|
|
114
|
+
.map((h: string, i: number) => pad(h, colWidths[i]))
|
|
115
|
+
.join(" ");
|
|
116
|
+
log.info(line);
|
|
117
|
+
log.info(colWidths.map((w: number) => "─".repeat(w)).join(" "));
|
|
118
|
+
for (const row of rows) {
|
|
119
|
+
log.info(
|
|
120
|
+
row.map((c: string, i: number) => pad(c, colWidths[i])).join(" "),
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function formatRelativeTime(iso: string): string {
|
|
128
|
+
const ms = Date.now() - new Date(iso).getTime();
|
|
129
|
+
if (ms < 0) return "just now";
|
|
130
|
+
const sec = Math.floor(ms / 1000);
|
|
131
|
+
if (sec < 60) return `${sec}s ago`;
|
|
132
|
+
const min = Math.floor(sec / 60);
|
|
133
|
+
if (min < 60) return `${min}m ago`;
|
|
134
|
+
const hr = Math.floor(min / 60);
|
|
135
|
+
if (hr < 24) return `${hr}h ago`;
|
|
136
|
+
const days = Math.floor(hr / 24);
|
|
137
|
+
return `${days}d ago`;
|
|
138
|
+
}
|
|
@@ -40,7 +40,6 @@ Examples:
|
|
|
40
40
|
keys: ["list", "set", "delete"],
|
|
41
41
|
trust: ["list", "remove", "clear"],
|
|
42
42
|
memory: ["status", "backfill", "cleanup", "query", "rebuild-index"],
|
|
43
|
-
hooks: ["list", "enable", "disable", "install", "remove"],
|
|
44
43
|
contacts: ["list", "invites", "get", "merge"],
|
|
45
44
|
autonomy: ["get", "set"],
|
|
46
45
|
};
|
|
@@ -50,7 +49,6 @@ Examples:
|
|
|
50
49
|
"keys",
|
|
51
50
|
"trust",
|
|
52
51
|
"memory",
|
|
53
|
-
"hooks",
|
|
54
52
|
"contacts",
|
|
55
53
|
"autonomy",
|
|
56
54
|
"audit",
|
|
@@ -63,7 +61,7 @@ Examples:
|
|
|
63
61
|
process.stdout.write(generateBashCompletion(topLevel, subcommands));
|
|
64
62
|
break;
|
|
65
63
|
case "zsh":
|
|
66
|
-
process.stdout.write(generateZshCompletion(
|
|
64
|
+
process.stdout.write(generateZshCompletion(subcommands));
|
|
67
65
|
break;
|
|
68
66
|
case "fish":
|
|
69
67
|
process.stdout.write(generateFishCompletion(topLevel, subcommands));
|
|
@@ -113,10 +111,7 @@ complete -F _assistant_completions assistant
|
|
|
113
111
|
`;
|
|
114
112
|
}
|
|
115
113
|
|
|
116
|
-
function generateZshCompletion(
|
|
117
|
-
topLevel: string[],
|
|
118
|
-
subcommands: Record<string, string[]>,
|
|
119
|
-
): string {
|
|
114
|
+
function generateZshCompletion(subcommands: Record<string, string[]>): string {
|
|
120
115
|
const subcmdCases = Object.entries(subcommands)
|
|
121
116
|
.map(([cmd, subs]) => ` ${cmd}) compadd ${subs.join(" ")} ;;`)
|
|
122
117
|
.join("\n");
|
|
@@ -132,7 +127,6 @@ _assistant() {
|
|
|
132
127
|
'keys:Manage API keys in secure storage'
|
|
133
128
|
'trust:Manage trust rules'
|
|
134
129
|
'memory:Manage long-term memory'
|
|
135
|
-
'hooks:Manage hooks'
|
|
136
130
|
'contacts:Manage the contact graph'
|
|
137
131
|
'autonomy:View and configure autonomy tiers'
|
|
138
132
|
'audit:Show recent tool invocations'
|
|
@@ -172,7 +166,6 @@ function generateFishCompletion(
|
|
|
172
166
|
keys: "Manage API keys in secure storage",
|
|
173
167
|
trust: "Manage trust rules",
|
|
174
168
|
memory: "Manage long-term memory",
|
|
175
|
-
hooks: "Manage hooks",
|
|
176
169
|
contacts: "Manage the contact graph",
|
|
177
170
|
autonomy: "View and configure autonomy tiers",
|
|
178
171
|
audit: "Show recent tool invocations",
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
import type { Command } from "commander";
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
getQdrantUrlEnv,
|
|
5
|
-
getRuntimeHttpHost,
|
|
6
|
-
getRuntimeHttpPort,
|
|
7
|
-
} from "../../config/env.js";
|
|
3
|
+
import { getRuntimeHttpHost, getRuntimeHttpPort } from "../../config/env.js";
|
|
8
4
|
import { getConfig } from "../../config/loader.js";
|
|
9
5
|
import { shouldAutoStartDaemon } from "../../daemon/connection-policy.js";
|
|
10
6
|
import { healthCheckHost, isHttpHealthy } from "../../daemon/daemon-control.js";
|
|
@@ -25,7 +21,10 @@ import {
|
|
|
25
21
|
SPARSE_EMBEDDING_VERSION,
|
|
26
22
|
} from "../../memory/embedding-backend.js";
|
|
27
23
|
import { enqueueMemoryJob } from "../../memory/jobs-store.js";
|
|
28
|
-
import {
|
|
24
|
+
import {
|
|
25
|
+
initQdrantClient,
|
|
26
|
+
resolveQdrantUrl,
|
|
27
|
+
} from "../../memory/qdrant-client.js";
|
|
29
28
|
import {
|
|
30
29
|
initAuthSigningKey,
|
|
31
30
|
loadOrCreateSigningKey,
|
|
@@ -113,6 +112,55 @@ Examples:
|
|
|
113
112
|
);
|
|
114
113
|
});
|
|
115
114
|
|
|
115
|
+
conversations
|
|
116
|
+
.command("rename <conversationId> <title>")
|
|
117
|
+
.description("Rename a conversation")
|
|
118
|
+
.addHelpText(
|
|
119
|
+
"after",
|
|
120
|
+
`
|
|
121
|
+
Arguments:
|
|
122
|
+
conversationId Conversation ID (or unique prefix). Supports prefix matching.
|
|
123
|
+
Run 'assistant conversations list' to find IDs.
|
|
124
|
+
title The new title for the conversation. Should be concise (under
|
|
125
|
+
60 characters) and descriptive of the current topic.
|
|
126
|
+
|
|
127
|
+
Renames the conversation to the given title and marks it as a manual rename
|
|
128
|
+
(auto-generated titles will not overwrite it).
|
|
129
|
+
|
|
130
|
+
Examples:
|
|
131
|
+
$ assistant conversations rename abc123 "Project planning"
|
|
132
|
+
$ assistant conversations rename abc123 "Bug triage 2026-04-22"`,
|
|
133
|
+
)
|
|
134
|
+
.action(async (conversationId: string, title: string) => {
|
|
135
|
+
const trimmedTitle = title.trim();
|
|
136
|
+
if (!trimmedTitle) {
|
|
137
|
+
log.error("Error: title must be a non-empty string");
|
|
138
|
+
process.exit(1);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const ipcResult = await cliIpcCall<{ ok: boolean; error?: string }>(
|
|
142
|
+
"rename_conversation",
|
|
143
|
+
{ conversationId, title: trimmedTitle },
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
if (!ipcResult.ok) {
|
|
147
|
+
log.error(
|
|
148
|
+
`Rename failed: ${ipcResult.error}. Run 'assistant conversations list' to verify the conversation exists.`,
|
|
149
|
+
);
|
|
150
|
+
process.exit(1);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const result = ipcResult.result!;
|
|
154
|
+
if (!result.ok) {
|
|
155
|
+
log.error(
|
|
156
|
+
`Rename failed: ${result.error}. Run 'assistant conversations list' to see available conversations.`,
|
|
157
|
+
);
|
|
158
|
+
process.exit(1);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
log.info(`Renamed conversation to "${trimmedTitle}" (${conversationId})`);
|
|
162
|
+
});
|
|
163
|
+
|
|
116
164
|
conversations
|
|
117
165
|
.command("export [conversationId]")
|
|
118
166
|
.description("Export a conversation as markdown or JSON")
|
|
@@ -247,7 +295,7 @@ Examples:
|
|
|
247
295
|
);
|
|
248
296
|
|
|
249
297
|
const config = getConfig();
|
|
250
|
-
const qdrantUrl =
|
|
298
|
+
const qdrantUrl = resolveQdrantUrl(config);
|
|
251
299
|
const embeddingSelection = await selectEmbeddingBackend(config);
|
|
252
300
|
const embeddingModel = embeddingSelection.backend
|
|
253
301
|
? `${embeddingSelection.backend.provider}:${embeddingSelection.backend.model}:sparse-v${SPARSE_EMBEDDING_VERSION}`
|
|
@@ -5,16 +5,13 @@ import { join } from "node:path";
|
|
|
5
5
|
import { Command } from "commander";
|
|
6
6
|
|
|
7
7
|
import { getConfig } from "../../config/loader.js";
|
|
8
|
+
import { resolveImageGenCredentials } from "../../media/image-credentials.js";
|
|
8
9
|
import {
|
|
9
10
|
generateImage,
|
|
10
11
|
type ImageGenCredentials,
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
buildManagedBaseUrl,
|
|
15
|
-
resolveManagedProxyContext,
|
|
16
|
-
} from "../../providers/managed-proxy/context.js";
|
|
17
|
-
import { getProviderKeyAsync } from "../../security/secure-keys.js";
|
|
12
|
+
mapImageGenError,
|
|
13
|
+
providerForModel,
|
|
14
|
+
} from "../../media/image-service.js";
|
|
18
15
|
import { log } from "../logger.js";
|
|
19
16
|
|
|
20
17
|
// ---------------------------------------------------------------------------
|
|
@@ -72,11 +69,12 @@ export function registerImageGenerationCommand(program: Command): void {
|
|
|
72
69
|
`
|
|
73
70
|
Modes:
|
|
74
71
|
managed — Uses platform-managed credentials (requires login to Vellum).
|
|
75
|
-
your-own — Uses your own Gemini API key configured
|
|
72
|
+
your-own — Uses your own Gemini or OpenAI API key depending on the configured model.
|
|
76
73
|
|
|
77
74
|
Supported models:
|
|
78
75
|
gemini-3.1-flash-image-preview (default)
|
|
79
76
|
gemini-3-pro-image-preview
|
|
77
|
+
gpt-image-2
|
|
80
78
|
|
|
81
79
|
Examples:
|
|
82
80
|
$ assistant image-generation generate --prompt "A sunset over the ocean"
|
|
@@ -114,12 +112,14 @@ Notes:
|
|
|
114
112
|
Edit mode (--mode edit) requires at least one --source image file.
|
|
115
113
|
Output files are named image-1.png, image-2.png, etc. (extension matches MIME type).
|
|
116
114
|
Default output directory is the system temp directory.
|
|
115
|
+
Uses your own Gemini or OpenAI API key depending on the configured model.
|
|
117
116
|
|
|
118
117
|
Examples:
|
|
119
118
|
$ assistant image-generation generate --prompt "A mountain landscape at dawn"
|
|
120
119
|
$ assistant image-generation generate --prompt "Make it darker" --mode edit --source input.png
|
|
121
120
|
$ assistant image-generation generate --prompt "Logo variations" --variants 4 --output-dir ./logos
|
|
122
|
-
$ assistant image-generation generate --prompt "A robot" --model gemini-3-pro-image-preview --json
|
|
121
|
+
$ assistant image-generation generate --prompt "A robot" --model gemini-3-pro-image-preview --json
|
|
122
|
+
$ assistant image-generation generate --prompt "A robot" --model gpt-image-2 --json`,
|
|
123
123
|
);
|
|
124
124
|
|
|
125
125
|
generate.action(async (opts) => {
|
|
@@ -149,33 +149,30 @@ Examples:
|
|
|
149
149
|
|
|
150
150
|
// --- Resolve credentials ---
|
|
151
151
|
const config = getConfig();
|
|
152
|
-
const
|
|
152
|
+
const svc = config.services["image-generation"];
|
|
153
153
|
|
|
154
|
-
|
|
154
|
+
// Derive provider from the explicit `--model` override when supplied so
|
|
155
|
+
// that `--model gpt-image-2` routes to OpenAI even when config.provider
|
|
156
|
+
// is `gemini` (and vice-versa). Without this, the Gemini service would
|
|
157
|
+
// silently downgrade unknown models to its default.
|
|
158
|
+
const provider = providerForModel(modelOverride, svc.provider);
|
|
155
159
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
credentials = {
|
|
161
|
-
type: "managed-proxy",
|
|
162
|
-
assistantApiKey: ctx.assistantApiKey,
|
|
163
|
-
baseUrl: managedBaseUrl,
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
} else {
|
|
167
|
-
const apiKey = await getProviderKeyAsync("gemini");
|
|
168
|
-
if (apiKey) {
|
|
169
|
-
credentials = { type: "direct", apiKey };
|
|
170
|
-
}
|
|
171
|
-
}
|
|
160
|
+
const { credentials, errorHint } = await resolveImageGenCredentials({
|
|
161
|
+
provider,
|
|
162
|
+
mode: svc.mode,
|
|
163
|
+
});
|
|
172
164
|
|
|
173
165
|
if (!credentials) {
|
|
166
|
+
const baseHint =
|
|
167
|
+
errorHint ?? "No credentials available for image generation.";
|
|
168
|
+
// The shared hint in image-credentials.ts is UI-neutral (it points at
|
|
169
|
+
// "Settings > Models & Services"), which is correct for tool surfaces
|
|
170
|
+
// but drops the actionable CLI command. Prepend the exact command for
|
|
171
|
+
// each mode so CLI users see a next-step they can copy-paste.
|
|
174
172
|
const hint =
|
|
175
|
-
|
|
176
|
-
?
|
|
177
|
-
:
|
|
178
|
-
|
|
173
|
+
svc.mode === "managed"
|
|
174
|
+
? `${baseHint}\n Run 'assistant auth login' to authenticate, or set services.image-generation.mode to 'your-own' in config.`
|
|
175
|
+
: `Run: assistant keys set ${provider} <key>.\n${baseHint}`;
|
|
179
176
|
if (jsonOutput) {
|
|
180
177
|
process.stdout.write(JSON.stringify({ ok: false, error: hint }) + "\n");
|
|
181
178
|
} else {
|
|
@@ -185,6 +182,8 @@ Examples:
|
|
|
185
182
|
return;
|
|
186
183
|
}
|
|
187
184
|
|
|
185
|
+
const resolvedCredentials: ImageGenCredentials = credentials;
|
|
186
|
+
|
|
188
187
|
// --- Read source images for edit mode ---
|
|
189
188
|
let sourceImages:
|
|
190
189
|
| Array<{ mimeType: string; dataBase64: string }>
|
|
@@ -231,11 +230,11 @@ Examples:
|
|
|
231
230
|
}
|
|
232
231
|
|
|
233
232
|
// --- Resolve model ---
|
|
234
|
-
const model = modelOverride ??
|
|
233
|
+
const model = modelOverride ?? svc.model;
|
|
235
234
|
|
|
236
235
|
// --- Generate image ---
|
|
237
236
|
try {
|
|
238
|
-
const result = await generateImage(
|
|
237
|
+
const result = await generateImage(provider, resolvedCredentials, {
|
|
239
238
|
prompt,
|
|
240
239
|
mode,
|
|
241
240
|
sourceImages,
|
|
@@ -286,7 +285,7 @@ Examples:
|
|
|
286
285
|
}
|
|
287
286
|
}
|
|
288
287
|
} catch (error) {
|
|
289
|
-
const errorMsg =
|
|
288
|
+
const errorMsg = mapImageGenError(provider, error);
|
|
290
289
|
if (jsonOutput) {
|
|
291
290
|
process.stdout.write(
|
|
292
291
|
JSON.stringify({ ok: false, error: errorMsg }) + "\n",
|
|
@@ -1,41 +1,9 @@
|
|
|
1
1
|
import type { Command } from "commander";
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import { emitNotificationSignal } from "../../notifications/emit-signal.js";
|
|
5
|
-
import { listEvents } from "../../notifications/events-store.js";
|
|
6
|
-
import {
|
|
7
|
-
isNotificationSourceChannel,
|
|
8
|
-
isNotificationSourceEventName,
|
|
9
|
-
NOTIFICATION_SOURCE_CHANNELS,
|
|
10
|
-
NOTIFICATION_SOURCE_EVENT_NAMES,
|
|
11
|
-
} from "../../notifications/signal.js";
|
|
12
|
-
import type { NotificationChannel } from "../../notifications/types.js";
|
|
13
|
-
import {
|
|
14
|
-
initAuthSigningKey,
|
|
15
|
-
resolveSigningKey,
|
|
16
|
-
} from "../../runtime/auth/token-service.js";
|
|
17
|
-
import { initializeDb } from "../db.js";
|
|
3
|
+
import { cliIpcCall } from "../../ipc/cli-client.js";
|
|
18
4
|
import { log } from "../logger.js";
|
|
19
5
|
import { shouldOutputJson, writeOutput } from "../output.js";
|
|
20
6
|
|
|
21
|
-
// ---------------------------------------------------------------------------
|
|
22
|
-
// Help text builders
|
|
23
|
-
// ---------------------------------------------------------------------------
|
|
24
|
-
|
|
25
|
-
function buildSourceChannelsHelpBlock(): string {
|
|
26
|
-
const lines = NOTIFICATION_SOURCE_CHANNELS.map(
|
|
27
|
-
(c) => ` ${c.id.padEnd(20)} ${c.description}`,
|
|
28
|
-
);
|
|
29
|
-
return `\nSource channels:\n${lines.join("\n")}`;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function buildSourceEventNamesHelpBlock(): string {
|
|
33
|
-
const lines = NOTIFICATION_SOURCE_EVENT_NAMES.map(
|
|
34
|
-
(e) => ` ${e.id.padEnd(50)} ${e.description}`,
|
|
35
|
-
);
|
|
36
|
-
return `\nSource event names:\n${lines.join("\n")}`;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
7
|
// ---------------------------------------------------------------------------
|
|
40
8
|
// Command registration
|
|
41
9
|
// ---------------------------------------------------------------------------
|
|
@@ -55,8 +23,6 @@ Notifications flow through a unified pipeline: a signal is emitted with a
|
|
|
55
23
|
source channel, event name, and attention hints. The decision engine evaluates
|
|
56
24
|
whether and where to deliver the notification based on connected channels,
|
|
57
25
|
urgency, and user preferences.
|
|
58
|
-
${buildSourceChannelsHelpBlock()}
|
|
59
|
-
${buildSourceEventNamesHelpBlock()}
|
|
60
26
|
|
|
61
27
|
Examples:
|
|
62
28
|
$ assistant notifications send --source-channel assistant_tool --source-event-name user.send_notification --message "Build finished"
|
|
@@ -129,6 +95,10 @@ Examples:
|
|
|
129
95
|
"--dedupe-key <key>",
|
|
130
96
|
"Optional dedupe key to suppress duplicate notifications",
|
|
131
97
|
)
|
|
98
|
+
.option(
|
|
99
|
+
"--deep-link-metadata <json>",
|
|
100
|
+
"Optional JSON metadata clients can use for deep linking",
|
|
101
|
+
)
|
|
132
102
|
.addHelpText(
|
|
133
103
|
"after",
|
|
134
104
|
`
|
|
@@ -165,37 +135,12 @@ Examples:
|
|
|
165
135
|
preferredChannels?: string;
|
|
166
136
|
sessionId?: string;
|
|
167
137
|
dedupeKey?: string;
|
|
138
|
+
deepLinkMetadata?: string;
|
|
168
139
|
},
|
|
169
140
|
cmd: Command,
|
|
170
141
|
) => {
|
|
171
142
|
try {
|
|
172
|
-
// Validate --
|
|
173
|
-
if (!isNotificationSourceChannel(opts.sourceChannel)) {
|
|
174
|
-
const validChannels = NOTIFICATION_SOURCE_CHANNELS.map(
|
|
175
|
-
(c) => c.id,
|
|
176
|
-
).join(", ");
|
|
177
|
-
writeOutput(cmd, {
|
|
178
|
-
ok: false,
|
|
179
|
-
error: `Invalid source channel "${opts.sourceChannel}". Valid values: ${validChannels}`,
|
|
180
|
-
});
|
|
181
|
-
process.exitCode = 1;
|
|
182
|
-
return;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
// Validate --source-event-name
|
|
186
|
-
if (!isNotificationSourceEventName(opts.sourceEventName)) {
|
|
187
|
-
const validEvents = NOTIFICATION_SOURCE_EVENT_NAMES.map(
|
|
188
|
-
(e) => e.id,
|
|
189
|
-
).join(", ");
|
|
190
|
-
writeOutput(cmd, {
|
|
191
|
-
ok: false,
|
|
192
|
-
error: `Invalid source event name "${opts.sourceEventName}". Valid values: ${validEvents}`,
|
|
193
|
-
});
|
|
194
|
-
process.exitCode = 1;
|
|
195
|
-
return;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
// Validate --message
|
|
143
|
+
// Validate --message (keep basic validation for immediate CLI feedback)
|
|
199
144
|
const message = opts.message.trim();
|
|
200
145
|
if (message.length === 0) {
|
|
201
146
|
writeOutput(cmd, {
|
|
@@ -217,7 +162,7 @@ Examples:
|
|
|
217
162
|
return;
|
|
218
163
|
}
|
|
219
164
|
|
|
220
|
-
//
|
|
165
|
+
// Parse --deadline-at
|
|
221
166
|
let deadlineAt: number | undefined;
|
|
222
167
|
if (opts.deadlineAt != null) {
|
|
223
168
|
const parsed = Number(opts.deadlineAt);
|
|
@@ -232,36 +177,43 @@ Examples:
|
|
|
232
177
|
deadlineAt = parsed;
|
|
233
178
|
}
|
|
234
179
|
|
|
235
|
-
//
|
|
236
|
-
let preferredChannels:
|
|
180
|
+
// Parse --preferred-channels
|
|
181
|
+
let preferredChannels: string[] | undefined;
|
|
237
182
|
if (opts.preferredChannels) {
|
|
238
|
-
|
|
239
|
-
const requested = opts.preferredChannels
|
|
183
|
+
preferredChannels = opts.preferredChannels
|
|
240
184
|
.split(",")
|
|
241
185
|
.map((ch) => ch.trim())
|
|
242
186
|
.filter((ch) => ch.length > 0);
|
|
187
|
+
}
|
|
243
188
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
189
|
+
// Parse --deep-link-metadata
|
|
190
|
+
let deepLinkMetadata: Record<string, unknown> | undefined;
|
|
191
|
+
if (opts.deepLinkMetadata != null) {
|
|
192
|
+
try {
|
|
193
|
+
deepLinkMetadata = JSON.parse(opts.deepLinkMetadata) as Record<
|
|
194
|
+
string,
|
|
195
|
+
unknown
|
|
196
|
+
>;
|
|
197
|
+
} catch {
|
|
198
|
+
writeOutput(cmd, {
|
|
199
|
+
ok: false,
|
|
200
|
+
error: `Invalid deep-link-metadata: must be a valid JSON string`,
|
|
201
|
+
});
|
|
202
|
+
process.exitCode = 1;
|
|
203
|
+
return;
|
|
253
204
|
}
|
|
254
|
-
preferredChannels = requested as NotificationChannel[];
|
|
255
205
|
}
|
|
256
206
|
|
|
257
|
-
initializeDb();
|
|
258
|
-
initAuthSigningKey(resolveSigningKey());
|
|
259
|
-
|
|
260
207
|
const sourceContextId = opts.sessionId ?? `cli-${Date.now()}`;
|
|
261
208
|
|
|
262
|
-
const result = await
|
|
263
|
-
|
|
209
|
+
const result = await cliIpcCall<{
|
|
210
|
+
signalId: string;
|
|
211
|
+
dispatched: boolean;
|
|
212
|
+
deduplicated: boolean;
|
|
213
|
+
reason: string;
|
|
214
|
+
}>("emit_notification_signal", {
|
|
264
215
|
sourceChannel: opts.sourceChannel,
|
|
216
|
+
sourceEventName: opts.sourceEventName,
|
|
265
217
|
sourceContextId,
|
|
266
218
|
attentionHints: {
|
|
267
219
|
requiresAction: opts.requiresAction ?? true,
|
|
@@ -275,24 +227,33 @@ Examples:
|
|
|
275
227
|
requestedBySource: opts.sourceChannel,
|
|
276
228
|
...(opts.title ? { requestedTitle: opts.title } : {}),
|
|
277
229
|
...(preferredChannels?.length ? { preferredChannels } : {}),
|
|
230
|
+
...(deepLinkMetadata ? { deepLinkMetadata } : {}),
|
|
278
231
|
},
|
|
279
232
|
...(opts.dedupeKey ? { dedupeKey: opts.dedupeKey } : {}),
|
|
280
233
|
throwOnError: true,
|
|
281
234
|
});
|
|
282
235
|
|
|
236
|
+
if (!result.ok) {
|
|
237
|
+
writeOutput(cmd, { ok: false, error: result.error });
|
|
238
|
+
process.exitCode = 1;
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
const signal = result.result!;
|
|
243
|
+
|
|
283
244
|
writeOutput(cmd, {
|
|
284
245
|
ok: true,
|
|
285
|
-
signalId:
|
|
286
|
-
dispatched:
|
|
287
|
-
reason:
|
|
246
|
+
signalId: signal.signalId,
|
|
247
|
+
dispatched: signal.dispatched,
|
|
248
|
+
reason: signal.reason,
|
|
288
249
|
});
|
|
289
250
|
|
|
290
251
|
if (!shouldOutputJson(cmd)) {
|
|
291
252
|
log.info(
|
|
292
|
-
`Signal ${
|
|
253
|
+
`Signal ${signal.signalId} emitted (dispatched: ${signal.dispatched})`,
|
|
293
254
|
);
|
|
294
|
-
if (
|
|
295
|
-
log.info(` Reason: ${
|
|
255
|
+
if (signal.reason) {
|
|
256
|
+
log.info(` Reason: ${signal.reason}`);
|
|
296
257
|
}
|
|
297
258
|
}
|
|
298
259
|
} catch (err) {
|
|
@@ -318,7 +279,6 @@ Examples:
|
|
|
318
279
|
Reads from the local notification events store, ordered by creation time
|
|
319
280
|
(newest first). Each event represents a signal that was emitted through the
|
|
320
281
|
notification pipeline.
|
|
321
|
-
${buildSourceEventNamesHelpBlock()}
|
|
322
282
|
|
|
323
283
|
Examples:
|
|
324
284
|
$ assistant notifications list
|
|
@@ -327,7 +287,7 @@ Examples:
|
|
|
327
287
|
$ assistant notifications list --source-event-name schedule.notify --limit 10 --json`,
|
|
328
288
|
)
|
|
329
289
|
.action(
|
|
330
|
-
(
|
|
290
|
+
async (
|
|
331
291
|
opts: {
|
|
332
292
|
limit?: string;
|
|
333
293
|
sourceEventName?: string;
|
|
@@ -368,23 +328,28 @@ Examples:
|
|
|
368
328
|
limit = parsed;
|
|
369
329
|
}
|
|
370
330
|
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
331
|
+
const result = await cliIpcCall<
|
|
332
|
+
Array<{
|
|
333
|
+
id: string;
|
|
334
|
+
sourceEventName: string;
|
|
335
|
+
sourceChannel: string;
|
|
336
|
+
sourceContextId: string;
|
|
337
|
+
urgency: string;
|
|
338
|
+
dedupeKey: string | null;
|
|
339
|
+
createdAt: string;
|
|
340
|
+
}>
|
|
341
|
+
>("list_notification_events", {
|
|
374
342
|
limit,
|
|
375
343
|
sourceEventName: opts.sourceEventName,
|
|
376
344
|
});
|
|
377
345
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
dedupeKey: row.dedupeKey,
|
|
386
|
-
createdAt: new Date(row.createdAt).toISOString(),
|
|
387
|
-
}));
|
|
346
|
+
if (!result.ok) {
|
|
347
|
+
writeOutput(cmd, { ok: false, error: result.error });
|
|
348
|
+
process.exitCode = 1;
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
const events = result.result!;
|
|
388
353
|
|
|
389
354
|
writeOutput(cmd, { ok: true, events });
|
|
390
355
|
|