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/dist/store/db.js
ADDED
|
@@ -0,0 +1,711 @@
|
|
|
1
|
+
import Database from 'better-sqlite3';
|
|
2
|
+
import { decodeAccessScopes } from './scopeEncoding.js';
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import { DodoError } from '../errors.js';
|
|
5
|
+
/**
|
|
6
|
+
* Durable state (spec §5). WAL mode so the CLI can perform offline writes
|
|
7
|
+
* (trust, client registration) while a server holds the database.
|
|
8
|
+
* Fail closed on migration problems — never fall back to in-memory auth state.
|
|
9
|
+
*/
|
|
10
|
+
const MIGRATIONS = [
|
|
11
|
+
`
|
|
12
|
+
CREATE TABLE meta (key TEXT PRIMARY KEY, value TEXT NOT NULL);
|
|
13
|
+
CREATE TABLE workspaces (
|
|
14
|
+
id TEXT PRIMARY KEY, root TEXT NOT NULL, dev INTEGER NOT NULL, ino INTEGER NOT NULL,
|
|
15
|
+
trust_mode TEXT NOT NULL DEFAULT 'inspect', created_at INTEGER NOT NULL,
|
|
16
|
+
last_epoch TEXT, last_seen_at INTEGER
|
|
17
|
+
);
|
|
18
|
+
CREATE TABLE policy_versions (
|
|
19
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT, workspace_id TEXT NOT NULL,
|
|
20
|
+
mode TEXT NOT NULL, changed_at INTEGER NOT NULL
|
|
21
|
+
);
|
|
22
|
+
CREATE TABLE oauth_clients (
|
|
23
|
+
client_id TEXT PRIMARY KEY, payload TEXT NOT NULL, created_at INTEGER NOT NULL
|
|
24
|
+
);
|
|
25
|
+
CREATE TABLE oauth_models (
|
|
26
|
+
model TEXT NOT NULL, id TEXT NOT NULL, payload TEXT NOT NULL,
|
|
27
|
+
grant_id TEXT, uid TEXT, user_code TEXT,
|
|
28
|
+
expires_at INTEGER, consumed_at INTEGER,
|
|
29
|
+
PRIMARY KEY (model, id)
|
|
30
|
+
);
|
|
31
|
+
CREATE INDEX idx_oauth_models_grant ON oauth_models (grant_id);
|
|
32
|
+
CREATE INDEX idx_oauth_models_uid ON oauth_models (uid);
|
|
33
|
+
CREATE INDEX idx_oauth_models_expiry ON oauth_models (expires_at);
|
|
34
|
+
CREATE TABLE grants (
|
|
35
|
+
id TEXT PRIMARY KEY, workspace_id TEXT NOT NULL, client_id TEXT NOT NULL,
|
|
36
|
+
account_id TEXT NOT NULL, scopes TEXT NOT NULL,
|
|
37
|
+
created_at INTEGER NOT NULL, revoked_at INTEGER
|
|
38
|
+
);
|
|
39
|
+
CREATE INDEX idx_grants_workspace ON grants (workspace_id);
|
|
40
|
+
CREATE TABLE pending_approvals (
|
|
41
|
+
id TEXT PRIMARY KEY, kind TEXT NOT NULL, workspace_id TEXT, epoch TEXT,
|
|
42
|
+
principal TEXT, tool TEXT, digest TEXT, summary TEXT NOT NULL,
|
|
43
|
+
created_at INTEGER NOT NULL, expires_at INTEGER NOT NULL,
|
|
44
|
+
status TEXT NOT NULL DEFAULT 'pending', approved_at INTEGER, consumed_at INTEGER
|
|
45
|
+
);
|
|
46
|
+
CREATE INDEX idx_approvals_digest ON pending_approvals (workspace_id, digest);
|
|
47
|
+
CREATE TABLE change_plans (
|
|
48
|
+
id TEXT PRIMARY KEY, workspace_id TEXT NOT NULL, epoch TEXT NOT NULL,
|
|
49
|
+
principal TEXT NOT NULL, plan_hash TEXT NOT NULL, payload TEXT NOT NULL,
|
|
50
|
+
created_at INTEGER NOT NULL, expires_at INTEGER NOT NULL, invalidated_at INTEGER
|
|
51
|
+
);
|
|
52
|
+
CREATE TABLE changesets (
|
|
53
|
+
id TEXT PRIMARY KEY, workspace_id TEXT NOT NULL, epoch TEXT NOT NULL,
|
|
54
|
+
plan_id TEXT, principal TEXT NOT NULL, status TEXT NOT NULL, kind TEXT NOT NULL,
|
|
55
|
+
created_at INTEGER NOT NULL, committed_at INTEGER, summary TEXT, error TEXT
|
|
56
|
+
);
|
|
57
|
+
CREATE INDEX idx_changesets_ws ON changesets (workspace_id, created_at);
|
|
58
|
+
CREATE TABLE journal_steps (
|
|
59
|
+
changeset_id TEXT NOT NULL, seq INTEGER NOT NULL, op TEXT NOT NULL,
|
|
60
|
+
path TEXT NOT NULL, dest_path TEXT, before_hash TEXT, after_hash TEXT,
|
|
61
|
+
backup_path TEXT, state TEXT NOT NULL,
|
|
62
|
+
PRIMARY KEY (changeset_id, seq)
|
|
63
|
+
);
|
|
64
|
+
CREATE TABLE idempotency_keys (
|
|
65
|
+
key TEXT NOT NULL, principal TEXT NOT NULL, workspace_id TEXT NOT NULL, tool TEXT NOT NULL,
|
|
66
|
+
payload_hash TEXT NOT NULL, state TEXT NOT NULL, result TEXT,
|
|
67
|
+
created_at INTEGER NOT NULL,
|
|
68
|
+
PRIMARY KEY (key, principal, workspace_id, tool)
|
|
69
|
+
);
|
|
70
|
+
CREATE TABLE jobs (
|
|
71
|
+
id TEXT PRIMARY KEY, workspace_id TEXT NOT NULL, epoch TEXT NOT NULL, principal TEXT NOT NULL,
|
|
72
|
+
kind TEXT NOT NULL, program TEXT NOT NULL, args TEXT NOT NULL, cwd TEXT NOT NULL,
|
|
73
|
+
recipe_id TEXT, pid INTEGER, status TEXT NOT NULL,
|
|
74
|
+
exit_code INTEGER, signal TEXT, started_at INTEGER, ended_at INTEGER,
|
|
75
|
+
timeout_ms INTEGER NOT NULL, created_at INTEGER NOT NULL
|
|
76
|
+
);
|
|
77
|
+
CREATE INDEX idx_jobs_ws ON jobs (workspace_id, created_at);
|
|
78
|
+
CREATE TABLE audit_events (
|
|
79
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT, ts INTEGER NOT NULL, request_id TEXT,
|
|
80
|
+
principal TEXT, workspace_id TEXT, tool TEXT, paths TEXT, input_digest TEXT,
|
|
81
|
+
ref_id TEXT, duration_ms INTEGER, result TEXT NOT NULL
|
|
82
|
+
);
|
|
83
|
+
CREATE INDEX idx_audit_ts ON audit_events (ts);
|
|
84
|
+
CREATE TABLE handoffs (
|
|
85
|
+
id TEXT PRIMARY KEY, workspace_id TEXT NOT NULL, principal TEXT NOT NULL,
|
|
86
|
+
payload TEXT NOT NULL, created_at INTEGER NOT NULL
|
|
87
|
+
);
|
|
88
|
+
CREATE INDEX idx_handoffs_ws ON handoffs (workspace_id, created_at);
|
|
89
|
+
`,
|
|
90
|
+
`
|
|
91
|
+
CREATE TABLE todos (
|
|
92
|
+
workspace_id TEXT PRIMARY KEY, payload TEXT NOT NULL, updated_at INTEGER NOT NULL, principal TEXT NOT NULL
|
|
93
|
+
);
|
|
94
|
+
`,
|
|
95
|
+
`CREATE TABLE workspace_clients (
|
|
96
|
+
workspace_id TEXT NOT NULL, client_id TEXT NOT NULL, scopes TEXT NOT NULL,
|
|
97
|
+
PRIMARY KEY (workspace_id, client_id)
|
|
98
|
+
);
|
|
99
|
+
INSERT OR REPLACE INTO workspace_clients(workspace_id,client_id,scopes)
|
|
100
|
+
SELECT workspace_id,client_id,scopes FROM grants WHERE revoked_at IS NULL ORDER BY created_at;
|
|
101
|
+
`,
|
|
102
|
+
(db) => {
|
|
103
|
+
// An earlier schema step copied grants.scopes (space-separated) into a
|
|
104
|
+
// JSON ACL. Normalize both partially and directly upgraded stores.
|
|
105
|
+
const rows = db.prepare('SELECT workspace_id, client_id, scopes FROM workspace_clients').all();
|
|
106
|
+
const update = db.prepare('UPDATE workspace_clients SET scopes=? WHERE workspace_id=? AND client_id=?');
|
|
107
|
+
for (const row of rows)
|
|
108
|
+
update.run(JSON.stringify(decodeAccessScopes(row.scopes, true)), row.workspace_id, row.client_id);
|
|
109
|
+
},
|
|
110
|
+
`CREATE TABLE usage_consents (
|
|
111
|
+
id TEXT PRIMARY KEY, workspace_id TEXT NOT NULL, epoch TEXT NOT NULL,
|
|
112
|
+
client_id TEXT NOT NULL, grant_id TEXT NOT NULL, label TEXT NOT NULL,
|
|
113
|
+
status TEXT NOT NULL, created_at INTEGER NOT NULL, expires_at INTEGER NOT NULL
|
|
114
|
+
);
|
|
115
|
+
CREATE INDEX idx_usage_ws ON usage_consents(workspace_id, epoch);
|
|
116
|
+
CREATE TABLE schedules (
|
|
117
|
+
id TEXT PRIMARY KEY, workspace_id TEXT NOT NULL, payload TEXT NOT NULL,
|
|
118
|
+
digest TEXT NOT NULL, status TEXT NOT NULL, created_at INTEGER NOT NULL,
|
|
119
|
+
expires_at INTEGER NOT NULL, next_at INTEGER, approved_at INTEGER
|
|
120
|
+
);
|
|
121
|
+
CREATE TABLE schedule_runs (
|
|
122
|
+
schedule_id TEXT NOT NULL, due_at INTEGER NOT NULL, status TEXT NOT NULL,
|
|
123
|
+
job_id TEXT, error TEXT, PRIMARY KEY(schedule_id, due_at)
|
|
124
|
+
);`,
|
|
125
|
+
`CREATE TABLE chat_permissions (
|
|
126
|
+
id TEXT PRIMARY KEY, workspace_id TEXT NOT NULL, client_id TEXT NOT NULL, chat_id TEXT NOT NULL,
|
|
127
|
+
created_at INTEGER NOT NULL, expires_at INTEGER, revoked_at INTEGER,
|
|
128
|
+
root_dev INTEGER NOT NULL, root_ino INTEGER NOT NULL
|
|
129
|
+
);
|
|
130
|
+
CREATE UNIQUE INDEX idx_chat_active ON chat_permissions(workspace_id,client_id,chat_id) WHERE revoked_at IS NULL;
|
|
131
|
+
ALTER TABLE usage_consents ADD COLUMN chat_permission_id TEXT;
|
|
132
|
+
CREATE INDEX idx_usage_chat ON usage_consents(chat_permission_id);`,
|
|
133
|
+
`CREATE TABLE project_registry (
|
|
134
|
+
id TEXT PRIMARY KEY,
|
|
135
|
+
workspace_id TEXT NOT NULL,
|
|
136
|
+
canonical_root TEXT NOT NULL,
|
|
137
|
+
display_name TEXT NOT NULL,
|
|
138
|
+
root_dev INTEGER NOT NULL,
|
|
139
|
+
root_ino INTEGER NOT NULL,
|
|
140
|
+
metadata_version INTEGER NOT NULL,
|
|
141
|
+
created_at INTEGER NOT NULL,
|
|
142
|
+
updated_at INTEGER NOT NULL,
|
|
143
|
+
removed_at INTEGER
|
|
144
|
+
);
|
|
145
|
+
CREATE UNIQUE INDEX idx_project_registry_active_root
|
|
146
|
+
ON project_registry(canonical_root) WHERE removed_at IS NULL;
|
|
147
|
+
CREATE UNIQUE INDEX idx_project_registry_active_identity
|
|
148
|
+
ON project_registry(root_dev, root_ino) WHERE removed_at IS NULL;
|
|
149
|
+
CREATE INDEX idx_project_registry_updated
|
|
150
|
+
ON project_registry(removed_at, updated_at DESC);`,
|
|
151
|
+
`CREATE TABLE resource_objects (
|
|
152
|
+
hash TEXT PRIMARY KEY,
|
|
153
|
+
bytes INTEGER NOT NULL,
|
|
154
|
+
created_at INTEGER NOT NULL,
|
|
155
|
+
verified_at INTEGER NOT NULL
|
|
156
|
+
);
|
|
157
|
+
CREATE TABLE resource_refs (
|
|
158
|
+
id TEXT PRIMARY KEY,
|
|
159
|
+
workspace_id TEXT NOT NULL,
|
|
160
|
+
principal TEXT NOT NULL,
|
|
161
|
+
object_hash TEXT NOT NULL REFERENCES resource_objects(hash) ON DELETE RESTRICT,
|
|
162
|
+
mime_type TEXT NOT NULL,
|
|
163
|
+
source_kind TEXT NOT NULL,
|
|
164
|
+
source_label TEXT NOT NULL,
|
|
165
|
+
capabilities TEXT NOT NULL,
|
|
166
|
+
metadata TEXT NOT NULL,
|
|
167
|
+
created_at INTEGER NOT NULL,
|
|
168
|
+
expires_at INTEGER NOT NULL
|
|
169
|
+
);
|
|
170
|
+
CREATE INDEX idx_resource_refs_owner
|
|
171
|
+
ON resource_refs(workspace_id, principal, expires_at);
|
|
172
|
+
CREATE INDEX idx_resource_refs_object
|
|
173
|
+
ON resource_refs(object_hash);
|
|
174
|
+
CREATE INDEX idx_resource_refs_expiry
|
|
175
|
+
ON resource_refs(expires_at);`,
|
|
176
|
+
`CREATE TRIGGER resource_objects_quota
|
|
177
|
+
BEFORE INSERT ON resource_objects
|
|
178
|
+
WHEN NOT EXISTS (SELECT 1 FROM resource_objects WHERE hash=NEW.hash)
|
|
179
|
+
AND COALESCE((SELECT SUM(bytes) FROM resource_objects),0) + NEW.bytes > 2147483648
|
|
180
|
+
BEGIN
|
|
181
|
+
SELECT RAISE(ABORT, 'resource store quota exceeded');
|
|
182
|
+
END;`,
|
|
183
|
+
`CREATE TABLE brain_index_state (
|
|
184
|
+
workspace_id TEXT PRIMARY KEY,
|
|
185
|
+
namespace TEXT NOT NULL,
|
|
186
|
+
schema_version INTEGER NOT NULL,
|
|
187
|
+
parser_version TEXT NOT NULL,
|
|
188
|
+
config_hash TEXT NOT NULL,
|
|
189
|
+
status TEXT NOT NULL,
|
|
190
|
+
paused INTEGER NOT NULL DEFAULT 0,
|
|
191
|
+
generation INTEGER NOT NULL DEFAULT 0,
|
|
192
|
+
active_run_id TEXT,
|
|
193
|
+
last_run_id TEXT,
|
|
194
|
+
last_started_at INTEGER,
|
|
195
|
+
last_completed_at INTEGER,
|
|
196
|
+
last_error TEXT,
|
|
197
|
+
source_hash TEXT,
|
|
198
|
+
metrics TEXT NOT NULL
|
|
199
|
+
);
|
|
200
|
+
CREATE TABLE brain_file_cache (
|
|
201
|
+
workspace_id TEXT NOT NULL,
|
|
202
|
+
path TEXT NOT NULL,
|
|
203
|
+
file_id TEXT NOT NULL,
|
|
204
|
+
content_hash TEXT NOT NULL,
|
|
205
|
+
bytes INTEGER NOT NULL,
|
|
206
|
+
mtime_ms REAL NOT NULL,
|
|
207
|
+
ctime_ms REAL NOT NULL,
|
|
208
|
+
parser_version TEXT NOT NULL,
|
|
209
|
+
schema_version INTEGER NOT NULL,
|
|
210
|
+
config_hash TEXT NOT NULL,
|
|
211
|
+
payload TEXT NOT NULL,
|
|
212
|
+
indexed_at INTEGER NOT NULL,
|
|
213
|
+
generation INTEGER NOT NULL,
|
|
214
|
+
PRIMARY KEY (workspace_id, path),
|
|
215
|
+
UNIQUE (workspace_id, file_id)
|
|
216
|
+
);
|
|
217
|
+
CREATE INDEX idx_brain_files_hash ON brain_file_cache(workspace_id, content_hash);
|
|
218
|
+
CREATE TABLE brain_nodes (
|
|
219
|
+
workspace_id TEXT NOT NULL,
|
|
220
|
+
node_id TEXT NOT NULL,
|
|
221
|
+
uri TEXT NOT NULL,
|
|
222
|
+
node_type TEXT NOT NULL,
|
|
223
|
+
name TEXT NOT NULL,
|
|
224
|
+
qualified_name TEXT,
|
|
225
|
+
path TEXT NOT NULL,
|
|
226
|
+
line INTEGER NOT NULL,
|
|
227
|
+
column_no INTEGER NOT NULL,
|
|
228
|
+
end_line INTEGER NOT NULL,
|
|
229
|
+
end_column INTEGER NOT NULL,
|
|
230
|
+
source_hash TEXT NOT NULL,
|
|
231
|
+
parser_version TEXT NOT NULL,
|
|
232
|
+
schema_version INTEGER NOT NULL,
|
|
233
|
+
freshness TEXT NOT NULL,
|
|
234
|
+
details TEXT NOT NULL,
|
|
235
|
+
updated_at INTEGER NOT NULL,
|
|
236
|
+
generation INTEGER NOT NULL,
|
|
237
|
+
PRIMARY KEY (workspace_id, node_id),
|
|
238
|
+
UNIQUE (workspace_id, uri)
|
|
239
|
+
);
|
|
240
|
+
CREATE INDEX idx_brain_nodes_query ON brain_nodes(workspace_id, node_type, name);
|
|
241
|
+
CREATE INDEX idx_brain_nodes_path ON brain_nodes(workspace_id, path);
|
|
242
|
+
CREATE TABLE brain_edges (
|
|
243
|
+
workspace_id TEXT NOT NULL,
|
|
244
|
+
edge_id TEXT NOT NULL,
|
|
245
|
+
edge_type TEXT NOT NULL,
|
|
246
|
+
from_node_id TEXT NOT NULL,
|
|
247
|
+
to_node_id TEXT,
|
|
248
|
+
target_key TEXT,
|
|
249
|
+
source_path TEXT NOT NULL,
|
|
250
|
+
target_path TEXT,
|
|
251
|
+
line INTEGER NOT NULL,
|
|
252
|
+
source_hash TEXT NOT NULL,
|
|
253
|
+
parser_version TEXT NOT NULL,
|
|
254
|
+
schema_version INTEGER NOT NULL,
|
|
255
|
+
freshness TEXT NOT NULL,
|
|
256
|
+
details TEXT NOT NULL,
|
|
257
|
+
updated_at INTEGER NOT NULL,
|
|
258
|
+
generation INTEGER NOT NULL,
|
|
259
|
+
PRIMARY KEY (workspace_id, edge_id)
|
|
260
|
+
);
|
|
261
|
+
CREATE INDEX idx_brain_edges_source ON brain_edges(workspace_id, source_path, edge_type);
|
|
262
|
+
CREATE INDEX idx_brain_edges_target ON brain_edges(workspace_id, target_path, edge_type);
|
|
263
|
+
CREATE TABLE brain_runs (
|
|
264
|
+
id TEXT PRIMARY KEY,
|
|
265
|
+
workspace_id TEXT NOT NULL,
|
|
266
|
+
mode TEXT NOT NULL,
|
|
267
|
+
trigger_kind TEXT NOT NULL,
|
|
268
|
+
status TEXT NOT NULL,
|
|
269
|
+
started_at INTEGER NOT NULL,
|
|
270
|
+
ended_at INTEGER,
|
|
271
|
+
metrics TEXT NOT NULL,
|
|
272
|
+
error TEXT
|
|
273
|
+
);
|
|
274
|
+
CREATE INDEX idx_brain_runs_workspace ON brain_runs(workspace_id, started_at DESC);`,
|
|
275
|
+
`CREATE TABLE context_cache (
|
|
276
|
+
cache_key TEXT PRIMARY KEY,
|
|
277
|
+
workspace_id TEXT NOT NULL,
|
|
278
|
+
principal TEXT NOT NULL,
|
|
279
|
+
level INTEGER NOT NULL CHECK(level BETWEEN 0 AND 6),
|
|
280
|
+
query_hash TEXT NOT NULL,
|
|
281
|
+
payload TEXT NOT NULL,
|
|
282
|
+
dependencies TEXT NOT NULL,
|
|
283
|
+
created_at INTEGER NOT NULL,
|
|
284
|
+
last_hit_at INTEGER NOT NULL,
|
|
285
|
+
hits INTEGER NOT NULL DEFAULT 0,
|
|
286
|
+
expires_at INTEGER NOT NULL
|
|
287
|
+
);
|
|
288
|
+
CREATE INDEX idx_context_cache_scope ON context_cache(workspace_id, principal, query_hash, level);
|
|
289
|
+
CREATE INDEX idx_context_cache_expiry ON context_cache(expires_at);
|
|
290
|
+
CREATE TABLE context_evidence (
|
|
291
|
+
evidence_id TEXT PRIMARY KEY,
|
|
292
|
+
request_workspace_id TEXT NOT NULL,
|
|
293
|
+
source_workspace_id TEXT NOT NULL,
|
|
294
|
+
principal TEXT NOT NULL,
|
|
295
|
+
query_hash TEXT NOT NULL,
|
|
296
|
+
kind TEXT NOT NULL,
|
|
297
|
+
claim TEXT NOT NULL,
|
|
298
|
+
project_id TEXT,
|
|
299
|
+
display_name TEXT NOT NULL,
|
|
300
|
+
active_source INTEGER NOT NULL,
|
|
301
|
+
source_kind TEXT NOT NULL,
|
|
302
|
+
source_resource TEXT NOT NULL,
|
|
303
|
+
source_path TEXT,
|
|
304
|
+
source_hash TEXT NOT NULL,
|
|
305
|
+
source_line INTEGER,
|
|
306
|
+
source_end_line INTEGER,
|
|
307
|
+
commit_sha TEXT,
|
|
308
|
+
confidence REAL NOT NULL,
|
|
309
|
+
ranking_score REAL NOT NULL,
|
|
310
|
+
ranking_reasons TEXT NOT NULL,
|
|
311
|
+
limitations TEXT NOT NULL,
|
|
312
|
+
freshness TEXT NOT NULL,
|
|
313
|
+
generated_at INTEGER NOT NULL,
|
|
314
|
+
last_verified_at INTEGER NOT NULL,
|
|
315
|
+
expires_at INTEGER NOT NULL
|
|
316
|
+
);
|
|
317
|
+
CREATE INDEX idx_context_evidence_scope ON context_evidence(request_workspace_id, principal, query_hash, freshness);
|
|
318
|
+
CREATE INDEX idx_context_evidence_source ON context_evidence(source_workspace_id, source_path, source_hash);
|
|
319
|
+
CREATE INDEX idx_context_evidence_expiry ON context_evidence(expires_at);
|
|
320
|
+
CREATE TABLE context_metrics (
|
|
321
|
+
workspace_id TEXT NOT NULL,
|
|
322
|
+
principal TEXT NOT NULL,
|
|
323
|
+
queries INTEGER NOT NULL DEFAULT 0,
|
|
324
|
+
cache_hits INTEGER NOT NULL DEFAULT 0,
|
|
325
|
+
total_latency_ms INTEGER NOT NULL DEFAULT 0,
|
|
326
|
+
candidates INTEGER NOT NULL DEFAULT 0,
|
|
327
|
+
returned INTEGER NOT NULL DEFAULT 0,
|
|
328
|
+
stale_transitions INTEGER NOT NULL DEFAULT 0,
|
|
329
|
+
last_term_coverage REAL NOT NULL DEFAULT 0,
|
|
330
|
+
last_query_at INTEGER,
|
|
331
|
+
PRIMARY KEY(workspace_id, principal)
|
|
332
|
+
);`,
|
|
333
|
+
`CREATE TABLE memory_proposals (
|
|
334
|
+
id TEXT PRIMARY KEY,
|
|
335
|
+
source_workspace_id TEXT NOT NULL,
|
|
336
|
+
source_project_id TEXT,
|
|
337
|
+
principal TEXT NOT NULL,
|
|
338
|
+
kind TEXT NOT NULL,
|
|
339
|
+
claim TEXT NOT NULL,
|
|
340
|
+
rationale TEXT NOT NULL,
|
|
341
|
+
affected_entities TEXT NOT NULL,
|
|
342
|
+
evidence TEXT NOT NULL,
|
|
343
|
+
confidence REAL NOT NULL,
|
|
344
|
+
fingerprint TEXT NOT NULL,
|
|
345
|
+
conflicts TEXT NOT NULL,
|
|
346
|
+
digest TEXT NOT NULL,
|
|
347
|
+
retention_days INTEGER NOT NULL,
|
|
348
|
+
status TEXT NOT NULL,
|
|
349
|
+
created_at INTEGER NOT NULL,
|
|
350
|
+
expires_at INTEGER NOT NULL,
|
|
351
|
+
reviewed_at INTEGER,
|
|
352
|
+
review_note TEXT,
|
|
353
|
+
approved_memory_id TEXT
|
|
354
|
+
);
|
|
355
|
+
CREATE INDEX idx_memory_proposals_workspace ON memory_proposals(source_workspace_id,status,created_at);
|
|
356
|
+
CREATE INDEX idx_memory_proposals_fingerprint ON memory_proposals(source_workspace_id,fingerprint,status);
|
|
357
|
+
CREATE TABLE memories (
|
|
358
|
+
id TEXT PRIMARY KEY,
|
|
359
|
+
kind TEXT NOT NULL,
|
|
360
|
+
claim TEXT NOT NULL,
|
|
361
|
+
rationale TEXT NOT NULL,
|
|
362
|
+
affected_entities TEXT NOT NULL,
|
|
363
|
+
source_workspace_id TEXT NOT NULL,
|
|
364
|
+
source_project_id TEXT,
|
|
365
|
+
evidence TEXT NOT NULL,
|
|
366
|
+
confidence REAL NOT NULL,
|
|
367
|
+
status TEXT NOT NULL,
|
|
368
|
+
stale_reason TEXT,
|
|
369
|
+
fingerprint TEXT NOT NULL,
|
|
370
|
+
content_hash TEXT NOT NULL,
|
|
371
|
+
revision INTEGER NOT NULL,
|
|
372
|
+
proposal_id TEXT NOT NULL UNIQUE REFERENCES memory_proposals(id) ON DELETE RESTRICT,
|
|
373
|
+
conflicts TEXT NOT NULL,
|
|
374
|
+
created_at INTEGER NOT NULL,
|
|
375
|
+
approved_at INTEGER NOT NULL,
|
|
376
|
+
last_verified_at INTEGER NOT NULL,
|
|
377
|
+
expires_at INTEGER
|
|
378
|
+
);
|
|
379
|
+
CREATE INDEX idx_memories_status ON memories(status,approved_at DESC);
|
|
380
|
+
CREATE INDEX idx_memories_source ON memories(source_workspace_id,status);
|
|
381
|
+
CREATE UNIQUE INDEX idx_memories_current_fingerprint ON memories(source_workspace_id,fingerprint) WHERE status='CURRENT';
|
|
382
|
+
CREATE TABLE memory_visibility (
|
|
383
|
+
memory_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,
|
|
384
|
+
workspace_id TEXT NOT NULL,
|
|
385
|
+
project_id TEXT,
|
|
386
|
+
display_name TEXT NOT NULL,
|
|
387
|
+
created_at INTEGER NOT NULL,
|
|
388
|
+
PRIMARY KEY(memory_id,workspace_id)
|
|
389
|
+
);
|
|
390
|
+
CREATE INDEX idx_memory_visibility_workspace ON memory_visibility(workspace_id,memory_id);
|
|
391
|
+
CREATE TABLE memory_learning_proposals (
|
|
392
|
+
id TEXT PRIMARY KEY,
|
|
393
|
+
source_workspace_id TEXT NOT NULL,
|
|
394
|
+
principal TEXT NOT NULL,
|
|
395
|
+
kind TEXT NOT NULL,
|
|
396
|
+
title TEXT NOT NULL,
|
|
397
|
+
summary TEXT NOT NULL,
|
|
398
|
+
steps TEXT NOT NULL,
|
|
399
|
+
supporting_memory_ids TEXT NOT NULL,
|
|
400
|
+
digest TEXT NOT NULL,
|
|
401
|
+
status TEXT NOT NULL,
|
|
402
|
+
created_at INTEGER NOT NULL,
|
|
403
|
+
expires_at INTEGER NOT NULL,
|
|
404
|
+
reviewed_at INTEGER,
|
|
405
|
+
review_note TEXT
|
|
406
|
+
);
|
|
407
|
+
CREATE INDEX idx_memory_learning_workspace ON memory_learning_proposals(source_workspace_id,status,created_at);`,
|
|
408
|
+
`CREATE TABLE runtime_sessions (
|
|
409
|
+
id TEXT PRIMARY KEY,
|
|
410
|
+
workspace_id TEXT NOT NULL,
|
|
411
|
+
opened_epoch TEXT NOT NULL,
|
|
412
|
+
owner TEXT NOT NULL,
|
|
413
|
+
label TEXT NOT NULL,
|
|
414
|
+
status TEXT NOT NULL,
|
|
415
|
+
created_at INTEGER NOT NULL,
|
|
416
|
+
last_seen_at INTEGER NOT NULL,
|
|
417
|
+
expires_at INTEGER NOT NULL,
|
|
418
|
+
closed_at INTEGER
|
|
419
|
+
);
|
|
420
|
+
CREATE INDEX idx_runtime_sessions_owner
|
|
421
|
+
ON runtime_sessions(workspace_id,owner,status,last_seen_at DESC);
|
|
422
|
+
CREATE INDEX idx_runtime_sessions_expiry ON runtime_sessions(expires_at);
|
|
423
|
+
CREATE TABLE runtime_tasks (
|
|
424
|
+
id TEXT PRIMARY KEY,
|
|
425
|
+
session_id TEXT NOT NULL REFERENCES runtime_sessions(id) ON DELETE CASCADE,
|
|
426
|
+
workspace_id TEXT NOT NULL,
|
|
427
|
+
owner TEXT NOT NULL,
|
|
428
|
+
job_id TEXT NOT NULL UNIQUE,
|
|
429
|
+
kind TEXT NOT NULL,
|
|
430
|
+
created_at INTEGER NOT NULL
|
|
431
|
+
);
|
|
432
|
+
CREATE INDEX idx_runtime_tasks_session ON runtime_tasks(session_id,created_at DESC);
|
|
433
|
+
CREATE TABLE runtime_evidence (
|
|
434
|
+
id TEXT PRIMARY KEY,
|
|
435
|
+
session_id TEXT NOT NULL REFERENCES runtime_sessions(id) ON DELETE CASCADE,
|
|
436
|
+
workspace_id TEXT NOT NULL,
|
|
437
|
+
owner TEXT NOT NULL,
|
|
438
|
+
kind TEXT NOT NULL,
|
|
439
|
+
payload TEXT NOT NULL,
|
|
440
|
+
source_ref TEXT NOT NULL,
|
|
441
|
+
source_hash TEXT NOT NULL,
|
|
442
|
+
content_hash TEXT NOT NULL,
|
|
443
|
+
status TEXT NOT NULL,
|
|
444
|
+
stale_reason TEXT,
|
|
445
|
+
created_at INTEGER NOT NULL,
|
|
446
|
+
last_verified_at INTEGER NOT NULL,
|
|
447
|
+
expires_at INTEGER NOT NULL,
|
|
448
|
+
UNIQUE(session_id,owner,kind,source_ref,source_hash)
|
|
449
|
+
);
|
|
450
|
+
CREATE INDEX idx_runtime_evidence_session ON runtime_evidence(session_id,status,created_at DESC);
|
|
451
|
+
CREATE INDEX idx_runtime_evidence_expiry ON runtime_evidence(expires_at);`,
|
|
452
|
+
`CREATE TABLE agent_runs (
|
|
453
|
+
id TEXT PRIMARY KEY,
|
|
454
|
+
workspace_id TEXT NOT NULL,
|
|
455
|
+
opened_epoch TEXT NOT NULL,
|
|
456
|
+
owner TEXT NOT NULL,
|
|
457
|
+
goal TEXT NOT NULL,
|
|
458
|
+
criteria TEXT NOT NULL,
|
|
459
|
+
capabilities TEXT NOT NULL,
|
|
460
|
+
status TEXT NOT NULL,
|
|
461
|
+
revision INTEGER NOT NULL,
|
|
462
|
+
action_count INTEGER NOT NULL,
|
|
463
|
+
created_at INTEGER NOT NULL,
|
|
464
|
+
updated_at INTEGER NOT NULL,
|
|
465
|
+
expires_at INTEGER NOT NULL,
|
|
466
|
+
completed_at INTEGER
|
|
467
|
+
);
|
|
468
|
+
CREATE INDEX idx_agent_runs_owner ON agent_runs(workspace_id,owner,status,updated_at DESC);
|
|
469
|
+
CREATE INDEX idx_agent_runs_expiry ON agent_runs(expires_at);
|
|
470
|
+
CREATE TABLE agent_plans (
|
|
471
|
+
run_id TEXT NOT NULL REFERENCES agent_runs(id) ON DELETE CASCADE,
|
|
472
|
+
revision INTEGER NOT NULL,
|
|
473
|
+
workspace_id TEXT NOT NULL,
|
|
474
|
+
owner TEXT NOT NULL,
|
|
475
|
+
steps TEXT NOT NULL,
|
|
476
|
+
content_hash TEXT NOT NULL,
|
|
477
|
+
created_at INTEGER NOT NULL,
|
|
478
|
+
PRIMARY KEY(run_id,revision)
|
|
479
|
+
);
|
|
480
|
+
CREATE TABLE agent_hypotheses (
|
|
481
|
+
id TEXT PRIMARY KEY,
|
|
482
|
+
run_id TEXT NOT NULL REFERENCES agent_runs(id) ON DELETE CASCADE,
|
|
483
|
+
workspace_id TEXT NOT NULL,
|
|
484
|
+
owner TEXT NOT NULL,
|
|
485
|
+
title TEXT NOT NULL,
|
|
486
|
+
probable_cause TEXT NOT NULL,
|
|
487
|
+
expected_evidence TEXT NOT NULL,
|
|
488
|
+
status TEXT NOT NULL,
|
|
489
|
+
created_at INTEGER NOT NULL,
|
|
490
|
+
updated_at INTEGER NOT NULL
|
|
491
|
+
);
|
|
492
|
+
CREATE INDEX idx_agent_hypotheses_run ON agent_hypotheses(run_id,status,created_at);
|
|
493
|
+
CREATE TABLE agent_intents (
|
|
494
|
+
id TEXT PRIMARY KEY,
|
|
495
|
+
run_id TEXT NOT NULL REFERENCES agent_runs(id) ON DELETE CASCADE,
|
|
496
|
+
hypothesis_id TEXT NOT NULL REFERENCES agent_hypotheses(id) ON DELETE CASCADE,
|
|
497
|
+
workspace_id TEXT NOT NULL,
|
|
498
|
+
owner TEXT NOT NULL,
|
|
499
|
+
kind TEXT NOT NULL,
|
|
500
|
+
resource_key TEXT NOT NULL,
|
|
501
|
+
status TEXT NOT NULL,
|
|
502
|
+
created_at INTEGER NOT NULL,
|
|
503
|
+
expires_at INTEGER NOT NULL,
|
|
504
|
+
released_at INTEGER
|
|
505
|
+
);
|
|
506
|
+
CREATE INDEX idx_agent_intents_active ON agent_intents(workspace_id,status,kind,resource_key,expires_at);
|
|
507
|
+
CREATE INDEX idx_agent_intents_hypothesis ON agent_intents(hypothesis_id,status,created_at);
|
|
508
|
+
CREATE TABLE agent_actions (
|
|
509
|
+
id TEXT PRIMARY KEY,
|
|
510
|
+
run_id TEXT NOT NULL REFERENCES agent_runs(id) ON DELETE CASCADE,
|
|
511
|
+
hypothesis_id TEXT NOT NULL REFERENCES agent_hypotheses(id) ON DELETE CASCADE,
|
|
512
|
+
workspace_id TEXT NOT NULL,
|
|
513
|
+
owner TEXT NOT NULL,
|
|
514
|
+
operation TEXT NOT NULL,
|
|
515
|
+
input_hash TEXT NOT NULL,
|
|
516
|
+
status TEXT NOT NULL,
|
|
517
|
+
result_code TEXT,
|
|
518
|
+
result_hash TEXT,
|
|
519
|
+
created_at INTEGER NOT NULL,
|
|
520
|
+
completed_at INTEGER
|
|
521
|
+
);
|
|
522
|
+
CREATE INDEX idx_agent_actions_run ON agent_actions(run_id,created_at DESC);
|
|
523
|
+
CREATE TABLE agent_snapshots (
|
|
524
|
+
id TEXT PRIMARY KEY,
|
|
525
|
+
run_id TEXT NOT NULL REFERENCES agent_runs(id) ON DELETE CASCADE,
|
|
526
|
+
hypothesis_id TEXT NOT NULL REFERENCES agent_hypotheses(id) ON DELETE CASCADE,
|
|
527
|
+
workspace_id TEXT NOT NULL,
|
|
528
|
+
owner TEXT NOT NULL,
|
|
529
|
+
manifest_hash TEXT NOT NULL,
|
|
530
|
+
manifest TEXT NOT NULL,
|
|
531
|
+
created_at INTEGER NOT NULL
|
|
532
|
+
);
|
|
533
|
+
CREATE INDEX idx_agent_snapshots_run ON agent_snapshots(run_id,created_at DESC);
|
|
534
|
+
CREATE TABLE agent_judgements (
|
|
535
|
+
id TEXT PRIMARY KEY,
|
|
536
|
+
run_id TEXT NOT NULL REFERENCES agent_runs(id) ON DELETE CASCADE,
|
|
537
|
+
workspace_id TEXT NOT NULL,
|
|
538
|
+
owner TEXT NOT NULL,
|
|
539
|
+
payload TEXT NOT NULL,
|
|
540
|
+
content_hash TEXT NOT NULL,
|
|
541
|
+
created_at INTEGER NOT NULL
|
|
542
|
+
);
|
|
543
|
+
CREATE INDEX idx_agent_judgements_run ON agent_judgements(run_id,created_at DESC);
|
|
544
|
+
CREATE TABLE agent_skill_proposals (
|
|
545
|
+
id TEXT PRIMARY KEY,
|
|
546
|
+
workspace_id TEXT NOT NULL,
|
|
547
|
+
principal TEXT NOT NULL,
|
|
548
|
+
skill_key TEXT NOT NULL,
|
|
549
|
+
title TEXT NOT NULL,
|
|
550
|
+
summary TEXT NOT NULL,
|
|
551
|
+
steps TEXT NOT NULL,
|
|
552
|
+
capabilities TEXT NOT NULL,
|
|
553
|
+
base_skill_id TEXT,
|
|
554
|
+
base_version INTEGER,
|
|
555
|
+
digest TEXT NOT NULL,
|
|
556
|
+
status TEXT NOT NULL,
|
|
557
|
+
created_at INTEGER NOT NULL,
|
|
558
|
+
expires_at INTEGER NOT NULL,
|
|
559
|
+
reviewed_at INTEGER,
|
|
560
|
+
review_note TEXT
|
|
561
|
+
);
|
|
562
|
+
CREATE INDEX idx_agent_skill_proposals_workspace ON agent_skill_proposals(workspace_id,status,created_at DESC);
|
|
563
|
+
CREATE TABLE agent_skills (
|
|
564
|
+
id TEXT NOT NULL,
|
|
565
|
+
workspace_id TEXT NOT NULL,
|
|
566
|
+
skill_key TEXT NOT NULL,
|
|
567
|
+
title TEXT NOT NULL,
|
|
568
|
+
summary TEXT NOT NULL,
|
|
569
|
+
steps TEXT NOT NULL,
|
|
570
|
+
capabilities TEXT NOT NULL,
|
|
571
|
+
version INTEGER NOT NULL,
|
|
572
|
+
proposal_id TEXT NOT NULL UNIQUE REFERENCES agent_skill_proposals(id) ON DELETE RESTRICT,
|
|
573
|
+
digest TEXT NOT NULL,
|
|
574
|
+
status TEXT NOT NULL,
|
|
575
|
+
created_at INTEGER NOT NULL,
|
|
576
|
+
approved_at INTEGER NOT NULL,
|
|
577
|
+
PRIMARY KEY(id,version),
|
|
578
|
+
UNIQUE(workspace_id,skill_key,version)
|
|
579
|
+
);
|
|
580
|
+
CREATE UNIQUE INDEX idx_agent_skills_current ON agent_skills(workspace_id,skill_key) WHERE status='CURRENT';`,
|
|
581
|
+
(db) => {
|
|
582
|
+
// Project registry v2 adds a stable directory-generation marker. Device
|
|
583
|
+
// and inode alone are insufficient because Linux can reuse an inode
|
|
584
|
+
// immediately after a directory is removed. A v1 row has no prior birth
|
|
585
|
+
// time to compare, so it cannot be upgraded safely by inspecting the live
|
|
586
|
+
// path. Leave every v1 row invalid for explicit owner review/re-add.
|
|
587
|
+
db.exec('ALTER TABLE project_registry ADD COLUMN root_birthtime_ns TEXT');
|
|
588
|
+
},
|
|
589
|
+
`CREATE TABLE ai_settings (kind TEXT NOT NULL, id TEXT NOT NULL, payload TEXT NOT NULL, updated_at INTEGER NOT NULL, PRIMARY KEY(kind,id));
|
|
590
|
+
CREATE TABLE ai_runs (id TEXT PRIMARY KEY, workspace_id TEXT NOT NULL, owner TEXT NOT NULL, idempotency_key TEXT NOT NULL,
|
|
591
|
+
digest TEXT NOT NULL, status TEXT NOT NULL, payload TEXT NOT NULL, created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL,
|
|
592
|
+
UNIQUE(workspace_id,owner,idempotency_key));
|
|
593
|
+
CREATE TABLE ai_events (seq INTEGER PRIMARY KEY AUTOINCREMENT, run_id TEXT NOT NULL REFERENCES ai_runs(id) ON DELETE CASCADE,
|
|
594
|
+
created_at INTEGER NOT NULL, kind TEXT NOT NULL, payload TEXT NOT NULL);
|
|
595
|
+
CREATE INDEX idx_ai_runs_owner ON ai_runs(workspace_id,owner,created_at);`,
|
|
596
|
+
];
|
|
597
|
+
/**
|
|
598
|
+
* Read-only open with NO migration — for CLI helpers (status/approve) that
|
|
599
|
+
* only need to read the install secret to derive the workspace id. A readonly
|
|
600
|
+
* connection never takes a write lock, so it cannot race a running server's
|
|
601
|
+
* startup migration. Returns undefined if the store does not exist yet.
|
|
602
|
+
*/
|
|
603
|
+
export function openDatabaseReadonly(dbFile) {
|
|
604
|
+
try {
|
|
605
|
+
const db = new Database(dbFile, { readonly: true, fileMustExist: true });
|
|
606
|
+
db.pragma('busy_timeout = 5000');
|
|
607
|
+
return db;
|
|
608
|
+
}
|
|
609
|
+
catch {
|
|
610
|
+
return undefined;
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
export function openDatabase(dbFile) {
|
|
614
|
+
let db;
|
|
615
|
+
try {
|
|
616
|
+
db = new Database(dbFile, { timeout: 10000 });
|
|
617
|
+
}
|
|
618
|
+
catch (err) {
|
|
619
|
+
throw new DodoError('INTERNAL_ERROR', `cannot open state database: ${err.message}`, {
|
|
620
|
+
recovery: `check permissions on ${dbFile}`,
|
|
621
|
+
});
|
|
622
|
+
}
|
|
623
|
+
try {
|
|
624
|
+
// Set the busy handler before any pragma that may need a database lock.
|
|
625
|
+
// Concurrent owner CLI processes can otherwise fail at journal_mode=WAL
|
|
626
|
+
// before migration's own retry loop has a chance to run.
|
|
627
|
+
db.pragma('busy_timeout = 10000');
|
|
628
|
+
withBusyRetry(() => db.pragma('journal_mode = WAL'));
|
|
629
|
+
db.pragma('synchronous = FULL');
|
|
630
|
+
db.pragma('foreign_keys = ON');
|
|
631
|
+
migrateWithRetry(db);
|
|
632
|
+
}
|
|
633
|
+
catch (err) {
|
|
634
|
+
db.close();
|
|
635
|
+
if (err instanceof DodoError)
|
|
636
|
+
throw err;
|
|
637
|
+
throw new DodoError('INTERNAL_ERROR', `state database migration failed: ${err.message}`, {
|
|
638
|
+
recovery: 'the database may be corrupt; restore from backup or move it aside (auth state will be lost)',
|
|
639
|
+
});
|
|
640
|
+
}
|
|
641
|
+
if (process.platform !== 'win32') {
|
|
642
|
+
try {
|
|
643
|
+
fs.chmodSync(dbFile, 0o600);
|
|
644
|
+
}
|
|
645
|
+
catch {
|
|
646
|
+
/* best effort */
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
return db;
|
|
650
|
+
}
|
|
651
|
+
/**
|
|
652
|
+
* Two processes may open the store at once (e.g. `dodo status` while
|
|
653
|
+
* `dodo start` boots). WAL allows concurrent readers and one writer; the
|
|
654
|
+
* loser of a migration-write race retries within busy_timeout rather than
|
|
655
|
+
* failing the command. Migrations are idempotent (guarded by
|
|
656
|
+
* schema_migrations), so a retry after another process finished is a no-op.
|
|
657
|
+
*/
|
|
658
|
+
function migrateWithRetry(db) {
|
|
659
|
+
withBusyRetry(() => migrate(db));
|
|
660
|
+
}
|
|
661
|
+
function withBusyRetry(operation, timeoutMs = 15000) {
|
|
662
|
+
const deadline = Date.now() + timeoutMs;
|
|
663
|
+
const waitCell = new Int32Array(new SharedArrayBuffer(4));
|
|
664
|
+
let attempt = 0;
|
|
665
|
+
for (;;) {
|
|
666
|
+
try {
|
|
667
|
+
return operation();
|
|
668
|
+
}
|
|
669
|
+
catch (err) {
|
|
670
|
+
const code = err.code ?? '';
|
|
671
|
+
const busy = code === 'SQLITE_BUSY' || code === 'SQLITE_BUSY_SNAPSHOT' || /database is locked/.test(err.message);
|
|
672
|
+
if (!busy || Date.now() >= deadline)
|
|
673
|
+
throw err;
|
|
674
|
+
// Processes launched together otherwise wake in lockstep and repeatedly
|
|
675
|
+
// collide. A PID-derived offset keeps the wait deterministic per process
|
|
676
|
+
// while the capped backoff leaves enough time for the migration owner.
|
|
677
|
+
const delayMs = Math.min(50 * (2 ** attempt), 1000) + (process.pid % 47);
|
|
678
|
+
Atomics.wait(waitCell, 0, 0, Math.min(delayMs, Math.max(1, deadline - Date.now())));
|
|
679
|
+
attempt += 1;
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
function migrate(db) {
|
|
684
|
+
// Run the whole migration under BEGIN IMMEDIATE so a second process that
|
|
685
|
+
// opens the store concurrently takes the write lock before even creating
|
|
686
|
+
// schema_migrations. The loser waits, then re-reads applied versions after
|
|
687
|
+
// the winner commits instead of racing schema initialization.
|
|
688
|
+
const apply = db.transaction(() => {
|
|
689
|
+
db.exec('CREATE TABLE IF NOT EXISTS schema_migrations (version INTEGER PRIMARY KEY, applied_at INTEGER NOT NULL)');
|
|
690
|
+
const appliedRows = db.prepare('SELECT version FROM schema_migrations ORDER BY version').all();
|
|
691
|
+
const applied = new Set(appliedRows.map((r) => r.version));
|
|
692
|
+
if (appliedRows.some((r) => r.version > MIGRATIONS.length)) {
|
|
693
|
+
throw new DodoError('INTERNAL_ERROR', 'state database is from a newer DODO version; refusing to run', {
|
|
694
|
+
recovery: 'upgrade DODO or restore the matching database',
|
|
695
|
+
});
|
|
696
|
+
}
|
|
697
|
+
for (let i = 0; i < MIGRATIONS.length; i += 1) {
|
|
698
|
+
const version = i + 1;
|
|
699
|
+
if (applied.has(version))
|
|
700
|
+
continue;
|
|
701
|
+
const migration = MIGRATIONS[i];
|
|
702
|
+
if (typeof migration === 'string')
|
|
703
|
+
db.exec(migration);
|
|
704
|
+
else
|
|
705
|
+
migration(db);
|
|
706
|
+
db.prepare('INSERT INTO schema_migrations (version, applied_at) VALUES (?, ?)').run(version, Date.now());
|
|
707
|
+
}
|
|
708
|
+
});
|
|
709
|
+
apply.immediate();
|
|
710
|
+
}
|
|
711
|
+
//# sourceMappingURL=db.js.map
|