@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
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unattended plugin upgrades, driven from the resource monitor process.
|
|
3
|
+
*
|
|
4
|
+
* A workspace opts in with `pluginUpdates.mode: "auto"`; the default,
|
|
5
|
+
* `"manual"`, keeps the pre-existing behavior where a plugin only ever moves
|
|
6
|
+
* when a human runs `assistant plugins upgrade`. When opted in, this sweep
|
|
7
|
+
* walks every installed, enabled plugin once per `pluginUpdates.checkIntervalMs`
|
|
8
|
+
* (default hourly), inspects which ones can actually move, and upgrades those
|
|
9
|
+
* with the configured merge strategy (default `theirs`).
|
|
10
|
+
*
|
|
11
|
+
* The monitor drives it — not the daemon — for the same reason it drives the
|
|
12
|
+
* plugin source watch and crash recovery: the work is periodic, network-bound,
|
|
13
|
+
* and must not compete with the daemon's turn loop. Drift detection happens
|
|
14
|
+
* here too (`inspectPlugin` reads the catalog; no clone), so a workspace whose
|
|
15
|
+
* plugins are all current costs the daemon nothing. But the monitor does *not*
|
|
16
|
+
* perform the upgrade itself. It asks the daemon to, over the CLI IPC socket
|
|
17
|
+
* (`plugins_upgrade`), because the upgrade has in-process lifecycle: the old
|
|
18
|
+
* version's `shutdown` must run at the swap boundary and the new version's
|
|
19
|
+
* `init` must run right after, both inside the process that loaded the plugin.
|
|
20
|
+
* A monitor-local upgrade would swap files under a daemon that never tore the
|
|
21
|
+
* old version down. When the daemon is unreachable nothing is attempted and
|
|
22
|
+
* the sweep stays due, so it retries on the next poll rather than skipping the
|
|
23
|
+
* window.
|
|
24
|
+
*
|
|
25
|
+
* The last completed sweep is stamped in the monitoring data dir, so a daemon
|
|
26
|
+
* that restarts every few minutes still upgrades at most once per interval
|
|
27
|
+
* instead of re-cloning on every boot.
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
import { statSync, writeFileSync } from "node:fs";
|
|
31
|
+
import { join } from "node:path";
|
|
32
|
+
|
|
33
|
+
import { inspectPlugin } from "../cli/lib/inspect-plugin.js";
|
|
34
|
+
import { listInstalledPlugins } from "../cli/lib/list-installed-plugins.js";
|
|
35
|
+
import { getConfigReadOnly } from "../config/loader.js";
|
|
36
|
+
import type { PluginUpdatesConfig } from "../config/schemas/plugin-updates.js";
|
|
37
|
+
import { cliIpcCall } from "../ipc/cli-client.js";
|
|
38
|
+
import { isPluginDisabled } from "../plugins/disabled-state.js";
|
|
39
|
+
import { getLogger } from "../util/logger.js";
|
|
40
|
+
import { getMonitoringDataDir } from "../util/platform.js";
|
|
41
|
+
|
|
42
|
+
const log = getLogger("plugin-auto-update");
|
|
43
|
+
|
|
44
|
+
/** IPC method backing `POST /v1/plugins/:name/upgrade` on the daemon. */
|
|
45
|
+
const UPGRADE_IPC_METHOD = "plugins_upgrade";
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Per-plugin ceiling for the daemon call. An upgrade clones the source, may
|
|
49
|
+
* install dependencies, and runs the plugin's `shutdown`/`init` hooks, so it
|
|
50
|
+
* is far slower than the IPC client's default 60s — but it must still be
|
|
51
|
+
* bounded, or one wedged upgrade stalls the sweep forever.
|
|
52
|
+
*/
|
|
53
|
+
const UPGRADE_TIMEOUT_MS = 5 * 60 * 1000;
|
|
54
|
+
|
|
55
|
+
/** How often the loop re-tests whether a sweep is due. */
|
|
56
|
+
const DUE_POLL_INTERVAL_MS = 60_000;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Delay before the first due-check. The monitor starts alongside the daemon,
|
|
60
|
+
* which is still migrating and loading plugins; there is nothing to upgrade
|
|
61
|
+
* into until it is up.
|
|
62
|
+
*/
|
|
63
|
+
const BOOT_DELAY_MS = 60_000;
|
|
64
|
+
|
|
65
|
+
const STAMP_FILENAME = "plugin-auto-update-last-run-at";
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Inspection verdicts worth asking the daemon about.
|
|
69
|
+
*
|
|
70
|
+
* `update-available` is the obvious one. `unknown-provenance` (an older or
|
|
71
|
+
* manually-copied install with no recorded commit) is included because an
|
|
72
|
+
* upgrade re-pins it, which is how it stops being unknown. So is
|
|
73
|
+
* `not-in-marketplace`: a plugin installed straight from a GitHub URL has no
|
|
74
|
+
* catalog entry to compare against, but it still tracks a ref upstream may
|
|
75
|
+
* have moved — only the daemon's upgrade can resolve that, and it no-ops when
|
|
76
|
+
* the ref still points at the installed commit.
|
|
77
|
+
*
|
|
78
|
+
* Everything else is skipped: `up-to-date` has nowhere to move, and
|
|
79
|
+
* `remote-unavailable` means the catalog could not be read, so an upgrade
|
|
80
|
+
* would fail on the same outage a moment later.
|
|
81
|
+
*/
|
|
82
|
+
const UPGRADABLE_STATUSES: ReadonlySet<string> = new Set([
|
|
83
|
+
"update-available",
|
|
84
|
+
"unknown-provenance",
|
|
85
|
+
"not-in-marketplace",
|
|
86
|
+
]);
|
|
87
|
+
|
|
88
|
+
/** Outcome the daemon reports for one plugin; mirrors `PluginUpgradeResult`. */
|
|
89
|
+
interface UpgradeCallResult {
|
|
90
|
+
readonly outcome?: string;
|
|
91
|
+
readonly fromCommit?: string | null;
|
|
92
|
+
readonly toCommit?: string;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function stampPath(): string {
|
|
96
|
+
return join(getMonitoringDataDir(), STAMP_FILENAME);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** Epoch millis of the last completed sweep, or `null` when never swept. */
|
|
100
|
+
function lastSweepAt(): number | null {
|
|
101
|
+
try {
|
|
102
|
+
return statSync(stampPath()).mtimeMs;
|
|
103
|
+
} catch {
|
|
104
|
+
return null; // never swept, or an unreadable stamp — treat as due
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function stampSweep(): void {
|
|
109
|
+
try {
|
|
110
|
+
writeFileSync(stampPath(), "");
|
|
111
|
+
} catch (err) {
|
|
112
|
+
log.warn({ err }, "Could not stamp the plugin auto-update sweep");
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Installed plugins this sweep should ask the daemon to upgrade.
|
|
118
|
+
*
|
|
119
|
+
* Only user-installed plugins are listed (defaults ship with the assistant and
|
|
120
|
+
* have no upstream to advance to). A disabled plugin is deliberately left
|
|
121
|
+
* alone — the user switched it off, and upgrading it would re-materialize code
|
|
122
|
+
* and re-declare schedules for something that isn't running. What survives
|
|
123
|
+
* that is inspected, so the daemon is only asked about plugins that can
|
|
124
|
+
* actually move (see {@link UPGRADABLE_STATUSES}).
|
|
125
|
+
*/
|
|
126
|
+
async function listUpgradableNames(): Promise<string[]> {
|
|
127
|
+
const installed = listInstalledPlugins()
|
|
128
|
+
.map((plugin) => plugin.name)
|
|
129
|
+
.filter((name) => !isPluginDisabled(name));
|
|
130
|
+
|
|
131
|
+
const candidates: string[] = [];
|
|
132
|
+
for (const name of installed) {
|
|
133
|
+
try {
|
|
134
|
+
const inspection = await inspectPlugin(
|
|
135
|
+
{ name },
|
|
136
|
+
{ fetch: globalThis.fetch.bind(globalThis) },
|
|
137
|
+
);
|
|
138
|
+
if (UPGRADABLE_STATUSES.has(inspection.status)) {
|
|
139
|
+
candidates.push(name);
|
|
140
|
+
}
|
|
141
|
+
} catch (err) {
|
|
142
|
+
// An install whose drift cannot be classified (source unreachable,
|
|
143
|
+
// rate-limited) is skipped rather than handed to the daemon, which
|
|
144
|
+
// would hit the same failure a moment later.
|
|
145
|
+
log.debug({ err, name }, "Plugin auto-update could not inspect plugin");
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return candidates;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/** Ask the daemon to upgrade one plugin. */
|
|
152
|
+
function requestUpgrade(
|
|
153
|
+
name: string,
|
|
154
|
+
strategy: PluginUpdatesConfig["strategy"],
|
|
155
|
+
) {
|
|
156
|
+
return cliIpcCall<UpgradeCallResult>(
|
|
157
|
+
UPGRADE_IPC_METHOD,
|
|
158
|
+
// The target revision is never caller-supplied — the daemon resolves it
|
|
159
|
+
// from the plugin's own source, exactly as an interactive upgrade does.
|
|
160
|
+
{ pathParams: { name }, body: { strategy } },
|
|
161
|
+
{ timeoutMs: UPGRADE_TIMEOUT_MS },
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/** What one sweep did, for logging and tests. */
|
|
166
|
+
export interface PluginAutoUpdateSweepResult {
|
|
167
|
+
/** Why the sweep did no work, or `null` when it ran. */
|
|
168
|
+
readonly skipped:
|
|
169
|
+
| "manual"
|
|
170
|
+
| "not-due"
|
|
171
|
+
| "no-candidates"
|
|
172
|
+
| "config-unreadable"
|
|
173
|
+
| null;
|
|
174
|
+
readonly upgraded: readonly string[];
|
|
175
|
+
readonly unchanged: readonly string[];
|
|
176
|
+
readonly failed: readonly string[];
|
|
177
|
+
/** True when the daemon could not be reached, so the sweep stays due. */
|
|
178
|
+
readonly daemonUnreachable: boolean;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const NOTHING: Omit<PluginAutoUpdateSweepResult, "skipped"> = {
|
|
182
|
+
upgraded: [],
|
|
183
|
+
unchanged: [],
|
|
184
|
+
failed: [],
|
|
185
|
+
daemonUnreachable: false,
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Run one sweep if the workspace is opted in and the interval has elapsed.
|
|
190
|
+
*
|
|
191
|
+
* Never throws: a plugin whose upgrade fails (source unreachable, no upstream
|
|
192
|
+
* to advance to, an unreconstructable merge baseline) is logged and skipped so
|
|
193
|
+
* one bad plugin cannot block the rest, and the sweep is stamped regardless —
|
|
194
|
+
* a failure retries on the next interval, not on the next minute.
|
|
195
|
+
*/
|
|
196
|
+
export async function runPluginAutoUpdateSweepIfDue(): Promise<PluginAutoUpdateSweepResult> {
|
|
197
|
+
let config: PluginUpdatesConfig;
|
|
198
|
+
try {
|
|
199
|
+
// `getConfigReadOnly` never creates directories or writes config.json —
|
|
200
|
+
// the monitor must not repair the daemon's config file behind its back.
|
|
201
|
+
// It re-reads on change, so flipping the mode needs no restart.
|
|
202
|
+
config = getConfigReadOnly().pluginUpdates;
|
|
203
|
+
} catch (err) {
|
|
204
|
+
// A config that cannot be read is not an invitation to upgrade anything.
|
|
205
|
+
log.warn({ err }, "Plugin auto-update could not read config — skipping");
|
|
206
|
+
return { skipped: "config-unreadable", ...NOTHING };
|
|
207
|
+
}
|
|
208
|
+
if (config.mode !== "auto") {
|
|
209
|
+
return { skipped: "manual", ...NOTHING };
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
const lastRunAt = lastSweepAt();
|
|
213
|
+
if (lastRunAt !== null && Date.now() - lastRunAt < config.checkIntervalMs) {
|
|
214
|
+
return { skipped: "not-due", ...NOTHING };
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
let names: string[];
|
|
218
|
+
try {
|
|
219
|
+
names = await listUpgradableNames();
|
|
220
|
+
} catch (err) {
|
|
221
|
+
log.warn({ err }, "Plugin auto-update could not list installed plugins");
|
|
222
|
+
return { skipped: "no-candidates", ...NOTHING };
|
|
223
|
+
}
|
|
224
|
+
if (names.length === 0) {
|
|
225
|
+
// Stamp anyway: a workspace with nothing to move is a completed sweep, and
|
|
226
|
+
// re-inspecting every plugin a minute later would be pure churn.
|
|
227
|
+
stampSweep();
|
|
228
|
+
return { skipped: "no-candidates", ...NOTHING };
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
const upgraded: string[] = [];
|
|
232
|
+
const unchanged: string[] = [];
|
|
233
|
+
const failed: string[] = [];
|
|
234
|
+
let daemonUnreachable = false;
|
|
235
|
+
|
|
236
|
+
// Sequential on purpose: each upgrade clones a repository and may install
|
|
237
|
+
// dependencies, and the daemon runs the swapped plugin's lifecycle hooks.
|
|
238
|
+
// Running them one at a time keeps the monitor's network and the daemon's
|
|
239
|
+
// event loop from being flooded by a workspace with many plugins.
|
|
240
|
+
for (const name of names) {
|
|
241
|
+
let call: Awaited<ReturnType<typeof requestUpgrade>>;
|
|
242
|
+
try {
|
|
243
|
+
call = await requestUpgrade(name, config.strategy);
|
|
244
|
+
} catch (err) {
|
|
245
|
+
failed.push(name);
|
|
246
|
+
log.warn({ err, name }, "Plugin auto-update call failed");
|
|
247
|
+
continue;
|
|
248
|
+
}
|
|
249
|
+
if (call.ok) {
|
|
250
|
+
const outcome = call.result?.outcome;
|
|
251
|
+
if (outcome === "upgraded") {
|
|
252
|
+
upgraded.push(name);
|
|
253
|
+
log.info(
|
|
254
|
+
{
|
|
255
|
+
name,
|
|
256
|
+
strategy: config.strategy,
|
|
257
|
+
from: call.result?.fromCommit,
|
|
258
|
+
to: call.result?.toCommit,
|
|
259
|
+
},
|
|
260
|
+
"Plugin auto-upgraded",
|
|
261
|
+
);
|
|
262
|
+
} else {
|
|
263
|
+
unchanged.push(name);
|
|
264
|
+
}
|
|
265
|
+
continue;
|
|
266
|
+
}
|
|
267
|
+
if (call.timedOut) {
|
|
268
|
+
// The request was delivered and the daemon may still be swapping this
|
|
269
|
+
// plugin — closing our socket does not abort its handler. Stop the sweep
|
|
270
|
+
// and stamp it: retrying in a minute would pile work onto an upgrade
|
|
271
|
+
// that is still running (the daemon refuses a second upgrade of the same
|
|
272
|
+
// plugin anyway). The next attempt is a full interval away.
|
|
273
|
+
failed.push(name);
|
|
274
|
+
log.warn(
|
|
275
|
+
{ name, timeoutMs: UPGRADE_TIMEOUT_MS },
|
|
276
|
+
"Plugin auto-upgrade timed out — abandoning the sweep until the next interval",
|
|
277
|
+
);
|
|
278
|
+
break;
|
|
279
|
+
}
|
|
280
|
+
if (call.statusCode === undefined) {
|
|
281
|
+
// Transport failure: the daemon is down, restarting, or still gated on
|
|
282
|
+
// migrations. Nothing after this would fare better, so abandon the
|
|
283
|
+
// sweep without stamping and retry on the next poll.
|
|
284
|
+
daemonUnreachable = true;
|
|
285
|
+
log.debug(
|
|
286
|
+
{ name, error: call.error },
|
|
287
|
+
"Plugin auto-update could not reach the daemon — staying due",
|
|
288
|
+
);
|
|
289
|
+
break;
|
|
290
|
+
}
|
|
291
|
+
failed.push(name);
|
|
292
|
+
log.warn(
|
|
293
|
+
{ name, statusCode: call.statusCode, error: call.error },
|
|
294
|
+
"Plugin auto-upgrade was refused",
|
|
295
|
+
);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
if (!daemonUnreachable) {
|
|
299
|
+
stampSweep();
|
|
300
|
+
log.info(
|
|
301
|
+
{
|
|
302
|
+
upgraded: upgraded.length,
|
|
303
|
+
unchanged: unchanged.length,
|
|
304
|
+
failed: failed.length,
|
|
305
|
+
strategy: config.strategy,
|
|
306
|
+
},
|
|
307
|
+
"Plugin auto-update sweep complete",
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
return { skipped: null, upgraded, unchanged, failed, daemonUnreachable };
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/** Handle for the running auto-update loop. */
|
|
315
|
+
export interface PluginAutoUpdateHandle {
|
|
316
|
+
stop(): void;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
let inFlight = false;
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Guarded sweep: a sweep can outlive the poll interval (each plugin gets up to
|
|
323
|
+
* {@link UPGRADE_TIMEOUT_MS}), and two concurrent sweeps would ask the daemon
|
|
324
|
+
* to upgrade the same plugin twice.
|
|
325
|
+
*/
|
|
326
|
+
async function tick(): Promise<void> {
|
|
327
|
+
if (inFlight) {
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
inFlight = true;
|
|
331
|
+
try {
|
|
332
|
+
await runPluginAutoUpdateSweepIfDue();
|
|
333
|
+
} catch (err) {
|
|
334
|
+
log.warn({ err }, "Plugin auto-update sweep failed (non-fatal)");
|
|
335
|
+
} finally {
|
|
336
|
+
inFlight = false;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* Start the auto-update loop in the monitor process.
|
|
342
|
+
*
|
|
343
|
+
* The timer runs regardless of the current mode — it is the sweep that reads
|
|
344
|
+
* `pluginUpdates.mode`, so switching a workspace to `auto` takes effect within
|
|
345
|
+
* one poll instead of at the next daemon restart. Timers are unref'd so the
|
|
346
|
+
* loop never keeps the process alive.
|
|
347
|
+
*/
|
|
348
|
+
export function startPluginAutoUpdate(): PluginAutoUpdateHandle {
|
|
349
|
+
const bootTimer = setTimeout(() => void tick(), BOOT_DELAY_MS);
|
|
350
|
+
bootTimer.unref?.();
|
|
351
|
+
const pollTimer = setInterval(() => void tick(), DUE_POLL_INTERVAL_MS);
|
|
352
|
+
pollTimer.unref?.();
|
|
353
|
+
return {
|
|
354
|
+
stop() {
|
|
355
|
+
clearTimeout(bootTimer);
|
|
356
|
+
clearInterval(pollTimer);
|
|
357
|
+
},
|
|
358
|
+
};
|
|
359
|
+
}
|
|
@@ -83,10 +83,10 @@ export function computeSampleDeltas(
|
|
|
83
83
|
* Take a single point-in-time sample of memory + disk. When `prev` is given,
|
|
84
84
|
* the sample carries counter deltas relative to it.
|
|
85
85
|
*/
|
|
86
|
-
export function takeSample(
|
|
86
|
+
export async function takeSample(
|
|
87
87
|
now: number,
|
|
88
88
|
prev: ResourceSample | null = null,
|
|
89
|
-
): ResourceSample {
|
|
89
|
+
): Promise<ResourceSample> {
|
|
90
90
|
const currentBytes = getContainerMemoryUsageBytes();
|
|
91
91
|
const limitBytes = getContainerMemoryLimitBytes();
|
|
92
92
|
const memory: ResourceSampleMemory | null =
|
|
@@ -99,7 +99,7 @@ export function takeSample(
|
|
|
99
99
|
}
|
|
100
100
|
: null;
|
|
101
101
|
|
|
102
|
-
const disk = getDiskUsageInfo();
|
|
102
|
+
const disk = await getDiskUsageInfo();
|
|
103
103
|
|
|
104
104
|
// One read feeds both parsers so the breakdown and counters are coherent.
|
|
105
105
|
const statRaw = readMemoryStatRaw();
|
|
@@ -236,11 +236,27 @@ export function startResourceSampler(
|
|
|
236
236
|
// thread's kernel state mid-stall when the heartbeat goes stale.
|
|
237
237
|
const stallCapture = createStallCaptureMonitor(dataDir);
|
|
238
238
|
|
|
239
|
-
|
|
239
|
+
// Skip ticks while a sample is in flight: the disk measurement can take
|
|
240
|
+
// seconds (du over the workspace), and overlapping ticks would all delta
|
|
241
|
+
// against the same stale prevSample and land in one burst.
|
|
242
|
+
let sampleInFlight = false;
|
|
243
|
+
const tick = async () => {
|
|
244
|
+
if (sampleInFlight) {
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
sampleInFlight = true;
|
|
248
|
+
try {
|
|
249
|
+
await runTick();
|
|
250
|
+
} finally {
|
|
251
|
+
sampleInFlight = false;
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
const runTick = async () => {
|
|
240
256
|
const now = clock();
|
|
241
257
|
let sample: ResourceSample;
|
|
242
258
|
try {
|
|
243
|
-
sample = takeSample(now, prevSample);
|
|
259
|
+
sample = await takeSample(now, prevSample);
|
|
244
260
|
prevSample = sample;
|
|
245
261
|
buffer.append(sample);
|
|
246
262
|
} catch (err) {
|
package/src/monitoring/worker.ts
CHANGED
|
@@ -47,6 +47,10 @@ import {
|
|
|
47
47
|
type FileDescriptorMonitorHandle,
|
|
48
48
|
startFileDescriptorMonitor,
|
|
49
49
|
} from "./file-descriptors.js";
|
|
50
|
+
import {
|
|
51
|
+
type PluginAutoUpdateHandle,
|
|
52
|
+
startPluginAutoUpdate,
|
|
53
|
+
} from "./plugin-auto-update.js";
|
|
50
54
|
import {
|
|
51
55
|
type PluginSourceWatchHandle,
|
|
52
56
|
startPluginSourceWatch,
|
|
@@ -90,6 +94,7 @@ async function main(): Promise<void> {
|
|
|
90
94
|
let sampler: ResourceSamplerHandle | null = null;
|
|
91
95
|
let fdMonitor: FileDescriptorMonitorHandle | null = null;
|
|
92
96
|
let sourceWatch: PluginSourceWatchHandle | null = null;
|
|
97
|
+
let autoUpdate: PluginAutoUpdateHandle | null = null;
|
|
93
98
|
let recovery: RecoveryHandle | null = null;
|
|
94
99
|
|
|
95
100
|
let shuttingDown = false;
|
|
@@ -104,6 +109,7 @@ async function main(): Promise<void> {
|
|
|
104
109
|
stopConfigSnapshotReporter();
|
|
105
110
|
stopMemoryTierReporter();
|
|
106
111
|
stopDbIntegritySampler();
|
|
112
|
+
autoUpdate?.stop();
|
|
107
113
|
sourceWatch?.stop();
|
|
108
114
|
fdMonitor?.stop();
|
|
109
115
|
sampler?.stop();
|
|
@@ -153,6 +159,10 @@ async function main(): Promise<void> {
|
|
|
153
159
|
sourceWatch = startPluginSourceWatch(
|
|
154
160
|
config.monitoring.pluginSourceScanIntervalMs,
|
|
155
161
|
);
|
|
162
|
+
// Unattended plugin upgrades, when the workspace opted in
|
|
163
|
+
// (`pluginUpdates.mode: "auto"`). The loop starts either way — the pass
|
|
164
|
+
// reads the mode, so flipping it takes effect without a restart.
|
|
165
|
+
autoUpdate = startPluginAutoUpdate();
|
|
156
166
|
// Crash recovery runs here, off the daemon's boot path and event loop.
|
|
157
167
|
recovery = startRecovery();
|
|
158
168
|
|
|
@@ -181,6 +191,7 @@ async function main(): Promise<void> {
|
|
|
181
191
|
process.on("uncaughtException", (err) => {
|
|
182
192
|
log.error({ err }, "Uncaught exception in resource monitor process");
|
|
183
193
|
recovery?.stop();
|
|
194
|
+
autoUpdate?.stop();
|
|
184
195
|
sourceWatch?.stop();
|
|
185
196
|
fdMonitor?.stop();
|
|
186
197
|
sampler?.stop();
|
|
@@ -192,6 +203,7 @@ async function main(): Promise<void> {
|
|
|
192
203
|
process.on("unhandledRejection", (reason) => {
|
|
193
204
|
log.error({ reason }, "Unhandled rejection in resource monitor process");
|
|
194
205
|
recovery?.stop();
|
|
206
|
+
autoUpdate?.stop();
|
|
195
207
|
sourceWatch?.stop();
|
|
196
208
|
fdMonitor?.stop();
|
|
197
209
|
sampler?.stop();
|
|
@@ -202,6 +214,7 @@ async function main(): Promise<void> {
|
|
|
202
214
|
|
|
203
215
|
process.on("exit", () => {
|
|
204
216
|
recovery?.stop();
|
|
217
|
+
autoUpdate?.stop();
|
|
205
218
|
sourceWatch?.stop();
|
|
206
219
|
fdMonitor?.stop();
|
|
207
220
|
sampler?.stop();
|