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.
Files changed (447) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +425 -0
  3. package/dist/auth/adapter.js +43 -0
  4. package/dist/auth/adapter.js.map +1 -0
  5. package/dist/auth/clientDeletion.js +45 -0
  6. package/dist/auth/clientDeletion.js.map +1 -0
  7. package/dist/auth/clients.js +55 -0
  8. package/dist/auth/clients.js.map +1 -0
  9. package/dist/auth/constants.js +10 -0
  10. package/dist/auth/constants.js.map +1 -0
  11. package/dist/auth/interactions.js +184 -0
  12. package/dist/auth/interactions.js.map +1 -0
  13. package/dist/auth/keys.js +56 -0
  14. package/dist/auth/keys.js.map +1 -0
  15. package/dist/auth/provider.js +131 -0
  16. package/dist/auth/provider.js.map +1 -0
  17. package/dist/auth/verifier.js +74 -0
  18. package/dist/auth/verifier.js.map +1 -0
  19. package/dist/cli/kill.js +124 -0
  20. package/dist/cli/kill.js.map +1 -0
  21. package/dist/cli/main.js +1393 -0
  22. package/dist/cli/main.js.map +1 -0
  23. package/dist/cli/menu.js +127 -0
  24. package/dist/cli/menu.js.map +1 -0
  25. package/dist/cli/terminal.js +30 -0
  26. package/dist/cli/terminal.js.map +1 -0
  27. package/dist/config/globalConfig.js +144 -0
  28. package/dist/config/globalConfig.js.map +1 -0
  29. package/dist/config/limits.js +42 -0
  30. package/dist/config/limits.js.map +1 -0
  31. package/dist/config/paths.js +94 -0
  32. package/dist/config/paths.js.map +1 -0
  33. package/dist/config/projectConfig.js +63 -0
  34. package/dist/config/projectConfig.js.map +1 -0
  35. package/dist/config/stateImport.js +306 -0
  36. package/dist/config/stateImport.js.map +1 -0
  37. package/dist/config/tunnelConfig.js +23 -0
  38. package/dist/config/tunnelConfig.js.map +1 -0
  39. package/dist/errors.js +82 -0
  40. package/dist/errors.js.map +1 -0
  41. package/dist/evaluation/contracts.js +86 -0
  42. package/dist/evaluation/contracts.js.map +1 -0
  43. package/dist/evaluation/dodoBench.js +69 -0
  44. package/dist/evaluation/dodoBench.js.map +1 -0
  45. package/dist/index.js +26 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/ipc/authentication.js +117 -0
  48. package/dist/ipc/authentication.js.map +1 -0
  49. package/dist/ipc/client.js +86 -0
  50. package/dist/ipc/client.js.map +1 -0
  51. package/dist/ipc/installationClient.js +83 -0
  52. package/dist/ipc/installationClient.js.map +1 -0
  53. package/dist/ipc/ownerControl.js +46 -0
  54. package/dist/ipc/ownerControl.js.map +1 -0
  55. package/dist/ipc/protocol.js +2 -0
  56. package/dist/ipc/protocol.js.map +1 -0
  57. package/dist/ipc/server.js +108 -0
  58. package/dist/ipc/server.js.map +1 -0
  59. package/dist/platform/execResolve.js +64 -0
  60. package/dist/platform/execResolve.js.map +1 -0
  61. package/dist/platform/fileIdentity.js +26 -0
  62. package/dist/platform/fileIdentity.js.map +1 -0
  63. package/dist/platform/fsRetry.js +22 -0
  64. package/dist/platform/fsRetry.js.map +1 -0
  65. package/dist/platform/pathPolicy.js +29 -0
  66. package/dist/platform/pathPolicy.js.map +1 -0
  67. package/dist/platform/privateFs.js +116 -0
  68. package/dist/platform/privateFs.js.map +1 -0
  69. package/dist/platform/processTree.js +31 -0
  70. package/dist/platform/processTree.js.map +1 -0
  71. package/dist/platform/shell.js +74 -0
  72. package/dist/platform/shell.js.map +1 -0
  73. package/dist/platform/speech.js +94 -0
  74. package/dist/platform/speech.js.map +1 -0
  75. package/dist/platform/system.js +28 -0
  76. package/dist/platform/system.js.map +1 -0
  77. package/dist/platform/windowsSandbox.js +129 -0
  78. package/dist/platform/windowsSandbox.js.map +1 -0
  79. package/dist/projects/federation.js +312 -0
  80. package/dist/projects/federation.js.map +1 -0
  81. package/dist/projects/registry.js +291 -0
  82. package/dist/projects/registry.js.map +1 -0
  83. package/dist/security/accessMode.js +19 -0
  84. package/dist/security/accessMode.js.map +1 -0
  85. package/dist/security/approvals.js +56 -0
  86. package/dist/security/approvals.js.map +1 -0
  87. package/dist/security/env.js +57 -0
  88. package/dist/security/env.js.map +1 -0
  89. package/dist/security/mutationQueue.js +78 -0
  90. package/dist/security/mutationQueue.js.map +1 -0
  91. package/dist/security/policy.js +22 -0
  92. package/dist/security/policy.js.map +1 -0
  93. package/dist/security/projectAuthority.js +22 -0
  94. package/dist/security/projectAuthority.js.map +1 -0
  95. package/dist/security/redact.js +30 -0
  96. package/dist/security/redact.js.map +1 -0
  97. package/dist/server/aiAdmin.js +201 -0
  98. package/dist/server/aiAdmin.js.map +1 -0
  99. package/dist/server/appServer.js +461 -0
  100. package/dist/server/appServer.js.map +1 -0
  101. package/dist/server/bootstrap.js +185 -0
  102. package/dist/server/bootstrap.js.map +1 -0
  103. package/dist/server/configUi/app.css +347 -0
  104. package/dist/server/configUi/app.js +958 -0
  105. package/dist/server/configUi/index.html +379 -0
  106. package/dist/server/configUi/ui/alerts.js +92 -0
  107. package/dist/server/configUi/ui/dom.js +19 -0
  108. package/dist/server/configUi/ui/tooltips.js +115 -0
  109. package/dist/server/configUi/vendor/VERSION.txt +1 -0
  110. package/dist/server/configUi/vendor/sweetalert2.min.css +1 -0
  111. package/dist/server/configUi/vendor/sweetalert2.min.js +5 -0
  112. package/dist/server/configUi/workbench.css +62 -0
  113. package/dist/server/configUi/workbench.js +394 -0
  114. package/dist/server/installationRuntime.js +155 -0
  115. package/dist/server/installationRuntime.js.map +1 -0
  116. package/dist/server/instructions.js +17 -0
  117. package/dist/server/instructions.js.map +1 -0
  118. package/dist/server/ipcDispatch.js +225 -0
  119. package/dist/server/ipcDispatch.js.map +1 -0
  120. package/dist/server/localConfig.js +561 -0
  121. package/dist/server/localConfig.js.map +1 -0
  122. package/dist/server/optionalServices.js +30 -0
  123. package/dist/server/optionalServices.js.map +1 -0
  124. package/dist/server/projectLease.js +46 -0
  125. package/dist/server/projectLease.js.map +1 -0
  126. package/dist/server/stdioServer.js +75 -0
  127. package/dist/server/stdioServer.js.map +1 -0
  128. package/dist/server/version.js +13 -0
  129. package/dist/server/version.js.map +1 -0
  130. package/dist/server/workspaceHost.js +194 -0
  131. package/dist/server/workspaceHost.js.map +1 -0
  132. package/dist/services/agent/agentService.js +598 -0
  133. package/dist/services/agent/agentService.js.map +1 -0
  134. package/dist/services/agent/contracts.js +102 -0
  135. package/dist/services/agent/contracts.js.map +1 -0
  136. package/dist/services/ai/adapters.js +287 -0
  137. package/dist/services/ai/adapters.js.map +1 -0
  138. package/dist/services/ai/contracts.js +39 -0
  139. package/dist/services/ai/contracts.js.map +1 -0
  140. package/dist/services/ai/credentials.js +77 -0
  141. package/dist/services/ai/credentials.js.map +1 -0
  142. package/dist/services/ai/network.js +113 -0
  143. package/dist/services/ai/network.js.map +1 -0
  144. package/dist/services/ai/settings.js +178 -0
  145. package/dist/services/ai/settings.js.map +1 -0
  146. package/dist/services/ai/subagents.js +468 -0
  147. package/dist/services/ai/subagents.js.map +1 -0
  148. package/dist/services/assistance/analysis.js +352 -0
  149. package/dist/services/assistance/analysis.js.map +1 -0
  150. package/dist/services/assistance/contracts.js +54 -0
  151. package/dist/services/assistance/contracts.js.map +1 -0
  152. package/dist/services/assistance/verification.js +274 -0
  153. package/dist/services/assistance/verification.js.map +1 -0
  154. package/dist/services/brain/brainParser.js +97 -0
  155. package/dist/services/brain/brainParser.js.map +1 -0
  156. package/dist/services/brain/brainService.js +733 -0
  157. package/dist/services/brain/brainService.js.map +1 -0
  158. package/dist/services/brain/brainWorker.js +212 -0
  159. package/dist/services/brain/brainWorker.js.map +1 -0
  160. package/dist/services/brain/contracts.js +154 -0
  161. package/dist/services/brain/contracts.js.map +1 -0
  162. package/dist/services/brain/protocol.js +2 -0
  163. package/dist/services/brain/protocol.js.map +1 -0
  164. package/dist/services/changes/applier.js +544 -0
  165. package/dist/services/changes/applier.js.map +1 -0
  166. package/dist/services/changes/contentBudget.js +11 -0
  167. package/dist/services/changes/contentBudget.js.map +1 -0
  168. package/dist/services/changes/planner.js +284 -0
  169. package/dist/services/changes/planner.js.map +1 -0
  170. package/dist/services/changes/types.js +3 -0
  171. package/dist/services/changes/types.js.map +1 -0
  172. package/dist/services/context/contextEngine.js +746 -0
  173. package/dist/services/context/contextEngine.js.map +1 -0
  174. package/dist/services/context/contracts.js +88 -0
  175. package/dist/services/context/contracts.js.map +1 -0
  176. package/dist/services/desktop/desktopPolicy.js +76 -0
  177. package/dist/services/desktop/desktopPolicy.js.map +1 -0
  178. package/dist/services/desktop/desktopService.js +130 -0
  179. package/dist/services/desktop/desktopService.js.map +1 -0
  180. package/dist/services/desktop/nativeBackend.js +174 -0
  181. package/dist/services/desktop/nativeBackend.js.map +1 -0
  182. package/dist/services/desktop/protocol.js +32 -0
  183. package/dist/services/desktop/protocol.js.map +1 -0
  184. package/dist/services/files/readService.js +136 -0
  185. package/dist/services/files/readService.js.map +1 -0
  186. package/dist/services/git/gitService.js +369 -0
  187. package/dist/services/git/gitService.js.map +1 -0
  188. package/dist/services/intelligence/intelService.js +136 -0
  189. package/dist/services/intelligence/intelService.js.map +1 -0
  190. package/dist/services/intelligence/protocol.js +2 -0
  191. package/dist/services/intelligence/protocol.js.map +1 -0
  192. package/dist/services/intelligence/tsWorker.js +419 -0
  193. package/dist/services/intelligence/tsWorker.js.map +1 -0
  194. package/dist/services/jobs/commandInput.js +34 -0
  195. package/dist/services/jobs/commandInput.js.map +1 -0
  196. package/dist/services/jobs/jobManager.js +398 -0
  197. package/dist/services/jobs/jobManager.js.map +1 -0
  198. package/dist/services/jobs/sandbox.js +156 -0
  199. package/dist/services/jobs/sandbox.js.map +1 -0
  200. package/dist/services/jobs/sandboxWiring.js +37 -0
  201. package/dist/services/jobs/sandboxWiring.js.map +1 -0
  202. package/dist/services/jobs/spool.js +112 -0
  203. package/dist/services/jobs/spool.js.map +1 -0
  204. package/dist/services/jobs/windowsSandboxChild.js +24 -0
  205. package/dist/services/jobs/windowsSandboxChild.js.map +1 -0
  206. package/dist/services/jobs/windowsSandboxWorker.js +155 -0
  207. package/dist/services/jobs/windowsSandboxWorker.js.map +1 -0
  208. package/dist/services/lsp/documentUri.js +16 -0
  209. package/dist/services/lsp/documentUri.js.map +1 -0
  210. package/dist/services/lsp/jsonrpc.js +382 -0
  211. package/dist/services/lsp/jsonrpc.js.map +1 -0
  212. package/dist/services/lsp/lspService.js +1051 -0
  213. package/dist/services/lsp/lspService.js.map +1 -0
  214. package/dist/services/memory/contracts.js +94 -0
  215. package/dist/services/memory/contracts.js.map +1 -0
  216. package/dist/services/memory/memoryService.js +683 -0
  217. package/dist/services/memory/memoryService.js.map +1 -0
  218. package/dist/services/multimodal/browserService.js +407 -0
  219. package/dist/services/multimodal/browserService.js.map +1 -0
  220. package/dist/services/multimodal/byteRange.js +31 -0
  221. package/dist/services/multimodal/byteRange.js.map +1 -0
  222. package/dist/services/multimodal/contracts.js +59 -0
  223. package/dist/services/multimodal/contracts.js.map +1 -0
  224. package/dist/services/multimodal/gameService.js +95 -0
  225. package/dist/services/multimodal/gameService.js.map +1 -0
  226. package/dist/services/multimodal/images.js +107 -0
  227. package/dist/services/multimodal/images.js.map +1 -0
  228. package/dist/services/multimodal/mediaService.js +279 -0
  229. package/dist/services/multimodal/mediaService.js.map +1 -0
  230. package/dist/services/multimodal/mediaWorker.js +143 -0
  231. package/dist/services/multimodal/mediaWorker.js.map +1 -0
  232. package/dist/services/multimodal/multimodalService.js +51 -0
  233. package/dist/services/multimodal/multimodalService.js.map +1 -0
  234. package/dist/services/multimodal/network.js +69 -0
  235. package/dist/services/multimodal/network.js.map +1 -0
  236. package/dist/services/multimodal/operations.js +40 -0
  237. package/dist/services/multimodal/operations.js.map +1 -0
  238. package/dist/services/multimodal/storage.js +160 -0
  239. package/dist/services/multimodal/storage.js.map +1 -0
  240. package/dist/services/multimodal/workflowService.js +179 -0
  241. package/dist/services/multimodal/workflowService.js.map +1 -0
  242. package/dist/services/overview.js +284 -0
  243. package/dist/services/overview.js.map +1 -0
  244. package/dist/services/resources/casStore.js +304 -0
  245. package/dist/services/resources/casStore.js.map +1 -0
  246. package/dist/services/resources/contracts.js +75 -0
  247. package/dist/services/resources/contracts.js.map +1 -0
  248. package/dist/services/resources/mime.js +77 -0
  249. package/dist/services/resources/mime.js.map +1 -0
  250. package/dist/services/resources/providerRegistry.js +22 -0
  251. package/dist/services/resources/providerRegistry.js.map +1 -0
  252. package/dist/services/resources/providers.js +120 -0
  253. package/dist/services/resources/providers.js.map +1 -0
  254. package/dist/services/resources/resourceService.js +282 -0
  255. package/dist/services/resources/resourceService.js.map +1 -0
  256. package/dist/services/runtime/contracts.js +65 -0
  257. package/dist/services/runtime/contracts.js.map +1 -0
  258. package/dist/services/runtime/runtimeService.js +364 -0
  259. package/dist/services/runtime/runtimeService.js.map +1 -0
  260. package/dist/services/schedules/scheduleService.js +198 -0
  261. package/dist/services/schedules/scheduleService.js.map +1 -0
  262. package/dist/services/search/searchService.js +434 -0
  263. package/dist/services/search/searchService.js.map +1 -0
  264. package/dist/services/search/searchWorker.js +58 -0
  265. package/dist/services/search/searchWorker.js.map +1 -0
  266. package/dist/setup/componentProbes.js +259 -0
  267. package/dist/setup/componentProbes.js.map +1 -0
  268. package/dist/setup/download.js +139 -0
  269. package/dist/setup/download.js.map +1 -0
  270. package/dist/setup/managedTools.js +118 -0
  271. package/dist/setup/managedTools.js.map +1 -0
  272. package/dist/setup/sandboxProbe.js +172 -0
  273. package/dist/setup/sandboxProbe.js.map +1 -0
  274. package/dist/setup/setup.js +522 -0
  275. package/dist/setup/setup.js.map +1 -0
  276. package/dist/setup/windowsChromiumAcl.js +56 -0
  277. package/dist/setup/windowsChromiumAcl.js.map +1 -0
  278. package/dist/setup/windowsSandboxInstall.js +94 -0
  279. package/dist/setup/windowsSandboxInstall.js.map +1 -0
  280. package/dist/setup/windowsSpeechInstall.js +86 -0
  281. package/dist/setup/windowsSpeechInstall.js.map +1 -0
  282. package/dist/store/db.js +711 -0
  283. package/dist/store/db.js.map +1 -0
  284. package/dist/store/scopeEncoding.js +15 -0
  285. package/dist/store/scopeEncoding.js.map +1 -0
  286. package/dist/store/store.js +467 -0
  287. package/dist/store/store.js.map +1 -0
  288. package/dist/tools/agentRuntimeTools.js +216 -0
  289. package/dist/tools/agentRuntimeTools.js.map +1 -0
  290. package/dist/tools/agentTools.js +317 -0
  291. package/dist/tools/agentTools.js.map +1 -0
  292. package/dist/tools/assistanceTools.js +126 -0
  293. package/dist/tools/assistanceTools.js.map +1 -0
  294. package/dist/tools/brainTools.js +130 -0
  295. package/dist/tools/brainTools.js.map +1 -0
  296. package/dist/tools/catalog.js +30 -0
  297. package/dist/tools/catalog.js.map +1 -0
  298. package/dist/tools/changeTools.js +188 -0
  299. package/dist/tools/changeTools.js.map +1 -0
  300. package/dist/tools/context.js +243 -0
  301. package/dist/tools/context.js.map +1 -0
  302. package/dist/tools/contextTools.js +57 -0
  303. package/dist/tools/contextTools.js.map +1 -0
  304. package/dist/tools/coreCatalog.js +82 -0
  305. package/dist/tools/coreCatalog.js.map +1 -0
  306. package/dist/tools/desktopTools.js +41 -0
  307. package/dist/tools/desktopTools.js.map +1 -0
  308. package/dist/tools/directTools.js +273 -0
  309. package/dist/tools/directTools.js.map +1 -0
  310. package/dist/tools/envelope.js +71 -0
  311. package/dist/tools/envelope.js.map +1 -0
  312. package/dist/tools/extraTools.js +298 -0
  313. package/dist/tools/extraTools.js.map +1 -0
  314. package/dist/tools/gitTools.js +93 -0
  315. package/dist/tools/gitTools.js.map +1 -0
  316. package/dist/tools/jobTools.js +454 -0
  317. package/dist/tools/jobTools.js.map +1 -0
  318. package/dist/tools/memoryTools.js +102 -0
  319. package/dist/tools/memoryTools.js.map +1 -0
  320. package/dist/tools/metaTools.js +153 -0
  321. package/dist/tools/metaTools.js.map +1 -0
  322. package/dist/tools/multimodalTools.js +262 -0
  323. package/dist/tools/multimodalTools.js.map +1 -0
  324. package/dist/tools/projectTools.js +261 -0
  325. package/dist/tools/projectTools.js.map +1 -0
  326. package/dist/tools/resourceTools.js +81 -0
  327. package/dist/tools/resourceTools.js.map +1 -0
  328. package/dist/tools/runtimeTools.js +137 -0
  329. package/dist/tools/runtimeTools.js.map +1 -0
  330. package/dist/tools/scheduleTools.js +10 -0
  331. package/dist/tools/scheduleTools.js.map +1 -0
  332. package/dist/tools/semanticTools.js +141 -0
  333. package/dist/tools/semanticTools.js.map +1 -0
  334. package/dist/tools/subagentTools.js +32 -0
  335. package/dist/tools/subagentTools.js.map +1 -0
  336. package/dist/tools/surface.js +644 -0
  337. package/dist/tools/surface.js.map +1 -0
  338. package/dist/tunnel/control.js +113 -0
  339. package/dist/tunnel/control.js.map +1 -0
  340. package/dist/tunnel/credentials.js +392 -0
  341. package/dist/tunnel/credentials.js.map +1 -0
  342. package/dist/tunnel/log.js +84 -0
  343. package/dist/tunnel/log.js.map +1 -0
  344. package/dist/tunnel/runtime.js +55 -0
  345. package/dist/tunnel/runtime.js.map +1 -0
  346. package/dist/tunnel/supervisor.js +280 -0
  347. package/dist/tunnel/supervisor.js.map +1 -0
  348. package/dist/util/bytes.js +53 -0
  349. package/dist/util/bytes.js.map +1 -0
  350. package/dist/util/hash.js +53 -0
  351. package/dist/util/hash.js.map +1 -0
  352. package/dist/workspace/fs.js +305 -0
  353. package/dist/workspace/fs.js.map +1 -0
  354. package/dist/workspace/identity.js +17 -0
  355. package/dist/workspace/identity.js.map +1 -0
  356. package/dist/workspace/ignores.js +173 -0
  357. package/dist/workspace/ignores.js.map +1 -0
  358. package/dist/workspace/root.js +59 -0
  359. package/dist/workspace/root.js.map +1 -0
  360. package/docs/AGENT_RUNTIME.md +154 -0
  361. package/docs/AI_PROVIDERS.md +110 -0
  362. package/docs/ARCHITECTURE.md +331 -0
  363. package/docs/ASSISTANCE.md +31 -0
  364. package/docs/AUTH.md +59 -0
  365. package/docs/BRAIN.md +92 -0
  366. package/docs/COMPATIBILITY.md +92 -0
  367. package/docs/CONFIRMATION.md +13 -0
  368. package/docs/CONTEXT.md +87 -0
  369. package/docs/DESKTOP.md +35 -0
  370. package/docs/EVALUATION.md +86 -0
  371. package/docs/LARGE_INPUTS.md +21 -0
  372. package/docs/LSP.md +21 -0
  373. package/docs/MANUAL_ACCEPTANCE.md +283 -0
  374. package/docs/MEMORY.md +128 -0
  375. package/docs/MULTIMODAL.md +32 -0
  376. package/docs/PROJECTS.md +146 -0
  377. package/docs/RELEASE_1.0.0.md +111 -0
  378. package/docs/RELEASE_NOTES.md +92 -0
  379. package/docs/RESOURCES.md +83 -0
  380. package/docs/RUNTIME.md +125 -0
  381. package/docs/SCHEDULES.md +23 -0
  382. package/docs/SECURITY.md +250 -0
  383. package/docs/TEST_REPORT.md +312 -0
  384. package/docs/TUNNEL.md +86 -0
  385. package/docs/WEB_CLIENTS.md +43 -0
  386. package/docs/WINDOWS.md +79 -0
  387. package/docs/adr/001-one-process-one-workspace.md +22 -0
  388. package/docs/adr/002-external-tunnel.md +19 -0
  389. package/docs/adr/003-sdk-v2-legacy-stateless.md +20 -0
  390. package/docs/adr/004-embedded-oauth-provider.md +19 -0
  391. package/docs/adr/005-static-client-baseline.md +19 -0
  392. package/docs/adr/006-guarded-fs-explicit-exec.md +16 -0
  393. package/docs/adr/007-preview-hash-journal.md +18 -0
  394. package/docs/adr/008-ts-js-semantics-first.md +17 -0
  395. package/docs/adr/009-jobs-polling.md +18 -0
  396. package/docs/adr/010-sqlite-better-sqlite3.md +18 -0
  397. package/docs/adr/011-env-example-secure-default.md +19 -0
  398. package/docs/adr/012-workspace-scope-grant.md +24 -0
  399. package/docs/adr/013-loopback-proxy-trust.md +18 -0
  400. package/docs/adr/014-direct-coding-tier.md +48 -0
  401. package/docs/adr/015-coding-agent-parity.md +56 -0
  402. package/docs/adr/016-oidc-openid-consent.md +15 -0
  403. package/docs/adr/017-installation-identity-local-config.md +44 -0
  404. package/docs/adr/018-access-scope-encoding.md +11 -0
  405. package/docs/adr/019-runtime-workspace-switch.md +59 -0
  406. package/docs/adr/020-desktop-access.md +50 -0
  407. package/docs/adr/021-persistent-desktop-consent.md +39 -0
  408. package/docs/adr/022-owner-kill-preserves-login.md +30 -0
  409. package/docs/adr/023-large-coding-inputs.md +49 -0
  410. package/docs/adr/024-usage-rounds-and-schedules.md +72 -0
  411. package/docs/adr/025-owner-chat-whitelist.md +53 -0
  412. package/docs/adr/026-remove-conversation-confirmation.md +35 -0
  413. package/docs/adr/027-workspace-client-list.md +20 -0
  414. package/docs/adr/028-owner-client-deletion.md +25 -0
  415. package/docs/adr/029-compact-tool-surface.md +121 -0
  416. package/docs/adr/030-windows-native-candidate.md +71 -0
  417. package/docs/adr/031-owner-selected-tunnel-supervision.md +13 -0
  418. package/docs/adr/032-owner-project-registry.md +43 -0
  419. package/docs/adr/033-read-only-project-federation.md +61 -0
  420. package/docs/adr/034-universal-resource-cas.md +60 -0
  421. package/docs/adr/035-project-brain-incremental-index.md +51 -0
  422. package/docs/adr/036-context-engine-evidence.md +53 -0
  423. package/docs/adr/037-owner-reviewed-memory.md +46 -0
  424. package/docs/adr/038-runtime-intelligence.md +46 -0
  425. package/docs/adr/039-advanced-agent-runtime.md +57 -0
  426. package/docs/adr/040-dodobench-release-gate.md +43 -0
  427. package/docs/adr/041-local-macos-docker-linux-gates.md +32 -0
  428. package/docs/adr/042-project-directory-generation-identity.md +36 -0
  429. package/docs/adr/043-trusted-self-hosted-platform-gates.md +38 -0
  430. package/docs/adr/044-global-launcher-and-cli-menu.md +43 -0
  431. package/docs/adr/045-ai-providers-multiproject.md +56 -0
  432. package/docs/adr/046-personal-access-mode.md +32 -0
  433. package/docs/adr/README.md +64 -0
  434. package/examples/.dodo.json.example +20 -0
  435. package/examples/cloudflared.yml +23 -0
  436. package/examples/reverse-proxy-fixture.mjs +37 -0
  437. package/native/desktop-linux.py +387 -0
  438. package/native/desktop-windows.cs +180 -0
  439. package/native/desktop.swift +212 -0
  440. package/package.json +145 -0
  441. package/schemas/global-config.schema.json +497 -0
  442. package/schemas/project-config.schema.json +75 -0
  443. package/schemas/tools.compact.json +3236 -0
  444. package/schemas/tools.hybrid.json +8194 -0
  445. package/schemas/tools.json +34518 -0
  446. package/scripts/guard-publish.mjs +12 -0
  447. package/scripts/setup-multimodal.mjs +70 -0
