@vellumai/assistant 0.11.2 → 0.11.3-staging.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +58 -3
- package/docs/trusted-contact-access.md +9 -5
- package/docs/vellum-doctor.md +195 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/channels.ts +39 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/ingress.ts +10 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/remote-web-pairing.ts +6 -0
- package/node_modules/@vellumai/ces-client/src/index.ts +1 -0
- package/node_modules/@vellumai/ces-client/src/rpc-client.ts +19 -2
- package/node_modules/@vellumai/environments/package.json +2 -1
- package/node_modules/@vellumai/environments/src/__tests__/cloud-assistant-hub-url.test.ts +38 -0
- package/node_modules/@vellumai/environments/src/__tests__/install-layout.test.ts +98 -0
- package/node_modules/@vellumai/environments/src/__tests__/package-boundary.test.ts +5 -5
- package/node_modules/@vellumai/environments/src/index.ts +17 -6
- package/node_modules/@vellumai/environments/src/install-layout.ts +49 -0
- package/node_modules/@vellumai/environments/src/seeds.ts +29 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/channels.ts +39 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/ingress.ts +10 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/remote-web-pairing.ts +6 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +4 -0
- package/node_modules/@vellumai/gateway-client/src/verification-session-contract.ts +91 -6
- package/node_modules/@vellumai/ipc-server-utils/src/endpoint.test.ts +36 -0
- package/node_modules/@vellumai/ipc-server-utils/src/endpoint.ts +142 -0
- package/node_modules/@vellumai/ipc-server-utils/src/index.ts +2 -0
- package/node_modules/@vellumai/ipc-server-utils/src/listen-options.ts +3 -0
- package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.test.ts +15 -1
- package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.ts +17 -2
- package/node_modules/@vellumai/service-contracts/src/channels.ts +39 -0
- package/node_modules/@vellumai/service-contracts/src/ingress.ts +10 -0
- package/node_modules/@vellumai/service-contracts/src/remote-web-pairing.ts +6 -0
- package/node_modules/@vellumai/slack-text/src/index.ts +16 -2
- package/openapi.yaml +589 -30
- package/package.json +1 -1
- package/src/__tests__/agent-image-optimize.test.ts +4 -4
- package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +113 -66
- package/src/__tests__/agent-loop-override-profile.test.ts +38 -48
- package/src/__tests__/agent-loop-subagent-billing-headers.test.ts +166 -0
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +1 -0
- package/src/__tests__/agent-wake-override-profile.test.ts +1 -0
- package/src/__tests__/answered-question-persistence.test.ts +240 -0
- package/src/__tests__/anthropic-provider.test.ts +165 -30
- package/src/__tests__/app-control-flow.test.ts +9 -8
- package/src/__tests__/assistant-event-hub.test.ts +48 -0
- package/src/__tests__/attachments-store-heic-normalize.test.ts +16 -12
- package/src/__tests__/attachments-store.test.ts +130 -68
- package/src/__tests__/attachments.test.ts +36 -36
- package/src/__tests__/background-workers-disk-pressure.test.ts +1 -1
- package/src/__tests__/call-start-guardian-guard.test.ts +18 -4
- package/src/__tests__/canned-reply-release.test.ts +86 -0
- package/src/__tests__/channel-guardian.test.ts +59 -29
- package/src/__tests__/channel-readiness-telegram-remote.test.ts +154 -0
- package/src/__tests__/channel-setup-panel-ack.test.ts +6 -5
- package/src/__tests__/client-os-metadata-persistence.test.ts +103 -4
- package/src/__tests__/compactor-image-manifest-trust.test.ts +1 -1
- package/src/__tests__/consult-deadline.test.ts +65 -0
- package/src/__tests__/conversation-agent-loop.test.ts +438 -2
- package/src/__tests__/conversation-disk-view-integration.test.ts +5 -1
- package/src/__tests__/conversation-disk-view.test.ts +4 -4
- package/src/__tests__/conversation-error.test.ts +22 -3
- package/src/__tests__/conversation-fork-crud.test.ts +5 -1
- package/src/__tests__/conversation-fork-referential.test.ts +352 -0
- package/src/__tests__/conversation-fork-retrospective.test.ts +5 -1
- package/src/__tests__/conversation-group-tools.test.ts +32 -2
- package/src/__tests__/conversation-inference-profile-route.test.ts +27 -1
- package/src/__tests__/conversation-initial-prompt.test.ts +51 -22
- package/src/__tests__/conversation-key-store-bootstrap-cleanup.test.ts +119 -0
- package/src/__tests__/conversation-key-store-origin.test.ts +105 -0
- package/src/__tests__/conversation-list-recency-ordering.test.ts +104 -0
- package/src/__tests__/conversation-origin-at-creation.test.ts +153 -0
- package/src/__tests__/conversation-origin-channel-filter.test.ts +95 -0
- package/src/__tests__/conversation-placement-promotion.test.ts +172 -0
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +123 -0
- package/src/__tests__/conversation-queue.test.ts +433 -1
- package/src/__tests__/conversation-retry-route.test.ts +3 -1
- package/src/__tests__/conversation-routes-hidden-queue.test.ts +64 -1
- package/src/__tests__/conversation-store-ephemeral.test.ts +4 -0
- package/src/__tests__/conversation-store.test.ts +26 -10
- package/src/__tests__/conversation-summarize-route.test.ts +1 -1
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +15 -6
- package/src/__tests__/conversation-surfaces-activation-emit.test.ts +6 -5
- package/src/__tests__/conversation-surfaces-app-control.test.ts +12 -11
- package/src/__tests__/conversation-surfaces-app-open.test.ts +11 -5
- package/src/__tests__/conversation-surfaces-data-persist.test.ts +5 -4
- package/src/__tests__/conversation-surfaces-history-restored-completion.test.ts +967 -0
- package/src/__tests__/conversation-surfaces-persisted-info.test.ts +312 -0
- package/src/__tests__/conversation-surfaces-queued-emit.test.ts +6 -5
- package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +12 -8
- package/src/__tests__/conversation-surfaces-standalone.test.ts +21 -11
- package/src/__tests__/conversation-surfaces-state-update.test.ts +7 -11
- package/src/__tests__/conversation-surfaces-table-action.test.ts +7 -6
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +11 -6
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +9 -6
- package/src/__tests__/conversation-tool-setup-attribution.test.ts +70 -7
- package/src/__tests__/conversation-wait-for-idle.test.ts +6 -11
- package/src/__tests__/credential-prompt-route.test.ts +57 -7
- package/src/__tests__/credential-security-invariants.test.ts +1 -0
- package/src/__tests__/cu-unified-flow.test.ts +89 -28
- package/src/__tests__/custom-group-listing-visibility.test.ts +1 -1
- package/src/__tests__/db-schedule-syntax-migration.test.ts +4 -1
- package/src/__tests__/discord-access-request-privacy.test.ts +366 -0
- package/src/__tests__/discord-requester-notice-privacy.test.ts +87 -0
- package/src/__tests__/disk-pressure-guard.test.ts +55 -55
- package/src/__tests__/disk-pressure-routes.test.ts +10 -10
- package/src/__tests__/disk-pressure-tools.test.ts +2 -2
- package/src/__tests__/disk-usage.test.ts +35 -20
- package/src/__tests__/document-sync-tags.test.ts +379 -0
- package/src/__tests__/document-update-default-surface.test.ts +28 -0
- package/src/__tests__/dynamic-skill-background-guard.test.ts +2 -2
- package/src/__tests__/emit-signal-routing-intent.test.ts +3 -4
- package/src/__tests__/ensure-conversation-exists.test.ts +8 -5
- package/src/__tests__/events-dev-bypass-actor.test.ts +183 -1
- package/src/__tests__/evict-conversations-for-reload.test.ts +90 -0
- package/src/__tests__/file-list-tool.test.ts +12 -10
- package/src/__tests__/file-ops-service.test.ts +151 -44
- package/src/__tests__/file-read-container-boundary.test.ts +137 -0
- package/src/__tests__/file-read-tool.test.ts +21 -9
- package/src/__tests__/file-url-path-guard.test.ts +83 -0
- package/src/__tests__/filesystem-tools.test.ts +82 -66
- package/src/__tests__/guardian-outbound-http.test.ts +8 -8
- package/src/__tests__/helpers/gateway-verification-sessions-stub.ts +14 -1
- package/src/__tests__/helpers/hub-clients.ts +42 -0
- package/src/__tests__/helpers/mock-conversation.ts +46 -0
- package/src/__tests__/helpers/verification-sessions-ipc-sim.ts +61 -57
- package/src/__tests__/history-repair.test.ts +112 -12
- package/src/__tests__/host-bash-proxy.test.ts +10 -5
- package/src/__tests__/host-bash-routes.test.ts +67 -0
- package/src/__tests__/host-browser-proxy.test.ts +2 -2
- package/src/__tests__/host-cu-proxy.test.ts +3 -7
- package/src/__tests__/host-file-proxy.test.ts +3 -7
- package/src/__tests__/host-file-read-tool.test.ts +5 -1
- package/src/__tests__/host-transfer-proxy-targeted.test.ts +6 -4
- package/src/__tests__/http-conversation-lineage.test.ts +2 -5
- package/src/__tests__/http-user-message-parity.test.ts +44 -0
- package/src/__tests__/identity-routes.test.ts +13 -13
- package/src/__tests__/image-conversion.test.ts +29 -26
- package/src/__tests__/image-source-path-reinject.test.ts +2 -2
- package/src/__tests__/inference-profile-session-handler.test.ts +95 -0
- package/src/__tests__/inference-profile-session-ipc.test.ts +25 -0
- package/src/__tests__/introduction-card-resolver.test.ts +6 -1
- package/src/__tests__/list-messages-attachments.test.ts +56 -32
- package/src/__tests__/list-messages-background-tool-completion.test.ts +4 -4
- package/src/__tests__/list-messages-client-message-id.test.ts +2 -2
- package/src/__tests__/list-messages-hidden-metadata.test.ts +16 -16
- package/src/__tests__/list-messages-page-latest.test.ts +61 -61
- package/src/__tests__/list-messages-provider-error.test.ts +6 -6
- package/src/__tests__/list-messages-queued.test.ts +49 -6
- package/src/__tests__/list-messages-system-card.test.ts +4 -4
- package/src/__tests__/list-messages-tool-merge.test.ts +9 -9
- package/src/__tests__/llm-resolver-override-or-default.test.ts +141 -0
- package/src/__tests__/llm-usage-store.test.ts +55 -0
- package/src/__tests__/manual-token-reconciliation.test.ts +45 -0
- package/src/__tests__/mcp-tool-annotations-risk.test.ts +133 -0
- package/src/__tests__/media-stream-server-integration.test.ts +36 -0
- package/src/__tests__/migration-export-http.test.ts +1 -1
- package/src/__tests__/migration-import-commit-http.test.ts +1 -1
- package/src/__tests__/migration-import-preflight-http.test.ts +1 -1
- package/src/__tests__/migration-validate-http.test.ts +1 -1
- package/src/__tests__/mtime-cache.test.ts +65 -3
- package/src/__tests__/notification-platform-adapter.test.ts +104 -0
- package/src/__tests__/notification-schedule-notify-dedup.test.ts +1 -1
- package/src/__tests__/oauth-provider-profiles.test.ts +4 -2
- package/src/__tests__/oauth-provider-seed-logos.test.ts +65 -0
- package/src/__tests__/oauth-provider-serializer.test.ts +17 -0
- package/src/__tests__/oauth-providers-routes.test.ts +1 -0
- package/src/__tests__/openai-responses-prompt-cache.test.ts +5 -2
- package/src/__tests__/path-policy.test.ts +164 -1
- package/src/__tests__/persist-media-references.test.ts +2 -2
- package/src/__tests__/persist-unsendable-image-downscale.test.ts +5 -5
- package/src/__tests__/persist-unsendable-image.test.ts +23 -23
- package/src/__tests__/persona-resolver.test.ts +154 -0
- package/src/__tests__/plugin-api-webhook-url.test.ts +170 -0
- package/src/__tests__/plugin-import-boundary-guard.test.ts +6 -0
- package/src/__tests__/processing-flag-persist-failure.test.ts +15 -10
- package/src/__tests__/profile-availability-incomplete.test.ts +113 -0
- package/src/__tests__/profiler-routes.test.ts +13 -13
- package/src/__tests__/prompt-cache-cross-turn-stability.test.ts +593 -0
- package/src/__tests__/proxy-approval-callback.test.ts +3 -3
- package/src/__tests__/queued-message-cancel-and-steer.test.ts +189 -0
- package/src/__tests__/queued-message-steer-actor-scoping.test.ts +164 -0
- package/src/__tests__/resolve-trust-class.test.ts +20 -0
- package/src/__tests__/run-conversation-turn-persistence.test.ts +1 -1
- package/src/__tests__/run-due-schedules.test.ts +174 -0
- package/src/__tests__/runtime-attachment-metadata.test.ts +15 -7
- package/src/__tests__/scaffold-managed-skill-tool.test.ts +166 -0
- package/src/__tests__/schedule-routes.test.ts +730 -8
- package/src/__tests__/schedule-store.test.ts +540 -0
- package/src/__tests__/schedule-tools.test.ts +103 -0
- package/src/__tests__/scheduler-wake.test.ts +5 -0
- package/src/__tests__/secret-routes-platform-proxy.test.ts +29 -1
- package/src/__tests__/secure-keys.test.ts +91 -0
- package/src/__tests__/server-history-render.test.ts +97 -7
- package/src/__tests__/size-guard.test.ts +8 -8
- package/src/__tests__/skill-docs-sync-guard.test.ts +3 -2
- package/src/__tests__/skill-tool-factory.test.ts +247 -0
- package/src/__tests__/skills-install-staging.test.ts +15 -6
- package/src/__tests__/slack-edit-ordering-characterization.test.ts +103 -0
- package/src/__tests__/slack-inbound-verification.test.ts +4 -1
- package/src/__tests__/slack-mention-binding-invariance.test.ts +103 -0
- package/src/__tests__/slack-mention-provider-leak-audit.test.ts +135 -0
- package/src/__tests__/starter-task-flow.test.ts +5 -4
- package/src/__tests__/steer-on-enqueue-question.test.ts +3 -2
- package/src/__tests__/stt-language-catalog-parity.test.ts +38 -0
- package/src/__tests__/subagent-allowlist-validation.test.ts +26 -4
- package/src/__tests__/subagent-cron-run-attribution.test.ts +301 -0
- package/src/__tests__/subagent-disposal.test.ts +10 -0
- package/src/__tests__/subagent-fork-notifications.test.ts +10 -0
- package/src/__tests__/subagent-fork-prompt-role.test.ts +85 -11
- package/src/__tests__/subagent-fork-spawn.test.ts +15 -7
- package/src/__tests__/subagent-manager-notify.test.ts +148 -0
- package/src/__tests__/subagent-notify-parent.test.ts +1 -1
- package/src/__tests__/subagent-persistence.test.ts +141 -0
- package/src/__tests__/subagent-role-registry.test.ts +172 -63
- package/src/__tests__/subagent-role-resolution.test.ts +88 -0
- package/src/__tests__/subagent-spawn-and-await.test.ts +48 -0
- package/src/__tests__/subagent-spawn-tool-fork.test.ts +111 -10
- package/src/__tests__/subagent-terminal-message.test.ts +88 -1
- package/src/__tests__/subagent-tool-gate-mode.test.ts +225 -10
- package/src/__tests__/subagent-tools.test.ts +1901 -108
- package/src/__tests__/surface-completion-compaction-boundary.test.ts +124 -0
- package/src/__tests__/surface-completion-in-flight-snapshot.test.ts +298 -0
- package/src/__tests__/system-prompt.test.ts +82 -7
- package/src/__tests__/tool-grant-request-escalation.test.ts +40 -1
- package/src/__tests__/tool-result-spool.test.ts +74 -18
- package/src/__tests__/tool-side-effects-documents.test.ts +174 -0
- package/src/__tests__/tool-side-effects-hook-failures.test.ts +129 -0
- package/src/__tests__/tools-audio-read.test.ts +10 -10
- package/src/__tests__/tools-get-route.test.ts +85 -12
- package/src/__tests__/tools-list-cli.test.ts +171 -0
- package/src/__tests__/top-level-renderer.test.ts +54 -1
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +68 -1
- package/src/__tests__/trusted-contact-multichannel.test.ts +4 -1
- package/src/__tests__/turn-tail-chain.test.ts +135 -0
- package/src/__tests__/ui-choice-copy-surfaces.test.ts +6 -4
- package/src/__tests__/ui-visual-surface.test.ts +5 -4
- package/src/__tests__/ui-work-result-surface.test.ts +5 -4
- package/src/__tests__/unified-turn-context-visible-app.test.ts +7 -8
- package/src/__tests__/usage-routes.test.ts +62 -0
- package/src/__tests__/verification-outbound-delivery.test.ts +176 -0
- package/src/__tests__/visible-app-context.test.ts +20 -4
- package/src/__tests__/web-search-history.test.ts +96 -0
- package/src/__tests__/workspace-migration-139-clear-renamed-cost-profile-label.test.ts +6 -6
- package/src/__tests__/workspace-migration-140-repair-seed-pinned-memory-v3-live.test.ts +330 -0
- package/src/acp/failure-error.ts +3 -5
- package/src/agent/attachments.ts +26 -24
- package/src/agent/history-repair/history-repair.ts +27 -26
- package/src/agent/image-optimize.ts +6 -6
- package/src/agent/loop.ts +40 -22
- package/src/agent/message-types.ts +3 -3
- package/src/api/constants/document-tools.ts +55 -0
- package/src/api/events/question-answered.ts +53 -0
- package/src/api/events/tool-result.ts +7 -0
- package/src/api/index.ts +13 -0
- package/src/api/responses/conversation-message.ts +11 -0
- package/src/api/surfaces-oauth-connect.test.ts +96 -0
- package/src/api/surfaces.ts +36 -8
- package/src/approvals/guardian-channel-delivery.ts +83 -0
- package/src/approvals/guardian-expiry-notifier.ts +13 -11
- package/src/approvals/guardian-request-resolvers.ts +222 -135
- package/src/calls/__tests__/voice-session-bridge.test.ts +50 -0
- package/src/calls/media-stream-server.ts +9 -1
- package/src/calls/voice-session-bridge.ts +38 -0
- package/src/channels/__tests__/gateway-verification-sessions.test.ts +3 -3
- package/src/channels/config.ts +7 -2
- package/src/channels/gateway-verification-sessions.ts +7 -2
- package/src/channels/types.ts +7 -1
- package/src/cli/commands/__tests__/cache.test.ts +7 -4
- package/src/cli/commands/__tests__/cli-test-harness.ts +82 -0
- package/src/cli/commands/__tests__/conversations-wake.test.ts +51 -6
- package/src/cli/commands/__tests__/inference-models.test.ts +14 -0
- package/src/cli/commands/__tests__/inference-profiles.test.ts +44 -1
- package/src/cli/commands/__tests__/inference-providers.test.ts +7 -0
- package/src/cli/commands/__tests__/plugins.test.ts +692 -0
- package/src/cli/commands/__tests__/schedules.test.ts +136 -37
- package/src/cli/commands/conversations.ts +7 -3
- package/src/cli/commands/credentials.help.ts +7 -0
- package/src/cli/commands/inference-profiles.ts +9 -3
- package/src/cli/commands/inference.help.ts +16 -2
- package/src/cli/commands/mcp.help.ts +4 -2
- package/src/cli/commands/memory/memory-retrospective.ts +18 -0
- package/src/cli/commands/notifications.ts +3 -6
- package/src/cli/commands/oauth/connect-surface-guidance.test.ts +16 -0
- package/src/cli/commands/oauth/connect-surface-guidance.ts +25 -7
- package/src/cli/commands/oauth/connect.test.ts +26 -1
- package/src/cli/commands/oauth/connect.ts +4 -1
- package/src/cli/commands/oauth/index.help.ts +3 -1
- package/src/cli/commands/oauth/providers.ts +3 -0
- package/src/cli/commands/plugins.help.ts +25 -2
- package/src/cli/commands/plugins.ts +289 -10
- package/src/cli/commands/schedules.help.ts +14 -12
- package/src/cli/commands/schedules.ts +19 -5
- package/src/cli/commands/tools.help.ts +4 -2
- package/src/cli/commands/tools.ts +38 -0
- package/src/cli/lib/__tests__/inspect-plugin.test.ts +1 -0
- package/src/cli/lib/__tests__/install-from-github.test.ts +79 -0
- package/src/cli/lib/__tests__/install-from-platform.test.ts +47 -1
- package/src/cli/lib/__tests__/plugin-surfaces.test.ts +86 -7
- package/src/cli/lib/__tests__/upgrade-plugin.test.ts +122 -0
- package/src/cli/lib/install-from-github.ts +61 -0
- package/src/cli/lib/install-from-platform.ts +13 -2
- package/src/cli/lib/plugin-surfaces.ts +124 -4
- package/src/cli/lib/upgrade-plugin.ts +18 -0
- package/src/cli.ts +1 -1
- package/src/config/__tests__/deployment-context-defaults.test.ts +73 -0
- package/src/config/__tests__/memory-retrospective-schema.test.ts +40 -0
- package/src/config/__tests__/plugin-updates-schema.test.ts +43 -0
- package/src/config/__tests__/profile-tool-support.test.ts +131 -0
- package/src/config/bundled-skills/AGENTS.md +1 -1
- package/src/config/bundled-skills/app-builder/SKILL.md +1 -1
- package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +3 -3
- package/src/config/bundled-skills/schedule/SKILL.md +5 -1
- package/src/config/bundled-skills/schedule/TOOLS.json +2 -2
- package/src/config/bundled-skills/settings/TOOLS.json +2 -2
- package/src/config/bundled-skills/settings/tools/voice-config-update.ts +1 -0
- package/src/config/bundled-skills/subagent/SKILL.md +53 -22
- package/src/config/bundled-skills/subagent/TOOLS.json +14 -13
- package/src/config/bundled-skills/visualize/SKILL.md +1 -1
- package/src/config/default-profile-catalog.ts +6 -2
- package/src/config/feature-flag-registry.json +25 -17
- package/src/config/llm-resolver.ts +45 -15
- package/src/config/loader.ts +70 -1
- package/src/config/profile-tool-support.ts +110 -0
- package/src/config/sanitize-for-transfer.ts +11 -0
- package/src/config/schema.ts +4 -0
- package/src/config/schemas/__tests__/stt.test.ts +20 -5
- package/src/config/schemas/channels.ts +13 -0
- package/src/config/schemas/memory-retrospective.ts +25 -0
- package/src/config/schemas/plugin-updates.ts +55 -0
- package/src/config/schemas/services.ts +8 -4
- package/src/config/schemas/stt.ts +17 -5
- package/src/config/schemas/timeouts.ts +1 -1
- package/src/contacts/__tests__/guardian-delivery-reader.test.ts +16 -0
- package/src/contacts/guardian-delivery-reader.ts +29 -2
- package/src/context/compactor.ts +4 -4
- package/src/context/post-turn-tool-result-truncation.ts +32 -16
- package/src/context/strip-injections.ts +42 -0
- package/src/context/tool-result-spool.ts +32 -18
- package/src/credential-execution/ces-runtime.ts +3 -0
- package/src/credential-execution/client.ts +22 -1
- package/src/credential-execution/process-manager.test.ts +99 -0
- package/src/credential-execution/process-manager.ts +62 -16
- package/src/daemon/__tests__/abort-null-controller.test.ts +141 -5
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +8 -12
- package/src/daemon/__tests__/install-assistant-command.test.ts +234 -0
- package/src/daemon/__tests__/turn-tail-assistant-reply-notify.test.ts +2 -4
- package/src/daemon/__tests__/turn-tail-deleted-conversation.test.ts +20 -29
- package/src/daemon/channel-ui-capability.ts +4 -4
- package/src/daemon/conversation-agent-loop-handlers.ts +117 -61
- package/src/daemon/conversation-agent-loop.ts +318 -148
- package/src/daemon/conversation-attachments.ts +1 -1
- package/src/daemon/conversation-error.ts +8 -1
- package/src/daemon/conversation-initial-prompt.ts +16 -38
- package/src/daemon/conversation-lifecycle.ts +154 -32
- package/src/daemon/conversation-messaging.ts +106 -43
- package/src/daemon/conversation-process.ts +131 -33
- package/src/daemon/conversation-queue-manager.ts +10 -0
- package/src/daemon/conversation-runtime-assembly.ts +9 -4
- package/src/daemon/conversation-store.ts +52 -3
- package/src/daemon/conversation-surface-state.ts +9 -0
- package/src/daemon/conversation-surfaces.ts +403 -210
- package/src/daemon/conversation-tool-setup.ts +56 -7
- package/src/daemon/conversation-turn-finalize.ts +134 -89
- package/src/daemon/conversation.ts +111 -27
- package/src/daemon/disk-pressure-guard-lifecycle.ts +2 -2
- package/src/daemon/disk-pressure-guard.ts +3 -3
- package/src/daemon/doordash-steps.ts +5 -5
- package/src/daemon/external-plugins-bootstrap.ts +7 -1
- package/src/daemon/handlers/config-channels.ts +48 -5
- package/src/daemon/handlers/conversation-history.ts +1 -1
- package/src/daemon/handlers/conversations.ts +62 -17
- package/src/daemon/handlers/shared.ts +12 -0
- package/src/daemon/handlers/skills.ts +11 -1
- package/src/daemon/identity-helpers.ts +38 -10
- package/src/daemon/install-assistant-command.ts +322 -0
- package/src/daemon/lifecycle.ts +14 -3
- package/src/daemon/message-types/conversations.ts +6 -7
- package/src/daemon/message-types/sync.ts +1 -0
- package/src/daemon/persist-media-references.ts +23 -14
- package/src/daemon/process-message.ts +6 -6
- package/src/daemon/tool-setup-types.ts +19 -122
- package/src/daemon/tool-side-effects.ts +17 -94
- package/src/daemon/trust-context-types.ts +39 -0
- package/src/daemon/trust-context.ts +14 -6
- package/src/daemon/turn-tail-chain.ts +73 -0
- package/src/daemon/web-search-history.ts +47 -33
- package/src/heartbeat/heartbeat-service.ts +6 -6
- package/src/ipc/__tests__/socket-path.test.ts +21 -0
- package/src/ipc/assistant-server.ts +17 -10
- package/src/ipc/cli-client.ts +10 -1
- package/src/ipc/routes/__tests__/documents-sync-ipc-routes.test.ts +56 -0
- package/src/ipc/routes/documents-sync-ipc-routes.ts +42 -0
- package/src/ipc/socket-cleanup.ts +9 -7
- package/src/ipc/socket-path.ts +4 -96
- package/src/live-voice/__tests__/live-voice-archive.test.ts +16 -16
- package/src/live-voice/__tests__/live-voice-attach-image.test.ts +209 -0
- package/src/live-voice/__tests__/live-voice-connection.test.ts +20 -0
- package/src/live-voice/__tests__/live-voice-integration.test.ts +7 -5
- package/src/live-voice/__tests__/live-voice-session-telemetry.test.ts +265 -0
- package/src/live-voice/__tests__/live-voice-stt.test.ts +6 -1
- package/src/live-voice/__tests__/live-voice-vad.test.ts +35 -15
- package/src/live-voice/__tests__/protocol.test.ts +52 -0
- package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +3 -0
- package/src/live-voice/live-voice-archive.ts +13 -13
- package/src/live-voice/live-voice-connection.ts +7 -1
- package/src/live-voice/live-voice-photo.ts +169 -0
- package/src/live-voice/live-voice-session.ts +108 -4
- package/src/live-voice/protocol.ts +89 -1
- package/src/mcp/client.ts +10 -0
- package/src/messaging/providers/__tests__/callback-routing.test.ts +5 -1
- package/src/messaging/providers/__tests__/transport-dispatch.test.ts +66 -4
- package/src/messaging/providers/callback-routing.ts +1 -0
- package/src/messaging/providers/discord/api.ts +312 -0
- package/src/messaging/providers/discord/dm-delivery.test.ts +204 -0
- package/src/messaging/providers/discord/render.test.ts +204 -0
- package/src/messaging/providers/discord/render.ts +195 -0
- package/src/messaging/providers/discord/send.test.ts +179 -0
- package/src/messaging/providers/discord/send.ts +212 -0
- package/src/messaging/providers/discord/transport.ts +81 -0
- package/src/messaging/providers/index.ts +3 -1
- package/src/messaging/providers/retry-policy.test.ts +247 -0
- package/src/messaging/providers/retry-policy.ts +206 -0
- package/src/messaging/providers/slack/mention-source.test.ts +285 -0
- package/src/messaging/providers/slack/mention-source.ts +287 -0
- package/src/messaging/providers/telegram-bot/api.ts +47 -130
- package/src/messaging/providers/whatsapp/api.ts +47 -136
- package/src/monitoring/__tests__/db-integrity-sample.test.ts +4 -1
- package/src/monitoring/__tests__/plugin-auto-update.test.ts +332 -0
- package/src/monitoring/db-integrity-sample.ts +6 -1
- package/src/monitoring/plugin-auto-update.ts +359 -0
- package/src/monitoring/resource-sampler.ts +21 -5
- package/src/monitoring/worker.ts +13 -0
- package/src/notifications/__tests__/assistant-reply-producer.test.ts +375 -2
- package/src/notifications/__tests__/broadcaster.test.ts +37 -1
- package/src/notifications/__tests__/copy-composer.test.ts +165 -0
- package/src/notifications/__tests__/emit-signal-pipeline-failure.test.ts +205 -0
- package/src/notifications/__tests__/notification-utils.test.ts +249 -0
- package/src/notifications/adapters/platform.ts +31 -2
- package/src/notifications/assistant-reply-producer.ts +79 -32
- package/src/notifications/broadcaster.ts +30 -10
- package/src/notifications/copy-composer.ts +69 -0
- package/src/notifications/emit-signal.ts +82 -15
- package/src/notifications/events-store.ts +10 -2
- package/src/notifications/home-feed-side-effect.ts +6 -3
- package/src/notifications/notification-utils.ts +173 -5
- package/src/notifications/signal.ts +12 -0
- package/src/oauth/AGENTS.md +4 -2
- package/src/oauth/byo-connection.ts +6 -1
- package/src/oauth/credential-token-resolver.ts +3 -10
- package/src/oauth/manual-token-connection.ts +29 -64
- package/src/oauth/manual-token-providers.ts +62 -0
- package/src/oauth/provider-serializer.ts +13 -0
- package/src/oauth/seed-providers.ts +62 -11
- package/src/onboarding/onboarding-events-store.ts +91 -1
- package/src/permissions/question-prompter.test.ts +4 -0
- package/src/permissions/question-prompter.ts +21 -4
- package/src/persistence/__tests__/conversation-lineage.test.ts +248 -0
- package/src/persistence/attachments-store.ts +15 -15
- package/src/persistence/conversation-attention-store.ts +30 -10
- package/src/persistence/conversation-bootstrap.ts +17 -0
- package/src/persistence/conversation-crud.ts +363 -97
- package/src/persistence/conversation-group-migration.ts +1 -1
- package/src/persistence/conversation-key-store.ts +38 -10
- package/src/persistence/conversation-lineage.ts +226 -0
- package/src/persistence/conversation-plugin-facade.ts +28 -3
- package/src/persistence/conversation-queries.ts +207 -33
- package/src/persistence/conversation-types.ts +107 -1
- package/src/persistence/jobs-store.ts +32 -8
- package/src/persistence/llm-usage-store.ts +22 -0
- package/src/persistence/migrations/361-normalize-managed-connection-rows.test.ts +168 -0
- package/src/persistence/migrations/361-normalize-managed-connection-rows.ts +76 -0
- package/src/persistence/migrations/362-add-conversation-subagent-kind.test.ts +187 -0
- package/src/persistence/migrations/362-add-conversation-subagent-kind.ts +93 -0
- package/src/persistence/migrations/363-backfill-schedule-inference-profile.test.ts +229 -0
- package/src/persistence/migrations/363-backfill-schedule-inference-profile.ts +127 -0
- package/src/persistence/migrations/364-add-schedule-source-key.test.ts +120 -0
- package/src/persistence/migrations/364-add-schedule-source-key.ts +43 -0
- package/src/persistence/migrations/365-add-conversation-fork-strategy.ts +27 -0
- package/src/persistence/schema/conversations.ts +32 -0
- package/src/persistence/schema/infrastructure.ts +3 -0
- package/src/persistence/steps.ts +30 -0
- package/src/persistence/subagent-store.ts +148 -6
- package/src/platform/managed-speech.test.ts +20 -0
- package/src/platform/managed-speech.ts +9 -0
- package/src/plugin-api/index.ts +8 -0
- package/src/plugin-api/webhook-url.ts +151 -0
- package/src/plugins/__tests__/installed-plugin-dirs.test.ts +82 -0
- package/src/plugins/__tests__/source-fingerprint.test.ts +5 -1
- package/src/plugins/collect-source-versions.ts +4 -27
- package/src/plugins/defaults/exploration-drift/hooks/post-tool-use.ts +5 -5
- package/src/plugins/defaults/exploration-drift/package.json +1 -1
- package/src/plugins/defaults/image-recovery/hooks/post-model-call.ts +4 -2
- package/src/plugins/defaults/image-recovery/recover.ts +67 -57
- package/src/plugins/defaults/index.ts +1 -1
- package/src/plugins/defaults/memory/__tests__/conversation-queries.test.ts +64 -18
- package/src/plugins/defaults/memory/__tests__/jobs-worker-outcome-contract.test.ts +242 -0
- package/src/plugins/defaults/memory/__tests__/jobs-worker-retrospective-sweep.test.ts +24 -1
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-enqueue.test.ts +48 -3
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +511 -19
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-prompt.test.ts +39 -3
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-provider-path.test.ts +493 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-wake-chain.test.ts +5 -4
- package/src/plugins/defaults/memory/__tests__/memory-tier-boundary-guard.test.ts +5 -1
- package/src/plugins/defaults/memory/job-handlers.ts +87 -5
- package/src/plugins/defaults/memory/jobs-worker.ts +60 -6
- package/src/plugins/defaults/memory/memory-retrospective-constants.ts +11 -0
- package/src/plugins/defaults/memory/memory-retrospective-enqueue.ts +29 -0
- package/src/plugins/defaults/memory/memory-retrospective-job.ts +342 -60
- package/src/plugins/defaults/memory/memory-retrospective-prompt.ts +23 -3
- package/src/plugins/defaults/memory/substrate/consolidation-lock.ts +9 -4
- package/src/plugins/defaults/memory/substrate/sweep-job.ts +7 -0
- package/src/plugins/defaults/memory/v1/graph/injection.ts +1 -1
- package/src/plugins/defaults/memory/v2/router.ts +8 -0
- package/src/plugins/defaults/turn-context/unified-turn-context.ts +1 -2
- package/src/plugins/external-plugin-loader.ts +17 -8
- package/src/plugins/installed-plugin-dirs.ts +101 -0
- package/src/plugins/mtime-cache.ts +34 -22
- package/src/plugins/types.ts +69 -8
- package/src/prompts/persona-resolver.ts +6 -2
- package/src/prompts/system-prompt.ts +72 -17
- package/src/providers/__tests__/inference.test.ts +40 -0
- package/src/providers/__tests__/preflight-resolved-config.test.ts +58 -1
- package/src/providers/__tests__/retry-callsite.test.ts +67 -0
- package/src/providers/__tests__/vellum-connection-routing.test.ts +42 -11
- package/src/providers/anthropic/client.ts +112 -95
- package/src/providers/connection-resolution.ts +35 -1
- package/src/providers/gemini/client.ts +5 -5
- package/src/providers/inference/adapter-factory.ts +16 -10
- package/src/providers/inference/auth.ts +16 -0
- package/src/providers/inference/connection-availability.ts +164 -12
- package/src/providers/inference/connections.ts +25 -1
- package/src/providers/media-resolve.ts +21 -11
- package/src/providers/model-catalog.ts +15 -0
- package/src/providers/openai/chat-completions-provider.ts +4 -4
- package/src/providers/openai/responses-provider.ts +12 -25
- package/src/providers/registry.ts +9 -4
- package/src/providers/retry.ts +25 -0
- package/src/providers/server-tool-pairing.ts +134 -0
- package/src/providers/speech-to-text/__tests__/resolve.test.ts +187 -6
- package/src/providers/speech-to-text/deepgram.ts +1 -0
- package/src/providers/speech-to-text/resolve.ts +80 -10
- package/src/providers/speech-to-text/vellum-managed.ts +7 -1
- package/src/providers/speech-to-text/vellum-speech-relay-connection.ts +3 -1
- package/src/providers/types.ts +26 -6
- package/src/providers/vellum-model-routing.ts +6 -7
- package/src/runtime/AGENTS.md +2 -0
- package/src/runtime/__tests__/agent-wake.test.ts +16 -16
- package/src/runtime/__tests__/background-job-runner.test.ts +0 -144
- package/src/runtime/__tests__/desktop-presence.test.ts +162 -0
- package/src/runtime/agent-wake.ts +63 -24
- package/src/runtime/assistant-event-hub.ts +87 -12
- package/src/runtime/auth/__tests__/guard-tests.test.ts +2 -0
- package/src/runtime/auth/__tests__/scopes.test.ts +20 -0
- package/src/runtime/auth/same-actor.ts +56 -8
- package/src/runtime/auth/scopes.ts +12 -0
- package/src/runtime/auth/types.ts +2 -0
- package/src/runtime/background-job-runner.ts +5 -27
- package/src/runtime/channel-readiness-service.ts +59 -3
- package/src/runtime/channel-readiness-types.ts +18 -0
- package/src/runtime/desktop-presence.ts +69 -0
- package/src/runtime/http-server.ts +12 -0
- package/src/runtime/local-actor-identity.ts +11 -9
- package/src/runtime/migrations/__tests__/vbundle-symlink-streaming-importer.test.ts +0 -0
- package/src/runtime/routes/__tests__/channel-verification-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/client-routes.test.ts +186 -14
- package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +547 -1
- package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +162 -7
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +14 -10
- package/src/runtime/routes/__tests__/inference-profiles-routes.test.ts +340 -3
- package/src/runtime/routes/__tests__/llm-call-sites-routes.test.ts +28 -1
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +173 -1
- package/src/runtime/routes/__tests__/question-routes.test.ts +64 -0
- package/src/runtime/routes/__tests__/retrospective-routes.test.ts +20 -0
- package/src/runtime/routes/__tests__/skill-history-route.test.ts +116 -0
- package/src/runtime/routes/__tests__/wake-conversation-routes.test.ts +60 -2
- package/src/runtime/routes/archive-utils.ts +16 -12
- package/src/runtime/routes/attachment-routes.ts +13 -6
- package/src/runtime/routes/canned-reply-release.ts +54 -0
- package/src/runtime/routes/channel-verification-routes.ts +2 -27
- package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +5 -0
- package/src/runtime/routes/client-routes.ts +114 -2
- package/src/runtime/routes/conversation-cli-routes.ts +10 -12
- package/src/runtime/routes/conversation-list-routes.ts +59 -10
- package/src/runtime/routes/conversation-management-routes.ts +47 -18
- package/src/runtime/routes/conversation-query-routes.ts +32 -53
- package/src/runtime/routes/conversation-routes.ts +360 -293
- package/src/runtime/routes/credential-prompt-routes.ts +23 -2
- package/src/runtime/routes/debug-routes.ts +4 -1
- package/src/runtime/routes/default-provider-routes.ts +7 -11
- package/src/runtime/routes/documents-routes.ts +44 -1
- package/src/runtime/routes/events-routes.ts +28 -1
- package/src/runtime/routes/host-app-control-routes.ts +2 -0
- package/src/runtime/routes/host-bash-routes.ts +2 -0
- package/src/runtime/routes/host-browser-routes.ts +2 -0
- package/src/runtime/routes/host-cu-routes.ts +2 -0
- package/src/runtime/routes/host-file-routes.ts +2 -0
- package/src/runtime/routes/host-transfer-routes.ts +4 -0
- package/src/runtime/routes/identity-routes.ts +6 -6
- package/src/runtime/routes/inbound-message-handler.ts +5 -5
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +7 -3
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +14 -0
- package/src/runtime/routes/inbound-stages/bootstrap-intercept.ts +2 -2
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +14 -11
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +14 -17
- package/src/runtime/routes/inference-profile-availability-guard.ts +171 -0
- package/src/runtime/routes/inference-profile-session-handler.ts +26 -2
- package/src/runtime/routes/inference-profile-session-routes.ts +2 -1
- package/src/runtime/routes/inference-profiles-routes.ts +152 -73
- package/src/runtime/routes/inference-provider-connection-routes.ts +0 -16
- package/src/runtime/routes/llm-call-sites-routes.ts +13 -0
- package/src/runtime/routes/log-export-routes.ts +1 -1
- package/src/runtime/routes/notification-routes.ts +0 -14
- package/src/runtime/routes/oauth-providers.ts +1 -0
- package/src/runtime/routes/plugins-routes.ts +106 -1
- package/src/runtime/routes/profiler-routes.ts +4 -2
- package/src/runtime/routes/question-routes.ts +28 -10
- package/src/runtime/routes/retrospective-routes.ts +9 -3
- package/src/runtime/routes/schedule-routes.ts +210 -12
- package/src/runtime/routes/secret-routes.ts +40 -23
- package/src/runtime/routes/settings-routes.ts +41 -13
- package/src/runtime/routes/skills-routes.ts +79 -0
- package/src/runtime/routes/ui-snapshot-routes.ts +1 -0
- package/src/runtime/routes/wake-conversation-routes.ts +23 -0
- package/src/runtime/services/__tests__/conversation-serializer.test.ts +1 -0
- package/src/runtime/services/conversation-serializer.ts +24 -9
- package/src/runtime/sync/documents-sidecar-publish.test.ts +101 -0
- package/src/runtime/sync/resource-sync-events.ts +79 -1
- package/src/runtime/sync/worker-daemon-notify.test.ts +34 -0
- package/src/runtime/sync/worker-daemon-notify.ts +44 -6
- package/src/runtime/verification-outbound-actions.ts +250 -222
- package/src/runtime/verification-templates.ts +41 -30
- package/src/schedule/__tests__/plugin-schedule-declarations.test.ts +614 -0
- package/src/schedule/__tests__/plugin-schedule-reconciler.test.ts +1066 -0
- package/src/schedule/inference-profile.ts +64 -3
- package/src/schedule/plugin-schedule-declarations.ts +518 -0
- package/src/schedule/plugin-schedule-reconciler.ts +605 -0
- package/src/schedule/plugin-schedules-gate.ts +23 -0
- package/src/schedule/schedule-store.ts +520 -26
- package/src/schedule/scheduler.ts +38 -0
- package/src/security/credential-backend.ts +51 -4
- package/src/security/encrypted-store.ts +64 -42
- package/src/security/secure-keys.ts +55 -7
- package/src/skills/catalog-install.ts +20 -7
- package/src/skills/inline-command-runner.ts +2 -7
- package/src/skills/skill-history.test.ts +269 -0
- package/src/skills/skill-history.ts +250 -0
- package/src/skills/skillssh-registry.ts +1 -1
- package/src/stt/daemon-batch-transcriber.ts +8 -6
- package/src/subagent/__tests__/consult-prompt.test.ts +25 -0
- package/src/subagent/consult-prompt.ts +3 -1
- package/src/subagent/consult-transcript.ts +1 -1
- package/src/subagent/manager.ts +304 -44
- package/src/subagent/progress-events.ts +35 -0
- package/src/subagent/role-resolution.ts +88 -0
- package/src/subagent/types.ts +302 -67
- package/src/subagent/validate-allowlists.ts +3 -4
- package/src/telegram/__tests__/webhook-health.test.ts +73 -1
- package/src/telegram/webhook-health.ts +101 -3
- package/src/telemetry/__tests__/telemetry-event-fixtures.ts +2 -0
- package/src/telemetry/activation-funnel.ts +6 -1
- package/src/telemetry/live-voice-funnel.ts +75 -0
- package/src/telemetry/telemetry-event-sources.ts +6 -0
- package/src/telemetry/telemetry-wire-source.json +1 -1
- package/src/telemetry/telemetry-wire.generated.ts +2 -0
- package/src/telemetry/types.ts +23 -4
- package/src/telemetry/usage-telemetry-reporter.test.ts +4 -0
- package/src/tools/__tests__/subagent-workflow-tool-input-schemas.test.ts +1 -1
- package/src/tools/ask-question/ask-question-tool.test.ts +118 -3
- package/src/tools/ask-question/ask-question-tool.ts +56 -2
- package/src/tools/browser/browser-execution.ts +1 -1
- package/src/tools/calls/call-start.ts +8 -5
- package/src/tools/conversation-groups/move_to_group.ts +10 -12
- package/src/tools/document/document-tool.ts +11 -4
- package/src/tools/execution-timeout.ts +9 -2
- package/src/tools/executor.ts +7 -6
- package/src/tools/filesystem/edit.ts +1 -1
- package/src/tools/filesystem/list.ts +1 -1
- package/src/tools/filesystem/read.ts +7 -13
- package/src/tools/filesystem/search.ts +23 -21
- package/src/tools/filesystem/write.ts +4 -1
- package/src/tools/host-filesystem/edit.ts +7 -2
- package/src/tools/host-filesystem/read.ts +21 -8
- package/src/tools/host-filesystem/write.ts +10 -2
- package/src/tools/host-terminal/host-shell.ts +2 -2
- package/src/tools/mcp/mcp-tool-factory.ts +25 -1
- package/src/tools/permission-checker.ts +8 -3
- package/src/tools/schedule/delete.ts +13 -1
- package/src/tools/schedule/list.ts +14 -3
- package/src/tools/schedule/update.ts +56 -33
- package/src/tools/shared/filesystem/audio-read.ts +6 -4
- package/src/tools/shared/filesystem/file-ops-service.ts +176 -116
- package/src/tools/shared/filesystem/image-read.ts +12 -12
- package/src/tools/shared/filesystem/path-policy.ts +70 -5
- package/src/tools/shared/filesystem/size-guard.ts +6 -6
- package/src/tools/shared/input-misuse.ts +72 -0
- package/src/tools/skills/scaffold-managed.ts +82 -0
- package/src/tools/skills/skill-tool-factory.ts +14 -1
- package/src/tools/subagent/consult-deadline.ts +12 -7
- package/src/tools/subagent/message.ts +3 -1
- package/src/tools/subagent/read.ts +66 -4
- package/src/tools/subagent/spawn.ts +500 -78
- package/src/tools/tool-approval-handler.ts +45 -4
- package/src/tools/types.ts +22 -3
- package/src/tools/ui-surface/surface-shape-docs.ts +1 -1
- package/src/tools/ui-surface/visual-validation.ts +2 -0
- package/src/usage/__tests__/subagent-attribution.test.ts +109 -0
- package/src/usage/subagent-attribution.ts +108 -0
- package/src/util/__tests__/sqlite-retry.test.ts +112 -0
- package/src/util/abort-reasons.ts +16 -0
- package/src/util/ansi.ts +44 -0
- package/src/util/disk-usage.ts +17 -13
- package/src/util/image-conversion.ts +20 -13
- package/src/util/schedule-source-key.ts +23 -0
- package/src/util/worker-process.ts +7 -1
- package/src/workspace/git-service.ts +33 -9
- package/src/workspace/migrations/140-repair-seed-pinned-memory-v3-live.ts +260 -0
- package/src/workspace/migrations/141-stt-english-default-to-multilingual.ts +111 -0
- package/src/workspace/migrations/__tests__/141-stt-english-default-to-multilingual.test.ts +126 -0
- package/src/workspace/migrations/registry.ts +4 -0
- package/src/workspace/top-level-renderer.ts +15 -2
- package/src/__tests__/tool-side-effects-slack-dm.test.ts +0 -357
- package/src/daemon/install-symlink.ts +0 -207
- package/src/notifications/deferred-emit.ts +0 -147
|
@@ -7,10 +7,14 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { createRequire } from "node:module";
|
|
10
|
+
import { join } from "node:path";
|
|
10
11
|
|
|
11
12
|
import type { Command } from "commander";
|
|
12
13
|
|
|
13
14
|
import { cliIpcCall } from "../../ipc/cli-client.js";
|
|
15
|
+
import { stripAnsiAndControlChars } from "../../util/ansi.js";
|
|
16
|
+
import { getWorkspacePluginsDir } from "../../util/platform.js";
|
|
17
|
+
import { truncate } from "../../util/truncate.js";
|
|
14
18
|
import { yellow } from "../lib/cli-colors.js";
|
|
15
19
|
import { applyCommandHelp, subcommand } from "../lib/cli-command-help.js";
|
|
16
20
|
import { confirmPrompt } from "../lib/confirm-prompt.js";
|
|
@@ -20,6 +24,7 @@ import type {
|
|
|
20
24
|
PluginRemoteInfo,
|
|
21
25
|
} from "../lib/inspect-plugin.js";
|
|
22
26
|
import type {
|
|
27
|
+
ConfirmStagedInstall,
|
|
23
28
|
InstallPluginOptions,
|
|
24
29
|
PluginFetchSource,
|
|
25
30
|
} from "../lib/install-from-github.js";
|
|
@@ -37,6 +42,7 @@ import {
|
|
|
37
42
|
} from "../lib/plugin-constants.js";
|
|
38
43
|
import type { FingerprintComparison } from "../lib/plugin-fingerprint.js";
|
|
39
44
|
import type { PluginPinHistoryEntry } from "../lib/plugin-pin-history.js";
|
|
45
|
+
import type { PluginScheduleSurface } from "../lib/plugin-surfaces.js";
|
|
40
46
|
import { runPublish } from "../lib/publish-plugin.js";
|
|
41
47
|
import { registerCommand } from "../lib/register-command.js";
|
|
42
48
|
import {
|
|
@@ -99,6 +105,11 @@ const libs = {
|
|
|
99
105
|
"../lib/search-plugins.js",
|
|
100
106
|
) as typeof import("../lib/search-plugins.js");
|
|
101
107
|
},
|
|
108
|
+
get surfaces() {
|
|
109
|
+
return loadModule(
|
|
110
|
+
"../lib/plugin-surfaces.js",
|
|
111
|
+
) as typeof import("../lib/plugin-surfaces.js");
|
|
112
|
+
},
|
|
102
113
|
get uninstall() {
|
|
103
114
|
return loadModule(
|
|
104
115
|
"../lib/uninstall-plugin.js",
|
|
@@ -157,6 +168,16 @@ export function registerPluginsCommand(program: Command): void {
|
|
|
157
168
|
const usesMarketplaceGit =
|
|
158
169
|
!direct && Boolean(opts.pin || opts.ref || opts.allowUnreviewed);
|
|
159
170
|
|
|
171
|
+
// Consent gate the installers run between staging and finalize:
|
|
172
|
+
// a plugin that declares schedules gets them listed and, unless
|
|
173
|
+
// --force, must be confirmed before anything lands on disk that
|
|
174
|
+
// the daemon's schedule reconciler could arm.
|
|
175
|
+
const confirmStaged: ConfirmStagedInstall = (staged) =>
|
|
176
|
+
confirmDeclaredSchedules(staged, "install", {
|
|
177
|
+
force: Boolean(opts.force),
|
|
178
|
+
json: false,
|
|
179
|
+
});
|
|
180
|
+
|
|
160
181
|
let result;
|
|
161
182
|
let untrusted = false;
|
|
162
183
|
if (!direct && !usesMarketplaceGit) {
|
|
@@ -167,7 +188,7 @@ export function registerPluginsCommand(program: Command): void {
|
|
|
167
188
|
if (libs.catalogLocal.arePlatformFeaturesEnabled()) {
|
|
168
189
|
result = await libs.installPlatform.installPluginViaPlatform(
|
|
169
190
|
{ name: nameOrUrl, force: opts.force },
|
|
170
|
-
{ fetch: globalThis.fetch.bind(globalThis) },
|
|
191
|
+
{ fetch: globalThis.fetch.bind(globalThis), confirmStaged },
|
|
171
192
|
);
|
|
172
193
|
} else {
|
|
173
194
|
const source =
|
|
@@ -190,7 +211,7 @@ export function registerPluginsCommand(program: Command): void {
|
|
|
190
211
|
ref: source.ref,
|
|
191
212
|
},
|
|
192
213
|
},
|
|
193
|
-
{ fetch: globalThis.fetch.bind(globalThis) },
|
|
214
|
+
{ fetch: globalThis.fetch.bind(globalThis), confirmStaged },
|
|
194
215
|
);
|
|
195
216
|
}
|
|
196
217
|
} else {
|
|
@@ -210,6 +231,7 @@ export function registerPluginsCommand(program: Command): void {
|
|
|
210
231
|
}
|
|
211
232
|
result = await libs.installGitHub.installPlugin(installOpts, {
|
|
212
233
|
fetch: globalThis.fetch.bind(globalThis),
|
|
234
|
+
confirmStaged,
|
|
213
235
|
});
|
|
214
236
|
}
|
|
215
237
|
log.info(
|
|
@@ -231,6 +253,11 @@ export function registerPluginsCommand(program: Command): void {
|
|
|
231
253
|
`Installed ${label} "${result.name}" (${result.fileCount} file${result.fileCount === 1 ? "" : "s"})${pinned} → ${result.target}`,
|
|
232
254
|
);
|
|
233
255
|
} catch (err) {
|
|
256
|
+
if (err instanceof libs.installGitHub.PluginInstallDeclinedError) {
|
|
257
|
+
// The consent gate already printed the outcome and set the exit
|
|
258
|
+
// code; the install was aborted with nothing left on disk.
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
234
261
|
if (err instanceof libs.installGitHub.PluginAlreadyInstalledError) {
|
|
235
262
|
console.error(`${err.message}\nPass --force to overwrite.`);
|
|
236
263
|
process.exitCode = 1;
|
|
@@ -407,7 +434,10 @@ export function registerPluginsCommand(program: Command): void {
|
|
|
407
434
|
"plugin inspect",
|
|
408
435
|
);
|
|
409
436
|
|
|
410
|
-
|
|
437
|
+
const describeCron = inspection.surfaces?.schedules.length
|
|
438
|
+
? await loadCronDescriber()
|
|
439
|
+
: null;
|
|
440
|
+
for (const line of formatInspection(inspection, describeCron)) {
|
|
411
441
|
console.log(line);
|
|
412
442
|
}
|
|
413
443
|
} catch (err) {
|
|
@@ -665,7 +695,12 @@ export function registerPluginsCommand(program: Command): void {
|
|
|
665
695
|
subcommand(plugins, "upgrade").action(
|
|
666
696
|
async (
|
|
667
697
|
name: string,
|
|
668
|
-
opts: {
|
|
698
|
+
opts: {
|
|
699
|
+
dryRun?: boolean;
|
|
700
|
+
strategy?: string;
|
|
701
|
+
json?: boolean;
|
|
702
|
+
force?: boolean;
|
|
703
|
+
},
|
|
669
704
|
) => {
|
|
670
705
|
const strategy = opts.strategy;
|
|
671
706
|
if (
|
|
@@ -682,11 +717,16 @@ export function registerPluginsCommand(program: Command): void {
|
|
|
682
717
|
// Prefer the daemon: when the upgrade re-materializes files it runs
|
|
683
718
|
// the plugin's `shutdown` + `init` hooks in the main process —
|
|
684
719
|
// symmetric to how install/uninstall run their lifecycle there.
|
|
720
|
+
// The daemon route is unattended (no staging prompt); a schedule
|
|
721
|
+
// the upgraded revision adds is surfaced by the reconciler's
|
|
722
|
+
// `schedule.declared` notification, and mirrored at the terminal
|
|
723
|
+
// by the declared-schedules listing printed after the upgrade.
|
|
685
724
|
// Fall back to a local upgrade only when the daemon is unreachable
|
|
686
725
|
// (a transport error carries no `statusCode`); an operator can still
|
|
687
726
|
// upgrade while it's stopped, and the new code is picked up on the
|
|
688
727
|
// daemon's next start. A daemon-side decision (not installed, not
|
|
689
728
|
// upgradable, …) is surfaced rather than silently retried locally.
|
|
729
|
+
const preUpgradeScheduleNames = listInstalledScheduleNames(name);
|
|
690
730
|
const daemon = await cliIpcCall<PluginUpgradeResult>(
|
|
691
731
|
"plugins_upgrade",
|
|
692
732
|
{
|
|
@@ -695,20 +735,36 @@ export function registerPluginsCommand(program: Command): void {
|
|
|
695
735
|
},
|
|
696
736
|
);
|
|
697
737
|
let result: PluginUpgradeResult;
|
|
738
|
+
let upgradedViaDaemon = false;
|
|
698
739
|
if (daemon.ok && daemon.result) {
|
|
699
740
|
result = daemon.result;
|
|
741
|
+
upgradedViaDaemon = true;
|
|
700
742
|
} else if (daemon.statusCode === undefined) {
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
743
|
+
// The CLI logger writes debug to stdout, which would corrupt
|
|
744
|
+
// --json output, so under --json the same note goes to stderr.
|
|
745
|
+
// The CLI logger drops structured fields either way.
|
|
746
|
+
const fallbackNote =
|
|
747
|
+
"upgrade could not reach the daemon; upgrading locally";
|
|
748
|
+
if (opts.json) {
|
|
749
|
+
console.error(fallbackNote);
|
|
750
|
+
} else {
|
|
751
|
+
log.debug({ name, error: daemon.error }, fallbackNote);
|
|
752
|
+
}
|
|
753
|
+
// The local path stages in this process, so it gets the same
|
|
754
|
+
// consent gate as install: declared schedules are listed and
|
|
755
|
+
// confirmed (or --force) before the staged tree goes live.
|
|
756
|
+
const confirmStaged: ConfirmStagedInstall = (staged) =>
|
|
757
|
+
confirmDeclaredSchedules(staged, "upgrade", {
|
|
758
|
+
force: Boolean(opts.force),
|
|
759
|
+
json: Boolean(opts.json),
|
|
760
|
+
});
|
|
705
761
|
result = await libs.upgrade.upgradePlugin(
|
|
706
762
|
{
|
|
707
763
|
name,
|
|
708
764
|
dryRun: opts.dryRun,
|
|
709
765
|
strategy: strategy as PluginUpgradeStrategy | undefined,
|
|
710
766
|
},
|
|
711
|
-
{ fetch: globalThis.fetch.bind(globalThis) },
|
|
767
|
+
{ fetch: globalThis.fetch.bind(globalThis), confirmStaged },
|
|
712
768
|
);
|
|
713
769
|
} else {
|
|
714
770
|
console.error(daemon.error ?? "Plugin upgrade failed.");
|
|
@@ -736,7 +792,20 @@ export function registerPluginsCommand(program: Command): void {
|
|
|
736
792
|
for (const line of formatUpgrade(result)) {
|
|
737
793
|
console.log(line);
|
|
738
794
|
}
|
|
795
|
+
|
|
796
|
+
if (upgradedViaDaemon && result.outcome === "upgraded") {
|
|
797
|
+
await printDeclaredSchedulesAfterUpgrade(
|
|
798
|
+
result.name,
|
|
799
|
+
result.target,
|
|
800
|
+
preUpgradeScheduleNames,
|
|
801
|
+
);
|
|
802
|
+
}
|
|
739
803
|
} catch (err) {
|
|
804
|
+
if (err instanceof libs.installGitHub.PluginInstallDeclinedError) {
|
|
805
|
+
// The consent gate already printed the outcome and set the exit
|
|
806
|
+
// code; the upgrade was aborted with the live install untouched.
|
|
807
|
+
return;
|
|
808
|
+
}
|
|
740
809
|
if (
|
|
741
810
|
err instanceof libs.uninstall.PluginNotInstalledError ||
|
|
742
811
|
err instanceof libs.upgrade.PluginNotUpgradableError ||
|
|
@@ -935,6 +1004,209 @@ function printUntrustedPluginWarning(
|
|
|
935
1004
|
console.error(yellow(lines.join("\n")));
|
|
936
1005
|
}
|
|
937
1006
|
|
|
1007
|
+
/**
|
|
1008
|
+
* The declared-schedules block for a plugin tree: a heading plus one aligned
|
|
1009
|
+
* row per schedule, or null when the plugin declares none. Callers own the
|
|
1010
|
+
* output stream and any per-row annotation.
|
|
1011
|
+
*/
|
|
1012
|
+
async function buildDeclaredScheduleListing(
|
|
1013
|
+
pluginName: string,
|
|
1014
|
+
pluginDir: string,
|
|
1015
|
+
): Promise<{
|
|
1016
|
+
heading: string;
|
|
1017
|
+
rows: string[];
|
|
1018
|
+
schedules: readonly PluginScheduleSurface[];
|
|
1019
|
+
} | null> {
|
|
1020
|
+
const { schedules } = libs.surfaces.detectPluginSurfaces(pluginDir);
|
|
1021
|
+
if (schedules.length === 0) {
|
|
1022
|
+
return null;
|
|
1023
|
+
}
|
|
1024
|
+
const describeCron = await loadCronDescriber();
|
|
1025
|
+
return {
|
|
1026
|
+
heading: `Plugin "${pluginName}" declares ${schedules.length} schedule${schedules.length === 1 ? "" : "s"}:`,
|
|
1027
|
+
rows: formatScheduleRows(schedules, describeCron),
|
|
1028
|
+
schedules,
|
|
1029
|
+
};
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
/**
|
|
1033
|
+
* List a staged plugin's declared schedules and ask for consent. Schedules run
|
|
1034
|
+
* automatically once armed, so neither an install nor an upgrade may add any
|
|
1035
|
+
* silently: the user either confirms the listing or passes --force. Returns
|
|
1036
|
+
* whether the operation may proceed; a refusal's user-facing outcome (message
|
|
1037
|
+
* + exit code) is fully handled here, so the caller aborts without further
|
|
1038
|
+
* output. `action` selects the install vs upgrade wording.
|
|
1039
|
+
*/
|
|
1040
|
+
async function confirmDeclaredSchedules(
|
|
1041
|
+
staged: { name: string; stagingDir: string },
|
|
1042
|
+
action: "install" | "upgrade",
|
|
1043
|
+
opts: { force: boolean; json: boolean },
|
|
1044
|
+
): Promise<boolean> {
|
|
1045
|
+
const listing = await buildDeclaredScheduleListing(
|
|
1046
|
+
staged.name,
|
|
1047
|
+
staged.stagingDir,
|
|
1048
|
+
);
|
|
1049
|
+
if (!listing) {
|
|
1050
|
+
return true;
|
|
1051
|
+
}
|
|
1052
|
+
// Everything this gate prints is human output: the listing, the prompt
|
|
1053
|
+
// itself, and the cancellation line. Under --json all of it goes to stderr
|
|
1054
|
+
// so it cannot corrupt the JSON document the caller parses off stdout.
|
|
1055
|
+
const write = (line: string): void => {
|
|
1056
|
+
if (opts.json) {
|
|
1057
|
+
console.error(line);
|
|
1058
|
+
} else {
|
|
1059
|
+
console.log(line);
|
|
1060
|
+
}
|
|
1061
|
+
};
|
|
1062
|
+
write(listing.heading);
|
|
1063
|
+
for (const row of listing.rows) {
|
|
1064
|
+
write(` ${row}`);
|
|
1065
|
+
}
|
|
1066
|
+
write(
|
|
1067
|
+
"Schedules run automatically in the background once the plugin is installed.",
|
|
1068
|
+
);
|
|
1069
|
+
if (opts.force) {
|
|
1070
|
+
return true;
|
|
1071
|
+
}
|
|
1072
|
+
const verb = action === "install" ? "Install" : "Upgrade";
|
|
1073
|
+
const result = await confirmPrompt({
|
|
1074
|
+
question: `${verb} "${staged.name}" and allow these schedules? [y/N] `,
|
|
1075
|
+
isTTY: Boolean(process.stdin.isTTY),
|
|
1076
|
+
refuseNonInteractiveMessage: `Refusing to ${action} "${staged.name}" non-interactively: it declares schedules. Pass --force to confirm.`,
|
|
1077
|
+
stdout: opts.json ? process.stderr : undefined,
|
|
1078
|
+
});
|
|
1079
|
+
if (result === "non-interactive") {
|
|
1080
|
+
process.exitCode = 1;
|
|
1081
|
+
return false;
|
|
1082
|
+
}
|
|
1083
|
+
if (result === "denied") {
|
|
1084
|
+
write(`${verb} cancelled.`);
|
|
1085
|
+
return false;
|
|
1086
|
+
}
|
|
1087
|
+
return true;
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
/**
|
|
1091
|
+
* Maximum rendered width of a declared-schedule listing cell. Declaration
|
|
1092
|
+
* strings come from the plugin being installed, so an overlong expression
|
|
1093
|
+
* must not be able to push the consent prompt off-screen.
|
|
1094
|
+
*/
|
|
1095
|
+
const MAX_SCHEDULE_CELL_WIDTH = 60;
|
|
1096
|
+
|
|
1097
|
+
/**
|
|
1098
|
+
* Make a plugin-controlled declaration string safe to print next to the
|
|
1099
|
+
* install consent prompt: drop escape sequences and control characters
|
|
1100
|
+
* (which could rewrite or hide the surrounding untrusted-source warning)
|
|
1101
|
+
* and cap the cell width.
|
|
1102
|
+
*/
|
|
1103
|
+
function sanitizeScheduleCell(value: string): string {
|
|
1104
|
+
return truncate(stripAnsiAndControlChars(value), MAX_SCHEDULE_CELL_WIDTH);
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
/** Humanizes a cron expression for display; returns the input when unrecognized. */
|
|
1108
|
+
type CronDescriber = (expression: string) => string;
|
|
1109
|
+
|
|
1110
|
+
/**
|
|
1111
|
+
* Load the schedule store's cron humanizer for cadence display. Loaded
|
|
1112
|
+
* lazily inside actions because it lives in the daemon's module graph
|
|
1113
|
+
* (see the `cli/no-daemon-internals` hoisting rule); when it cannot be
|
|
1114
|
+
* loaded, listings fall back to raw expressions.
|
|
1115
|
+
*/
|
|
1116
|
+
async function loadCronDescriber(): Promise<CronDescriber | null> {
|
|
1117
|
+
try {
|
|
1118
|
+
const { describeCronExpression } =
|
|
1119
|
+
await import("../../schedule/schedule-store.js");
|
|
1120
|
+
return describeCronExpression;
|
|
1121
|
+
} catch {
|
|
1122
|
+
return null;
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
/**
|
|
1127
|
+
* Cadence cell for a declared-schedules listing: the humanized cron cadence
|
|
1128
|
+
* with the raw expression kept as ground truth ("Every day at 9:00 AM
|
|
1129
|
+
* (0 9 * * *)"). RRULEs and anything the describer does not recognize stay
|
|
1130
|
+
* as the raw expression alone.
|
|
1131
|
+
*/
|
|
1132
|
+
function formatCadenceCell(
|
|
1133
|
+
cadence: string,
|
|
1134
|
+
describeCron: CronDescriber | null,
|
|
1135
|
+
): string {
|
|
1136
|
+
const described = describeCron?.(cadence);
|
|
1137
|
+
return described && described !== cadence
|
|
1138
|
+
? `${described} (${cadence})`
|
|
1139
|
+
: cadence;
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1142
|
+
/** Aligned `name cadence (mode)` rows for a declared-schedules listing. */
|
|
1143
|
+
function formatScheduleRows(
|
|
1144
|
+
schedules: readonly PluginScheduleSurface[],
|
|
1145
|
+
describeCron: CronDescriber | null,
|
|
1146
|
+
): string[] {
|
|
1147
|
+
if (schedules.length === 0) {
|
|
1148
|
+
return [];
|
|
1149
|
+
}
|
|
1150
|
+
const rows = schedules.map((s) => ({
|
|
1151
|
+
name: sanitizeScheduleCell(s.name),
|
|
1152
|
+
cadence: sanitizeScheduleCell(formatCadenceCell(s.cadence, describeCron)),
|
|
1153
|
+
mode: s.mode,
|
|
1154
|
+
}));
|
|
1155
|
+
const nameW = Math.max(...rows.map((r) => r.name.length));
|
|
1156
|
+
const cadenceW = Math.max(...rows.map((r) => r.cadence.length));
|
|
1157
|
+
return rows.map(
|
|
1158
|
+
(r) =>
|
|
1159
|
+
`${r.name.padEnd(nameW)} ${r.cadence.padEnd(cadenceW)} (${r.mode})`,
|
|
1160
|
+
);
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1163
|
+
/**
|
|
1164
|
+
* Names of the schedules the installed copy of a plugin currently declares.
|
|
1165
|
+
* Empty when the plugin (or its schedules/ dir) is absent, or when the
|
|
1166
|
+
* install path cannot be probed at all (for example an unsanitized name);
|
|
1167
|
+
* the upgrade itself surfaces such errors, this snapshot never does.
|
|
1168
|
+
*/
|
|
1169
|
+
function listInstalledScheduleNames(name: string): ReadonlySet<string> {
|
|
1170
|
+
try {
|
|
1171
|
+
const surfaces = libs.surfaces.detectPluginSurfaces(
|
|
1172
|
+
join(getWorkspacePluginsDir(), name),
|
|
1173
|
+
);
|
|
1174
|
+
return new Set(surfaces.schedules.map((s) => s.name));
|
|
1175
|
+
} catch {
|
|
1176
|
+
return new Set();
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
/**
|
|
1181
|
+
* After a daemon-applied upgrade, list the revision's declared schedules with
|
|
1182
|
+
* a `[new]` marker on the ones the previous revision did not declare. The
|
|
1183
|
+
* daemon path has no staging prompt, so this display is how the operator sees
|
|
1184
|
+
* at the terminal what the reconciler's notification says. Display only:
|
|
1185
|
+
* arming decisions stay with the reconciler.
|
|
1186
|
+
*/
|
|
1187
|
+
async function printDeclaredSchedulesAfterUpgrade(
|
|
1188
|
+
name: string,
|
|
1189
|
+
target: string,
|
|
1190
|
+
previousNames: ReadonlySet<string>,
|
|
1191
|
+
): Promise<void> {
|
|
1192
|
+
const listing = await buildDeclaredScheduleListing(name, target);
|
|
1193
|
+
if (!listing) {
|
|
1194
|
+
return;
|
|
1195
|
+
}
|
|
1196
|
+
const { heading, rows, schedules } = listing;
|
|
1197
|
+
console.log("");
|
|
1198
|
+
console.log(heading);
|
|
1199
|
+
schedules.forEach((schedule, index) => {
|
|
1200
|
+
const marker = previousNames.has(schedule.name) ? "" : " [new]";
|
|
1201
|
+
console.log(` ${rows[index]}${marker}`);
|
|
1202
|
+
});
|
|
1203
|
+
if (schedules.some((schedule) => !previousNames.has(schedule.name))) {
|
|
1204
|
+
console.log(
|
|
1205
|
+
"New schedules run automatically in the background. Run 'assistant schedules list' to review them, or 'assistant schedules disable <id>' to turn one off.",
|
|
1206
|
+
);
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
|
|
938
1210
|
/**
|
|
939
1211
|
* Render a plugin's marketplace-pin history as a table: the pinned commit (short
|
|
940
1212
|
* SHA), when it was promoted, and a marker for the pin currently active. An
|
|
@@ -1059,7 +1331,10 @@ function remoteLocation(remote: PluginRemoteInfo): string {
|
|
|
1059
1331
|
* that each carry `timestamp` (the human version), `hash` (the precise id), and
|
|
1060
1332
|
* `location`, with a `drift` line under the installed copy.
|
|
1061
1333
|
*/
|
|
1062
|
-
function formatInspection(
|
|
1334
|
+
function formatInspection(
|
|
1335
|
+
inspection: PluginInspection,
|
|
1336
|
+
describeCron: CronDescriber | null,
|
|
1337
|
+
): string[] {
|
|
1063
1338
|
const { name, status, local, remote, remoteError, surfaces } = inspection;
|
|
1064
1339
|
const lines: string[] = [name, "─".repeat(44)];
|
|
1065
1340
|
const topRow = (label: string, value: string) =>
|
|
@@ -1124,6 +1399,10 @@ function formatInspection(inspection: PluginInspection): string[] {
|
|
|
1124
1399
|
surfaceBlock("skills", surfaces.skills);
|
|
1125
1400
|
surfaceBlock("hooks", surfaces.hooks);
|
|
1126
1401
|
surfaceBlock("tools", surfaces.tools);
|
|
1402
|
+
surfaceBlock(
|
|
1403
|
+
"schedules",
|
|
1404
|
+
formatScheduleRows(surfaces.schedules, describeCron),
|
|
1405
|
+
);
|
|
1127
1406
|
}
|
|
1128
1407
|
|
|
1129
1408
|
for (const issue of local?.issues ?? []) {
|
|
@@ -68,8 +68,9 @@ Arguments:
|
|
|
68
68
|
Behavior:
|
|
69
69
|
Prints every stored field of the schedule: name, description, mode,
|
|
70
70
|
expression/syntax, timezone, enabled state, status, next/last run times,
|
|
71
|
-
message or script body, inference profile (shown as '
|
|
72
|
-
when
|
|
71
|
+
message or script body, inference profile (shown as 'none (mainAgent
|
|
72
|
+
call-site default)' when no named profile resolves), routing intent, and
|
|
73
|
+
retry policy. Works for
|
|
73
74
|
deferred schedules that 'assistant schedules list' hides by default.
|
|
74
75
|
Aliased as 'inspect'.
|
|
75
76
|
|
|
@@ -149,7 +150,7 @@ Examples:
|
|
|
149
150
|
{
|
|
150
151
|
flags: "--profile <name>",
|
|
151
152
|
description:
|
|
152
|
-
"Inference profile (llm.profiles key) the schedule's runs use;
|
|
153
|
+
"Inference profile (llm.profiles key) the schedule's runs use; when omitted the schedule is pinned to your current default profile",
|
|
153
154
|
},
|
|
154
155
|
{
|
|
155
156
|
flags: "--no-enabled",
|
|
@@ -170,8 +171,9 @@ Options:
|
|
|
170
171
|
--timeout-ms <ms> Script timeout override in ms (--mode script).
|
|
171
172
|
-t, --timezone <tz> IANA timezone applied to the expression.
|
|
172
173
|
--profile <name> Inference profile (llm.profiles key) the schedule's
|
|
173
|
-
runs use. When omitted,
|
|
174
|
-
|
|
174
|
+
runs use. When omitted, the schedule is pinned to
|
|
175
|
+
your current default profile so its model stays
|
|
176
|
+
put when that default changes.
|
|
175
177
|
--no-enabled Create the schedule disabled. Defaults to enabled.
|
|
176
178
|
--json Output the updated schedule list as compact JSON.
|
|
177
179
|
|
|
@@ -279,12 +281,12 @@ Examples:
|
|
|
279
281
|
{
|
|
280
282
|
flags: "--profile <name>",
|
|
281
283
|
description:
|
|
282
|
-
"Inference profile (llm.profiles key) the schedule's runs use
|
|
284
|
+
"Inference profile (llm.profiles key) the schedule's runs use",
|
|
283
285
|
},
|
|
284
286
|
{
|
|
285
287
|
flags: "--clear-profile",
|
|
286
288
|
description:
|
|
287
|
-
"
|
|
289
|
+
"Re-pin the schedule to your current default inference profile",
|
|
288
290
|
},
|
|
289
291
|
{
|
|
290
292
|
flags: "--json",
|
|
@@ -310,11 +312,11 @@ Options:
|
|
|
310
312
|
--clear-timeout Remove the timeout override (mutually exclusive
|
|
311
313
|
with --timeout-ms).
|
|
312
314
|
--profile <name> Inference profile (llm.profiles key) the schedule's
|
|
313
|
-
runs use.
|
|
314
|
-
|
|
315
|
-
--clear-profile
|
|
316
|
-
|
|
317
|
-
|
|
315
|
+
runs use. Every schedule is pinned to one, so its
|
|
316
|
+
model stays put when your default changes.
|
|
317
|
+
--clear-profile Re-pin the schedule to your current default
|
|
318
|
+
inference profile (mutually exclusive with
|
|
319
|
+
--profile).
|
|
318
320
|
--json Output the updated schedule list as compact JSON.
|
|
319
321
|
|
|
320
322
|
Arguments:
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Command } from "commander";
|
|
2
2
|
|
|
3
3
|
import { cliIpcCall, exitFromIpcResult } from "../../ipc/cli-client.js";
|
|
4
|
+
import { describeScheduleSource } from "../../util/schedule-source-key.js";
|
|
4
5
|
import { applyCommandHelp, subcommand } from "../lib/cli-command-help.js";
|
|
5
6
|
import { formatCostUsd } from "../lib/cli-output.js";
|
|
6
7
|
import { confirmPrompt } from "../lib/confirm-prompt.js";
|
|
@@ -36,6 +37,8 @@ interface ScheduleRecord {
|
|
|
36
37
|
routingIntent: string;
|
|
37
38
|
reuseConversation: boolean;
|
|
38
39
|
wakeConversationId: string | null;
|
|
40
|
+
sourceKey: string | null;
|
|
41
|
+
userEnabled: boolean | null;
|
|
39
42
|
isOneShot: boolean;
|
|
40
43
|
}
|
|
41
44
|
|
|
@@ -115,6 +118,7 @@ export function registerSchedulesCommand(program: Command): void {
|
|
|
115
118
|
name: schedule.name,
|
|
116
119
|
enabled: schedule.enabled ? "enabled" : "disabled",
|
|
117
120
|
mode: schedule.mode,
|
|
121
|
+
source: describeScheduleSource(schedule.sourceKey) ?? "",
|
|
118
122
|
schedule: describeSchedule(schedule),
|
|
119
123
|
nextRun: formatTimestamp(schedule.nextRunAt),
|
|
120
124
|
lastStatus: schedule.lastStatus ?? "—",
|
|
@@ -125,6 +129,7 @@ export function registerSchedulesCommand(program: Command): void {
|
|
|
125
129
|
"NAME",
|
|
126
130
|
"ENABLED",
|
|
127
131
|
"MODE",
|
|
132
|
+
"SOURCE",
|
|
128
133
|
"SCHEDULE",
|
|
129
134
|
"NEXT RUN",
|
|
130
135
|
"LAST STATUS",
|
|
@@ -137,6 +142,7 @@ export function registerSchedulesCommand(program: Command): void {
|
|
|
137
142
|
headers[4].length,
|
|
138
143
|
headers[5].length,
|
|
139
144
|
headers[6].length,
|
|
145
|
+
headers[7].length,
|
|
140
146
|
];
|
|
141
147
|
|
|
142
148
|
for (const row of rows) {
|
|
@@ -144,9 +150,10 @@ export function registerSchedulesCommand(program: Command): void {
|
|
|
144
150
|
widths[1] = Math.max(widths[1], row.name.length);
|
|
145
151
|
widths[2] = Math.max(widths[2], row.enabled.length);
|
|
146
152
|
widths[3] = Math.max(widths[3], row.mode.length);
|
|
147
|
-
widths[4] = Math.max(widths[4], row.
|
|
148
|
-
widths[5] = Math.max(widths[5], row.
|
|
149
|
-
widths[6] = Math.max(widths[6], row.
|
|
153
|
+
widths[4] = Math.max(widths[4], row.source.length);
|
|
154
|
+
widths[5] = Math.max(widths[5], row.schedule.length);
|
|
155
|
+
widths[6] = Math.max(widths[6], row.nextRun.length);
|
|
156
|
+
widths[7] = Math.max(widths[7], row.lastStatus.length);
|
|
150
157
|
}
|
|
151
158
|
|
|
152
159
|
const pad = (value: string, width: number) => value.padEnd(width);
|
|
@@ -163,6 +170,7 @@ export function registerSchedulesCommand(program: Command): void {
|
|
|
163
170
|
row.name,
|
|
164
171
|
row.enabled,
|
|
165
172
|
row.mode,
|
|
173
|
+
row.source,
|
|
166
174
|
row.schedule,
|
|
167
175
|
row.nextRun,
|
|
168
176
|
row.lastStatus,
|
|
@@ -203,6 +211,11 @@ export function registerSchedulesCommand(program: Command): void {
|
|
|
203
211
|
return;
|
|
204
212
|
}
|
|
205
213
|
|
|
214
|
+
// Lazily loaded so the schedule module stays out of the CLI's
|
|
215
|
+
// static graph (cli/no-daemon-internals).
|
|
216
|
+
const { formatScheduleInferenceProfile } =
|
|
217
|
+
await import("../../schedule/inference-profile.js");
|
|
218
|
+
|
|
206
219
|
const fields: Array<[string, string]> = [
|
|
207
220
|
["ID", schedule.id],
|
|
208
221
|
["Name", schedule.name],
|
|
@@ -222,7 +235,7 @@ export function registerSchedulesCommand(program: Command): void {
|
|
|
222
235
|
["Script", schedule.script ?? "—"],
|
|
223
236
|
[
|
|
224
237
|
"Inference profile",
|
|
225
|
-
schedule.inferenceProfile
|
|
238
|
+
formatScheduleInferenceProfile(schedule.inferenceProfile),
|
|
226
239
|
],
|
|
227
240
|
["Routing intent", schedule.routingIntent],
|
|
228
241
|
["Reuse conversation", schedule.reuseConversation ? "yes" : "no"],
|
|
@@ -232,6 +245,7 @@ export function registerSchedulesCommand(program: Command): void {
|
|
|
232
245
|
["Retry backoff", formatDuration(schedule.retryBackoffMs)],
|
|
233
246
|
["Timeout", formatDuration(schedule.timeoutMs)],
|
|
234
247
|
["Source conversation", schedule.createdFromConversationId ?? "—"],
|
|
248
|
+
["Plugin", describeScheduleSource(schedule.sourceKey) ?? "-"],
|
|
235
249
|
];
|
|
236
250
|
const labelWidth = Math.max(...fields.map(([label]) => label.length));
|
|
237
251
|
for (const [label, value] of fields) {
|
|
@@ -500,7 +514,7 @@ export function registerSchedulesCommand(program: Command): void {
|
|
|
500
514
|
|
|
501
515
|
if (opts.clearProfile && opts.profile != null) {
|
|
502
516
|
fail(
|
|
503
|
-
"--profile and --clear-profile are mutually exclusive; pass --profile to
|
|
517
|
+
"--profile and --clear-profile are mutually exclusive; pass --profile to pin a specific profile or --clear-profile to re-pin the schedule to your current default profile",
|
|
504
518
|
);
|
|
505
519
|
return;
|
|
506
520
|
}
|
|
@@ -28,6 +28,7 @@ Examples:
|
|
|
28
28
|
$ assistant tools list --json
|
|
29
29
|
$ assistant tools list --conversation conv_abc123
|
|
30
30
|
$ assistant tools list --agent researcher
|
|
31
|
+
$ assistant tools list --agent "a staff security engineer"
|
|
31
32
|
$ assistant tools list --agent subagent_abc123 --json
|
|
32
33
|
$ assistant tools run web_fetch --input '{"url":"https://example.com"}'
|
|
33
34
|
$ assistant tools run file_read --input-file args.json
|
|
@@ -39,7 +40,8 @@ Examples:
|
|
|
39
40
|
options: [
|
|
40
41
|
{
|
|
41
42
|
flags: "--json",
|
|
42
|
-
description:
|
|
43
|
+
description:
|
|
44
|
+
"Emit the tool array as machine-readable JSON instead of a table; a note about how --agent resolved goes to stderr so stdout stays pipeable",
|
|
43
45
|
},
|
|
44
46
|
{
|
|
45
47
|
flags: "--conversation <id>",
|
|
@@ -49,7 +51,7 @@ Examples:
|
|
|
49
51
|
{
|
|
50
52
|
flags: "--agent <role|subagent-id>",
|
|
51
53
|
description:
|
|
52
|
-
"Show tools available to a subagent role (
|
|
54
|
+
"Show tools available to a subagent role (researcher, builder, advisor) or a live subagent by its id. Reads the value the way a spawn reads its role: an older name (planner, investigator, coder, general) lists its successor's toolset, and any other text is a persona that lists the researcher toolset. The output names what the value resolved to. Simulates the subagent tool projection: role allowlist + subagent-only gating.",
|
|
53
55
|
},
|
|
54
56
|
],
|
|
55
57
|
},
|
|
@@ -24,10 +24,40 @@ interface ToolListEntry {
|
|
|
24
24
|
source: string;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
/** How the daemon read an `--agent` value, when it read one as a role string. */
|
|
28
|
+
interface ResolvedAgentInfo {
|
|
29
|
+
requested: string;
|
|
30
|
+
role: string;
|
|
31
|
+
alias?: string;
|
|
32
|
+
persona?: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
27
35
|
interface ToolsGetResponse {
|
|
28
36
|
names: string[];
|
|
29
37
|
schemas: Record<string, unknown>;
|
|
30
38
|
tools: ToolListEntry[];
|
|
39
|
+
agent?: ResolvedAgentInfo;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* What to report when `--agent` landed on a different subagent type than the
|
|
44
|
+
* value asked for, or `undefined` when it named a type outright (or resolved a
|
|
45
|
+
* live subagent id, which carries no resolution block).
|
|
46
|
+
*
|
|
47
|
+
* A listing that came from an older name or from a persona fallback looks
|
|
48
|
+
* exactly like one asked for by name, so without this line a typo reads as a
|
|
49
|
+
* researcher's tool surface with nothing saying the value was not a type. It
|
|
50
|
+
* goes to stderr so it reaches a person without entering the `--json` stream,
|
|
51
|
+
* whose stdout contract is the tool array on its own.
|
|
52
|
+
*/
|
|
53
|
+
function agentResolutionLine(agent?: ResolvedAgentInfo): string | undefined {
|
|
54
|
+
if (agent?.alias) {
|
|
55
|
+
return `"${agent.requested}" is an older name for "${agent.role}"; listing the ${agent.role} toolset.`;
|
|
56
|
+
}
|
|
57
|
+
if (agent?.persona) {
|
|
58
|
+
return `"${agent.requested}" is not a subagent type, so it is carried as a persona and runs as a researcher; listing the researcher toolset.`;
|
|
59
|
+
}
|
|
60
|
+
return undefined;
|
|
31
61
|
}
|
|
32
62
|
|
|
33
63
|
export function registerToolsCommand(program: Command): void {
|
|
@@ -61,12 +91,20 @@ export function registerToolsCommand(program: Command): void {
|
|
|
61
91
|
}
|
|
62
92
|
|
|
63
93
|
const tools = response.result?.tools ?? [];
|
|
94
|
+
const resolutionLine = agentResolutionLine(response.result?.agent);
|
|
64
95
|
|
|
65
96
|
if (opts.json) {
|
|
97
|
+
if (resolutionLine) {
|
|
98
|
+
console.error(resolutionLine);
|
|
99
|
+
}
|
|
66
100
|
console.log(JSON.stringify(tools, null, 2));
|
|
67
101
|
return;
|
|
68
102
|
}
|
|
69
103
|
|
|
104
|
+
if (resolutionLine) {
|
|
105
|
+
console.log(`${resolutionLine}\n`);
|
|
106
|
+
}
|
|
107
|
+
|
|
70
108
|
if (tools.length === 0) {
|
|
71
109
|
console.log("No tools registered.");
|
|
72
110
|
return;
|