@wardby/cli 0.1.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 (412) hide show
  1. package/.env.example +131 -0
  2. package/LICENSE +202 -0
  3. package/NOTICE +2 -0
  4. package/README.md +282 -0
  5. package/bin/wardby.js +3 -0
  6. package/deploy/local/docker-compose.yml +19 -0
  7. package/dist/claude-coding-worker/driver.d.ts +70 -0
  8. package/dist/claude-coding-worker/driver.js +128 -0
  9. package/dist/claude-coding-worker/main.d.ts +2 -0
  10. package/dist/claude-coding-worker/main.js +41 -0
  11. package/dist/claude-coding-worker/sdk.d.ts +4 -0
  12. package/dist/claude-coding-worker/sdk.js +43 -0
  13. package/dist/claude-coding-worker/tool-relay.d.ts +1 -0
  14. package/dist/claude-coding-worker/tool-relay.js +9 -0
  15. package/dist/cli-help.d.ts +1 -0
  16. package/dist/cli-help.js +20 -0
  17. package/dist/cli.d.ts +18 -0
  18. package/dist/cli.js +629 -0
  19. package/dist/coding/observability.d.ts +59 -0
  20. package/dist/coding/observability.js +77 -0
  21. package/dist/coding/profile.d.ts +88 -0
  22. package/dist/coding/profile.js +137 -0
  23. package/dist/coding/protocol.d.ts +345 -0
  24. package/dist/coding/protocol.js +445 -0
  25. package/dist/coding/provider.d.ts +4 -0
  26. package/dist/coding/provider.js +18 -0
  27. package/dist/coding-proxy/main.d.ts +1 -0
  28. package/dist/coding-proxy/main.js +51 -0
  29. package/dist/coding-worker/artifact.d.ts +16 -0
  30. package/dist/coding-worker/artifact.js +37 -0
  31. package/dist/coding-worker/driver.d.ts +46 -0
  32. package/dist/coding-worker/driver.js +158 -0
  33. package/dist/coding-worker/errors.d.ts +1 -0
  34. package/dist/coding-worker/errors.js +23 -0
  35. package/dist/coding-worker/isolation-probe.d.ts +1 -0
  36. package/dist/coding-worker/isolation-probe.js +146 -0
  37. package/dist/coding-worker/keeper.d.ts +4 -0
  38. package/dist/coding-worker/keeper.js +29 -0
  39. package/dist/coding-worker/main.d.ts +2 -0
  40. package/dist/coding-worker/main.js +43 -0
  41. package/dist/coding-worker/sdk.d.ts +26 -0
  42. package/dist/coding-worker/sdk.js +28 -0
  43. package/dist/coding-worker/types.d.ts +64 -0
  44. package/dist/coding-worker/types.js +1 -0
  45. package/dist/config/providers.d.ts +158 -0
  46. package/dist/config/providers.js +162 -0
  47. package/dist/core/budget-groups.d.ts +72 -0
  48. package/dist/core/budget-groups.js +149 -0
  49. package/dist/core/budget.d.ts +63 -0
  50. package/dist/core/budget.js +69 -0
  51. package/dist/core/coding-queue.d.ts +32 -0
  52. package/dist/core/coding-queue.js +54 -0
  53. package/dist/core/cron.d.ts +31 -0
  54. package/dist/core/cron.js +43 -0
  55. package/dist/core/datastores.d.ts +41 -0
  56. package/dist/core/datastores.js +105 -0
  57. package/dist/core/db.d.ts +2 -0
  58. package/dist/core/db.js +2 -0
  59. package/dist/core/dispatch.d.ts +81 -0
  60. package/dist/core/dispatch.js +184 -0
  61. package/dist/core/engine-native.d.ts +29 -0
  62. package/dist/core/engine-native.js +259 -0
  63. package/dist/core/http-runtime.d.ts +7 -0
  64. package/dist/core/http-runtime.js +101 -0
  65. package/dist/core/lease.d.ts +13 -0
  66. package/dist/core/lease.js +22 -0
  67. package/dist/core/logger.d.ts +13 -0
  68. package/dist/core/logger.js +45 -0
  69. package/dist/core/memory-tools.d.ts +11 -0
  70. package/dist/core/memory-tools.js +122 -0
  71. package/dist/core/reconciler.d.ts +45 -0
  72. package/dist/core/reconciler.js +152 -0
  73. package/dist/core/runner.d.ts +87 -0
  74. package/dist/core/runner.js +529 -0
  75. package/dist/core/scheduler.d.ts +47 -0
  76. package/dist/core/scheduler.js +121 -0
  77. package/dist/core/secrets.d.ts +46 -0
  78. package/dist/core/secrets.js +100 -0
  79. package/dist/core/subagent-memory-tools.d.ts +18 -0
  80. package/dist/core/subagent-memory-tools.js +121 -0
  81. package/dist/core/timing.d.ts +7 -0
  82. package/dist/core/timing.js +7 -0
  83. package/dist/core/webhooks.d.ts +23 -0
  84. package/dist/core/webhooks.js +113 -0
  85. package/dist/env.d.ts +11 -0
  86. package/dist/env.js +13 -0
  87. package/dist/import/budgets.d.ts +16 -0
  88. package/dist/import/budgets.js +21 -0
  89. package/dist/import/bundle.d.ts +16 -0
  90. package/dist/import/bundle.js +61 -0
  91. package/dist/import/cli-args.d.ts +2 -0
  92. package/dist/import/cli-args.js +44 -0
  93. package/dist/import/create.d.ts +34 -0
  94. package/dist/import/create.js +363 -0
  95. package/dist/import/index.d.ts +25 -0
  96. package/dist/import/index.js +130 -0
  97. package/dist/import/model-gate.d.ts +1 -0
  98. package/dist/import/model-gate.js +3 -0
  99. package/dist/import/neutral-schema.d.ts +369 -0
  100. package/dist/import/neutral-schema.js +109 -0
  101. package/dist/import/preflight.d.ts +41 -0
  102. package/dist/import/preflight.js +71 -0
  103. package/dist/import/report.d.ts +5 -0
  104. package/dist/import/report.js +98 -0
  105. package/dist/import/tool-scan.d.ts +8 -0
  106. package/dist/import/tool-scan.js +20 -0
  107. package/dist/mcp/auth/ownership.d.ts +113 -0
  108. package/dist/mcp/auth/ownership.js +87 -0
  109. package/dist/mcp/auth/principal.d.ts +9 -0
  110. package/dist/mcp/auth/principal.js +9 -0
  111. package/dist/mcp/auth/resource-server.d.ts +47 -0
  112. package/dist/mcp/auth/resource-server.js +82 -0
  113. package/dist/mcp/auth/self-hosted/browser.d.ts +3 -0
  114. package/dist/mcp/auth/self-hosted/browser.js +273 -0
  115. package/dist/mcp/auth/self-hosted/cli.d.ts +2 -0
  116. package/dist/mcp/auth/self-hosted/cli.js +39 -0
  117. package/dist/mcp/auth/self-hosted/credentials.d.ts +58 -0
  118. package/dist/mcp/auth/self-hosted/credentials.js +106 -0
  119. package/dist/mcp/auth/self-hosted/rate-limit.d.ts +13 -0
  120. package/dist/mcp/auth/self-hosted/rate-limit.js +20 -0
  121. package/dist/mcp/auth/self-hosted/session.d.ts +36 -0
  122. package/dist/mcp/auth/self-hosted/session.js +110 -0
  123. package/dist/mcp/capabilities.d.ts +11 -0
  124. package/dist/mcp/capabilities.js +10 -0
  125. package/dist/mcp/context.d.ts +46 -0
  126. package/dist/mcp/context.js +1 -0
  127. package/dist/mcp/errors.d.ts +13 -0
  128. package/dist/mcp/errors.js +22 -0
  129. package/dist/mcp/index.d.ts +32 -0
  130. package/dist/mcp/index.js +187 -0
  131. package/dist/mcp/jsonrpc.d.ts +8 -0
  132. package/dist/mcp/jsonrpc.js +1 -0
  133. package/dist/mcp/server.d.ts +107 -0
  134. package/dist/mcp/server.js +203 -0
  135. package/dist/mcp/tasks/manager.d.ts +63 -0
  136. package/dist/mcp/tasks/manager.js +103 -0
  137. package/dist/mcp/tools/agents.d.ts +2 -0
  138. package/dist/mcp/tools/agents.js +375 -0
  139. package/dist/mcp/tools/budget-groups.d.ts +2 -0
  140. package/dist/mcp/tools/budget-groups.js +136 -0
  141. package/dist/mcp/tools/datastore.d.ts +2 -0
  142. package/dist/mcp/tools/datastore.js +217 -0
  143. package/dist/mcp/tools/memory.d.ts +3 -0
  144. package/dist/mcp/tools/memory.js +60 -0
  145. package/dist/mcp/tools/models.d.ts +8 -0
  146. package/dist/mcp/tools/models.js +15 -0
  147. package/dist/mcp/tools/runs.d.ts +2 -0
  148. package/dist/mcp/tools/runs.js +61 -0
  149. package/dist/mcp/tools/scheduling.d.ts +2 -0
  150. package/dist/mcp/tools/scheduling.js +48 -0
  151. package/dist/mcp/tools/secret-elicitation-form.d.ts +22 -0
  152. package/dist/mcp/tools/secret-elicitation-form.js +93 -0
  153. package/dist/mcp/tools/secret-elicitation-server.d.ts +5 -0
  154. package/dist/mcp/tools/secret-elicitation-server.js +57 -0
  155. package/dist/mcp/tools/secret-elicitation.d.ts +38 -0
  156. package/dist/mcp/tools/secret-elicitation.js +52 -0
  157. package/dist/mcp/tools/secrets.d.ts +13 -0
  158. package/dist/mcp/tools/secrets.js +124 -0
  159. package/dist/mcp/tools/subagents.d.ts +2 -0
  160. package/dist/mcp/tools/subagents.js +133 -0
  161. package/dist/mcp/tools/text-result.d.ts +6 -0
  162. package/dist/mcp/tools/text-result.js +3 -0
  163. package/dist/mcp/tools/tools.d.ts +2 -0
  164. package/dist/mcp/tools/tools.js +211 -0
  165. package/dist/mcp/tools/trigger.d.ts +2 -0
  166. package/dist/mcp/tools/trigger.js +120 -0
  167. package/dist/mcp/tools/webhooks.d.ts +2 -0
  168. package/dist/mcp/tools/webhooks.js +34 -0
  169. package/dist/mcp/transport/http-limits.d.ts +17 -0
  170. package/dist/mcp/transport/http-limits.js +92 -0
  171. package/dist/mcp/transport/stdio.d.ts +23 -0
  172. package/dist/mcp/transport/stdio.js +6 -0
  173. package/dist/mcp/transport/streamable-http.d.ts +34 -0
  174. package/dist/mcp/transport/streamable-http.js +158 -0
  175. package/dist/mcp/unattended-schedules.d.ts +15 -0
  176. package/dist/mcp/unattended-schedules.js +21 -0
  177. package/dist/mcp/webhooks/ingress.d.ts +17 -0
  178. package/dist/mcp/webhooks/ingress.js +33 -0
  179. package/dist/observability/config.d.ts +6 -0
  180. package/dist/observability/config.js +20 -0
  181. package/dist/observability/metrics-server.d.ts +11 -0
  182. package/dist/observability/metrics-server.js +47 -0
  183. package/dist/observability/metrics.d.ts +36 -0
  184. package/dist/observability/metrics.js +158 -0
  185. package/dist/providers/auth/authorization-server.d.ts +41 -0
  186. package/dist/providers/auth/authorization-server.js +1 -0
  187. package/dist/providers/auth/delegating.d.ts +44 -0
  188. package/dist/providers/auth/delegating.js +105 -0
  189. package/dist/providers/auth/index.d.ts +11 -0
  190. package/dist/providers/auth/index.js +20 -0
  191. package/dist/providers/auth/release-gate.d.ts +1 -0
  192. package/dist/providers/auth/release-gate.js +4 -0
  193. package/dist/providers/auth/self-hosted.d.ts +78 -0
  194. package/dist/providers/auth/self-hosted.js +377 -0
  195. package/dist/providers/auth/subject.d.ts +1 -0
  196. package/dist/providers/auth/subject.js +6 -0
  197. package/dist/providers/auth/types.d.ts +63 -0
  198. package/dist/providers/auth/types.js +22 -0
  199. package/dist/providers/coding-proxy/deny-port.d.ts +5 -0
  200. package/dist/providers/coding-proxy/deny-port.js +45 -0
  201. package/dist/providers/coding-proxy/environment-credentials.d.ts +7 -0
  202. package/dist/providers/coding-proxy/environment-credentials.js +16 -0
  203. package/dist/providers/coding-proxy/index.d.ts +7 -0
  204. package/dist/providers/coding-proxy/index.js +7 -0
  205. package/dist/providers/coding-proxy/memory-ledger.d.ts +17 -0
  206. package/dist/providers/coding-proxy/memory-ledger.js +103 -0
  207. package/dist/providers/coding-proxy/metering.d.ts +20 -0
  208. package/dist/providers/coding-proxy/metering.js +161 -0
  209. package/dist/providers/coding-proxy/prisma-ledger.d.ts +15 -0
  210. package/dist/providers/coding-proxy/prisma-ledger.js +213 -0
  211. package/dist/providers/coding-proxy/proxy.d.ts +75 -0
  212. package/dist/providers/coding-proxy/proxy.js +721 -0
  213. package/dist/providers/coding-proxy/runtime.d.ts +18 -0
  214. package/dist/providers/coding-proxy/runtime.js +39 -0
  215. package/dist/providers/coding-proxy/secure-fetch.d.ts +9 -0
  216. package/dist/providers/coding-proxy/secure-fetch.js +72 -0
  217. package/dist/providers/coding-proxy/server.d.ts +17 -0
  218. package/dist/providers/coding-proxy/server.js +139 -0
  219. package/dist/providers/coding-proxy/types.d.ts +99 -0
  220. package/dist/providers/coding-proxy/types.js +1 -0
  221. package/dist/providers/datastore/index.d.ts +2 -0
  222. package/dist/providers/datastore/index.js +2 -0
  223. package/dist/providers/datastore/postgres.d.ts +20 -0
  224. package/dist/providers/datastore/postgres.js +130 -0
  225. package/dist/providers/datastore/scoped.d.ts +10 -0
  226. package/dist/providers/datastore/scoped.js +46 -0
  227. package/dist/providers/datastore/types.d.ts +31 -0
  228. package/dist/providers/datastore/types.js +7 -0
  229. package/dist/providers/email/types.d.ts +46 -0
  230. package/dist/providers/email/types.js +8 -0
  231. package/dist/providers/engine/index.d.ts +1 -0
  232. package/dist/providers/engine/index.js +1 -0
  233. package/dist/providers/engine/types.d.ts +67 -0
  234. package/dist/providers/engine/types.js +16 -0
  235. package/dist/providers/executor/build.d.ts +6 -0
  236. package/dist/providers/executor/build.js +15 -0
  237. package/dist/providers/executor/composition.d.ts +14 -0
  238. package/dist/providers/executor/composition.js +123 -0
  239. package/dist/providers/executor/container.d.ts +184 -0
  240. package/dist/providers/executor/container.js +936 -0
  241. package/dist/providers/executor/dbos-status.d.ts +50 -0
  242. package/dist/providers/executor/dbos-status.js +64 -0
  243. package/dist/providers/executor/dbos.d.ts +53 -0
  244. package/dist/providers/executor/dbos.js +269 -0
  245. package/dist/providers/executor/in-process.d.ts +18 -0
  246. package/dist/providers/executor/in-process.js +38 -0
  247. package/dist/providers/executor/index.d.ts +8 -0
  248. package/dist/providers/executor/index.js +8 -0
  249. package/dist/providers/executor/routing.d.ts +48 -0
  250. package/dist/providers/executor/routing.js +70 -0
  251. package/dist/providers/executor/types.d.ts +55 -0
  252. package/dist/providers/executor/types.js +1 -0
  253. package/dist/providers/index.d.ts +43 -0
  254. package/dist/providers/index.js +18 -0
  255. package/dist/providers/jobs/docker-isolation.d.ts +166 -0
  256. package/dist/providers/jobs/docker-isolation.js +724 -0
  257. package/dist/providers/jobs/docker.d.ts +127 -0
  258. package/dist/providers/jobs/docker.js +1027 -0
  259. package/dist/providers/jobs/fake-kubernetes-api.d.ts +98 -0
  260. package/dist/providers/jobs/fake-kubernetes-api.js +142 -0
  261. package/dist/providers/jobs/fake.d.ts +23 -0
  262. package/dist/providers/jobs/fake.js +132 -0
  263. package/dist/providers/jobs/kubernetes-api.d.ts +60 -0
  264. package/dist/providers/jobs/kubernetes-api.js +20 -0
  265. package/dist/providers/jobs/kubernetes-client.d.ts +36 -0
  266. package/dist/providers/jobs/kubernetes-client.js +171 -0
  267. package/dist/providers/jobs/kubernetes-dry-run-fixture.d.ts +49 -0
  268. package/dist/providers/jobs/kubernetes-dry-run-fixture.js +141 -0
  269. package/dist/providers/jobs/kubernetes-isolation.d.ts +147 -0
  270. package/dist/providers/jobs/kubernetes-isolation.js +607 -0
  271. package/dist/providers/jobs/kubernetes-platform.d.ts +177 -0
  272. package/dist/providers/jobs/kubernetes-platform.js +280 -0
  273. package/dist/providers/jobs/kubernetes-preflight.d.ts +59 -0
  274. package/dist/providers/jobs/kubernetes-preflight.js +339 -0
  275. package/dist/providers/jobs/kubernetes-witness.d.ts +10 -0
  276. package/dist/providers/jobs/kubernetes-witness.js +193 -0
  277. package/dist/providers/jobs/kubernetes.d.ts +127 -0
  278. package/dist/providers/jobs/kubernetes.js +874 -0
  279. package/dist/providers/jobs/safe-extract.d.ts +9 -0
  280. package/dist/providers/jobs/safe-extract.js +325 -0
  281. package/dist/providers/jobs/types.d.ts +78 -0
  282. package/dist/providers/jobs/types.js +6 -0
  283. package/dist/providers/jobs/workspace-swap.d.ts +2 -0
  284. package/dist/providers/jobs/workspace-swap.js +47 -0
  285. package/dist/providers/llm/anthropic.d.ts +13 -0
  286. package/dist/providers/llm/anthropic.js +21 -0
  287. package/dist/providers/llm/bedrock.d.ts +19 -0
  288. package/dist/providers/llm/bedrock.js +33 -0
  289. package/dist/providers/llm/claude-messages.d.ts +106 -0
  290. package/dist/providers/llm/claude-messages.js +157 -0
  291. package/dist/providers/llm/claude-provider.d.ts +40 -0
  292. package/dist/providers/llm/claude-provider.js +31 -0
  293. package/dist/providers/llm/index.d.ts +10 -0
  294. package/dist/providers/llm/index.js +10 -0
  295. package/dist/providers/llm/openai.d.ts +23 -0
  296. package/dist/providers/llm/openai.js +156 -0
  297. package/dist/providers/llm/pricing-anthropic.d.ts +4 -0
  298. package/dist/providers/llm/pricing-anthropic.js +30 -0
  299. package/dist/providers/llm/pricing-bedrock-claude.d.ts +12 -0
  300. package/dist/providers/llm/pricing-bedrock-claude.js +37 -0
  301. package/dist/providers/llm/pricing-core.d.ts +26 -0
  302. package/dist/providers/llm/pricing-core.js +17 -0
  303. package/dist/providers/llm/pricing.d.ts +30 -0
  304. package/dist/providers/llm/pricing.js +74 -0
  305. package/dist/providers/llm/registration.d.ts +8 -0
  306. package/dist/providers/llm/registration.js +39 -0
  307. package/dist/providers/llm/routing.d.ts +25 -0
  308. package/dist/providers/llm/routing.js +32 -0
  309. package/dist/providers/llm/types.d.ts +85 -0
  310. package/dist/providers/llm/types.js +12 -0
  311. package/dist/providers/memory/index.d.ts +2 -0
  312. package/dist/providers/memory/index.js +2 -0
  313. package/dist/providers/memory/postgres.d.ts +20 -0
  314. package/dist/providers/memory/postgres.js +72 -0
  315. package/dist/providers/memory/types.d.ts +32 -0
  316. package/dist/providers/memory/types.js +17 -0
  317. package/dist/providers/secrets/app-key.d.ts +8 -0
  318. package/dist/providers/secrets/app-key.js +50 -0
  319. package/dist/providers/secrets/index.d.ts +10 -0
  320. package/dist/providers/secrets/index.js +13 -0
  321. package/dist/providers/secrets/transfer-envelope.d.ts +12 -0
  322. package/dist/providers/secrets/transfer-envelope.js +35 -0
  323. package/dist/providers/secrets/types.d.ts +18 -0
  324. package/dist/providers/secrets/types.js +12 -0
  325. package/dist/providers/storage/types.d.ts +18 -0
  326. package/dist/providers/storage/types.js +7 -0
  327. package/dist/providers/vcs/git.d.ts +105 -0
  328. package/dist/providers/vcs/git.js +710 -0
  329. package/dist/providers/vcs/github.d.ts +105 -0
  330. package/dist/providers/vcs/github.js +394 -0
  331. package/dist/providers/vcs/index.d.ts +6 -0
  332. package/dist/providers/vcs/index.js +26 -0
  333. package/dist/providers/vcs/types.d.ts +118 -0
  334. package/dist/providers/vcs/types.js +1 -0
  335. package/dist/sandbox/bounded-json.d.ts +2 -0
  336. package/dist/sandbox/bounded-json.js +36 -0
  337. package/dist/sandbox/bridge.d.ts +15 -0
  338. package/dist/sandbox/bridge.js +78 -0
  339. package/dist/sandbox/eval-core.d.ts +37 -0
  340. package/dist/sandbox/eval-core.js +159 -0
  341. package/dist/sandbox/fetch-policy.d.ts +24 -0
  342. package/dist/sandbox/fetch-policy.js +96 -0
  343. package/dist/sandbox/generated/zod-to-json-schema.bundle.js +5 -0
  344. package/dist/sandbox/generated/zod.bundle.js +1 -0
  345. package/dist/sandbox/host-functions.d.ts +29 -0
  346. package/dist/sandbox/host-functions.js +168 -0
  347. package/dist/sandbox/limits.d.ts +39 -0
  348. package/dist/sandbox/limits.js +39 -0
  349. package/dist/sandbox/parser-worker/__fixtures__/crash.d.ts +1 -0
  350. package/dist/sandbox/parser-worker/__fixtures__/crash.js +6 -0
  351. package/dist/sandbox/parser-worker/__fixtures__/echo.d.ts +1 -0
  352. package/dist/sandbox/parser-worker/__fixtures__/echo.js +5 -0
  353. package/dist/sandbox/parser-worker/__fixtures__/reject.d.ts +1 -0
  354. package/dist/sandbox/parser-worker/__fixtures__/reject.js +5 -0
  355. package/dist/sandbox/parser-worker/__fixtures__/spin-forever.d.ts +1 -0
  356. package/dist/sandbox/parser-worker/__fixtures__/spin-forever.js +11 -0
  357. package/dist/sandbox/parser-worker/pool.d.ts +13 -0
  358. package/dist/sandbox/parser-worker/pool.js +111 -0
  359. package/dist/sandbox/parser-worker/worker.d.ts +14 -0
  360. package/dist/sandbox/parser-worker/worker.js +63 -0
  361. package/dist/sandbox/pii-redaction.d.ts +1 -0
  362. package/dist/sandbox/pii-redaction.js +29 -0
  363. package/dist/sandbox/prelude.d.ts +26 -0
  364. package/dist/sandbox/prelude.js +408 -0
  365. package/dist/sandbox/quickjs-module.d.ts +13 -0
  366. package/dist/sandbox/quickjs-module.js +19 -0
  367. package/dist/sandbox/run-in-sandbox.d.ts +34 -0
  368. package/dist/sandbox/run-in-sandbox.js +53 -0
  369. package/dist/sandbox/safe-fetch.d.ts +26 -0
  370. package/dist/sandbox/safe-fetch.js +140 -0
  371. package/dist/sandbox/tool-capabilities.d.ts +66 -0
  372. package/dist/sandbox/tool-capabilities.js +103 -0
  373. package/dist/sandbox/zod-params.d.ts +22 -0
  374. package/dist/sandbox/zod-params.js +60 -0
  375. package/dist/serve.d.ts +14 -0
  376. package/dist/serve.js +54 -0
  377. package/dist/wardby-bin.d.ts +2 -0
  378. package/dist/wardby-bin.js +20 -0
  379. package/package.json +123 -0
  380. package/prisma/migrations/20260905000000_init/migration.sql +34 -0
  381. package/prisma/migrations/20260905010000_scheduler_durability/migration.sql +31 -0
  382. package/prisma/migrations/20260905020000_tools_multiturn/migration.sql +47 -0
  383. package/prisma/migrations/20260905030000_cache_tool_json_schema/migration.sql +13 -0
  384. package/prisma/migrations/20260906000000_mcp_phase4/migration.sql +115 -0
  385. package/prisma/migrations/20260906010000_run_final_text/migration.sql +7 -0
  386. package/prisma/migrations/20260906020000_run_turns/migration.sql +6 -0
  387. package/prisma/migrations/20260906030000_task_principal_id/migration.sql +5 -0
  388. package/prisma/migrations/20260906040000_secure_self_hosted_oauth/migration.sql +67 -0
  389. package/prisma/migrations/20260906050000_phase5_coding_agents/migration.sql +52 -0
  390. package/prisma/migrations/20260906060000_tool_capability_scoping/migration.sql +22 -0
  391. package/prisma/migrations/20260906070000_datastore_pii_flag/migration.sql +6 -0
  392. package/prisma/migrations/20260906080000_secret_elicitation_outcomes/migration.sql +13 -0
  393. package/prisma/migrations/20260907010000_coding_proxy_ledger/migration.sql +57 -0
  394. package/prisma/migrations/20260907020000_budget_groups/migration.sql +24 -0
  395. package/prisma/migrations/20260907030000_coding_webhook_task_override/migration.sql +4 -0
  396. package/prisma/migrations/20260908010000_run_execution_backend/migration.sql +2 -0
  397. package/prisma/migrations/20260908020000_coding_run_audit_metadata/migration.sql +7 -0
  398. package/prisma/migrations/20260910010000_agent_secret_bound_name/migration.sql +16 -0
  399. package/prisma/migrations/20260911010000_coding_worker_toolchains/migration.sql +5 -0
  400. package/prisma/migrations/20260912010000_coding_provider_contract/migration.sql +24 -0
  401. package/prisma/migrations/20260912020000_coding_proxy_protocol/migration.sql +10 -0
  402. package/prisma/migrations/20260912030000_agent_memory/migration.sql +18 -0
  403. package/prisma/migrations/20260912040000_named_shared_datastores/migration.sql +68 -0
  404. package/prisma/migrations/20260913000000_run_trigger_webhook/migration.sql +2 -0
  405. package/prisma/migrations/20260913010000_agent_sub_agent/migration.sql +32 -0
  406. package/prisma/migrations/20260913020000_run_task_override/migration.sql +5 -0
  407. package/prisma/migrations/20260913030000_coding_run_root/migration.sql +11 -0
  408. package/prisma/migrations/20260922010000_coding_run_queued_at/migration.sql +8 -0
  409. package/prisma/migrations/20260922020000_coding_workspace_disk/migration.sql +8 -0
  410. package/prisma/migrations/migration_lock.toml +3 -0
  411. package/prisma/schema.prisma +723 -0
  412. package/scripts/git-askpass.sh +11 -0
