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
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 DODO contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,425 @@
|
|
|
1
|
+
# DODO MCP
|
|
2
|
+
|
|
3
|
+
**DODO MCP 1.0.0** คือ MCP server แบบ local-first สำหรับให้ AI ช่วยพัฒนา software โดยทำงานกับ workspace ที่เจ้าของเลือก ค่าเริ่มต้นเป็นโหมดส่วนตัวแบบเพิ่มโปรเจกต์แล้วใช้ได้ทันที และยังมีโหมด managed สำหรับแยก workspace ACL/trust แบบละเอียด
|
|
4
|
+
|
|
5
|
+
## จุดเด่น
|
|
6
|
+
|
|
7
|
+
- MCP ผ่าน HTTP ที่ `127.0.0.1:21730/mcp` พร้อม OAuth และ PKCE
|
|
8
|
+
- Local Config แบบ loopback ที่ `127.0.0.1:21731`
|
|
9
|
+
- HTTP ใช้ Compact Tool Surface 19 tools เพื่อลดภาระการโหลด schema
|
|
10
|
+
- STDIO ใช้ Full Tool Surface; มี capability definitions ทั้งหมด 125 รายการ แต่ค่าเริ่มต้นซ่อน Sub-agent 4 operations จาก MCP จึงเห็น 121 tools
|
|
11
|
+
- Hybrid Surface 49 tools สำหรับ client ที่รับ catalog ขนาดกลาง
|
|
12
|
+
- อ่าน ค้นหา สร้าง แก้ ย้าย ลบไฟล์ พร้อม expected hash, journal และ rollback
|
|
13
|
+
- รันคำสั่ง งานแบบขนาน jobs, Git, TypeScript/JavaScript intelligence, LSP และ task assistance
|
|
14
|
+
- รองรับภาพ เสียง วิดีโอ เบราว์เซอร์ เกม และ workflow ตาม dependency และ permission ที่เจ้าของเปิดใช้
|
|
15
|
+
- มี Universal Resource Layer + CAS สำหรับ text/binary/image/audio/video/PDF/ZIP/WASM พร้อม SHA-256, dedup, bounded range/resume และ MCP image/audio blocks
|
|
16
|
+
- มี Project Brain ที่ทำ incremental AST index สำหรับ symbols, references, imports, routes, tests และ dependencies พร้อม source-hash freshness
|
|
17
|
+
- มี Context Engine สำหรับ goal-driven retrieval แบบมี budget, provenance, confidence, freshness และ L0–L6 dependency cache
|
|
18
|
+
- มี owner-reviewed Memory สำหรับ fact/decision/fix/convention ที่ผูก source evidence, retention และ freshness พร้อม learning proposal ที่ไม่ติดตั้งหรือรันเอง
|
|
19
|
+
- มี Runtime Intelligence สำหรับ task ที่ reconnect ได้, process/test/browser evidence แบบ bounded, snapshot freshness และ diagnosis ที่แยก fact/observation/inference
|
|
20
|
+
- มี Advanced Agent Runtime สำหรับ immutable plan, parallel hypotheses, intent locks, guarded snapshots, evidence-backed completion, restart recovery และ owner-reviewed reusable guidance
|
|
21
|
+
- มี AI Providers เจ็ด presets/Custom, profiles, model/tool loop และประวัติ private ผ่าน Local Config ([คู่มือ](docs/AI_PROVIDERS.md))
|
|
22
|
+
- เขียน/รันหลายโปรเจกต์พร้อมกันด้วย targetProjectId และคิว mutation แยกโปรเจกต์
|
|
23
|
+
- มี DodoBench และ revision-bound release gate สำหรับ retrieval, safe edit, runtime, resource, recovery, security และ fresh package artifact
|
|
24
|
+
- เปลี่ยน workspace จาก Local Config ได้จริง โดยรอ request/jobs และ rollback เมื่อเตรียม workspace ใหม่ไม่สำเร็จ
|
|
25
|
+
- มี owner-only Project Registry พร้อม stable project ID และ readiness โดยไม่คัดลอก trust/ACL
|
|
26
|
+
- อ่าน overview/list/files และค้นหาพร้อมกันได้สูงสุด 8 โปรเจกต์ที่เจ้าของลงทะเบียน โดย personal mode ไม่ต้องตั้ง ACL ซ้ำ
|
|
27
|
+
- เปิด Cloudflare Tunnel พร้อม `dodo start` ด้วย token ชั่วคราวจาก terminal หรือ Local Config โดยไม่บันทึก token ลงเครื่อง
|
|
28
|
+
- ไม่ส่ง token, secret หรือ state DB ไปที่ repository และไม่ให้ repository config เพิ่มสิทธิ์
|
|
29
|
+
|
|
30
|
+
## เริ่มใช้งาน
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install -g dodo-mcp
|
|
34
|
+
dodo setup --check
|
|
35
|
+
dodo --cli
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
`dodo --cli` เปิดเมนู local owner สำหรับเลือก/เพิ่มโปรเจกต์ เปิด MCP + Local Config +
|
|
39
|
+
Tunnel และรัน setup รวม `cloudflared` โดยไม่ต้อง `cd` เข้าโปรเจกต์
|
|
40
|
+
ก่อน หากเรียก `dodo` หรือ `dodo start` จากโฟลเดอร์ใดก็ตาม ระบบจะเปิดโปรเจกต์ที่
|
|
41
|
+
เจ้าของเลือกล่าสุด หากยังไม่มีโปรเจกต์ใน registry จะเปิด control plane, OAuth และ
|
|
42
|
+
authenticated tool catalog ได้โดยไม่ใช้ CWD เป็น workspace เมื่อเจ้าของเพิ่มโปรเจกต์
|
|
43
|
+
จาก Local Config แล้ว OAuth client ที่เจ้าของอนุมัติจะใช้โปรเจกต์นั้นได้ทันทีตาม scopes
|
|
44
|
+
ของ token และ Agent Profile ที่เลือก โดยไม่ต้องตั้ง permission ซ้ำต่อ path
|
|
45
|
+
|
|
46
|
+
เปิดโปรเจกต์โดยตรงและจำไว้สำหรับครั้งถัดไปได้ด้วย:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
dodo start --root /path/to/your/project
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
โหมดส่วนตัวใช้ effective trust แบบ trusted กับโปรเจกต์ที่เจ้าของลงทะเบียน คำสั่งจึงรัน
|
|
53
|
+
ด้วยสิทธิ์ OS ของบัญชีเจ้าของและยังผ่าน command sandbox ที่ตั้งไว้, path/secret guards,
|
|
54
|
+
expected hash, workspace context และ OAuth scopes หากต้องแยก client/profile/trust ต่อ
|
|
55
|
+
โปรเจกต์ ให้เปลี่ยนเป็นโหมด managed ที่หน้า Settings
|
|
56
|
+
|
|
57
|
+
`dodo setup --check` และ `dodo setup --plan` เป็น read-only หากแผนมี dependency ที่ต้องติดตั้ง ให้ตรวจรายการก่อนแล้วจึงรัน `dodo setup --yes --components <list>` ระบบจะไม่เริ่ม installer หากไม่มี `--yes` และ `--yes` ไม่ข้าม sudo, OS permission หรือ owner consent
|
|
58
|
+
|
|
59
|
+
เมื่อ DODO ตรวจพบ config เดิมในตำแหน่งมาตรฐาน สามารถใช้ `dodo setup --import-state` เพื่อนำเข้าเฉพาะ preference ที่ปลอดภัย เช่น port, search backend, retention และ tool surface ระบบจะสร้าง installation identity ใหม่เสมอและไม่คัดลอก OAuth keys/tokens, client grants, workspace ACL, trust, approvals, schedules, public origin, web/desktop permission, executable registration หรือฐานข้อมูลเดิม ต้นฉบับจะไม่ถูกแก้ไข
|
|
60
|
+
|
|
61
|
+
เปิด Local Config จาก URL ที่ `dodo` แสดงใน terminal ใช้สำหรับเพิ่มโปรเจกต์, AI
|
|
62
|
+
connections/profiles, public origin และเปลี่ยน access mode เจ้าของเท่านั้น โหมดส่วนตัว
|
|
63
|
+
พร้อมใช้โดยไม่ต้องตั้ง trust/client/profile permission รายโปรเจกต์
|
|
64
|
+
|
|
65
|
+
หน้าเว็บจัดเป็น dashboard 8 หน้า (ภาพรวม · โปรเจกต์ · Providers & Profiles ·
|
|
66
|
+
Chat & Tasks · Runs & Jobs · Approvals · Knowledge · Settings) หน้าภาพรวมแสดงสถานะ,
|
|
67
|
+
ขั้นตอนถัดไป และสิ่งที่ต้องตรวจสอบเท่านั้น คำอธิบายยาวถูกย้ายไป tooltip (ปุ่ม `?`
|
|
68
|
+
เปิดด้วย hover/โฟกัสคีย์บอร์ด/แตะ ปิดด้วย Escape) และส่วน "รายละเอียดทางเทคนิค"
|
|
69
|
+
ที่พับได้ กล่องยืนยัน/แจ้งผลใช้ SweetAlert2 ที่ vendor มากับแพ็กเกจ (same-origin
|
|
70
|
+
ไม่มี CDN, CSP `'self'` เท่าเดิม) การลบ/ยกเลิก/เปลี่ยนโหมดต้องยืนยันก่อนเสมอ
|
|
71
|
+
และงานที่มีค่าใช้จ่ายหรือผลไม่แน่นอนจะบอกชัดว่า "ไม่ retry อัตโนมัติ"
|
|
72
|
+
|
|
73
|
+
หน้า **Settings → Sub-agent tools ใน MCP** มีสวิตช์เปิด/ปิดการ expose
|
|
74
|
+
`subagent_spawn`, `subagent_status`, `subagent_result` และ `subagent_control` ให้ AI
|
|
75
|
+
ภายนอก ค่าเริ่มต้นปิดเพื่อให้ catalog สำหรับงานทั่วไปกระชับขึ้น แต่หน้า Chat & Tasks
|
|
76
|
+
ยังสร้างและจัดการ agent ได้ตามเดิม เมื่อเปลี่ยนค่านี้ต้อง restart DODO แล้ว rescan หรือ
|
|
77
|
+
สร้าง MCP app ใหม่ตามพฤติกรรมของ client การตั้งค่านี้เปลี่ยนเฉพาะการมองเห็น tools
|
|
78
|
+
และไม่เพิ่ม OAuth scope, trust, approval หรือสิทธิ์ของ profile
|
|
79
|
+
|
|
80
|
+
ลงทะเบียนโปรเจกต์ที่ต้องการใช้งานบ่อยได้โดยไม่เริ่ม server:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
dodo project add /absolute/path/to/project --name "Web application"
|
|
84
|
+
dodo project list
|
|
85
|
+
dodo project info prj_xxxxxxxxxxxx
|
|
86
|
+
dodo project remove prj_xxxxxxxxxxxx --yes
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Project Registry ใช้ project ID คงที่แยกจาก workspace authority และแสดง readiness
|
|
90
|
+
ของ path ปัจจุบัน ดู contract ที่ [Project Registry](docs/PROJECTS.md)
|
|
91
|
+
|
|
92
|
+
### อ่านหลายโปรเจกต์พร้อมกัน
|
|
93
|
+
|
|
94
|
+
เจ้าของต้องลงทะเบียนแต่ละโปรเจกต์ โหมดส่วนตัวใช้ OAuth scopes เดิมกับทุก project
|
|
95
|
+
ที่ลงทะเบียน ส่วนโหมด managed ต้องให้ `dodo:read` แก่ client ในแต่ละ workspace:
|
|
96
|
+
|
|
97
|
+
```text
|
|
98
|
+
project_overview()
|
|
99
|
+
→ federation.projects แสดงเฉพาะโปรเจกต์ที่ client อ่านได้
|
|
100
|
+
|
|
101
|
+
dodo_read(operation="search_code", args={
|
|
102
|
+
projectIds: ["prj_2bcdefghjkmn", "prj_3cdefghjkmnp"],
|
|
103
|
+
query: "UserDto"
|
|
104
|
+
})
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
`project_overview`, `list_files` และ `read_files` รับ `projectId` ได้ ส่วน
|
|
108
|
+
`search_code` รับ `projectId` หรือ `projectIds` สูงสุด 8 รายการ ผลแต่ละโปรเจกต์มี
|
|
109
|
+
project/workspace identity, federation epoch และ source hash เพื่อแยก evidence
|
|
110
|
+
ออกจากกัน ค่า `workspaceId`/`workspaceEpoch` ระดับบนของ MCP call ยังคงเป็นของ
|
|
111
|
+
active workspace เสมอ
|
|
112
|
+
|
|
113
|
+
Federation แบบ `projectId/projectIds` ยังคง read-only สำหรับการเขียน/รันหลายโปรเจกต์
|
|
114
|
+
ให้เรียก `project_overview(targetProjectId="prj_…")` แล้วใช้ `targetProjectId` และ
|
|
115
|
+
workspace ID/epoch ที่ได้รับกับทุก operation ต่อมา คนละโปรเจกต์ทำงานพร้อมกันได้
|
|
116
|
+
โดยไม่เปลี่ยน default; งาน mutation ในโปรเจกต์เดียวกันเข้าคิวร่วมกัน
|
|
117
|
+
ดู [การตั้ง AI Providers, Profiles และ Sub-agents ผ่านเว็บ](docs/AI_PROVIDERS.md)
|
|
118
|
+
|
|
119
|
+
### Universal Resource Layer
|
|
120
|
+
|
|
121
|
+
ไฟล์ขนาดใหญ่และสื่อใช้ resource contract เดียวกัน โดยเริ่มจาก path ภายใน active
|
|
122
|
+
workspace หรือ `assetId` ที่ principal เดียวกันเป็นเจ้าของ:
|
|
123
|
+
|
|
124
|
+
```text
|
|
125
|
+
resource_inspect(path="docs/spec.pdf")
|
|
126
|
+
→ resourceId + dodo-resource:// URI + MIME + bytes + SHA-256 + capabilities
|
|
127
|
+
|
|
128
|
+
resource_read_range(resourceId=..., offset=0, length=65536)
|
|
129
|
+
→ bounded Base64 chunk + chunk hash + principal-bound resumeToken
|
|
130
|
+
|
|
131
|
+
resource_preview(resourceId=...)
|
|
132
|
+
→ text / MCP image / MCP audio / metadata ตามชนิดและขนาด
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
HTTP Compact/Hybrid เรียก operation เดียวกันผ่าน `dodo_media` หลังค้นด้วย
|
|
136
|
+
`dodo_discover` CAS เก็บ object แบบ immutable ตาม hash และ deduplicate ข้าม reference
|
|
137
|
+
ได้ แต่ resource ID/URI ไม่ใช่ capability ทุก call ยังตรวจ OAuth, live grant,
|
|
138
|
+
target authority, workspace ID/epoch และ principal ownership ซ้ำ ไม่ ingest `.env`,
|
|
139
|
+
private DODO state, traversal, symlink หรือ hardlink และไม่ inflate/execute archive
|
|
140
|
+
content ดูรายละเอียดที่ [Resources](docs/RESOURCES.md)
|
|
141
|
+
|
|
142
|
+
### Project Brain
|
|
143
|
+
|
|
144
|
+
Project Brain สร้าง graph แบบ bounded จาก TypeScript/JavaScript AST และ
|
|
145
|
+
`package.json` โดยไม่รัน source, repository plugin หรือ command ใด ๆ ระบบ refresh
|
|
146
|
+
อัตโนมัติและ parse ใหม่เฉพาะไฟล์ที่เปลี่ยน พร้อมขยายผลไปยัง relation ที่ได้รับ
|
|
147
|
+
ผลกระทบ:
|
|
148
|
+
|
|
149
|
+
```text
|
|
150
|
+
brain_status()
|
|
151
|
+
brain_query(query="UserService", nodeTypes=["symbol"])
|
|
152
|
+
brain_symbol(uri="symbol://...")
|
|
153
|
+
brain_rebuild(mode="incremental", waitMs=10000)
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
ใน Compact/Hybrid ให้เรียกผ่าน `dodo_assist_read` หรือ `dodo_assist_change`
|
|
157
|
+
ตาม schema จาก `dodo_discover` ค่า `symbol://` เป็น semantic identity ที่คงเดิม
|
|
158
|
+
เมื่อไฟล์ถูกย้ายแบบ exact-content แต่ URI/index row ไม่ใช่สิทธิ์ ทุก query จะตรวจ
|
|
159
|
+
OAuth, live grant, target authority, workspace ID/epoch, path/secret policy และ SHA-256
|
|
160
|
+
ของ source ปัจจุบันใหม่ก่อนคืนผล ดู [Project Brain](docs/BRAIN.md)
|
|
161
|
+
|
|
162
|
+
### Context Engine และ Evidence
|
|
163
|
+
|
|
164
|
+
ให้ AI ขอ context ตาม goal ได้โดยไม่ต้องเลือก search/brain/git ทีละตัว:
|
|
165
|
+
|
|
166
|
+
```text
|
|
167
|
+
context_query(goal="Fix login callback", terms=["loginCallback", "OAuth"],
|
|
168
|
+
projects=["Frontend", "Backend"], budget=24000)
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Compact/Hybrid ใช้ `dodo_assist_read(operation="context_query", args={...})` ผลลัพธ์
|
|
172
|
+
แยก `FACT`, `OBSERVATION`, `MEMORY`, `INFERENCE`, `HYPOTHESIS` และทุก evidence มี
|
|
173
|
+
project identity, source hash, line/commit, confidence, generated/verified time และ
|
|
174
|
+
freshness Cache L0–L6 ตรวจ ACL และ dependency hash ก่อนใช้ซ้ำ Source เปลี่ยนแล้ว
|
|
175
|
+
evidence เดิมจะเป็น stale และ derived cache ถูกสร้างใหม่
|
|
176
|
+
|
|
177
|
+
ผลค้นหา, README และ repository instruction เป็น untrusted content และไม่สามารถเพิ่ม
|
|
178
|
+
scope, ACL, trust หรือ approval ได้ Memory ที่เจ้าของอนุมัติจะแสดงเป็น evidence class
|
|
179
|
+
`MEMORY`; runtime evidence ที่ caller เดียวกันเก็บไว้จะแสดงเป็น `OBSERVATION` พร้อม
|
|
180
|
+
source hash และ freshness ดู contract ที่
|
|
181
|
+
[Context Engine](docs/CONTEXT.md)
|
|
182
|
+
|
|
183
|
+
### Owner-reviewed Memory
|
|
184
|
+
|
|
185
|
+
AI สร้าง memory ถาวรเองไม่ได้ ขั้นแรกต้องใช้ current `context_evidence` เพื่อเสนอ:
|
|
186
|
+
|
|
187
|
+
```text
|
|
188
|
+
dodo_assist_read(operation="context_query", args={goal:"Find session policy", ...})
|
|
189
|
+
dodo_assist_change(operation="memory_propose", args={
|
|
190
|
+
kind:"decision",
|
|
191
|
+
claim:"Keep session state scoped to one workspace.",
|
|
192
|
+
evidenceIds:["evidence_..."]
|
|
193
|
+
})
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
จากนั้นเจ้าของตรวจ proposal และ digest ผ่าน private local CLI เท่านั้น:
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
dodo memory pending
|
|
200
|
+
dodo memory show memprop_xxxxxxxxxxxx
|
|
201
|
+
dodo memory approve memprop_xxxxxxxxxxxx --digest sha256:...
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
Memory ทุกชิ้นเป็น `evidence_only` และ `untrusted_content` Source เปลี่ยนหรือ retention
|
|
205
|
+
หมดจะเป็น stale และไม่ถูกใช้เป็น current context การแชร์ข้าม project ต้องระบุ
|
|
206
|
+
`--share-with` ตอน owner approval และ client ยังต้องมี live ACL ใน project เป้าหมาย
|
|
207
|
+
รายละเอียดอยู่ที่ [Memory and Reviewed Learning](docs/MEMORY.md)
|
|
208
|
+
|
|
209
|
+
### Runtime Intelligence
|
|
210
|
+
|
|
211
|
+
งานทดสอบหรือ process ที่ต้องติดตามข้ามการ reconnect ใช้ runtime session โดยคำสั่ง
|
|
212
|
+
ยังผ่าน exec approval, trusted executable resolver และ command sandbox เดิม:
|
|
213
|
+
|
|
214
|
+
```text
|
|
215
|
+
dodo_assist_change(operation="runtime_session_open", args={label:"verify checkout"})
|
|
216
|
+
dodo_exec(operation="runtime_task_start", args={
|
|
217
|
+
sessionId:"runtime_...", kind:"test", program:"npm", args:["test"],
|
|
218
|
+
network:false, idempotencyKey:"client-generated-key"
|
|
219
|
+
})
|
|
220
|
+
dodo_assist_read(operation="runtime_task_observe", args={sessionId:"runtime_...", taskId:"rtask_..."})
|
|
221
|
+
dodo_assist_read(operation="runtime_diagnose", args={sessionId:"runtime_...", evidenceIds:["runtimeev_..."]})
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
Runtime store เก็บเฉพาะ status, byte counts, aggregate test counts และ SHA-256 ไม่เก็บ
|
|
225
|
+
stdout/stderr, DOM, console หรือ header ดิบ Browser collector ใช้ได้เฉพาะ
|
|
226
|
+
`browser_session` ที่ caller เปิดและมีสิทธิ์อยู่แล้ว โดยส่ง bounded observation/image
|
|
227
|
+
ใน response ปัจจุบัน แต่ persist เฉพาะ safe URL, hashes และ counts Snapshot ไม่ copy
|
|
228
|
+
ไฟล์และไม่ rollback เอง; ต้องเรียก `rollback_changes` แยกต่างหาก ดู
|
|
229
|
+
[Runtime Intelligence](docs/RUNTIME.md)
|
|
230
|
+
|
|
231
|
+
### Advanced Agent Runtime
|
|
232
|
+
|
|
233
|
+
งานแก้ปัญหาหลายขั้นสามารถเปิด durable agent run ที่จำกัด project, writable paths,
|
|
234
|
+
programs, optional capabilities, quotas และเวลาทำงานเพิ่มจากสิทธิ์เดิม:
|
|
235
|
+
|
|
236
|
+
```text
|
|
237
|
+
dodo_assist_change(operation="agent_run_open", args={goal, completionCriteria, capabilities})
|
|
238
|
+
dodo_assist_change(operation="agent_hypothesis_open", args={runId, ...})
|
|
239
|
+
dodo_assist_change(operation="agent_intent_acquire", args={runId, hypothesisId, kind:"path", resourceKey:"src"})
|
|
240
|
+
dodo_write(operation="agent_write", args={runId, hypothesisId, operation:"edit_file", args:{...}})
|
|
241
|
+
dodo_assist_read(operation="agent_snapshot_compare", args={...})
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
Run/plan/hypothesis/intent/snapshot/skill ไม่ให้ permission เพิ่ม ทุก target ยังผ่าน
|
|
245
|
+
OAuth scope, live target authority/epoch, trust approval, path/secret guards, expected hash,
|
|
246
|
+
command sandbox, idempotency และ audit เดิม `agent_exec` ใช้ explicit argv/owned handles
|
|
247
|
+
เท่านั้น และ cancel/pause coordinator ไม่ kill job ดู
|
|
248
|
+
[Advanced Agent Runtime](docs/AGENT_RUNTIME.md)
|
|
249
|
+
|
|
250
|
+
### เชื่อม Remote MCP ผ่าน Cloudflare Tunnel
|
|
251
|
+
|
|
252
|
+
DODO ไม่สร้าง Tunnel, DNS หรือ Cloudflare account ให้ ผู้ใช้สร้าง remotely-managed Tunnel และตั้ง public hostname ให้ route **ทุก path** มาที่ `http://127.0.0.1:21730` ก่อน จากนั้นตั้ง public origin ครั้งเดียว:
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
dodo setup --check --components cloudflared
|
|
256
|
+
dodo init --public-url https://mcp.example.com
|
|
257
|
+
dodo start
|
|
258
|
+
# Cloudflare Tunnel token (temporary; Enter = local only):
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
เมื่อกรอก token DODO จะเริ่ม `cloudflared` เป็น child process ของรอบนั้นและหยุดพร้อม
|
|
262
|
+
DODO Token อยู่ในหน่วยความจำระหว่างรอบและ environment ของ child เท่านั้น ไม่อยู่ใน
|
|
263
|
+
argv, config, Keychain, Credential Manager, Secret Service, tunnel log, MCP response
|
|
264
|
+
หรือ environment ของ MCP jobs กด Enter หรือใช้ `dodo start --no-tunnel` เพื่อเปิด
|
|
265
|
+
เฉพาะ local MCP
|
|
266
|
+
|
|
267
|
+
หน้า Local Config ที่ `127.0.0.1:21731` มีช่อง **Temporary Tunnel token** สำหรับเริ่ม
|
|
268
|
+
และหยุด tunnel ของ DODO process ปัจจุบันได้จริง ช่องจะถูกล้างหลังส่งและ backend ไม่
|
|
269
|
+
persist ค่า ดูสถานะด้วย `dodo tunnel status`, ตรวจ connectivity ด้วย
|
|
270
|
+
`dodo tunnel doctor` และดู log ที่ redacted ด้วย `dodo tunnel logs` คำสั่ง
|
|
271
|
+
`dodo tunnel configure` เดิมยังมีสำหรับ advanced/headless compatibility และต้องเรียก
|
|
272
|
+
โดยเจ้าของอย่างชัดเจน; เส้นทาง `dodo start` และหน้าเว็บไม่ใช้ credential store
|
|
273
|
+
|
|
274
|
+
บน macOS `dodo setup --yes` เลือก component `cloudflared` อยู่ในชุด `all` แล้ว
|
|
275
|
+
Tunnel route ต้องชี้เฉพาะ MCP/OAuth listener `21730` ห้ามชี้ Local Config `21731`
|
|
276
|
+
หรือ metrics `21732` ออก public
|
|
277
|
+
|
|
278
|
+
สำหรับ local MCP client เช่น Codex, Cursor หรือ Claude Desktop:
|
|
279
|
+
|
|
280
|
+
```bash
|
|
281
|
+
dodo stdio --root /path/to/your/project
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
STDIO ใช้ full catalog เป็นค่าเริ่มต้น ถ้าต้องการลด catalog ชั่วคราว:
|
|
285
|
+
|
|
286
|
+
```bash
|
|
287
|
+
dodo stdio --root /path/to/your/project --tools compact
|
|
288
|
+
dodo stdio --root /path/to/your/project --tools hybrid
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
## Compact Tool Surface
|
|
292
|
+
|
|
293
|
+
HTTP ใช้ Compact เป็นค่าเริ่มต้น ลำดับการใช้งานคือ:
|
|
294
|
+
|
|
295
|
+
```text
|
|
296
|
+
project_overview
|
|
297
|
+
→ dodo_discover
|
|
298
|
+
→ gateway ที่ตรงกับ operation
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
ตัวอย่างให้ AI แก้ `src/example.ts`:
|
|
302
|
+
|
|
303
|
+
```text
|
|
304
|
+
dodo_discover(query="edit TypeScript file")
|
|
305
|
+
dodo_read(operation="read_files", args={...})
|
|
306
|
+
dodo_write(operation="edit_file", args={...})
|
|
307
|
+
dodo_read(operation="read_files", args={...})
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
`dodo_discover` คืน schema ของ operation ที่เลือกและ hash ที่ deterministic ส่วน gateway จะส่ง request ผ่าน policy pipeline เดียวกับ tool รายตัว จึงยังตรวจ scope, ACL, workspace ID/epoch, trust, approval, path guard, secret guard, hash และ audit ครบทุกชั้น
|
|
311
|
+
|
|
312
|
+
ชื่อ gateway `dodo_*` เป็นชื่อ MCP protocol ที่คงไว้เพื่อ compatibility กับ client ที่เชื่อมต่ออยู่ การเปลี่ยนชื่อ gateway ต้องทำเป็น protocol migration แยกต่างหาก
|
|
313
|
+
|
|
314
|
+
## การเปลี่ยน workspace
|
|
315
|
+
|
|
316
|
+
1. เปิด Local Config จาก workspace ปัจจุบัน
|
|
317
|
+
2. ใส่ absolute path ของ project ใหม่
|
|
318
|
+
3. กดเปลี่ยนโปรเจกต์
|
|
319
|
+
4. ระบบตรวจ realpath, root policy, jobs และ request ที่กำลังทำงาน
|
|
320
|
+
5. ระบบเตรียม workspace ใหม่ก่อนสลับ และคืน workspace เดิมหากเตรียมไม่สำเร็จ
|
|
321
|
+
6. client ต้องเรียก `project_overview` ใหม่เพื่อรับ workspace ID/epoch ใหม่
|
|
322
|
+
|
|
323
|
+
ระบบไม่ kill jobs เงียบ ๆ Managed mode ไม่คัดลอก trust หรือ client ACL ไปยัง workspace ใหม่
|
|
324
|
+
|
|
325
|
+
## การเชื่อมต่อ
|
|
326
|
+
|
|
327
|
+
- **Local MCP:** `http://127.0.0.1:21730/mcp` สำหรับ process ในเครื่อง
|
|
328
|
+
- **Public MCP:** origin HTTPS ของ tunnel ที่เจ้าของสร้างและกำหนด route เอง; DODO อาจ supervise เฉพาะ `cloudflared` process ที่เจ้าของสั่ง
|
|
329
|
+
- **Local Config:** loopback เท่านั้น ใช้ owner capability token และ Host/Origin checks
|
|
330
|
+
|
|
331
|
+
DODO รายงาน `connected` เฉพาะเมื่อ managed `cloudflared` ตอบ readiness จริง และ `doctor` แยก local/public health ออกจากกัน สถานะนี้ไม่ใช่หลักฐานว่า ChatGPT หรือ AI client เชื่อมต่อแล้ว
|
|
332
|
+
|
|
333
|
+
## สิทธิ์
|
|
334
|
+
|
|
335
|
+
ค่าเริ่มต้น **personal** ใช้ OAuth scope + Agent Profile เป็นเพดานและไม่ถามซ้ำต่อ
|
|
336
|
+
โปรเจกต์ ส่วน **managed** ใช้ intersection ของ OAuth scope, workspace ACL และ local policy:
|
|
337
|
+
|
|
338
|
+
- `inspect` อ่านและวิเคราะห์ได้
|
|
339
|
+
- `edit` ทำ file changes ที่ผ่าน approval/policy ได้
|
|
340
|
+
- `trusted` อนุญาต effectful work ตาม policy ที่เจ้าของยืนยัน
|
|
341
|
+
|
|
342
|
+
โหมด trusted และคำสั่งที่เจ้าของอนุมัติใช้สิทธิ์ OS ของผู้ใช้จริง ควรเปิดเฉพาะ workspace ที่เชื่อถือได้
|
|
343
|
+
|
|
344
|
+
`dodo --bypass` ปรับ policy เฉพาะรอบนั้นตามที่เจ้าของสั่ง และไม่ปิด OAuth, target authority, workspace context, path guards หรือ secret guards
|
|
345
|
+
|
|
346
|
+
Desktop/Chrome consent แบบ `--persist` เป็นระดับ installation อนุญาตครั้งเดียวจาก path
|
|
347
|
+
ใดก็ได้แล้วใช้กับทุกโปรเจกต์ ส่วน macOS Screen Recording/Accessibility ยังต้องกดให้
|
|
348
|
+
สิทธิ์ใน System Settings จริง:
|
|
349
|
+
|
|
350
|
+
```bash
|
|
351
|
+
dodo desktop allow --app com.google.Chrome --mode control --persist --yes
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
## ความปลอดภัย
|
|
355
|
+
|
|
356
|
+
- public MCP ใช้ OAuth เสมอ ไม่มี NoAuth fallback
|
|
357
|
+
- Local Config bind loopback และมี capability token, expiration, Host/Origin checks และ rate limit
|
|
358
|
+
- client secret/access token ไม่แสดงใน UI หรือ audit
|
|
359
|
+
- path traversal, symlink/hardlink, secret paths และ stale hashes ถูกปฏิเสธ
|
|
360
|
+
- command environment ใช้ allowlist และไม่ส่ง local auth state ให้ child process
|
|
361
|
+
- repository instructions, `.dodo.json`, project hints และ AGENTS.md ไม่มีอำนาจเพิ่มสิทธิ์
|
|
362
|
+
- gateway ไม่ grant สิทธิ์และไม่ข้าม approval หรือ target operation policy
|
|
363
|
+
- CAS URI/hash ไม่ grant สิทธิ์; resource ทุก read/range/preview ตรวจ live target authority และ object hash ซ้ำ
|
|
364
|
+
|
|
365
|
+
ดูรายละเอียดที่ [SECURITY](docs/SECURITY.md), [AUTH](docs/AUTH.md) และ [ARCHITECTURE](docs/ARCHITECTURE.md)
|
|
366
|
+
|
|
367
|
+
## เอกสาร
|
|
368
|
+
|
|
369
|
+
- [Release 1.0.0](docs/RELEASE_1.0.0.md)
|
|
370
|
+
- [Runtime Intelligence](docs/RUNTIME.md)
|
|
371
|
+
- [Advanced Agent Runtime](docs/AGENT_RUNTIME.md)
|
|
372
|
+
- [Release notes](docs/RELEASE_NOTES.md)
|
|
373
|
+
- [Architecture](docs/ARCHITECTURE.md)
|
|
374
|
+
- [Compatibility](docs/COMPATIBILITY.md)
|
|
375
|
+
- [Security](docs/SECURITY.md)
|
|
376
|
+
- [Authentication](docs/AUTH.md)
|
|
377
|
+
- [Tunnel](docs/TUNNEL.md)
|
|
378
|
+
- [Web clients](docs/WEB_CLIENTS.md)
|
|
379
|
+
- [Windows compatibility](docs/WINDOWS.md)
|
|
380
|
+
- [Task assistance](docs/ASSISTANCE.md)
|
|
381
|
+
- [Multimodal](docs/MULTIMODAL.md)
|
|
382
|
+
- [Project Registry](docs/PROJECTS.md)
|
|
383
|
+
- [Universal resources and CAS](docs/RESOURCES.md)
|
|
384
|
+
- [Project Brain and incremental index](docs/BRAIN.md)
|
|
385
|
+
- [DodoBench and release gate](docs/EVALUATION.md)
|
|
386
|
+
- [Manual acceptance](docs/MANUAL_ACCEPTANCE.md)
|
|
387
|
+
- [Test report](docs/TEST_REPORT.md)
|
|
388
|
+
|
|
389
|
+
## Development
|
|
390
|
+
|
|
391
|
+
Platform CI ใช้ dedicated self-hosted runners ที่เจ้าของควบคุม: Linux X64 รันผ่าน
|
|
392
|
+
Docker พร้อม Playwright Chromium และ Windows X64 รัน native candidate gate ส่วน
|
|
393
|
+
macOS ยังรัน release gate บนเครื่องพัฒนา Workflow รับเฉพาะ push ที่ `main` และ manual
|
|
394
|
+
dispatch ไม่รัน pull request จากภายนอกบน self-hosted runner
|
|
395
|
+
|
|
396
|
+
รัน regression benchmark, macOS candidate gate และ Linux Docker gate ได้ด้วย:
|
|
397
|
+
|
|
398
|
+
```bash
|
|
399
|
+
npm run bench
|
|
400
|
+
npm run release:gate
|
|
401
|
+
npm run test:linux:docker
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
GitHub workflow รัน Node 22 และ 24 ทั้ง Linux/Windows โดยไม่ publish npm Windows จะ
|
|
405
|
+
ยังไม่ถูกประกาศเป็น supported platform จนกว่า automated native gate และ manual
|
|
406
|
+
Windows 11 acceptance จะผ่านตามเอกสาร
|
|
407
|
+
|
|
408
|
+
Release gate สร้างหลักฐาน non-secret ใน ignored `release-evidence/` และตรวจ fresh
|
|
409
|
+
exact-tarball ผ่าน STDIO Full กับ HTTP/OAuth Compact โดยไม่ publish npm ดูรายละเอียดที่
|
|
410
|
+
[DodoBench และ Release Gate](docs/EVALUATION.md)
|
|
411
|
+
|
|
412
|
+
เมื่อทั้งสอง report มาจาก Git revision และ `package-lock.json` เดียวกัน ให้รวมหลักฐาน
|
|
413
|
+
บน macOS ด้วย `node scripts/release-gate.mjs --release --platform-evidence /absolute/path/to/linux/gate-report.json`
|
|
414
|
+
คำสั่งนี้ไม่ publish package
|
|
415
|
+
|
|
416
|
+
```bash
|
|
417
|
+
npm ci
|
|
418
|
+
npm run build
|
|
419
|
+
npm run typecheck
|
|
420
|
+
npm run lint
|
|
421
|
+
npm run test:all
|
|
422
|
+
npm pack
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
โปรเจกต์นี้ใช้ GitHub repository [arthittakun/dodo-mcp](https://github.com/arthittakun/dodo-mcp) และ package `dodo-mcp`
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* oidc-provider persistence adapter backed by SQLite (spec §5, §8).
|
|
3
|
+
* The provider's own serializers are used untouched — DODO never invents its
|
|
4
|
+
* own OAuth token formats. Model `Client` resolves against the static
|
|
5
|
+
* registrations table so `dodo auth add-client` entries are live without a
|
|
6
|
+
* provider restart.
|
|
7
|
+
*/
|
|
8
|
+
export function createAdapterFactory(store) {
|
|
9
|
+
return (name) => new SqliteOidcAdapter(store, name);
|
|
10
|
+
}
|
|
11
|
+
class SqliteOidcAdapter {
|
|
12
|
+
store;
|
|
13
|
+
name;
|
|
14
|
+
constructor(store, name) {
|
|
15
|
+
this.store = store;
|
|
16
|
+
this.name = name;
|
|
17
|
+
}
|
|
18
|
+
async upsert(id, payload, expiresIn) {
|
|
19
|
+
this.store.oauthUpsert(this.name, id, payload, expiresIn);
|
|
20
|
+
}
|
|
21
|
+
async find(id) {
|
|
22
|
+
if (this.name === 'Client') {
|
|
23
|
+
return this.store.getOAuthClient(id);
|
|
24
|
+
}
|
|
25
|
+
return this.store.oauthFind(this.name, id);
|
|
26
|
+
}
|
|
27
|
+
async findByUserCode(userCode) {
|
|
28
|
+
return this.store.oauthFindByUserCode(this.name, userCode);
|
|
29
|
+
}
|
|
30
|
+
async findByUid(uid) {
|
|
31
|
+
return this.store.oauthFindByUid(this.name, uid);
|
|
32
|
+
}
|
|
33
|
+
async consume(id) {
|
|
34
|
+
this.store.oauthConsume(this.name, id);
|
|
35
|
+
}
|
|
36
|
+
async destroy(id) {
|
|
37
|
+
this.store.oauthDestroy(this.name, id);
|
|
38
|
+
}
|
|
39
|
+
async revokeByGrantId(grantId) {
|
|
40
|
+
this.store.oauthRevokeByGrantId(grantId);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../src/auth/adapter.ts"],"names":[],"mappings":"AAGA;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAY;IAC/C,OAAO,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,iBAAiB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;AAC9D,CAAC;AAED,MAAM,iBAAiB;IAEF;IACA;IAFnB,YACmB,KAAY,EACZ,IAAY;QADZ,UAAK,GAAL,KAAK,CAAO;QACZ,SAAI,GAAJ,IAAI,CAAQ;IAC5B,CAAC;IAEJ,KAAK,CAAC,MAAM,CAAC,EAAU,EAAE,OAAuB,EAAE,SAAkB;QAClE,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,OAAkC,EAAE,SAAS,CAAC,CAAC;IACvF,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,EAAU;QACnB,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC3B,OAAO,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE,CAA+B,CAAC;QACrE,CAAC;QACD,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAA+B,CAAC;IAC3E,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,QAAgB;QACnC,OAAO,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAA+B,CAAC;IAC3F,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,GAAW;QACzB,OAAO,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAA+B,CAAC;IACjF,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,EAAU;QACtB,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,EAAU;QACtB,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,OAAe;QACnC,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC3C,CAAC;CACF"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { DodoError } from '../errors.js';
|
|
3
|
+
import { digestOf } from '../util/hash.js';
|
|
4
|
+
export const DeleteClientsInput = z.object({
|
|
5
|
+
clients: z.array(z.object({ id: z.string().min(1).max(128), reviewHash: z.string().regex(/^sha256:[a-f0-9]{64}$/) }).strict()).min(1).max(100),
|
|
6
|
+
confirm: z.literal('delete-selected-clients'),
|
|
7
|
+
}).strict();
|
|
8
|
+
/** Owner-only review: counts and opaque fingerprint, never credentials or paths. */
|
|
9
|
+
export function reviewClientDeletion(store, id) {
|
|
10
|
+
const client = store.getOAuthClient(id);
|
|
11
|
+
if (!client)
|
|
12
|
+
throw new DodoError('NOT_FOUND', 'Client no longer exists; reload the list');
|
|
13
|
+
const access = store.db.prepare('SELECT workspace_id, scopes FROM workspace_clients WHERE client_id=? ORDER BY workspace_id').all(id);
|
|
14
|
+
const grants = store.db.prepare('SELECT id,revoked_at FROM grants WHERE client_id=? ORDER BY id').all(id);
|
|
15
|
+
return {
|
|
16
|
+
id,
|
|
17
|
+
name: typeof client['client_name'] === 'string' ? client['client_name'] : null,
|
|
18
|
+
workspaceCount: access.filter(a => store.clientAccess(a.workspace_id, id).length > 0).length,
|
|
19
|
+
grantCount: grants.filter(g => g.revoked_at === null).length,
|
|
20
|
+
reviewHash: digestOf({ id, client, access, grants }),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/** One durable transaction for the reviewed selection; no wildcard/global reset. */
|
|
24
|
+
export function deleteReviewedClients(store, input, workspaceId) {
|
|
25
|
+
const ids = input.clients.map(c => c.id);
|
|
26
|
+
if (new Set(ids).size !== ids.length)
|
|
27
|
+
throw new DodoError('INVALID_INPUT', 'Select each client only once');
|
|
28
|
+
return store.db.transaction(() => {
|
|
29
|
+
// Revalidate all before touching any row. A new client is never swept in.
|
|
30
|
+
for (const c of input.clients) {
|
|
31
|
+
if (reviewClientDeletion(store, c.id).reviewHash !== c.reviewHash)
|
|
32
|
+
throw new DodoError('CONFLICT', 'Client access changed since review; reload and select again');
|
|
33
|
+
}
|
|
34
|
+
for (const id of ids) {
|
|
35
|
+
store.db.prepare("UPDATE pending_approvals SET status='denied' WHERE status IN ('pending','approved') AND (principal IN (SELECT id FROM grants WHERE client_id=?) OR (kind='oauth' AND CASE WHEN json_valid(summary) THEN json_extract(summary,'$.clientId') END=?))").run(id, id);
|
|
36
|
+
store.db.prepare('UPDATE grants SET revoked_at=COALESCE(revoked_at,?) WHERE client_id=?').run(Date.now(), id);
|
|
37
|
+
store.db.prepare("DELETE FROM oauth_models WHERE grant_id IN (SELECT id FROM grants WHERE client_id=?) OR (model='Grant' AND id IN (SELECT id FROM grants WHERE client_id=?)) OR CASE WHEN json_valid(payload) THEN json_extract(payload,'$.clientId') END=? OR CASE WHEN json_valid(payload) THEN json_extract(payload,'$.params.client_id') END=?").run(id, id, id, id);
|
|
38
|
+
store.db.prepare('DELETE FROM workspace_clients WHERE client_id=?').run(id);
|
|
39
|
+
store.db.prepare('DELETE FROM oauth_clients WHERE client_id=?').run(id);
|
|
40
|
+
store.audit({ principal: 'local-config-owner', workspaceId, tool: 'local.client.delete', refId: id, result: 'deleted' });
|
|
41
|
+
}
|
|
42
|
+
return { ok: true, deleted: ids };
|
|
43
|
+
}).immediate();
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=clientDeletion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clientDeletion.js","sourceRoot":"","sources":["../../src/auth/clientDeletion.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { randomBytes } from 'node:crypto';
|
|
2
|
+
import { DodoError } from '../errors.js';
|
|
3
|
+
export function addStaticClient(store, opts) {
|
|
4
|
+
if (opts.redirectUris.length === 0)
|
|
5
|
+
throw new DodoError('INVALID_INPUT', 'at least one --redirect-uri is required');
|
|
6
|
+
for (const uri of opts.redirectUris) {
|
|
7
|
+
let parsed;
|
|
8
|
+
try {
|
|
9
|
+
parsed = new URL(uri);
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
throw new DodoError('INVALID_INPUT', `redirect URI is not a valid URL: ${uri}`);
|
|
13
|
+
}
|
|
14
|
+
if (parsed.protocol !== 'https:' && parsed.hostname !== 'localhost' && parsed.hostname !== '127.0.0.1') {
|
|
15
|
+
throw new DodoError('INVALID_INPUT', 'redirect URIs must be https (or loopback for local testing)');
|
|
16
|
+
}
|
|
17
|
+
if (uri.includes('*'))
|
|
18
|
+
throw new DodoError('INVALID_INPUT', 'wildcard redirect URIs are not allowed');
|
|
19
|
+
if (parsed.hash !== '')
|
|
20
|
+
throw new DodoError('INVALID_INPUT', 'redirect URIs must not contain a fragment');
|
|
21
|
+
}
|
|
22
|
+
const clientId = `dodo-client-${randomBytes(6).toString('hex')}`;
|
|
23
|
+
const isPublic = opts.public === true;
|
|
24
|
+
const clientSecret = isPublic ? undefined : randomBytes(32).toString('base64url');
|
|
25
|
+
const payload = {
|
|
26
|
+
client_id: clientId,
|
|
27
|
+
client_name: opts.name ?? 'dodo remote client',
|
|
28
|
+
redirect_uris: opts.redirectUris,
|
|
29
|
+
grant_types: ['authorization_code', 'refresh_token'],
|
|
30
|
+
response_types: ['code'],
|
|
31
|
+
token_endpoint_auth_method: isPublic ? 'none' : 'client_secret_basic',
|
|
32
|
+
application_type: 'web',
|
|
33
|
+
};
|
|
34
|
+
if (clientSecret)
|
|
35
|
+
payload['client_secret'] = clientSecret;
|
|
36
|
+
store.putOAuthClient(clientId, payload);
|
|
37
|
+
const info = {
|
|
38
|
+
clientId,
|
|
39
|
+
redirectUris: opts.redirectUris,
|
|
40
|
+
name: payload['client_name'] ?? 'dodo remote client',
|
|
41
|
+
tokenEndpointAuthMethod: payload['token_endpoint_auth_method'],
|
|
42
|
+
};
|
|
43
|
+
if (clientSecret !== undefined)
|
|
44
|
+
info.clientSecret = clientSecret;
|
|
45
|
+
return info;
|
|
46
|
+
}
|
|
47
|
+
export function listStaticClients(store) {
|
|
48
|
+
return store.listOAuthClients().map((c) => ({
|
|
49
|
+
clientId: c.clientId,
|
|
50
|
+
name: c.payload['client_name'] ?? '',
|
|
51
|
+
redirectUris: c.payload['redirect_uris'] ?? [],
|
|
52
|
+
createdAt: c.createdAt,
|
|
53
|
+
}));
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=clients.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clients.js","sourceRoot":"","sources":["../../src/auth/clients.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** The single local owner account id (single-owner mode, spec §8.4). */
|
|
2
|
+
export const OWNER_ACCOUNT_ID = 'owner';
|
|
3
|
+
/**
|
|
4
|
+
* OAuth login identifies one DODO installation. Project access is a separate
|
|
5
|
+
* owner-managed ACL, so consent must never be bound to whichever project is
|
|
6
|
+
* selected while the browser flow happens.
|
|
7
|
+
*/
|
|
8
|
+
export const INSTALLATION_AUTHORITY_ID = 'dodo-installation';
|
|
9
|
+
export const INSTALLATION_AUTHORITY_EPOCH = 'installation-auth-v2';
|
|
10
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/auth/constants.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,MAAM,CAAC,MAAM,gBAAgB,GAAG,OAAO,CAAC;AAExC;;;;GAIG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,mBAAmB,CAAC;AAC7D,MAAM,CAAC,MAAM,4BAA4B,GAAG,sBAAsB,CAAC"}
|