@vellumai/assistant 0.6.2 → 0.6.3
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/bun.lock +40 -40
- package/bunfig.toml +3 -0
- package/docs/architecture/memory.md +1 -1
- package/node_modules/@vellumai/ces-contracts/src/rpc.ts +42 -0
- package/openapi.yaml +184 -69
- package/package.json +41 -41
- package/scripts/generate-openapi.ts +1 -2
- package/src/__tests__/acp-session.test.ts +43 -0
- package/src/__tests__/app-builder-tool-scripts.test.ts +1 -0
- package/src/__tests__/app-executors.test.ts +1 -0
- package/src/__tests__/app-source-watcher.test.ts +37 -11
- package/src/__tests__/approval-routes-http.test.ts +178 -1
- package/src/__tests__/browser-fill-credential.test.ts +229 -94
- package/src/__tests__/browser-manager.test.ts +40 -27
- package/src/__tests__/catalog-files.test.ts +862 -0
- package/src/__tests__/channel-approvals.test.ts +53 -0
- package/src/__tests__/config-managed-gemini-defaults.test.ts +326 -0
- package/src/__tests__/config-schema-cmd.test.ts +2 -2
- package/src/__tests__/config-schema.test.ts +125 -48
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +23 -0
- package/src/__tests__/context-overflow-approval.test.ts +16 -1
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop.test.ts +1 -1
- package/src/__tests__/conversation-analysis-routes.test.ts +2 -2
- package/src/__tests__/conversation-attachments.test.ts +80 -4
- package/src/__tests__/conversation-confirmation-signals.test.ts +155 -0
- package/src/__tests__/conversation-fork-crud.test.ts +17 -0
- package/src/__tests__/conversation-history-web-search.test.ts +1 -0
- package/src/__tests__/conversation-host-access-routes.test.ts +229 -0
- package/src/__tests__/conversation-inject-context.test.ts +103 -0
- package/src/__tests__/conversation-queue.test.ts +45 -2
- package/src/__tests__/conversation-routes-disk-view.test.ts +5 -0
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +16 -0
- package/src/__tests__/conversation-routes-slash-commands.test.ts +1 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +269 -46
- package/src/__tests__/conversation-starter-routes.test.ts +126 -0
- package/src/__tests__/conversation-starters-cadence.test.ts +161 -0
- package/src/__tests__/conversation-store.test.ts +195 -0
- package/src/__tests__/conversation-workspace-cache-state.test.ts +193 -0
- package/src/__tests__/credential-execution-approval-bridge.test.ts +32 -1
- package/src/__tests__/credential-security-invariants.test.ts +1 -0
- package/src/__tests__/credential-vault-unit.test.ts +4 -4
- package/src/__tests__/credential-vault.test.ts +152 -13
- package/src/__tests__/credentials-cli.test.ts +2 -2
- package/src/__tests__/date-context.test.ts +4 -4
- package/src/__tests__/embedding-managed-proxy-selection.test.ts +256 -0
- package/src/__tests__/extension-id-sync-guard.test.ts +155 -0
- package/src/__tests__/fixtures/mock-chrome-extension.ts +375 -0
- package/src/__tests__/gateway-only-guard.test.ts +3 -0
- package/src/__tests__/gemini-provider.test.ts +2 -2
- package/src/__tests__/guardian-routing-invariants.test.ts +70 -2
- package/src/__tests__/headless-browser-interactions.test.ts +707 -371
- package/src/__tests__/headless-browser-navigate.test.ts +389 -47
- package/src/__tests__/headless-browser-read-tools.test.ts +266 -103
- package/src/__tests__/headless-browser-snapshot.test.ts +240 -77
- package/src/__tests__/host-bash-proxy.test.ts +150 -1
- package/src/__tests__/host-browser-e2e-cloud.test.ts +462 -0
- package/src/__tests__/host-browser-e2e-self-hosted-capability.test.ts +286 -0
- package/src/__tests__/host-browser-e2e-self-hosted.test.ts +374 -0
- package/src/__tests__/host-browser-event-routes.test.ts +350 -0
- package/src/__tests__/host-browser-proxy.test.ts +444 -0
- package/src/__tests__/host-browser-routes.test.ts +198 -0
- package/src/__tests__/host-browser-ws-events-e2e.test.ts +320 -0
- package/src/__tests__/host-cu-proxy.test.ts +171 -1
- package/src/__tests__/host-file-proxy.test.ts +185 -1
- package/src/__tests__/host-file-read-tool.test.ts +52 -0
- package/src/__tests__/host-proxy-interface.test.ts +165 -0
- package/src/__tests__/host-shell-tool.test.ts +1 -11
- package/src/__tests__/http-user-message-parity.test.ts +1 -0
- package/src/__tests__/integration-status.test.ts +6 -7
- package/src/__tests__/list-messages-tool-merge.test.ts +37 -12
- package/src/__tests__/mcp-client-auth.test.ts +40 -4
- package/src/__tests__/mcp-health-check.test.ts +10 -3
- package/src/__tests__/migration-cross-version-compatibility.test.ts +3 -1
- package/src/__tests__/migration-export-http.test.ts +61 -2
- package/src/__tests__/migration-export-streaming.test.ts +66 -0
- package/src/__tests__/migration-import-commit-http.test.ts +101 -1
- package/src/__tests__/native-host-marker-sync-guard.test.ts +157 -0
- package/src/__tests__/oauth-apps-routes.test.ts +17 -12
- package/src/__tests__/oauth-cli.test.ts +707 -60
- package/src/__tests__/oauth-connect-orchestrator.test.ts +116 -24
- package/src/__tests__/oauth-provider-seed-logos.test.ts +23 -0
- package/src/__tests__/oauth-provider-serializer.test.ts +146 -10
- package/src/__tests__/oauth-provider-visibility.test.ts +19 -21
- package/src/__tests__/oauth-providers-routes.test.ts +50 -14
- package/src/__tests__/oauth-store.test.ts +1386 -182
- package/src/__tests__/oauth2-gateway-transport.test.ts +211 -20
- package/src/__tests__/onboarding-template-contract.test.ts +75 -57
- package/src/__tests__/openai-provider.test.ts +2 -2
- package/src/__tests__/outlook-categories.test.ts +1 -1
- package/src/__tests__/outlook-client-automation.test.ts +1 -1
- package/src/__tests__/outlook-compose-tools.test.ts +1 -1
- package/src/__tests__/outlook-email-watcher.test.ts +1 -1
- package/src/__tests__/outlook-follow-up.test.ts +1 -1
- package/src/__tests__/outlook-messaging-provider.test.ts +2 -2
- package/src/__tests__/outlook-trash.test.ts +1 -1
- package/src/__tests__/outlook-unsubscribe.test.ts +1 -1
- package/src/__tests__/permission-checker-host-gate.test.ts +74 -14
- package/src/__tests__/permission-mode.test.ts +28 -56
- package/src/__tests__/platform-callback-registration.test.ts +19 -0
- package/src/__tests__/post-turn-tool-result-truncation.test.ts +296 -0
- package/src/__tests__/proxy-approval-callback.test.ts +18 -0
- package/src/__tests__/require-fresh-approval.test.ts +40 -1
- package/src/__tests__/sanitize-config-for-transfer.test.ts +132 -0
- package/src/__tests__/schedule-routes.test.ts +162 -0
- package/src/__tests__/secret-detection-handler.test.ts +84 -0
- package/src/__tests__/secret-ingress-http.test.ts +1 -0
- package/src/__tests__/send-endpoint-busy.test.ts +3 -0
- package/src/__tests__/set-permission-mode.test.ts +13 -250
- package/src/__tests__/skills-file-content-endpoint.test.ts +670 -0
- package/src/__tests__/skills-files-catalog-fallback.test.ts +450 -0
- package/src/__tests__/slack-channel-config.test.ts +12 -15
- package/src/__tests__/subagent-detail.test.ts +44 -2
- package/src/__tests__/subagent-disposal.test.ts +1 -0
- package/src/__tests__/subagent-fork-notifications.test.ts +291 -0
- package/src/__tests__/subagent-fork-spawn.test.ts +384 -0
- package/src/__tests__/subagent-manager-notify.test.ts +1 -0
- package/src/__tests__/subagent-notify-parent.test.ts +1 -0
- package/src/__tests__/subagent-spawn-tool-fork.test.ts +411 -0
- package/src/__tests__/subagent-tools.test.ts +1 -0
- package/src/__tests__/subagent-types.test.ts +1 -0
- package/src/__tests__/system-prompt-ask-mode.test.ts +27 -71
- package/src/__tests__/system-prompt.test.ts +72 -1
- package/src/__tests__/task-scheduler.test.ts +32 -6
- package/src/__tests__/telegram-config.test.ts +10 -13
- package/src/__tests__/terminal-tools.test.ts +9 -0
- package/src/__tests__/tool-approval-handler.test.ts +73 -0
- package/src/__tests__/tool-side-effects-slack-dm.test.ts +22 -0
- package/src/__tests__/top-level-renderer.test.ts +73 -1
- package/src/__tests__/transport-hints-queue.test.ts +14 -29
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +109 -0
- package/src/__tests__/v2-consent-policy.test.ts +103 -0
- package/src/acp/client-handler.ts +30 -4
- package/src/agent/loop.ts +12 -6
- package/src/approvals/guardian-request-resolvers.ts +21 -15
- package/src/browser-session/__tests__/manager.test.ts +297 -0
- package/src/browser-session/backends/cdp-inspect.ts +30 -0
- package/src/browser-session/backends/extension.ts +26 -0
- package/src/browser-session/backends/local.ts +24 -0
- package/src/browser-session/events.ts +164 -0
- package/src/browser-session/index.ts +27 -0
- package/src/browser-session/manager.ts +159 -0
- package/src/browser-session/types.ts +28 -0
- package/src/channels/__tests__/types.test.ts +134 -0
- package/src/channels/types.ts +53 -3
- package/src/cli/commands/browser-relay.ts +339 -409
- package/src/cli/commands/credentials.ts +3 -3
- package/src/cli/commands/email.ts +18 -13
- package/src/cli/commands/mcp.ts +16 -4
- package/src/cli/commands/oauth/__tests__/connect.test.ts +44 -44
- package/src/cli/commands/oauth/__tests__/disconnect.test.ts +21 -21
- package/src/cli/commands/oauth/__tests__/mode.test.ts +17 -17
- package/src/cli/commands/oauth/__tests__/ping.test.ts +16 -16
- package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +31 -33
- package/src/cli/commands/oauth/__tests__/providers-register.test.ts +329 -0
- package/src/cli/commands/oauth/__tests__/providers-update.test.ts +116 -12
- package/src/cli/commands/oauth/__tests__/status.test.ts +10 -10
- package/src/cli/commands/oauth/__tests__/token.test.ts +7 -7
- package/src/cli/commands/oauth/apps.ts +7 -4
- package/src/cli/commands/oauth/connect.ts +6 -3
- package/src/cli/commands/oauth/disconnect.ts +1 -1
- package/src/cli/commands/oauth/providers.ts +200 -36
- package/src/cli/commands/oauth/shared.ts +5 -5
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +259 -0
- package/src/cli/commands/platform/index.ts +107 -10
- package/src/cli/commands/usage.ts +10 -9
- package/src/cli/lib/daemon-credential-client.ts +4 -0
- package/src/cli/program.ts +1 -1
- package/src/config/bundled-skills/app-builder/SKILL.md +26 -249
- package/src/config/bundled-skills/app-builder/references/CUSTOM_ROUTES.md +105 -0
- package/src/config/bundled-skills/app-builder/references/INTERACTION_HOOKS.md +56 -0
- package/src/config/bundled-skills/app-builder/references/WIDGETS.md +125 -0
- package/src/config/bundled-skills/contacts/SKILL.md +3 -0
- package/src/config/bundled-skills/document/SKILL.md +4 -0
- package/src/config/bundled-skills/gmail/SKILL.md +1 -1
- package/src/config/bundled-skills/outlook/SKILL.md +7 -0
- package/src/config/bundled-skills/subagent/SKILL.md +21 -0
- package/src/config/bundled-skills/subagent/TOOLS.json +8 -4
- package/src/config/bundled-skills/tasks/SKILL.md +5 -0
- package/src/config/env-registry.ts +14 -0
- package/src/config/env.ts +21 -0
- package/src/config/feature-flag-registry.json +44 -5
- package/src/config/loader.ts +56 -1
- package/src/config/sanitize-for-transfer.ts +47 -0
- package/src/config/schema.ts +46 -5
- package/src/config/schemas/host-browser.ts +66 -0
- package/src/config/schemas/memory-lifecycle.ts +1 -1
- package/src/config/schemas/memory-retrieval.ts +103 -0
- package/src/config/schemas/security.ts +0 -6
- package/src/config/schemas/services.ts +8 -0
- package/src/config/types.ts +0 -1
- package/src/context/post-turn-tool-result-truncation.ts +176 -0
- package/src/context/window-manager.ts +19 -1
- package/src/credential-execution/approval-bridge.ts +49 -15
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +186 -0
- package/src/daemon/app-source-watcher.ts +35 -0
- package/src/daemon/context-overflow-approval.ts +5 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +17 -2
- package/src/daemon/conversation-agent-loop.ts +58 -24
- package/src/daemon/conversation-attachments.ts +40 -0
- package/src/daemon/conversation-process.ts +48 -1
- package/src/daemon/conversation-runtime-assembly.ts +118 -36
- package/src/daemon/conversation-surfaces.ts +37 -36
- package/src/daemon/conversation-tool-setup.ts +74 -8
- package/src/daemon/conversation-workspace.ts +12 -0
- package/src/daemon/conversation.ts +226 -8
- package/src/daemon/date-context.ts +10 -10
- package/src/daemon/first-greeting.ts +3 -2
- package/src/daemon/handlers/conversations.ts +9 -140
- package/src/daemon/handlers/shared.ts +58 -0
- package/src/daemon/handlers/skills.ts +232 -37
- package/src/daemon/host-bash-proxy.ts +48 -13
- package/src/daemon/host-browser-proxy.ts +191 -0
- package/src/daemon/host-cu-proxy.ts +36 -11
- package/src/daemon/host-file-proxy.ts +57 -9
- package/src/daemon/lifecycle.ts +65 -11
- package/src/daemon/message-protocol.ts +7 -0
- package/src/daemon/message-types/conversations.ts +55 -13
- package/src/daemon/message-types/host-browser.ts +100 -0
- package/src/daemon/message-types/messages.ts +5 -5
- package/src/daemon/message-types/skills.ts +10 -0
- package/src/daemon/message-types/subagents.ts +2 -0
- package/src/daemon/server.ts +92 -12
- package/src/daemon/tool-side-effects.ts +6 -0
- package/src/daemon/transport-hints.ts +5 -24
- package/src/inbound/platform-callback-registration.ts +18 -17
- package/src/mcp/client.ts +59 -24
- package/src/memory/app-store.ts +31 -1
- package/src/memory/conversation-crud.ts +23 -0
- package/src/memory/conversation-starters-cadence.ts +76 -0
- package/src/memory/conversation-title-service.ts +5 -2
- package/src/memory/db-init.ts +12 -0
- package/src/memory/embedding-backend.test.ts +75 -0
- package/src/memory/embedding-backend.ts +131 -5
- package/src/memory/embedding-gemini.test.ts +54 -0
- package/src/memory/embedding-gemini.ts +20 -9
- package/src/memory/embedding-local.ts +176 -17
- package/src/memory/graph/consolidation.ts +10 -23
- package/src/memory/graph/extraction-job.ts +15 -0
- package/src/memory/graph/retriever.ts +40 -22
- package/src/memory/graph/store.test.ts +7 -3
- package/src/memory/graph/store.ts +47 -12
- package/src/memory/llm-usage-store.ts +45 -4
- package/src/memory/migrations/213-oauth-providers-scope-separator.ts +13 -0
- package/src/memory/migrations/214-oauth-providers-refresh-url.ts +11 -0
- package/src/memory/migrations/215-oauth-providers-revoke.ts +14 -0
- package/src/memory/migrations/216-oauth-providers-token-auth-method.ts +30 -0
- package/src/memory/migrations/217-conversation-host-access.ts +40 -0
- package/src/memory/migrations/218-oauth-providers-logo-url.ts +11 -0
- package/src/memory/migrations/index.ts +6 -0
- package/src/memory/migrations/registry.ts +8 -0
- package/src/memory/schema/conversations.ts +1 -0
- package/src/memory/schema/oauth.ts +18 -13
- package/src/oauth/AGENTS.md +76 -0
- package/src/oauth/__tests__/identity-verifier.test.ts +24 -19
- package/src/oauth/__tests__/seed-providers-managed.test.ts +32 -0
- package/src/oauth/byo-connection.test.ts +8 -8
- package/src/oauth/byo-connection.ts +7 -7
- package/src/oauth/connect-orchestrator.ts +23 -21
- package/src/oauth/connect-types.ts +3 -3
- package/src/oauth/connection-resolver.test.ts +17 -4
- package/src/oauth/connection-resolver.ts +16 -16
- package/src/oauth/connection.ts +1 -1
- package/src/oauth/manual-token-connection.ts +13 -13
- package/src/oauth/oauth-store.ts +214 -100
- package/src/oauth/platform-connection.test.ts +3 -3
- package/src/oauth/platform-connection.ts +4 -4
- package/src/oauth/provider-serializer.ts +31 -5
- package/src/oauth/revoke.ts +76 -0
- package/src/oauth/seed-providers.ts +126 -87
- package/src/oauth/token-persistence.ts +1 -1
- package/src/permissions/permission-mode.ts +4 -11
- package/src/permissions/prompter.ts +13 -1
- package/src/permissions/v2-consent-policy.ts +87 -0
- package/src/prompts/system-prompt.ts +18 -21
- package/src/prompts/templates/BOOTSTRAP-REFERENCE.md +3 -65
- package/src/prompts/templates/BOOTSTRAP.md +59 -105
- package/src/providers/anthropic/client.ts +1 -0
- package/src/providers/types.ts +1 -1
- package/src/runtime/AGENTS.md +23 -0
- package/src/runtime/__tests__/browser-extension-pair-routes.test.ts +715 -0
- package/src/runtime/__tests__/capability-tokens.test.ts +258 -0
- package/src/runtime/__tests__/chrome-extension-registry.test.ts +518 -0
- package/src/runtime/assistant-event-hub.ts +2 -2
- package/src/runtime/auth/__tests__/guard-tests.test.ts +1 -0
- package/src/runtime/auth/__tests__/middleware.test.ts +116 -1
- package/src/runtime/auth/__tests__/route-policy.test.ts +8 -0
- package/src/runtime/auth/middleware.ts +98 -0
- package/src/runtime/auth/route-policy.ts +6 -7
- package/src/runtime/capability-tokens.ts +414 -0
- package/src/runtime/channel-approvals.ts +18 -5
- package/src/runtime/chrome-extension-registry.ts +332 -0
- package/src/runtime/confirmation-request-guardian-bridge.ts +6 -0
- package/src/runtime/guardian-decision-types.ts +7 -0
- package/src/runtime/http-server.ts +425 -70
- package/src/runtime/migrations/__tests__/rebind-secrets-credentials.test.ts +172 -0
- package/src/runtime/migrations/__tests__/vbundle-builder-credentials.test.ts +276 -0
- package/src/runtime/migrations/__tests__/vbundle-import-credentials.test.ts +162 -0
- package/src/runtime/migrations/migration-transport.ts +6 -0
- package/src/runtime/migrations/migration-wizard.ts +22 -2
- package/src/runtime/migrations/rebind-secrets-screen.ts +76 -15
- package/src/runtime/migrations/vbundle-builder.ts +145 -38
- package/src/runtime/migrations/vbundle-import-analyzer.ts +19 -0
- package/src/runtime/migrations/vbundle-importer.ts +55 -5
- package/src/runtime/pending-interactions.ts +29 -13
- package/src/runtime/routes/approval-routes.ts +90 -16
- package/src/runtime/routes/browser-cdp-routes.ts +229 -0
- package/src/runtime/routes/browser-extension-pair-routes.ts +497 -0
- package/src/runtime/routes/conversation-analysis-routes.ts +2 -1
- package/src/runtime/routes/conversation-management-routes.ts +108 -0
- package/src/runtime/routes/conversation-routes.ts +301 -27
- package/src/runtime/routes/conversation-starter-routes.ts +78 -16
- package/src/runtime/routes/guardian-action-routes.ts +24 -13
- package/src/runtime/routes/host-browser-routes.ts +279 -0
- package/src/runtime/routes/host-file-routes.ts +9 -1
- package/src/runtime/routes/identity-routes.ts +259 -16
- package/src/runtime/routes/log-export-routes.ts +42 -22
- package/src/runtime/routes/memory-item-routes.ts +1 -7
- package/src/runtime/routes/migration-routes.ts +87 -2
- package/src/runtime/routes/oauth-apps.ts +15 -17
- package/src/runtime/routes/oauth-providers.ts +4 -0
- package/src/runtime/routes/schedule-routes.ts +24 -11
- package/src/runtime/routes/settings-routes.ts +9 -97
- package/src/runtime/routes/skills-routes.ts +52 -2
- package/src/runtime/routes/subagents-routes.ts +14 -10
- package/src/runtime/routes/usage-routes.ts +8 -7
- package/src/runtime/routes/workspace-routes.test.ts +22 -0
- package/src/runtime/routes/workspace-routes.ts +8 -1
- package/src/runtime/routes/workspace-utils.ts +2 -0
- package/src/schedule/scheduler.ts +7 -5
- package/src/security/ces-credential-client.ts +20 -0
- package/src/security/ces-rpc-credential-backend.ts +17 -0
- package/src/security/credential-backend.ts +5 -0
- package/src/security/oauth2.ts +42 -25
- package/src/security/secure-keys.ts +118 -25
- package/src/security/token-manager.ts +23 -10
- package/src/skills/catalog-files.ts +492 -0
- package/src/subagent/manager.ts +131 -26
- package/src/subagent/types.ts +19 -0
- package/src/tools/apps/executors.ts +11 -2
- package/src/tools/browser/__tests__/auth-detector.test.ts +202 -108
- package/src/tools/browser/auth-detector.ts +43 -12
- package/src/tools/browser/browser-execution.ts +645 -340
- package/src/tools/browser/browser-manager.ts +36 -12
- package/src/tools/browser/cdp-client/__tests__/accessibility-snapshot.test.ts +318 -0
- package/src/tools/browser/cdp-client/__tests__/cdp-dom-helpers.test.ts +1175 -0
- package/src/tools/browser/cdp-client/__tests__/cdp-inspect-client.test.ts +870 -0
- package/src/tools/browser/cdp-client/__tests__/extension-cdp-client.test.ts +330 -0
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +377 -0
- package/src/tools/browser/cdp-client/__tests__/fixtures/ax-tree-nested-frames.json +64 -0
- package/src/tools/browser/cdp-client/__tests__/fixtures/ax-tree-simple.json +69 -0
- package/src/tools/browser/cdp-client/__tests__/local-cdp-client.test.ts +310 -0
- package/src/tools/browser/cdp-client/__tests__/types.test.ts +96 -0
- package/src/tools/browser/cdp-client/accessibility-snapshot.ts +387 -0
- package/src/tools/browser/cdp-client/cdp-dom-helpers.ts +695 -0
- package/src/tools/browser/cdp-client/cdp-inspect/__tests__/discovery.test.ts +743 -0
- package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +580 -0
- package/src/tools/browser/cdp-client/cdp-inspect/discovery.ts +578 -0
- package/src/tools/browser/cdp-client/cdp-inspect/ws-transport.ts +579 -0
- package/src/tools/browser/cdp-client/cdp-inspect-client.ts +635 -0
- package/src/tools/browser/cdp-client/errors.ts +34 -0
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +125 -0
- package/src/tools/browser/cdp-client/factory.ts +204 -0
- package/src/tools/browser/cdp-client/index.ts +14 -0
- package/src/tools/browser/cdp-client/local-cdp-client.ts +187 -0
- package/src/tools/browser/cdp-client/types.ts +52 -0
- package/src/tools/filesystem/edit.ts +1 -1
- package/src/tools/filesystem/list.ts +1 -1
- package/src/tools/filesystem/read.ts +1 -1
- package/src/tools/filesystem/write.ts +2 -1
- package/src/tools/host-filesystem/edit.ts +1 -1
- package/src/tools/host-filesystem/read.ts +12 -15
- package/src/tools/host-filesystem/write.ts +1 -1
- package/src/tools/host-terminal/host-shell.ts +21 -16
- package/src/tools/permission-checker.ts +77 -82
- package/src/tools/registry.ts +0 -2
- package/src/tools/secret-detection-handler.ts +34 -0
- package/src/tools/shared/filesystem/image-read.ts +61 -40
- package/src/tools/subagent/spawn.ts +47 -3
- package/src/tools/subagent/status.ts +2 -0
- package/src/tools/system/register.ts +2 -16
- package/src/tools/terminal/safe-env.ts +7 -0
- package/src/tools/terminal/shell.ts +21 -16
- package/src/tools/tool-approval-handler.ts +48 -2
- package/src/tools/types.ts +2 -0
- package/src/util/platform.ts +14 -19
- package/src/workspace/top-level-renderer.ts +19 -1
- package/src/__tests__/chrome-cdp.test.ts +0 -419
- package/src/__tests__/permission-mode-sse.test.ts +0 -418
- package/src/__tests__/permission-mode-store.test.ts +0 -277
- package/src/browser-extension-relay/protocol.ts +0 -63
- package/src/browser-extension-relay/server.ts +0 -203
- package/src/config/schemas/sandbox.ts +0 -14
- package/src/permissions/permission-mode-store.ts +0 -180
- package/src/tools/browser/chrome-cdp.ts +0 -239
- package/src/tools/system/set-permission-mode.ts +0 -103
package/src/subagent/manager.ts
CHANGED
|
@@ -142,6 +142,14 @@ export class SubagentManager {
|
|
|
142
142
|
*/
|
|
143
143
|
broadcastToAllClients?: (msg: ServerMessage) => void;
|
|
144
144
|
|
|
145
|
+
/**
|
|
146
|
+
* Resolve a live parent Conversation by conversationId.
|
|
147
|
+
* Wired by DaemonServer at startup — follows the same pattern as
|
|
148
|
+
* `onSubagentFinished`. Used by fork spawn to resolve the parent's
|
|
149
|
+
* system prompt when `config.parentSystemPrompt` is not provided.
|
|
150
|
+
*/
|
|
151
|
+
resolveParentConversation?: (conversationId: string) => Conversation | undefined;
|
|
152
|
+
|
|
145
153
|
// ── Spawn ───────────────────────────────────────────────────────────
|
|
146
154
|
|
|
147
155
|
/**
|
|
@@ -165,7 +173,19 @@ export class SubagentManager {
|
|
|
165
173
|
}
|
|
166
174
|
|
|
167
175
|
// ── Resolve role ─────────────────────────────────────────────────
|
|
168
|
-
const
|
|
176
|
+
const isFork = config.fork === true;
|
|
177
|
+
let role: SubagentRole = (config.role as SubagentRole) ?? "general";
|
|
178
|
+
if (isFork && role !== "general") {
|
|
179
|
+
log.warn(
|
|
180
|
+
{
|
|
181
|
+
requestedRole: role,
|
|
182
|
+
parentConversationId: config.parentConversationId,
|
|
183
|
+
label: config.label,
|
|
184
|
+
},
|
|
185
|
+
"Fork requested with non-general role — forcing general to preserve KV cache alignment",
|
|
186
|
+
);
|
|
187
|
+
role = "general";
|
|
188
|
+
}
|
|
169
189
|
if (!SUBAGENT_ROLE_REGISTRY[role]) {
|
|
170
190
|
throw new Error(
|
|
171
191
|
`Invalid subagent role "${config.role}". Must be one of: ${Object.keys(SUBAGENT_ROLE_REGISTRY).join(", ")}`,
|
|
@@ -194,24 +214,58 @@ export class SubagentManager {
|
|
|
194
214
|
);
|
|
195
215
|
}
|
|
196
216
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
217
|
+
let systemPrompt: string;
|
|
218
|
+
if (isFork) {
|
|
219
|
+
// Forks use the parent's system prompt directly — no subagent preamble.
|
|
220
|
+
if (config.parentSystemPrompt) {
|
|
221
|
+
systemPrompt = config.parentSystemPrompt;
|
|
222
|
+
} else if (this.resolveParentConversation) {
|
|
223
|
+
const parentConv = this.resolveParentConversation(config.parentConversationId);
|
|
224
|
+
const resolved = parentConv?.getCurrentSystemPrompt();
|
|
225
|
+
if (!resolved) {
|
|
226
|
+
throw new Error(
|
|
227
|
+
"Fork spawn requires a parent system prompt but neither config.parentSystemPrompt " +
|
|
228
|
+
"nor resolveParentConversation yielded one.",
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
systemPrompt = resolved;
|
|
232
|
+
} else {
|
|
233
|
+
throw new Error(
|
|
234
|
+
"Fork spawn requires a parent system prompt but neither config.parentSystemPrompt " +
|
|
235
|
+
"is set nor resolveParentConversation callback is wired.",
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
} else {
|
|
239
|
+
systemPrompt =
|
|
240
|
+
config.systemPromptOverride ??
|
|
241
|
+
buildSubagentSystemPrompt({ ...config, id: subagentId }, role);
|
|
242
|
+
}
|
|
200
243
|
const maxTokens = appConfig.maxTokens;
|
|
201
244
|
const workingDir = getSandboxWorkingDir();
|
|
202
245
|
|
|
203
|
-
const memoryPolicy: ConversationMemoryPolicy =
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
246
|
+
const memoryPolicy: ConversationMemoryPolicy = isFork
|
|
247
|
+
? {
|
|
248
|
+
scopeId: "default",
|
|
249
|
+
includeDefaultFallback: false,
|
|
250
|
+
strictSideEffects: false,
|
|
251
|
+
}
|
|
252
|
+
: {
|
|
253
|
+
scopeId: `subagent:${subagentId}`,
|
|
254
|
+
includeDefaultFallback: true,
|
|
255
|
+
strictSideEffects: false,
|
|
256
|
+
};
|
|
208
257
|
|
|
209
258
|
// ── Initialise state ────────────────────────────────────────────
|
|
210
259
|
const now = Date.now();
|
|
260
|
+
// For forks, default sendResultToUser to false (silent) unless explicitly true.
|
|
261
|
+
const resolvedSendResultToUser = isFork
|
|
262
|
+
? (config.sendResultToUser === true ? true : false)
|
|
263
|
+
: config.sendResultToUser;
|
|
211
264
|
const state: SubagentState = {
|
|
212
|
-
config: { ...config, id: subagentId },
|
|
265
|
+
config: { ...config, id: subagentId, sendResultToUser: resolvedSendResultToUser },
|
|
213
266
|
status: "pending",
|
|
214
267
|
conversationId: conversationRecord.id,
|
|
268
|
+
isFork,
|
|
215
269
|
createdAt: now,
|
|
216
270
|
usage: { inputTokens: 0, outputTokens: 0, estimatedCost: 0 },
|
|
217
271
|
};
|
|
@@ -255,8 +309,16 @@ export class SubagentManager {
|
|
|
255
309
|
conversation.updateClient(wrappedSendToClient, true);
|
|
256
310
|
conversation.setIsSubagent(true);
|
|
257
311
|
|
|
312
|
+
if (isFork) {
|
|
313
|
+
// Force the fork to use the parent's system prompt as-is without dynamic rebuild.
|
|
314
|
+
// This ensures KV cache alignment with the parent conversation.
|
|
315
|
+
conversation.hasSystemPromptOverride = true;
|
|
316
|
+
}
|
|
317
|
+
|
|
258
318
|
// Apply role-based tool filter if the role defines one.
|
|
259
|
-
|
|
319
|
+
// Skip for forks — general role has allowedTools: undefined, and forks
|
|
320
|
+
// should have the same tool access as the parent.
|
|
321
|
+
if (!isFork && roleConfig.allowedTools) {
|
|
260
322
|
conversation.setSubagentAllowedTools(new Set(roleConfig.allowedTools));
|
|
261
323
|
}
|
|
262
324
|
|
|
@@ -298,6 +360,7 @@ export class SubagentManager {
|
|
|
298
360
|
parentConversationId: config.parentConversationId,
|
|
299
361
|
label: config.label,
|
|
300
362
|
objective: config.objective,
|
|
363
|
+
isFork: config.fork ?? false,
|
|
301
364
|
} as ServerMessage);
|
|
302
365
|
|
|
303
366
|
log.info(
|
|
@@ -339,9 +402,37 @@ export class SubagentManager {
|
|
|
339
402
|
const onEvent = conversation.sendToClient;
|
|
340
403
|
|
|
341
404
|
try {
|
|
405
|
+
// For forks, inject the parent's message history before the first message.
|
|
406
|
+
// This prepends the inherited context so the fork has full conversational
|
|
407
|
+
// awareness while the objective becomes the latest user turn.
|
|
408
|
+
if (managed.state.isFork && managed.state.config.parentMessages) {
|
|
409
|
+
conversation.injectInheritedContext(managed.state.config.parentMessages);
|
|
410
|
+
// Release the parent message arrays now that they've been injected — holding
|
|
411
|
+
// them in SubagentState.config would retain significant memory until the TTL
|
|
412
|
+
// sweep disposes this entry (up to 30 minutes for terminal subagents).
|
|
413
|
+
managed.state.config.parentMessages = undefined;
|
|
414
|
+
managed.state.config.parentSystemPrompt = undefined;
|
|
415
|
+
}
|
|
416
|
+
|
|
342
417
|
// Send the objective as the first user message and process it.
|
|
343
|
-
|
|
344
|
-
|
|
418
|
+
// For forks, wrap the objective in directive framing so it overrides
|
|
419
|
+
// conversational momentum from the inherited context. Without this,
|
|
420
|
+
// the fork tends to continue the parent conversation instead of
|
|
421
|
+
// pivoting to the task — the inherited context is louder than a bare
|
|
422
|
+
// objective buried after 100k+ tokens of chat history.
|
|
423
|
+
const message = managed.state.isFork
|
|
424
|
+
? [
|
|
425
|
+
"⎯⎯⎯ FORK TASK ⎯⎯⎯",
|
|
426
|
+
"You have been forked from the parent conversation to execute a specific task.",
|
|
427
|
+
"The conversation above is context — do NOT continue it. Do NOT spawn sub-agents.",
|
|
428
|
+
"Complete this task directly and return only your findings:",
|
|
429
|
+
"",
|
|
430
|
+
objective,
|
|
431
|
+
"⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯",
|
|
432
|
+
].join("\n")
|
|
433
|
+
: objective;
|
|
434
|
+
const messageId = await conversation.persistUserMessage(message, []);
|
|
435
|
+
await conversation.runAgentLoop(message, messageId, onEvent);
|
|
345
436
|
|
|
346
437
|
// Agent loop completed successfully.
|
|
347
438
|
// Copy usage stats from the conversation before sending status (which includes usage).
|
|
@@ -431,9 +522,10 @@ export class SubagentManager {
|
|
|
431
522
|
// Skip when the parent LLM itself called subagent_abort (it already has the tool result).
|
|
432
523
|
if (this.onSubagentFinished && !options?.suppressNotification) {
|
|
433
524
|
const label = managed.state.config.label;
|
|
525
|
+
const prefix = managed.state.isFork ? "Fork" : "Subagent";
|
|
434
526
|
const message =
|
|
435
|
-
`[
|
|
436
|
-
`This
|
|
527
|
+
`[${prefix} "${label}" was explicitly aborted]\n\n` +
|
|
528
|
+
`This ${prefix.toLowerCase()} was cancelled on purpose. Do NOT re-spawn or retry it.`;
|
|
437
529
|
try {
|
|
438
530
|
// Use the managed subagent's stored parentSendToClient so the
|
|
439
531
|
// notification routes to the parent conversation's socket, not the
|
|
@@ -781,10 +873,11 @@ export class SubagentManager {
|
|
|
781
873
|
if (!managed || TERMINAL_STATUSES.has(managed.state.status)) return false;
|
|
782
874
|
if (!this.onSubagentFinished) return false;
|
|
783
875
|
|
|
784
|
-
|
|
876
|
+
const prefix = managed.state.isFork ? "Fork" : "Subagent";
|
|
877
|
+
let notificationString = `[${prefix} "${info.label}" — ${urgency}] ${message}`;
|
|
785
878
|
if (urgency === "blocked") {
|
|
786
879
|
notificationString +=
|
|
787
|
-
|
|
880
|
+
`\nUse subagent_message to send guidance to this ${prefix.toLowerCase()}.`;
|
|
788
881
|
}
|
|
789
882
|
|
|
790
883
|
try {
|
|
@@ -820,22 +913,34 @@ export class SubagentManager {
|
|
|
820
913
|
if (!this.onSubagentFinished) return;
|
|
821
914
|
|
|
822
915
|
const { config } = managed.state;
|
|
916
|
+
const isFork = managed.state.isFork;
|
|
823
917
|
let message: string;
|
|
824
918
|
|
|
825
919
|
if (outcome === "completed") {
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
920
|
+
if (isFork) {
|
|
921
|
+
const silent = config.sendResultToUser !== true;
|
|
922
|
+
message =
|
|
923
|
+
`[Fork "${config.label}" completed]\n\n` +
|
|
924
|
+
`Use subagent_read with subagent_id "${config.id}" and last_n: 1 to retrieve the final synthesis.\n` +
|
|
925
|
+
(silent
|
|
926
|
+
? `This fork was spawned for internal processing. Process the findings internally — do NOT share raw fork output with the user.`
|
|
927
|
+
: `Do NOT re-spawn this fork — just read and share the results.`);
|
|
928
|
+
} else {
|
|
929
|
+
const silent = config.sendResultToUser === false;
|
|
930
|
+
message =
|
|
931
|
+
`[Subagent "${config.label}" completed]\n\n` +
|
|
932
|
+
`Use subagent_read with subagent_id "${config.id}" to retrieve the full output.\n` +
|
|
933
|
+
(silent
|
|
934
|
+
? `This subagent was spawned for internal processing. Read the result for your own use but do NOT share it with the user.\nDo NOT re-spawn this subagent.`
|
|
935
|
+
: `Do NOT re-spawn this subagent — just read and share the results.`);
|
|
936
|
+
}
|
|
833
937
|
} else {
|
|
834
938
|
const error = managed.state.error ?? "Unknown error";
|
|
939
|
+
const prefix = isFork ? "Fork" : "Subagent";
|
|
835
940
|
message =
|
|
836
|
-
`[
|
|
941
|
+
`[${prefix} "${config.label}" failed]\n\n` +
|
|
837
942
|
`Error: ${error}\n` +
|
|
838
|
-
`Do NOT re-spawn or retry this
|
|
943
|
+
`Do NOT re-spawn or retry this ${prefix.toLowerCase()} unless the user explicitly asks.`;
|
|
839
944
|
}
|
|
840
945
|
|
|
841
946
|
const notification: SubagentNotificationInfo = {
|
package/src/subagent/types.ts
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import type { UsageStats } from "../daemon/message-protocol.js";
|
|
10
|
+
import type { Message } from "../providers/types.js";
|
|
10
11
|
|
|
11
12
|
// ── Status ──────────────────────────────────────────────────────────────
|
|
12
13
|
|
|
@@ -43,6 +44,22 @@ export interface SubagentConfig {
|
|
|
43
44
|
sendResultToUser?: boolean;
|
|
44
45
|
/** Optional role for the subagent. Defaults handled by consumers. */
|
|
45
46
|
role?: SubagentRole;
|
|
47
|
+
/**
|
|
48
|
+
* When true, the sub-agent inherits the parent's full context instead of
|
|
49
|
+
* receiving only the objective + context fields.
|
|
50
|
+
*/
|
|
51
|
+
fork?: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* The parent conversation's in-memory message history at fork time.
|
|
54
|
+
* Only set when `fork: true`.
|
|
55
|
+
*/
|
|
56
|
+
parentMessages?: Message[];
|
|
57
|
+
/**
|
|
58
|
+
* The parent's current resolved system prompt. Only set when `fork: true`.
|
|
59
|
+
* Distinct from `systemPromptOverride` which replaces the subagent-built prompt;
|
|
60
|
+
* for forks, this IS the system prompt (no subagent preamble is built).
|
|
61
|
+
*/
|
|
62
|
+
parentSystemPrompt?: string;
|
|
46
63
|
}
|
|
47
64
|
|
|
48
65
|
// ── State (runtime) ─────────────────────────────────────────────────────
|
|
@@ -52,6 +69,8 @@ export interface SubagentState {
|
|
|
52
69
|
status: SubagentStatus;
|
|
53
70
|
/** The subagent's own conversationId (different from parentConversationId). */
|
|
54
71
|
conversationId: string;
|
|
72
|
+
/** Whether this sub-agent is a fork (inherits parent context). Defaults to `false`. */
|
|
73
|
+
isFork: boolean;
|
|
55
74
|
/** Error message if status is 'failed'. */
|
|
56
75
|
error?: string;
|
|
57
76
|
/** Timestamps (epoch ms). */
|
|
@@ -32,6 +32,7 @@ export interface ExecutorResult {
|
|
|
32
32
|
export interface AppStoreReader {
|
|
33
33
|
getApp(id: string): AppDefinition | null;
|
|
34
34
|
listApps(): AppDefinition[];
|
|
35
|
+
appFileExists(appId: string, path: string): boolean;
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
export interface AppStoreWriter {
|
|
@@ -183,8 +184,16 @@ function App() {
|
|
|
183
184
|
render(<App />, document.getElementById('app')!);
|
|
184
185
|
`;
|
|
185
186
|
|
|
186
|
-
|
|
187
|
-
|
|
187
|
+
// Only write scaffold files when they don't already exist on disk.
|
|
188
|
+
// The LLM may have written custom source files via file_write before
|
|
189
|
+
// calling app_create, and overwriting them would destroy the real app
|
|
190
|
+
// content, leaving only the scaffold placeholder.
|
|
191
|
+
if (!store.appFileExists(app.id, "src/index.html")) {
|
|
192
|
+
store.writeAppFile(app.id, "src/index.html", indexHtml);
|
|
193
|
+
}
|
|
194
|
+
if (!store.appFileExists(app.id, "src/main.tsx")) {
|
|
195
|
+
store.writeAppFile(app.id, "src/main.tsx", mainTsx);
|
|
196
|
+
}
|
|
188
197
|
|
|
189
198
|
// Compile src/ → dist/
|
|
190
199
|
const appDir = getAppDirPath(app.id);
|