dodo-mcp 1.0.0
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/LICENSE +21 -0
- package/README.md +425 -0
- package/dist/auth/adapter.js +43 -0
- package/dist/auth/adapter.js.map +1 -0
- package/dist/auth/clientDeletion.js +45 -0
- package/dist/auth/clientDeletion.js.map +1 -0
- package/dist/auth/clients.js +55 -0
- package/dist/auth/clients.js.map +1 -0
- package/dist/auth/constants.js +10 -0
- package/dist/auth/constants.js.map +1 -0
- package/dist/auth/interactions.js +184 -0
- package/dist/auth/interactions.js.map +1 -0
- package/dist/auth/keys.js +56 -0
- package/dist/auth/keys.js.map +1 -0
- package/dist/auth/provider.js +131 -0
- package/dist/auth/provider.js.map +1 -0
- package/dist/auth/verifier.js +74 -0
- package/dist/auth/verifier.js.map +1 -0
- package/dist/cli/kill.js +124 -0
- package/dist/cli/kill.js.map +1 -0
- package/dist/cli/main.js +1393 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/menu.js +127 -0
- package/dist/cli/menu.js.map +1 -0
- package/dist/cli/terminal.js +30 -0
- package/dist/cli/terminal.js.map +1 -0
- package/dist/config/globalConfig.js +144 -0
- package/dist/config/globalConfig.js.map +1 -0
- package/dist/config/limits.js +42 -0
- package/dist/config/limits.js.map +1 -0
- package/dist/config/paths.js +94 -0
- package/dist/config/paths.js.map +1 -0
- package/dist/config/projectConfig.js +63 -0
- package/dist/config/projectConfig.js.map +1 -0
- package/dist/config/stateImport.js +306 -0
- package/dist/config/stateImport.js.map +1 -0
- package/dist/config/tunnelConfig.js +23 -0
- package/dist/config/tunnelConfig.js.map +1 -0
- package/dist/errors.js +82 -0
- package/dist/errors.js.map +1 -0
- package/dist/evaluation/contracts.js +86 -0
- package/dist/evaluation/contracts.js.map +1 -0
- package/dist/evaluation/dodoBench.js +69 -0
- package/dist/evaluation/dodoBench.js.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/ipc/authentication.js +117 -0
- package/dist/ipc/authentication.js.map +1 -0
- package/dist/ipc/client.js +86 -0
- package/dist/ipc/client.js.map +1 -0
- package/dist/ipc/installationClient.js +83 -0
- package/dist/ipc/installationClient.js.map +1 -0
- package/dist/ipc/ownerControl.js +46 -0
- package/dist/ipc/ownerControl.js.map +1 -0
- package/dist/ipc/protocol.js +2 -0
- package/dist/ipc/protocol.js.map +1 -0
- package/dist/ipc/server.js +108 -0
- package/dist/ipc/server.js.map +1 -0
- package/dist/platform/execResolve.js +64 -0
- package/dist/platform/execResolve.js.map +1 -0
- package/dist/platform/fileIdentity.js +26 -0
- package/dist/platform/fileIdentity.js.map +1 -0
- package/dist/platform/fsRetry.js +22 -0
- package/dist/platform/fsRetry.js.map +1 -0
- package/dist/platform/pathPolicy.js +29 -0
- package/dist/platform/pathPolicy.js.map +1 -0
- package/dist/platform/privateFs.js +116 -0
- package/dist/platform/privateFs.js.map +1 -0
- package/dist/platform/processTree.js +31 -0
- package/dist/platform/processTree.js.map +1 -0
- package/dist/platform/shell.js +74 -0
- package/dist/platform/shell.js.map +1 -0
- package/dist/platform/speech.js +94 -0
- package/dist/platform/speech.js.map +1 -0
- package/dist/platform/system.js +28 -0
- package/dist/platform/system.js.map +1 -0
- package/dist/platform/windowsSandbox.js +129 -0
- package/dist/platform/windowsSandbox.js.map +1 -0
- package/dist/projects/federation.js +312 -0
- package/dist/projects/federation.js.map +1 -0
- package/dist/projects/registry.js +291 -0
- package/dist/projects/registry.js.map +1 -0
- package/dist/security/accessMode.js +19 -0
- package/dist/security/accessMode.js.map +1 -0
- package/dist/security/approvals.js +56 -0
- package/dist/security/approvals.js.map +1 -0
- package/dist/security/env.js +57 -0
- package/dist/security/env.js.map +1 -0
- package/dist/security/mutationQueue.js +78 -0
- package/dist/security/mutationQueue.js.map +1 -0
- package/dist/security/policy.js +22 -0
- package/dist/security/policy.js.map +1 -0
- package/dist/security/projectAuthority.js +22 -0
- package/dist/security/projectAuthority.js.map +1 -0
- package/dist/security/redact.js +30 -0
- package/dist/security/redact.js.map +1 -0
- package/dist/server/aiAdmin.js +201 -0
- package/dist/server/aiAdmin.js.map +1 -0
- package/dist/server/appServer.js +461 -0
- package/dist/server/appServer.js.map +1 -0
- package/dist/server/bootstrap.js +185 -0
- package/dist/server/bootstrap.js.map +1 -0
- package/dist/server/configUi/app.css +347 -0
- package/dist/server/configUi/app.js +958 -0
- package/dist/server/configUi/index.html +379 -0
- package/dist/server/configUi/ui/alerts.js +92 -0
- package/dist/server/configUi/ui/dom.js +19 -0
- package/dist/server/configUi/ui/tooltips.js +115 -0
- package/dist/server/configUi/vendor/VERSION.txt +1 -0
- package/dist/server/configUi/vendor/sweetalert2.min.css +1 -0
- package/dist/server/configUi/vendor/sweetalert2.min.js +5 -0
- package/dist/server/configUi/workbench.css +62 -0
- package/dist/server/configUi/workbench.js +394 -0
- package/dist/server/installationRuntime.js +155 -0
- package/dist/server/installationRuntime.js.map +1 -0
- package/dist/server/instructions.js +17 -0
- package/dist/server/instructions.js.map +1 -0
- package/dist/server/ipcDispatch.js +225 -0
- package/dist/server/ipcDispatch.js.map +1 -0
- package/dist/server/localConfig.js +561 -0
- package/dist/server/localConfig.js.map +1 -0
- package/dist/server/optionalServices.js +30 -0
- package/dist/server/optionalServices.js.map +1 -0
- package/dist/server/projectLease.js +46 -0
- package/dist/server/projectLease.js.map +1 -0
- package/dist/server/stdioServer.js +75 -0
- package/dist/server/stdioServer.js.map +1 -0
- package/dist/server/version.js +13 -0
- package/dist/server/version.js.map +1 -0
- package/dist/server/workspaceHost.js +194 -0
- package/dist/server/workspaceHost.js.map +1 -0
- package/dist/services/agent/agentService.js +598 -0
- package/dist/services/agent/agentService.js.map +1 -0
- package/dist/services/agent/contracts.js +102 -0
- package/dist/services/agent/contracts.js.map +1 -0
- package/dist/services/ai/adapters.js +287 -0
- package/dist/services/ai/adapters.js.map +1 -0
- package/dist/services/ai/contracts.js +39 -0
- package/dist/services/ai/contracts.js.map +1 -0
- package/dist/services/ai/credentials.js +77 -0
- package/dist/services/ai/credentials.js.map +1 -0
- package/dist/services/ai/network.js +113 -0
- package/dist/services/ai/network.js.map +1 -0
- package/dist/services/ai/settings.js +178 -0
- package/dist/services/ai/settings.js.map +1 -0
- package/dist/services/ai/subagents.js +468 -0
- package/dist/services/ai/subagents.js.map +1 -0
- package/dist/services/assistance/analysis.js +352 -0
- package/dist/services/assistance/analysis.js.map +1 -0
- package/dist/services/assistance/contracts.js +54 -0
- package/dist/services/assistance/contracts.js.map +1 -0
- package/dist/services/assistance/verification.js +274 -0
- package/dist/services/assistance/verification.js.map +1 -0
- package/dist/services/brain/brainParser.js +97 -0
- package/dist/services/brain/brainParser.js.map +1 -0
- package/dist/services/brain/brainService.js +733 -0
- package/dist/services/brain/brainService.js.map +1 -0
- package/dist/services/brain/brainWorker.js +212 -0
- package/dist/services/brain/brainWorker.js.map +1 -0
- package/dist/services/brain/contracts.js +154 -0
- package/dist/services/brain/contracts.js.map +1 -0
- package/dist/services/brain/protocol.js +2 -0
- package/dist/services/brain/protocol.js.map +1 -0
- package/dist/services/changes/applier.js +544 -0
- package/dist/services/changes/applier.js.map +1 -0
- package/dist/services/changes/contentBudget.js +11 -0
- package/dist/services/changes/contentBudget.js.map +1 -0
- package/dist/services/changes/planner.js +284 -0
- package/dist/services/changes/planner.js.map +1 -0
- package/dist/services/changes/types.js +3 -0
- package/dist/services/changes/types.js.map +1 -0
- package/dist/services/context/contextEngine.js +746 -0
- package/dist/services/context/contextEngine.js.map +1 -0
- package/dist/services/context/contracts.js +88 -0
- package/dist/services/context/contracts.js.map +1 -0
- package/dist/services/desktop/desktopPolicy.js +76 -0
- package/dist/services/desktop/desktopPolicy.js.map +1 -0
- package/dist/services/desktop/desktopService.js +130 -0
- package/dist/services/desktop/desktopService.js.map +1 -0
- package/dist/services/desktop/nativeBackend.js +174 -0
- package/dist/services/desktop/nativeBackend.js.map +1 -0
- package/dist/services/desktop/protocol.js +32 -0
- package/dist/services/desktop/protocol.js.map +1 -0
- package/dist/services/files/readService.js +136 -0
- package/dist/services/files/readService.js.map +1 -0
- package/dist/services/git/gitService.js +369 -0
- package/dist/services/git/gitService.js.map +1 -0
- package/dist/services/intelligence/intelService.js +136 -0
- package/dist/services/intelligence/intelService.js.map +1 -0
- package/dist/services/intelligence/protocol.js +2 -0
- package/dist/services/intelligence/protocol.js.map +1 -0
- package/dist/services/intelligence/tsWorker.js +419 -0
- package/dist/services/intelligence/tsWorker.js.map +1 -0
- package/dist/services/jobs/commandInput.js +34 -0
- package/dist/services/jobs/commandInput.js.map +1 -0
- package/dist/services/jobs/jobManager.js +398 -0
- package/dist/services/jobs/jobManager.js.map +1 -0
- package/dist/services/jobs/sandbox.js +156 -0
- package/dist/services/jobs/sandbox.js.map +1 -0
- package/dist/services/jobs/sandboxWiring.js +37 -0
- package/dist/services/jobs/sandboxWiring.js.map +1 -0
- package/dist/services/jobs/spool.js +112 -0
- package/dist/services/jobs/spool.js.map +1 -0
- package/dist/services/jobs/windowsSandboxChild.js +24 -0
- package/dist/services/jobs/windowsSandboxChild.js.map +1 -0
- package/dist/services/jobs/windowsSandboxWorker.js +155 -0
- package/dist/services/jobs/windowsSandboxWorker.js.map +1 -0
- package/dist/services/lsp/documentUri.js +16 -0
- package/dist/services/lsp/documentUri.js.map +1 -0
- package/dist/services/lsp/jsonrpc.js +382 -0
- package/dist/services/lsp/jsonrpc.js.map +1 -0
- package/dist/services/lsp/lspService.js +1051 -0
- package/dist/services/lsp/lspService.js.map +1 -0
- package/dist/services/memory/contracts.js +94 -0
- package/dist/services/memory/contracts.js.map +1 -0
- package/dist/services/memory/memoryService.js +683 -0
- package/dist/services/memory/memoryService.js.map +1 -0
- package/dist/services/multimodal/browserService.js +407 -0
- package/dist/services/multimodal/browserService.js.map +1 -0
- package/dist/services/multimodal/byteRange.js +31 -0
- package/dist/services/multimodal/byteRange.js.map +1 -0
- package/dist/services/multimodal/contracts.js +59 -0
- package/dist/services/multimodal/contracts.js.map +1 -0
- package/dist/services/multimodal/gameService.js +95 -0
- package/dist/services/multimodal/gameService.js.map +1 -0
- package/dist/services/multimodal/images.js +107 -0
- package/dist/services/multimodal/images.js.map +1 -0
- package/dist/services/multimodal/mediaService.js +279 -0
- package/dist/services/multimodal/mediaService.js.map +1 -0
- package/dist/services/multimodal/mediaWorker.js +143 -0
- package/dist/services/multimodal/mediaWorker.js.map +1 -0
- package/dist/services/multimodal/multimodalService.js +51 -0
- package/dist/services/multimodal/multimodalService.js.map +1 -0
- package/dist/services/multimodal/network.js +69 -0
- package/dist/services/multimodal/network.js.map +1 -0
- package/dist/services/multimodal/operations.js +40 -0
- package/dist/services/multimodal/operations.js.map +1 -0
- package/dist/services/multimodal/storage.js +160 -0
- package/dist/services/multimodal/storage.js.map +1 -0
- package/dist/services/multimodal/workflowService.js +179 -0
- package/dist/services/multimodal/workflowService.js.map +1 -0
- package/dist/services/overview.js +284 -0
- package/dist/services/overview.js.map +1 -0
- package/dist/services/resources/casStore.js +304 -0
- package/dist/services/resources/casStore.js.map +1 -0
- package/dist/services/resources/contracts.js +75 -0
- package/dist/services/resources/contracts.js.map +1 -0
- package/dist/services/resources/mime.js +77 -0
- package/dist/services/resources/mime.js.map +1 -0
- package/dist/services/resources/providerRegistry.js +22 -0
- package/dist/services/resources/providerRegistry.js.map +1 -0
- package/dist/services/resources/providers.js +120 -0
- package/dist/services/resources/providers.js.map +1 -0
- package/dist/services/resources/resourceService.js +282 -0
- package/dist/services/resources/resourceService.js.map +1 -0
- package/dist/services/runtime/contracts.js +65 -0
- package/dist/services/runtime/contracts.js.map +1 -0
- package/dist/services/runtime/runtimeService.js +364 -0
- package/dist/services/runtime/runtimeService.js.map +1 -0
- package/dist/services/schedules/scheduleService.js +198 -0
- package/dist/services/schedules/scheduleService.js.map +1 -0
- package/dist/services/search/searchService.js +434 -0
- package/dist/services/search/searchService.js.map +1 -0
- package/dist/services/search/searchWorker.js +58 -0
- package/dist/services/search/searchWorker.js.map +1 -0
- package/dist/setup/componentProbes.js +259 -0
- package/dist/setup/componentProbes.js.map +1 -0
- package/dist/setup/download.js +139 -0
- package/dist/setup/download.js.map +1 -0
- package/dist/setup/managedTools.js +118 -0
- package/dist/setup/managedTools.js.map +1 -0
- package/dist/setup/sandboxProbe.js +172 -0
- package/dist/setup/sandboxProbe.js.map +1 -0
- package/dist/setup/setup.js +522 -0
- package/dist/setup/setup.js.map +1 -0
- package/dist/setup/windowsChromiumAcl.js +56 -0
- package/dist/setup/windowsChromiumAcl.js.map +1 -0
- package/dist/setup/windowsSandboxInstall.js +94 -0
- package/dist/setup/windowsSandboxInstall.js.map +1 -0
- package/dist/setup/windowsSpeechInstall.js +86 -0
- package/dist/setup/windowsSpeechInstall.js.map +1 -0
- package/dist/store/db.js +711 -0
- package/dist/store/db.js.map +1 -0
- package/dist/store/scopeEncoding.js +15 -0
- package/dist/store/scopeEncoding.js.map +1 -0
- package/dist/store/store.js +467 -0
- package/dist/store/store.js.map +1 -0
- package/dist/tools/agentRuntimeTools.js +216 -0
- package/dist/tools/agentRuntimeTools.js.map +1 -0
- package/dist/tools/agentTools.js +317 -0
- package/dist/tools/agentTools.js.map +1 -0
- package/dist/tools/assistanceTools.js +126 -0
- package/dist/tools/assistanceTools.js.map +1 -0
- package/dist/tools/brainTools.js +130 -0
- package/dist/tools/brainTools.js.map +1 -0
- package/dist/tools/catalog.js +30 -0
- package/dist/tools/catalog.js.map +1 -0
- package/dist/tools/changeTools.js +188 -0
- package/dist/tools/changeTools.js.map +1 -0
- package/dist/tools/context.js +243 -0
- package/dist/tools/context.js.map +1 -0
- package/dist/tools/contextTools.js +57 -0
- package/dist/tools/contextTools.js.map +1 -0
- package/dist/tools/coreCatalog.js +82 -0
- package/dist/tools/coreCatalog.js.map +1 -0
- package/dist/tools/desktopTools.js +41 -0
- package/dist/tools/desktopTools.js.map +1 -0
- package/dist/tools/directTools.js +273 -0
- package/dist/tools/directTools.js.map +1 -0
- package/dist/tools/envelope.js +71 -0
- package/dist/tools/envelope.js.map +1 -0
- package/dist/tools/extraTools.js +298 -0
- package/dist/tools/extraTools.js.map +1 -0
- package/dist/tools/gitTools.js +93 -0
- package/dist/tools/gitTools.js.map +1 -0
- package/dist/tools/jobTools.js +454 -0
- package/dist/tools/jobTools.js.map +1 -0
- package/dist/tools/memoryTools.js +102 -0
- package/dist/tools/memoryTools.js.map +1 -0
- package/dist/tools/metaTools.js +153 -0
- package/dist/tools/metaTools.js.map +1 -0
- package/dist/tools/multimodalTools.js +262 -0
- package/dist/tools/multimodalTools.js.map +1 -0
- package/dist/tools/projectTools.js +261 -0
- package/dist/tools/projectTools.js.map +1 -0
- package/dist/tools/resourceTools.js +81 -0
- package/dist/tools/resourceTools.js.map +1 -0
- package/dist/tools/runtimeTools.js +137 -0
- package/dist/tools/runtimeTools.js.map +1 -0
- package/dist/tools/scheduleTools.js +10 -0
- package/dist/tools/scheduleTools.js.map +1 -0
- package/dist/tools/semanticTools.js +141 -0
- package/dist/tools/semanticTools.js.map +1 -0
- package/dist/tools/subagentTools.js +32 -0
- package/dist/tools/subagentTools.js.map +1 -0
- package/dist/tools/surface.js +644 -0
- package/dist/tools/surface.js.map +1 -0
- package/dist/tunnel/control.js +113 -0
- package/dist/tunnel/control.js.map +1 -0
- package/dist/tunnel/credentials.js +392 -0
- package/dist/tunnel/credentials.js.map +1 -0
- package/dist/tunnel/log.js +84 -0
- package/dist/tunnel/log.js.map +1 -0
- package/dist/tunnel/runtime.js +55 -0
- package/dist/tunnel/runtime.js.map +1 -0
- package/dist/tunnel/supervisor.js +280 -0
- package/dist/tunnel/supervisor.js.map +1 -0
- package/dist/util/bytes.js +53 -0
- package/dist/util/bytes.js.map +1 -0
- package/dist/util/hash.js +53 -0
- package/dist/util/hash.js.map +1 -0
- package/dist/workspace/fs.js +305 -0
- package/dist/workspace/fs.js.map +1 -0
- package/dist/workspace/identity.js +17 -0
- package/dist/workspace/identity.js.map +1 -0
- package/dist/workspace/ignores.js +173 -0
- package/dist/workspace/ignores.js.map +1 -0
- package/dist/workspace/root.js +59 -0
- package/dist/workspace/root.js.map +1 -0
- package/docs/AGENT_RUNTIME.md +154 -0
- package/docs/AI_PROVIDERS.md +110 -0
- package/docs/ARCHITECTURE.md +331 -0
- package/docs/ASSISTANCE.md +31 -0
- package/docs/AUTH.md +59 -0
- package/docs/BRAIN.md +92 -0
- package/docs/COMPATIBILITY.md +92 -0
- package/docs/CONFIRMATION.md +13 -0
- package/docs/CONTEXT.md +87 -0
- package/docs/DESKTOP.md +35 -0
- package/docs/EVALUATION.md +86 -0
- package/docs/LARGE_INPUTS.md +21 -0
- package/docs/LSP.md +21 -0
- package/docs/MANUAL_ACCEPTANCE.md +283 -0
- package/docs/MEMORY.md +128 -0
- package/docs/MULTIMODAL.md +32 -0
- package/docs/PROJECTS.md +146 -0
- package/docs/RELEASE_1.0.0.md +111 -0
- package/docs/RELEASE_NOTES.md +92 -0
- package/docs/RESOURCES.md +83 -0
- package/docs/RUNTIME.md +125 -0
- package/docs/SCHEDULES.md +23 -0
- package/docs/SECURITY.md +250 -0
- package/docs/TEST_REPORT.md +312 -0
- package/docs/TUNNEL.md +86 -0
- package/docs/WEB_CLIENTS.md +43 -0
- package/docs/WINDOWS.md +79 -0
- package/docs/adr/001-one-process-one-workspace.md +22 -0
- package/docs/adr/002-external-tunnel.md +19 -0
- package/docs/adr/003-sdk-v2-legacy-stateless.md +20 -0
- package/docs/adr/004-embedded-oauth-provider.md +19 -0
- package/docs/adr/005-static-client-baseline.md +19 -0
- package/docs/adr/006-guarded-fs-explicit-exec.md +16 -0
- package/docs/adr/007-preview-hash-journal.md +18 -0
- package/docs/adr/008-ts-js-semantics-first.md +17 -0
- package/docs/adr/009-jobs-polling.md +18 -0
- package/docs/adr/010-sqlite-better-sqlite3.md +18 -0
- package/docs/adr/011-env-example-secure-default.md +19 -0
- package/docs/adr/012-workspace-scope-grant.md +24 -0
- package/docs/adr/013-loopback-proxy-trust.md +18 -0
- package/docs/adr/014-direct-coding-tier.md +48 -0
- package/docs/adr/015-coding-agent-parity.md +56 -0
- package/docs/adr/016-oidc-openid-consent.md +15 -0
- package/docs/adr/017-installation-identity-local-config.md +44 -0
- package/docs/adr/018-access-scope-encoding.md +11 -0
- package/docs/adr/019-runtime-workspace-switch.md +59 -0
- package/docs/adr/020-desktop-access.md +50 -0
- package/docs/adr/021-persistent-desktop-consent.md +39 -0
- package/docs/adr/022-owner-kill-preserves-login.md +30 -0
- package/docs/adr/023-large-coding-inputs.md +49 -0
- package/docs/adr/024-usage-rounds-and-schedules.md +72 -0
- package/docs/adr/025-owner-chat-whitelist.md +53 -0
- package/docs/adr/026-remove-conversation-confirmation.md +35 -0
- package/docs/adr/027-workspace-client-list.md +20 -0
- package/docs/adr/028-owner-client-deletion.md +25 -0
- package/docs/adr/029-compact-tool-surface.md +121 -0
- package/docs/adr/030-windows-native-candidate.md +71 -0
- package/docs/adr/031-owner-selected-tunnel-supervision.md +13 -0
- package/docs/adr/032-owner-project-registry.md +43 -0
- package/docs/adr/033-read-only-project-federation.md +61 -0
- package/docs/adr/034-universal-resource-cas.md +60 -0
- package/docs/adr/035-project-brain-incremental-index.md +51 -0
- package/docs/adr/036-context-engine-evidence.md +53 -0
- package/docs/adr/037-owner-reviewed-memory.md +46 -0
- package/docs/adr/038-runtime-intelligence.md +46 -0
- package/docs/adr/039-advanced-agent-runtime.md +57 -0
- package/docs/adr/040-dodobench-release-gate.md +43 -0
- package/docs/adr/041-local-macos-docker-linux-gates.md +32 -0
- package/docs/adr/042-project-directory-generation-identity.md +36 -0
- package/docs/adr/043-trusted-self-hosted-platform-gates.md +38 -0
- package/docs/adr/044-global-launcher-and-cli-menu.md +43 -0
- package/docs/adr/045-ai-providers-multiproject.md +56 -0
- package/docs/adr/046-personal-access-mode.md +32 -0
- package/docs/adr/README.md +64 -0
- package/examples/.dodo.json.example +20 -0
- package/examples/cloudflared.yml +23 -0
- package/examples/reverse-proxy-fixture.mjs +37 -0
- package/native/desktop-linux.py +387 -0
- package/native/desktop-windows.cs +180 -0
- package/native/desktop.swift +212 -0
- package/package.json +145 -0
- package/schemas/global-config.schema.json +497 -0
- package/schemas/project-config.schema.json +75 -0
- package/schemas/tools.compact.json +3236 -0
- package/schemas/tools.hybrid.json +8194 -0
- package/schemas/tools.json +34518 -0
- package/scripts/guard-publish.mjs +12 -0
- package/scripts/setup-multimodal.mjs +70 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# 017 — Installation identity, workspace ACL and private config (baseline)
|
|
2
|
+
|
|
3
|
+
Owner-requested change supersedes the original per-workspace OAuth grant-only
|
|
4
|
+
contract. One running process still serves one canonical CWD/root and epoch.
|
|
5
|
+
|
|
6
|
+
New consent records are marked `identity-grant:<id> = 2` in durable metadata.
|
|
7
|
+
Tokens carry `dodo_auth: 2`. Verification requires both markers, issuer,
|
|
8
|
+
audience, expiry, live grant and matching client. Resource scopes never exceed
|
|
9
|
+
the token/grant intersection. Personal mode applies that ceiling to registered
|
|
10
|
+
projects; managed mode also intersects the current workspace/client ACL.
|
|
11
|
+
No remote tool can register a path or grant itself access. Refresh preserves
|
|
12
|
+
grant version.
|
|
13
|
+
|
|
14
|
+
OAuth consent is installation-scoped and does not follow the active workspace
|
|
15
|
+
or the CLI process CWD. Completing login never creates a workspace ACL. An
|
|
16
|
+
authenticated client may scan the bounded tool catalog before a project is
|
|
17
|
+
selected. Operations require a real owner-registered project; only managed
|
|
18
|
+
mode requires an additional explicit client ACL there. Pending/approve/deny and
|
|
19
|
+
grant revocation locate the authenticated live HTTP installation process from
|
|
20
|
+
private per-instance IPC metadata, so owner commands work from any directory.
|
|
21
|
+
|
|
22
|
+
Migration 3 creates workspace_clients and copies active legacy grant scopes to
|
|
23
|
+
their original paths only. Legacy tokens remain bound to their original root.
|
|
24
|
+
Users log in once to receive the new identity grant. Revocation still checks
|
|
25
|
+
the live grant on every request. Root inode/device replacement resets saved
|
|
26
|
+
trust and client ACLs. Changing mode does not cancel already launched jobs.
|
|
27
|
+
|
|
28
|
+
Bare dodo now starts HTTP regardless of stdin. MCP subprocess clients must
|
|
29
|
+
explicitly use stdio. CLI HTTP starts local config at 127.0.0.1:21731, separate
|
|
30
|
+
from MCP 21730. Library callers opt in with configPort (0 supported for tests).
|
|
31
|
+
Admin API requires an 8-hour, random 256-bit per-process bearer capability,
|
|
32
|
+
passed in the terminal URL fragment, never query strings. The page moves it to
|
|
33
|
+
sessionStorage and strips the fragment. It rejects nonlocal hosts, foreign
|
|
34
|
+
origins, cross-site fetches and proxy/Cloudflare headers. No CORS or public
|
|
35
|
+
admin route. Same-UID adversaries and intentionally rewritten owner proxies
|
|
36
|
+
are not an isolation boundary. No remote config opt-in in this release.
|
|
37
|
+
|
|
38
|
+
--allow --all: run-only trusted actions and fetch_url; configured job sandbox.
|
|
39
|
+
--bypass: same plus default commandSandbox off. Neither changes durable trust,
|
|
40
|
+
OAuth, target authority, file guard, hashes or epoch checks. Flags do not alter
|
|
41
|
+
client application's own confirmations. They are local owner capabilities.
|
|
42
|
+
|
|
43
|
+
Recovery journal reconciliation, recovery status and interrupted-job updates
|
|
44
|
+
are scoped to the selected workspace, to avoid modifying another root's state.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# 018 — ACL scope encoding contract
|
|
2
|
+
|
|
3
|
+
OAuth grants store a space-separated scope list while `workspace_clients`
|
|
4
|
+
stores JSON arrays. Schema migration must normalize the two representations
|
|
5
|
+
without widening permissions.
|
|
6
|
+
|
|
7
|
+
A transactional schema step normalizes recognized space-delimited scope lists
|
|
8
|
+
and existing JSON ACLs. Invalid or unknown entries become empty ACLs, never new
|
|
9
|
+
permissions. Empty ACLs remain empty, existing grants are not recopied on
|
|
10
|
+
reopen, and runtime JSON decoding fails closed. Tests cover each supported
|
|
11
|
+
schema transition and already-normalized state.
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# 019 — Runtime workspace switch from Local Config (workspace lifecycle)
|
|
2
|
+
|
|
3
|
+
Supersedes the "no runtime root change" statement of ADR-001 for the HTTP
|
|
4
|
+
entry. One `dodo start` process still serves exactly one ACTIVE workspace at
|
|
5
|
+
any moment, but the owner can move it to another directory from the Local
|
|
6
|
+
Config page without restarting, re-authorizing OAuth clients, or losing state.
|
|
7
|
+
|
|
8
|
+
## Decision
|
|
9
|
+
|
|
10
|
+
- A `WorkspaceHost` (`src/server/workspaceHost.ts`) owns the active
|
|
11
|
+
`BootstrappedWorkspace`. The MCP server factory, the token verifier, the
|
|
12
|
+
consent router, the IPC dispatcher and the config plane resolve the active
|
|
13
|
+
workspace **per request** instead of capturing it in a closure.
|
|
14
|
+
- OAuth and consent state use an installation-scoped store connection that
|
|
15
|
+
outlives any workspace; a workspace's own connection is closed when it is
|
|
16
|
+
switched out.
|
|
17
|
+
- The switch is **owner-only**: `POST /api/workspace/switch` on the loopback
|
|
18
|
+
config plane, behind the private capability. There is no MCP tool that can
|
|
19
|
+
change the root, and the boot-time `--allow-unsafe-root` never applies to a
|
|
20
|
+
switch (the strict root policy always does).
|
|
21
|
+
- Order of operations: validate (absolute path → realpath → shared root
|
|
22
|
+
policy) → refuse if jobs run → mark `switching` (new MCP calls get 503 +
|
|
23
|
+
Retry-After) → drain in-flight calls (bounded) → re-check jobs → refuse if
|
|
24
|
+
another live process serves the target (its IPC socket answers) → bootstrap
|
|
25
|
+
the new workspace (new workspaceId + fresh epoch, its own trust and ACL rows,
|
|
26
|
+
journal reconcile scoped to it) → readiness check → start its IPC socket →
|
|
27
|
+
**commit** → shut down the old IPC socket and services → deny orphaned
|
|
28
|
+
pending approvals of the old workspace/epoch → audit.
|
|
29
|
+
- Any failure before commit discards the half-built workspace and leaves the
|
|
30
|
+
old one serving; failures after commit are logged and never roll back.
|
|
31
|
+
- Nothing is copied between workspaces. Managed mode uses the new root's saved
|
|
32
|
+
trust mode and client ACL rows; personal mode derives trusted policy and
|
|
33
|
+
target scopes from the owner-approved installation grant. In both modes,
|
|
34
|
+
context captured from the old workspace fails
|
|
35
|
+
`WORKSPACE_MISMATCH` / `STALE_WORKSPACE`; plans expire; the run mode
|
|
36
|
+
(`--allow --all` / `--bypass`) is a per-process owner capability and
|
|
37
|
+
carries over.
|
|
38
|
+
- The IPC socket path follows the workspace id, so `dodo status/stop/approve`
|
|
39
|
+
run from the new directory find the server; the old socket is removed.
|
|
40
|
+
|
|
41
|
+
## Consequences
|
|
42
|
+
|
|
43
|
+
- Clients must call `project_overview` again after a switch (the page says so).
|
|
44
|
+
- `STALE_WORKSPACE` / `PLAN_EXPIRED` wording now mentions a switch.
|
|
45
|
+
- Two `BootstrappedWorkspace` instances coexist briefly (WAL SQLite); the old
|
|
46
|
+
one is only torn down after the swap, so no request sees a closed store.
|
|
47
|
+
- Refusals are explicit and typed (409 CONFLICT for jobs/in-flight/other
|
|
48
|
+
process, 400 for invalid targets, 501 for entries without switching).
|
|
49
|
+
- Tests: `tests/security/workspaceSwitch.test.ts` (WS-01..06) and the Local
|
|
50
|
+
Config suite; manual browser checks are listed in MANUAL_ACCEPTANCE.md.
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
## workspace lifecycle corrections
|
|
54
|
+
|
|
55
|
+
Local admin mutations are bound to the reviewed workspace and epoch, not just
|
|
56
|
+
the current root at arrival. Independent tool leases survive client disconnects.
|
|
57
|
+
The switch gate stays closed through old-resource teardown. Shutdown closes
|
|
58
|
+
old HTTP connections before OAuth stores, and retains handler resources until
|
|
59
|
+
completion. Regression evidence: WS-07, WS-08 and WS-09.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# ADR-020 — Local, app-scoped macOS desktop access
|
|
2
|
+
|
|
3
|
+
Date: 2026-09-09. Status: accepted for desktop integration. The owner's explicit desktop
|
|
4
|
+
feature request supersedes v1's prohibition on desktop automation; it does not
|
|
5
|
+
remove OAuth, workspace identity, local authorization or the file guards.
|
|
6
|
+
|
|
7
|
+
The owner later requested one-time saved desktop configuration. The optional
|
|
8
|
+
persistent-grant behavior in [ADR-021](021-persistent-desktop-consent.md)
|
|
9
|
+
supersedes only the mandatory expiration/boot reset described below for
|
|
10
|
+
explicitly remembered grants; temporary grants retain this original behavior.
|
|
11
|
+
|
|
12
|
+
Use a bundled Swift helper, explicitly compiled by `dodo desktop setup` with
|
|
13
|
+
Apple Command Line Tools. No install lifecycle hooks, external relay, downloaded
|
|
14
|
+
executables, arbitrary AppleScript, clipboard or autonomous LLM loop. This
|
|
15
|
+
keeps one npm package and uses Apple's native permission checks:
|
|
16
|
+
|
|
17
|
+
- [ScreenCaptureKit / SCScreenshotManager](https://developer.apple.com/documentation/screencapturekit/scscreenshotmanager): bounded single-window capture on macOS 14+.
|
|
18
|
+
- [CGEvent](https://developer.apple.com/documentation/coregraphics/cgevent): explicit mouse/keyboard input; CGPreflightScreenCaptureAccess and AXIsProcessTrusted gate native operations.
|
|
19
|
+
- [Vision text recognition](https://developer.apple.com/documentation/vision/vnrecognizetextrequest): optional local OCR. UI text is data, never authorization.
|
|
20
|
+
|
|
21
|
+
APIs were verified by compiling against the installed Apple SDK and testing a
|
|
22
|
+
native fixture on macOS 26.3.1 arm64. The SDK's CGEvent.h notes that application
|
|
23
|
+
frameworks may ignore an event's Unicode string; callers must verify the result.
|
|
24
|
+
The [Desktop Commander project](https://github.com/wonderwhy-er/DesktopCommanderMCP)
|
|
25
|
+
and available connector catalog informed the comparison only; no assertion
|
|
26
|
+
about its hosted internals or complete parity is made.
|
|
27
|
+
|
|
28
|
+
Desktop authorization is off by default and a separate, expiring, exact-app
|
|
29
|
+
allowlist stored per workspace/boot epoch. Only private owner IPC enables it;
|
|
30
|
+
private Local Config can revoke. All image/UI tools beyond non-content status
|
|
31
|
+
require dodo:exec and the current client/path ACL, including over OAuth. View
|
|
32
|
+
permission enables reading; control additionally uses the existing exec trust
|
|
33
|
+
and exact local action approval gate. Run overrides do not enable desktop.
|
|
34
|
+
|
|
35
|
+
Snapshot IDs bind principal, workspace service/epoch, grant, window PID/id/app,
|
|
36
|
+
geometry and image-coordinate mapping for at most 30 seconds. Actions use a
|
|
37
|
+
single service mutex; all snapshots are invalidated before dispatch. A durable
|
|
38
|
+
started receipt precedes input, and uncertain outcomes are never automatically
|
|
39
|
+
repeated. Native checks require a frontmost matching window for input and check
|
|
40
|
+
point occlusion; they do not freeze the UI or form a same-UID security boundary.
|
|
41
|
+
|
|
42
|
+
Image bytes and typed text are not persisted in the state/audit; file-image
|
|
43
|
+
reads still use WorkspaceFS. Native helper input/output, OCR, AX traversal,
|
|
44
|
+
action size, process time and receipt count are bounded. Stop prevents future
|
|
45
|
+
dispatch, not rollback of OS events already posted.
|
|
46
|
+
|
|
47
|
+
Native compile/capture/OCR and refusal without Accessibility passed. Positive
|
|
48
|
+
Accessibility/input acceptance remains MANUAL_NOT_RUN because the machine did
|
|
49
|
+
not grant that OS permission. Default tests use a fake OS adapter so they never
|
|
50
|
+
click a user's screen; HTTP/OAuth/IPC/SQLite policy tests remain real.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# ADR-021 — Remember desktop consent for an installation
|
|
2
|
+
|
|
3
|
+
Date: 2026-09-09. Status: accepted for persistent desktop consent at the owner's explicit request.
|
|
4
|
+
|
|
5
|
+
`dodo desktop allow --app <exact-bundle-ids> --mode view|control --persist --yes`
|
|
6
|
+
saves standing consent until disabled. It works before a server is started.
|
|
7
|
+
Without `--persist`, consent retains the 60-minute default (1–480 configurable)
|
|
8
|
+
and expires on boot/root switch. Mixing `--persist` and `--minutes` is rejected.
|
|
9
|
+
Every persistent allow replaces the installation app/mode grant.
|
|
10
|
+
|
|
11
|
+
Use the existing private SQLite meta store keyed by installation. No project
|
|
12
|
+
file, public endpoint or MCP tool can set this policy. Saved consent applies to
|
|
13
|
+
all registered project runtimes but does not grant OAuth scopes, register roots,
|
|
14
|
+
change exec trust or relax snapshot checks. Temporary grants remain keyed by
|
|
15
|
+
workspace and epoch. The local CLI and owner IPC/UI
|
|
16
|
+
share one validated writer. CLI save/disable use local SQLite directly, like
|
|
17
|
+
the existing trust command, so neither needs a running server. There is no
|
|
18
|
+
automatic listener, native helper setup or OS permission prompt.
|
|
19
|
+
|
|
20
|
+
The stored policy adds `persistent` (legacy default false), `revision` (UUID),
|
|
21
|
+
and nullable `expiresAt` (null only for explicitly persistent grants). On read,
|
|
22
|
+
persistent consent binds the current service epoch. Every replacement receives
|
|
23
|
+
a new revision; running services re-read it before work, so old snapshots and
|
|
24
|
+
action approvals cannot survive a CLI change even with identical apps/mode.
|
|
25
|
+
Snapshots remain principal-bound and at most 30 seconds. Uncertain action
|
|
26
|
+
receipts remain durable and never auto-replay after restart.
|
|
27
|
+
|
|
28
|
+
`dodo desktop disable` and the private config stop button revoke AND forget the
|
|
29
|
+
installation grant. They prevent future dispatch; neither can retract an already
|
|
30
|
+
posted OS event. Exact named-app allowlisting remains mandatory. Same-UID
|
|
31
|
+
processes remain outside the security boundary.
|
|
32
|
+
|
|
33
|
+
Evidence: existing Zod 4 and better-sqlite3 13.0.3 APIs, no new dependencies or
|
|
34
|
+
native code. Unit cases cover old records, malformed records, expiry versus
|
|
35
|
+
persistence, roots/epochs, revision invalidation and cross-connection revocation.
|
|
36
|
+
Real CLI tests save offline, start/restart a nested Thai/space path, reuse the
|
|
37
|
+
grant from its parent, then revoke while stopped. HTTP/OAuth tests retain scope,
|
|
38
|
+
workspace snapshot and action boundaries with a fake OS adapter. Final outcomes are recorded
|
|
39
|
+
in TEST_REPORT; this change does not claim new native click/type acceptance.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# ADR-022 — CWD-independent owner shutdown preserves OAuth identity
|
|
2
|
+
|
|
3
|
+
Date: 2026-09-09. Status: accepted for owner shutdown, requested by the owner.
|
|
4
|
+
|
|
5
|
+
Implement `dodo kill` as a lifecycle command over private IPC, not process-name
|
|
6
|
+
matching or a signal to whatever owns 21730. Resolve the owner's installation
|
|
7
|
+
config independently of CWD and read the SQLite workspace registry without
|
|
8
|
+
writing/migrating auth data. Old versions are discoverable through their root
|
|
9
|
+
sockets. New versions also maintain a unique per-instance control socket and
|
|
10
|
+
ephemeral metadata so multiple stdio clients of the same root stay discoverable.
|
|
11
|
+
|
|
12
|
+
Validate private same-user sockets, live status/root/workspace and endpoint
|
|
13
|
+
identity. Stop requests include expected PID/epoch; new servers reject stale
|
|
14
|
+
values. Probe first and deduplicate processes before dispatching stops. Bound
|
|
15
|
+
concurrency to eight, response bytes and wait durations. Report failures rather
|
|
16
|
+
than silently force-killing a hung or unregistered process. Another
|
|
17
|
+
DODO_CONFIG_DIR is a separate installation; never scan other users/configs.
|
|
18
|
+
|
|
19
|
+
Cancel owned jobs before draining handlers that may wait for their completion.
|
|
20
|
+
Prevent new jobs once shutdown starts and share the close promise with repeated
|
|
21
|
+
callers. Library shutdown closes resources; the CLI exits after completion.
|
|
22
|
+
Keep OAuth keys, clients, tokens, grants, config and ACLs. Restore neither
|
|
23
|
+
expired/revoked credentials nor missing client access to another root.
|
|
24
|
+
|
|
25
|
+
Tests cover real child HTTP/stdio processes, duplicate stdio roots, unrelated
|
|
26
|
+
process/config preservation, owned job cancellation, and real OAuth access plus
|
|
27
|
+
refresh credentials after restart. Negative cases cover spoofed status,
|
|
28
|
+
symlink/non-private sockets, stale stop identity, oversized IPC and timeout.
|
|
29
|
+
Actual ChatGPT automatic reconnect is a manual gate; local token continuity
|
|
30
|
+
does not prove client retry behavior. See TEST_REPORT for commands/outcomes.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# ADR-023: Large coding inputs with owner-controlled budgets
|
|
2
|
+
|
|
3
|
+
Date: 2026-09-09. Status: accepted in large-input policy (source/local).
|
|
4
|
+
|
|
5
|
+
## Problem
|
|
6
|
+
|
|
7
|
+
The original 8,192-character shell field and 4,096-character argv elements
|
|
8
|
+
blocked ordinary generated web source. Raising only the schema cap would
|
|
9
|
+
still hit native execve limits. Unlimited requests would make memory use
|
|
10
|
+
unbounded, and old persisted configs would retain their small limits.
|
|
11
|
+
|
|
12
|
+
## Decision
|
|
13
|
+
|
|
14
|
+
Use owner-selected `dodo limits --profile standard|large`; merge only input
|
|
15
|
+
budgets into trusted global config and require restart. Preserve saved values
|
|
16
|
+
on upgrade. Expose active budgets via project_overview. Command source is
|
|
17
|
+
checked in UTF-8 bytes (default 1 MiB, maximum 8 MiB); direct source schemas
|
|
18
|
+
support up to 16 MiB with lower active file/plan/request limits enforced.
|
|
19
|
+
Native argv remains independently bounded to 64 KiB per element, 128 KiB total.
|
|
20
|
+
|
|
21
|
+
Shell source above 16 KiB runs as a mode-0600 private script under an owned
|
|
22
|
+
mode-0700 job directory. No source in native argv, no stdin consumption, no
|
|
23
|
+
workspace source artifact. Record job ownership before spawning. The normal
|
|
24
|
+
job lifecycle removes scripts on exit/cancel/spawn failure. Crash residue is
|
|
25
|
+
never rerun. Script semantics (`$0` points to the script) are documented.
|
|
26
|
+
Scopes, trust, sandbox requests, idempotency and owned process cancellation
|
|
27
|
+
still apply. Validate every batch command's size/NUL before launching any.
|
|
28
|
+
|
|
29
|
+
Keep response/log caps. Bound echoed commands/argv. Skip diff construction for
|
|
30
|
+
combined before/after content above 2 MiB; smaller diffs use abortable budgets.
|
|
31
|
+
Preflight literal replacement expansion and incrementally bound patch/bulk
|
|
32
|
+
result content. Full hashes, backups, immutable plans and rollback are kept.
|
|
33
|
+
|
|
34
|
+
## Evidence and compatibility
|
|
35
|
+
|
|
36
|
+
Installed official MCP server SDK 2.0.0 `stdio.d.mts` exposes
|
|
37
|
+
`serveStdio({transport})` and `StdioServerTransport(...,{maxBufferSize})`.
|
|
38
|
+
Use that API to align STDIO buffer size with HTTP request limits; no custom
|
|
39
|
+
wire protocol. HTTP authenticates before parsing larger JSON bodies.
|
|
40
|
+
Installed diff 9.0.0 `libesm/patch/create.d.ts` supports abortable
|
|
41
|
+
`createTwoFilesPatch` with timeout/maxEditLength and undefined on exhaustion.
|
|
42
|
+
No dependency or OAuth protocol changes.
|
|
43
|
+
|
|
44
|
+
Actual tests include real modern/legacy HTTP, an 11 MiB STDIO file, an exact
|
|
45
|
+
8 MiB shell command via STDIO, 3 MiB write/edit/rollback, UTF-8 limits,
|
|
46
|
+
parallel commands, stdin, cancellation, sandbox, failed spawn and state writes,
|
|
47
|
+
owner CLI profiles and pre-allocation expansion refusal. See TEST_REPORT for
|
|
48
|
+
the executed gate, versions and results. External client/proxy input limits
|
|
49
|
+
are independent and manual acceptance is not claimed.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# ADR-024: owner-confirmed usage rounds and separately approved schedules
|
|
2
|
+
|
|
3
|
+
> Conversation/usage-round portions superseded by [ADR-026](026-remove-conversation-confirmation.md). Scheduled-command approval remains accepted. The original decision below is retained as design context.
|
|
4
|
+
|
|
5
|
+
Date: 2026-09-10. Status: retained design decision. Supersedes any earlier assumption
|
|
6
|
+
that OAuth/trust alone enables project tools, or that a missing workspace ACL
|
|
7
|
+
is an invalid OAuth identity token.
|
|
8
|
+
|
|
9
|
+
## Decision and limits
|
|
10
|
+
|
|
11
|
+
Installed official MCP SDK server/client 2.0.0 provides the existing stateless
|
|
12
|
+
HTTP and STDIO handlers; neither the request label nor a model-chosen ID is a
|
|
13
|
+
trusted conversation identity. Do not invent a protocol session and claim chat
|
|
14
|
+
isolation. Ship fail-closed owner-approved usage rounds with client/grant/root/
|
|
15
|
+
epoch/expiry binding, and require cooperative clients to create a new round per
|
|
16
|
+
conversation and end it on revocation/end. No verified chat adapter is claimed.
|
|
17
|
+
An approved ID replayed by the same authenticated principal in another chat is
|
|
18
|
+
indistinguishable in this fallback. Process restart/root switch requires a fresh
|
|
19
|
+
round; a dropped network connection does not.
|
|
20
|
+
|
|
21
|
+
All actual tools, including overview/read/job/desktop, share the gate before
|
|
22
|
+
handler dispatch. Only usage_request/status/end are exempt control operations;
|
|
23
|
+
these reveal no workspace context. No MCP approve operation exists. Owner CLI
|
|
24
|
+
uses private IPC; UI approval keeps existing capability/origin/workspace epoch
|
|
25
|
+
checks and requires typing the displayed phrase. Default TTL 60 min, max 8h;
|
|
26
|
+
pending requests expire in 10 min. Internal bootstrap/recovery by the owner CLI
|
|
27
|
+
and OAuth/protocol metadata are control-plane operations, not granted tool use.
|
|
28
|
+
|
|
29
|
+
A valid identity token without active workspace permissions authenticates with
|
|
30
|
+
zero effective scopes. Tools return WORKSPACE_ACCESS_REQUIRED with null workspace
|
|
31
|
+
context, without WWW-Authenticate. Invalid/expired/wrong-audience/revoked tokens
|
|
32
|
+
still fail at the resource server. No root access is added by this distinction.
|
|
33
|
+
|
|
34
|
+
Schedules have immutable specs/digests and local owner approval distinct from
|
|
35
|
+
usage consent. They run current project code, not a pinned revision. Baseline
|
|
36
|
+
saved trust must be trusted and the captured root/policy must match. Defaults:
|
|
37
|
+
require OS sandbox, network off, timeout 5 min, expiry explicitly supplied up to
|
|
38
|
+
30 days, five-field cron. Local owner-created schedules do not depend on OAuth;
|
|
39
|
+
remote proposals additionally depend on their client's live exec ACL/grant.
|
|
40
|
+
|
|
41
|
+
SQLite migration 5 adds usage_consents, schedules and schedule_runs. Claim due
|
|
42
|
+
slots and advance next_at in BEGIN IMMEDIATE before spawn. A crash may lose an
|
|
43
|
+
execution, but never automatically replays an uncertain occurrence. Skip missed
|
|
44
|
+
and overlapping ticks. Scheduler is internal to the active HTTP workspace only;
|
|
45
|
+
no OS cron/launchd installation, no inactive-root traversal, no auto-start service.
|
|
46
|
+
|
|
47
|
+
## Evidence
|
|
48
|
+
|
|
49
|
+
- Registry verified cron-parser 5.10.0 (Node >=18), pinned exact with lockfile.
|
|
50
|
+
API read from installed declarations: CronExpressionParser.parse(...,
|
|
51
|
+
{tz,currentDate}).next().getTime(); use maintained parser for calendar/timezone
|
|
52
|
+
computation. Upstream: https://github.com/harrisiirak/cron-parser
|
|
53
|
+
- Installed SDK declarations support McpServer options.instructions; both transports
|
|
54
|
+
advertise confirmation/revocation instructions without changing the MCP protocol.
|
|
55
|
+
- tests/security/usageConsent.test.ts: actual HTTP/OAuth dispatch denied before
|
|
56
|
+
confirmation, local IPC/UI approval, replay/client/root/epoch/expiry/revoke cases.
|
|
57
|
+
- tests/integration/schedules.test.ts: pending/approve/hash, real execution,
|
|
58
|
+
overlap, revoke, restart/missed/uncertain, policy/grant changes, shared claims.
|
|
59
|
+
- Existing identity tests now assert zero effective scopes AND tool denial, rather
|
|
60
|
+
than only an OAuth exception. Old-schema migration fixtures remove later tables
|
|
61
|
+
when reconstructing the actual historical schema.
|
|
62
|
+
- Exact totals and manual gates: TEST_REPORT and MANUAL_ACCEPTANCE.
|
|
63
|
+
|
|
64
|
+
## Threat model
|
|
65
|
+
|
|
66
|
+
Private same-UID IPC is the existing owner authority boundary, not a defense
|
|
67
|
+
against hostile code already running as that OS user. Unsandboxed trusted exec
|
|
68
|
+
or desktop control can act with user privileges, including interacting with
|
|
69
|
+
owner controls. Prompt instructions forbid self-approval, but are not an OS
|
|
70
|
+
security boundary. These limitations remain explicit; usage consent does not
|
|
71
|
+
turn arbitrary code execution into isolation. No server-side guarantee of
|
|
72
|
+
recognizing chat text or closing a chat is claimed.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# ADR-025: Owner-first chat references and reset
|
|
2
|
+
|
|
3
|
+
> Superseded by [ADR-026](026-remove-conversation-confirmation.md). This record describes historical behavior, no longer active.
|
|
4
|
+
|
|
5
|
+
Accepted: 2026-09-10. Retained as design context.
|
|
6
|
+
|
|
7
|
+
Owners want to paste a ChatGPT /c/ URL without first asking an AI to create a
|
|
8
|
+
pending usage request. The installed MCP SDK 2.0.0 contract supplies no trusted
|
|
9
|
+
ChatGPT conversation identity. A caller-supplied UUID is not authentication.
|
|
10
|
+
|
|
11
|
+
Decision: accept strictly parsed URLs/UUIDs only on the existing owner CLI/IPC
|
|
12
|
+
and private Local Config plane. Migration 6 stores permission generations bound
|
|
13
|
+
to workspace ID, directory device/inode and selected client. Owner permissions
|
|
14
|
+
persist until reset or optional expiry; duplicate allow is idempotent and does
|
|
15
|
+
not extend expiry. No new remote approval tool, public endpoint, OAuth scope or
|
|
16
|
+
DCR behavior is introduced. Ambiguous client selection fails closed.
|
|
17
|
+
|
|
18
|
+
Every operation accepts `chat` alternatively to an approved `usageId`. A valid
|
|
19
|
+
reference derives an epoch/grant-bound round from the standing permission. The
|
|
20
|
+
reference never falls back to a different or sole allowed chat. Round revocation
|
|
21
|
+
also revokes its parent permission; automatic round expiry does not, so an
|
|
22
|
+
unexpired standing permission can derive a fresh round. Reset invalidates all
|
|
23
|
+
linked rounds, including old epochs; allowing again uses a new generation.
|
|
24
|
+
Current live jobs belonging to those rounds are canceled. Schedules and OAuth
|
|
25
|
+
remain independent. Root replacement invalidates old permissions.
|
|
26
|
+
|
|
27
|
+
The private UI retains capability, Origin/forwarding rejection and workspace
|
|
28
|
+
header checks for every mutation. Chat links are parsed as text, never fetched.
|
|
29
|
+
`dodo reset` means current-workspace usage/chat reset, not factory reset. CLI
|
|
30
|
+
controls require a running process for that CWD; no offline/global reset implied.
|
|
31
|
+
|
|
32
|
+
Limitation: a cooperating client must supply the correct current-chat reference.
|
|
33
|
+
Another conversation using the same authenticated client can replay a permitted
|
|
34
|
+
reference. Whitelisting is owner consent with caller-supplied correlation, not
|
|
35
|
+
attestation or a verified lifecycle. This limitation is explicit in UI, server
|
|
36
|
+
instructions, tool descriptions, CLI output and docs. A trusted client adapter
|
|
37
|
+
would be needed to guarantee actual conversation isolation.
|
|
38
|
+
|
|
39
|
+
Evidence: chatConsent security fixtures cover raw MCP dispatch, no-root denial,
|
|
40
|
+
private UI, CLI reset, client/workspace isolation, root replacement, expiry,
|
|
41
|
+
revocation/cancellation and separate Cron execution; STDIO and packed-package
|
|
42
|
+
fixtures exercise the installed commands. See TEST_REPORT for actual commands
|
|
43
|
+
and results. No live ChatGPT conversation test is claimed.
|
|
44
|
+
|
|
45
|
+
### client context policy compatibility amendment
|
|
46
|
+
|
|
47
|
+
A user supplied a real-world `/c/WEB:UUID` URL rejected by the initial parser.
|
|
48
|
+
Accept that explicit namespace (or bare WEB:UUID) across the shared parser.
|
|
49
|
+
Preserve the prefix rather than stripping it: the server has no attestation that
|
|
50
|
+
a namespaced identifier equals the same bare UUID. Case normalizes within each
|
|
51
|
+
format; approval/reset do not cross namespaces. No arbitrary prefix, URL decode,
|
|
52
|
+
network request or weaker host/path check is added. Regression cases exercise
|
|
53
|
+
CLI, private UI API, MCP, namespace isolation/reset, STDIO and installed tarball.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# ADR-026: remove conversation confirmation; retain existing access policy
|
|
2
|
+
|
|
3
|
+
Status: accepted, 2026-09-10. Supersedes ADR-025 and the usage-round portion of
|
|
4
|
+
ADR-024; scheduled commands retain their separate local approval.
|
|
5
|
+
|
|
6
|
+
## Decision
|
|
7
|
+
|
|
8
|
+
The owner explicitly requested removal after the chat-ID workflow proved cumbersome.
|
|
9
|
+
Remove the gate entirely rather than infer a conversation from untrusted labels
|
|
10
|
+
or silently approve a default chat. The MCP transport exposes no verified chat
|
|
11
|
+
identity in our installed integration; an owner-pasted ID never proved one.
|
|
12
|
+
|
|
13
|
+
HTTP authentication, effective workspace ACL/scopes, workspace ID/epoch, trust,
|
|
14
|
+
action approval, Desktop policy, path/hash/journal checks remain. Both HTTP and
|
|
15
|
+
STDIO start with direct project_overview. Shared connections share permission;
|
|
16
|
+
DODO no longer claims conversation-level permission or revocation.
|
|
17
|
+
|
|
18
|
+
Remove all three usage tools, chat/usageId wire fields, owner chat/usage/reset
|
|
19
|
+
commands, private routes/UI and usage service/timer. Keep schedule_propose and
|
|
20
|
+
owner schedule approval. Catalog: 52 -> 49. Job principal is the authenticated
|
|
21
|
+
grant. This policy requires refreshing cached tool schemas and restarting DODO.
|
|
22
|
+
|
|
23
|
+
Retain migrations 5/6 and their old tables as inert upgrade history, without
|
|
24
|
+
runtime permission reads/writes. Do not reset OAuth, keys, ACLs, desktop consent,
|
|
25
|
+
schedules, files or audit history. This avoids destructive rollback of state.
|
|
26
|
+
|
|
27
|
+
## Evidence
|
|
28
|
+
|
|
29
|
+
Dependencies unchanged: MCP SDK 2.0.0, oidc-provider 9.12.2 and better-sqlite3
|
|
30
|
+
13.0.3. directAccess.test.ts covers immediate HTTP read/write/exec, removed
|
|
31
|
+
schemas/interfaces, legacy rows across restart and unchanged auth/path/trust
|
|
32
|
+
boundaries. STDIO, schedule, kill and package tests dispatch without any hidden
|
|
33
|
+
consent fixture. Removed feature tests are replaced by direct-access regressions;
|
|
34
|
+
existing auth, file safety, exec and Desktop security tests remain. Exact commands
|
|
35
|
+
and outcomes are recorded in TEST_REPORT.md; external AI-client runs remain manual.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# ADR-027: show current-root client access; keep OAuth registration shared
|
|
2
|
+
|
|
3
|
+
Status: accepted, 2026-09-10.
|
|
4
|
+
|
|
5
|
+
The owner wants Client access to show only the running folder's clients. The
|
|
6
|
+
old UI listed all registrations, making unrelated ChatGPT entries look active.
|
|
7
|
+
Filter the main state/list by nonempty current-workspace ACL. Preserve shared
|
|
8
|
+
OAuth registration and other-root ACLs, rather than duplicate or delete clients.
|
|
9
|
+
|
|
10
|
+
An owner can explicitly add an existing registration through an on-demand picker
|
|
11
|
+
under the same private capability/Host/Origin boundary. Bind its read and write
|
|
12
|
+
to the reviewed workspace/epoch; invalidate stale UI responses on switch. Add-only
|
|
13
|
+
writes reject an existing ACL to avoid overwriting another tab's recent grant.
|
|
14
|
+
Revocation removes only the local ACL/card; it leaves login and registration.
|
|
15
|
+
|
|
16
|
+
No dependency/schema migration/MCP wire change. Evidence: localConfig security
|
|
17
|
+
fixtures for filtering, secret exclusion, read-only enumeration, local-only
|
|
18
|
+
addition/revocation and stale/foreign requests; workspaceSwitch verifies filtering
|
|
19
|
+
and unchanged cross-root OAuth denial. Browser fixture checks the actual owner
|
|
20
|
+
picker. Exact results are in TEST_REPORT; real ChatGPT remains MANUAL_NOT_RUN.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# ADR-028: explicit reviewed deletion of selected OAuth clients
|
|
2
|
+
|
|
3
|
+
Status: accepted, 2026-09-10. The owner requested a clear-client button.
|
|
4
|
+
|
|
5
|
+
Keep the current-folder access list. A separate collapsed manager loads safe
|
|
6
|
+
installation-wide ID/name/count summaries on demand and deletes only explicitly
|
|
7
|
+
selected registrations (up to 100). Confirm the global effect with exact IDs.
|
|
8
|
+
The UI uses textContent; no client secret or callback is returned by review.
|
|
9
|
+
|
|
10
|
+
Deletion is a single SQLite IMMEDIATE transaction after all review hashes match:
|
|
11
|
+
deny related approvals, revoke grant rows, remove provider models and workspace
|
|
12
|
+
ACLs, delete client registrations, audit. Roll back the entire batch on failure.
|
|
13
|
+
Keep histories and unrelated registrations/keys/files. No wildcard future-client
|
|
14
|
+
selection, reset of state or remote MCP tool is introduced. Existing work may
|
|
15
|
+
finish; subsequent calls/refresh and grant-backed scheduled launches are denied.
|
|
16
|
+
|
|
17
|
+
The existing oidc-provider 9.12.2 implementation (lib/models/client.js Client.find)
|
|
18
|
+
consults the adapter before dynamic-cache reuse; clients:[] avoids static cached
|
|
19
|
+
registrations. The verifier independently checks registration existence and
|
|
20
|
+
interaction completion checks again after asynchronous grant persistence.
|
|
21
|
+
|
|
22
|
+
Evidence: clientDeletion.test.ts real access/refresh, preserved second client,
|
|
23
|
+
stale/hostile requests, race-safe selection and injected SQLite rollback tests;
|
|
24
|
+
local browser cancel/select/delete/empty-state check. Exact outcomes in
|
|
25
|
+
TEST_REPORT. Real owner clients were not deleted. No new dependencies/migrations.
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# 029 — Compact MCP tool surface with capability gateways (tool surface policy)
|
|
2
|
+
|
|
3
|
+
Status: accepted, 2026-09-10.
|
|
4
|
+
|
|
5
|
+
## Problem
|
|
6
|
+
|
|
7
|
+
The catalog contains 74 tools. The full `tools/list` serializes to roughly
|
|
8
|
+
236 KB. Remote MCP clients ingest every tool definition at connection time,
|
|
9
|
+
and clients differ in the catalog/schema volume they retain. HTTP+OAuth and
|
|
10
|
+
STDIO fixtures prove the direct write/edit path independently. No hard
|
|
11
|
+
per-client tool limit is claimed; compact mode reduces catalog/schema load and
|
|
12
|
+
avoids requiring clients to ingest every detailed operation schema at
|
|
13
|
+
connection time.
|
|
14
|
+
|
|
15
|
+
## Decision
|
|
16
|
+
|
|
17
|
+
Two tool surfaces over ONE unchanged capability set:
|
|
18
|
+
|
|
19
|
+
- **full** — the existing 74-tool catalog, byte-for-byte the same names,
|
|
20
|
+
order, schemas and behavior. Default for STDIO (Codex, Claude Code, Cursor).
|
|
21
|
+
- **compact** — 19 tools: `project_overview`, `dodo_discover`, and 17 domain
|
|
22
|
+
gateways (`dodo_read`, `dodo_write`, `dodo_exec`, `dodo_git_read`,
|
|
23
|
+
`dodo_git_write`, `dodo_desktop_view`, `dodo_desktop_control`,
|
|
24
|
+
`dodo_assist_read`, `dodo_assist_change`, `dodo_media`, `dodo_browser`,
|
|
25
|
+
`dodo_game`, `dodo_workflow_read`, `dodo_workflow_write`,
|
|
26
|
+
`dodo_workflow_run`, `dodo_schedule`, `dodo_web`). Default for HTTP.
|
|
27
|
+
A gateway call is `{ workspaceId, workspaceEpoch, operation, args }` where
|
|
28
|
+
`operation` is enum-bound to that gateway's fixed allowlist; every
|
|
29
|
+
full-catalog tool except `project_overview` is reachable through exactly one
|
|
30
|
+
gateway. `dodo_discover` searches operations and returns one operation's
|
|
31
|
+
args-only JSON Schema plus a deterministic `schemaHash`; workspace context
|
|
32
|
+
remains top-level gateway input and cannot be overridden inside `args`.
|
|
33
|
+
|
|
34
|
+
Selection: `toolSurface` in the global config overrides the transport default;
|
|
35
|
+
`--tools compact|full|hybrid` on `dodo start`/`dodo stdio` overrides both for one
|
|
36
|
+
run. The setting changes tool exposure only — never permissions.
|
|
37
|
+
|
|
38
|
+
## Security invariants (unchanged, now single-pathed)
|
|
39
|
+
|
|
40
|
+
`registerTool` and the gateways route through one function,
|
|
41
|
+
`invokeToolDefinition` (src/tools/context.ts): live principal →
|
|
42
|
+
WORKSPACE_ACCESS_REQUIRED on empty workspace ACL → the TARGET tool's
|
|
43
|
+
`requiredScope` → workspaceId/epoch context → request byte budget → the
|
|
44
|
+
target's ORIGINAL strict Zod input schema → the target handler (which runs its
|
|
45
|
+
own `policyGate`/local approvals, idempotency and journaling) → envelope →
|
|
46
|
+
audit. Consequences, all covered by tests:
|
|
47
|
+
|
|
48
|
+
- A read-only token calling `dodo_write(write_file)` fails `FORBIDDEN` with
|
|
49
|
+
the target's scope in `detail`, exactly like the direct call.
|
|
50
|
+
- In `inspect` mode an effectful gateway call produces an approval bound to
|
|
51
|
+
the TARGET operation (`tool: write_file`), never a blanket gateway approval.
|
|
52
|
+
- `args` may not carry `workspaceId`/`workspaceEpoch` (rejected
|
|
53
|
+
`INVALID_INPUT`); the gateway injects the top-level context itself.
|
|
54
|
+
- Target error codes (`FILE_CHANGED`, `AMBIGUOUS_EDIT`, `SECRET_PATH_DENIED`,
|
|
55
|
+
`APPROVAL_REQUIRED`, …) pass through unchanged via `fromErrorInfo`.
|
|
56
|
+
- Image/audio MCP content blocks pass through unchanged.
|
|
57
|
+
- Gateways cannot target other gateways, `project_overview`, owner IPC
|
|
58
|
+
controls or anything outside the fixed allowlists (construction-time
|
|
59
|
+
invariant + tests). Each gateway's own `requiredScope` is computed as the
|
|
60
|
+
minimum of its targets, so it can never be broader than the catalog.
|
|
61
|
+
- Both the gateway call and the target invocation are audited.
|
|
62
|
+
|
|
63
|
+
## Evidence
|
|
64
|
+
|
|
65
|
+
- Serialized tools/list-equivalent payload (name+title+description+annotations+
|
|
66
|
+
input+output schemas): 74 tools = 237 755 bytes; compact 19 = 46 834 (−80.3%);
|
|
67
|
+
measured live tools/list: 236 518 → 46 707 bytes. Recorded by the
|
|
68
|
+
`[dodo] mcp tool surface` startup diagnostic and `schemas/tools.compact.json`.
|
|
69
|
+
- Suites: `tests/unit/compactSurface.test.ts`,
|
|
70
|
+
`tests/security/compactGateway.test.ts`,
|
|
71
|
+
`tests/integration/compactHttp.test.ts`,
|
|
72
|
+
`tests/integration/compactStdio.test.ts`,
|
|
73
|
+
`tests/integration/compactCapabilities.test.ts`, packaging PACK-12; the 24
|
|
74
|
+
direct-contract suites pin `toolSurface: 'full'` explicitly.
|
|
75
|
+
- Live ChatGPT re-scan against the compact surface is a MANUAL gate
|
|
76
|
+
(MANUAL_ACCEPTANCE.md); no client-side limit figure is asserted.
|
|
77
|
+
|
|
78
|
+
## Addendum (tool surface policy): hybrid surface
|
|
79
|
+
|
|
80
|
+
The owner's live ChatGPT connector displayed exactly 49 tools against a
|
|
81
|
+
74-tool catalog — the first 49 in catalog order — consistent with a
|
|
82
|
+
client-side tool-count cap near ~50 (still not asserted as a universal
|
|
83
|
+
constant). For clients in that range that prefer direct tools, the
|
|
84
|
+
opt-in `hybrid` surface: 49 tools, compact coverage core first (truncation-
|
|
85
|
+
safe), then 30 direct coding tools (`HYBRID_DIRECT_OPERATIONS`). Selection
|
|
86
|
+
via config/CLI as before; defaults unchanged; every path keeps the shared
|
|
87
|
+
invocation pipeline.
|
|
88
|
+
|
|
89
|
+
## Addendum (Phase 04): resource operations
|
|
90
|
+
|
|
91
|
+
ADR-034 adds six individual resource definitions to Full, so the Phase 04 surfaces
|
|
92
|
+
became Full 89, Compact 19 and Hybrid 49. Compact/Hybrid route the new operations
|
|
93
|
+
through the existing `dodo_media` gateway; no new gateway or direct Hybrid duplicate
|
|
94
|
+
was added. The historical 74-tool measurements above remain the evidence captured
|
|
95
|
+
when this ADR was first accepted. Generated schemas and `docs/TEST_REPORT.md` carry
|
|
96
|
+
the current byte measurements.
|
|
97
|
+
|
|
98
|
+
## Addendum (Phase 07): owner-reviewed memory operations
|
|
99
|
+
|
|
100
|
+
ADR-037 added five individual memory definitions to Full, so the surfaces at that point were
|
|
101
|
+
Full 121, Compact 19 and Hybrid 49. Compact/Hybrid route read operations through
|
|
102
|
+
`dodo_assist_read` and proposal operations through `dodo_assist_change`. Owner approval,
|
|
103
|
+
rejection, prune and learning review remain private IPC commands and are never added
|
|
104
|
+
to any MCP surface.
|
|
105
|
+
|
|
106
|
+
## Addendum: provider-backed sub-agents
|
|
107
|
+
|
|
108
|
+
ADR-045 adds four individual Sub-agent definitions, so the current surfaces are Full 125,
|
|
109
|
+
Compact 19 and Hybrid 49. Compact/Hybrid route them through the existing assistance
|
|
110
|
+
gateways. Personal/managed access mode changes authorization decisions only; it does not
|
|
111
|
+
change catalog size or let a gateway bypass the target definition.
|
|
112
|
+
|
|
113
|
+
## Addendum: optional Sub-agent exposure
|
|
114
|
+
|
|
115
|
+
The installed capability contract still contains all 125 definitions, but
|
|
116
|
+
`exposeSubagentsToMcp` defaults to false. A live Full surface therefore registers 121
|
|
117
|
+
tools by default. Compact and Hybrid keep their stable 19/49 gateway names while removing
|
|
118
|
+
the four Sub-agent operation values from their schemas, discover index and instructions.
|
|
119
|
+
The private web workbench remains able to create and manage runs. Enabling the setting
|
|
120
|
+
requires a process restart and client catalog rescan; it changes exposure only and never
|
|
121
|
+
authority.
|