@@ -0,0 +1,723 @@
1
+ // Hand-written per CLEANROOM.md — never generated from another project's
2
+ // schema. Targets PostgreSQL even for the laptop demo; "portable" means any
3
+ // Postgres (see deploy/local/docker-compose.yml), not a cloud dependency.
4
+
5
+ generator client {
6
+ provider = "prisma-client-js"
7
+ }
8
+
9
+ datasource db {
10
+ provider = "postgresql"
11
+ url = env("DATABASE_URL")
12
+ }
13
+
14
+ model Agent {
15
+ id String @id @default(cuid())
16
+ name String @unique
17
+ systemPrompt String
18
+ model String
19
+ budgetUsd Decimal @db.Decimal(10, 4)
20
+ createdAt DateTime @default(now())
21
+ updatedAt DateTime @updatedAt
22
+ runs Run[]
23
+ kind AgentKind @default(native)
24
+ codingProfile CodingAgentProfile?
25
+
26
+ // Phase 2: scheduling. `schedule` is a cron expression; null = manual-only.
27
+ schedule String?
28
+ timezone String @default("UTC")
29
+ scheduleEnabled Boolean @default(true)
30
+ /// Start of the most recent due window this agent was fired for.
31
+ lastScheduledAt DateTime?
32
+
33
+ // Phase 3: tools + multi-turn loop.
34
+ tools AgentTool[]
35
+ maxTurns Int @default(10)
36
+
37
+ // Phase 4: ownership. Null = public/unowned (pre-Phase-4 agents migrate this way).
38
+ ownerId String?
39
+ owner Principal? @relation(fields: [ownerId], references: [id])
40
+ secrets AgentSecret[]
41
+ datastores AgentDatastore[]
42
+ webhooks Webhook[]
43
+
44
+ // Phase 7: at most one budget group. Null = uncapped beyond its own budgetUsd.
45
+ budgetGroupId String?
46
+ budgetGroup BudgetGroup? @relation(fields: [budgetGroupId], references: [id])
47
+
48
+ /// Un-phased: gates the memory_get/memory_set/memory_list/memory_search
49
+ /// built-in tools (see AgentMemory below). Off by default — a memory-less
50
+ /// agent sees no memory tools at all, and no AgentMemory rows are ever
51
+ /// created for it.
52
+ memoryEnabled Boolean @default(false)
53
+
54
+ /// Un-phased: sub-agent composition edges (see AgentSubAgent below). An
55
+ /// agent can be a parent (has children it can delegate to) and/or a
56
+ /// child (is delegated to by others) independently.
57
+ subAgentEdgesAsParent AgentSubAgent[] @relation("SubAgentParent")
58
+ subAgentEdgesAsChild AgentSubAgent[] @relation("SubAgentChild")
59
+ }
60
+
61
+ /// Un-phased: agent-composition edge, referenced by agent name at the
62
+ /// import boundary (capabilities/subagents.json) but id-based here to
63
+ /// match that Tier-1 convention. Cycle-checked in the MCP tool handler at
64
+ /// creation time, not enforced by the database (Postgres has no native
65
+ /// "no cycles" constraint).
66
+ model AgentSubAgent {
67
+ parentAgentId String
68
+ childAgentId String
69
+ /// Local name the parent's dispatch tool is exposed under
70
+ /// (delegate_to_<boundName>) — decoupled from the child's own possibly-
71
+ /// renamed Agent.name, same convention as AgentDatastore.boundName.
72
+ boundName String
73
+ parent Agent @relation("SubAgentParent", fields: [parentAgentId], references: [id], onDelete: Cascade)
74
+ child Agent @relation("SubAgentChild", fields: [childAgentId], references: [id], onDelete: Cascade)
75
+
76
+ @@id([parentAgentId, childAgentId])
77
+ @@unique([parentAgentId, boundName])
78
+ }
79
+
80
+ /// Phase 7: an optional recurring spend cap across a group of agents,
81
+ /// layered on top of each agent's own per-run budgetUsd (which stays
82
+ /// required and unchanged). All three period caps are independently
83
+ /// optional -- unset means "no cap for that period." warnThresholdRatio
84
+ /// is per-group so different groups can choose their own early-warning
85
+ /// point; enforcement itself never lives here -- see
86
+ /// src/core/budget-groups.ts and runner.ts's executeRun, which turn a
87
+ /// group's remaining period budget into a tightened *effective* per-run
88
+ /// budget the existing engine budget machinery enforces unchanged.
89
+ model BudgetGroup {
90
+ id String @id @default(cuid())
91
+ name String
92
+ ownerId String?
93
+ owner Principal? @relation(fields: [ownerId], references: [id])
94
+ dailyBudgetUsd Decimal? @db.Decimal(10, 4)
95
+ weeklyBudgetUsd Decimal? @db.Decimal(10, 4)
96
+ monthlyBudgetUsd Decimal? @db.Decimal(10, 4)
97
+ warnThresholdRatio Decimal @default(0.8) @db.Decimal(3, 2)
98
+ createdAt DateTime @default(now())
99
+ updatedAt DateTime @updatedAt
100
+ agents Agent[]
101
+
102
+ @@unique([ownerId, name])
103
+ }
104
+
105
+ enum AgentKind {
106
+ native
107
+ coding
108
+ }
109
+
110
+ enum RunStatus {
111
+ pending
112
+ running
113
+ succeeded
114
+ failed
115
+ refused
116
+ /// Phase 2: orphaned by a dead executor, recovered by the reconciler.
117
+ lost
118
+ /// Phase 3: budget ran out mid-loop; graceful wind-down (or hard-stop)
119
+ /// already applied. Distinct from `refused` (turn-1, zero spend) and
120
+ /// `failed` (an actual error).
121
+ budget_exhausted
122
+ /// Phase 5: explicitly stopped by an authenticated caller.
123
+ cancelled
124
+ }
125
+
126
+ /// Phase 3: a WASM-sandboxed, Zod-validated tool a model can call.
127
+ model Tool {
128
+ id String @id @default(cuid())
129
+ name String @unique
130
+ description String
131
+ /// Zod schema *source text*; compiled and evaluated inside the sandbox,
132
+ /// never in the host process.
133
+ paramsZod String
134
+ /// JSON Schema derived from paramsZod at registration time (deriveJsonSchema)
135
+ /// and cached here — re-deriving it on every run would spin a fresh QuickJS
136
+ /// runtime and evaluate the whole vendored zod bundle per attached tool,
137
+ /// before the first LLM call, on every single run. Safe to cache because
138
+ /// there's no "update tool" path — paramsZod can't change without a new row.
139
+ jsonSchema Json
140
+ /// Tool body source; run inside the sandbox with the validated params.
141
+ code String
142
+ createdAt DateTime @default(now())
143
+ updatedAt DateTime @updatedAt
144
+ agents AgentTool[]
145
+
146
+ // Phase 4: ownership. Null = public/unowned.
147
+ ownerId String?
148
+ owner Principal? @relation(fields: [ownerId], references: [id])
149
+ }
150
+
151
+ /// Phase 3: explicit many-to-many join between Agent and Tool.
152
+ /// Phase 6: per-attachment capability scoping (OWASP LLM08 fix — Excessive
153
+ /// Agency). Empty array = no access to that resource class; a tool must be
154
+ /// explicitly granted secrets/datastore-prefixes/hosts at attach time. A
155
+ /// literal "*" element in allowedHosts lifts the fetch allowlist entirely
156
+ /// (existing SSRF protection against private/link-local addresses still
157
+ /// applies) — the back-compat escape hatch for pre-existing attachments and
158
+ /// deliberate full-web-access tools. See src/sandbox/tool-capabilities.ts.
159
+ model AgentTool {
160
+ agentId String
161
+ toolId String
162
+ agent Agent @relation(fields: [agentId], references: [id])
163
+ tool Tool @relation(fields: [toolId], references: [id])
164
+
165
+ allowedSecrets Json @default("[]")
166
+ allowedDatastorePrefixes Json @default("[]")
167
+ allowedHosts Json @default("[]")
168
+ allowedSharedDatastorePrefixes Json @default("{}")
169
+
170
+ @@id([agentId, toolId])
171
+ }
172
+
173
+ /// Named, owned resource shared across agents via AgentDatastore (Un-phased
174
+ /// roadmap item "Named / shared datastores"). Null ownerId = public/unowned,
175
+ /// matching Tool's convention.
176
+ model Datastore {
177
+ id String @id @default(cuid())
178
+ name String
179
+ ownerId String?
180
+ owner Principal? @relation(fields: [ownerId], references: [id])
181
+ agents AgentDatastore[]
182
+ entries DatastoreEntry[]
183
+ createdAt DateTime @default(now())
184
+ updatedAt DateTime @updatedAt
185
+
186
+ @@unique([ownerId, name])
187
+ }
188
+
189
+ /// Attaches a Datastore to an agent, addressed at sandbox point-of-use by
190
+ /// `boundName` (sharedDatastore.get(boundName, key)) — same boundName
191
+ /// convention as AgentSecret. Defaults to the datastore's own name.
192
+ model AgentDatastore {
193
+ agentId String
194
+ datastoreId String
195
+ boundName String
196
+ agent Agent @relation(fields: [agentId], references: [id])
197
+ datastore Datastore @relation(fields: [datastoreId], references: [id])
198
+
199
+ @@id([agentId, datastoreId])
200
+ @@unique([agentId, boundName])
201
+ }
202
+
203
+ /// Phase 3: the datastore seam's Postgres-backed default. Scoped by agentId
204
+ /// (private, per-agent) or datastoreId (shared, see Datastore above) — a row
205
+ /// carries exactly one, enforced by a hand-written CHECK in the migration
206
+ /// (Prisma has no declarative "exactly one of two columns" constraint).
207
+ /// Phase 6: optional per-entry PII encryption (see `pii`/`keyId` below).
208
+ ///
209
+ /// `id` is a surrogate key required by Prisma's schema validator: with
210
+ /// agentId and datastoreId both optional, neither `@@unique` below has an
211
+ /// all-required-fields criterion, and Prisma rejects a model with no such
212
+ /// criterion (P1012, "Each model must have at least one unique criteria
213
+ /// that has only required fields") — `prisma generate`/`validate` refuse to
214
+ /// run at all without it. Point lookups still go through the
215
+ /// agentId_key/datastoreId_key compound uniques; `id` is not otherwise used.
216
+ model DatastoreEntry {
217
+ id String @id @default(cuid())
218
+ agentId String?
219
+ datastoreId String?
220
+ key String
221
+ value Json
222
+ pii Boolean @default(false)
223
+ keyId String?
224
+ updatedAt DateTime @updatedAt
225
+ // onDelete: Restrict is explicit (Prisma's inferred default for an
226
+ // optional relation is SetNull) because the migration's FK is RESTRICT:
227
+ // nulling datastoreId on delete would leave both agentId and datastoreId
228
+ // null, violating the DatastoreEntry_scope_xor CHECK above.
229
+ datastore Datastore? @relation(fields: [datastoreId], references: [id], onDelete: Restrict)
230
+
231
+ @@unique([agentId, key])
232
+ @@unique([datastoreId, key])
233
+ }
234
+
235
+ /// Un-phased: agent-controlled persistent memory (key/content per agent),
236
+ /// gated by Agent.memoryEnabled. Deliberately a separate table rather than a
237
+ /// Datastore convention — memory has its own access surface (built-in
238
+ /// memory_get/memory_set/memory_list/memory_search tools, not user-authored
239
+ /// sandbox code) and its own full-text search index, which would be an odd
240
+ /// fit bolted onto Datastore's opaque-JSON-value shape. No FK to Agent,
241
+ /// matching DatastoreEntry: deleting an agent leaves orphaned rows today,
242
+ /// same pre-existing gap, not a new one.
243
+ ///
244
+ /// `contentTsv` is maintained by application code (see
245
+ /// PostgresAgentMemory.set), never a Postgres GENERATED column — a generated
246
+ /// column's expression has no representation in `Unsupported()`, which risks
247
+ /// the migration-vs-schema drift check (CLAUDE.md) never landing clean.
248
+ model AgentMemory {
249
+ agentId String
250
+ key String
251
+ content String
252
+ contentTsv Unsupported("tsvector")?
253
+ updatedAt DateTime @updatedAt
254
+
255
+ @@id([agentId, key])
256
+ @@index([contentTsv], type: Gin)
257
+ }
258
+
259
+ /// Phase 2: how a Run was created.
260
+ enum RunTrigger {
261
+ manual
262
+ scheduled
263
+ webhook
264
+ subagent
265
+ }
266
+
267
+ model Run {
268
+ id String @id @default(cuid())
269
+ agent Agent @relation(fields: [agentId], references: [id])
270
+ agentId String
271
+ status RunStatus @default(pending)
272
+ trigger RunTrigger @default(manual)
273
+ tokensIn Int @default(0)
274
+ tokensOut Int @default(0)
275
+ costUsd Decimal @default(0) @db.Decimal(10, 6)
276
+ error String?
277
+ startedAt DateTime @default(now())
278
+ finishedAt DateTime?
279
+ /// Phase 2: beaten by the executor while running; a stale value past
280
+ /// HEARTBEAT_TIMEOUT is how the reconciler finds an orphaned run.
281
+ heartbeatAt DateTime?
282
+ /// Phase 4: EngineResult.finalText, persisted so a Task (MCP) or later
283
+ /// inspection can read a completed run's answer. Previously only ever
284
+ /// streamed live via onText and dropped — no durable place to read it
285
+ /// from until this field existed.
286
+ finalText String?
287
+ /// Phase 4: EngineResult.turns, persisted for the same reason as
288
+ /// finalText — MCP's list_runs/get_run need it and it was previously
289
+ /// dropped after the engine returned.
290
+ turns Int @default(0)
291
+ /// Detached executors are recovered by handle rather than inferred from trigger.
292
+ executionManaged Boolean @default(false)
293
+ /// Phase 6: which durable executor backend holds this run, if any
294
+ /// ("dbos" = a DBOS workflow whose id equals this run's id). Null for
295
+ /// in-process runs. The reconciler consults the backend before declaring a
296
+ /// stale run lost, and can adopt one orphaned by a dead instance.
297
+ executionBackend String?
298
+ codingRun CodingRun?
299
+
300
+ /// Un-phased: sub-agent dispatch (see AgentSubAgent). Null for a
301
+ /// top-level run; set when this run was created by a parent run's
302
+ /// delegate_to_<boundName> tool call. The run tree rooted at the
303
+ /// top-level ancestor shares one real-time budget scope (see
304
+ /// src/core/budget-groups.ts's pattern, generalized from BudgetGroup
305
+ /// membership to this tree).
306
+ parentRunId String?
307
+ parentRun Run? @relation("RunTree", fields: [parentRunId], references: [id])
308
+ childRuns Run[] @relation("RunTree")
309
+ /// Ephemeral, per-dispatch grant: exactly the parent-memory keys this
310
+ /// one child run was handed permission to read via parent_memory_get.
311
+ /// Never a standing allowlist — re-granted on every dispatch call.
312
+ grantedParentMemoryKeys String[] @default([])
313
+ /// Per-run task text for a native agent, which otherwise has no
314
+ /// per-invocation input at all (only its fixed systemPrompt). Set only by
315
+ /// delegate_to_<boundName> dispatch today — never exposed as a public
316
+ /// trigger_agent/webhook parameter for native agents, unlike coding
317
+ /// agents' CodingTaskOverrideSchema. Appended (never prepended) to the
318
+ /// loaded systemPrompt at run time so the stable prefix stays
319
+ /// prompt-cache-eligible across dispatches.
320
+ taskOverride String?
321
+ }
322
+
323
+ /// Phase 5: owner-configured coding behavior. Runtime credentials and opaque
324
+ /// launcher handles never live on the reusable profile.
325
+ model CodingAgentProfile {
326
+ agentId String @id
327
+ agent Agent @relation(fields: [agentId], references: [id], onDelete: Cascade)
328
+ provider String @default("codex")
329
+ repository String
330
+ baseRef String @default("main")
331
+ defaultTask String?
332
+ allowWebhookTaskOverride Boolean @default(false)
333
+ timeoutSec Int @default(1800)
334
+ allowedEgress Json
335
+ protectedPaths Json
336
+ toolchain String @default("node")
337
+ toolchainVersion String?
338
+ workerImageRef String?
339
+ /// Per-agent workspace size in MiB; null = CODING_DISK_MB.
340
+ workspaceDiskMb Int?
341
+ }
342
+
343
+ /// Phase 5: immutable dispatch inputs plus opaque execution/result state for
344
+ /// one coding run. Policy is copied from the profile before work starts.
345
+ model CodingRun {
346
+ runId String @id
347
+ run Run @relation(fields: [runId], references: [id], onDelete: Cascade)
348
+ task String
349
+ repository String
350
+ baseRef String
351
+ headRef String
352
+ provider String
353
+ model String
354
+ timeoutSec Int
355
+ allowedEgress Json
356
+ protectedPaths Json
357
+ jobBackend String?
358
+ jobHandle String?
359
+ result Json?
360
+ resultSchema Int @default(1)
361
+ /// Sanitized terminal classification and an opaque log correlation reference.
362
+ /// Neither field may contain task, repository, environment, or credential data.
363
+ failureCategory String?
364
+ diagnosticId String?
365
+ workerImage String?
366
+ budgetReservedUsd Decimal @db.Decimal(10, 6)
367
+ /// Phase 12 concurrency queue: set when start() found every coding slot
368
+ /// taken (CODING_MAX_CONCURRENT), cleared when the run claims a slot. A
369
+ /// pending run with queuedAt set is waiting, not orphaned.
370
+ queuedAt DateTime?
371
+ /// Per-agent workspace size in MiB; null = CODING_DISK_MB.
372
+ workspaceDiskMb Int?
373
+ createdAt DateTime @default(now())
374
+ updatedAt DateTime @updatedAt
375
+ proxySession CodingProxySession?
376
+
377
+ /// Revision-in-place for continuing an existing coding pull request.
378
+ /// Points directly at the ROOT CodingRun that actually owns the branch/PR
379
+ /// this run's headRef reuses -- never a chain to "whichever run
380
+ /// immediately preceded this one." Deliberately not restricted to the
381
+ /// same agent: a plan run's PR can be continued by an implement run on
382
+ /// the same branch. Null means this run owns its own fresh branch/PR.
383
+ rootCodingRunId String?
384
+ rootCodingRun CodingRun? @relation("CodingRunContinuation", fields: [rootCodingRunId], references: [runId])
385
+ continuations CodingRun[] @relation("CodingRunContinuation")
386
+
387
+ @@index([jobBackend, jobHandle])
388
+ @@index([failureCategory])
389
+ @@index([queuedAt])
390
+ @@index([rootCodingRunId])
391
+ }
392
+
393
+ enum CodingProxySessionStatus {
394
+ active
395
+ cancelled
396
+ }
397
+
398
+ enum CodingProxyRequestStatus {
399
+ reserved
400
+ completed
401
+ released
402
+ uncertain
403
+ }
404
+
405
+ /// Trusted-boundary state for one coding run. Only a capability digest and an
406
+ /// upstream credential reference are persisted; neither secret value enters the DB.
407
+ model CodingProxySession {
408
+ id String @id @default(cuid())
409
+ runId String @unique
410
+ run CodingRun @relation(fields: [runId], references: [runId], onDelete: Cascade)
411
+ capabilityHash String @unique
412
+ credentialRef String
413
+ protocol String @default("openai-responses")
414
+ allowedModels Json
415
+ deadlineAt DateTime
416
+ budgetUsd Decimal @db.Decimal(18, 10)
417
+ status CodingProxySessionStatus @default(active)
418
+ createdAt DateTime @default(now())
419
+ updatedAt DateTime @updatedAt
420
+ requests CodingProxyRequest[]
421
+
422
+ @@index([deadlineAt])
423
+ }
424
+
425
+ /// Monotonic per-upstream-call ledger. Uncertain reservations remain held so a
426
+ /// crash or truncated provider stream can never create new spendable budget.
427
+ model CodingProxyRequest {
428
+ id String @id @default(cuid())
429
+ sessionId String
430
+ session CodingProxySession @relation(fields: [sessionId], references: [id], onDelete: Cascade)
431
+ requestKey String
432
+ requestFingerprint String
433
+ model String
434
+ status CodingProxyRequestStatus @default(reserved)
435
+ reservationUsd Decimal @db.Decimal(18, 10)
436
+ actualCostUsd Decimal? @db.Decimal(18, 10)
437
+ pricingVersion String
438
+ pricingSnapshot Json
439
+ inputTokens Int?
440
+ outputTokens Int?
441
+ cachedInputTokens Int?
442
+ cacheWriteTokens Int?
443
+ reasoningTokens Int?
444
+ upstreamStatus Int?
445
+ createdAt DateTime @default(now())
446
+ updatedAt DateTime @updatedAt
447
+ completedAt DateTime?
448
+
449
+ @@unique([sessionId, requestKey])
450
+ @@index([sessionId, status])
451
+ }
452
+
453
+ /// Phase 2: single-row-per-scope lease so exactly one scheduler process
454
+ /// ticks at a time. `holder` is a process instance id (crypto.randomUUID()).
455
+ model SchedulerLease {
456
+ scope String @id
457
+ holder String
458
+ expiresAt DateTime
459
+ updatedAt DateTime @updatedAt
460
+ }
461
+
462
+ /// Phase 4: an authenticated caller. `subject` is the IdP subject claim
463
+ /// (delegating mode) or the configured LOCAL_PRINCIPAL (stdio, no token).
464
+ /// Created on first sight (find-or-create by subject).
465
+ model Principal {
466
+ id String @id @default(cuid())
467
+ subject String @unique
468
+ createdAt DateTime @default(now())
469
+ agents Agent[]
470
+ tools Tool[]
471
+ secrets Secret[]
472
+ datastores Datastore[]
473
+ webhooks Webhook[]
474
+ authUser AuthUser?
475
+ budgetGroups BudgetGroup[]
476
+ }
477
+
478
+ /// Phase 4: durable handle backing both a triggered run and (reserved,
479
+ /// unused this phase) guided tool authoring. Persisted before the
480
+ /// tools/call response is returned, so a client's first tasks/get always
481
+ /// finds it.
482
+ enum TaskKind {
483
+ run
484
+ tool_authoring
485
+ }
486
+
487
+ enum TaskStatus {
488
+ working
489
+ input_required
490
+ completed
491
+ failed
492
+ cancelled
493
+ }
494
+
495
+ model Task {
496
+ id String @id @default(cuid())
497
+ kind TaskKind
498
+ runId String?
499
+ principalId String?
500
+ status TaskStatus @default(working)
501
+ inputRequests Json?
502
+ inputResponses Json?
503
+ result Json?
504
+ error Json?
505
+ ttlAt DateTime
506
+ createdAt DateTime @default(now())
507
+ updatedAt DateTime @updatedAt
508
+ }
509
+
510
+ /// Phase 4: a secret value, encrypted at rest via the SecretCipher seam.
511
+ /// `ciphertext` is opaque to Prisma; only the cipher's decrypt() ever
512
+ /// produces plaintext, and only at point-of-use inside the sandbox.
513
+ model Secret {
514
+ id String @id @default(cuid())
515
+ name String
516
+ ciphertext String
517
+ keyId String
518
+ ownerId String?
519
+ owner Principal? @relation(fields: [ownerId], references: [id])
520
+ createdAt DateTime @default(now())
521
+ updatedAt DateTime @updatedAt
522
+ agents AgentSecret[]
523
+
524
+ @@unique([ownerId, name])
525
+ }
526
+
527
+ /// Phase 4: attaches a secret to an agent, addressed at sandbox point-of-use
528
+ /// by `boundName` (secrets.get(boundName)). `boundName` defaults to the
529
+ /// secret's canonical name; it differs only when the agent binds the secret
530
+ /// under an alias, letting two agents resolve the same logical name to
531
+ /// different underlying secrets.
532
+ model AgentSecret {
533
+ agentId String
534
+ secretId String
535
+ boundName String
536
+ agent Agent @relation(fields: [agentId], references: [id])
537
+ secret Secret @relation(fields: [secretId], references: [id])
538
+
539
+ @@id([agentId, secretId])
540
+ @@unique([agentId, boundName])
541
+ }
542
+
543
+ /// Cross-instance persistence for the out-of-band secret-entry flow
544
+ /// (mcp/tools/secret-elicitation.ts) — was an in-process Map, which stranded
545
+ /// a browser-form submission on the wrong instance under a multi-instance
546
+ /// HTTP deployment. `outcome` holds the SecretElicitationOutcome JSON;
547
+ /// `expiresAt` mirrors the old TTL sweep, now a `DELETE WHERE expiresAt <=
548
+ /// now()` instead of a Map scan.
549
+ model SecretElicitationOutcome {
550
+ ownerId String
551
+ secretName String
552
+ outcome Json
553
+ expiresAt DateTime
554
+
555
+ @@id([ownerId, secretName])
556
+ }
557
+
558
+ enum WebhookStatus {
559
+ enabled
560
+ disabled
561
+ }
562
+
563
+ /// Phase 4: inbound trigger for an agent. `secretHash` is an HMAC/hash of
564
+ /// the validation secret shown to the caller once at creation; the raw
565
+ /// secret itself is never stored.
566
+ model Webhook {
567
+ id String @id @default(cuid())
568
+ agentId String
569
+ agent Agent @relation(fields: [agentId], references: [id])
570
+ secretHash String
571
+ status WebhookStatus @default(enabled)
572
+ ownerId String?
573
+ owner Principal? @relation(fields: [ownerId], references: [id])
574
+ createdAt DateTime @default(now())
575
+ lastFiredAt DateTime?
576
+
577
+ @@index([agentId])
578
+ }
579
+
580
+ /// Phase 4 (self-hosted AS only): a registered OAuth client. Created and
581
+ /// used only under AUTH_PROVIDER=self-hosted; the delegating adapter never
582
+ /// writes these tables even though the migration creates them unconditionally.
583
+ model OAuthClient {
584
+ clientId String @id
585
+ metadata Json
586
+ createdAt DateTime @default(now())
587
+ requests OAuthAuthorizationRequest[]
588
+ codes OAuthAuthorizationCode[]
589
+ families OAuthFamily[]
590
+ }
591
+
592
+ /// Phase 4 (self-hosted AS only): an issued authorization grant / refresh token.
593
+ model OAuthGrant {
594
+ id String @id
595
+ familyId String
596
+ family OAuthFamily @relation(fields: [familyId], references: [id], onDelete: Cascade)
597
+ refreshTokenHash String
598
+ expiresAt DateTime
599
+ createdAt DateTime @default(now())
600
+ consumedAt DateTime?
601
+ revokedAt DateTime?
602
+ replacedById String?
603
+
604
+ @@index([familyId])
605
+ @@index([expiresAt])
606
+ }
607
+
608
+ model AuthUser {
609
+ id String @id @default(cuid())
610
+ principalId String @unique
611
+ principal Principal @relation(fields: [principalId], references: [id])
612
+ displayName String?
613
+ status String @default("enabled")
614
+ createdAt DateTime @default(now())
615
+ updatedAt DateTime @updatedAt
616
+ loginKeys AuthLoginKey[]
617
+ sessions AuthSession[]
618
+ codes OAuthAuthorizationCode[]
619
+ families OAuthFamily[]
620
+ }
621
+
622
+ model AuthLoginKey {
623
+ keyId String @id
624
+ userId String
625
+ user AuthUser @relation(fields: [userId], references: [id], onDelete: Cascade)
626
+ secretHash String
627
+ createdAt DateTime @default(now())
628
+ lastUsedAt DateTime?
629
+ expiresAt DateTime
630
+ revokedAt DateTime?
631
+
632
+ @@index([userId])
633
+ @@index([expiresAt])
634
+ }
635
+
636
+ model AuthSession {
637
+ sessionId String @id
638
+ userId String
639
+ user AuthUser @relation(fields: [userId], references: [id], onDelete: Cascade)
640
+ secretHash String
641
+ createdAt DateTime @default(now())
642
+ lastSeenAt DateTime @default(now())
643
+ expiresAt DateTime
644
+ revokedAt DateTime?
645
+ challenges AuthFormChallenge[]
646
+
647
+ @@index([userId])
648
+ @@index([expiresAt])
649
+ }
650
+
651
+ model AuthFormChallenge {
652
+ challengeId String @id
653
+ sessionId String?
654
+ session AuthSession? @relation(fields: [sessionId], references: [sessionId], onDelete: Cascade)
655
+ purpose String
656
+ binding String
657
+ secretHash String
658
+ createdAt DateTime @default(now())
659
+ expiresAt DateTime
660
+ consumedAt DateTime?
661
+
662
+ @@index([expiresAt])
663
+ }
664
+
665
+ model OAuthAuthorizationRequest {
666
+ id String @id @default(cuid())
667
+ clientId String
668
+ client OAuthClient @relation(fields: [clientId], references: [clientId], onDelete: Cascade)
669
+ redirectUri String
670
+ resource String
671
+ requestedScope String
672
+ codeChallenge String
673
+ state String?
674
+ createdAt DateTime @default(now())
675
+ expiresAt DateTime
676
+ consumedAt DateTime?
677
+
678
+ @@index([expiresAt])
679
+ }
680
+
681
+ model OAuthAuthorizationCode {
682
+ codeId String @id
683
+ secretHash String
684
+ clientId String
685
+ client OAuthClient @relation(fields: [clientId], references: [clientId], onDelete: Cascade)
686
+ userId String
687
+ user AuthUser @relation(fields: [userId], references: [id], onDelete: Cascade)
688
+ redirectUri String
689
+ resource String
690
+ scope String
691
+ codeChallenge String
692
+ createdAt DateTime @default(now())
693
+ expiresAt DateTime
694
+ consumedAt DateTime?
695
+
696
+ @@index([expiresAt])
697
+ }
698
+
699
+ // The family row serializes refresh/revocation, including creation of replacements.
700
+ model OAuthFamily {
701
+ id String @id
702
+ clientId String
703
+ client OAuthClient @relation(fields: [clientId], references: [clientId], onDelete: Cascade)
704
+ userId String
705
+ user AuthUser @relation(fields: [userId], references: [id], onDelete: Cascade)
706
+ scope String
707
+ resource String
708
+ expiresAt DateTime
709
+ revokedAt DateTime?
710
+ createdAt DateTime @default(now())
711
+ grants OAuthGrant[]
712
+
713
+ @@index([userId])
714
+ @@index([expiresAt])
715
+ }
716
+
717
+ model AuthRateLimit {
718
+ key String @id
719
+ hits Int
720
+ expiresAt DateTime
721
+
722
+ @@index([expiresAt])
723
+ }