@vellumai/assistant 0.7.0 → 0.7.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 +38 -56
- package/Dockerfile +2 -0
- package/README.md +3 -4
- package/__tests__/permissions/gateway-threshold-reader.test.ts +88 -142
- package/bun.lock +29 -26
- package/docs/architecture/security.md +38 -16
- package/docs/plugins.md +7 -9
- package/knip.json +2 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +1 -0
- package/node_modules/@vellumai/gateway-client/src/ipc-client.ts +39 -1
- package/node_modules/@vellumai/gateway-client/src/types.ts +11 -0
- package/node_modules/@vellumai/service-contracts/package.json +2 -0
- package/node_modules/@vellumai/service-contracts/src/__tests__/contracts.test.ts +4 -0
- package/node_modules/@vellumai/service-contracts/src/__tests__/ingress.test.ts +107 -0
- package/node_modules/@vellumai/service-contracts/src/index.ts +5 -1
- package/node_modules/@vellumai/service-contracts/src/ingress.ts +24 -0
- package/node_modules/@vellumai/service-contracts/src/twilio-ingress.ts +84 -0
- package/node_modules/@vellumai/skill-host-contracts/__tests__/client.test.ts +1 -5
- package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +9 -5
- package/node_modules/@vellumai/skill-host-contracts/src/client.ts +10 -16
- package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +1 -9
- package/node_modules/@vellumai/skill-host-contracts/src/tool-types.ts +12 -12
- package/node_modules/@vellumai/slack-text/bun.lock +24 -0
- package/node_modules/@vellumai/slack-text/package.json +18 -0
- package/node_modules/@vellumai/slack-text/src/index.test.ts +153 -0
- package/node_modules/@vellumai/slack-text/src/index.ts +235 -0
- package/node_modules/@vellumai/slack-text/tsconfig.json +20 -0
- package/node_modules/@vellumai/twilio-client/bun.lock +24 -0
- package/node_modules/@vellumai/twilio-client/package.json +18 -0
- package/node_modules/@vellumai/twilio-client/src/__tests__/twilio-client.test.ts +128 -0
- package/node_modules/@vellumai/twilio-client/src/index.ts +179 -0
- package/node_modules/@vellumai/twilio-client/tsconfig.json +20 -0
- package/openapi.yaml +869 -129
- package/package.json +8 -3
- package/scripts/generate-openapi.ts +16 -111
- package/src/__tests__/agent-wake-override-profile.test.ts +23 -1
- package/src/__tests__/anthropic-provider.test.ts +56 -13
- package/src/__tests__/app-builder-tool-scripts.test.ts +3 -3
- package/src/__tests__/app-bundler.test.ts +170 -1
- package/src/__tests__/app-control-flow.test.ts +374 -0
- package/src/__tests__/app-control-no-global-cgevent.test.ts +98 -0
- package/src/__tests__/app-control-tool-schemas.test.ts +621 -0
- package/src/__tests__/app-conversation-ids-backfill.test.ts +278 -0
- package/src/__tests__/app-conversation-ids.test.ts +151 -0
- package/src/__tests__/app-executors.test.ts +30 -43
- package/src/__tests__/approval-cascade.test.ts +0 -15
- package/src/__tests__/approval-routes-http.test.ts +29 -23
- package/src/__tests__/assistant-event-hub-machine-name.test.ts +146 -0
- package/src/__tests__/assistant-event-hub-targeted.test.ts +257 -0
- package/src/__tests__/assistant-event-hub.test.ts +235 -79
- package/src/__tests__/assistant-event.test.ts +10 -5
- package/src/__tests__/assistant-events-sse-hardening.test.ts +44 -17
- package/src/__tests__/assistant-feature-flags-integration.test.ts +11 -36
- package/src/__tests__/background-shell-host-bash.test.ts +46 -56
- package/src/__tests__/bootstrap-turn-cleanup.test.ts +44 -0
- package/src/__tests__/btw-routes.test.ts +13 -4
- package/src/__tests__/call-controller.test.ts +50 -2
- package/src/__tests__/call-domain.test.ts +0 -2
- package/src/__tests__/call-routes-http.test.ts +0 -2
- package/src/__tests__/call-site-routing-provider.test.ts +193 -0
- package/src/__tests__/channel-approval-routes.test.ts +10 -296
- package/src/__tests__/channel-approvals.test.ts +25 -17
- package/src/__tests__/channel-guardian.test.ts +100 -146
- package/src/__tests__/channel-readiness-service.test.ts +59 -1
- package/src/__tests__/checker.test.ts +23 -38
- package/src/__tests__/compact-event-conversation-id-guard.test.ts +50 -0
- package/src/__tests__/compaction-events.test.ts +2 -0
- package/src/__tests__/config-loader-backfill.test.ts +90 -155
- package/src/__tests__/config-loader-platform-defaults.test.ts +196 -0
- package/src/__tests__/config-schema-cmd.test.ts +0 -1
- package/src/__tests__/config-schema.test.ts +6 -48
- package/src/__tests__/config-set-platform-guard.test.ts +48 -4
- package/src/__tests__/config-watcher-cleanup-throttle.test.ts +2 -2
- package/src/__tests__/config-watcher.test.ts +14 -2
- package/src/__tests__/connection-policy.test.ts +1 -52
- package/src/__tests__/contacts-write.test.ts +2 -64
- package/src/__tests__/context-image-dimensions.test.ts +1 -1
- package/src/__tests__/context-search-memory-source.test.ts +120 -1
- package/src/__tests__/context-search-memory-v2-source.test.ts +383 -0
- package/src/__tests__/context-search-pkb-source.test.ts +49 -0
- package/src/__tests__/context-search-workspace-source.test.ts +9 -22
- package/src/__tests__/context-window-manager.test.ts +46 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +2 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +102 -29
- package/src/__tests__/conversation-agent-loop.test.ts +980 -13
- package/src/__tests__/conversation-analysis-routes.test.ts +12 -10
- package/src/__tests__/conversation-app-control-instantiation.test.ts +392 -0
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +237 -0
- package/src/__tests__/conversation-attention-telegram.test.ts +11 -3
- package/src/__tests__/conversation-confirmation-signals.test.ts +0 -291
- package/src/__tests__/conversation-history-web-search.test.ts +4 -3
- package/src/__tests__/conversation-inference-profile-route.test.ts +12 -23
- package/src/__tests__/conversation-init.benchmark.test.ts +0 -2
- package/src/__tests__/conversation-lifecycle.test.ts +40 -4
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +283 -0
- package/src/__tests__/conversation-process-callsite.test.ts +79 -2
- package/src/__tests__/conversation-queue.test.ts +3 -8
- package/src/__tests__/conversation-routes-disk-view.test.ts +7 -161
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +120 -104
- package/src/__tests__/conversation-routes-slash-commands.test.ts +76 -66
- package/src/__tests__/conversation-runtime-assembly.test.ts +257 -3
- package/src/__tests__/conversation-slash-commands.test.ts +24 -8
- package/src/__tests__/conversation-slash-queue.test.ts +2 -0
- package/src/__tests__/conversation-speed-override.test.ts +0 -3
- package/src/__tests__/conversation-starter-routes.test.ts +79 -2
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +202 -0
- package/src/__tests__/conversation-surfaces-app-control.test.ts +317 -0
- package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +12 -5
- package/src/__tests__/conversation-surfaces-standalone.test.ts +18 -14
- package/src/__tests__/conversation-surfaces-state-update.test.ts +3 -2
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +8 -46
- package/src/__tests__/conversation-usage.test.ts +253 -3
- package/src/__tests__/credential-execution-feature-gates.test.ts +5 -12
- package/src/__tests__/credential-execution-managed-contract.test.ts +3 -131
- package/src/__tests__/credential-execution-shell-lockdown.test.ts +0 -39
- package/src/__tests__/credential-health-service.test.ts +68 -0
- package/src/__tests__/credential-security-e2e.test.ts +4 -3
- package/src/__tests__/credential-security-invariants.test.ts +1 -5
- package/src/__tests__/credential-token-resolver.test.ts +180 -0
- package/src/__tests__/credentials-cli.test.ts +5 -12
- package/src/__tests__/cu-unified-flow.test.ts +206 -27
- package/src/__tests__/daemon-assistant-events.test.ts +34 -21
- package/src/__tests__/daemon-credential-client.test.ts +102 -17
- package/src/__tests__/db-connection-isolation.test.ts +125 -0
- package/src/__tests__/db-migration-rollback.test.ts +101 -0
- package/src/__tests__/db-schedule-syntax-migration.test.ts +2 -0
- package/src/__tests__/db-slack-compaction-watermark-migration.test.ts +169 -0
- package/src/__tests__/deterministic-verification-control-plane.test.ts +7 -80
- package/src/__tests__/document-conversations.test.ts +332 -0
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
- package/src/__tests__/embedding-managed-proxy-selection.test.ts +2 -2
- package/src/__tests__/emit-event-signal.test.ts +4 -6
- package/src/__tests__/events-client-registration.test.ts +193 -49
- package/src/__tests__/filing-service.test.ts +58 -7
- package/src/__tests__/first-greeting.test.ts +156 -150
- package/src/__tests__/fixtures/mock-chrome-extension.ts +108 -66
- package/src/__tests__/gateway-only-enforcement.test.ts +0 -1
- package/src/__tests__/get-skill-detail-audit.test.ts +3 -8
- package/src/__tests__/guardian-binding-drift-heal.test.ts +1 -1
- package/src/__tests__/guardian-dispatch.test.ts +1 -1
- package/src/__tests__/guardian-grant-minting.test.ts +7 -2
- package/src/__tests__/guardian-routing-invariants.test.ts +7 -2
- package/src/__tests__/guardian-routing-state.test.ts +1 -1
- package/src/__tests__/guardian-verification-voice-binding.test.ts +0 -2
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +30 -11
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +2 -84
- package/src/__tests__/headless-browser-mode.test.ts +4 -9
- package/src/__tests__/headless-browser-navigate.test.ts +21 -20
- package/src/__tests__/heartbeat-service.test.ts +1007 -8
- package/src/__tests__/helpers/call-route-handler.ts +7 -1
- package/src/__tests__/helpers/channel-test-adapter.ts +2 -2
- package/src/__tests__/helpers/create-guardian-binding.ts +91 -0
- package/src/__tests__/host-app-control-proxy.test.ts +602 -0
- package/src/__tests__/host-app-control-routes.test.ts +263 -0
- package/src/__tests__/host-bash-proxy.test.ts +270 -147
- package/src/__tests__/host-bash-routes.test.ts +294 -0
- package/src/__tests__/host-browser-proxy.test.ts +126 -198
- package/src/__tests__/host-browser-routes.test.ts +50 -54
- package/src/__tests__/host-cu-proxy.test.ts +78 -144
- package/src/__tests__/host-cu-routes-targeted.test.ts +300 -0
- package/src/__tests__/host-file-edit-tool.test.ts +47 -1
- package/src/__tests__/host-file-proxy-targeted.test.ts +339 -0
- package/src/__tests__/host-file-proxy.test.ts +62 -122
- package/src/__tests__/host-file-read-tool.test.ts +59 -21
- package/src/__tests__/host-file-routes-targeted.test.ts +262 -0
- package/src/__tests__/host-file-write-tool.test.ts +42 -1
- package/src/__tests__/host-proxy-base.test.ts +312 -0
- package/src/__tests__/host-shell-tool.test.ts +53 -70
- package/src/__tests__/host-transfer-pending-interactions.test.ts +2 -18
- package/src/__tests__/host-transfer-proxy-targeted.test.ts +583 -0
- package/src/__tests__/host-transfer-proxy.test.ts +145 -56
- package/src/__tests__/host-transfer-routes-targeted.test.ts +447 -0
- package/src/__tests__/http-user-message-parity.test.ts +1 -6
- package/src/__tests__/identity-intro-cache.test.ts +29 -0
- package/src/__tests__/identity-routes.test.ts +103 -1
- package/src/__tests__/inbound-slack-persistence.test.ts +31 -0
- package/src/__tests__/init-feature-flag-overrides.test.ts +26 -3
- package/src/__tests__/injector-chain.test.ts +10 -5
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +124 -0
- package/src/__tests__/inline-command-runner.test.ts +0 -67
- package/src/__tests__/inline-skill-load-permissions.test.ts +5 -13
- package/src/__tests__/install-skill-routing.test.ts +1 -13
- package/src/__tests__/integration-status.test.ts +85 -5
- package/src/__tests__/intent-routing.test.ts +0 -1
- package/src/__tests__/jobs-store-qdrant-breaker.test.ts +95 -5
- package/src/__tests__/lifecycle-memory-v2-seed.test.ts +17 -0
- package/src/__tests__/llm-callsite-catalog.test.ts +34 -0
- package/src/__tests__/llm-catalog-parity.test.ts +90 -0
- package/src/__tests__/llm-context-resolution.test.ts +180 -0
- package/src/__tests__/llm-resolver.test.ts +80 -12
- package/src/__tests__/llm-usage-store.test.ts +269 -4
- package/src/__tests__/log-export-routes.test.ts +89 -0
- package/src/__tests__/managed-profile-guard.test.ts +225 -0
- package/src/__tests__/managed-skill-lifecycle.test.ts +0 -11
- package/src/__tests__/manual-token-reconciliation.test.ts +334 -0
- package/src/__tests__/mcp-auth-routes.test.ts +197 -0
- package/src/__tests__/mcp-cli.test.ts +338 -2
- package/src/__tests__/memory-jobs-worker-lanes.test.ts +188 -0
- package/src/__tests__/memory-v2-static-injector.test.ts +95 -0
- package/src/__tests__/migration-cross-version-compatibility.test.ts +197 -291
- package/src/__tests__/migration-export-http.test.ts +33 -26
- package/src/__tests__/migration-export-streaming.test.ts +18 -10
- package/src/__tests__/migration-export-to-gcs.test.ts +49 -9
- package/src/__tests__/migration-import-commit-http.test.ts +172 -21
- package/src/__tests__/migration-import-from-gcs.test.ts +50 -9
- package/src/__tests__/migration-import-from-url.test.ts +20 -6
- package/src/__tests__/migration-import-preflight-http.test.ts +95 -95
- package/src/__tests__/migration-parity-persistence.test.ts +62 -25
- package/src/__tests__/migration-transport.test.ts +115 -23
- package/src/__tests__/migration-validate-http.test.ts +105 -80
- package/src/__tests__/migration-wizard.test.ts +133 -27
- package/src/__tests__/mock-gateway-ipc.ts +1 -0
- package/src/__tests__/non-member-access-request.test.ts +1 -1
- package/src/__tests__/notification-guardian-path.test.ts +1 -1
- package/src/__tests__/oauth-cli.test.ts +0 -2
- package/src/__tests__/oauth-store.test.ts +19 -0
- package/src/__tests__/oauth2-gateway-transport.test.ts +0 -1
- package/src/__tests__/persistence-secret-redaction.test.ts +299 -0
- package/src/__tests__/platform-bash-auto-approve.test.ts +26 -21
- package/src/__tests__/prechat-onboarding-contract.test.ts +34 -8
- package/src/__tests__/pricing.test.ts +68 -4
- package/src/__tests__/process-message-background-slack.test.ts +333 -0
- package/src/__tests__/provider-commit-message-generator.test.ts +0 -1
- package/src/__tests__/provider-managed-proxy-integration.test.ts +153 -17
- package/src/__tests__/provider-send-message-override-profile.test.ts +50 -0
- package/src/__tests__/provider-usage-tracking.test.ts +208 -0
- package/src/__tests__/public-ingress-urls.test.ts +97 -0
- package/src/__tests__/reaction-persistence.test.ts +9 -6
- package/src/__tests__/rebind-secrets-screen.test.ts +53 -16
- package/src/__tests__/recording-handler.test.ts +64 -81
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +4 -3
- package/src/__tests__/relay-server.test.ts +18 -13
- package/src/__tests__/require-fresh-approval.test.ts +13 -23
- package/src/__tests__/retry-backoff.test.ts +87 -0
- package/src/__tests__/runtime-attachment-metadata.test.ts +1 -1
- package/src/__tests__/runtime-events-sse-parity.test.ts +3 -4
- package/src/__tests__/runtime-events-sse.test.ts +13 -18
- package/src/__tests__/sanitize-config-for-transfer.test.ts +24 -2
- package/src/__tests__/schedule-retry.test.ts +715 -0
- package/src/__tests__/script-proxy-mitm-handler.test.ts +1 -1
- package/src/__tests__/search-skills-unified.test.ts +9 -15
- package/src/__tests__/secret-ingress-cli.test.ts +2 -5
- package/src/__tests__/secret-ingress-http.test.ts +1 -4
- package/src/__tests__/secret-onetime-send.test.ts +4 -2
- package/src/__tests__/secret-prompt-log-hygiene.test.ts +24 -7
- package/src/__tests__/secret-prompter-channel-fallback.test.ts +42 -47
- package/src/__tests__/secret-response-routing.test.ts +29 -15
- package/src/__tests__/secret-routes-managed-proxy.test.ts +5 -1
- package/src/__tests__/secret-scanner.test.ts +2 -545
- package/src/__tests__/send-endpoint-busy.test.ts +12 -24
- package/src/__tests__/settings-routes.test.ts +1 -1
- package/src/__tests__/shell-credential-ref.test.ts +0 -8
- package/src/__tests__/shell-tool-proxy-mode.test.ts +0 -57
- package/src/__tests__/skill-feature-flags.test.ts +43 -41
- package/src/__tests__/skill-load-feature-flag.test.ts +13 -14
- package/src/__tests__/skill-load-inline-command.test.ts +0 -51
- package/src/__tests__/skill-load-inline-includes.test.ts +0 -43
- package/src/__tests__/skill-projection.benchmark.test.ts +0 -1
- package/src/__tests__/skill-script-runner-sandbox.test.ts +0 -12
- package/src/__tests__/skill-tool-factory.test.ts +97 -0
- package/src/__tests__/skills-file-content-endpoint.test.ts +9 -30
- package/src/__tests__/skills-files-catalog-fallback.test.ts +11 -17
- package/src/__tests__/slack-channel-config.test.ts +9 -14
- package/src/__tests__/slack-inbound-verification.test.ts +1 -62
- package/src/__tests__/subagent-fork-notifications.test.ts +57 -47
- package/src/__tests__/subagent-manager-notify.test.ts +70 -70
- package/src/__tests__/subagent-notify-parent.test.ts +80 -83
- package/src/__tests__/system-prompt-ask-mode.test.ts +0 -1
- package/src/__tests__/system-prompt.test.ts +115 -14
- package/src/__tests__/telegram-config.test.ts +0 -1
- package/src/__tests__/terminal-tools.test.ts +0 -89
- package/src/__tests__/test-preload.ts +8 -0
- package/src/__tests__/thread-backfill.test.ts +945 -31
- package/src/__tests__/tool-approval-handler.test.ts +3 -4
- package/src/__tests__/tool-audit-listener.test.ts +48 -0
- package/src/__tests__/tool-domain-event-publisher.test.ts +0 -36
- package/src/__tests__/tool-execute-pipeline.test.ts +0 -7
- package/src/__tests__/tool-execution-abort-cleanup.test.ts +0 -17
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +9 -19
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +4 -8
- package/src/__tests__/tool-executor.test.ts +12 -20
- package/src/__tests__/tool-metrics-listener.test.ts +0 -35
- package/src/__tests__/tool-side-effects-slack-dm.test.ts +1 -0
- package/src/__tests__/tool-trace-listener.test.ts +0 -17
- package/src/__tests__/transfer-progress-screen.test.ts +63 -26
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +2 -149
- package/src/__tests__/trusted-contact-multichannel.test.ts +2 -4
- package/src/__tests__/trusted-contact-verification.test.ts +1 -1
- package/src/__tests__/tts-catalog-parity.test.ts +16 -5
- package/src/__tests__/twilio-config.test.ts +3 -16
- package/src/__tests__/twilio-routes.test.ts +3 -5
- package/src/__tests__/twilio-validation.test.ts +93 -0
- package/src/__tests__/usage-attribution.test.ts +247 -0
- package/src/__tests__/usage-cli.test.ts +143 -0
- package/src/__tests__/usage-grouped-buckets.test.ts +155 -0
- package/src/__tests__/usage-routes.test.ts +150 -0
- package/src/__tests__/validation-results-screen.test.ts +39 -16
- package/src/__tests__/vbundle-pax-and-symlink.test.ts +12 -3
- package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +47 -138
- package/src/__tests__/verification-control-plane-policy.test.ts +6 -11
- package/src/__tests__/voice-ingress-preflight.test.ts +19 -0
- package/src/__tests__/voice-session-bridge.test.ts +5 -5
- package/src/__tests__/workspace-migration-006-services-config.test.ts +3 -2
- package/src/__tests__/workspace-migration-062-drop-memory-v2-edges-json.test.ts +103 -0
- package/src/__tests__/workspace-migration-063-release-notes-dynamic-model-context.test.ts +77 -0
- package/src/__tests__/workspace-migration-064-unwind-main-agent-opus-seed.test.ts +225 -0
- package/src/__tests__/workspace-migration-backfill-installation-id.test.ts +1 -5
- package/src/__tests__/workspace-migration-down-functions.test.ts +8 -8
- package/src/__tests__/workspace-migration-memory-v2-init.test.ts +8 -30
- package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +10 -6
- package/src/acp/index.ts +0 -15
- package/src/acp/session-manager.ts +37 -34
- package/src/agent/loop.ts +16 -1
- package/src/approvals/AGENTS.md +4 -0
- package/src/approvals/__tests__/guardian-feed-event.test.ts +10 -3
- package/src/approvals/guardian-request-resolvers.ts +10 -2
- package/src/backup/__tests__/paths.test.ts +0 -22
- package/src/backup/__tests__/restore.test.ts +94 -177
- package/src/backup/paths.ts +2 -15
- package/src/backup/restore.ts +107 -231
- package/src/browser-session/events.ts +0 -9
- package/src/bundler/app-bundler.ts +51 -3
- package/src/calls/call-store.ts +1 -34
- package/src/calls/guardian-question-copy.ts +0 -108
- package/src/calls/relay-server.ts +4 -68
- package/src/calls/twilio-config.ts +2 -17
- package/src/calls/twilio-rest.ts +31 -141
- package/src/calls/twilio-routes.ts +12 -13
- package/src/calls/voice-session-bridge.ts +7 -38
- package/src/channels/types.ts +8 -42
- package/src/cli/commands/__tests__/backup.test.ts +6 -277
- package/src/cli/commands/__tests__/cache.test.ts +152 -5
- package/src/cli/commands/__tests__/gateway.test.ts +288 -0
- package/src/cli/commands/__tests__/memory-v2.test.ts +18 -28
- package/src/cli/commands/__tests__/trust.test.ts +21 -387
- package/src/cli/commands/__tests__/webhooks.test.ts +0 -1
- package/src/cli/commands/backup.ts +6 -331
- package/src/cli/commands/cache-fs.ts +8 -0
- package/src/cli/commands/cache.ts +153 -82
- package/src/cli/commands/clients.ts +64 -7
- package/src/cli/commands/completions.ts +3 -3
- package/src/cli/commands/contacts.ts +304 -76
- package/src/cli/commands/conversations.ts +2 -5
- package/src/cli/commands/credentials.ts +15 -7
- package/src/cli/commands/domain.ts +66 -15
- package/src/cli/commands/gateway.ts +183 -0
- package/src/cli/commands/keys.ts +13 -7
- package/src/cli/commands/mcp.ts +116 -156
- package/src/cli/commands/memory-v2.ts +320 -53
- package/src/cli/commands/oauth/shared.ts +2 -29
- package/src/cli/commands/pending.ts +102 -0
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +0 -1
- package/src/cli/commands/platform/__tests__/connect.test.ts +0 -2
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +0 -2
- package/src/cli/commands/platform/__tests__/status.test.ts +13 -15
- package/src/cli/commands/platform/disconnect.ts +5 -4
- package/src/cli/commands/platform/index.ts +0 -18
- package/src/cli/commands/skills.ts +77 -35
- package/src/cli/commands/trust.ts +70 -430
- package/src/cli/commands/usage.ts +25 -16
- package/src/cli/lib/daemon-credential-client.ts +115 -19
- package/src/cli/program.ts +4 -0
- package/src/cli.ts +0 -21
- package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
- package/src/config/assistant-feature-flags.ts +67 -10
- package/src/config/bundled-skills/acp/SKILL.md +6 -0
- package/src/config/bundled-skills/acp/TOOLS.json +1 -22
- package/src/config/bundled-skills/app-builder/SKILL.md +14 -109
- package/src/config/bundled-skills/app-builder/TOOLS.json +1 -28
- package/src/config/bundled-skills/app-builder/tools/app-create.ts +1 -10
- package/src/config/bundled-skills/app-control/SKILL.md +75 -0
- package/src/config/bundled-skills/app-control/TOOLS.json +299 -0
- package/src/config/bundled-skills/app-control/tools/app-control-click.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-combo.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-drag.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-observe.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-press.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-sequence.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-start.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-stop.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-type.ts +12 -0
- package/src/config/bundled-skills/computer-use/SKILL.md +6 -0
- package/src/config/bundled-skills/computer-use/TOOLS.json +67 -43
- package/src/config/bundled-skills/contacts/TOOLS.json +0 -16
- package/src/config/bundled-skills/document/TOOLS.json +0 -8
- package/src/config/bundled-skills/followups/TOOLS.json +0 -12
- package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
- package/src/config/bundled-skills/image-studio/TOOLS.json +0 -4
- package/src/config/bundled-skills/media-processing/TOOLS.json +0 -24
- package/src/config/bundled-skills/messaging/TOOLS.json +14 -44
- package/src/config/bundled-skills/phone-calls/TOOLS.json +0 -12
- package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +19 -4
- package/src/config/bundled-skills/playbooks/TOOLS.json +0 -16
- package/src/config/bundled-skills/schedule/TOOLS.json +14 -14
- package/src/config/bundled-skills/sequences/TOOLS.json +0 -36
- package/src/config/bundled-skills/settings/SKILL.md +4 -0
- package/src/config/bundled-skills/settings/TOOLS.json +0 -12
- package/src/config/bundled-skills/skill-management/SKILL.md +6 -0
- package/src/config/bundled-skills/skill-management/TOOLS.json +0 -8
- package/src/config/bundled-skills/subagent/SKILL.md +6 -2
- package/src/config/bundled-skills/subagent/TOOLS.json +0 -20
- package/src/config/bundled-skills/transcribe/SKILL.md +4 -0
- package/src/config/bundled-skills/transcribe/TOOLS.json +0 -4
- package/src/config/bundled-tool-registry.ts +21 -0
- package/src/config/env-registry.ts +12 -4
- package/src/config/env.ts +22 -26
- package/src/config/feature-flag-registry.json +40 -152
- package/src/config/llm-callsite-catalog.ts +12 -0
- package/src/config/llm-context-resolution.ts +80 -0
- package/src/config/llm-resolver.ts +58 -22
- package/src/config/loader.ts +76 -102
- package/src/config/sanitize-for-transfer.ts +2 -0
- package/src/config/schema.ts +2 -158
- package/src/config/schemas/__tests__/memory-lifecycle.test.ts +80 -0
- package/src/config/schemas/__tests__/memory-v2.test.ts +8 -4
- package/src/config/schemas/call-site-catalog.ts +271 -0
- package/src/config/schemas/calls.ts +5 -14
- package/src/config/schemas/heartbeat.ts +63 -0
- package/src/config/schemas/inference.ts +1 -1
- package/src/config/schemas/ingress.ts +11 -7
- package/src/config/schemas/llm.ts +34 -11
- package/src/config/schemas/memory-lifecycle.ts +77 -24
- package/src/config/schemas/memory-retrieval.ts +2 -2
- package/src/config/schemas/memory-v2.ts +57 -4
- package/src/config/schemas/platform.ts +6 -0
- package/src/config/schemas/security.ts +1 -42
- package/src/config/schemas/services.ts +7 -21
- package/src/config/schemas/skills.ts +5 -11
- package/src/config/schemas/tts.ts +1 -1
- package/src/config/seed-inference-profiles.ts +117 -0
- package/src/config/skills.ts +0 -90
- package/src/config/types.ts +3 -6
- package/src/contacts/contact-store.ts +0 -47
- package/src/contacts/contacts-write.ts +1 -132
- package/src/context/window-manager.ts +43 -5
- package/src/credential-execution/feature-gates.ts +10 -10
- package/src/credential-execution/process-manager.ts +46 -51
- package/src/credential-health/credential-health-service.ts +21 -16
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +75 -82
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +126 -5
- package/src/daemon/__tests__/daemon-skill-host.test.ts +2 -9
- package/src/daemon/bootstrap-turn-cleanup.ts +45 -0
- package/src/daemon/config-watcher.ts +4 -3
- package/src/daemon/connection-policy.ts +1 -26
- package/src/daemon/conversation-agent-loop-handlers.ts +74 -7
- package/src/daemon/conversation-agent-loop.ts +309 -64
- package/src/daemon/conversation-history.ts +8 -8
- package/src/daemon/conversation-launch.ts +20 -135
- package/src/daemon/conversation-lifecycle.ts +8 -1
- package/src/daemon/conversation-messaging.ts +1 -0
- package/src/daemon/conversation-process.ts +97 -172
- package/src/daemon/conversation-runtime-assembly.ts +219 -76
- package/src/daemon/conversation-slash.ts +47 -5
- package/src/daemon/conversation-store.ts +7 -31
- package/src/daemon/conversation-surfaces.ts +144 -29
- package/src/daemon/conversation-tool-setup.ts +18 -87
- package/src/daemon/conversation-usage.ts +36 -0
- package/src/daemon/conversation.ts +134 -231
- package/src/daemon/daemon-control.ts +3 -71
- package/src/daemon/daemon-skill-host.ts +8 -11
- package/src/daemon/dictation-profile-store.ts +2 -26
- package/src/daemon/doordash-steps.ts +1 -1
- package/src/daemon/first-greeting.ts +44 -156
- package/src/daemon/handlers/config-channels.ts +12 -12
- package/src/daemon/handlers/config-ingress.ts +4 -165
- package/src/daemon/handlers/config-model.ts +1 -1
- package/src/daemon/handlers/config-voice.ts +0 -42
- package/src/daemon/handlers/conversations.ts +11 -190
- package/src/daemon/handlers/recording.ts +26 -158
- package/src/daemon/handlers/shared.ts +27 -72
- package/src/daemon/handlers/skills.ts +42 -93
- package/src/daemon/host-app-control-proxy.ts +293 -0
- package/src/daemon/host-bash-proxy.ts +124 -92
- package/src/daemon/host-browser-proxy.ts +111 -88
- package/src/daemon/host-cu-proxy.ts +100 -104
- package/src/daemon/host-file-proxy.ts +136 -91
- package/src/daemon/host-proxy-base.ts +294 -0
- package/src/daemon/host-proxy-preactivation.ts +82 -0
- package/src/daemon/host-transfer-proxy.ts +303 -147
- package/src/daemon/lifecycle.ts +164 -132
- package/src/daemon/message-protocol.ts +3 -8
- package/src/daemon/message-types/contacts.ts +23 -1
- package/src/daemon/message-types/conversations.ts +18 -8
- package/src/daemon/message-types/host-app-control.ts +150 -0
- package/src/daemon/message-types/host-bash.ts +5 -0
- package/src/daemon/message-types/host-cu.ts +3 -0
- package/src/daemon/message-types/host-file.ts +5 -0
- package/src/daemon/message-types/host-transfer.ts +4 -0
- package/src/daemon/message-types/messages.ts +10 -9
- package/src/daemon/message-types/schedules.ts +8 -3
- package/src/daemon/message-types/skills.ts +2 -2
- package/src/daemon/message-types/workspace.ts +1 -1
- package/src/daemon/process-message.ts +119 -239
- package/src/daemon/server.ts +13 -462
- package/src/daemon/shutdown-handlers.ts +2 -5
- package/src/daemon/tool-setup-types.ts +51 -0
- package/src/daemon/tool-side-effects.ts +126 -108
- package/src/daemon/trust-context.ts +13 -0
- package/src/daemon/wake-target-adapter.ts +4 -9
- package/src/events/domain-events.ts +0 -8
- package/src/events/tool-audit-listener.ts +5 -2
- package/src/events/tool-domain-event-publisher.ts +0 -10
- package/src/events/tool-metrics-listener.ts +0 -17
- package/src/events/tool-trace-listener.ts +0 -14
- package/src/filing/filing-service.ts +13 -1
- package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +21 -9
- package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +216 -0
- package/src/heartbeat/heartbeat-run-store.ts +236 -0
- package/src/heartbeat/heartbeat-service.ts +303 -54
- package/src/home/__tests__/feed-writer.test.ts +0 -4
- package/src/home/__tests__/post-connect-feed.test.ts +99 -0
- package/src/home/__tests__/relationship-state-writer.test.ts +41 -9
- package/src/home/__tests__/suggested-prompts.test.ts +89 -0
- package/src/home/feed-writer.ts +1 -2
- package/src/home/post-connect-feed.ts +68 -0
- package/src/home/relationship-state-writer.ts +33 -95
- package/src/home/suggested-prompts.ts +46 -10
- package/src/inbound/public-ingress-urls.ts +32 -34
- package/src/ipc/__tests__/browser-ipc.test.ts +2 -12
- package/src/ipc/__tests__/route-error-envelope.test.ts +80 -0
- package/src/ipc/__tests__/skill-server-bidirectional.test.ts +0 -1
- package/src/ipc/assistant-server.ts +17 -11
- package/src/ipc/cli-client.ts +32 -1
- package/src/ipc/routes/__tests__/memory-v2-backfill.test.ts +39 -20
- package/src/ipc/routes/route-adapter.ts +1 -1
- package/src/ipc/routes/trust-rules.test.ts +0 -95
- package/src/ipc/skill-ipc-types.ts +41 -0
- package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +13 -27
- package/src/ipc/skill-routes/__tests__/identity.test.ts +4 -23
- package/src/ipc/skill-routes/events.ts +12 -23
- package/src/ipc/skill-routes/identity.ts +4 -17
- package/src/ipc/skill-routes/index.ts +1 -1
- package/src/ipc/skill-server.ts +6 -39
- package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +0 -8
- package/src/live-voice/live-voice-metrics.ts +10 -10
- package/src/live-voice/protocol.ts +4 -13
- package/src/mcp/__tests__/mcp-auth-orchestrator.test.ts +304 -0
- package/src/mcp/manager.ts +0 -5
- package/src/mcp/mcp-auth-orchestrator.ts +213 -0
- package/src/mcp/mcp-auth-state.ts +133 -0
- package/src/mcp/mcp-oauth-provider.ts +19 -0
- package/src/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +55 -0
- package/src/memory/__tests__/jobs-store-job-classes.test.ts +24 -0
- package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +127 -0
- package/src/memory/__tests__/qdrant-client-sentinel.test.ts +49 -0
- package/src/memory/__tests__/sparse-tokenize.test.ts +66 -0
- package/src/memory/anisotropy.test.ts +247 -0
- package/src/memory/anisotropy.ts +443 -0
- package/src/memory/app-git-service.ts +0 -32
- package/src/memory/app-store.ts +154 -0
- package/src/memory/attachments-store.ts +6 -0
- package/src/memory/auto-analysis-constants.ts +17 -0
- package/src/memory/auto-analysis-guard.ts +5 -15
- package/src/memory/canonical-guardian-store.ts +7 -7
- package/src/memory/context-search/__tests__/agent-runner-redaction.test.ts +122 -0
- package/src/memory/context-search/agent-protocol.ts +6 -6
- package/src/memory/context-search/agent-runner.ts +32 -7
- package/src/memory/context-search/sources/memory-v2.ts +590 -0
- package/src/memory/context-search/sources/memory.ts +5 -0
- package/src/memory/context-search/sources/pkb.ts +10 -1
- package/src/memory/context-search/sources/workspace.ts +3 -2
- package/src/memory/conversation-crud.ts +30 -5
- package/src/memory/conversation-disk-view.ts +1 -5
- package/src/memory/conversation-key-store.ts +2 -15
- package/src/memory/conversation-starter-checkpoints.ts +63 -0
- package/src/memory/db-connection.ts +62 -0
- package/src/memory/db-init.ts +18 -0
- package/src/memory/embedding-backend.ts +12 -42
- package/src/memory/embedding-gemini.ts +0 -2
- package/src/memory/embedding-local.ts +6 -6
- package/src/memory/embedding-ollama.ts +6 -6
- package/src/memory/embedding-openai.ts +6 -6
- package/src/memory/embedding-types.ts +21 -0
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +49 -8
- package/src/memory/graph/conversation-graph-memory.ts +35 -36
- package/src/memory/graph/graph-search.ts +8 -0
- package/src/memory/graph/injection.test.ts +2 -2
- package/src/memory/graph/injection.ts +1 -1
- package/src/memory/graph/retriever.ts +28 -0
- package/src/memory/graph/tools.ts +1 -1
- package/src/memory/guardian-action-store.ts +0 -83
- package/src/memory/guardian-approvals.ts +0 -48
- package/src/memory/indexer.ts +1 -15
- package/src/memory/job-handlers/conversation-starters.ts +36 -53
- package/src/memory/job-utils.ts +0 -6
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +8 -2
- package/src/memory/jobs/embed-concept-page.ts +28 -2
- package/src/memory/jobs/embed-pkb-file.test.ts +2 -2
- package/src/memory/jobs-store.ts +66 -23
- package/src/memory/jobs-worker.ts +114 -79
- package/src/memory/llm-request-log-store.ts +0 -41
- package/src/memory/llm-usage-store.ts +129 -43
- package/src/memory/memory-v2-activation-log-store.ts +115 -0
- package/src/memory/migrations/233-document-conversations.ts +54 -0
- package/src/memory/migrations/234-memory-v2-activation-logs.ts +55 -0
- package/src/memory/migrations/235-llm-usage-attribution.ts +31 -0
- package/src/memory/migrations/235-slack-compaction-watermark.ts +44 -0
- package/src/memory/migrations/236-tool-invocations-matched-rule-id.ts +26 -0
- package/src/memory/migrations/237-heartbeat-runs.ts +45 -0
- package/src/memory/migrations/238-schedule-retry-policy.ts +20 -0
- package/src/memory/migrations/__tests__/234-memory-v2-activation-logs.test.ts +182 -0
- package/src/memory/migrations/index.ts +19 -0
- package/src/memory/migrations/registry.ts +32 -0
- package/src/memory/pkb/pkb-search.ts +7 -0
- package/src/memory/qdrant-client.ts +50 -20
- package/src/memory/raw-query.ts +2 -68
- package/src/memory/schema/conversations.ts +7 -0
- package/src/memory/schema/infrastructure.ts +40 -0
- package/src/memory/search/semantic.ts +12 -16
- package/src/memory/sparse-tokenize.ts +49 -0
- package/src/memory/tool-usage-store.ts +2 -0
- package/src/memory/usage-buckets.ts +40 -1
- package/src/memory/usage-grouped-buckets.ts +127 -0
- package/src/memory/v2/__tests__/activation.test.ts +361 -180
- package/src/memory/v2/__tests__/backfill-jobs.test.ts +2 -129
- package/src/memory/v2/__tests__/consolidation-job.test.ts +28 -11
- package/src/memory/v2/__tests__/edge-index.test.ts +278 -0
- package/src/memory/v2/__tests__/injection.test.ts +424 -33
- package/src/memory/v2/__tests__/migration.test.ts +64 -36
- package/src/memory/v2/__tests__/page-store.test.ts +191 -8
- package/src/memory/v2/__tests__/prompts-consolidation.test.ts +181 -0
- package/src/memory/v2/__tests__/sim.test.ts +166 -6
- package/src/memory/v2/__tests__/skill-store.test.ts +115 -3
- package/src/memory/v2/__tests__/sparse-bm25.test.ts +292 -0
- package/src/memory/v2/__tests__/static-context.test.ts +152 -0
- package/src/memory/v2/activation.ts +215 -163
- package/src/memory/v2/backfill-jobs.ts +15 -100
- package/src/memory/v2/consolidation-job.ts +17 -17
- package/src/memory/v2/constants.ts +7 -0
- package/src/memory/v2/edge-index.ts +191 -0
- package/src/memory/v2/injection.ts +241 -84
- package/src/memory/v2/migration.ts +57 -64
- package/src/memory/v2/now-text.ts +2 -3
- package/src/memory/v2/page-store.ts +168 -31
- package/src/memory/v2/prompts/consolidation.ts +385 -88
- package/src/memory/v2/prompts/sweep.ts +3 -3
- package/src/memory/v2/qdrant.ts +99 -1
- package/src/memory/v2/sim.ts +126 -16
- package/src/memory/v2/skill-qdrant.ts +12 -3
- package/src/memory/v2/skill-store.ts +71 -8
- package/src/memory/v2/sparse-bm25.ts +245 -0
- package/src/memory/v2/static-context.ts +63 -0
- package/src/memory/v2/types.ts +10 -20
- package/src/memory/validation.ts +0 -11
- package/src/messaging/draft-store.ts +0 -6
- package/src/messaging/provider-types.ts +8 -0
- package/src/messaging/provider.ts +7 -0
- package/src/messaging/providers/gmail/client.ts +1 -121
- package/src/messaging/providers/gmail/types.ts +0 -49
- package/src/messaging/providers/outlook/client.ts +0 -73
- package/src/messaging/providers/slack/__tests__/adapter-mention-rendering.test.ts +226 -0
- package/src/messaging/providers/slack/adapter.ts +123 -52
- package/src/messaging/providers/slack/backfill.test.ts +95 -6
- package/src/messaging/providers/slack/backfill.ts +89 -11
- package/src/messaging/providers/slack/client.ts +10 -124
- package/src/messaging/providers/slack/message-metadata.ts +12 -2
- package/src/messaging/providers/slack/render-transcript.test.ts +56 -0
- package/src/messaging/providers/slack/render-transcript.ts +126 -25
- package/src/messaging/providers/slack/types.ts +1 -32
- package/src/notifications/README.md +10 -10
- package/src/notifications/broadcaster.ts +1 -1
- package/src/notifications/guardian-question-mode.ts +5 -5
- package/src/oauth/connect-orchestrator.ts +4 -0
- package/src/oauth/connection-resolver.test.ts +8 -0
- package/src/oauth/connection-resolver.ts +8 -16
- package/src/oauth/credential-token-resolver.ts +95 -0
- package/src/oauth/manual-token-connection.ts +26 -34
- package/src/oauth/oauth-store.ts +6 -4
- package/src/outbound-proxy/certs.ts +0 -7
- package/src/outbound-proxy/index.ts +1 -59
- package/src/outbound-proxy/logging.ts +1 -1
- package/src/outbound-proxy/policy.ts +6 -5
- package/src/outbound-proxy/router.ts +2 -1
- package/src/permissions/approval-policy.test.ts +6 -275
- package/src/permissions/approval-policy.ts +0 -51
- package/src/permissions/approval-provenance.test.ts +184 -0
- package/src/permissions/approval-provenance.ts +70 -0
- package/src/permissions/checker.test.ts +0 -1
- package/src/permissions/checker.ts +7 -18
- package/src/permissions/gateway-threshold-reader.ts +6 -1
- package/src/permissions/prompter.ts +43 -3
- package/src/permissions/secret-prompter.ts +25 -48
- package/src/permissions/types.ts +33 -0
- package/src/permissions/workspace-policy.ts +0 -5
- package/src/platform/sync-identity.ts +0 -8
- package/src/plugins/defaults/injectors.ts +69 -2
- package/src/plugins/defaults/overflow-reduce.ts +3 -2
- package/src/plugins/types.ts +8 -0
- package/src/prompts/bootstrap-cleanup.ts +27 -0
- package/src/prompts/system-prompt.ts +37 -88
- package/src/prompts/templates/BOOTSTRAP.md +52 -6
- package/src/prompts/templates/SOUL.md +13 -1
- package/src/prompts/update-bulletin-job.ts +2 -0
- package/src/providers/__tests__/retry-callsite.test.ts +138 -1
- package/src/providers/anthropic/client.ts +72 -33
- package/src/providers/call-site-routing.ts +42 -3
- package/src/providers/gemini/client.ts +18 -2
- package/src/providers/managed-proxy/context.ts +0 -5
- package/src/providers/model-catalog.ts +105 -19
- package/src/providers/openai/chat-completions-provider.ts +6 -0
- package/src/providers/openai/responses-provider.ts +7 -1
- package/src/providers/provider-send-message.ts +45 -2
- package/src/providers/ratelimit.ts +7 -2
- package/src/providers/registry.ts +14 -9
- package/src/providers/retry.ts +96 -8
- package/src/providers/speech-to-text/provider-catalog.ts +7 -8
- package/src/providers/types.ts +13 -0
- package/src/providers/usage-tracking.ts +96 -0
- package/src/runtime/AGENTS.md +10 -6
- package/src/runtime/__tests__/agent-wake.test.ts +89 -0
- package/src/runtime/agent-wake.ts +39 -2
- package/src/runtime/assistant-event-hub.ts +570 -52
- package/src/runtime/assistant-event.ts +2 -6
- package/src/runtime/auth/__tests__/middleware.test.ts +11 -56
- package/src/runtime/auth/context.ts +0 -9
- package/src/runtime/auth/middleware.ts +1 -97
- package/src/runtime/auth/route-policy.ts +30 -9
- package/src/runtime/auth/token-service.ts +0 -11
- package/src/runtime/btw-sidechain.ts +2 -3
- package/src/runtime/channel-approvals.ts +6 -2
- package/src/runtime/channel-invite-transport.ts +2 -48
- package/src/runtime/channel-invite-transports/email.ts +1 -1
- package/src/runtime/channel-invite-transports/slack.ts +1 -1
- package/src/runtime/channel-invite-transports/telegram.ts +1 -1
- package/src/runtime/channel-invite-transports/voice.ts +1 -1
- package/src/runtime/channel-invite-transports/whatsapp.ts +1 -1
- package/src/runtime/channel-invite-types.ts +54 -0
- package/src/runtime/channel-readiness-service.ts +32 -13
- package/src/runtime/channel-verification-service.ts +3 -5
- package/src/runtime/http-errors.ts +0 -34
- package/src/runtime/http-router.ts +6 -3
- package/src/runtime/http-server.ts +16 -402
- package/src/runtime/http-types.ts +5 -5
- package/src/runtime/interactive-ui.ts +0 -1
- package/src/runtime/middleware/auth.ts +0 -20
- package/src/runtime/migrations/__tests__/v1-test-helpers.ts +112 -0
- package/src/runtime/migrations/__tests__/vbundle-builder-credentials.test.ts +11 -4
- package/src/runtime/migrations/__tests__/vbundle-builder-v1-shape.test.ts +253 -0
- package/src/runtime/migrations/__tests__/vbundle-import-credentials.test.ts +19 -6
- package/src/runtime/migrations/__tests__/vbundle-import-parity.test.ts +413 -0
- package/src/runtime/migrations/__tests__/vbundle-import-policy.test.ts +260 -0
- package/src/runtime/migrations/__tests__/vbundle-import-version-compat.test.ts +189 -0
- package/src/runtime/migrations/__tests__/vbundle-legacy-user-md.test.ts +71 -27
- package/src/runtime/migrations/__tests__/vbundle-metadata-merge-integration.test.ts +41 -2
- package/src/runtime/migrations/__tests__/vbundle-streaming-importer.test.ts +296 -80
- package/src/runtime/migrations/__tests__/vbundle-streaming-validator.test.ts +143 -23
- package/src/runtime/migrations/__tests__/vbundle-symlink-importer.test.ts +451 -0
- package/src/runtime/migrations/__tests__/vbundle-symlink-streaming-importer.test.ts +0 -0
- package/src/runtime/migrations/__tests__/vbundle-symlink-streaming.test.ts +515 -0
- package/src/runtime/migrations/__tests__/vbundle-symlink-tar.test.ts +437 -0
- package/src/runtime/migrations/__tests__/vbundle-symlink-walker.test.ts +319 -0
- package/src/runtime/migrations/__tests__/vbundle-tar-stream.test.ts +2 -2
- package/src/runtime/migrations/__tests__/vbundle-validator-v1-schema.test.ts +421 -0
- package/src/runtime/migrations/migration-transport.ts +49 -16
- package/src/runtime/migrations/migration-wizard.ts +2 -2
- package/src/runtime/migrations/origin-mode.ts +40 -0
- package/src/runtime/migrations/vbundle-builder.ts +457 -136
- package/src/runtime/migrations/vbundle-import-analyzer.ts +13 -11
- package/src/runtime/migrations/vbundle-import-policy.ts +172 -0
- package/src/runtime/migrations/vbundle-importer.ts +251 -74
- package/src/runtime/migrations/vbundle-metadata-merge.ts +1 -1
- package/src/runtime/migrations/vbundle-streaming-importer.ts +329 -38
- package/src/runtime/migrations/vbundle-streaming-validator.ts +203 -28
- package/src/runtime/migrations/vbundle-tar-stream.ts +15 -6
- package/src/runtime/migrations/vbundle-validator.ts +328 -41
- package/src/runtime/pending-interactions.ts +48 -13
- package/src/runtime/routes/__tests__/acp-routes.test.ts +0 -1
- package/src/runtime/routes/__tests__/backup-routes.test.ts +49 -168
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +333 -0
- package/src/runtime/routes/__tests__/gateway-log-routes.test.ts +242 -0
- package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +112 -0
- package/src/runtime/routes/__tests__/llm-call-sites-routes.test.ts +58 -0
- package/src/runtime/routes/__tests__/migration-export-secrets-redacted.test.ts +54 -0
- package/src/runtime/routes/__tests__/migration-import-credential-filter.test.ts +19 -6
- package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +7 -7
- package/src/runtime/routes/acp-routes.test.ts +0 -3
- package/src/runtime/routes/acp-routes.ts +3 -7
- package/src/runtime/routes/app-management-routes.ts +18 -9
- package/src/runtime/routes/approval-interception-types.ts +13 -0
- package/src/runtime/routes/approval-routes.ts +55 -14
- package/src/runtime/routes/approval-strategies/guardian-text-engine-strategy.ts +1 -1
- package/src/runtime/routes/avatar-routes.ts +3 -5
- package/src/runtime/routes/backup-routes.ts +15 -38
- package/src/runtime/routes/browser-routes.ts +1 -15
- package/src/runtime/routes/btw-routes.ts +14 -37
- package/src/runtime/routes/channel-guardian-routes.ts +1 -5
- package/src/runtime/routes/channel-readiness-routes.ts +3 -7
- package/src/runtime/routes/channel-route-shared.ts +2 -28
- package/src/runtime/routes/client-routes.ts +46 -12
- package/src/runtime/routes/consolidation-routes.ts +115 -0
- package/src/runtime/routes/contact-prompt-routes.ts +183 -0
- package/src/runtime/routes/conversation-list-routes.ts +12 -29
- package/src/runtime/routes/conversation-management-routes.ts +14 -51
- package/src/runtime/routes/conversation-query-routes.ts +156 -9
- package/src/runtime/routes/conversation-routes.ts +72 -539
- package/src/runtime/routes/conversation-starter-routes.ts +19 -40
- package/src/runtime/routes/document-pdf-renderer.ts +165 -0
- package/src/runtime/routes/documents-routes.ts +83 -18
- package/src/runtime/routes/errors.ts +19 -4
- package/src/runtime/routes/events-routes.ts +68 -94
- package/src/runtime/routes/filing-routes.ts +18 -1
- package/src/runtime/routes/gateway-log-routes.ts +79 -0
- package/src/runtime/routes/guardian-action-routes.ts +4 -9
- package/src/runtime/routes/guardian-approval-interception.ts +2 -8
- package/src/runtime/routes/heartbeat-routes.ts +103 -38
- package/src/runtime/routes/host-app-control-routes.ts +134 -0
- package/src/runtime/routes/host-bash-routes.ts +37 -6
- package/src/runtime/routes/host-browser-routes.ts +96 -25
- package/src/runtime/routes/host-cu-routes.ts +48 -13
- package/src/runtime/routes/host-file-routes.ts +35 -11
- package/src/runtime/routes/host-transfer-routes.ts +73 -37
- package/src/runtime/routes/http-adapter.ts +1 -0
- package/src/runtime/routes/identity-intro-cache.ts +30 -0
- package/src/runtime/routes/identity-routes.ts +93 -49
- package/src/runtime/routes/inbound-message-handler.ts +581 -146
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +2 -95
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +3 -0
- package/src/runtime/routes/inbound-stages/edit-intercept.ts +0 -8
- package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +0 -20
- package/src/runtime/routes/inbound-stages/transcribe-audio.ts +5 -13
- package/src/runtime/routes/index.ts +12 -0
- package/src/runtime/routes/integrations/slack/channel.ts +0 -24
- package/src/runtime/routes/llm-call-sites-routes.ts +22 -0
- package/src/runtime/routes/mcp-auth-routes.ts +132 -0
- package/src/runtime/routes/memory-item-routes.ts +10 -12
- package/src/runtime/routes/memory-v2-routes.ts +451 -16
- package/src/runtime/routes/migration-routes.ts +284 -31
- package/src/runtime/routes/playground/guard.ts +1 -1
- package/src/runtime/routes/playground/index.ts +0 -2
- package/src/runtime/routes/recording-routes.ts +4 -24
- package/src/runtime/routes/rename-conversation-routes.ts +2 -6
- package/src/runtime/routes/schedule-routes.ts +10 -6
- package/src/runtime/routes/secret-routes.ts +87 -18
- package/src/runtime/routes/settings-routes.ts +29 -28
- package/src/runtime/routes/skills-routes.ts +12 -31
- package/src/runtime/routes/suggest-trust-rule-routes.ts +32 -1
- package/src/runtime/routes/task-routes.ts +6 -6
- package/src/runtime/routes/trust-rules-routes.ts +3 -94
- package/src/runtime/routes/types.ts +4 -4
- package/src/runtime/routes/upgrade-broadcast-routes.ts +3 -10
- package/src/runtime/routes/usage-routes.ts +87 -10
- package/src/runtime/routes/user-routes.ts +17 -31
- package/src/runtime/routes/work-items-routes.ts +1 -4
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +2 -2
- package/src/runtime/services/analyze-conversation.ts +7 -17
- package/src/runtime/services/conversation-serializer.ts +2 -4
- package/src/runtime/verification-outbound-actions.ts +1 -1
- package/src/runtime/verification-rate-limiter.ts +1 -1
- package/src/runtime/verification-templates.ts +4 -7
- package/src/schedule/integration-status.ts +66 -2
- package/src/schedule/recurrence-engine.ts +4 -1
- package/src/schedule/retry-backoff.ts +18 -0
- package/src/schedule/retry-policy.ts +82 -0
- package/src/schedule/schedule-recovery.ts +64 -0
- package/src/schedule/schedule-store.ts +106 -18
- package/src/schedule/scheduler-types.ts +25 -0
- package/src/schedule/scheduler.ts +63 -38
- package/src/security/oauth-callback-registry.ts +8 -0
- package/src/security/secret-scanner.ts +14 -547
- package/src/security/secure-keys.ts +31 -11
- package/src/security/token-manager.ts +7 -3
- package/src/sequence/analytics.ts +5 -5
- package/src/sequence/engine.ts +1 -1
- package/src/signals/cancel.ts +16 -25
- package/src/signals/conversation-undo.ts +2 -27
- package/src/signals/emit-event.ts +1 -2
- package/src/signals/user-message.ts +108 -22
- package/src/skills/catalog-files.ts +2 -8
- package/src/skills/catalog-install.ts +1 -0
- package/src/skills/clawhub.ts +2 -2
- package/src/skills/include-graph.ts +5 -5
- package/src/skills/inline-command-runner.ts +1 -7
- package/src/skills/remote-skill-policy.ts +5 -5
- package/src/skills/skill-file-provider.ts +1 -1
- package/src/skills/skill-file-types.ts +13 -0
- package/src/skills/skillssh-audit-types.ts +28 -0
- package/src/skills/skillssh-registry.ts +8 -21
- package/src/subagent/manager.ts +67 -84
- package/src/tasks/task-store.ts +1 -28
- package/src/telemetry/types.ts +8 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +59 -15
- package/src/telemetry/usage-telemetry-reporter.ts +4 -5
- package/src/tools/acp/spawn.test.ts +1 -2
- package/src/tools/acp/steer.test.ts +1 -2
- package/src/tools/app-control/skill-proxy-bridge.ts +28 -0
- package/src/tools/apps/executors.ts +56 -69
- package/src/tools/browser/__tests__/browser-status.test.ts +55 -135
- package/src/tools/browser/browser-execution.ts +31 -147
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +145 -70
- package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +12 -6
- package/src/tools/browser/cdp-client/factory.ts +62 -91
- package/src/tools/browser/cdp-client/index.ts +1 -27
- package/src/tools/computer-use/definitions.ts +42 -20
- package/src/tools/executor.ts +46 -31
- package/src/tools/host-filesystem/edit.ts +29 -2
- package/src/tools/host-filesystem/read.ts +29 -2
- package/src/tools/host-filesystem/transfer.test.ts +45 -42
- package/src/tools/host-filesystem/transfer.ts +35 -4
- package/src/tools/host-filesystem/write.ts +29 -2
- package/src/tools/host-terminal/host-shell.ts +62 -3
- package/src/tools/network/script-proxy/index.ts +1 -10
- package/src/tools/permission-checker.ts +66 -1
- package/src/tools/schedule/create.ts +6 -0
- package/src/tools/schedule/list.ts +2 -0
- package/src/tools/schedule/update.ts +10 -0
- package/src/tools/shared/filesystem/file-ops-service.ts +2 -0
- package/src/tools/shared/filesystem/path-policy.ts +25 -1
- package/src/tools/skills/load.ts +0 -32
- package/src/tools/skills/sandbox-runner.ts +1 -6
- package/src/tools/skills/skill-tool-factory.ts +32 -0
- package/src/tools/terminal/safe-env.ts +1 -0
- package/src/tools/terminal/shell.ts +2 -78
- package/src/tools/tool-approval-handler.ts +1 -5
- package/src/tools/types.ts +16 -39
- package/src/tts/__tests__/provider-catalog.test.ts +2 -2
- package/src/tts/provider-catalog.ts +1 -1
- package/src/usage/actors.ts +2 -1
- package/src/usage/attribution.ts +185 -0
- package/src/usage/pricing.ts +166 -0
- package/src/usage/types.ts +14 -0
- package/src/util/json.ts +13 -0
- package/src/util/logger.ts +3 -3
- package/src/util/pricing.ts +50 -3
- package/src/work-items/work-item-runner.ts +15 -42
- package/src/workspace/hatched-date.ts +86 -0
- package/src/workspace/migrations/003-seed-device-id.ts +1 -1
- package/src/workspace/migrations/006-services-config.ts +8 -5
- package/src/workspace/migrations/016-extract-feature-flags-to-protected.ts +3 -9
- package/src/workspace/migrations/021-move-signals-to-workspace.ts +4 -10
- package/src/workspace/migrations/022-move-hooks-to-workspace.ts +4 -10
- package/src/workspace/migrations/023-move-config-files-to-workspace.ts +4 -11
- package/src/workspace/migrations/024-move-runtime-files-to-workspace.ts +3 -10
- package/src/workspace/migrations/040-seed-latency-callsite-defaults.ts +3 -2
- package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +6 -4
- package/src/workspace/migrations/052-seed-default-inference-profiles.ts +3 -3
- package/src/workspace/migrations/059-move-pid-to-workspace.ts +3 -8
- package/src/workspace/migrations/060-memory-v2-init.ts +2 -18
- package/src/workspace/migrations/061-move-backup-key-to-workspace.ts +54 -0
- package/src/workspace/migrations/062-drop-memory-v2-edges-json.ts +27 -0
- package/src/workspace/migrations/063-release-notes-dynamic-model-context.ts +70 -0
- package/src/workspace/migrations/064-unwind-main-agent-opus-seed.ts +64 -0
- package/src/workspace/migrations/AGENTS.md +1 -1
- package/src/workspace/migrations/migrate-to-workspace-volume.ts +4 -10
- package/src/workspace/migrations/registry.ts +8 -0
- package/src/workspace/migrations/utils.ts +21 -0
- package/src/workspace/provider-commit-message-generator.ts +3 -3
- package/src/__tests__/host-browser-e2e-cloud.test.ts +0 -904
- package/src/__tests__/host-browser-e2e-self-hosted-capability.test.ts +0 -296
- package/src/__tests__/host-browser-ws-events-e2e.test.ts +0 -431
- package/src/__tests__/sandbox-diagnostics.test.ts +0 -138
- package/src/__tests__/sandbox-host-parity.test.ts +0 -1024
- package/src/__tests__/secret-detection-handler.test.ts +0 -67
- package/src/__tests__/secret-scanner-executor.test.ts +0 -450
- package/src/__tests__/tcc-sandbox-deny.test.ts +0 -198
- package/src/__tests__/terminal-sandbox.test.ts +0 -374
- package/src/__tests__/tool-notification-listener.test.ts +0 -65
- package/src/__tests__/twilio-rest.test.ts +0 -34
- package/src/backup/__tests__/backup-key.test.ts +0 -152
- package/src/backup/__tests__/backup-worker.test.ts +0 -754
- package/src/backup/__tests__/offsite-writer.test.ts +0 -641
- package/src/backup/__tests__/stream-crypt.test.ts +0 -228
- package/src/backup/backup-key.ts +0 -137
- package/src/backup/backup-worker.ts +0 -438
- package/src/backup/offsite-writer.ts +0 -222
- package/src/backup/stream-crypt.ts +0 -263
- package/src/context/__tests__/microcompact.test.ts +0 -805
- package/src/context/microcompact.ts +0 -443
- package/src/daemon/handlers/slack-channel-oauth-install.ts +0 -197
- package/src/daemon/message-types/pairing.ts +0 -58
- package/src/events/tool-notification-listener.ts +0 -17
- package/src/ipc/routes/__tests__/memory-v2-validate.test.ts +0 -219
- package/src/memory/v2/__tests__/edges.test.ts +0 -435
- package/src/memory/v2/edges.ts +0 -217
- package/src/outbound-proxy/config.ts +0 -94
- package/src/outbound-proxy/health.ts +0 -62
- package/src/outbound-proxy/types.ts +0 -150
- package/src/prompts/__tests__/system-prompt-memory-v2.test.ts +0 -197
- package/src/runtime/__tests__/chrome-extension-registry.test.ts +0 -518
- package/src/runtime/__tests__/client-registry.test.ts +0 -271
- package/src/runtime/capability-tokens.ts +0 -190
- package/src/runtime/chrome-extension-registry.ts +0 -368
- package/src/runtime/client-registry.ts +0 -254
- package/src/runtime/routes/inbound-stages/verification-intercept.ts +0 -329
- package/src/signals/mcp-reload.ts +0 -18
- package/src/tools/secret-detection-handler.ts +0 -269
- package/src/tools/terminal/backends/native.ts +0 -327
- package/src/tools/terminal/backends/types.ts +0 -37
- package/src/tools/terminal/sandbox-diagnostics.ts +0 -87
- package/src/tools/terminal/sandbox.ts +0 -40
|
@@ -31,6 +31,7 @@ import {
|
|
|
31
31
|
getConfiguredProvider,
|
|
32
32
|
userMessage,
|
|
33
33
|
} from "../../providers/provider-send-message.js";
|
|
34
|
+
import { broadcastMessage } from "../../runtime/assistant-event-hub.js";
|
|
34
35
|
import {
|
|
35
36
|
isTextMimeType as isTextMime,
|
|
36
37
|
MAX_INLINE_TEXT_SIZE,
|
|
@@ -50,7 +51,6 @@ import {
|
|
|
50
51
|
upsertSkillsIndex,
|
|
51
52
|
} from "../../skills/catalog-install.js";
|
|
52
53
|
import { filterByQuery } from "../../skills/catalog-search.js";
|
|
53
|
-
import type { SkillCategory } from "../../skills/category-inference.js";
|
|
54
54
|
import { inferCategory } from "../../skills/category-inference.js";
|
|
55
55
|
import {
|
|
56
56
|
clawhubCheckUpdates,
|
|
@@ -81,36 +81,14 @@ import {
|
|
|
81
81
|
type SkillAuditData,
|
|
82
82
|
} from "../../skills/skillssh-registry.js";
|
|
83
83
|
import { getWorkspaceSkillsDir } from "../../util/platform.js";
|
|
84
|
+
import { getConfigWatcher } from "../config-watcher.js";
|
|
84
85
|
import { maybeSeedMemoryV2Skills } from "../memory-v2-startup.js";
|
|
85
86
|
import type {
|
|
86
87
|
SkillDetailResponse,
|
|
87
88
|
SkillFileContentResponse,
|
|
88
89
|
SlimSkillResponse,
|
|
89
90
|
} from "../message-types/skills.js";
|
|
90
|
-
|
|
91
|
-
// Re-export for use by route layer and future consumers.
|
|
92
|
-
export type { SkillCategory };
|
|
93
|
-
export { inferCategory };
|
|
94
|
-
import {
|
|
95
|
-
CONFIG_RELOAD_DEBOUNCE_MS,
|
|
96
|
-
ensureSkillEntry,
|
|
97
|
-
type HandlerContext,
|
|
98
|
-
log,
|
|
99
|
-
} from "./shared.js";
|
|
100
|
-
|
|
101
|
-
// ─── Shared context for standalone functions ─────────────────────────────────
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Minimal context needed by the standalone skill business-logic functions.
|
|
105
|
-
* HandlerContext satisfies this interface, but HTTP routes can also provide
|
|
106
|
-
* a compatible object without coupling to handler internals.
|
|
107
|
-
*/
|
|
108
|
-
export interface SkillOperationContext {
|
|
109
|
-
debounceTimers: HandlerContext["debounceTimers"];
|
|
110
|
-
setSuppressConfigReload(value: boolean): void;
|
|
111
|
-
updateConfigFingerprint(): void;
|
|
112
|
-
broadcast: HandlerContext["broadcast"];
|
|
113
|
-
}
|
|
91
|
+
import { CONFIG_RELOAD_DEBOUNCE_MS, ensureSkillEntry, log } from "./shared.js";
|
|
114
92
|
|
|
115
93
|
// ─── Provider chain for uninstalled skill file preview ───────────────────────
|
|
116
94
|
// Ordered by priority: vellum first (most common and cheapest to check),
|
|
@@ -258,28 +236,25 @@ const LLM_DRAFT_TIMEOUT_MS = 15_000;
|
|
|
258
236
|
// These are consumed by both the handlers below and the HTTP route layer.
|
|
259
237
|
|
|
260
238
|
/** Helper: suppress config reload, save, debounce, and update fingerprint. */
|
|
261
|
-
function saveConfigWithSuppression(
|
|
262
|
-
|
|
263
|
-
ctx: SkillOperationContext,
|
|
264
|
-
): void {
|
|
265
|
-
ctx.setSuppressConfigReload(true);
|
|
239
|
+
function saveConfigWithSuppression(raw: Record<string, unknown>): void {
|
|
240
|
+
getConfigWatcher().suppressConfigReload = true;
|
|
266
241
|
try {
|
|
267
242
|
saveRawConfig(raw);
|
|
268
243
|
} catch (err) {
|
|
269
|
-
|
|
244
|
+
getConfigWatcher().suppressConfigReload = false;
|
|
270
245
|
throw err;
|
|
271
246
|
}
|
|
272
247
|
invalidateConfigCache();
|
|
273
248
|
|
|
274
|
-
|
|
249
|
+
getConfigWatcher().timers.schedule(
|
|
275
250
|
"__suppress_reset__",
|
|
276
251
|
() => {
|
|
277
|
-
|
|
252
|
+
getConfigWatcher().suppressConfigReload = false;
|
|
278
253
|
},
|
|
279
254
|
CONFIG_RELOAD_DEBOUNCE_MS,
|
|
280
255
|
);
|
|
281
256
|
|
|
282
|
-
|
|
257
|
+
getConfigWatcher().updateFingerprint();
|
|
283
258
|
}
|
|
284
259
|
|
|
285
260
|
/**
|
|
@@ -296,11 +271,7 @@ function saveConfigWithSuppression(
|
|
|
296
271
|
* NOT used for bundled skills — those have a simpler inline path in
|
|
297
272
|
* `installSkill()` that only auto-enables, broadcasts, and seeds memories.
|
|
298
273
|
*/
|
|
299
|
-
function postInstallSkill(
|
|
300
|
-
skillId: string,
|
|
301
|
-
_skillDir: string,
|
|
302
|
-
ctx: SkillOperationContext,
|
|
303
|
-
): void {
|
|
274
|
+
function postInstallSkill(skillId: string, _skillDir: string): void {
|
|
304
275
|
// Reload skill catalog so the newly installed skill is picked up
|
|
305
276
|
loadSkillCatalog();
|
|
306
277
|
|
|
@@ -308,8 +279,8 @@ function postInstallSkill(
|
|
|
308
279
|
try {
|
|
309
280
|
const raw = loadRawConfig();
|
|
310
281
|
ensureSkillEntry(raw, skillId).enabled = true;
|
|
311
|
-
saveConfigWithSuppression(raw
|
|
312
|
-
|
|
282
|
+
saveConfigWithSuppression(raw);
|
|
283
|
+
broadcastMessage({
|
|
313
284
|
type: "skills_state_changed",
|
|
314
285
|
name: skillId,
|
|
315
286
|
state: "enabled",
|
|
@@ -413,7 +384,7 @@ function toSlimSkillResponse(
|
|
|
413
384
|
}
|
|
414
385
|
}
|
|
415
386
|
|
|
416
|
-
export function listSkills(
|
|
387
|
+
export function listSkills(): SlimSkillResponse[] {
|
|
417
388
|
const config = getConfig();
|
|
418
389
|
const catalog = loadSkillCatalog();
|
|
419
390
|
const resolved = resolveSkillStates(catalog, config);
|
|
@@ -431,10 +402,8 @@ export function listSkills(_ctx: SkillOperationContext): SlimSkillResponse[] {
|
|
|
431
402
|
* List installed skills merged with available catalog skills.
|
|
432
403
|
* Installed skills take precedence when deduplicating by ID.
|
|
433
404
|
*/
|
|
434
|
-
async function listSkillsWithCatalog(
|
|
435
|
-
|
|
436
|
-
): Promise<SlimSkillResponse[]> {
|
|
437
|
-
const installed = listSkills(ctx);
|
|
405
|
+
async function listSkillsWithCatalog(): Promise<SlimSkillResponse[]> {
|
|
406
|
+
const installed = listSkills();
|
|
438
407
|
const installedIds = new Set(installed.map((s) => s.id));
|
|
439
408
|
|
|
440
409
|
let catalogSkills: CatalogSkill[];
|
|
@@ -503,18 +472,15 @@ function originMatchesQuery(origin: string, query: string): boolean {
|
|
|
503
472
|
* List skills with filtering, category counts, and sorting.
|
|
504
473
|
* Calls listSkillsWithCatalog for the full merged list, then applies filters.
|
|
505
474
|
*/
|
|
506
|
-
export async function listSkillsFiltered(
|
|
507
|
-
filter: SkillListFilter,
|
|
508
|
-
ctx: SkillOperationContext,
|
|
509
|
-
): Promise<{
|
|
475
|
+
export async function listSkillsFiltered(filter: SkillListFilter): Promise<{
|
|
510
476
|
skills: SlimSkillResponse[];
|
|
511
477
|
categoryCounts: Record<string, number>;
|
|
512
478
|
totalCount: number;
|
|
513
479
|
}> {
|
|
514
480
|
let skills =
|
|
515
481
|
filter.includeCatalog !== false
|
|
516
|
-
? await listSkillsWithCatalog(
|
|
517
|
-
: listSkills(
|
|
482
|
+
? await listSkillsWithCatalog()
|
|
483
|
+
: listSkills();
|
|
518
484
|
|
|
519
485
|
// Apply origin filter
|
|
520
486
|
if (filter.origin) {
|
|
@@ -608,7 +574,6 @@ function findSkillById(
|
|
|
608
574
|
|
|
609
575
|
export async function getSkill(
|
|
610
576
|
skillId: string,
|
|
611
|
-
_ctx: SkillOperationContext,
|
|
612
577
|
): Promise<{ skill: SkillDetailResponse } | { error: string; status: number }> {
|
|
613
578
|
const found = findSkillById(skillId);
|
|
614
579
|
if (!found) {
|
|
@@ -812,7 +777,6 @@ function readDirRecursive(dir: string, rootDir: string): SkillFileEntry[] {
|
|
|
812
777
|
export async function getSkillFileContent(
|
|
813
778
|
skillId: string,
|
|
814
779
|
relativePath: string,
|
|
815
|
-
_ctx: SkillOperationContext,
|
|
816
780
|
): Promise<SkillFileContentResponse | { error: string; status: number }> {
|
|
817
781
|
const sanitized = sanitizeRelativePath(relativePath);
|
|
818
782
|
if (!sanitized) {
|
|
@@ -935,7 +899,6 @@ export async function getSkillFileContent(
|
|
|
935
899
|
|
|
936
900
|
export async function getSkillFiles(
|
|
937
901
|
skillId: string,
|
|
938
|
-
_ctx: SkillOperationContext,
|
|
939
902
|
): Promise<
|
|
940
903
|
| { skill: SlimSkillResponse; files: SkillFileEntry[] }
|
|
941
904
|
| { error: string; status: number }
|
|
@@ -976,13 +939,12 @@ export async function getSkillFiles(
|
|
|
976
939
|
|
|
977
940
|
export function enableSkill(
|
|
978
941
|
skillId: string,
|
|
979
|
-
ctx: SkillOperationContext,
|
|
980
942
|
): { success: true } | { success: false; error: string } {
|
|
981
943
|
try {
|
|
982
944
|
const raw = loadRawConfig();
|
|
983
945
|
ensureSkillEntry(raw, skillId).enabled = true;
|
|
984
|
-
saveConfigWithSuppression(raw
|
|
985
|
-
|
|
946
|
+
saveConfigWithSuppression(raw);
|
|
947
|
+
broadcastMessage({
|
|
986
948
|
type: "skills_state_changed",
|
|
987
949
|
name: skillId,
|
|
988
950
|
state: "enabled",
|
|
@@ -1000,13 +962,12 @@ export function enableSkill(
|
|
|
1000
962
|
|
|
1001
963
|
export function disableSkill(
|
|
1002
964
|
skillId: string,
|
|
1003
|
-
ctx: SkillOperationContext,
|
|
1004
965
|
): { success: true } | { success: false; error: string } {
|
|
1005
966
|
try {
|
|
1006
967
|
const raw = loadRawConfig();
|
|
1007
968
|
ensureSkillEntry(raw, skillId).enabled = false;
|
|
1008
|
-
saveConfigWithSuppression(raw
|
|
1009
|
-
|
|
969
|
+
saveConfigWithSuppression(raw);
|
|
970
|
+
broadcastMessage({
|
|
1010
971
|
type: "skills_state_changed",
|
|
1011
972
|
name: skillId,
|
|
1012
973
|
state: "disabled",
|
|
@@ -1029,7 +990,6 @@ export function configureSkill(
|
|
|
1029
990
|
apiKey?: string;
|
|
1030
991
|
config?: Record<string, unknown>;
|
|
1031
992
|
},
|
|
1032
|
-
ctx: SkillOperationContext,
|
|
1033
993
|
): { success: true } | { success: false; error: string } {
|
|
1034
994
|
try {
|
|
1035
995
|
const raw = loadRawConfig();
|
|
@@ -1037,7 +997,7 @@ export function configureSkill(
|
|
|
1037
997
|
if (config.env) entry.env = config.env;
|
|
1038
998
|
if (config.apiKey !== undefined) entry.apiKey = config.apiKey;
|
|
1039
999
|
if (config.config) entry.config = config.config;
|
|
1040
|
-
saveConfigWithSuppression(raw
|
|
1000
|
+
saveConfigWithSuppression(raw);
|
|
1041
1001
|
return { success: true };
|
|
1042
1002
|
} catch (err) {
|
|
1043
1003
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -1054,15 +1014,12 @@ function looksLikeSkillsShSlug(slug: string): boolean {
|
|
|
1054
1014
|
return slug.split("/").length >= 3;
|
|
1055
1015
|
}
|
|
1056
1016
|
|
|
1057
|
-
export async function installSkill(
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
},
|
|
1064
|
-
ctx: SkillOperationContext,
|
|
1065
|
-
): Promise<
|
|
1017
|
+
export async function installSkill(spec: {
|
|
1018
|
+
slug: string;
|
|
1019
|
+
version?: string;
|
|
1020
|
+
origin?: "clawhub" | "skillssh";
|
|
1021
|
+
contactId?: string;
|
|
1022
|
+
}): Promise<
|
|
1066
1023
|
{ success: true; skillId: string } | { success: false; error: string }
|
|
1067
1024
|
> {
|
|
1068
1025
|
try {
|
|
@@ -1095,8 +1052,8 @@ export async function installSkill(
|
|
|
1095
1052
|
try {
|
|
1096
1053
|
const raw = loadRawConfig();
|
|
1097
1054
|
ensureSkillEntry(raw, spec.slug).enabled = true;
|
|
1098
|
-
saveConfigWithSuppression(raw
|
|
1099
|
-
|
|
1055
|
+
saveConfigWithSuppression(raw);
|
|
1056
|
+
broadcastMessage({
|
|
1100
1057
|
type: "skills_state_changed",
|
|
1101
1058
|
name: spec.slug,
|
|
1102
1059
|
state: "enabled",
|
|
@@ -1130,7 +1087,7 @@ export async function installSkill(
|
|
|
1130
1087
|
);
|
|
1131
1088
|
|
|
1132
1089
|
const skillDir = join(getWorkspaceSkillsDir(), spec.slug);
|
|
1133
|
-
postInstallSkill(spec.slug, skillDir
|
|
1090
|
+
postInstallSkill(spec.slug, skillDir);
|
|
1134
1091
|
return { success: true, skillId: spec.slug };
|
|
1135
1092
|
}
|
|
1136
1093
|
} catch (err) {
|
|
@@ -1158,7 +1115,7 @@ export async function installSkill(
|
|
|
1158
1115
|
);
|
|
1159
1116
|
|
|
1160
1117
|
const skillDir = join(getWorkspaceSkillsDir(), resolved.skillSlug);
|
|
1161
|
-
postInstallSkill(resolved.skillSlug, skillDir
|
|
1118
|
+
postInstallSkill(resolved.skillSlug, skillDir);
|
|
1162
1119
|
return { success: true, skillId: resolved.skillSlug };
|
|
1163
1120
|
}
|
|
1164
1121
|
|
|
@@ -1186,7 +1143,7 @@ export async function installSkill(
|
|
|
1186
1143
|
}
|
|
1187
1144
|
upsertSkillsIndex(skillId);
|
|
1188
1145
|
|
|
1189
|
-
postInstallSkill(skillId, skillDir
|
|
1146
|
+
postInstallSkill(skillId, skillDir);
|
|
1190
1147
|
return { success: true, skillId };
|
|
1191
1148
|
} catch (err) {
|
|
1192
1149
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -1197,7 +1154,6 @@ export async function installSkill(
|
|
|
1197
1154
|
|
|
1198
1155
|
export async function uninstallSkill(
|
|
1199
1156
|
skillId: string,
|
|
1200
|
-
ctx: SkillOperationContext,
|
|
1201
1157
|
): Promise<{ success: true } | { success: false; error: string }> {
|
|
1202
1158
|
// Validate skill name to prevent path traversal while allowing namespaced slugs (org/name)
|
|
1203
1159
|
const validNamespacedSlug =
|
|
@@ -1245,10 +1201,10 @@ export async function uninstallSkill(
|
|
|
1245
1201
|
const entries = skills?.entries as Record<string, unknown> | undefined;
|
|
1246
1202
|
if (entries?.[skillId]) {
|
|
1247
1203
|
delete entries[skillId];
|
|
1248
|
-
saveConfigWithSuppression(raw
|
|
1204
|
+
saveConfigWithSuppression(raw);
|
|
1249
1205
|
}
|
|
1250
1206
|
|
|
1251
|
-
|
|
1207
|
+
broadcastMessage({
|
|
1252
1208
|
type: "skills_state_changed",
|
|
1253
1209
|
name: skillId,
|
|
1254
1210
|
state: "uninstalled",
|
|
@@ -1264,7 +1220,6 @@ export async function uninstallSkill(
|
|
|
1264
1220
|
|
|
1265
1221
|
export async function updateSkill(
|
|
1266
1222
|
skillId: string,
|
|
1267
|
-
_ctx: SkillOperationContext,
|
|
1268
1223
|
): Promise<{ success: true } | { success: false; error: string }> {
|
|
1269
1224
|
try {
|
|
1270
1225
|
const result = await clawhubUpdate(skillId);
|
|
@@ -1281,9 +1236,7 @@ export async function updateSkill(
|
|
|
1281
1236
|
}
|
|
1282
1237
|
}
|
|
1283
1238
|
|
|
1284
|
-
export async function checkSkillUpdates(
|
|
1285
|
-
_ctx: SkillOperationContext,
|
|
1286
|
-
): Promise<
|
|
1239
|
+
export async function checkSkillUpdates(): Promise<
|
|
1287
1240
|
{ success: true; data: unknown } | { success: false; error: string }
|
|
1288
1241
|
> {
|
|
1289
1242
|
try {
|
|
@@ -1298,7 +1251,6 @@ export async function checkSkillUpdates(
|
|
|
1298
1251
|
|
|
1299
1252
|
export async function searchSkills(
|
|
1300
1253
|
query: string,
|
|
1301
|
-
_ctx: SkillOperationContext,
|
|
1302
1254
|
): Promise<
|
|
1303
1255
|
| { success: true; skills: SlimSkillResponse[] }
|
|
1304
1256
|
| { success: false; error: string }
|
|
@@ -1461,7 +1413,6 @@ export async function searchSkills(
|
|
|
1461
1413
|
|
|
1462
1414
|
export async function inspectSkill(
|
|
1463
1415
|
skillId: string,
|
|
1464
|
-
_ctx: SkillOperationContext,
|
|
1465
1416
|
): Promise<{ slug: string; data?: ClawhubInspectResult; error?: string }> {
|
|
1466
1417
|
try {
|
|
1467
1418
|
const result = await clawhubInspect(skillId);
|
|
@@ -1490,10 +1441,9 @@ export interface DraftResult {
|
|
|
1490
1441
|
error?: string;
|
|
1491
1442
|
}
|
|
1492
1443
|
|
|
1493
|
-
export async function draftSkill(
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
): Promise<DraftResult> {
|
|
1444
|
+
export async function draftSkill(params: {
|
|
1445
|
+
sourceText: string;
|
|
1446
|
+
}): Promise<DraftResult> {
|
|
1497
1447
|
try {
|
|
1498
1448
|
const warnings: string[] = [];
|
|
1499
1449
|
const parsed = parseFrontmatter(params.sourceText);
|
|
@@ -1645,7 +1595,6 @@ export interface CreateSkillParams {
|
|
|
1645
1595
|
|
|
1646
1596
|
export async function createSkill(
|
|
1647
1597
|
params: CreateSkillParams,
|
|
1648
|
-
ctx: SkillOperationContext,
|
|
1649
1598
|
): Promise<{ success: true } | { success: false; error: string }> {
|
|
1650
1599
|
try {
|
|
1651
1600
|
const result = createManagedSkill({
|
|
@@ -1669,8 +1618,8 @@ export async function createSkill(
|
|
|
1669
1618
|
try {
|
|
1670
1619
|
const raw = loadRawConfig();
|
|
1671
1620
|
ensureSkillEntry(raw, params.skillId).enabled = true;
|
|
1672
|
-
saveConfigWithSuppression(raw
|
|
1673
|
-
|
|
1621
|
+
saveConfigWithSuppression(raw);
|
|
1622
|
+
broadcastMessage({
|
|
1674
1623
|
type: "skills_state_changed",
|
|
1675
1624
|
name: params.skillId,
|
|
1676
1625
|
state: "enabled",
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Host app-control proxy.
|
|
3
|
+
*
|
|
4
|
+
* Proxies app-control actions (start, observe, press, combo, type, click,
|
|
5
|
+
* drag, stop) to the desktop client. Targets a specific application by
|
|
6
|
+
* bundle ID or process name — distinct from the system-wide computer-use
|
|
7
|
+
* proxy ({@link HostCuProxy}).
|
|
8
|
+
*
|
|
9
|
+
* Lifecycle (pending map, timeout, abort SSE, dispose, isAvailable) lives
|
|
10
|
+
* in {@link HostProxyBase}; this class layers app-control-specific state
|
|
11
|
+
* (PNG-hash loop guard) and the result-payload → ToolExecutionResult
|
|
12
|
+
* translation on top.
|
|
13
|
+
*
|
|
14
|
+
* **Singleton lock.** Only one conversation may hold an active app-control
|
|
15
|
+
* session at a time. The lock is module-level (`activeAppControlConversationId`)
|
|
16
|
+
* because a session targets the user's actual desktop application, which
|
|
17
|
+
* is a host-wide resource. The lock is acquired on a successful
|
|
18
|
+
* `app_control_start` and released when the owning proxy's `dispose()`
|
|
19
|
+
* fires. A second conversation that calls `start` while the lock is held
|
|
20
|
+
* receives an `isError: true` tool result naming the holding conversation.
|
|
21
|
+
*
|
|
22
|
+
* **No step cap.** Unlike {@link HostCuProxy} which enforces a per-session
|
|
23
|
+
* step ceiling via `loadConfig().maxStepsPerSession`, app-control sessions
|
|
24
|
+
* are not capped. App-control flows are typically narrower (single-app,
|
|
25
|
+
* shorter horizons) and the loop guard plus user oversight are the
|
|
26
|
+
* intended safeguards.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
import { createHash } from "node:crypto";
|
|
30
|
+
|
|
31
|
+
import type { ContentBlock } from "../providers/types.js";
|
|
32
|
+
import type { ToolExecutionResult } from "../tools/types.js";
|
|
33
|
+
import { getLogger } from "../util/logger.js";
|
|
34
|
+
import { HostProxyBase, HostProxyRequestError } from "./host-proxy-base.js";
|
|
35
|
+
import type {
|
|
36
|
+
HostAppControlInput,
|
|
37
|
+
HostAppControlResultPayload,
|
|
38
|
+
} from "./message-types/host-app-control.js";
|
|
39
|
+
|
|
40
|
+
const log = getLogger("host-app-control-proxy");
|
|
41
|
+
|
|
42
|
+
// ---------------------------------------------------------------------------
|
|
43
|
+
// Constants
|
|
44
|
+
// ---------------------------------------------------------------------------
|
|
45
|
+
|
|
46
|
+
const REQUEST_TIMEOUT_MS = 60 * 1000;
|
|
47
|
+
// Threshold of 4 means the warning fires on the 5th identical observation:
|
|
48
|
+
// the first observation establishes the baseline (count = 0), each
|
|
49
|
+
// subsequent identical observation increments the counter, so count = 4 is
|
|
50
|
+
// reached on the 5th total observation.
|
|
51
|
+
const STUCK_REPEAT_THRESHOLD = 4;
|
|
52
|
+
|
|
53
|
+
// ---------------------------------------------------------------------------
|
|
54
|
+
// Tool name constants
|
|
55
|
+
// ---------------------------------------------------------------------------
|
|
56
|
+
//
|
|
57
|
+
// Kept here (rather than imported from PR 5's tool registrations) so the
|
|
58
|
+
// proxy is independently testable. PR 5 must use these same string values.
|
|
59
|
+
|
|
60
|
+
const TOOL_START = "app_control_start";
|
|
61
|
+
|
|
62
|
+
// ---------------------------------------------------------------------------
|
|
63
|
+
// Module-level singleton lock
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Conversation id that currently owns the active app-control session, or
|
|
68
|
+
* `undefined` if no session is active. Set on a successful
|
|
69
|
+
* `app_control_start`; cleared by the owning proxy's `dispose()`.
|
|
70
|
+
*
|
|
71
|
+
* Exported for test inspection only. Production code paths must not read
|
|
72
|
+
* or mutate this directly — use the proxy methods.
|
|
73
|
+
*/
|
|
74
|
+
let activeAppControlConversationId: string | undefined;
|
|
75
|
+
|
|
76
|
+
/** Test-only helper: read current lock owner. */
|
|
77
|
+
export function _getActiveAppControlConversationId(): string | undefined {
|
|
78
|
+
return activeAppControlConversationId;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** Test-only helper: clear lock between test cases. */
|
|
82
|
+
export function _resetActiveAppControlConversationId(): void {
|
|
83
|
+
activeAppControlConversationId = undefined;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// ---------------------------------------------------------------------------
|
|
87
|
+
// HostAppControlProxy
|
|
88
|
+
// ---------------------------------------------------------------------------
|
|
89
|
+
|
|
90
|
+
export class HostAppControlProxy extends HostProxyBase<
|
|
91
|
+
HostAppControlInput,
|
|
92
|
+
HostAppControlResultPayload
|
|
93
|
+
> {
|
|
94
|
+
/** Conversation that owns this proxy instance. Used by `dispose()` to release the singleton lock only when this proxy is the holder. */
|
|
95
|
+
private readonly conversationId: string;
|
|
96
|
+
|
|
97
|
+
/** sha256 hex of the most recent observation's `pngBase64`, or undefined. */
|
|
98
|
+
private lastObservationHash?: string;
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Number of consecutive observations whose PNG hash matched the previous
|
|
102
|
+
* one. Reset to 0 when a different hash is observed. When this reaches
|
|
103
|
+
* {@link STUCK_REPEAT_THRESHOLD}, results carry a `"stuck"` warning.
|
|
104
|
+
*/
|
|
105
|
+
private observationHashRepeatCount = 0;
|
|
106
|
+
|
|
107
|
+
constructor(conversationId: string) {
|
|
108
|
+
super({
|
|
109
|
+
capabilityName: "host_app_control",
|
|
110
|
+
requestEventName: "host_app_control_request",
|
|
111
|
+
cancelEventName: "host_app_control_cancel",
|
|
112
|
+
resultPendingKind: "host_app_control",
|
|
113
|
+
timeoutMs: REQUEST_TIMEOUT_MS,
|
|
114
|
+
disposedMessage: "Host app-control proxy disposed",
|
|
115
|
+
});
|
|
116
|
+
this.conversationId = conversationId;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// ---------------------------------------------------------------------------
|
|
120
|
+
// State accessors (testing / external inspection)
|
|
121
|
+
// ---------------------------------------------------------------------------
|
|
122
|
+
|
|
123
|
+
get observationRepeatCount(): number {
|
|
124
|
+
return this.observationHashRepeatCount;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// ---------------------------------------------------------------------------
|
|
128
|
+
// Public request entry point
|
|
129
|
+
// ---------------------------------------------------------------------------
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Dispatch an app-control tool call to the desktop client. Catches the
|
|
133
|
+
* base's typed lifecycle errors (timeout/aborted/disposed) and returns
|
|
134
|
+
* a `ToolExecutionResult` instead of letting them bubble.
|
|
135
|
+
*/
|
|
136
|
+
async request(
|
|
137
|
+
toolName: string,
|
|
138
|
+
input: HostAppControlInput,
|
|
139
|
+
conversationId: string,
|
|
140
|
+
signal: AbortSignal,
|
|
141
|
+
): Promise<ToolExecutionResult> {
|
|
142
|
+
if (signal.aborted) {
|
|
143
|
+
return { content: "Aborted", isError: true };
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Singleton-lock guard for `start`. Other tools assume a session
|
|
147
|
+
// already exists and are not gated here.
|
|
148
|
+
if (toolName === TOOL_START) {
|
|
149
|
+
if (
|
|
150
|
+
activeAppControlConversationId != null &&
|
|
151
|
+
activeAppControlConversationId !== conversationId
|
|
152
|
+
) {
|
|
153
|
+
return {
|
|
154
|
+
content:
|
|
155
|
+
`Another conversation (${activeAppControlConversationId}) currently holds the ` +
|
|
156
|
+
`app-control session. Wait for it to finish, or call app_control_stop ` +
|
|
157
|
+
`from that conversation first.`,
|
|
158
|
+
isError: true,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
try {
|
|
164
|
+
const payload = await this.dispatchRequest(
|
|
165
|
+
toolName,
|
|
166
|
+
input,
|
|
167
|
+
conversationId,
|
|
168
|
+
signal,
|
|
169
|
+
);
|
|
170
|
+
return this.handleSuccess(toolName, payload);
|
|
171
|
+
} catch (err) {
|
|
172
|
+
if (err instanceof HostProxyRequestError) {
|
|
173
|
+
if (err.reason === "timeout") {
|
|
174
|
+
log.warn({ toolName }, "Host app-control proxy request timed out");
|
|
175
|
+
return {
|
|
176
|
+
content:
|
|
177
|
+
"Host app-control proxy timed out waiting for client response",
|
|
178
|
+
isError: true,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
if (err.reason === "aborted") {
|
|
182
|
+
return { content: "Aborted", isError: true };
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
// `disposed` and any other unexpected errors propagate.
|
|
186
|
+
throw err;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// ---------------------------------------------------------------------------
|
|
191
|
+
// Result handling
|
|
192
|
+
// ---------------------------------------------------------------------------
|
|
193
|
+
|
|
194
|
+
private handleSuccess(
|
|
195
|
+
toolName: string,
|
|
196
|
+
payload: HostAppControlResultPayload,
|
|
197
|
+
): ToolExecutionResult {
|
|
198
|
+
// Update PNG-hash loop tracking only for the "running" state — other
|
|
199
|
+
// states (missing/minimized) intentionally won't carry a
|
|
200
|
+
// representative window screenshot, so they should not feed the guard.
|
|
201
|
+
let stuck = false;
|
|
202
|
+
if (payload.state === "running" && payload.pngBase64) {
|
|
203
|
+
const hash = createHash("sha256").update(payload.pngBase64).digest("hex");
|
|
204
|
+
if (hash === this.lastObservationHash) {
|
|
205
|
+
this.observationHashRepeatCount++;
|
|
206
|
+
} else {
|
|
207
|
+
this.observationHashRepeatCount = 0;
|
|
208
|
+
}
|
|
209
|
+
this.lastObservationHash = hash;
|
|
210
|
+
if (this.observationHashRepeatCount >= STUCK_REPEAT_THRESHOLD) {
|
|
211
|
+
stuck = true;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// Acquire the singleton lock on a successful `start`.
|
|
216
|
+
if (toolName === TOOL_START && payload.state === "running") {
|
|
217
|
+
activeAppControlConversationId = this.conversationId;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
return this.formatResult(payload, stuck);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
private formatResult(
|
|
224
|
+
payload: HostAppControlResultPayload,
|
|
225
|
+
stuck: boolean,
|
|
226
|
+
): ToolExecutionResult {
|
|
227
|
+
const parts: string[] = [];
|
|
228
|
+
|
|
229
|
+
if (stuck) {
|
|
230
|
+
parts.push(
|
|
231
|
+
`WARNING: ${this.observationHashRepeatCount} consecutive observations ` +
|
|
232
|
+
`produced an identical screenshot — the app appears stuck. Try a ` +
|
|
233
|
+
`different action or call app_control_stop and restart.`,
|
|
234
|
+
);
|
|
235
|
+
parts.push("");
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
parts.push(`State: ${payload.state}`);
|
|
239
|
+
|
|
240
|
+
if (payload.windowBounds) {
|
|
241
|
+
const { x, y, width, height } = payload.windowBounds;
|
|
242
|
+
parts.push(`Window bounds: ${width}x${height} at (${x}, ${y})`);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
if (payload.executionResult) {
|
|
246
|
+
parts.push("");
|
|
247
|
+
parts.push(payload.executionResult);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
const isError = payload.executionError != null;
|
|
251
|
+
const errorPrefix = isError
|
|
252
|
+
? `Action failed: ${payload.executionError}`
|
|
253
|
+
: null;
|
|
254
|
+
|
|
255
|
+
const baseContent = parts.join("\n").trim() || `State: ${payload.state}`;
|
|
256
|
+
const content = errorPrefix
|
|
257
|
+
? `${errorPrefix}\n\n${baseContent}`
|
|
258
|
+
: baseContent;
|
|
259
|
+
|
|
260
|
+
const contentBlocks: ContentBlock[] = [];
|
|
261
|
+
if (payload.pngBase64) {
|
|
262
|
+
contentBlocks.push({
|
|
263
|
+
type: "image",
|
|
264
|
+
source: {
|
|
265
|
+
type: "base64",
|
|
266
|
+
media_type: "image/png",
|
|
267
|
+
data: payload.pngBase64,
|
|
268
|
+
},
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
return {
|
|
273
|
+
content,
|
|
274
|
+
isError,
|
|
275
|
+
...(contentBlocks.length > 0 ? { contentBlocks } : {}),
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// ---------------------------------------------------------------------------
|
|
280
|
+
// Lifecycle
|
|
281
|
+
// ---------------------------------------------------------------------------
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Reject pending requests via the base, then release the singleton lock
|
|
285
|
+
* if this proxy is the holder. Idempotent: safe to call multiple times.
|
|
286
|
+
*/
|
|
287
|
+
override dispose(): void {
|
|
288
|
+
super.dispose();
|
|
289
|
+
if (activeAppControlConversationId === this.conversationId) {
|
|
290
|
+
activeAppControlConversationId = undefined;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|