@vellumai/assistant 0.6.4 → 0.6.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.prettierignore +5 -0
- package/AGENTS.md +9 -1
- package/ARCHITECTURE.md +43 -49
- package/Dockerfile +17 -3
- package/README.md +3 -4
- package/__tests__/permissions/gateway-threshold-reader.test.ts +283 -0
- package/bun.lock +8 -3
- package/docs/architecture/integrations.md +33 -59
- package/docs/architecture/memory.md +25 -30
- package/docs/architecture/security.md +19 -18
- package/docs/browser-use-architecture-phase2.md +63 -20
- package/docs/error-handling.md +111 -0
- package/docs/plugins.md +761 -0
- package/docs/skills.md +10 -10
- package/docs/stt-provider-onboarding.md +2 -1
- package/examples/plugins/echo/README.md +132 -0
- package/examples/plugins/echo/package.json +17 -0
- package/examples/plugins/echo/register.ts +187 -0
- package/knip.json +9 -2
- package/node_modules/@vellumai/ces-contracts/package.json +2 -1
- package/node_modules/@vellumai/ces-contracts/src/__tests__/trust-rules.test.ts +471 -0
- package/node_modules/@vellumai/ces-contracts/src/trust-rules.ts +398 -4
- package/node_modules/@vellumai/credential-storage/bun.lock +2 -2
- package/node_modules/@vellumai/credential-storage/package.json +2 -2
- package/node_modules/@vellumai/credential-storage/src/oauth-runtime.ts +20 -2
- package/node_modules/@vellumai/egress-proxy/bun.lock +2 -2
- package/node_modules/@vellumai/egress-proxy/package.json +2 -2
- package/node_modules/@vellumai/egress-proxy/src/types.ts +19 -0
- package/openapi.yaml +334 -78
- package/package.json +6 -3
- package/scripts/generate-openapi.ts +50 -11
- package/src/__tests__/agent-loop-callsite-precedence.test.ts +318 -0
- package/src/__tests__/agent-loop-sentry-hygiene.test.ts +137 -0
- package/src/__tests__/agent-loop.test.ts +112 -1
- package/src/__tests__/anthropic-error-formatting.test.ts +98 -0
- package/src/__tests__/anthropic-provider.test.ts +171 -2
- package/src/__tests__/app-compiler.test.ts +57 -0
- package/src/__tests__/approval-cascade.test.ts +36 -10
- package/src/__tests__/approval-routes-http.test.ts +134 -10
- package/src/__tests__/assistant-attachments.test.ts +44 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +29 -0
- package/src/__tests__/auto-analysis-end-to-end.test.ts +1 -0
- package/src/__tests__/avatar-generator.test.ts +4 -2
- package/src/__tests__/browser-fill-credential.test.ts +1 -1
- package/src/__tests__/browser-identifier-parity-guard.test.ts +53 -0
- package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +23 -33
- package/src/__tests__/browser-skill-endstate.test.ts +51 -182
- package/src/__tests__/btw-routes.test.ts +47 -1
- package/src/__tests__/bundled-asset.test.ts +6 -6
- package/src/__tests__/call-controller.test.ts +1 -2
- package/src/__tests__/call-site-routing-provider.test.ts +214 -0
- package/src/__tests__/catalog-cache.test.ts +96 -4
- package/src/__tests__/channel-approval-routes.test.ts +4 -4
- package/src/__tests__/channel-reply-delivery.test.ts +300 -2
- package/src/__tests__/checker.test.ts +870 -655
- package/src/__tests__/circuit-breaker-pipeline.test.ts +406 -0
- package/src/__tests__/cli-command-risk-guard.test.ts +30 -33
- package/src/__tests__/compaction-events.test.ts +501 -0
- package/src/__tests__/compaction-pipeline.test.ts +210 -0
- package/src/__tests__/compaction-strip-metadata-clear.test.ts +181 -0
- package/src/__tests__/compaction-timeout-recovery.test.ts +262 -0
- package/src/__tests__/compaction.benchmark.test.ts +1 -1
- package/src/__tests__/config-analysis.test.ts +11 -28
- package/src/__tests__/config-loader-backfill.test.ts +174 -0
- package/src/__tests__/config-loader-corrupt.test.ts +183 -0
- package/src/__tests__/config-loader-quarantine-bulletin.test.ts +202 -0
- package/src/__tests__/config-model-image-provider.test.ts +110 -0
- package/src/__tests__/config-schema-cmd.test.ts +11 -5
- package/src/__tests__/config-schema.test.ts +440 -114
- package/src/__tests__/config-watcher-cleanup-throttle.test.ts +0 -4
- package/src/__tests__/config-watcher.test.ts +2 -2
- package/src/__tests__/contact-store-user-file.test.ts +72 -73
- package/src/__tests__/contacts-tools.test.ts +26 -0
- package/src/__tests__/contacts-write.test.ts +4 -4
- package/src/__tests__/context-overflow-policy.test.ts +7 -7
- package/src/__tests__/context-token-estimator.test.ts +191 -1
- package/src/__tests__/context-window-manager.test.ts +883 -4
- package/src/__tests__/conversation-abort-tool-results.test.ts +32 -15
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +86 -46
- package/src/__tests__/conversation-agent-loop.test.ts +435 -216
- package/src/__tests__/conversation-attachments.test.ts +1 -1
- package/src/__tests__/conversation-confirmation-signals.test.ts +36 -10
- package/src/__tests__/conversation-error.test.ts +37 -6
- package/src/__tests__/conversation-history-web-search.test.ts +7 -0
- package/src/__tests__/conversation-init.benchmark.test.ts +34 -12
- package/src/__tests__/conversation-lifecycle.test.ts +336 -0
- package/src/__tests__/conversation-load-history-repair.test.ts +27 -10
- package/src/__tests__/conversation-pairing.test.ts +174 -10
- package/src/__tests__/conversation-pre-run-repair.test.ts +32 -15
- package/src/__tests__/conversation-process-callsite.test.ts +309 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +44 -21
- package/src/__tests__/conversation-queue.test.ts +68 -38
- package/src/__tests__/conversation-routes-disk-view.test.ts +36 -7
- package/src/__tests__/conversation-routes-slash-commands.test.ts +31 -3
- package/src/__tests__/conversation-runtime-assembly.test.ts +2877 -152
- package/src/__tests__/conversation-runtime-workspace.test.ts +35 -50
- package/src/__tests__/conversation-seed-composer.test.ts +2 -2
- package/src/__tests__/conversation-skill-tools.test.ts +12 -146
- package/src/__tests__/conversation-slash-queue.test.ts +39 -19
- package/src/__tests__/conversation-slash-unknown.test.ts +53 -16
- package/src/__tests__/conversation-speed-override.test.ts +36 -12
- package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +1035 -0
- package/src/__tests__/conversation-surfaces-standalone.test.ts +630 -0
- package/src/__tests__/conversation-title-service.test.ts +118 -2
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +41 -2
- package/src/__tests__/conversation-tool-setup-batch-authorized.test.ts +1 -1
- package/src/__tests__/conversation-unread-route.test.ts +2 -2
- package/src/__tests__/conversation-usage.test.ts +4 -2
- package/src/__tests__/conversation-workspace-cache-state.test.ts +33 -9
- package/src/__tests__/conversation-workspace-injection.test.ts +46 -15
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +46 -15
- package/src/__tests__/credential-broker-browser-fill.test.ts +110 -0
- package/src/__tests__/credential-health-service.test.ts +78 -9
- package/src/__tests__/credential-security-invariants.test.ts +5 -2
- package/src/__tests__/credential-storage-oauth-compat.test.ts +18 -0
- package/src/__tests__/credential-storage-static-compat.test.ts +28 -0
- package/src/__tests__/credential-vault-unit.test.ts +135 -19
- package/src/__tests__/credentials-cli.test.ts +1 -9
- package/src/__tests__/cross-provider-web-search.test.ts +84 -0
- package/src/__tests__/daemon-server-persist-and-process-callsite.test.ts +92 -0
- package/src/__tests__/db-schedule-syntax-migration.test.ts +1 -0
- package/src/__tests__/delete-propagation.test.ts +437 -0
- package/src/__tests__/dm-backfill.test.ts +417 -0
- package/src/__tests__/dm-persistence.test.ts +227 -0
- package/src/__tests__/edit-propagation.test.ts +280 -0
- package/src/__tests__/empty-response-pipeline.test.ts +305 -0
- package/src/__tests__/ephemeral-permissions.test.ts +93 -3
- package/src/__tests__/estimator-calibration-integration.test.ts +208 -0
- package/src/__tests__/estimator-calibration.test.ts +213 -0
- package/src/__tests__/extension-id-sync-guard.test.ts +29 -10
- package/src/__tests__/file-write-tool.test.ts +151 -1
- package/src/__tests__/filing-service.test.ts +255 -0
- package/src/__tests__/first-greeting.test.ts +247 -5
- package/src/__tests__/gemini-provider.test.ts +0 -3
- package/src/__tests__/guardian-grant-minting.test.ts +8 -0
- package/src/__tests__/headless-browser-interactions.test.ts +1 -1
- package/src/__tests__/headless-browser-mode.test.ts +57 -0
- package/src/__tests__/heartbeat-service.test.ts +96 -15
- package/src/__tests__/history-repair-pipeline.test.ts +399 -0
- package/src/__tests__/host-browser-e2e-cloud.test.ts +307 -0
- package/src/__tests__/host-browser-e2e-self-hosted.test.ts +3 -3
- package/src/__tests__/host-proxy-interface.test.ts +36 -2
- package/src/__tests__/host-shell-tool.test.ts +124 -18
- package/src/__tests__/http-user-message-parity.test.ts +29 -1
- package/src/__tests__/image-credentials.test.ts +137 -0
- package/src/__tests__/image-service-dispatcher.test.ts +186 -0
- package/src/__tests__/inbound-slack-persistence.test.ts +340 -0
- package/src/__tests__/injector-chain.test.ts +526 -0
- package/src/__tests__/intent-routing.test.ts +1 -66
- package/src/__tests__/llm-call-pipeline.test.ts +285 -0
- package/src/__tests__/llm-catalog-parity.test.ts +174 -0
- package/src/__tests__/llm-context-normalization.test.ts +121 -0
- package/src/__tests__/llm-resolver.test.ts +214 -0
- package/src/__tests__/llm-schema.test.ts +223 -0
- package/src/__tests__/managed-proxy-context.test.ts +6 -2
- package/src/__tests__/media-generate-image.test.ts +119 -13
- package/src/__tests__/memory-retrieval-pipeline.test.ts +401 -0
- package/src/__tests__/memory-upsert-concurrency.test.ts +1 -0
- package/src/__tests__/messaging-skill-split.test.ts +3 -34
- package/src/__tests__/migration-import-from-url.test.ts +621 -0
- package/src/__tests__/model-intents.test.ts +11 -83
- package/src/__tests__/notification-broadcaster.test.ts +3 -3
- package/src/__tests__/notification-decision-fallback.test.ts +0 -10
- package/src/__tests__/notification-decision-identity.test.ts +0 -9
- package/src/__tests__/notification-decision-recipient-context.test.ts +0 -9
- package/src/__tests__/notification-decision-strategy.test.ts +0 -11
- package/src/__tests__/notification-schedule-notify-dedup.test.ts +108 -0
- package/src/__tests__/oauth-apps-routes.test.ts +1 -1
- package/src/__tests__/oauth-cli.test.ts +14 -12
- package/src/__tests__/oauth-connect-orchestrator.test.ts +4 -13
- package/src/__tests__/oauth-provider-serializer.test.ts +6 -4
- package/src/__tests__/oauth-provider-visibility.test.ts +3 -5
- package/src/__tests__/oauth-providers-routes.test.ts +3 -2
- package/src/__tests__/oauth-store.test.ts +46 -78
- package/src/__tests__/oauth2-gateway-transport.test.ts +8 -3
- package/src/__tests__/oauth2-refresh-retry.test.ts +279 -0
- package/src/__tests__/onboarding-template-contract.test.ts +16 -64
- package/src/__tests__/openai-image-service.test.ts +368 -0
- package/src/__tests__/openai-provider.test.ts +7 -0
- package/src/__tests__/openai-responses-provider.test.ts +396 -0
- package/src/__tests__/openrouter-provider-only.test.ts +135 -0
- package/src/__tests__/outbound-slack-persistence.test.ts +293 -0
- package/src/__tests__/overflow-reduce-pipeline.test.ts +676 -0
- package/src/__tests__/permission-checker-host-gate.test.ts +1 -25
- package/src/__tests__/permission-mode.test.ts +16 -0
- package/src/__tests__/permission-types.test.ts +0 -1
- package/src/__tests__/persist-onboarding-artifacts.test.ts +266 -0
- package/src/__tests__/persistence-pipeline.test.ts +377 -0
- package/src/__tests__/persona-resolver.test.ts +13 -13
- package/src/__tests__/pipeline-runner.test.ts +565 -0
- package/src/__tests__/pkb-autoinject.test.ts +37 -1
- package/src/__tests__/platform-bash-auto-approve.test.ts +1 -1
- package/src/__tests__/platform.test.ts +5 -2
- package/src/__tests__/plugin-bootstrap.test.ts +483 -0
- package/src/__tests__/plugin-registry.test.ts +273 -0
- package/src/__tests__/plugin-route-contribution.test.ts +288 -0
- package/src/__tests__/plugin-skill-contribution.test.ts +367 -0
- package/src/__tests__/plugin-tool-contribution.test.ts +286 -0
- package/src/__tests__/plugin-types.test.ts +320 -0
- package/src/__tests__/pricing.test.ts +93 -14
- package/src/__tests__/profiler-routes.test.ts +1 -1
- package/src/__tests__/provider-commit-message-generator.test.ts +14 -84
- package/src/__tests__/provider-env-vars-scope.test.ts +52 -0
- package/src/__tests__/provider-error-scenarios.test.ts +135 -6
- package/src/__tests__/provider-managed-proxy-integration.test.ts +42 -11
- package/src/__tests__/provider-registry-ollama.test.ts +1 -2
- package/src/__tests__/proxy-approval-callback.test.ts +69 -9
- package/src/__tests__/reaction-persistence.test.ts +561 -0
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +1 -0
- package/src/__tests__/registry.test.ts +0 -2
- package/src/__tests__/relay-server.test.ts +1 -1
- package/src/__tests__/require-fresh-approval.test.ts +1 -1
- package/src/__tests__/retry-openrouter-only-normalization.test.ts +136 -0
- package/src/__tests__/retry-thinking-tool-choice.test.ts +226 -0
- package/src/__tests__/risk-classifier-parity.test.ts +230 -0
- package/src/__tests__/sanitize-config-for-transfer.test.ts +78 -1
- package/src/__tests__/schedule-routes.test.ts +131 -1
- package/src/__tests__/scheduler-recurrence.test.ts +14 -70
- package/src/__tests__/scheduler-reuse-conversation.test.ts +10 -50
- package/src/__tests__/secret-detection-handler.test.ts +0 -10
- package/src/__tests__/secret-ingress-http.test.ts +28 -0
- package/src/__tests__/secret-prompter-channel-fallback.test.ts +125 -0
- package/src/__tests__/secret-routes-managed-proxy.test.ts +2 -3
- package/src/__tests__/secret-scanner-executor.test.ts +1 -1
- package/src/__tests__/send-endpoint-busy.test.ts +29 -1
- package/src/__tests__/server-history-render.test.ts +31 -0
- package/src/__tests__/shell-identity.test.ts +0 -134
- package/src/__tests__/shell-parser-property.test.ts +13 -13
- package/src/__tests__/skill-cache-store.test.ts +182 -0
- package/src/__tests__/skills.test.ts +19 -33
- package/src/__tests__/slack-app-setup-skill-regression.test.ts +3 -1
- package/src/__tests__/slack-skill.test.ts +3 -8
- package/src/__tests__/starter-bundle.test.ts +35 -0
- package/src/__tests__/subagent-call-site-routing.test.ts +280 -0
- package/src/__tests__/suggestion-routes.test.ts +259 -3
- package/src/__tests__/system-prompt.test.ts +22 -35
- package/src/__tests__/task-memory-cleanup.test.ts +1 -0
- package/src/__tests__/task-runner.test.ts +3 -1
- package/src/__tests__/task-scheduler.test.ts +3 -15
- package/src/__tests__/tcc-sandbox-deny.test.ts +198 -0
- package/src/__tests__/terminal-tools.test.ts +8 -0
- package/src/__tests__/test-preload.ts +11 -0
- package/src/__tests__/test-support/browser-skill-harness.ts +2 -52
- package/src/__tests__/thread-backfill.test.ts +941 -0
- package/src/__tests__/title-generate-pipeline.test.ts +224 -0
- package/src/__tests__/token-estimate-pipeline.test.ts +431 -0
- package/src/__tests__/tool-error-pipeline.test.ts +244 -0
- package/src/__tests__/tool-execute-pipeline.test.ts +431 -0
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +2 -8
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +2 -2
- package/src/__tests__/tool-executor-shell-integration.test.ts +7 -10
- package/src/__tests__/tool-executor.test.ts +201 -94
- package/src/__tests__/tool-result-truncate-pipeline.test.ts +356 -0
- package/src/__tests__/tool-result-truncation.test.ts +0 -110
- package/src/__tests__/trust-store.test.ts +442 -109
- package/src/__tests__/update-bulletin-job.test.ts +389 -0
- package/src/__tests__/usage-cache-backfill-migration.test.ts +3 -1
- package/src/__tests__/user-plugin-loader.test.ts +191 -0
- package/src/__tests__/verification-control-plane-policy.test.ts +1 -22
- package/src/__tests__/voice-session-bridge.test.ts +39 -0
- package/src/__tests__/volume-security-guard.test.ts +3 -2
- package/src/__tests__/web-search-history.test.ts +337 -0
- package/src/__tests__/workspace-migration-039-drop-legacy-llm-keys.test.ts +343 -0
- package/src/__tests__/workspace-migration-043-release-notes-latex-rendering.test.ts +202 -0
- package/src/__tests__/workspace-migration-045-release-notes-meet-avatar.test.ts +210 -0
- package/src/__tests__/workspace-migration-046-seed-conversation-starters-callsite.test.ts +185 -0
- package/src/__tests__/workspace-migration-049-release-notes-default-sonnet.test.ts +100 -0
- package/src/__tests__/workspace-migration-050-seed-main-agent-opus-callsite.test.ts +171 -0
- package/src/__tests__/workspace-migration-051-seed-conversation-summarization-callsite.test.ts +252 -0
- package/src/__tests__/workspace-migration-drop-user-md.test.ts +11 -11
- package/src/__tests__/workspace-migration-remove-hooks.test.ts +99 -0
- package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +841 -0
- package/src/__tests__/workspace-policy.test.ts +22 -16
- package/src/acp/client-handler.ts +1 -2
- package/src/agent/loop.ts +545 -115
- package/src/approvals/__tests__/guardian-feed-event.test.ts +304 -0
- package/src/approvals/guardian-request-resolvers.ts +80 -0
- package/src/avatar/resvg-lazy.test.ts +136 -0
- package/src/avatar/resvg-lazy.ts +82 -9
- package/src/avatar/traits-png-sync.ts +21 -1
- package/src/backup/__tests__/backup-worker.test.ts +2 -13
- package/src/backup/backup-worker.ts +3 -15
- package/src/browser/__tests__/operations.test.ts +163 -0
- package/src/browser/identifiers.ts +51 -0
- package/src/browser/operations.ts +660 -0
- package/src/browser/types.ts +81 -0
- package/src/bundler/app-compiler.ts +84 -1
- package/src/calls/call-state.ts +2 -2
- package/src/calls/guardian-question-copy.ts +2 -2
- package/src/calls/telephony-stt-routing.ts +1 -1
- package/src/calls/voice-session-bridge.ts +1 -0
- package/src/channels/__tests__/types.test.ts +3 -3
- package/src/channels/types.ts +6 -4
- package/src/cli/AGENTS.md +1 -1
- package/src/cli/__tests__/notifications.test.ts +87 -211
- package/src/cli/commands/__tests__/attachment.test.ts +438 -0
- package/src/cli/commands/__tests__/backup.test.ts +1 -1
- package/src/cli/commands/__tests__/browser.test.ts +554 -0
- package/src/cli/commands/__tests__/cache.test.ts +623 -0
- package/src/cli/commands/__tests__/email-list.test.ts +6 -0
- package/src/cli/commands/__tests__/email-send.test.ts +93 -1
- package/src/cli/commands/__tests__/image-generation.test.ts +886 -0
- package/src/cli/commands/__tests__/inference-send.test.ts +463 -0
- package/src/cli/commands/__tests__/stt-transcribe.test.ts +454 -0
- package/src/cli/commands/__tests__/task.test.ts +913 -0
- package/src/cli/commands/__tests__/tts-synthesize.test.ts +606 -0
- package/src/cli/commands/__tests__/ui-confirm.test.ts +650 -0
- package/src/cli/commands/__tests__/ui.test.ts +1215 -0
- package/src/cli/commands/__tests__/watchers.test.ts +716 -0
- package/src/cli/commands/attachment.ts +182 -0
- package/src/cli/commands/backup.ts +2 -2
- package/src/cli/commands/browser.ts +350 -0
- package/src/cli/commands/cache.ts +341 -0
- package/src/cli/commands/clients.ts +138 -0
- package/src/cli/commands/completions.ts +2 -12
- package/src/cli/commands/config.ts +6 -6
- package/src/cli/commands/conversations-import.ts +347 -0
- package/src/cli/commands/conversations.ts +69 -8
- package/src/cli/commands/email.ts +234 -194
- package/src/cli/commands/image-generation.ts +299 -0
- package/src/cli/commands/inference.ts +200 -0
- package/src/cli/commands/memory.ts +127 -17
- package/src/cli/commands/notifications.ts +68 -103
- package/src/cli/commands/oauth/__tests__/providers-register.test.ts +1 -1
- package/src/cli/commands/oauth/__tests__/providers-update.test.ts +1 -1
- package/src/cli/commands/oauth/connect.ts +2 -2
- package/src/cli/commands/oauth/providers.ts +176 -8
- package/src/cli/commands/oauth/status.ts +46 -36
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +0 -1
- package/src/cli/commands/platform/__tests__/connect.test.ts +0 -1
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +0 -1
- package/src/cli/commands/platform/__tests__/status.test.ts +0 -1
- package/src/cli/commands/skills.ts +3 -4
- package/src/cli/commands/stt.ts +339 -0
- package/src/cli/commands/task.ts +795 -0
- package/src/cli/commands/trust.ts +50 -19
- package/src/cli/commands/tts.ts +273 -0
- package/src/cli/commands/ui.ts +670 -0
- package/src/cli/commands/watchers.ts +509 -0
- package/src/cli/lib/daemon-credential-client.ts +0 -19
- package/src/cli/program.ts +39 -24
- package/src/cli.ts +0 -37
- package/src/config/__tests__/backup-schema.test.ts +7 -2
- package/src/config/bundled-skills/app-builder/SKILL.md +2 -2
- package/src/config/bundled-skills/app-builder/references/WIDGETS.md +10 -10
- package/src/config/bundled-skills/contacts/tools/contact-merge.ts +66 -87
- package/src/config/bundled-skills/contacts/tools/contact-search.ts +28 -51
- package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +22 -40
- package/src/config/bundled-skills/image-studio/SKILL.md +2 -1
- package/src/config/bundled-skills/image-studio/TOOLS.json +2 -1
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +23 -39
- package/src/config/bundled-skills/media-processing/services/reduce.ts +1 -1
- package/src/config/bundled-skills/messaging/SKILL.md +5 -5
- package/src/config/bundled-skills/messaging/TOOLS.json +4 -0
- package/src/config/bundled-skills/messaging/tools/__tests__/messaging-feed-events.test.ts +207 -0
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +20 -1
- package/src/config/bundled-skills/messaging/tools/messaging-read.ts +15 -1
- package/src/config/bundled-skills/messaging/tools/messaging-search.ts +21 -1
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +69 -12
- package/src/config/bundled-skills/phone-calls/references/CONFIG.md +9 -8
- package/src/config/bundled-skills/schedule/SKILL.md +8 -3
- package/src/config/bundled-skills/schedule/TOOLS.json +15 -7
- package/src/config/bundled-skills/schedule/references/SCRIPT_MODE_PATTERNS.md +59 -0
- package/src/config/bundled-skills/settings/TOOLS.json +3 -3
- package/src/config/bundled-tool-registry.ts +0 -190
- package/src/config/env.ts +7 -2
- package/src/config/feature-flag-registry.json +42 -10
- package/src/config/llm-resolver.ts +128 -0
- package/src/config/loader.ts +194 -10
- package/src/config/raw-config-utils.ts +30 -2
- package/src/config/sanitize-for-transfer.ts +35 -0
- package/src/config/schema.ts +49 -41
- package/src/config/schemas/analysis.ts +3 -22
- package/src/config/schemas/backup.ts +1 -1
- package/src/config/schemas/calls.ts +0 -4
- package/src/config/schemas/conversations.ts +16 -0
- package/src/config/schemas/filing.ts +2 -7
- package/src/config/schemas/heartbeat.ts +0 -5
- package/src/config/schemas/inference.ts +3 -23
- package/src/config/schemas/llm.ts +317 -0
- package/src/config/schemas/memory-processing.ts +1 -9
- package/src/config/schemas/notifications.ts +4 -11
- package/src/config/schemas/platform.ts +3 -9
- package/src/config/schemas/security.ts +33 -0
- package/src/config/schemas/services.ts +9 -4
- package/src/config/schemas/stt.ts +1 -0
- package/src/config/schemas/tts.ts +64 -0
- package/src/config/schemas/updates.ts +1 -1
- package/src/config/schemas/workspace-git.ts +3 -40
- package/src/config/skill-state.ts +6 -2
- package/src/config/skills.ts +96 -7
- package/src/context/__tests__/compact-prompt.test.ts +63 -0
- package/src/context/__tests__/microcompact.test.ts +805 -0
- package/src/context/estimator-calibration.ts +136 -0
- package/src/context/microcompact.ts +443 -0
- package/src/context/prompts/compact.md +26 -0
- package/src/context/token-estimator.ts +61 -3
- package/src/context/tool-result-truncation.ts +3 -63
- package/src/context/window-manager.ts +417 -39
- package/src/credential-execution/approval-bridge.ts +0 -1
- package/src/credential-execution/executable-discovery.ts +19 -8
- package/src/credential-execution/process-manager.test.ts +109 -0
- package/src/credential-execution/process-manager.ts +65 -2
- package/src/credential-health/credential-health-service.ts +19 -6
- package/src/daemon/__tests__/conversation-feed-event.test.ts +317 -0
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +4 -12
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +14 -15
- package/src/daemon/approval-generators.ts +29 -4
- package/src/daemon/assistant-attachments.ts +24 -13
- package/src/daemon/classifier.ts +2 -2
- package/src/daemon/config-watcher.ts +0 -3
- package/src/daemon/context-overflow-policy.ts +4 -13
- package/src/daemon/context-overflow-reducer.ts +4 -1
- package/src/daemon/conversation-agent-loop-handlers.ts +162 -34
- package/src/daemon/conversation-agent-loop.ts +1282 -599
- package/src/daemon/conversation-attachments.ts +2 -6
- package/src/daemon/conversation-error.ts +36 -1
- package/src/daemon/conversation-history.ts +10 -19
- package/src/daemon/conversation-lifecycle.ts +59 -17
- package/src/daemon/conversation-messaging.ts +73 -4
- package/src/daemon/conversation-notifiers.ts +2 -110
- package/src/daemon/conversation-process.ts +24 -11
- package/src/daemon/conversation-queue-manager.ts +3 -0
- package/src/daemon/conversation-runtime-assembly.ts +1063 -211
- package/src/daemon/conversation-slash.ts +2 -2
- package/src/daemon/conversation-surfaces.ts +389 -1
- package/src/daemon/conversation-tool-setup.ts +51 -9
- package/src/daemon/conversation-usage.ts +1 -1
- package/src/daemon/conversation.ts +197 -64
- package/src/daemon/external-plugins-bootstrap.ts +478 -0
- package/src/daemon/external-skills-bootstrap.ts +41 -0
- package/src/daemon/first-greeting.ts +191 -14
- package/src/daemon/guardian-action-generators.ts +34 -14
- package/src/daemon/handlers/config-model.test.ts +86 -0
- package/src/daemon/handlers/config-model.ts +65 -12
- package/src/daemon/handlers/conversations.ts +9 -2
- package/src/daemon/handlers/shared.ts +39 -11
- package/src/daemon/handlers/skills.ts +7 -3
- package/src/daemon/handlers/slack-channel-oauth-install.ts +197 -0
- package/src/daemon/lifecycle.ts +109 -82
- package/src/daemon/message-types/computer-use.ts +2 -34
- package/src/daemon/message-types/conversations.ts +63 -0
- package/src/daemon/message-types/messages.ts +21 -1
- package/src/daemon/message-types/trust.ts +0 -2
- package/src/daemon/parse-actual-tokens-from-error.test.ts +57 -1
- package/src/daemon/parse-actual-tokens-from-error.ts +66 -0
- package/src/daemon/pkb-context-tracker.test.ts +169 -0
- package/src/daemon/pkb-context-tracker.ts +125 -0
- package/src/daemon/pkb-reminder-builder.test.ts +70 -0
- package/src/daemon/pkb-reminder-builder.ts +31 -0
- package/src/daemon/providers-setup.ts +6 -0
- package/src/daemon/server.ts +122 -12
- package/src/daemon/shutdown-handlers.ts +2 -12
- package/src/daemon/tool-side-effects.ts +14 -65
- package/src/daemon/web-search-history.ts +126 -0
- package/src/events/domain-events.ts +0 -1
- package/src/filing/filing-service.ts +9 -10
- package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +160 -0
- package/src/heartbeat/heartbeat-service.ts +99 -28
- package/src/home/__tests__/feed-population-integration.test.ts +312 -0
- package/src/home/__tests__/feed-scheduler.test.ts +39 -11
- package/src/home/__tests__/rollup-producer.test.ts +44 -0
- package/src/home/assistant-feed-authoring.ts +4 -0
- package/src/home/emit-feed-event.ts +11 -0
- package/src/home/feed-scheduler.ts +20 -4
- package/src/home/feed-types.ts +97 -4
- package/src/home/relationship-state-writer.ts +2 -2
- package/src/home/rewrite-command-preview.ts +66 -0
- package/src/home/rollup-producer.ts +34 -5
- package/src/home/suggested-prompts.ts +101 -0
- package/src/ipc/__tests__/attachment-ipc.test.ts +213 -0
- package/src/ipc/__tests__/browser-ipc.test.ts +339 -0
- package/src/ipc/__tests__/cache-ipc.test.ts +266 -0
- package/src/ipc/__tests__/socket-path.test.ts +34 -0
- package/src/ipc/__tests__/task-ipc.test.ts +577 -0
- package/src/ipc/__tests__/ui-request-route.test.ts +495 -0
- package/src/ipc/__tests__/watcher-ipc.test.ts +295 -0
- package/src/ipc/cli-client.ts +2 -1
- package/src/ipc/cli-server.ts +26 -8
- package/src/ipc/gateway-client.ts +6 -3
- package/src/ipc/routes/attachment.ts +114 -0
- package/src/ipc/routes/browser-context.ts +63 -0
- package/src/ipc/routes/browser.ts +97 -0
- package/src/ipc/routes/cache.ts +96 -0
- package/src/ipc/routes/get-contact.ts +16 -0
- package/src/ipc/routes/index.ts +31 -1
- package/src/ipc/routes/list-clients.ts +31 -0
- package/src/ipc/routes/merge-contacts.ts +17 -0
- package/src/ipc/routes/notification.ts +133 -0
- package/src/ipc/routes/rename-conversation.ts +59 -0
- package/src/ipc/routes/search-contacts.ts +19 -0
- package/src/ipc/routes/task-queue.ts +226 -0
- package/src/ipc/routes/task.ts +173 -0
- package/src/ipc/routes/ui-request.ts +50 -0
- package/src/ipc/routes/upsert-contact.ts +25 -0
- package/src/ipc/routes/watcher.ts +203 -0
- package/src/ipc/socket-path.ts +76 -0
- package/src/media/app-icon-generator.ts +23 -46
- package/src/media/avatar-router.ts +26 -41
- package/src/media/gemini-image-service.ts +8 -41
- package/src/media/image-credentials.ts +73 -0
- package/src/media/image-service.ts +85 -0
- package/src/media/openai-image-service.ts +131 -0
- package/src/media/types.ts +46 -0
- package/src/memory/__tests__/conversation-analyze-job.test.ts +9 -8
- package/src/memory/__tests__/conversation-group-migration.test.ts +99 -0
- package/src/memory/admin.ts +18 -0
- package/src/memory/conversation-analyze-job.ts +14 -13
- package/src/memory/conversation-attention-store.ts +13 -6
- package/src/memory/conversation-crud.ts +133 -3
- package/src/memory/conversation-group-migration.ts +38 -6
- package/src/memory/conversation-queries.ts +57 -4
- package/src/memory/conversation-title-service.ts +32 -4
- package/src/memory/db-init.ts +10 -0
- package/src/memory/embedding-backend.ts +1 -1
- package/src/memory/embedding-gemini.test.ts +41 -2
- package/src/memory/embedding-gemini.ts +6 -1
- package/src/memory/graph/bootstrap.test.ts +282 -0
- package/src/memory/graph/bootstrap.ts +8 -5
- package/src/memory/graph/compaction.ts +299 -0
- package/src/memory/graph/consolidation.ts +4 -4
- package/src/memory/graph/conversation-graph-memory.ts +89 -29
- package/src/memory/graph/extraction.test.ts +272 -2
- package/src/memory/graph/extraction.ts +183 -53
- package/src/memory/graph/graph-search.test.ts +93 -0
- package/src/memory/graph/graph-search.ts +4 -1
- package/src/memory/graph/inspect.ts +2 -2
- package/src/memory/graph/narrative.ts +2 -2
- package/src/memory/graph/pattern-scan.ts +2 -2
- package/src/memory/graph/retriever.test.ts +459 -0
- package/src/memory/graph/retriever.ts +237 -48
- package/src/memory/graph/store.ts +41 -0
- package/src/memory/graph/tool-handlers.ts +27 -0
- package/src/memory/graph/tools.ts +6 -1
- package/src/memory/indexer.ts +5 -5
- package/src/memory/job-handlers/conversation-starters.ts +23 -20
- package/src/memory/job-handlers/summarization.ts +2 -2
- package/src/memory/job-utils.ts +7 -1
- package/src/memory/jobs/embed-pkb-file.test.ts +168 -0
- package/src/memory/jobs/embed-pkb-file.ts +54 -0
- package/src/memory/jobs-store.ts +44 -3
- package/src/memory/jobs-worker.ts +4 -0
- package/src/memory/migrations/041-approval-prompt-ts-tracker.ts +26 -0
- package/src/memory/migrations/140-backfill-usage-cache-accounting.ts +1 -1
- package/src/memory/migrations/149-oauth-tables.ts +1 -0
- package/src/memory/migrations/220-normalize-user-file-by-principal.ts +2 -2
- package/src/memory/migrations/222-strip-placeholder-sentinels-from-messages.ts +82 -0
- package/src/memory/migrations/223-schedule-script-column.ts +11 -0
- package/src/memory/migrations/224-oauth-providers-managed-service-is-paid.ts +24 -0
- package/src/memory/migrations/225-oauth-providers-available-scopes.ts +13 -0
- package/src/memory/migrations/index.ts +5 -0
- package/src/memory/pkb/pkb-index.test.ts +369 -0
- package/src/memory/pkb/pkb-index.ts +255 -0
- package/src/memory/pkb/pkb-reconcile.test.ts +252 -0
- package/src/memory/pkb/pkb-reconcile.ts +148 -0
- package/src/memory/pkb/pkb-search.test.ts +499 -0
- package/src/memory/pkb/pkb-search.ts +159 -0
- package/src/memory/pkb/types.ts +53 -0
- package/src/memory/qdrant-client.test.ts +60 -0
- package/src/memory/qdrant-client.ts +147 -1
- package/src/memory/schema/infrastructure.ts +1 -0
- package/src/memory/schema/oauth.ts +4 -1
- package/src/memory/slack-thread-store.ts +37 -0
- package/src/messaging/providers/gmail/adapter.ts +6 -16
- package/src/messaging/providers/gmail/client.ts +22 -0
- package/src/messaging/providers/gmail/types.ts +7 -0
- package/src/messaging/providers/slack/adapter.ts +14 -2
- package/src/messaging/providers/slack/backfill.test.ts +257 -0
- package/src/messaging/providers/slack/backfill.ts +101 -0
- package/src/messaging/providers/slack/message-metadata.test.ts +316 -0
- package/src/messaging/providers/slack/message-metadata.ts +123 -0
- package/src/messaging/providers/slack/render-transcript.test.ts +1421 -0
- package/src/messaging/providers/slack/render-transcript.ts +501 -0
- package/src/messaging/style-analyzer.ts +5 -2
- package/src/notifications/README.md +9 -5
- package/src/notifications/conversation-pairing.ts +78 -19
- package/src/notifications/copy-composer.ts +0 -5
- package/src/notifications/decision-engine.ts +3 -9
- package/src/notifications/emit-signal.ts +1 -1
- package/src/notifications/preference-extractor.ts +2 -6
- package/src/notifications/signal.ts +1 -2
- package/src/oauth/AGENTS.md +1 -1
- package/src/oauth/__tests__/identity-verifier.test.ts +2 -1
- package/src/oauth/connect-orchestrator.ts +8 -34
- package/src/oauth/connect-types.ts +6 -10
- package/src/oauth/manual-token-connection.ts +23 -0
- package/src/oauth/oauth-store.ts +31 -14
- package/src/oauth/platform-connection.test.ts +47 -0
- package/src/oauth/platform-connection.ts +15 -5
- package/src/oauth/provider-serializer.ts +6 -1
- package/src/oauth/seed-providers.ts +56 -106
- package/src/outbound-proxy/http-forwarder.ts +9 -0
- package/src/permissions/approval-policy.test.ts +1223 -0
- package/src/permissions/approval-policy.ts +309 -0
- package/src/permissions/arg-parser.test.ts +161 -0
- package/src/permissions/arg-parser.ts +141 -0
- package/src/permissions/bash-risk-classifier.test.ts +1620 -0
- package/src/permissions/bash-risk-classifier.ts +950 -0
- package/src/permissions/checker.ts +348 -711
- package/src/permissions/command-registry.test.ts +774 -0
- package/src/permissions/command-registry.ts +1005 -0
- package/src/permissions/defaults.ts +28 -79
- package/src/permissions/file-risk-classifier.test.ts +535 -0
- package/src/permissions/file-risk-classifier.ts +274 -0
- package/src/permissions/gateway-threshold-reader.ts +196 -0
- package/src/permissions/prompter.ts +4 -0
- package/src/permissions/risk-types.ts +262 -0
- package/src/permissions/schedule-risk-classifier.test.ts +129 -0
- package/src/permissions/schedule-risk-classifier.ts +85 -0
- package/src/permissions/secret-prompter.ts +53 -2
- package/src/permissions/shell-identity.ts +2 -42
- package/src/permissions/skill-risk-classifier.test.ts +311 -0
- package/src/permissions/skill-risk-classifier.ts +214 -0
- package/src/permissions/trust-client.ts +52 -25
- package/src/permissions/trust-store-interface.ts +1 -6
- package/src/permissions/trust-store.ts +161 -62
- package/src/permissions/types.ts +25 -14
- package/src/permissions/web-risk-classifier.test.ts +170 -0
- package/src/permissions/web-risk-classifier.ts +89 -0
- package/src/permissions/workspace-policy.ts +9 -19
- package/src/platform/client.ts +19 -1
- package/src/plugins/defaults/circuit-breaker.ts +146 -0
- package/src/plugins/defaults/compaction.ts +145 -0
- package/src/plugins/defaults/empty-response.ts +126 -0
- package/src/plugins/defaults/history-repair.ts +85 -0
- package/src/plugins/defaults/index.ts +116 -0
- package/src/plugins/defaults/injectors.ts +491 -0
- package/src/plugins/defaults/llm-call.ts +82 -0
- package/src/plugins/defaults/memory-retrieval.ts +226 -0
- package/src/plugins/defaults/overflow-reduce.ts +181 -0
- package/src/plugins/defaults/persistence.ts +129 -0
- package/src/plugins/defaults/title-generate.ts +95 -0
- package/src/plugins/defaults/token-estimate.ts +104 -0
- package/src/plugins/defaults/tool-error.ts +126 -0
- package/src/plugins/defaults/tool-execute.ts +89 -0
- package/src/plugins/defaults/tool-result-truncate.ts +88 -0
- package/src/plugins/pipeline.ts +316 -0
- package/src/plugins/plugin-skill-contributions.ts +292 -0
- package/src/plugins/registry.ts +241 -0
- package/src/plugins/types.ts +1134 -0
- package/src/plugins/user-loader.ts +177 -0
- package/src/prompts/persona-resolver.ts +3 -3
- package/src/prompts/system-prompt.ts +19 -20
- package/src/prompts/templates/BOOTSTRAP.md +27 -77
- package/src/prompts/templates/SOUL.md +2 -2
- package/src/prompts/update-bulletin-job.ts +190 -0
- package/src/providers/__tests__/context-overflow-error.test.ts +328 -0
- package/src/providers/__tests__/provider-env-vars.test.ts +102 -0
- package/src/providers/__tests__/retry-callsite.test.ts +424 -0
- package/src/providers/anthropic/client.ts +183 -14
- package/src/providers/call-site-routing.ts +71 -0
- package/src/providers/gemini/client.ts +65 -2
- package/src/providers/managed-proxy/constants.ts +2 -1
- package/src/providers/model-catalog.ts +524 -33
- package/src/providers/model-intents.ts +4 -4
- package/src/providers/openai/chat-completions-provider.ts +57 -1
- package/src/providers/openai/responses-provider.ts +86 -9
- package/src/providers/openrouter/client.ts +80 -9
- package/src/providers/provider-env-vars.ts +56 -0
- package/src/providers/provider-send-message.ts +22 -5
- package/src/providers/ratelimit.ts +4 -0
- package/src/providers/registry.ts +19 -8
- package/src/providers/retry.ts +174 -39
- package/src/providers/speech-to-text/__tests__/resolve.test.ts +55 -0
- package/src/providers/speech-to-text/deepgram-realtime.test.ts +61 -0
- package/src/providers/speech-to-text/deepgram-realtime.ts +57 -0
- package/src/providers/speech-to-text/google-gemini-live-stream.ts +4 -4
- package/src/providers/speech-to-text/provider-catalog.ts +17 -0
- package/src/providers/speech-to-text/resolve.ts +7 -0
- package/src/providers/speech-to-text/xai-realtime.test.ts +646 -0
- package/src/providers/speech-to-text/xai-realtime.ts +821 -0
- package/src/providers/speech-to-text/xai.test.ts +155 -0
- package/src/providers/speech-to-text/xai.ts +97 -0
- package/src/providers/types.ts +93 -3
- package/src/runtime/AGENTS.md +27 -18
- package/src/runtime/__tests__/agent-wake.test.ts +43 -2
- package/src/runtime/__tests__/browser-extension-pair-routes.test.ts +3 -3
- package/src/runtime/__tests__/client-registry.test.ts +293 -0
- package/src/runtime/__tests__/interactive-ui.test.ts +673 -0
- package/src/runtime/agent-wake.ts +63 -22
- package/src/runtime/auth/route-policy.ts +4 -0
- package/src/runtime/btw-sidechain.ts +13 -3
- package/src/runtime/channel-reply-delivery.ts +106 -2
- package/src/runtime/client-registry.ts +261 -0
- package/src/runtime/decision-token.ts +116 -0
- package/src/runtime/gateway-client.ts +2 -2
- package/src/runtime/http-router.ts +32 -0
- package/src/runtime/http-server.ts +129 -9
- package/src/runtime/http-types.ts +23 -3
- package/src/runtime/interactive-ui.ts +362 -0
- package/src/runtime/invite-instruction-generator.ts +2 -2
- package/src/runtime/migrations/__tests__/gcs-signed-url.test.ts +176 -0
- package/src/runtime/migrations/__tests__/vbundle-metadata-merge-integration.test.ts +390 -0
- package/src/runtime/migrations/__tests__/vbundle-metadata-merge.test.ts +221 -0
- package/src/runtime/migrations/__tests__/vbundle-streaming-importer.test.ts +1540 -0
- package/src/runtime/migrations/__tests__/vbundle-streaming-validator.test.ts +453 -0
- package/src/runtime/migrations/__tests__/vbundle-tar-stream.test.ts +222 -0
- package/src/runtime/migrations/gcs-signed-url.ts +162 -0
- package/src/runtime/migrations/vbundle-builder.ts +1 -22
- package/src/runtime/migrations/vbundle-importer.ts +154 -9
- package/src/runtime/migrations/vbundle-metadata-merge.ts +124 -0
- package/src/runtime/migrations/vbundle-streaming-importer.ts +2522 -0
- package/src/runtime/migrations/vbundle-streaming-validator.ts +244 -0
- package/src/runtime/migrations/vbundle-tar-stream.ts +217 -0
- package/src/runtime/migrations/vbundle-validator.ts +15 -6
- package/src/runtime/routes/__tests__/home-feed-routes.test.ts +111 -0
- package/src/runtime/routes/__tests__/migration-import-credential-filter.test.ts +114 -75
- package/src/runtime/routes/__tests__/migration-vellum-metadata-reconcile.test.ts +246 -0
- package/src/runtime/routes/approval-prompt-ts-tracker.ts +78 -0
- package/src/runtime/routes/approval-routes.ts +29 -17
- package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +9 -0
- package/src/runtime/routes/avatar-routes.ts +20 -4
- package/src/runtime/routes/browser-extension-pair-routes.ts +27 -8
- package/src/runtime/routes/btw-routes.ts +1 -4
- package/src/runtime/routes/conversation-management-routes.ts +20 -2
- package/src/runtime/routes/conversation-routes.ts +351 -138
- package/src/runtime/routes/debug-routes.ts +1 -1
- package/src/runtime/routes/diagnostics-routes.ts +6 -4
- package/src/runtime/routes/events-routes.ts +16 -0
- package/src/runtime/routes/guardian-approval-interception.ts +33 -3
- package/src/runtime/routes/guardian-approval-prompt.ts +13 -3
- package/src/runtime/routes/home-feed-routes.ts +120 -2
- package/src/runtime/routes/inbound-message-handler.ts +987 -2
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +113 -2
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +61 -3
- package/src/runtime/routes/inbound-stages/edit-intercept.ts +129 -6
- package/src/runtime/routes/integrations/slack/channel.ts +25 -3
- package/src/runtime/routes/llm-context-normalization.ts +23 -1
- package/src/runtime/routes/memory-item-routes.test.ts +1 -0
- package/src/runtime/routes/migration-routes.ts +720 -127
- package/src/runtime/routes/playground/__tests__/force-compact.test.ts +284 -0
- package/src/runtime/routes/playground/__tests__/guard.test.ts +80 -0
- package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +294 -0
- package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +271 -0
- package/src/runtime/routes/playground/__tests__/seed-conversation.test.ts +202 -0
- package/src/runtime/routes/playground/__tests__/seeded-conversations.test.ts +309 -0
- package/src/runtime/routes/playground/__tests__/state.test.ts +224 -0
- package/src/runtime/routes/playground/conversation-not-found.ts +29 -0
- package/src/runtime/routes/playground/deps.ts +56 -0
- package/src/runtime/routes/playground/force-compact.ts +73 -0
- package/src/runtime/routes/playground/guard.ts +37 -0
- package/src/runtime/routes/playground/index.ts +28 -0
- package/src/runtime/routes/playground/inject-failures.ts +159 -0
- package/src/runtime/routes/playground/reset-circuit.ts +115 -0
- package/src/runtime/routes/playground/seed-conversation.ts +139 -0
- package/src/runtime/routes/playground/seeded-conversations.ts +78 -0
- package/src/runtime/routes/playground/state.ts +78 -0
- package/src/runtime/routes/schedule-routes.ts +89 -8
- package/src/runtime/routes/settings-routes.ts +4 -2
- package/src/runtime/routes/trust-rules-routes.ts +30 -14
- package/src/runtime/routes/work-items-routes.test.ts +1 -1
- package/src/runtime/routes/work-items-routes.ts +3 -2
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +25 -43
- package/src/runtime/services/analyze-conversation.ts +12 -16
- package/src/runtime/skill-route-registry.ts +97 -15
- package/src/schedule/run-script.ts +68 -0
- package/src/schedule/schedule-store.ts +7 -1
- package/src/schedule/scheduler.ts +56 -8
- package/src/security/__tests__/provider-key-env-fallback.test.ts +119 -0
- package/src/security/__tests__/untrusted-content.test.ts +109 -0
- package/src/security/oauth2.ts +98 -35
- package/src/security/secure-keys.ts +7 -8
- package/src/security/token-manager.ts +27 -13
- package/src/security/untrusted-content.ts +102 -0
- package/src/skills/catalog-cache.ts +35 -9
- package/src/skills/catalog-install.ts +31 -3
- package/src/skills/skill-cache-store.ts +97 -0
- package/src/stt/__tests__/daemon-batch-transcriber.test.ts +76 -0
- package/src/stt/daemon-batch-transcriber.ts +33 -0
- package/src/stt/stt-stream-session.ts +8 -1
- package/src/stt/types.ts +5 -1
- package/src/subagent/manager.ts +41 -13
- package/src/tasks/ephemeral-permissions.ts +9 -4
- package/src/telemetry/usage-telemetry-reporter.ts +27 -5
- package/src/tools/browser/__tests__/browser-status.test.ts +234 -2
- package/src/tools/browser/browser-execution.ts +150 -54
- package/src/tools/browser/cdp-client/__tests__/extension-cdp-client.test.ts +230 -0
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +146 -3
- package/src/tools/browser/cdp-client/cdp-inspect/discovery.ts +22 -0
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +54 -3
- package/src/tools/browser/cdp-client/factory.ts +15 -4
- package/src/tools/credentials/tool-policy.ts +39 -5
- package/src/tools/credentials/vault.ts +9 -4
- package/src/tools/executor.ts +129 -73
- package/src/tools/filesystem/write.ts +52 -0
- package/src/tools/host-terminal/host-shell.ts +45 -5
- package/src/tools/memory/register.test.ts +185 -0
- package/src/tools/memory/register.ts +3 -1
- package/src/tools/network/script-proxy/session-manager.ts +37 -1
- package/src/tools/network/web-fetch.ts +20 -10
- package/src/tools/network/web-search.ts +19 -4
- package/src/tools/permission-checker.ts +116 -46
- package/src/tools/policy-context.ts +29 -8
- package/src/tools/registry.ts +195 -6
- package/src/tools/schedule/create.ts +23 -8
- package/src/tools/schedule/update.ts +3 -1
- package/src/tools/secret-detection-handler.ts +0 -51
- package/src/tools/side-effects.ts +0 -11
- package/src/tools/skills/execute.ts +2 -2
- package/src/tools/skills/sandbox-runner.ts +5 -2
- package/src/tools/system/avatar-generator.ts +6 -2
- package/src/tools/terminal/backends/native.ts +51 -2
- package/src/tools/terminal/safe-env.ts +3 -2
- package/src/tools/terminal/shell.ts +1 -0
- package/src/tools/tool-manifest.ts +6 -21
- package/src/tools/types.ts +40 -5
- package/src/tools/verification-control-plane-policy.ts +1 -1
- package/src/tts/__tests__/provider-adapters.test.ts +240 -13
- package/src/tts/provider-catalog.ts +18 -0
- package/src/tts/providers/index.ts +2 -0
- package/src/tts/providers/xai-provider.ts +224 -0
- package/src/tts/types.ts +46 -0
- package/src/types/tar-stream.d.ts +66 -0
- package/src/util/json.ts +17 -0
- package/src/util/platform.ts +9 -4
- package/src/util/pricing.ts +41 -8
- package/src/watcher/engine.ts +1 -1
- package/src/watcher/providers/google-calendar.ts +134 -8
- package/src/watcher/providers/outlook-calendar.ts +42 -2
- package/src/workspace/git-service.ts +23 -4
- package/src/workspace/migrations/006-services-config.ts +2 -4
- package/src/workspace/migrations/022-move-hooks-to-workspace.ts +2 -3
- package/src/workspace/migrations/038-unify-llm-callsite-configs.ts +516 -0
- package/src/workspace/migrations/039-drop-legacy-llm-keys.ts +171 -0
- package/src/workspace/migrations/040-seed-latency-callsite-defaults.ts +154 -0
- package/src/workspace/migrations/041-backfill-google-gmail-settings-scope.ts +56 -0
- package/src/workspace/migrations/042-fix-backfill-google-gmail-settings-scope.ts +70 -0
- package/src/workspace/migrations/043-release-notes-latex-rendering.ts +75 -0
- package/src/workspace/migrations/044-bump-stale-provider-stream-timeout.ts +51 -0
- package/src/workspace/migrations/045-release-notes-meet-avatar.ts +130 -0
- package/src/workspace/migrations/046-seed-conversation-starters-callsite.ts +108 -0
- package/src/workspace/migrations/047-remove-watch-callsites.ts +54 -0
- package/src/workspace/migrations/048-remove-workspace-hooks.ts +81 -0
- package/src/workspace/migrations/049-release-notes-default-sonnet.ts +80 -0
- package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +86 -0
- package/src/workspace/migrations/051-seed-conversation-summarization-callsite.ts +128 -0
- package/src/workspace/migrations/AGENTS.md +1 -1
- package/src/workspace/migrations/registry.ts +28 -0
- package/src/workspace/provider-commit-message-generator.ts +19 -38
- package/tsconfig.json +1 -1
- package/hook-templates/debug-prompt-logger/hook.json +0 -7
- package/hook-templates/debug-prompt-logger/run.sh +0 -66
- package/src/__tests__/context-overflow-approval.test.ts +0 -156
- package/src/__tests__/gmail-archive-fallback.test.ts +0 -193
- package/src/__tests__/gmail-archive-gate.test.ts +0 -246
- package/src/__tests__/gmail-preferences.test.ts +0 -117
- package/src/__tests__/hooks-blocking.test.ts +0 -178
- package/src/__tests__/hooks-cli.test.ts +0 -182
- package/src/__tests__/hooks-config.test.ts +0 -108
- package/src/__tests__/hooks-discovery.test.ts +0 -211
- package/src/__tests__/hooks-integration.test.ts +0 -196
- package/src/__tests__/hooks-manager.test.ts +0 -226
- package/src/__tests__/hooks-runner.test.ts +0 -175
- package/src/__tests__/hooks-settings.test.ts +0 -160
- package/src/__tests__/hooks-templates.test.ts +0 -169
- package/src/__tests__/hooks-ts-runner.test.ts +0 -170
- package/src/__tests__/hooks-watch.test.ts +0 -112
- package/src/__tests__/notification-schedule-dedup.test.ts +0 -213
- package/src/__tests__/oauth-scope-policy.test.ts +0 -180
- package/src/__tests__/outlook-attachments.test.ts +0 -301
- package/src/__tests__/outlook-automation-tools.test.ts +0 -425
- package/src/__tests__/outlook-categories.test.ts +0 -212
- package/src/__tests__/outlook-compose-tools.test.ts +0 -325
- package/src/__tests__/outlook-declutter-tools.test.ts +0 -585
- package/src/__tests__/outlook-follow-up.test.ts +0 -196
- package/src/__tests__/outlook-trash.test.ts +0 -77
- package/src/__tests__/outlook-unsubscribe.test.ts +0 -279
- package/src/__tests__/send-notification-tool.test.ts +0 -83
- package/src/__tests__/update-bulletin-format.test.ts +0 -181
- package/src/__tests__/update-bulletin-state.test.ts +0 -135
- package/src/__tests__/update-bulletin.test.ts +0 -478
- package/src/__tests__/update-template-contract.test.ts +0 -29
- package/src/cli/commands/doctor.ts +0 -341
- package/src/cli/commands/shotgun.ts +0 -266
- package/src/config/bundled-skills/browser/SKILL.md +0 -88
- package/src/config/bundled-skills/browser/TOOLS.json +0 -516
- package/src/config/bundled-skills/browser/tools/browser-attach.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-click.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-close.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-detach.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-extract.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-fill-credential.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-hover.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-navigate.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-press-key.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-screenshot.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-scroll.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-select-option.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-snapshot.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-status.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-type.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-wait-for-download.ts +0 -49
- package/src/config/bundled-skills/browser/tools/browser-wait-for.ts +0 -12
- package/src/config/bundled-skills/chatgpt-import/SKILL.md +0 -27
- package/src/config/bundled-skills/chatgpt-import/TOOLS.json +0 -27
- package/src/config/bundled-skills/chatgpt-import/tools/chatgpt-import.ts +0 -378
- package/src/config/bundled-skills/conversations/SKILL.md +0 -20
- package/src/config/bundled-skills/conversations/TOOLS.json +0 -23
- package/src/config/bundled-skills/conversations/tools/rename-conversation.ts +0 -66
- package/src/config/bundled-skills/gmail/SKILL.md +0 -221
- package/src/config/bundled-skills/gmail/TOOLS.json +0 -588
- package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +0 -256
- package/src/config/bundled-skills/gmail/tools/gmail-attachments.ts +0 -112
- package/src/config/bundled-skills/gmail/tools/gmail-draft.ts +0 -44
- package/src/config/bundled-skills/gmail/tools/gmail-filters.ts +0 -81
- package/src/config/bundled-skills/gmail/tools/gmail-follow-up.ts +0 -108
- package/src/config/bundled-skills/gmail/tools/gmail-forward.ts +0 -146
- package/src/config/bundled-skills/gmail/tools/gmail-label.ts +0 -53
- package/src/config/bundled-skills/gmail/tools/gmail-outreach-scan.ts +0 -347
- package/src/config/bundled-skills/gmail/tools/gmail-preferences-tool.ts +0 -59
- package/src/config/bundled-skills/gmail/tools/gmail-preferences.ts +0 -82
- package/src/config/bundled-skills/gmail/tools/gmail-send-draft.ts +0 -26
- package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +0 -347
- package/src/config/bundled-skills/gmail/tools/gmail-trash.ts +0 -29
- package/src/config/bundled-skills/gmail/tools/gmail-unsubscribe.ts +0 -122
- package/src/config/bundled-skills/gmail/tools/gmail-vacation.ts +0 -67
- package/src/config/bundled-skills/gmail/tools/scan-result-store.ts +0 -100
- package/src/config/bundled-skills/gmail/tools/shared.ts +0 -47
- package/src/config/bundled-skills/google-calendar/SKILL.md +0 -51
- package/src/config/bundled-skills/google-calendar/TOOLS.json +0 -226
- package/src/config/bundled-skills/google-calendar/calendar-client.ts +0 -223
- package/src/config/bundled-skills/google-calendar/tools/calendar-check-availability.ts +0 -27
- package/src/config/bundled-skills/google-calendar/tools/calendar-create-event.ts +0 -48
- package/src/config/bundled-skills/google-calendar/tools/calendar-get-event.ts +0 -19
- package/src/config/bundled-skills/google-calendar/tools/calendar-list-events.ts +0 -36
- package/src/config/bundled-skills/google-calendar/tools/calendar-rsvp.ts +0 -58
- package/src/config/bundled-skills/google-calendar/tools/shared.ts +0 -17
- package/src/config/bundled-skills/google-calendar/types.ts +0 -97
- package/src/config/bundled-skills/heartbeat/SKILL.md +0 -43
- package/src/config/bundled-skills/notifications/SKILL.md +0 -40
- package/src/config/bundled-skills/notifications/TOOLS.json +0 -80
- package/src/config/bundled-skills/notifications/tools/send-notification.ts +0 -152
- package/src/config/bundled-skills/notifications/tools/shared.ts +0 -13
- package/src/config/bundled-skills/outlook/SKILL.md +0 -196
- package/src/config/bundled-skills/outlook/TOOLS.json +0 -530
- package/src/config/bundled-skills/outlook/tools/outlook-attachments.ts +0 -85
- package/src/config/bundled-skills/outlook/tools/outlook-categories.ts +0 -77
- package/src/config/bundled-skills/outlook/tools/outlook-draft.ts +0 -84
- package/src/config/bundled-skills/outlook/tools/outlook-follow-up.ts +0 -94
- package/src/config/bundled-skills/outlook/tools/outlook-forward.ts +0 -49
- package/src/config/bundled-skills/outlook/tools/outlook-outreach-scan.ts +0 -237
- package/src/config/bundled-skills/outlook/tools/outlook-rules.ts +0 -161
- package/src/config/bundled-skills/outlook/tools/outlook-send-draft.ts +0 -32
- package/src/config/bundled-skills/outlook/tools/outlook-sender-digest.ts +0 -272
- package/src/config/bundled-skills/outlook/tools/outlook-trash.ts +0 -29
- package/src/config/bundled-skills/outlook/tools/outlook-unsubscribe.ts +0 -129
- package/src/config/bundled-skills/outlook/tools/outlook-vacation.ts +0 -87
- package/src/config/bundled-skills/outlook/tools/shared.ts +0 -20
- package/src/config/bundled-skills/outlook-calendar/SKILL.md +0 -51
- package/src/config/bundled-skills/outlook-calendar/TOOLS.json +0 -221
- package/src/config/bundled-skills/outlook-calendar/calendar-client.ts +0 -252
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-check-availability.ts +0 -53
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-create-event.ts +0 -74
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-get-event.ts +0 -18
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-list-events.ts +0 -46
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-rsvp.ts +0 -36
- package/src/config/bundled-skills/outlook-calendar/tools/shared.ts +0 -17
- package/src/config/bundled-skills/outlook-calendar/types.ts +0 -120
- package/src/config/bundled-skills/screen-watch/SKILL.md +0 -27
- package/src/config/bundled-skills/screen-watch/TOOLS.json +0 -35
- package/src/config/bundled-skills/screen-watch/tools/start-screen-watch.ts +0 -12
- package/src/config/bundled-skills/skills-catalog/SKILL.md +0 -84
- package/src/config/bundled-skills/slack/SKILL.md +0 -108
- package/src/config/bundled-skills/tasks/SKILL.md +0 -37
- package/src/config/bundled-skills/tasks/TOOLS.json +0 -353
- package/src/config/bundled-skills/tasks/icon.svg +0 -34
- package/src/config/bundled-skills/tasks/tools/task-delete.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-list-add.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-list-remove.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-list-show.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-list-update.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-list.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-queue-run.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-run.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-save.ts +0 -12
- package/src/config/bundled-skills/watcher/SKILL.md +0 -31
- package/src/config/bundled-skills/watcher/TOOLS.json +0 -167
- package/src/config/bundled-skills/watcher/tools/watcher-create.ts +0 -12
- package/src/config/bundled-skills/watcher/tools/watcher-delete.ts +0 -12
- package/src/config/bundled-skills/watcher/tools/watcher-digest.ts +0 -12
- package/src/config/bundled-skills/watcher/tools/watcher-list.ts +0 -12
- package/src/config/bundled-skills/watcher/tools/watcher-update.ts +0 -12
- package/src/daemon/context-overflow-approval.ts +0 -52
- package/src/daemon/watch-handler.ts +0 -399
- package/src/hooks/cli.ts +0 -253
- package/src/hooks/config.ts +0 -100
- package/src/hooks/discovery.ts +0 -135
- package/src/hooks/manager.ts +0 -179
- package/src/hooks/runner.ts +0 -117
- package/src/hooks/templates.ts +0 -77
- package/src/hooks/types.ts +0 -75
- package/src/oauth/scope-policy.ts +0 -89
- package/src/prompts/templates/UPDATES.md +0 -50
- package/src/prompts/update-bulletin-format.ts +0 -85
- package/src/prompts/update-bulletin-state.ts +0 -58
- package/src/prompts/update-bulletin-template-path.ts +0 -13
- package/src/prompts/update-bulletin.ts +0 -139
- package/src/runtime/gateway-internal-client.ts +0 -94
- package/src/runtime/routes/watch-routes.ts +0 -156
- package/src/shared/provider-env-vars.ts +0 -19
- package/src/signals/shotgun.ts +0 -203
- package/src/tools/watch/screen-watch.ts +0 -144
- package/src/tools/watch/watch-state.ts +0 -142
- package/src/tools/watcher/create.ts +0 -86
- package/src/tools/watcher/delete.ts +0 -36
- package/src/tools/watcher/digest.ts +0 -54
- package/src/tools/watcher/list.ts +0 -83
- package/src/tools/watcher/update.ts +0 -71
package/src/tools/registry.ts
CHANGED
|
@@ -16,6 +16,48 @@ const log = getLogger("tool-registry");
|
|
|
16
16
|
|
|
17
17
|
const tools = new Map<string, Tool>();
|
|
18
18
|
|
|
19
|
+
// ── External tool registry ───────────────────────────────────────────
|
|
20
|
+
// Skills register their tools here at initialization time so the tool
|
|
21
|
+
// manifest can include them without importing from `../skills/`.
|
|
22
|
+
//
|
|
23
|
+
// Each registration is stored as a provider closure. Closures are
|
|
24
|
+
// resolved at `getExternalTools()` time (which `initializeTools()`
|
|
25
|
+
// calls), not at registration time — this lets a skill defer its
|
|
26
|
+
// feature-flag check until after the daemon has run
|
|
27
|
+
// `mergeDefaultWorkspaceConfig()`, so skills see the merged config
|
|
28
|
+
// instead of forcing an early `loadConfig()` against unmerged defaults.
|
|
29
|
+
const externalToolProviders: Array<() => Tool[]> = [];
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Register tools provided by an external skill. Called during skill
|
|
33
|
+
* initialization (e.g. meet-join bootstrap).
|
|
34
|
+
*
|
|
35
|
+
* Accepts either a concrete `Tool[]` (resolved eagerly at the caller)
|
|
36
|
+
* or a `() => Tool[]` closure (resolved lazily inside
|
|
37
|
+
* `getExternalTools()`). Skills that perform feature-flag or config
|
|
38
|
+
* reads to decide which tools to surface must pass a closure so the
|
|
39
|
+
* read happens after daemon-startup config merging.
|
|
40
|
+
*
|
|
41
|
+
* Lives in registry.ts (not tool-manifest.ts) to avoid a circular
|
|
42
|
+
* dependency: skills/load.ts → … → meet-join/register.ts → tool-manifest.ts
|
|
43
|
+
* → skills/load.ts. Keeping it here lets external skill bootstraps import
|
|
44
|
+
* from registry.ts, which is already a leaf in the dependency graph.
|
|
45
|
+
*/
|
|
46
|
+
export function registerExternalTools(
|
|
47
|
+
toolsOrProvider: Tool[] | (() => Tool[]),
|
|
48
|
+
): void {
|
|
49
|
+
const provider =
|
|
50
|
+
typeof toolsOrProvider === "function"
|
|
51
|
+
? toolsOrProvider
|
|
52
|
+
: () => toolsOrProvider;
|
|
53
|
+
externalToolProviders.push(provider);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Return all externally registered tools. */
|
|
57
|
+
export function getExternalTools(): Tool[] {
|
|
58
|
+
return externalToolProviders.flatMap((provider) => provider());
|
|
59
|
+
}
|
|
60
|
+
|
|
19
61
|
// Snapshot of core tools captured after initializeTools() completes.
|
|
20
62
|
// Used by __resetRegistryForTesting() to restore eager tools that cannot
|
|
21
63
|
// be re-registered because ESM import caching prevents side effects
|
|
@@ -26,6 +68,12 @@ let coreToolsSnapshot: Map<string, Tool> | null = null;
|
|
|
26
68
|
// Tools are only removed from the global registry when this drops to 0.
|
|
27
69
|
const skillRefCount = new Map<string, number>();
|
|
28
70
|
|
|
71
|
+
// Plugin-tool refcount lives in its own namespace so plugin and skill IDs
|
|
72
|
+
// cannot collide in the ref map even if a plugin's `manifest.name` happens to
|
|
73
|
+
// match a skill id. Conflict detection on `tools` (keyed by tool name) is
|
|
74
|
+
// separate and covers the case of two extensions choosing the same tool name.
|
|
75
|
+
const pluginRefCount = new Map<string, number>();
|
|
76
|
+
|
|
29
77
|
export function registerTool(tool: Tool): void {
|
|
30
78
|
const existing = tools.get(tool.name);
|
|
31
79
|
if (existing) {
|
|
@@ -66,10 +114,22 @@ export function registerSkillTools(newTools: Tool[]): Tool[] {
|
|
|
66
114
|
);
|
|
67
115
|
continue;
|
|
68
116
|
}
|
|
69
|
-
// Existing is
|
|
70
|
-
|
|
117
|
+
// Existing is from a different origin (plugin/mcp) or a different
|
|
118
|
+
// skill — skill tools can only replace themselves (hot-reload).
|
|
119
|
+
if (
|
|
120
|
+
existing.origin !== "skill" ||
|
|
121
|
+
existing.ownerSkillId !== tool.ownerSkillId
|
|
122
|
+
) {
|
|
123
|
+
const owner =
|
|
124
|
+
existing.origin === "skill"
|
|
125
|
+
? `skill "${existing.ownerSkillId}"`
|
|
126
|
+
: existing.origin === "plugin"
|
|
127
|
+
? `plugin "${existing.ownerPluginId}"`
|
|
128
|
+
: existing.origin === "mcp"
|
|
129
|
+
? `MCP server "${existing.ownerMcpServerId}"`
|
|
130
|
+
: `${existing.origin ?? "unknown"}-origin tool`;
|
|
71
131
|
throw new Error(
|
|
72
|
-
`Skill tool "${tool.name}" is already registered by
|
|
132
|
+
`Skill tool "${tool.name}" is already registered by ${owner}`,
|
|
73
133
|
);
|
|
74
134
|
}
|
|
75
135
|
}
|
|
@@ -94,6 +154,111 @@ export function registerSkillTools(newTools: Tool[]): Tool[] {
|
|
|
94
154
|
return accepted;
|
|
95
155
|
}
|
|
96
156
|
|
|
157
|
+
/**
|
|
158
|
+
* Register tools contributed by a plugin. Stamps `origin: "plugin"` and
|
|
159
|
+
* `ownerPluginId: pluginName` on every incoming tool so plugin ownership is
|
|
160
|
+
* tracked in a namespace disjoint from skill tools — if a plugin's
|
|
161
|
+
* `manifest.name` happens to match a skill id, the two do not share refcount
|
|
162
|
+
* state or conflict-detection paths.
|
|
163
|
+
*
|
|
164
|
+
* Conflict handling mirrors {@link registerSkillTools}: collisions with core
|
|
165
|
+
* tools log a warning and skip; collisions with tools owned by a different
|
|
166
|
+
* plugin, skill, or MCP server throw; re-registering the same plugin's own
|
|
167
|
+
* tool (hot reload) is allowed.
|
|
168
|
+
*
|
|
169
|
+
* The stamp is authoritative: any pre-existing `origin` / `ownerPluginId` /
|
|
170
|
+
* `ownerSkillId` / `ownerMcpServerId` fields on the incoming tools are
|
|
171
|
+
* overwritten so the bootstrap cannot be spoofed into claiming tools on
|
|
172
|
+
* behalf of an unrelated extension.
|
|
173
|
+
*/
|
|
174
|
+
export function registerPluginTools(
|
|
175
|
+
pluginName: string,
|
|
176
|
+
newTools: Tool[],
|
|
177
|
+
): Tool[] {
|
|
178
|
+
const stamped: Tool[] = newTools.map((tool) => ({
|
|
179
|
+
...tool,
|
|
180
|
+
origin: "plugin" as const,
|
|
181
|
+
ownerPluginId: pluginName,
|
|
182
|
+
ownerSkillId: undefined,
|
|
183
|
+
ownerMcpServerId: undefined,
|
|
184
|
+
}));
|
|
185
|
+
|
|
186
|
+
const accepted: Tool[] = [];
|
|
187
|
+
for (const tool of stamped) {
|
|
188
|
+
const existing = tools.get(tool.name);
|
|
189
|
+
if (existing) {
|
|
190
|
+
const existingIsCore = existing.origin === "core" || !existing.origin;
|
|
191
|
+
if (existingIsCore) {
|
|
192
|
+
log.warn(
|
|
193
|
+
{ toolName: tool.name, pluginName },
|
|
194
|
+
`Plugin "${pluginName}" tried to register tool "${tool.name}" which conflicts with a core tool. Skipping.`,
|
|
195
|
+
);
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
if (existing.origin === "plugin") {
|
|
199
|
+
if (existing.ownerPluginId !== pluginName) {
|
|
200
|
+
throw new Error(
|
|
201
|
+
`Plugin tool "${tool.name}" is already registered by plugin "${existing.ownerPluginId}"`,
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
// Same plugin re-registering its own tool (hot reload) — allow.
|
|
205
|
+
} else {
|
|
206
|
+
// Conflict with a skill or MCP-owned tool.
|
|
207
|
+
throw new Error(
|
|
208
|
+
`Plugin "${pluginName}" tried to register tool "${tool.name}" which conflicts with a ${existing.origin}-origin tool`,
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
accepted.push(tool);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
for (const tool of accepted) {
|
|
216
|
+
tools.set(tool.name, tool);
|
|
217
|
+
log.info(
|
|
218
|
+
{ name: tool.name, ownerPluginId: tool.ownerPluginId },
|
|
219
|
+
"Plugin tool registered",
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
if (accepted.length > 0) {
|
|
224
|
+
pluginRefCount.set(pluginName, (pluginRefCount.get(pluginName) ?? 0) + 1);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
return accepted;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Decrement the reference count for a plugin and remove its tools only when
|
|
232
|
+
* no more references remain. Safe to call when the plugin never contributed
|
|
233
|
+
* tools (no-op).
|
|
234
|
+
*/
|
|
235
|
+
export function unregisterPluginTools(pluginName: string): void {
|
|
236
|
+
const current = pluginRefCount.get(pluginName) ?? 0;
|
|
237
|
+
if (current > 1) {
|
|
238
|
+
pluginRefCount.set(pluginName, current - 1);
|
|
239
|
+
log.info(
|
|
240
|
+
{ pluginName, remaining: current - 1 },
|
|
241
|
+
"Decremented plugin ref count, tools kept",
|
|
242
|
+
);
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
pluginRefCount.delete(pluginName);
|
|
247
|
+
for (const [name, tool] of tools) {
|
|
248
|
+
if (tool.origin === "plugin" && tool.ownerPluginId === pluginName) {
|
|
249
|
+
tools.delete(name);
|
|
250
|
+
log.info({ name, pluginName }, "Plugin tool unregistered");
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Return the current reference count for a plugin's tools. Exposed for testing.
|
|
257
|
+
*/
|
|
258
|
+
export function getPluginRefCount(pluginName: string): number {
|
|
259
|
+
return pluginRefCount.get(pluginName) ?? 0;
|
|
260
|
+
}
|
|
261
|
+
|
|
97
262
|
/**
|
|
98
263
|
* Decrement the reference count for a skill and remove its tools only when
|
|
99
264
|
* no more sessions reference them.
|
|
@@ -148,6 +313,17 @@ export function registerMcpTools(newTools: Tool[]): Tool[] {
|
|
|
148
313
|
);
|
|
149
314
|
continue;
|
|
150
315
|
}
|
|
316
|
+
if (existing.origin === "plugin") {
|
|
317
|
+
log.warn(
|
|
318
|
+
{
|
|
319
|
+
toolName: tool.name,
|
|
320
|
+
serverId: tool.ownerMcpServerId,
|
|
321
|
+
pluginName: existing.ownerPluginId,
|
|
322
|
+
},
|
|
323
|
+
`MCP server "${tool.ownerMcpServerId}" tried to register tool "${tool.name}" which conflicts with plugin tool from "${existing.ownerPluginId}". Skipping.`,
|
|
324
|
+
);
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
151
327
|
if (
|
|
152
328
|
existing.origin === "mcp" &&
|
|
153
329
|
existing.ownerMcpServerId !== tool.ownerMcpServerId
|
|
@@ -245,6 +421,15 @@ export async function initializeTools(): Promise<void> {
|
|
|
245
421
|
registerTool(tool);
|
|
246
422
|
}
|
|
247
423
|
|
|
424
|
+
// External skill tools — registered by skill bootstrap modules via
|
|
425
|
+
// `registerExternalTools()`. Called at init time (not spread into
|
|
426
|
+
// `explicitTools`) so registrations that happen between module-load
|
|
427
|
+
// and `initializeTools()` are picked up.
|
|
428
|
+
const extTools = getExternalTools();
|
|
429
|
+
for (const tool of extTools) {
|
|
430
|
+
registerTool(tool);
|
|
431
|
+
}
|
|
432
|
+
|
|
248
433
|
// Host tools are registered explicitly so host access stays opt-in until
|
|
249
434
|
// this point in startup, rather than as module side effects.
|
|
250
435
|
const hostTools = [
|
|
@@ -272,13 +457,14 @@ export async function initializeTools(): Promise<void> {
|
|
|
272
457
|
// arbitrary test tools that were registered before init.
|
|
273
458
|
//
|
|
274
459
|
// A pre-existing tool is included only if it is a known manifest tool
|
|
275
|
-
// (declared in eagerModuleToolNames, explicitTools, or
|
|
276
|
-
// This handles ESM cache hits where
|
|
277
|
-
// the registry before init ran.
|
|
460
|
+
// (declared in eagerModuleToolNames, explicitTools, hostTools, or any
|
|
461
|
+
// registered external skill tool). This handles ESM cache hits where
|
|
462
|
+
// eager-module tools are already in the registry before init ran.
|
|
278
463
|
if (!coreToolsSnapshot) {
|
|
279
464
|
const manifestToolNames = new Set<string>([
|
|
280
465
|
...eagerModuleToolNames,
|
|
281
466
|
...explicitTools.map((t: Tool) => t.name),
|
|
467
|
+
...extTools.map((t: Tool) => t.name),
|
|
282
468
|
...hostTools.map((t: Tool) => t.name),
|
|
283
469
|
...cesTools.map((t: Tool) => t.name),
|
|
284
470
|
...allComputerUseTools.map((t: Tool) => t.name),
|
|
@@ -289,6 +475,7 @@ export async function initializeTools(): Promise<void> {
|
|
|
289
475
|
coreToolsSnapshot = new Map<string, Tool>();
|
|
290
476
|
for (const [name, tool] of tools) {
|
|
291
477
|
if (tool.origin === "skill") continue;
|
|
478
|
+
if (tool.origin === "plugin") continue;
|
|
292
479
|
// Exclude pre-existing tools not declared in the manifest
|
|
293
480
|
if (preExisting.has(name) && !manifestToolNames.has(name)) continue;
|
|
294
481
|
coreToolsSnapshot.set(name, tool);
|
|
@@ -311,6 +498,7 @@ export async function initializeTools(): Promise<void> {
|
|
|
311
498
|
export function __resetRegistryForTesting(): void {
|
|
312
499
|
tools.clear();
|
|
313
500
|
skillRefCount.clear();
|
|
501
|
+
pluginRefCount.clear();
|
|
314
502
|
|
|
315
503
|
if (coreToolsSnapshot) {
|
|
316
504
|
for (const [name, tool] of coreToolsSnapshot) {
|
|
@@ -327,4 +515,5 @@ export function __resetRegistryForTesting(): void {
|
|
|
327
515
|
export function __clearRegistryForTesting(): void {
|
|
328
516
|
tools.clear();
|
|
329
517
|
skillRefCount.clear();
|
|
518
|
+
pluginRefCount.clear();
|
|
330
519
|
}
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
} from "../../schedule/schedule-store.js";
|
|
14
14
|
import type { ToolContext, ToolExecutionResult } from "../types.js";
|
|
15
15
|
|
|
16
|
-
const VALID_MODES: ScheduleMode[] = ["notify", "execute"];
|
|
16
|
+
const VALID_MODES: ScheduleMode[] = ["notify", "execute", "script"];
|
|
17
17
|
const VALID_ROUTING_INTENTS: RoutingIntent[] = [
|
|
18
18
|
"single_channel",
|
|
19
19
|
"multi_channel",
|
|
@@ -33,7 +33,8 @@ export async function executeScheduleCreate(
|
|
|
33
33
|
}
|
|
34
34
|
const name = input.name as string;
|
|
35
35
|
const timezone = (input.timezone as string) ?? null;
|
|
36
|
-
const message = input.message as string;
|
|
36
|
+
const message = (input.message as string) ?? "";
|
|
37
|
+
const script = (input.script as string) ?? null;
|
|
37
38
|
const enabled = (input.enabled as boolean) ?? true;
|
|
38
39
|
const fireAt = input.fire_at as string | undefined;
|
|
39
40
|
const mode = (input.mode as ScheduleMode | undefined) ?? "execute";
|
|
@@ -50,12 +51,6 @@ export async function executeScheduleCreate(
|
|
|
50
51
|
isError: true,
|
|
51
52
|
};
|
|
52
53
|
}
|
|
53
|
-
if (!message || typeof message !== "string") {
|
|
54
|
-
return {
|
|
55
|
-
content: "Error: message is required and must be a string",
|
|
56
|
-
isError: true,
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
54
|
|
|
60
55
|
// Validate mode
|
|
61
56
|
if (!VALID_MODES.includes(mode)) {
|
|
@@ -65,6 +60,24 @@ export async function executeScheduleCreate(
|
|
|
65
60
|
};
|
|
66
61
|
}
|
|
67
62
|
|
|
63
|
+
// Mode-specific field validation
|
|
64
|
+
if (mode === "script") {
|
|
65
|
+
if (!script || typeof script !== "string") {
|
|
66
|
+
return {
|
|
67
|
+
content:
|
|
68
|
+
"Error: script is required for script mode and must be a non-empty string",
|
|
69
|
+
isError: true,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
} else {
|
|
73
|
+
if (!message || typeof message !== "string") {
|
|
74
|
+
return {
|
|
75
|
+
content: "Error: message is required and must be a string",
|
|
76
|
+
isError: true,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
68
81
|
// Validate routing_intent
|
|
69
82
|
if (
|
|
70
83
|
routingIntent !== undefined &&
|
|
@@ -107,6 +120,7 @@ export async function executeScheduleCreate(
|
|
|
107
120
|
cronExpression: null,
|
|
108
121
|
timezone,
|
|
109
122
|
message,
|
|
123
|
+
script,
|
|
110
124
|
enabled,
|
|
111
125
|
syntax: "cron",
|
|
112
126
|
expression: null,
|
|
@@ -185,6 +199,7 @@ export async function executeScheduleCreate(
|
|
|
185
199
|
cronExpression: resolved.expression,
|
|
186
200
|
timezone,
|
|
187
201
|
message,
|
|
202
|
+
script,
|
|
188
203
|
enabled,
|
|
189
204
|
syntax: resolved.syntax,
|
|
190
205
|
expression: resolved.expression,
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
} from "../../schedule/schedule-store.js";
|
|
17
17
|
import type { ToolContext, ToolExecutionResult } from "../types.js";
|
|
18
18
|
|
|
19
|
-
const VALID_MODES: ScheduleMode[] = ["notify", "execute"];
|
|
19
|
+
const VALID_MODES: ScheduleMode[] = ["notify", "execute", "script"];
|
|
20
20
|
const VALID_ROUTING_INTENTS: RoutingIntent[] = [
|
|
21
21
|
"single_channel",
|
|
22
22
|
"multi_channel",
|
|
@@ -66,6 +66,7 @@ export async function executeScheduleUpdate(
|
|
|
66
66
|
if (input.name !== undefined) updates.name = input.name;
|
|
67
67
|
if (input.timezone !== undefined) updates.timezone = input.timezone;
|
|
68
68
|
if (input.message !== undefined) updates.message = input.message;
|
|
69
|
+
if (input.script !== undefined) updates.script = input.script;
|
|
69
70
|
if (input.enabled !== undefined) updates.enabled = input.enabled;
|
|
70
71
|
|
|
71
72
|
// Mode validation and pass-through
|
|
@@ -163,6 +164,7 @@ export async function executeScheduleUpdate(
|
|
|
163
164
|
cronExpression?: string;
|
|
164
165
|
timezone?: string | null;
|
|
165
166
|
message?: string;
|
|
167
|
+
script?: string | null;
|
|
166
168
|
enabled?: boolean;
|
|
167
169
|
syntax?: ScheduleSyntax;
|
|
168
170
|
expression?: string;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { getConfig } from "../config/loader.js";
|
|
2
|
-
import { getHookManager } from "../hooks/manager.js";
|
|
3
2
|
import { PermissionPrompter } from "../permissions/prompter.js";
|
|
4
3
|
import { RiskLevel } from "../permissions/types.js";
|
|
5
4
|
import { isPermissionControlsV2Enabled } from "../permissions/v2-consent-policy.js";
|
|
@@ -46,10 +45,6 @@ export class SecretDetectionHandler {
|
|
|
46
45
|
context: ToolContext,
|
|
47
46
|
event: ToolLifecycleEvent,
|
|
48
47
|
) => void,
|
|
49
|
-
sanitizeToolInput: (
|
|
50
|
-
toolName: string,
|
|
51
|
-
input: Record<string, unknown>,
|
|
52
|
-
) => Record<string, unknown>,
|
|
53
48
|
): Promise<{ result: ToolExecutionResult; earlyReturn: boolean }> {
|
|
54
49
|
const sdConfig = getConfig().secretDetection;
|
|
55
50
|
if (!sdConfig.enabled || execResult.isError) {
|
|
@@ -108,7 +103,6 @@ export class SecretDetectionHandler {
|
|
|
108
103
|
decision,
|
|
109
104
|
startTime,
|
|
110
105
|
emitLifecycleEvent,
|
|
111
|
-
sanitizeToolInput,
|
|
112
106
|
);
|
|
113
107
|
}
|
|
114
108
|
|
|
@@ -124,7 +118,6 @@ export class SecretDetectionHandler {
|
|
|
124
118
|
decision,
|
|
125
119
|
startTime,
|
|
126
120
|
emitLifecycleEvent,
|
|
127
|
-
sanitizeToolInput,
|
|
128
121
|
);
|
|
129
122
|
}
|
|
130
123
|
|
|
@@ -210,10 +203,6 @@ export class SecretDetectionHandler {
|
|
|
210
203
|
context: ToolContext,
|
|
211
204
|
event: ToolLifecycleEvent,
|
|
212
205
|
) => void,
|
|
213
|
-
sanitizeToolInput: (
|
|
214
|
-
toolName: string,
|
|
215
|
-
input: Record<string, unknown>,
|
|
216
|
-
) => Record<string, unknown>,
|
|
217
206
|
): { result: ToolExecutionResult; earlyReturn: boolean } {
|
|
218
207
|
const types = [...new Set(allMatches.map((m) => m.type))].join(", ");
|
|
219
208
|
const blockedContent = `Tool output blocked: detected ${allMatches.length} potential secret(s) (${types}). Configure secretDetection.action to "redact" or "prompt" to allow output.`;
|
|
@@ -237,15 +226,6 @@ export class SecretDetectionHandler {
|
|
|
237
226
|
result: blockedResult,
|
|
238
227
|
});
|
|
239
228
|
|
|
240
|
-
void getHookManager().trigger("post-tool-execute", {
|
|
241
|
-
toolName: name,
|
|
242
|
-
input: sanitizeToolInput(name, input),
|
|
243
|
-
riskLevel,
|
|
244
|
-
isError: true,
|
|
245
|
-
durationMs,
|
|
246
|
-
conversationId: context.conversationId,
|
|
247
|
-
});
|
|
248
|
-
|
|
249
229
|
return { result: blockedResult, earlyReturn: true };
|
|
250
230
|
}
|
|
251
231
|
|
|
@@ -263,10 +243,6 @@ export class SecretDetectionHandler {
|
|
|
263
243
|
context: ToolContext,
|
|
264
244
|
event: ToolLifecycleEvent,
|
|
265
245
|
) => void,
|
|
266
|
-
sanitizeToolInput: (
|
|
267
|
-
toolName: string,
|
|
268
|
-
input: Record<string, unknown>,
|
|
269
|
-
) => Record<string, unknown>,
|
|
270
246
|
): Promise<{ result: ToolExecutionResult; earlyReturn: boolean }> {
|
|
271
247
|
const types = [...new Set(allMatches.map((m) => m.type))].join(", ");
|
|
272
248
|
|
|
@@ -288,15 +264,6 @@ export class SecretDetectionHandler {
|
|
|
288
264
|
durationMs,
|
|
289
265
|
});
|
|
290
266
|
|
|
291
|
-
void getHookManager().trigger("post-tool-execute", {
|
|
292
|
-
toolName: name,
|
|
293
|
-
input: sanitizeToolInput(name, input),
|
|
294
|
-
riskLevel,
|
|
295
|
-
isError: true,
|
|
296
|
-
durationMs,
|
|
297
|
-
conversationId: context.conversationId,
|
|
298
|
-
});
|
|
299
|
-
|
|
300
267
|
return {
|
|
301
268
|
result: { content: blockedContent, isError: true },
|
|
302
269
|
earlyReturn: true,
|
|
@@ -322,15 +289,6 @@ export class SecretDetectionHandler {
|
|
|
322
289
|
durationMs,
|
|
323
290
|
});
|
|
324
291
|
|
|
325
|
-
void getHookManager().trigger("post-tool-execute", {
|
|
326
|
-
toolName: name,
|
|
327
|
-
input: sanitizeToolInput(name, input),
|
|
328
|
-
riskLevel,
|
|
329
|
-
isError: true,
|
|
330
|
-
durationMs,
|
|
331
|
-
conversationId: context.conversationId,
|
|
332
|
-
});
|
|
333
|
-
|
|
334
292
|
return {
|
|
335
293
|
result: { content: blockedContent, isError: true },
|
|
336
294
|
earlyReturn: true,
|
|
@@ -389,15 +347,6 @@ export class SecretDetectionHandler {
|
|
|
389
347
|
durationMs,
|
|
390
348
|
});
|
|
391
349
|
|
|
392
|
-
void getHookManager().trigger("post-tool-execute", {
|
|
393
|
-
toolName: name,
|
|
394
|
-
input: sanitizeToolInput(name, input),
|
|
395
|
-
riskLevel,
|
|
396
|
-
isError: true,
|
|
397
|
-
durationMs,
|
|
398
|
-
conversationId: context.conversationId,
|
|
399
|
-
});
|
|
400
|
-
|
|
401
350
|
return {
|
|
402
351
|
result: { content: blockedContent, isError: true },
|
|
403
352
|
earlyReturn: true,
|
|
@@ -12,17 +12,6 @@ const SIDE_EFFECT_TOOLS: ReadonlySet<string> = new Set([
|
|
|
12
12
|
"bash",
|
|
13
13
|
"host_bash",
|
|
14
14
|
"web_fetch",
|
|
15
|
-
"browser_navigate",
|
|
16
|
-
"browser_click",
|
|
17
|
-
"browser_type",
|
|
18
|
-
"browser_press_key",
|
|
19
|
-
"browser_scroll",
|
|
20
|
-
"browser_select_option",
|
|
21
|
-
"browser_hover",
|
|
22
|
-
"browser_close",
|
|
23
|
-
"browser_attach",
|
|
24
|
-
"browser_detach",
|
|
25
|
-
"browser_fill_credential",
|
|
26
15
|
"document_create",
|
|
27
16
|
"document_update",
|
|
28
17
|
"schedule_create",
|
|
@@ -6,7 +6,7 @@ import type { Tool, ToolContext, ToolExecutionResult } from "../types.js";
|
|
|
6
6
|
export class SkillExecuteTool implements Tool {
|
|
7
7
|
name = "skill_execute";
|
|
8
8
|
description =
|
|
9
|
-
"Execute a tool provided by a loaded skill. Use this instead of calling skill tools directly. The skill's instructions (from skill_load) describe available tools and their parameters.";
|
|
9
|
+
"Execute a tool provided by a loaded skill. Use this instead of calling skill tools directly. The skill's instructions (from skill_load) describe available tools and their parameters. For browser automation, use the `assistant browser` CLI commands instead.";
|
|
10
10
|
category = "skills";
|
|
11
11
|
defaultRiskLevel = RiskLevel.Low;
|
|
12
12
|
|
|
@@ -20,7 +20,7 @@ export class SkillExecuteTool implements Tool {
|
|
|
20
20
|
tool: {
|
|
21
21
|
type: "string",
|
|
22
22
|
description:
|
|
23
|
-
"The skill tool name to execute (e.g. '
|
|
23
|
+
"The skill tool name to execute (e.g. 'task_create', 'deploy_run')",
|
|
24
24
|
},
|
|
25
25
|
input: {
|
|
26
26
|
type: "object",
|
|
@@ -152,6 +152,7 @@ function spawnRunner(
|
|
|
152
152
|
workingDir: context.workingDir,
|
|
153
153
|
conversationId: context.conversationId,
|
|
154
154
|
});
|
|
155
|
+
env.__CONVERSATION_ID = context.conversationId;
|
|
155
156
|
|
|
156
157
|
const child = spawn(wrapped.command, wrapped.args, {
|
|
157
158
|
cwd: runDir,
|
|
@@ -219,7 +220,8 @@ function spawnRunner(
|
|
|
219
220
|
if (code !== 0) {
|
|
220
221
|
const truncatedStderr =
|
|
221
222
|
stderr.length > MAX_OUTPUT_CHARS
|
|
222
|
-
? safeStringSlice(stderr, 0, MAX_OUTPUT_CHARS) +
|
|
223
|
+
? safeStringSlice(stderr, 0, MAX_OUTPUT_CHARS) +
|
|
224
|
+
"\n[stderr truncated]"
|
|
223
225
|
: stderr;
|
|
224
226
|
resolve({
|
|
225
227
|
content: `Skill tool script "${executorPath}" exited with code ${code}:\n${truncatedStderr}`,
|
|
@@ -230,7 +232,8 @@ function spawnRunner(
|
|
|
230
232
|
|
|
231
233
|
const truncatedStdout =
|
|
232
234
|
stdout.length > MAX_OUTPUT_CHARS
|
|
233
|
-
? safeStringSlice(stdout, 0, MAX_OUTPUT_CHARS) +
|
|
235
|
+
? safeStringSlice(stdout, 0, MAX_OUTPUT_CHARS) +
|
|
236
|
+
"\n[stdout truncated]"
|
|
234
237
|
: stdout;
|
|
235
238
|
resolve({ content: truncatedStdout, isError: false });
|
|
236
239
|
});
|
|
@@ -3,7 +3,6 @@ import { mkdirSync, renameSync, writeFileSync } from "node:fs";
|
|
|
3
3
|
import { dirname } from "node:path";
|
|
4
4
|
|
|
5
5
|
import { generateAvatar } from "../../media/avatar-router.js";
|
|
6
|
-
import { mapGeminiError } from "../../media/gemini-image-service.js";
|
|
7
6
|
import { getLogger } from "../../util/logger.js";
|
|
8
7
|
import { getAvatarImagePath } from "../../util/platform.js";
|
|
9
8
|
|
|
@@ -69,7 +68,12 @@ export async function generateAndSaveAvatar(
|
|
|
69
68
|
isError: false,
|
|
70
69
|
};
|
|
71
70
|
} catch (error) {
|
|
72
|
-
|
|
71
|
+
// avatar-router already throws with a provider-aware, user-friendly
|
|
72
|
+
// message — just surface error.message directly.
|
|
73
|
+
const message =
|
|
74
|
+
error instanceof Error
|
|
75
|
+
? error.message
|
|
76
|
+
: "An unexpected error occurred during image generation.";
|
|
73
77
|
log.error({ error: message }, "Avatar generation failed");
|
|
74
78
|
return {
|
|
75
79
|
content: `Avatar generation failed: ${message}`,
|
|
@@ -12,6 +12,35 @@ const log = getLogger("sandbox");
|
|
|
12
12
|
|
|
13
13
|
const HASH_DISPLAY_LENGTH = 12;
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* macOS TCC-protected directories that trigger permission prompts when accessed.
|
|
17
|
+
* Unconditionally denied in the SBPL sandbox profile to prevent the assistant
|
|
18
|
+
* from triggering Photos, Contacts, Calendar, etc. dialogs during filesystem
|
|
19
|
+
* traversal (e.g. `find ~ -name .git`).
|
|
20
|
+
*
|
|
21
|
+
* Paths are relative to $HOME. Includes both TCC-protected directories that
|
|
22
|
+
* trigger prompts for all apps and directories like ~/Desktop and ~/Documents
|
|
23
|
+
* that are TCC-protected under App Sandbox or Full Disk Access checks.
|
|
24
|
+
*/
|
|
25
|
+
export const MACOS_TCC_PROTECTED_PATHS = [
|
|
26
|
+
"Desktop",
|
|
27
|
+
"Documents",
|
|
28
|
+
"Pictures/Photos Library.photoslibrary",
|
|
29
|
+
"Library/Photos",
|
|
30
|
+
"Library/Calendars",
|
|
31
|
+
"Library/Reminders",
|
|
32
|
+
"Library/Application Support/AddressBook",
|
|
33
|
+
"Library/Messages",
|
|
34
|
+
"Library/Mail",
|
|
35
|
+
"Library/Safari",
|
|
36
|
+
"Library/Cookies",
|
|
37
|
+
"Library/HomeKit",
|
|
38
|
+
"Library/IdentityServices",
|
|
39
|
+
"Library/Metadata/CoreSpotlight",
|
|
40
|
+
"Library/PersonalizationPortrait",
|
|
41
|
+
"Library/Suggestions",
|
|
42
|
+
];
|
|
43
|
+
|
|
15
44
|
/**
|
|
16
45
|
* Build a macOS sandbox-exec SBPL profile.
|
|
17
46
|
*
|
|
@@ -34,6 +63,18 @@ function buildSandboxProfile(
|
|
|
34
63
|
? ";; Allow network access (proxied mode - needed to reach the credential proxy)\n(allow network*)"
|
|
35
64
|
: ";; Block network access\n(deny network*)";
|
|
36
65
|
|
|
66
|
+
// Block macOS TCC-protected directories to prevent permission prompts
|
|
67
|
+
// during filesystem traversal. Placed AFTER (allow file-read*) because
|
|
68
|
+
// SBPL uses last-match-wins semantics.
|
|
69
|
+
const home = process.env.HOME ?? "";
|
|
70
|
+
const tccDenyRules = home
|
|
71
|
+
? "\n;; Block macOS TCC-protected directories to prevent permission prompts\n" +
|
|
72
|
+
MACOS_TCC_PROTECTED_PATHS.map(
|
|
73
|
+
(rel) =>
|
|
74
|
+
`(deny file-read* (subpath "${escapeSBPL(join(home, rel))}") (with no-log))`,
|
|
75
|
+
).join("\n")
|
|
76
|
+
: "";
|
|
77
|
+
|
|
37
78
|
// Build deny-read rules for protected paths (CES shell lockdown).
|
|
38
79
|
// These are placed AFTER the allow file-read* rule because SBPL uses
|
|
39
80
|
// last-match-wins semantics - the more specific deny overrides the
|
|
@@ -55,6 +96,13 @@ function buildSandboxProfile(
|
|
|
55
96
|
|
|
56
97
|
;; Allow read access to the filesystem (tools, libraries, etc.)
|
|
57
98
|
(allow file-read*)
|
|
99
|
+
${tccDenyRules}
|
|
100
|
+
|
|
101
|
+
;; Re-allow reads for the working directory even if it falls under a TCC-denied
|
|
102
|
+
;; subtree (e.g. ~/Desktop/my-project). SBPL is last-match-wins, so this
|
|
103
|
+
;; override must come after the TCC deny rules above but BEFORE the CES
|
|
104
|
+
;; deny-read rules below — credential isolation always takes precedence.
|
|
105
|
+
(allow file-read* (subpath "__WORKING_DIR__"))
|
|
58
106
|
${denyReadRules}
|
|
59
107
|
|
|
60
108
|
;; Allow write access to the working directory and its children
|
|
@@ -120,12 +168,13 @@ function getProfilePath(
|
|
|
120
168
|
if (!existsSync(dir)) {
|
|
121
169
|
mkdirSync(dir, { recursive: true });
|
|
122
170
|
}
|
|
123
|
-
// Include the network flag
|
|
124
|
-
// with different configurations don't collide.
|
|
171
|
+
// Include the network flag, deny-read paths, and HOME in the hash so
|
|
172
|
+
// profiles with different configurations don't collide.
|
|
125
173
|
let hashInput = allowNetwork ? `${workingDir}:proxied` : workingDir;
|
|
126
174
|
if (denyReadPaths && denyReadPaths.length > 0) {
|
|
127
175
|
hashInput += `:deny-read:${denyReadPaths.sort().join(",")}`;
|
|
128
176
|
}
|
|
177
|
+
hashInput += `:home:${process.env.HOME ?? ""}`;
|
|
129
178
|
const hash = createHash("sha256")
|
|
130
179
|
.update(hashInput)
|
|
131
180
|
.digest("hex")
|
|
@@ -30,9 +30,11 @@ export const SAFE_ENV_VARS = [
|
|
|
30
30
|
"VELLUM_DEV",
|
|
31
31
|
"VELLUM_DEBUG",
|
|
32
32
|
"VELLUM_ENVIRONMENT",
|
|
33
|
+
"BASE_DATA_DIR",
|
|
33
34
|
"VELLUM_WORKSPACE_DIR",
|
|
34
35
|
"CES_BOOTSTRAP_SOCKET_DIR",
|
|
35
36
|
"GATEWAY_INTERNAL_URL",
|
|
37
|
+
"GATEWAY_SECURITY_DIR",
|
|
36
38
|
"VELLUM_PLATFORM_URL",
|
|
37
39
|
"VELLUM_ASSISTANT_PLATFORM_URL",
|
|
38
40
|
"VELLUM_DOCS_BASE_URL",
|
|
@@ -82,8 +84,7 @@ export function buildSanitizedEnv(): Record<string, string> {
|
|
|
82
84
|
// Ensure UTF-8 locale so multi-byte characters (em dashes, curly quotes,
|
|
83
85
|
// arrows, etc.) survive piping through tools like pbcopy without corruption.
|
|
84
86
|
// macOS (Darwin) does not provide C.UTF-8, so use en_US.UTF-8 there.
|
|
85
|
-
const utf8Locale =
|
|
86
|
-
process.platform === "darwin" ? "en_US.UTF-8" : "C.UTF-8";
|
|
87
|
+
const utf8Locale = process.platform === "darwin" ? "en_US.UTF-8" : "C.UTF-8";
|
|
87
88
|
if (!env.LANG) env.LANG = utf8Locale;
|
|
88
89
|
if (!env.LC_ALL) env.LC_ALL = utf8Locale;
|
|
89
90
|
return env;
|