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