@@ -0,0 +1,291 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { DodoError } from '../errors.js';
4
+ import { newId } from '../util/hash.js';
5
+ import { mintWorkspaceId } from '../workspace/identity.js';
6
+ import { resolveWorkspaceRoot } from '../workspace/root.js';
7
+ import { fileIdentityBigInt, parseFileIdentity } from '../platform/fileIdentity.js';
8
+ export const PROJECT_METADATA_VERSION = 2;
9
+ const MAX_PROJECTS = 1000;
10
+ const PROJECT_ID = /^prj_[0-9a-hjkmnp-tv-z]{8,64}$/;
11
+ const WORKSPACE_ID = /^ws_[a-f0-9]{20}$/;
12
+ function samePath(a, b) {
13
+ return process.platform === 'win32' ? a.toLowerCase() === b.toLowerCase() : a === b;
14
+ }
15
+ function asFiniteInteger(value) {
16
+ return typeof value === 'number' && Number.isSafeInteger(value) && value >= 0 ? value : undefined;
17
+ }
18
+ function asBirthtimeNs(value) {
19
+ if (typeof value !== 'string' || !/^[1-9][0-9]{0,30}$/.test(value))
20
+ return undefined;
21
+ return value;
22
+ }
23
+ function safeDisplayName(input, root) {
24
+ const name = (input ?? path.basename(root)).trim();
25
+ if (name.length < 1 || name.length > 120 || /[\u0000-\u001f\u007f]/.test(name)) {
26
+ throw new DodoError('INVALID_INPUT', 'project display name must be 1..120 characters without control characters');
27
+ }
28
+ return name;
29
+ }
30
+ function validateProjectId(projectId) {
31
+ if (!PROJECT_ID.test(projectId))
32
+ throw new DodoError('INVALID_INPUT', 'invalid project ID');
33
+ }
34
+ function rawRows(db, includeRemoved) {
35
+ return db.prepare(`SELECT id, workspace_id, canonical_root, display_name, root_dev, root_ino, root_birthtime_ns,
36
+ metadata_version, created_at, updated_at, removed_at
37
+ FROM project_registry
38
+ ${includeRemoved ? '' : 'WHERE removed_at IS NULL'}
39
+ ORDER BY updated_at DESC, id ASC
40
+ LIMIT ?`).all(MAX_PROJECTS + 1);
41
+ }
42
+ function inspectAvailability(root, dev, ino, birthtimeNs) {
43
+ let link;
44
+ try {
45
+ link = fs.lstatSync(root);
46
+ }
47
+ catch (error) {
48
+ if (error.code === 'ENOENT')
49
+ return { availability: 'missing', statusText: 'ไม่พบ path ที่บันทึกไว้' };
50
+ return { availability: 'inaccessible', statusText: 'ไม่สามารถตรวจสอบ path ได้' };
51
+ }
52
+ if (link.isSymbolicLink())
53
+ return { availability: 'symlinked', statusText: 'path ที่บันทึกไว้ถูกแทนด้วย symbolic link' };
54
+ let real;
55
+ let stat;
56
+ try {
57
+ real = fs.realpathSync.native(root);
58
+ stat = fs.statSync(real, { bigint: true });
59
+ }
60
+ catch {
61
+ return { availability: 'inaccessible', statusText: 'ไม่สามารถตรวจสอบ directory identity ได้' };
62
+ }
63
+ if (!samePath(real, root) ||
64
+ !stat.isDirectory() ||
65
+ stat.dev !== fileIdentityBigInt(dev) ||
66
+ stat.ino !== fileIdentityBigInt(ino) ||
67
+ stat.birthtimeNs.toString() !== birthtimeNs) {
68
+ return { availability: 'replaced', statusText: 'path ชี้ไปยัง directory identity อื่น' };
69
+ }
70
+ return { availability: 'ready', statusText: 'พร้อมใช้งาน' };
71
+ }
72
+ function invalidProject(row) {
73
+ const now = Date.now();
74
+ return {
75
+ schemaVersion: 1,
76
+ projectId: typeof row.id === 'string' ? row.id : 'prj_invalid',
77
+ workspaceId: typeof row.workspace_id === 'string' ? row.workspace_id : 'ws_invalid',
78
+ root: typeof row.canonical_root === 'string' ? row.canonical_root : '(invalid path)',
79
+ displayName: typeof row.display_name === 'string' ? row.display_name : '(invalid project)',
80
+ createdAt: asFiniteInteger(row.created_at) ?? now,
81
+ updatedAt: asFiniteInteger(row.updated_at) ?? now,
82
+ removedAt: row.removed_at === null ? null : asFiniteInteger(row.removed_at) ?? null,
83
+ availability: 'invalid',
84
+ available: false,
85
+ statusText: 'registry metadata ไม่ถูกต้อง; ตรวจสอบและนำรายการนี้ออกก่อนใช้งาน',
86
+ identity: {
87
+ dev: parseFileIdentity(row.root_dev) ?? 0,
88
+ ino: parseFileIdentity(row.root_ino) ?? 0,
89
+ birthtimeNs: asBirthtimeNs(row.root_birthtime_ns) ?? '0',
90
+ },
91
+ };
92
+ }
93
+ function materialize(row) {
94
+ const id = typeof row.id === 'string' && PROJECT_ID.test(row.id) ? row.id : undefined;
95
+ const workspaceId = typeof row.workspace_id === 'string' && WORKSPACE_ID.test(row.workspace_id) ? row.workspace_id : undefined;
96
+ const root = typeof row.canonical_root === 'string' && path.isAbsolute(row.canonical_root) ? row.canonical_root : undefined;
97
+ const displayName = typeof row.display_name === 'string' && row.display_name.length >= 1 && row.display_name.length <= 120 && !/[\u0000-\u001f\u007f]/.test(row.display_name) ? row.display_name : undefined;
98
+ const dev = parseFileIdentity(row.root_dev);
99
+ const ino = parseFileIdentity(row.root_ino);
100
+ const birthtimeNs = asBirthtimeNs(row.root_birthtime_ns);
101
+ const createdAt = asFiniteInteger(row.created_at);
102
+ const updatedAt = asFiniteInteger(row.updated_at);
103
+ const removedAt = row.removed_at === null ? null : asFiniteInteger(row.removed_at);
104
+ if (!id || !workspaceId || !root || !displayName || dev === undefined || ino === undefined || !birthtimeNs || createdAt === undefined || updatedAt === undefined || removedAt === undefined || row.metadata_version !== PROJECT_METADATA_VERSION) {
105
+ return invalidProject(row);
106
+ }
107
+ const status = removedAt === null
108
+ ? inspectAvailability(root, dev, ino, birthtimeNs)
109
+ : { availability: 'removed', statusText: 'นำออกจาก registry แล้ว; ไฟล์และประวัติไม่ได้ถูกลบ' };
110
+ return {
111
+ schemaVersion: 1,
112
+ projectId: id,
113
+ workspaceId,
114
+ root,
115
+ displayName,
116
+ createdAt,
117
+ updatedAt,
118
+ removedAt,
119
+ availability: status.availability,
120
+ available: removedAt === null && status.availability === 'ready',
121
+ statusText: status.statusText,
122
+ identity: { dev, ino, birthtimeNs },
123
+ };
124
+ }
125
+ function resolveInput(candidate) {
126
+ if (typeof candidate !== 'string' || candidate.length < 1 || candidate.length > 4096 || candidate.includes('\0') || !path.isAbsolute(candidate)) {
127
+ throw new DodoError('INVALID_INPUT', 'project path must be an absolute path');
128
+ }
129
+ const root = resolveWorkspaceRoot(candidate, { allowUnsafe: false });
130
+ if (!root.birthtimeNs) {
131
+ throw new DodoError('NOT_SUPPORTED', 'project registry requires a filesystem with stable directory birth-time metadata', {
132
+ recovery: 'move the project to a local APFS, ext4, NTFS, or another filesystem that exposes directory birth time',
133
+ });
134
+ }
135
+ return { ...root, birthtimeNs: root.birthtimeNs };
136
+ }
137
+ /** Owner-only installation registry. It never changes workspace authority. */
138
+ export class ProjectRegistry {
139
+ store;
140
+ constructor(store) {
141
+ this.store = store;
142
+ }
143
+ list(options = {}) {
144
+ try {
145
+ const rows = rawRows(this.store.db, options.includeRemoved ?? false);
146
+ if (rows.length > MAX_PROJECTS)
147
+ throw new DodoError('RESOURCE_LIMIT', `project registry exceeds ${MAX_PROJECTS} entries`);
148
+ return rows.map(materialize);
149
+ }
150
+ catch (error) {
151
+ if (error instanceof DodoError)
152
+ throw error;
153
+ throw registryFailure('read');
154
+ }
155
+ }
156
+ get(projectId, options = {}) {
157
+ validateProjectId(projectId);
158
+ let row;
159
+ try {
160
+ row = this.store.db.prepare(`SELECT id, workspace_id, canonical_root, display_name, root_dev, root_ino, root_birthtime_ns,
161
+ metadata_version, created_at, updated_at, removed_at
162
+ FROM project_registry WHERE id = ? ${options.includeRemoved ? '' : 'AND removed_at IS NULL'}`).get(projectId);
163
+ }
164
+ catch {
165
+ throw registryFailure('read');
166
+ }
167
+ if (!row)
168
+ throw new DodoError('NOT_FOUND', `project not found: ${projectId}`);
169
+ return materialize(row);
170
+ }
171
+ add(candidate, displayName) {
172
+ const root = resolveInput(candidate);
173
+ const name = safeDisplayName(displayName, root.root);
174
+ const workspaceId = mintWorkspaceId(this.store.installSecret(), root.root);
175
+ let result;
176
+ const tx = this.store.db.transaction(() => {
177
+ const byRoot = this.store.db.prepare('SELECT * FROM project_registry WHERE canonical_root = ? AND removed_at IS NULL').get(root.root);
178
+ if (byRoot) {
179
+ const current = materialize(byRoot);
180
+ if (current.availability === 'invalid')
181
+ throw new DodoError('MIGRATION_REVIEW_REQUIRED', 'project registry row is invalid', { detail: { projectId: current.projectId } });
182
+ if (current.identity.dev !== root.dev || current.identity.ino !== root.ino || current.identity.birthtimeNs !== root.birthtimeNs) {
183
+ throw new DodoError('CONFLICT', 'registered project path now points to another directory identity', {
184
+ recovery: `review ${current.projectId}, remove it explicitly, then add the replacement as a new project`,
185
+ detail: { projectId: current.projectId, availability: current.availability },
186
+ });
187
+ }
188
+ if (displayName !== undefined && current.displayName !== name) {
189
+ const now = Date.now();
190
+ this.store.db.prepare('UPDATE project_registry SET display_name = ?, updated_at = ? WHERE id = ?').run(name, now, current.projectId);
191
+ result = { changed: true, relocated: false, project: this.get(current.projectId) };
192
+ this.audit(result, 'updated');
193
+ }
194
+ else
195
+ result = { changed: false, relocated: false, project: current };
196
+ return;
197
+ }
198
+ const byIdentity = this.store.db.prepare('SELECT * FROM project_registry WHERE root_dev = ? AND root_ino = ? AND removed_at IS NULL').get(root.dev, root.ino);
199
+ if (byIdentity) {
200
+ const current = materialize(byIdentity);
201
+ if (current.availability === 'invalid')
202
+ throw new DodoError('MIGRATION_REVIEW_REQUIRED', 'project registry row is invalid', { detail: { projectId: current.projectId } });
203
+ if (current.identity.birthtimeNs !== root.birthtimeNs) {
204
+ throw new DodoError('CONFLICT', 'a filesystem inode was reused by another directory generation', {
205
+ recovery: `review ${current.projectId}, remove it explicitly, then add the replacement as a new project`,
206
+ detail: { projectId: current.projectId, availability: current.availability },
207
+ });
208
+ }
209
+ if (samePath(current.root, root.root)) {
210
+ result = { changed: false, relocated: false, project: current };
211
+ return;
212
+ }
213
+ if (current.availability !== 'missing') {
214
+ throw new DodoError('CONFLICT', 'the same directory identity is already registered at another active path', { detail: { projectId: current.projectId } });
215
+ }
216
+ const now = Date.now();
217
+ this.store.db.prepare('UPDATE project_registry SET workspace_id = ?, canonical_root = ?, display_name = ?, root_birthtime_ns = ?, updated_at = ? WHERE id = ?')
218
+ .run(workspaceId, root.root, displayName === undefined ? current.displayName : name, root.birthtimeNs, now, current.projectId);
219
+ result = { changed: true, relocated: true, project: this.get(current.projectId) };
220
+ this.audit(result, 'relocated');
221
+ return;
222
+ }
223
+ const count = this.store.db.prepare('SELECT COUNT(*) AS count FROM project_registry WHERE removed_at IS NULL').get().count;
224
+ if (count >= MAX_PROJECTS)
225
+ throw new DodoError('RESOURCE_LIMIT', `project registry is limited to ${MAX_PROJECTS} active entries`);
226
+ const now = Date.now();
227
+ const projectId = newId('prj', 12);
228
+ this.store.db.prepare(`INSERT INTO project_registry
229
+ (id, workspace_id, canonical_root, display_name, root_dev, root_ino, root_birthtime_ns, metadata_version, created_at, updated_at, removed_at)
230
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NULL)`).run(projectId, workspaceId, root.root, name, root.dev, root.ino, root.birthtimeNs, PROJECT_METADATA_VERSION, now, now);
231
+ result = { changed: true, relocated: false, project: this.get(projectId) };
232
+ this.audit(result, 'added');
233
+ });
234
+ try {
235
+ tx.immediate();
236
+ }
237
+ catch (error) {
238
+ if (error instanceof DodoError)
239
+ throw error;
240
+ const code = error.code;
241
+ if (code === 'SQLITE_CONSTRAINT_UNIQUE') {
242
+ const existing = this.store.db.prepare('SELECT * FROM project_registry WHERE canonical_root = ? AND removed_at IS NULL').get(root.root);
243
+ if (existing)
244
+ return { changed: false, relocated: false, project: materialize(existing) };
245
+ throw new DodoError('CONFLICT', 'project registry changed concurrently; retry the command');
246
+ }
247
+ throw registryFailure('update');
248
+ }
249
+ return result;
250
+ }
251
+ remove(projectId) {
252
+ validateProjectId(projectId);
253
+ const current = this.get(projectId);
254
+ try {
255
+ const tx = this.store.db.transaction(() => {
256
+ const job = this.store.db.prepare("SELECT 1 FROM jobs WHERE workspace_id=? AND status='running' LIMIT 1").get(current.workspaceId);
257
+ const agent = this.store.db.prepare("SELECT 1 FROM ai_runs WHERE workspace_id=? AND status NOT IN ('completed','failed','canceled') LIMIT 1").get(current.workspaceId);
258
+ if (job || agent)
259
+ throw new DodoError('CONFLICT', 'project has unfinished jobs or agent runs; finish or cancel them before removal');
260
+ const now = Date.now();
261
+ const changed = this.store.db.prepare('UPDATE project_registry SET removed_at = ?, updated_at = ? WHERE id = ? AND removed_at IS NULL').run(now, now, projectId);
262
+ if (changed.changes !== 1)
263
+ throw new DodoError('CONFLICT', 'project registry changed concurrently; refresh and retry');
264
+ this.store.audit({ principal: 'local-project-owner', workspaceId: current.workspaceId, tool: 'local.project.remove', paths: [current.root], refId: projectId, result: 'removed' });
265
+ });
266
+ tx.immediate();
267
+ }
268
+ catch (error) {
269
+ if (error instanceof DodoError)
270
+ throw error;
271
+ throw registryFailure('update');
272
+ }
273
+ return this.get(projectId, { includeRemoved: true });
274
+ }
275
+ audit(result, outcome) {
276
+ this.store.audit({
277
+ principal: 'local-project-owner',
278
+ workspaceId: result.project.workspaceId,
279
+ tool: 'local.project.add',
280
+ paths: [result.project.root],
281
+ refId: result.project.projectId,
282
+ result: outcome,
283
+ });
284
+ }
285
+ }
286
+ function registryFailure(operation) {
287
+ return new DodoError('INTERNAL_ERROR', `project registry ${operation} failed`, {
288
+ recovery: 'the registry was left unchanged; back up the Dodo state directory and run dodo doctor before repairing state.db',
289
+ });
290
+ }
291
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/projects/registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ export const ACCESS_MODE_META_KEY = 'owner-access-mode';
2
+ /**
3
+ * Personal mode is DODO's single-owner default. OAuth still identifies the
4
+ * installed client and limits token scopes, while registered projects become
5
+ * available without a second per-project ACL/profile ceremony.
6
+ *
7
+ * Managed mode keeps the original project ACL, trust and AI egress allowlists
8
+ * for owners who share one installation between independently trusted clients.
9
+ */
10
+ export function accessMode(store) {
11
+ return store.getMeta(ACCESS_MODE_META_KEY) === 'managed' ? 'managed' : 'personal';
12
+ }
13
+ export function setAccessMode(store, mode) {
14
+ store.setMeta(ACCESS_MODE_META_KEY, mode);
15
+ }
16
+ export function isPersonalMode(store) {
17
+ return accessMode(store) === 'personal';
18
+ }
19
+ //# sourceMappingURL=accessMode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accessMode.js","sourceRoot":"","sources":["../../src/security/accessMode.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,oBAAoB,GAAG,mBAAmB,CAAC;AAGxD;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU,CAAC,KAAY;IACrC,OAAO,KAAK,CAAC,OAAO,CAAC,oBAAoB,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC;AACpF,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAY,EAAE,IAAgB;IAC1D,KAAK,CAAC,OAAO,CAAC,oBAAoB,EAAE,IAAI,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAY;IACzC,OAAO,UAAU,CAAC,KAAK,CAAC,KAAK,UAAU,CAAC;AAC1C,CAAC"}
@@ -0,0 +1,56 @@
1
+ import { DodoError } from '../errors.js';
2
+ import { digestOf } from '../util/hash.js';
3
+ export function actionDigest(req, policyVersion) {
4
+ return digestOf({ tool: req.tool, action: req.action, policyVersion });
5
+ }
6
+ function policyVersionOf(store, workspaceId) {
7
+ const row = store.db.prepare('SELECT COUNT(*) AS c FROM policy_versions WHERE workspace_id = ?').get(workspaceId);
8
+ return row.c;
9
+ }
10
+ /**
11
+ * Gate an action behind a local approval. Either returns (approval found and
12
+ * consumed — proceed) or throws APPROVAL_REQUIRED carrying an opaque request
13
+ * reference the model can surface to the user.
14
+ */
15
+ export function requireLocalApproval(store, req) {
16
+ const digest = actionDigest(req, policyVersionOf(store, req.workspaceId));
17
+ const existing = store.findPendingActionApproval(req.workspaceId, digest, req.principal);
18
+ if (existing) {
19
+ if (existing.epoch !== req.epoch) {
20
+ // approvals do not survive server restarts (spec §12.3)
21
+ store.setApprovalStatus(existing.id, 'denied');
22
+ }
23
+ else if (existing.status === 'approved') {
24
+ const consumed = store.setApprovalStatus(existing.id, 'consumed');
25
+ if (consumed)
26
+ return { approvalId: existing.id };
27
+ throw new DodoError('APPROVAL_EXPIRED', 'approval expired before use; request again', {
28
+ retryable: true,
29
+ detail: { approvalId: existing.id },
30
+ });
31
+ }
32
+ else if (existing.status === 'pending') {
33
+ throw new DodoError('APPROVAL_REQUIRED', `local approval pending: run \`dodo approve ${existing.id}\` on the server terminal`, {
34
+ retryable: true,
35
+ recovery: `ask the machine owner to run: dodo approve ${existing.id}`,
36
+ detail: { approvalId: existing.id, summary: req.summary },
37
+ });
38
+ }
39
+ }
40
+ const created = store.createApproval({
41
+ kind: 'action',
42
+ workspaceId: req.workspaceId,
43
+ epoch: req.epoch,
44
+ principal: req.principal,
45
+ tool: req.tool,
46
+ digest,
47
+ summary: req.summary,
48
+ ttlMs: req.ttlMs,
49
+ });
50
+ throw new DodoError('APPROVAL_REQUIRED', `local approval required: run \`dodo approve ${created.id}\` on the server terminal, then retry this call with the same arguments`, {
51
+ retryable: true,
52
+ recovery: `ask the machine owner to run: dodo approve ${created.id}`,
53
+ detail: { approvalId: created.id, summary: req.summary },
54
+ });
55
+ }
56
+ //# sourceMappingURL=approvals.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approvals.js","sourceRoot":"","sources":["../../src/security/approvals.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAsB3C,MAAM,UAAU,YAAY,CAAC,GAA6C,EAAE,aAAqB;IAC/F,OAAO,QAAQ,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC;AACzE,CAAC;AAED,SAAS,eAAe,CAAC,KAAY,EAAE,WAAmB;IACxD,MAAM,GAAG,GAAG,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,kEAAkE,CAAC,CAAC,GAAG,CAAC,WAAW,CAAkB,CAAC;IACnI,OAAO,GAAG,CAAC,CAAC,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAY,EAAE,GAAoB;IACrE,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,EAAE,eAAe,CAAC,KAAK,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC;IAC1E,MAAM,QAAQ,GAAG,KAAK,CAAC,yBAAyB,CAAC,GAAG,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC;IACzF,IAAI,QAAQ,EAAE,CAAC;QACb,IAAI,QAAQ,CAAC,KAAK,KAAK,GAAG,CAAC,KAAK,EAAE,CAAC;YACjC,wDAAwD;YACxD,KAAK,CAAC,iBAAiB,CAAC,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;QACjD,CAAC;aAAM,IAAI,QAAQ,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;YAC1C,MAAM,QAAQ,GAAG,KAAK,CAAC,iBAAiB,CAAC,QAAQ,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;YAClE,IAAI,QAAQ;gBAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjD,MAAM,IAAI,SAAS,CAAC,kBAAkB,EAAE,4CAA4C,EAAE;gBACpF,SAAS,EAAE,IAAI;gBACf,MAAM,EAAE,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,EAAE;aACpC,CAAC,CAAC;QACL,CAAC;aAAM,IAAI,QAAQ,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YACzC,MAAM,IAAI,SAAS,CAAC,mBAAmB,EAAE,8CAA8C,QAAQ,CAAC,EAAE,2BAA2B,EAAE;gBAC7H,SAAS,EAAE,IAAI;gBACf,QAAQ,EAAE,8CAA8C,QAAQ,CAAC,EAAE,EAAE;gBACrE,MAAM,EAAE,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE;aAC1D,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,MAAM,OAAO,GAAG,KAAK,CAAC,cAAc,CAAC;QACnC,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,SAAS,EAAE,GAAG,CAAC,SAAS;QACxB,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,MAAM;QACN,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,KAAK,EAAE,GAAG,CAAC,KAAK;KACjB,CAAC,CAAC;IACH,MAAM,IAAI,SAAS,CAAC,mBAAmB,EAAE,+CAA+C,OAAO,CAAC,EAAE,yEAAyE,EAAE;QAC3K,SAAS,EAAE,IAAI;QACf,QAAQ,EAAE,8CAA8C,OAAO,CAAC,EAAE,EAAE;QACpE,MAAM,EAAE,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE;KACzD,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,57 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { isWithinPath } from '../platform/pathPolicy.js';
4
+ import { envValue, windowsProgramDataDirectory } from '../platform/system.js';
5
+ /** Child jobs receive a whitelist, not the server's OAuth/config/loader state. */
6
+ const BASE_ALLOWED = ['HOME', 'LANG', 'LC_ALL', 'LC_CTYPE', 'TMPDIR', 'TZ', 'USER', 'LOGNAME', 'SHELL', 'COLORTERM'];
7
+ const WINDOWS_ALLOWED = ['SYSTEMROOT', 'WINDIR', 'SYSTEMDRIVE', 'USERPROFILE', 'HOMEDRIVE', 'HOMEPATH', 'APPDATA', 'LOCALAPPDATA', 'PROGRAMDATA', 'TEMP', 'TMP', 'USERNAME', 'USERDOMAIN', 'PROGRAMFILES', 'PROGRAMFILES(X86)', 'PROGRAMW6432', 'COMMONPROGRAMFILES', 'PROCESSOR_ARCHITECTURE', 'NUMBER_OF_PROCESSORS'];
8
+ const ALWAYS_DENIED = new Set(['NODE_OPTIONS', 'NODE_EXTRA_CA_CERTS', 'LD_PRELOAD', 'DYLD_INSERT_LIBRARIES', 'DYLD_LIBRARY_PATH', 'LD_LIBRARY_PATH', 'PATH', 'TERM', 'COMSPEC', 'PATHEXT', 'NODE_PATH', 'TUNNEL_TOKEN', 'TUNNEL_TOKEN_FILE']);
9
+ export function trustedPath(parentPath, workspaceRoot, platform = process.platform) {
10
+ const p = platform === 'win32' ? path.win32 : path.posix;
11
+ const real = (value) => {
12
+ try {
13
+ return platform === process.platform ? fs.realpathSync.native(value) : value;
14
+ }
15
+ catch {
16
+ return value;
17
+ }
18
+ };
19
+ const root = real(workspaceRoot);
20
+ const entries = (parentPath ?? '').split(p.delimiter).filter(entry => {
21
+ if (!entry || !p.isAbsolute(entry) || (platform === 'win32' && !/^[a-z]:[\\/]/i.test(entry)))
22
+ return false;
23
+ return !isWithinPath(workspaceRoot, entry, platform) && !isWithinPath(root, real(entry), platform);
24
+ });
25
+ if (entries.length > 0)
26
+ return [...new Set(entries)].join(p.delimiter);
27
+ if (platform === 'win32') {
28
+ const systemRoot = envValue(process.env, 'SystemRoot', 'win32') ?? 'C:\\Windows';
29
+ return [p.join(systemRoot, 'System32'), systemRoot].filter(entry => !isWithinPath(root, entry, platform)).join(';');
30
+ }
31
+ return ['/usr/bin', '/bin', '/usr/sbin', '/sbin'].filter(entry => !isWithinPath(root, real(entry), platform)).join(':');
32
+ }
33
+ export function buildChildEnv(opts) {
34
+ const platform = opts.platform ?? process.platform;
35
+ const out = { PATH: trustedPath(envValue(opts.parentEnv, 'PATH', platform), opts.workspaceRoot, platform), TERM: 'dumb' };
36
+ const names = new Set([...BASE_ALLOWED, ...(platform === 'win32' ? WINDOWS_ALLOWED : []), ...opts.extraAllowlist]);
37
+ for (const name of names) {
38
+ const upper = name.toUpperCase();
39
+ if (ALWAYS_DENIED.has(upper) || upper.startsWith('DODO_'))
40
+ continue;
41
+ const value = envValue(opts.parentEnv, name, platform);
42
+ if (value !== undefined)
43
+ out[platform === 'win32' ? upper : name] = value;
44
+ }
45
+ if (platform === 'win32') {
46
+ if (!out['PROGRAMDATA']) {
47
+ const programData = windowsProgramDataDirectory(opts.parentEnv);
48
+ if (programData)
49
+ out['PROGRAMDATA'] = programData;
50
+ }
51
+ const extensions = (envValue(opts.parentEnv, 'PATHEXT', platform) ?? '.COM;.EXE;.BAT;.CMD').split(';').map(e => e.toUpperCase()).filter(e => ['.EXE', '.COM', '.CMD', '.BAT'].includes(e));
52
+ out['PATHEXT'] = [...new Set(extensions.length ? extensions : ['.EXE', '.COM', '.CMD', '.BAT'])].join(';');
53
+ out['NoDefaultCurrentDirectoryInExePath'] = '1';
54
+ }
55
+ return out;
56
+ }
57
+ //# sourceMappingURL=env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/security/env.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,78 @@
1
+ import { AsyncLocalStorage } from 'node:async_hooks';
2
+ import { DodoError } from '../errors.js';
3
+ /** One queue per real workspace; nested dispatch shares its ticket, background jobs retain it. */
4
+ export class MutationQueue {
5
+ context = new AsyncLocalStorage();
6
+ active;
7
+ waiters = [];
8
+ get busy() { return this.active !== undefined; }
9
+ get pending() { return this.waiters.length; }
10
+ ticket() {
11
+ const t = { refs: 1, open: true, release: () => {
12
+ if (--t.refs !== 0)
13
+ return;
14
+ if (this.active === t)
15
+ this.active = undefined;
16
+ const next = this.waiters.shift();
17
+ if (next)
18
+ next(this.ticket());
19
+ } };
20
+ this.active = t;
21
+ return t;
22
+ }
23
+ async run(fn, signal) {
24
+ if (signal?.aborted)
25
+ throw new DodoError('CONFLICT', 'queued action was canceled');
26
+ const nested = this.context.getStore();
27
+ if (nested?.open && this.active === nested)
28
+ return fn();
29
+ let ticket;
30
+ if (this.busy) {
31
+ if (this.waiters.length >= 32)
32
+ throw new DodoError('RESOURCE_LIMIT', 'workspace mutation queue is full');
33
+ ticket = await new Promise((resolve, reject) => {
34
+ const waiter = (t) => { signal?.removeEventListener('abort', abort); resolve(t); };
35
+ const abort = () => { const i = this.waiters.indexOf(waiter); if (i >= 0) {
36
+ this.waiters.splice(i, 1);
37
+ reject(new DodoError('CONFLICT', 'queued action was canceled'));
38
+ } };
39
+ this.waiters.push(waiter);
40
+ signal?.addEventListener('abort', abort, { once: true });
41
+ if (signal?.aborted)
42
+ abort();
43
+ });
44
+ }
45
+ else
46
+ ticket = this.ticket();
47
+ try {
48
+ return await this.context.run(ticket, fn);
49
+ }
50
+ finally {
51
+ ticket.open = false;
52
+ ticket.release();
53
+ }
54
+ }
55
+ assertCanStart() {
56
+ const ticket = this.context.getStore();
57
+ if (this.busy && (!ticket?.open || ticket !== this.active))
58
+ throw new DodoError('CONFLICT', 'workspace mutation queue is busy');
59
+ }
60
+ /** Sync producers (schedules) refuse a busy queue; they may retry before claiming a due run. */
61
+ retainJob() {
62
+ let ticket = this.context.getStore();
63
+ if (!ticket?.open || ticket !== this.active) {
64
+ if (this.busy)
65
+ throw new DodoError('CONFLICT', 'workspace mutation queue is busy; wait for the current job');
66
+ ticket = this.ticket();
67
+ ticket.open = false;
68
+ }
69
+ else
70
+ ticket.refs++;
71
+ let done = false;
72
+ return () => { if (!done) {
73
+ done = true;
74
+ ticket.release();
75
+ } };
76
+ }
77
+ }
78
+ //# sourceMappingURL=mutationQueue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mutationQueue.js","sourceRoot":"","sources":["../../src/security/mutationQueue.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ export const ALL_SCOPES = ['dodo:read', 'dodo:write', 'dodo:exec'];
2
+ export function decide(action, mode) {
3
+ switch (action) {
4
+ case 'read':
5
+ case 'plan':
6
+ case 'job-control':
7
+ return 'allow';
8
+ case 'mutate-files':
9
+ return mode === 'inspect' ? 'approval' : 'allow';
10
+ case 'exec':
11
+ return mode === 'trusted' ? 'allow' : 'approval';
12
+ }
13
+ }
14
+ export function scopeSatisfied(required, tokenScopes) {
15
+ return tokenScopes.includes(required);
16
+ }
17
+ export const TRUST_MODE_DESCRIPTIONS = {
18
+ inspect: 'read & search allowed; every file change (write_file/edit_file/apply_changes) and every command (run_command/exec_command/run_task/git_commit) needs a per-action local approval',
19
+ edit: 'read & search allowed; file changes (write_file/edit_file/delete_path/move_path/apply_changes) apply directly under this standing consent; running commands still needs per-action local approval',
20
+ trusted: 'file changes and command execution (run_command/exec_command/run_task/git_commit) run directly — the recommended mode when your MCP client confirms every call. Commands run with YOUR OS user privileges — the workspace directory guard is NOT an OS sandbox; test/lint/build scripts can execute arbitrary code and reach files outside the workspace',
21
+ };
22
+ //# sourceMappingURL=policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.js","sourceRoot":"","sources":["../../src/security/policy.ts"],"names":[],"mappings":"AAWA,MAAM,CAAC,MAAM,UAAU,GAAiB,CAAC,WAAW,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC;AAYjF,MAAM,UAAU,MAAM,CAAC,MAAmB,EAAE,IAAe;IACzD,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,MAAM,CAAC;QACZ,KAAK,MAAM,CAAC;QACZ,KAAK,aAAa;YAChB,OAAO,OAAO,CAAC;QACjB,KAAK,cAAc;YACjB,OAAO,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC;QACnD,KAAK,MAAM;YACT,OAAO,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC;IACrD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,QAAoB,EAAE,WAAqB;IACxE,OAAO,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AACxC,CAAC;AAED,MAAM,CAAC,MAAM,uBAAuB,GAA8B;IAChE,OAAO,EAAE,kLAAkL;IAC3L,IAAI,EAAE,mMAAmM;IACzM,OAAO,EACL,0VAA0V;CAC7V,CAAC"}
@@ -0,0 +1,22 @@
1
+ import { DodoError } from '../errors.js';
2
+ import { isPersonalMode } from './accessMode.js';
3
+ export function isOwner(p) {
4
+ return p.sub === 'owner' && ((p.grantId === 'local-stdio' && p.clientId === 'stdio') || (p.grantId === 'local-config-owner' && p.clientId === 'local-config'));
5
+ }
6
+ /** A delegation can narrow token scopes; live target ACLs and expiry are always re-read. */
7
+ export function projectAuthority(store, p, workspaceId) {
8
+ if (p.projectRestriction && p.projectRestriction !== workspaceId)
9
+ throw new DodoError('FORBIDDEN', 'delegation is restricted to its target project');
10
+ if (p.expiresAt !== undefined && p.expiresAt <= Date.now() / 1000)
11
+ throw new DodoError('AUTH_REQUIRED', 'authorization expired; authenticate and resume');
12
+ if (isOwner(p))
13
+ return { ...p, scopes: [...p.scopes] };
14
+ const grant = store.getGrant(p.grantId);
15
+ if (!grant || grant.revokedAt !== null || grant.clientId !== p.clientId || !store.getOAuthClient(p.clientId))
16
+ throw new DodoError('AUTH_REQUIRED', 'authorization was revoked');
17
+ if ((p.identityGrant === false || store.getMeta(`identity-grant:${p.grantId}`) !== '2') && grant.workspaceId !== workspaceId)
18
+ throw new DodoError('FORBIDDEN', 'authorization is bound to another workspace');
19
+ const allowed = isPersonalMode(store) ? grant.scopes : store.clientAccess(workspaceId, p.clientId);
20
+ return { ...p, scopes: (p.tokenScopes ?? p.scopes).filter(s => grant.scopes.includes(s) && allowed.includes(s)) };
21
+ }
22
+ //# sourceMappingURL=projectAuthority.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projectAuthority.js","sourceRoot":"","sources":["../../src/security/projectAuthority.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAGzC,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,MAAM,UAAU,OAAO,CAAC,CAAY;IAClC,OAAO,CAAC,CAAC,GAAG,KAAK,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,KAAK,aAAa,IAAI,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,KAAK,oBAAoB,IAAI,CAAC,CAAC,QAAQ,KAAK,cAAc,CAAC,CAAC,CAAC;AACjK,CAAC;AACD,4FAA4F;AAC5F,MAAM,UAAU,gBAAgB,CAAC,KAAY,EAAE,CAAY,EAAE,WAAmB;IAC9E,IAAI,CAAC,CAAC,kBAAkB,IAAI,CAAC,CAAC,kBAAkB,KAAK,WAAW;QAAE,MAAM,IAAI,SAAS,CAAC,WAAW,EAAC,gDAAgD,CAAC,CAAC;IACpJ,IAAI,CAAC,CAAC,SAAS,KAAK,SAAS,IAAI,CAAC,CAAC,SAAS,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI;QAAE,MAAM,IAAI,SAAS,CAAC,eAAe,EAAE,gDAAgD,CAAC,CAAC;IAC1J,IAAI,OAAO,CAAC,CAAC,CAAC;QAAE,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;IACvD,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IACxC,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,SAAS,KAAK,IAAI,IAAI,KAAK,CAAC,QAAQ,KAAK,CAAC,CAAC,QAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC;QAAE,MAAM,IAAI,SAAS,CAAC,eAAe,EAAE,2BAA2B,CAAC,CAAC;IAChL,IAAI,CAAC,CAAC,CAAC,aAAa,KAAK,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC,OAAO,EAAE,CAAC,KAAK,GAAG,CAAC,IAAI,KAAK,CAAC,WAAW,KAAK,WAAW;QAAE,MAAM,IAAI,SAAS,CAAC,WAAW,EAAE,6CAA6C,CAAC,CAAC;IAC9M,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC;IACnG,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACpH,CAAC"}