okengine 0.2.6 → 0.3.2

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 (681) hide show
  1. package/AGENTS.md +33 -30
  2. package/README.md +74 -340
  3. package/{spec/manifest.v1.schema.json → manifest.v1.schema.json} +40 -9
  4. package/package.json +47 -44
  5. package/site/content/docs/ai/llms-txt.mdx +54 -0
  6. package/site/content/docs/ai/mcp.mdx +123 -0
  7. package/site/content/docs/ai/meta.json +5 -0
  8. package/site/content/docs/ai/skills.mdx +53 -0
  9. package/site/content/docs/console/access.mdx +29 -0
  10. package/site/content/docs/console/ai.mdx +35 -0
  11. package/site/content/docs/console/architecture.mdx +35 -0
  12. package/site/content/docs/console/channels.mdx +37 -0
  13. package/site/content/docs/console/clock.mdx +31 -0
  14. package/site/content/docs/console/flows.mdx +31 -0
  15. package/site/content/docs/console/gates.mdx +35 -0
  16. package/site/content/docs/console/manifest-diff.mdx +34 -0
  17. package/site/content/docs/console/meta.json +23 -0
  18. package/site/content/docs/console/overview.mdx +40 -0
  19. package/site/content/docs/console/plugins.mdx +41 -0
  20. package/site/content/docs/console/privacy.mdx +32 -0
  21. package/site/content/docs/console/runs.mdx +40 -0
  22. package/site/content/docs/console/signals.mdx +31 -0
  23. package/site/content/docs/console/store.mdx +32 -0
  24. package/site/content/docs/console/tenancy.mdx +32 -0
  25. package/site/content/docs/console/traces.mdx +34 -0
  26. package/site/content/docs/console/vault.mdx +37 -0
  27. package/site/content/docs/elements/ai.mdx +180 -0
  28. package/site/content/docs/elements/channel.mdx +167 -0
  29. package/site/content/docs/elements/clock.mdx +182 -0
  30. package/site/content/docs/elements/flow.mdx +288 -0
  31. package/site/content/docs/elements/gate.mdx +171 -0
  32. package/site/content/docs/elements/meta.json +5 -0
  33. package/site/content/docs/elements/signal.mdx +171 -0
  34. package/site/content/docs/elements/store.mdx +320 -0
  35. package/site/content/docs/elements/vault.mdx +263 -0
  36. package/site/content/docs/get-started/basic-usage.mdx +124 -0
  37. package/site/content/docs/get-started/comparison.mdx +65 -0
  38. package/site/content/docs/get-started/installation.mdx +113 -0
  39. package/site/content/docs/get-started/introduction.mdx +123 -0
  40. package/site/content/docs/get-started/meta.json +5 -0
  41. package/site/content/docs/index.mdx +63 -0
  42. package/site/content/docs/meta.json +5 -0
  43. package/site/content/docs/plugins/compression.mdx +60 -0
  44. package/site/content/docs/plugins/cors.mdx +92 -0
  45. package/site/content/docs/plugins/csrf.mdx +96 -0
  46. package/site/content/docs/plugins/ip-allowlist.mdx +92 -0
  47. package/site/content/docs/plugins/maintenance-mode.mdx +101 -0
  48. package/site/content/docs/plugins/meta.json +15 -0
  49. package/site/content/docs/plugins/security-headers.mdx +136 -0
  50. package/site/content/docs/reference/cli.md +101 -0
  51. package/site/content/docs/reference/configuration.mdx +159 -0
  52. package/site/content/docs/reference/environment-variables.mdx +87 -0
  53. package/site/content/docs/reference/errors.mdx +80 -0
  54. package/site/content/docs/reference/fx.mdx +117 -0
  55. package/site/content/docs/reference/meta.json +5 -0
  56. package/site/content/docs/reference/plugins.mdx +249 -0
  57. package/site/content/docs/reference/security.md +63 -0
  58. package/src/auth/api-keys.ts +2 -5
  59. package/src/auth/attenuation.ts +2 -6
  60. package/src/auth/auth.test.ts +56 -31
  61. package/src/auth/invoke-as.ts +1 -3
  62. package/src/auth/operator.ts +8 -26
  63. package/src/auth/planes.ts +2 -7
  64. package/src/auth/plugin.ts +4 -7
  65. package/src/auth/roles.ts +1 -5
  66. package/src/auth/sessions.ts +10 -39
  67. package/src/cli/args.ts +1 -5
  68. package/src/cli/ask-dev-mode.ts +40 -0
  69. package/src/cli/build.ts +1 -2
  70. package/src/cli/client-add.test.ts +8 -15
  71. package/src/cli/client-add.ts +5 -14
  72. package/src/cli/completion.test.ts +1 -5
  73. package/src/cli/completion.ts +4 -17
  74. package/src/cli/db-auto-push.test.ts +64 -0
  75. package/src/cli/db-auto-push.ts +72 -0
  76. package/src/cli/db.test.ts +189 -0
  77. package/src/cli/db.ts +456 -0
  78. package/src/cli/dev-app-runner.ts +2 -8
  79. package/src/cli/dev-db-push.test.ts +193 -0
  80. package/src/cli/dev-mode.test.ts +45 -0
  81. package/src/cli/dev-mode.ts +78 -0
  82. package/src/cli/dev-schema-sync.test.ts +66 -0
  83. package/src/cli/dev-schema-sync.ts +139 -0
  84. package/src/cli/dev.test.ts +264 -15
  85. package/src/cli/dev.ts +355 -139
  86. package/src/cli/doc-staleness.test.ts +69 -0
  87. package/src/cli/docker-cli.test.ts +27 -8
  88. package/src/cli/docker.ts +11 -3
  89. package/src/cli/doctor-diff.test.ts +1 -5
  90. package/src/cli/doctor-diff.ts +17 -46
  91. package/src/cli/doctor-pii.ts +2 -7
  92. package/src/cli/doctor.test.ts +26 -4
  93. package/src/cli/doctor.ts +35 -11
  94. package/src/cli/drizzle-env.test.ts +67 -0
  95. package/src/cli/drizzle-env.ts +78 -0
  96. package/src/cli/ensure-drizzle-config.ts +50 -0
  97. package/src/cli/eval.ts +4 -14
  98. package/src/cli/gates-list.ts +1 -4
  99. package/src/cli/hero-meta.test.ts +17 -19
  100. package/src/cli/hero-meta.ts +20 -30
  101. package/src/cli/images.ts +3 -8
  102. package/src/cli/index.ts +11 -2
  103. package/src/cli/load-config.images.test.ts +14 -14
  104. package/src/cli/load-config.ts +47 -47
  105. package/src/cli/mcp-from-console.ts +1 -4
  106. package/src/cli/mode.ts +65 -0
  107. package/src/cli/openbao-bootstrap.test.ts +147 -0
  108. package/src/cli/openbao-bootstrap.ts +280 -0
  109. package/src/cli/openbao-restart.integration.test.ts +136 -0
  110. package/src/cli/ports.test.ts +7 -14
  111. package/src/cli/ports.ts +7 -5
  112. package/src/cli/privacy-erase.ts +1 -3
  113. package/src/cli/registry.ts +75 -25
  114. package/src/cli/resolve-dev-sql-env.test.ts +48 -0
  115. package/src/cli/resolve-dev-sql-env.ts +42 -0
  116. package/src/cli/schema.ts +3 -10
  117. package/src/cli/stack.ts +8 -10
  118. package/src/cli/start.ts +4 -15
  119. package/src/cli/upgrade.ts +1 -4
  120. package/src/cli/vault-cmd.ts +63 -0
  121. package/src/client/budget-entry.ts +1 -6
  122. package/src/client/create.test.ts +6 -12
  123. package/src/client/create.ts +2 -8
  124. package/src/client/errors.ts +1 -4
  125. package/src/client/index.ts +1 -6
  126. package/src/client/notes-contract.test.ts +4 -13
  127. package/src/client/transport.ts +9 -30
  128. package/src/client/types.ts +15 -30
  129. package/src/compiler/aot.test.ts +2 -9
  130. package/src/compiler/aot.ts +1 -4
  131. package/src/compiler/differential.test.ts +3 -11
  132. package/src/compiler/dynamic.ts +1 -4
  133. package/src/compiler/effects-infer.ts +8 -34
  134. package/src/compiler/emit.ts +1 -3
  135. package/src/compiler/extract.test.ts +136 -30
  136. package/src/compiler/extract.ts +485 -157
  137. package/src/compiler/fixtures/skyport/oke.config.ts +3 -3
  138. package/src/compiler/fixtures/skyport/src/flows/bookings/index.ts +7 -3
  139. package/src/compiler/fixtures/skyport/src/flows/payments/index.ts +1 -3
  140. package/src/compiler/fixtures/skyport/src/flows/support/index.ts +4 -1
  141. package/src/compiler/fixtures/skyport.expected.json +24 -83
  142. package/src/compiler/fixtures/triggers/five-triggers.ts +1 -2
  143. package/src/compiler/http-parse.ts +2 -9
  144. package/src/compiler/index.ts +1 -5
  145. package/src/compiler/response.ts +16 -7
  146. package/src/compiler/sucrose.ts +11 -31
  147. package/src/config/define-config.test.ts +55 -34
  148. package/src/config/index.ts +177 -46
  149. package/src/config/resolve-driver.test.ts +28 -17
  150. package/src/console/budget.test.ts +1 -4
  151. package/src/console/index.ts +1 -4
  152. package/src/console/server/access.test.ts +15 -43
  153. package/src/console/server/access.ts +19 -49
  154. package/src/console/server/ai.test.ts +3 -11
  155. package/src/console/server/ai.ts +23 -46
  156. package/src/console/server/app.ts +16 -45
  157. package/src/console/server/auth-rate.test.ts +4 -12
  158. package/src/console/server/bind.ts +1 -5
  159. package/src/console/server/channels.test.ts +2 -6
  160. package/src/console/server/channels.ts +10 -35
  161. package/src/console/server/claim.ts +2 -8
  162. package/src/console/server/clock.test.ts +2 -6
  163. package/src/console/server/clock.ts +8 -26
  164. package/src/console/server/console.test.ts +1 -3
  165. package/src/console/server/diff.test.ts +5 -17
  166. package/src/console/server/diff.ts +10 -31
  167. package/src/console/server/dry-run.audit.test.ts +2 -8
  168. package/src/console/server/flows.ts +64 -233
  169. package/src/console/server/gates.test.ts +14 -50
  170. package/src/console/server/gates.ts +13 -48
  171. package/src/console/server/index.ts +2 -9
  172. package/src/console/server/live.ts +3 -12
  173. package/src/console/server/operator-db.test.ts +4 -15
  174. package/src/console/server/operator-db.ts +13 -32
  175. package/src/console/server/plugin.ts +50 -53
  176. package/src/console/server/plugins.test.ts +2 -6
  177. package/src/console/server/plugins.ts +17 -56
  178. package/src/console/server/runs-pii.ts +2 -7
  179. package/src/console/server/security.gate.test.ts +18 -40
  180. package/src/console/server/serve.ts +10 -25
  181. package/src/console/server/signals.test.ts +1 -3
  182. package/src/console/server/signals.ts +17 -40
  183. package/src/console/server/state.ts +21 -59
  184. package/src/console/server/store.test.ts +20 -22
  185. package/src/console/server/store.ts +31 -76
  186. package/src/console/server/vault.test.ts +12 -29
  187. package/src/console/server/vault.ts +44 -66
  188. package/src/console/ui/access/AccessA11yView.tsx +6 -21
  189. package/src/console/ui/access/a11y.test.tsx +3 -12
  190. package/src/console/ui/access/acknowledgement.test.ts +1 -4
  191. package/src/console/ui/access/acknowledgement.ts +1 -3
  192. package/src/console/ui/access/blast-radius.ts +1 -3
  193. package/src/console/ui/access/confirmation.test.ts +1 -5
  194. package/src/console/ui/access/confirmation.ts +1 -4
  195. package/src/console/ui/access/fixture.ts +1 -5
  196. package/src/console/ui/access/grantable.test.ts +1 -3
  197. package/src/console/ui/access/grantable.ts +2 -7
  198. package/src/console/ui/access/index.ts +2 -9
  199. package/src/console/ui/access/provenance.test.ts +1 -3
  200. package/src/console/ui/access/provenance.ts +2 -6
  201. package/src/console/ui/access/search.test.ts +1 -5
  202. package/src/console/ui/access/search.ts +2 -6
  203. package/src/console/ui/ai/AiA11yView.tsx +6 -17
  204. package/src/console/ui/ai/a11y.test.tsx +2 -5
  205. package/src/console/ui/ai/fixture.ts +2 -7
  206. package/src/console/ui/ai/format.ts +1 -3
  207. package/src/console/ui/ai/group.test.ts +1 -3
  208. package/src/console/ui/ai/group.ts +4 -12
  209. package/src/console/ui/ai/index.ts +2 -9
  210. package/src/console/ui/ai/promotion.test.ts +2 -7
  211. package/src/console/ui/ai/promotion.ts +4 -13
  212. package/src/console/ui/ai/search.test.ts +2 -11
  213. package/src/console/ui/ai/search.ts +3 -13
  214. package/src/console/ui/ai/types.ts +1 -8
  215. package/src/console/ui/architecture/ArchitectureA11yView.tsx +8 -29
  216. package/src/console/ui/architecture/a11y.test.tsx +1 -2
  217. package/src/console/ui/architecture/declared.ts +1 -5
  218. package/src/console/ui/architecture/index.ts +7 -35
  219. package/src/console/ui/architecture/layout.ts +1 -3
  220. package/src/console/ui/architecture/pathologies.ts +10 -19
  221. package/src/console/ui/architecture/search.ts +6 -15
  222. package/src/console/ui/architecture/traffic.ts +4 -14
  223. package/src/console/ui/architecture/types.ts +2 -10
  224. package/src/console/ui/architecture/view.test.ts +7 -19
  225. package/src/console/ui/architecture/view.ts +9 -36
  226. package/src/console/ui/channels/ChannelsA11yView.tsx +4 -13
  227. package/src/console/ui/channels/a11y.test.tsx +1 -2
  228. package/src/console/ui/channels/confirmation.test.ts +1 -4
  229. package/src/console/ui/channels/confirmation.ts +1 -4
  230. package/src/console/ui/channels/findings.ts +1 -5
  231. package/src/console/ui/channels/index.ts +2 -8
  232. package/src/console/ui/channels/locale.test.ts +1 -3
  233. package/src/console/ui/channels/locale.ts +2 -8
  234. package/src/console/ui/channels/search.ts +4 -13
  235. package/src/console/ui/channels/taxonomy.ts +1 -3
  236. package/src/console/ui/clock/ClockA11yView.tsx +9 -26
  237. package/src/console/ui/clock/a11y.test.tsx +2 -5
  238. package/src/console/ui/clock/confirmation.test.ts +1 -3
  239. package/src/console/ui/clock/confirmation.ts +1 -4
  240. package/src/console/ui/clock/findings.ts +1 -4
  241. package/src/console/ui/clock/health.ts +2 -7
  242. package/src/console/ui/clock/index.ts +2 -10
  243. package/src/console/ui/clock/search.test.ts +1 -3
  244. package/src/console/ui/clock/search.ts +2 -6
  245. package/src/console/ui/clock/timeline.test.ts +1 -3
  246. package/src/console/ui/clock/waiting-on.test.ts +1 -5
  247. package/src/console/ui/clock/waiting-on.ts +2 -7
  248. package/src/console/ui/diff/DiffA11yView.tsx +8 -17
  249. package/src/console/ui/diff/a11y.test.tsx +2 -5
  250. package/src/console/ui/diff/group.test.ts +3 -13
  251. package/src/console/ui/diff/group.ts +2 -8
  252. package/src/console/ui/diff/index.ts +2 -8
  253. package/src/console/ui/diff/search.test.ts +1 -5
  254. package/src/console/ui/diff/search.ts +4 -16
  255. package/src/console/ui/diff/summary.ts +1 -2
  256. package/src/console/ui/dist/assets/{index-Dy4jht9P.js → index-BWo8R7NR.js} +2 -2
  257. package/src/console/ui/dist/assets/{panel-access-Dd37LU2c.js → panel-access-C0J2D-a2.js} +1 -1
  258. package/src/console/ui/dist/assets/{panel-ai-CC7LR6-J.js → panel-ai-D_m6WQI8.js} +1 -1
  259. package/src/console/ui/dist/assets/{panel-architecture-B5b3iKCz.js → panel-architecture-CKnXFyUx.js} +1 -1
  260. package/src/console/ui/dist/assets/{panel-channels-CeNjTKXp.js → panel-channels-BOmQ-onL.js} +1 -1
  261. package/src/console/ui/dist/assets/{panel-clock-DgFTLoHV.js → panel-clock-giAq0Ccv.js} +1 -1
  262. package/src/console/ui/dist/assets/{panel-diff-DxehccqB.js → panel-diff-cdonmH8c.js} +1 -1
  263. package/src/console/ui/dist/assets/{panel-flows-BtrVn-Eg.js → panel-flows-DlCU5zjA.js} +2 -2
  264. package/src/console/ui/dist/assets/{panel-gates-Z9MKRGdH.js → panel-gates-XclZxWD5.js} +1 -1
  265. package/src/console/ui/dist/assets/{panel-overview-Dt_AeXgd.js → panel-overview-BznEOTnb.js} +1 -1
  266. package/src/console/ui/dist/assets/{panel-plugins-DWd0TowH.js → panel-plugins-CcGM1g64.js} +1 -1
  267. package/src/console/ui/dist/assets/{panel-runs-DGstFHeq.js → panel-runs-CGWNHLR4.js} +1 -1
  268. package/src/console/ui/dist/assets/{panel-signals-DzEa2Fnt.js → panel-signals-CNywkdak.js} +1 -1
  269. package/src/console/ui/dist/assets/{panel-store-BJkbNgxx.js → panel-store-KmTbFHMH.js} +1 -1
  270. package/src/console/ui/dist/assets/{panel-traces-BaRVO3gM.js → panel-traces-DBLx2ilD.js} +1 -1
  271. package/src/console/ui/dist/assets/panel-vault-CEnFc0dk.js +1 -0
  272. package/src/console/ui/dist/index.html +1 -1
  273. package/src/console/ui/flows/FlowsA11yView.tsx +7 -22
  274. package/src/console/ui/flows/a11y.test.tsx +2 -8
  275. package/src/console/ui/flows/buffer.test.ts +3 -11
  276. package/src/console/ui/flows/buffer.ts +4 -11
  277. package/src/console/ui/flows/confirmation.ts +1 -3
  278. package/src/console/ui/flows/contract.test.ts +3 -7
  279. package/src/console/ui/flows/contract.ts +12 -36
  280. package/src/console/ui/flows/graph.test.ts +3 -11
  281. package/src/console/ui/flows/graph.ts +5 -15
  282. package/src/console/ui/flows/index.ts +1 -6
  283. package/src/console/ui/flows/save-as-test.ts +1 -3
  284. package/src/console/ui/flows/search.ts +8 -25
  285. package/src/console/ui/flows/tiers.ts +2 -9
  286. package/src/console/ui/gates/GatesA11yView.tsx +4 -13
  287. package/src/console/ui/gates/a11y.test.tsx +2 -5
  288. package/src/console/ui/gates/audit.ts +1 -3
  289. package/src/console/ui/gates/denial.test.ts +1 -3
  290. package/src/console/ui/gates/denial.ts +4 -12
  291. package/src/console/ui/gates/findings.ts +1 -3
  292. package/src/console/ui/gates/group.test.ts +3 -3
  293. package/src/console/ui/gates/group.ts +3 -11
  294. package/src/console/ui/gates/index.ts +2 -10
  295. package/src/console/ui/gates/search.ts +3 -10
  296. package/src/console/ui/overview/OverviewA11yView.tsx +9 -27
  297. package/src/console/ui/overview/a11y.test.tsx +1 -2
  298. package/src/console/ui/overview/busiest.ts +1 -3
  299. package/src/console/ui/overview/compose.ts +1 -13
  300. package/src/console/ui/overview/cost.ts +34 -38
  301. package/src/console/ui/overview/fixture.ts +21 -26
  302. package/src/console/ui/overview/golden.ts +4 -14
  303. package/src/console/ui/overview/index.ts +2 -9
  304. package/src/console/ui/overview/rank.test.ts +3 -10
  305. package/src/console/ui/overview/rank.ts +2 -7
  306. package/src/console/ui/overview/slo.test.ts +5 -9
  307. package/src/console/ui/overview/slo.ts +6 -23
  308. package/src/console/ui/overview/verdict.ts +3 -10
  309. package/src/console/ui/plugins/PluginsA11yView.tsx +8 -18
  310. package/src/console/ui/plugins/a11y.test.tsx +1 -2
  311. package/src/console/ui/plugins/fixture.ts +2 -4
  312. package/src/console/ui/plugins/group.test.ts +1 -3
  313. package/src/console/ui/plugins/group.ts +1 -6
  314. package/src/console/ui/plugins/index.ts +3 -13
  315. package/src/console/ui/plugins/search.ts +7 -19
  316. package/src/console/ui/runs/RunsA11yView.tsx +5 -20
  317. package/src/console/ui/runs/a11y.test.tsx +2 -5
  318. package/src/console/ui/runs/explain.ts +2 -6
  319. package/src/console/ui/runs/group.ts +3 -12
  320. package/src/console/ui/runs/histogram.test.ts +2 -11
  321. package/src/console/ui/runs/histogram.ts +1 -4
  322. package/src/console/ui/runs/index.ts +4 -18
  323. package/src/console/ui/runs/project.ts +2 -6
  324. package/src/console/ui/runs/query.test.ts +1 -3
  325. package/src/console/ui/runs/query.ts +12 -35
  326. package/src/console/ui/runs/search.ts +5 -19
  327. package/src/console/ui/runs/trace-link.test.ts +2 -6
  328. package/src/console/ui/runs/trace-link.ts +4 -16
  329. package/src/console/ui/runs/types.ts +1 -3
  330. package/src/console/ui/shell/App.tsx +2 -10
  331. package/src/console/ui/shell/client.ts +22 -115
  332. package/src/console/ui/shell/components/ui.tsx +1 -4
  333. package/src/console/ui/shell/layout/Shell.tsx +2 -4
  334. package/src/console/ui/shell/main.tsx +31 -96
  335. package/src/console/ui/shell/panels/access/AccessPanel.tsx +34 -98
  336. package/src/console/ui/shell/panels/ai/AiPanel.tsx +35 -106
  337. package/src/console/ui/shell/panels/architecture/ArchitecturePanel.tsx +18 -66
  338. package/src/console/ui/shell/panels/channels/ChannelsPanel.tsx +20 -57
  339. package/src/console/ui/shell/panels/clock/ClockPanel.tsx +22 -54
  340. package/src/console/ui/shell/panels/diff/DiffPanel.tsx +20 -61
  341. package/src/console/ui/shell/panels/flows/ContractEditor.tsx +6 -23
  342. package/src/console/ui/shell/panels/flows/FlowDrawer.tsx +13 -28
  343. package/src/console/ui/shell/panels/flows/FlowsPanel.tsx +9 -29
  344. package/src/console/ui/shell/panels/gates/GatesPanel.tsx +24 -80
  345. package/src/console/ui/shell/panels/overview/OverviewPanel.tsx +20 -58
  346. package/src/console/ui/shell/panels/plugins/PluginsPanel.tsx +16 -41
  347. package/src/console/ui/shell/panels/runs/RunsPanel.tsx +31 -99
  348. package/src/console/ui/shell/panels/signals/SignalsPanel.tsx +38 -101
  349. package/src/console/ui/shell/panels/store/StorePanel.tsx +27 -66
  350. package/src/console/ui/shell/panels/traces/TracesPanel.tsx +28 -89
  351. package/src/console/ui/shell/panels/vault/VaultPanel.tsx +22 -53
  352. package/src/console/ui/shell/setup/Wizard.tsx +3 -5
  353. package/src/console/ui/shell/styles.css +1 -2
  354. package/src/console/ui/signals/SignalsA11yView.tsx +9 -33
  355. package/src/console/ui/signals/a11y.test.tsx +2 -5
  356. package/src/console/ui/signals/confirmation.test.ts +1 -5
  357. package/src/console/ui/signals/confirmation.ts +2 -6
  358. package/src/console/ui/signals/dry-run.ts +1 -3
  359. package/src/console/ui/signals/durable.ts +1 -3
  360. package/src/console/ui/signals/findings.ts +1 -3
  361. package/src/console/ui/signals/group.test.ts +2 -8
  362. package/src/console/ui/signals/group.ts +2 -10
  363. package/src/console/ui/signals/index.ts +1 -4
  364. package/src/console/ui/signals/monitor.ts +2 -7
  365. package/src/console/ui/signals/schema-form.test.ts +3 -14
  366. package/src/console/ui/signals/schema-form.ts +1 -4
  367. package/src/console/ui/signals/search.ts +4 -13
  368. package/src/console/ui/store/StoreA11yView.tsx +3 -9
  369. package/src/console/ui/store/a11y.test.tsx +2 -5
  370. package/src/console/ui/store/confirmation.test.ts +1 -3
  371. package/src/console/ui/store/confirmation.ts +1 -4
  372. package/src/console/ui/store/dry-run.ts +2 -5
  373. package/src/console/ui/store/fixture.ts +1 -2
  374. package/src/console/ui/store/group.test.ts +1 -6
  375. package/src/console/ui/store/group.ts +1 -4
  376. package/src/console/ui/store/index.ts +1 -5
  377. package/src/console/ui/store/search.ts +2 -6
  378. package/src/console/ui/store/will-not-fire.ts +1 -2
  379. package/src/console/ui/traces/TracesA11yView.tsx +10 -29
  380. package/src/console/ui/traces/a11y.test.tsx +1 -2
  381. package/src/console/ui/traces/chain.test.ts +5 -19
  382. package/src/console/ui/traces/chain.ts +1 -3
  383. package/src/console/ui/traces/critical-path.test.ts +1 -3
  384. package/src/console/ui/traces/critical-path.ts +2 -6
  385. package/src/console/ui/traces/filter.test.ts +2 -6
  386. package/src/console/ui/traces/filter.ts +5 -13
  387. package/src/console/ui/traces/fold.test.ts +4 -12
  388. package/src/console/ui/traces/fold.ts +1 -3
  389. package/src/console/ui/traces/mini.ts +1 -3
  390. package/src/console/ui/traces/replay.test.ts +1 -3
  391. package/src/console/ui/traces/replay.ts +1 -3
  392. package/src/console/ui/traces/sampling.ts +1 -4
  393. package/src/console/ui/traces/search.ts +4 -17
  394. package/src/console/ui/traces/tier.ts +1 -3
  395. package/src/console/ui/vault/VaultA11yView.tsx +5 -17
  396. package/src/console/ui/vault/a11y.test.tsx +1 -2
  397. package/src/console/ui/vault/blast-radius.ts +1 -3
  398. package/src/console/ui/vault/confirmation.test.ts +1 -5
  399. package/src/console/ui/vault/confirmation.ts +1 -4
  400. package/src/console/ui/vault/dormant.test.ts +1 -4
  401. package/src/console/ui/vault/export-safe.test.ts +1 -5
  402. package/src/console/ui/vault/export-safe.ts +1 -4
  403. package/src/console/ui/vault/fixture.ts +3 -3
  404. package/src/console/ui/vault/group.ts +1 -2
  405. package/src/console/ui/vault/index.ts +2 -10
  406. package/src/console/ui/vault/search.ts +2 -6
  407. package/src/console/ui/vault/types.ts +1 -1
  408. package/src/console/xss.gate.test.ts +1 -3
  409. package/src/docker/compose.ts +215 -27
  410. package/src/docker/derive.ts +6 -14
  411. package/src/docker/docker.test.ts +118 -15
  412. package/src/docker/dockerfile.integration.test.ts +12 -21
  413. package/src/docker/helpers.ts +5 -4
  414. package/src/docker/index.ts +9 -6
  415. package/src/docker/pin.ts +1 -9
  416. package/src/docker/recipes/index.ts +6 -6
  417. package/src/docker/recipes/mailpit.ts +22 -0
  418. package/src/docker/recipes/openbao.ts +47 -0
  419. package/src/docker/recipes/postgres.ts +17 -6
  420. package/src/docker/recipes/redis.ts +11 -2
  421. package/src/docker/recipes/rustfs.ts +32 -0
  422. package/src/docker/stack-id.test.ts +73 -5
  423. package/src/docker/stack-id.ts +124 -33
  424. package/src/docker/stack.integration.test.ts +6 -21
  425. package/src/docker/stack.ts +36 -4
  426. package/src/docker/types.ts +16 -4
  427. package/src/docs-origin.ts +4 -4
  428. package/src/drivers/ai-anthropic.ts +5 -14
  429. package/src/drivers/ai-mock.ts +2 -5
  430. package/src/drivers/ai-openai-compatible.ts +4 -10
  431. package/src/drivers/ai-providers.test.ts +6 -13
  432. package/src/drivers/bun-native-completeness.test.ts +6 -15
  433. package/src/drivers/channel-console.ts +6 -7
  434. package/src/drivers/channel-fcm.ts +20 -30
  435. package/src/drivers/channel-resend.ts +1 -3
  436. package/src/drivers/channel-smtp.ts +2 -6
  437. package/src/drivers/channel-types.ts +2 -12
  438. package/src/drivers/channel-unifonic.ts +2 -6
  439. package/src/drivers/channel-wa-cloud.ts +2 -6
  440. package/src/drivers/channel-webpush.ts +21 -60
  441. package/src/drivers/conformance.test.ts +2 -10
  442. package/src/drivers/conformance.ts +8 -21
  443. package/src/drivers/drizzle-dialect.test.ts +20 -0
  444. package/src/drivers/drizzle-dialect.ts +37 -0
  445. package/src/drivers/fs.ts +2 -8
  446. package/src/drivers/index.ts +12 -57
  447. package/src/drivers/memory.ts +287 -75
  448. package/src/drivers/pgvector.ts +7 -11
  449. package/src/drivers/postgres.ts +7 -13
  450. package/src/drivers/redis.ts +13 -37
  451. package/src/drivers/s3.ts +15 -18
  452. package/src/drivers/signal-engine.ts +12 -49
  453. package/src/drivers/signal-memory.ts +2 -8
  454. package/src/drivers/signal-nats.ts +4 -9
  455. package/src/drivers/signal-postgres.ts +62 -129
  456. package/src/drivers/signal-redis.ts +7 -21
  457. package/src/drivers/signal-types.ts +1 -4
  458. package/src/drivers/sqlite.ts +3 -12
  459. package/src/drivers/types.ts +4 -23
  460. package/src/drivers/vault-driver-removal.test.ts +55 -0
  461. package/src/drivers/vault-env.ts +2 -6
  462. package/src/drivers/vault-infisical.ts +1 -5
  463. package/src/drivers/vault-managed.ts +1 -5
  464. package/src/drivers/vault-memory.ts +1 -5
  465. package/src/drivers/vault-openbao.test.ts +97 -0
  466. package/src/drivers/vault-openbao.ts +103 -40
  467. package/src/drivers/vault-types.ts +3 -16
  468. package/src/elements/ai/declare.ts +4 -14
  469. package/src/elements/ai/eval.ts +2 -6
  470. package/src/elements/ai/pii.ts +1 -3
  471. package/src/elements/ai/runtime.ts +12 -50
  472. package/src/elements/ai/schema.ts +4 -15
  473. package/src/elements/ai.test.ts +13 -24
  474. package/src/elements/ai.ts +1 -5
  475. package/src/elements/channel/consent.ts +3 -12
  476. package/src/elements/channel/costs.ts +4 -15
  477. package/src/elements/channel/declare.ts +1 -4
  478. package/src/elements/channel/email-auth.ts +1 -4
  479. package/src/elements/channel/locale.ts +2 -10
  480. package/src/elements/channel/mask.ts +1 -3
  481. package/src/elements/channel/mime.ts +2 -12
  482. package/src/elements/channel/outcomes.test.ts +1 -5
  483. package/src/elements/channel/outcomes.ts +5 -15
  484. package/src/elements/channel/receipts.ts +2 -7
  485. package/src/elements/channel/runtime.ts +28 -74
  486. package/src/elements/channel/suppression.ts +8 -14
  487. package/src/elements/channel.test.ts +8 -31
  488. package/src/elements/channel.ts +3 -14
  489. package/src/elements/clock/actions.ts +6 -18
  490. package/src/elements/clock/declare.ts +1 -3
  491. package/src/elements/clock/dst.ts +1 -5
  492. package/src/elements/clock/durable.ts +4 -16
  493. package/src/elements/clock/health.ts +2 -7
  494. package/src/elements/clock/leader.ts +2 -9
  495. package/src/elements/clock/reconcile.ts +4 -15
  496. package/src/elements/clock/runtime.ts +2 -5
  497. package/src/elements/clock/schedule.ts +4 -20
  498. package/src/elements/clock.test.ts +2 -7
  499. package/src/elements/clock.ts +5 -23
  500. package/src/elements/gate/permissions.ts +1 -4
  501. package/src/elements/gate/runtime.ts +7 -28
  502. package/src/elements/gate.ts +1 -5
  503. package/src/elements/index.ts +9 -7
  504. package/src/elements/signal/declare.ts +2 -7
  505. package/src/elements/signal/reconcile.test.ts +1 -4
  506. package/src/elements/signal/runtime.ts +1 -3
  507. package/src/elements/signal.test.ts +3 -15
  508. package/src/elements/signal.ts +2 -8
  509. package/src/elements/store/cache.test.ts +46 -0
  510. package/src/elements/store/cache.ts +3 -11
  511. package/src/elements/store/classify.ts +5 -22
  512. package/src/elements/store/declare.ts +11 -17
  513. package/src/elements/store/domain-ddl.test.ts +86 -0
  514. package/src/elements/store/emit-drizzle.ts +363 -0
  515. package/src/elements/store/files-policy.test.ts +1 -5
  516. package/src/elements/store/files-policy.ts +4 -12
  517. package/src/elements/store/load-plugin-tables.ts +103 -0
  518. package/src/elements/store/missing-relation.test.ts +83 -0
  519. package/src/elements/store/missing-relation.ts +38 -0
  520. package/src/elements/store/replica.ts +1 -4
  521. package/src/elements/store/resource-list-docs.fixture.ts +56 -0
  522. package/src/elements/store/resource-list-docs.test.ts +79 -0
  523. package/src/elements/store/resource.test.ts +253 -0
  524. package/src/elements/store/resource.ts +786 -0
  525. package/src/elements/store/runtime.ts +25 -28
  526. package/src/elements/store/schema-decl.test.ts +227 -0
  527. package/src/elements/store/schema-decl.ts +516 -0
  528. package/src/elements/store/sql-condition.test.ts +132 -0
  529. package/src/elements/store/sql-condition.ts +293 -65
  530. package/src/elements/store/sql-session.test.ts +135 -0
  531. package/src/elements/store/sql-session.ts +241 -84
  532. package/src/elements/store/table.ts +69 -23
  533. package/src/elements/store.test.ts +17 -39
  534. package/src/elements/store.ts +53 -31
  535. package/src/elements/vault/chain.ts +34 -0
  536. package/src/elements/vault/declare.ts +22 -32
  537. package/src/elements/vault/fingerprint.ts +2 -7
  538. package/src/elements/vault/redact.ts +2 -6
  539. package/src/elements/vault/runtime.ts +19 -33
  540. package/src/elements/vault.test.ts +12 -55
  541. package/src/elements/vault.ts +9 -13
  542. package/src/index.ts +5 -2
  543. package/src/kernel/adopt-routes.ts +15 -29
  544. package/src/kernel/app.ts +92 -118
  545. package/src/kernel/auth-resolve.ts +2 -9
  546. package/src/kernel/boot-bind/ai.ts +1 -4
  547. package/src/kernel/boot-bind/channel.test.ts +60 -0
  548. package/src/kernel/boot-bind/channel.ts +61 -5
  549. package/src/kernel/boot-bind/clock.ts +2 -6
  550. package/src/kernel/boot-bind/gate.ts +2 -8
  551. package/src/kernel/boot-bind/runs.ts +1 -3
  552. package/src/kernel/boot-bind/signal.ts +3 -10
  553. package/src/kernel/boot-bind/store.test.ts +27 -18
  554. package/src/kernel/boot-bind/store.ts +93 -52
  555. package/src/kernel/boot-bind/vault.ts +2 -8
  556. package/src/kernel/boot.test.ts +4 -10
  557. package/src/kernel/boot.ts +30 -77
  558. package/src/kernel/budget.test.ts +1 -3
  559. package/src/kernel/capability.ts +3 -10
  560. package/src/kernel/dry-run.test.ts +1 -4
  561. package/src/kernel/dry-run.ts +3 -11
  562. package/src/kernel/edge.test.ts +68 -0
  563. package/src/kernel/effects.test.ts +1 -5
  564. package/src/kernel/effects.ts +4 -11
  565. package/src/kernel/errors.registry.test.ts +2 -8
  566. package/src/kernel/errors.ts +23 -32
  567. package/src/kernel/flow.test.ts +12 -25
  568. package/src/kernel/flow.ts +13 -25
  569. package/src/kernel/fx.test.ts +31 -40
  570. package/src/kernel/fx.ts +135 -90
  571. package/src/kernel/hook-timing.test.ts +3 -6
  572. package/src/kernel/hook-timing.ts +5 -14
  573. package/src/kernel/hooks.test.ts +43 -10
  574. package/src/kernel/hooks.ts +25 -12
  575. package/src/kernel/index.ts +11 -17
  576. package/src/kernel/journal.ts +7 -31
  577. package/src/kernel/on.ts +45 -9
  578. package/src/kernel/pipeline.test.ts +10 -19
  579. package/src/kernel/pipeline.ts +5 -17
  580. package/src/kernel/plug.ts +4 -11
  581. package/src/kernel/plugin/conflicts.test.ts +13 -25
  582. package/src/kernel/plugin/decorate.test.ts +8 -13
  583. package/src/kernel/plugin/scoping.test.ts +4 -11
  584. package/src/kernel/plugin.ts +81 -27
  585. package/src/kernel/registry-isolation.test.ts +74 -0
  586. package/src/kernel/registry.ts +102 -30
  587. package/src/kernel/router.test.ts +15 -13
  588. package/src/kernel/router.ts +9 -29
  589. package/src/kernel/routing-budget.test.ts +1 -3
  590. package/src/kernel/run-telemetry.ts +1 -3
  591. package/src/kernel/triggers.ts +63 -21
  592. package/src/manifest/diff.test.ts +26 -91
  593. package/src/manifest/diff.ts +95 -225
  594. package/src/manifest/fixtures/skyport.excerpt.json +1 -1
  595. package/src/manifest/fixtures/skyport.manifest.json +1 -1
  596. package/src/manifest/index.ts +3 -10
  597. package/src/manifest/types.ts +30 -6
  598. package/src/manifest/undeclared.test.ts +4 -12
  599. package/src/manifest/undeclared.ts +1 -2
  600. package/src/manifest/validate.test.ts +2 -6
  601. package/src/manifest/validate.ts +5 -15
  602. package/src/mcp/authorization.ts +8 -27
  603. package/src/mcp/confirmation.ts +3 -10
  604. package/src/mcp/data.ts +2 -6
  605. package/src/mcp/docs-index.ts +4 -7
  606. package/src/mcp/docs-mcp.test.ts +3 -12
  607. package/src/mcp/docs-server.ts +7 -27
  608. package/src/mcp/docs-tools.ts +2 -6
  609. package/src/mcp/index.ts +1 -6
  610. package/src/mcp/injection.gate.test.ts +4 -18
  611. package/src/mcp/mcp.test.ts +18 -49
  612. package/src/mcp/protocol.ts +3 -10
  613. package/src/mcp/server.ts +11 -52
  614. package/src/mcp/session.ts +4 -14
  615. package/src/mcp/tools.ts +14 -50
  616. package/src/plugins/catalogue.test.ts +3 -7
  617. package/src/plugins/catalogue.ts +1 -3
  618. package/src/plugins/compression.test.ts +127 -0
  619. package/src/plugins/compression.ts +94 -0
  620. package/src/plugins/config-source.test.ts +204 -0
  621. package/src/plugins/config-source.ts +209 -0
  622. package/src/plugins/cors.test.ts +138 -0
  623. package/src/plugins/cors.ts +129 -0
  624. package/src/plugins/csrf.test.ts +102 -0
  625. package/src/plugins/csrf.ts +86 -0
  626. package/src/plugins/headers.ts +54 -0
  627. package/src/plugins/index.ts +26 -0
  628. package/src/plugins/ip-allowlist.test.ts +105 -0
  629. package/src/plugins/ip-allowlist.ts +76 -0
  630. package/src/plugins/maintenance-mode.test.ts +91 -0
  631. package/src/plugins/maintenance-mode.ts +85 -0
  632. package/src/plugins/node-import-scan.ts +2 -5
  633. package/src/plugins/security-headers.test.ts +243 -0
  634. package/src/plugins/security-headers.ts +255 -0
  635. package/src/plugins/supply-chain.ts +5 -17
  636. package/src/release/exports.ts +3 -8
  637. package/src/release/measure.exports.test.ts +1 -3
  638. package/src/release/measure.ts +16 -45
  639. package/src/runs/bench.test.ts +1 -3
  640. package/src/runs/collect.ts +8 -25
  641. package/src/runs/drivers/clickhouse.ts +2 -9
  642. package/src/runs/drivers/files.ts +9 -31
  643. package/src/runs/drivers/memory.ts +5 -22
  644. package/src/runs/drivers/postgres.ts +8 -20
  645. package/src/runs/duckdb.ts +2 -8
  646. package/src/runs/index.ts +3 -14
  647. package/src/runs/outlier.ts +3 -10
  648. package/src/runs/parquet.ts +8 -26
  649. package/src/runs/privacy.ts +2 -8
  650. package/src/runs/runs.test.ts +3 -9
  651. package/src/runs/runtime.ts +7 -32
  652. package/src/runs/shred.ts +10 -29
  653. package/src/runs/types.ts +1 -4
  654. package/src/runtime/bun.ts +4 -15
  655. package/src/runtime/cold-start.bench.ts +1 -3
  656. package/src/runtime/dev-request-log.test.ts +1 -4
  657. package/src/runtime/dev-request-log.ts +1 -4
  658. package/src/runtime/index.ts +1 -6
  659. package/src/runtime/primitives.ts +5 -4
  660. package/src/runtime/security.ts +3 -13
  661. package/src/runtime/serve.test.ts +4 -7
  662. package/src/runtime/types.ts +1 -4
  663. package/src/runtime/web-standard.ts +3 -15
  664. package/src/term.test.ts +4 -6
  665. package/src/term.ts +49 -98
  666. package/src/test/create-test-app.test.ts +4 -14
  667. package/src/test/create-test-app.ts +27 -33
  668. package/src/test/provisions.integration.test.ts +3 -11
  669. package/src/upgrade/codemods.test.ts +25 -6
  670. package/src/upgrade/codemods.ts +116 -3
  671. package/src/validation/standard-schema.test.ts +2 -5
  672. package/src/validation/standard-schema.ts +13 -33
  673. package/docs/spec/console.md +0 -739
  674. package/docs/spec/example.md +0 -1196
  675. package/docs/spec/four-applications.md +0 -1195
  676. package/docs/spec/unified-theory.md +0 -489
  677. package/src/cli/doc-drift.test.ts +0 -146
  678. package/src/cli/doc-drift.ts +0 -430
  679. package/src/cli/doctor-diff-examples.ts +0 -92
  680. package/src/console/ui/dist/assets/panel-vault-BbfWdox0.js +0 -1
  681. package/src/drivers/vault-sops.ts +0 -271
@@ -0,0 +1,189 @@
1
+ /**
2
+ * `oke db` CLI wrappers.
3
+ */
4
+
5
+ import { describe, expect, test } from "bun:test";
6
+ import { mkdir, mkdtemp, readFile, writeFile } from "node:fs/promises";
7
+ import { tmpdir } from "node:os";
8
+ import { join, resolve } from "node:path";
9
+ import { EXIT_OK, EXIT_RUNTIME } from "./exit.ts";
10
+ import { dbCli, emitAbstractSchemaPrestep, runDb, runGenerate, runPush } from "./db.ts";
11
+
12
+ /** Repo public entry — absolute import so temp apps need no install. */
13
+ const OKE_INDEX = resolve(import.meta.dir, "../index.ts");
14
+ const CONFIG_MOD = resolve(import.meta.dir, "../config/index.ts");
15
+
16
+ describe("oke db", () => {
17
+ test("help lists subcommands", async () => {
18
+ const lines: string[] = [];
19
+ const orig = console.log;
20
+ console.log = (msg?: unknown) => {
21
+ lines.push(String(msg ?? ""));
22
+ };
23
+ try {
24
+ const code = await dbCli(["--help"]);
25
+ expect(code).toBe(EXIT_OK);
26
+ expect(lines.join("\n")).toContain("push");
27
+ expect(lines.join("\n")).toContain("generate");
28
+ expect(lines.join("\n")).toContain("migrate");
29
+ expect(lines.join("\n")).toContain("oke schema generate");
30
+ } finally {
31
+ console.log = orig;
32
+ }
33
+ });
34
+
35
+ test("push reports ok / no_changes via injectable", async () => {
36
+ const out: string[] = [];
37
+ const code = await runPush("/tmp/drizzle.config.ts", (t) => out.push(t), {
38
+ pushFn: async () => ({ status: "no_changes" }),
39
+ skipEmit: true,
40
+ });
41
+ expect(code).toBe(EXIT_OK);
42
+ expect(out.join("")).toContain("no_changes");
43
+ });
44
+
45
+ test("generate surfaces migration_path", async () => {
46
+ const out: string[] = [];
47
+ const code = await runGenerate("/tmp/drizzle.config.ts", (t) => out.push(t), {
48
+ generateFn: async () => ({
49
+ status: "ok",
50
+ migration_path: "/tmp/drizzle/0001_init.sql",
51
+ }),
52
+ skipEmit: true,
53
+ });
54
+ expect(code).toBe(EXIT_OK);
55
+ expect(out.join("")).toContain("0001_init.sql");
56
+ });
57
+
58
+ test("missing_hints exits runtime", async () => {
59
+ const code = await runDb("push", {
60
+ pushFn: async () => ({ status: "missing_hints", unresolved: [] }),
61
+ write: () => {},
62
+ skipEmit: true,
63
+ });
64
+ expect(code).toBe(EXIT_RUNTIME);
65
+ });
66
+
67
+ test("resolveDrizzleConfigPath uses db.config from oke.config", async () => {
68
+ const dir = await mkdtemp(join(tmpdir(), "oke-db-"));
69
+ await writeFile(
70
+ join(dir, "oke.config.ts"),
71
+ `import { defineConfig } from ${JSON.stringify(CONFIG_MOD)};
72
+ export default defineConfig({ db: { config: "custom.drizzle.ts" } });
73
+ `,
74
+ );
75
+ const { resolveDrizzleConfigPath } = await import("./db.ts");
76
+ const path = await resolveDrizzleConfigPath(dir);
77
+ expect(path.endsWith("custom.drizzle.ts")).toBe(true);
78
+ });
79
+ });
80
+
81
+ describe("oke db emit — live plugged plugin tables", () => {
82
+ /**
83
+ * End-to-end: real oke().plug() app + schema.decl + runDb("push") must write
84
+ * the plugin's field.* table into schema.generated.ts. Not a unit merge call.
85
+ */
86
+ test("push emits plugin field.* table into schema.generated.ts", async () => {
87
+ const dir = await mkdtemp(join(tmpdir(), "oke-db-plugin-emit-"));
88
+ await mkdir(join(dir, "src"), { recursive: true });
89
+
90
+ await writeFile(
91
+ join(dir, "oke.config.ts"),
92
+ `import { defineConfig } from ${JSON.stringify(CONFIG_MOD)};
93
+ export default defineConfig({
94
+ drivers: { store: { sql: { local: "sqlite", test: "memory", prod: "postgres" } } },
95
+ db: { declare: "src/schema.decl.ts", generated: "src/schema.generated.ts" },
96
+ });
97
+ `,
98
+ );
99
+
100
+ await writeFile(
101
+ join(dir, "src", "schema.decl.ts"),
102
+ `import { store, field, id } from ${JSON.stringify(OKE_INDEX)};
103
+ export const notes = store.schema.table("notes", {
104
+ id: field.text().primaryKey().defaultFn(id),
105
+ title: field.text().notNull(),
106
+ });
107
+ `,
108
+ );
109
+
110
+ await writeFile(
111
+ join(dir, "src", "app.ts"),
112
+ `import { oke, plugin, field, id } from ${JSON.stringify(OKE_INDEX)};
113
+
114
+ const audit = plugin("audit", { version: "1.0.0" }).table("audit_events", {
115
+ id: field.text().primaryKey().defaultFn(id),
116
+ actorId: field.text().notNull().pii(),
117
+ action: field.text().notNull(),
118
+ });
119
+
120
+ export const app = oke({ name: "plugin-emit" }).plug(audit);
121
+ `,
122
+ );
123
+
124
+ await writeFile(
125
+ join(dir, "drizzle.config.ts"),
126
+ `import { defineConfig } from "drizzle-kit";
127
+ export default defineConfig({
128
+ dialect: "sqlite",
129
+ schema: "./src/schema.generated.ts",
130
+ out: "./drizzle",
131
+ dbCredentials: { url: "file:./local.db" },
132
+ });
133
+ `,
134
+ );
135
+
136
+ const out: string[] = [];
137
+ const code = await runDb("push", {
138
+ cwd: dir,
139
+ write: (t) => out.push(t),
140
+ pushFn: async () => ({ status: "no_changes" }),
141
+ // Real emit path — do not skip; kit is mocked after emit.
142
+ });
143
+
144
+ expect(code).toBe(EXIT_OK);
145
+ expect(out.join("")).toMatch(/emitted.*schema\.generated\.ts/);
146
+
147
+ const generated = await readFile(join(dir, "src", "schema.generated.ts"), "utf8");
148
+ expect(generated).toContain('sqliteTable("notes"');
149
+ expect(generated).toContain('sqliteTable("audit_events"');
150
+ expect(generated).toContain('text("actor_id")');
151
+ expect(generated).toContain('text("action")');
152
+ expect(generated).toContain(".notNull()");
153
+ });
154
+
155
+ test("emitAbstractSchemaPrestep loads plugin tables from app entry alone", async () => {
156
+ const dir = await mkdtemp(join(tmpdir(), "oke-db-plugin-only-"));
157
+ await mkdir(join(dir, "src"), { recursive: true });
158
+
159
+ await writeFile(
160
+ join(dir, "oke.config.ts"),
161
+ `import { defineConfig } from ${JSON.stringify(CONFIG_MOD)};
162
+ export default defineConfig({
163
+ drivers: { store: { sql: { local: "sqlite" } } },
164
+ });
165
+ `,
166
+ );
167
+
168
+ await writeFile(
169
+ join(dir, "src", "app.ts"),
170
+ `import { oke, plugin, field } from ${JSON.stringify(OKE_INDEX)};
171
+ export const app = oke({ name: "plugin-only" }).plug(
172
+ plugin("metrics", { version: "1.0.0" }).table("metrics_daily", {
173
+ day: field.text().primaryKey(),
174
+ hits: field.integer().notNull().default(0),
175
+ }),
176
+ );
177
+ `,
178
+ );
179
+
180
+ const { loadOkeConfig } = await import("./load-config.ts");
181
+ const loaded = await loadOkeConfig(dir);
182
+ const emitted = await emitAbstractSchemaPrestep(dir, loaded.config, () => {}, "local");
183
+ expect(emitted).toBe(true);
184
+
185
+ const generated = await readFile(join(dir, "src", "schema.generated.ts"), "utf8");
186
+ expect(generated).toContain('sqliteTable("metrics_daily"');
187
+ expect(generated).toContain('integer("hits")');
188
+ });
189
+ });
package/src/cli/db.ts ADDED
@@ -0,0 +1,456 @@
1
+ /**
2
+ * `oke db push|generate|migrate` — domain schema sync via drizzle-kit.
3
+ *
4
+ * Distinct from `oke schema generate` (core/plugin stub tables).
5
+ * When abstract decls exist (`src/schema.decl.ts`), emits Drizzle first —
6
+ * not a third schema CLI.
7
+ */
8
+
9
+ import { resolve } from "node:path";
10
+ import {
11
+ dialectFromDriverId,
12
+ maybeEmitDomainSchema,
13
+ type SqlDialect,
14
+ } from "../elements/store/emit-drizzle.ts";
15
+ import { loadPluginTablesFromAppEntry } from "../elements/store/load-plugin-tables.ts";
16
+ import { resolveDriverId, type ConfigEnv, type OkeConfig } from "../config/index.ts";
17
+ import type { TableContribution } from "../kernel/plugin.ts";
18
+ import { resolveDrizzleKitEnv } from "./drizzle-env.ts";
19
+ import { resolveDevSqlEnv } from "./resolve-dev-sql-env.ts";
20
+ import { EXIT_OK, EXIT_RUNTIME, EXIT_USAGE } from "./exit.ts";
21
+ import { loadOkeConfig } from "./load-config.ts";
22
+
23
+ /**
24
+ * Apply a drizzle-kit env overlay to `process.env` for the in-process SDK,
25
+ * returning a restore function. drizzle-kit's `push`/`generate` read
26
+ * `process.env` directly (the project `drizzle.config.ts` also reads it), so
27
+ * CLI-resolved dialect + connection env must be present in this process.
28
+ *
29
+ * @param overlay - Env keys to set
30
+ */
31
+ export function applyDrizzleEnvOverlay(overlay: Record<string, string>): () => void {
32
+ const previous = new Map<string, string | undefined>();
33
+ for (const [key, value] of Object.entries(overlay)) {
34
+ previous.set(key, process.env[key]);
35
+ process.env[key] = value;
36
+ }
37
+ return () => {
38
+ for (const [key, value] of previous) {
39
+ if (value === undefined) delete process.env[key];
40
+ else process.env[key] = value;
41
+ }
42
+ };
43
+ }
44
+
45
+ /**
46
+ * Resolve env + apply the drizzle-kit overlay for the in-process SDK.
47
+ * Restores the env afterward via a `finally`.
48
+ *
49
+ * @param cwd - Project root
50
+ * @param config - Loaded oke config
51
+ * @param env - Active env
52
+ * @param fn - Work to run under the overlay
53
+ */
54
+ export async function withDrizzleKitEnv<T>(
55
+ cwd: string,
56
+ config: OkeConfig | null | undefined,
57
+ env: ConfigEnv,
58
+ fn: (dialect: string) => Promise<T>,
59
+ ): Promise<T> {
60
+ const { dialect, overlay } = await resolveDrizzleKitEnv(cwd, config, env);
61
+ const restore = applyDrizzleEnvOverlay(overlay);
62
+ try {
63
+ return await fn(dialect);
64
+ } finally {
65
+ restore();
66
+ }
67
+ }
68
+
69
+ /** Subcommands under `oke db`. */
70
+ export type DbSubcommand = "push" | "generate" | "migrate";
71
+
72
+ /** Options for {@link runDb}. */
73
+ export interface DbOptions {
74
+ readonly cwd?: string;
75
+ /** Path to drizzle.config.ts (overrides `db.config`). */
76
+ readonly config?: string;
77
+ readonly write?: (text: string) => void;
78
+ /** Injectable push (tests). */
79
+ readonly pushFn?: (opts: { config: string }) => Promise<DbKitResult>;
80
+ /** Injectable generate (tests). */
81
+ readonly generateFn?: (opts: {
82
+ config: string;
83
+ }) => Promise<DbKitResult & { readonly migration_path?: string }>;
84
+ /** Injectable migrate (tests). */
85
+ readonly migrateFn?: (opts: {
86
+ config: string;
87
+ cwd: string;
88
+ env: Record<string, string>;
89
+ }) => Promise<number>;
90
+ /**
91
+ * Dry-run push via drizzle-kit `explain` — used by doctor drift checks.
92
+ */
93
+ readonly explain?: boolean;
94
+ /**
95
+ * Skip abstract-schema emit pre-step (tests / explain-only).
96
+ */
97
+ readonly skipEmit?: boolean;
98
+ /** Active config env for dialect resolution (default `local`). */
99
+ readonly env?: ConfigEnv;
100
+ /**
101
+ * Injectable plugin tables for emit (tests). When omitted, loads the live
102
+ * app entry and reads `app.plugins.tableContributions()`.
103
+ */
104
+ readonly pluginTables?: readonly TableContribution[];
105
+ /** Override app entry path for plugin-table discovery. */
106
+ readonly entry?: string;
107
+ }
108
+
109
+ /** Minimal drizzle-kit envelope we handle. */
110
+ export interface DbKitResult {
111
+ readonly status: "ok" | "no_changes" | "missing_hints" | "error" | string;
112
+ readonly error?: { readonly code?: string; readonly message?: string };
113
+ readonly unresolved?: readonly unknown[];
114
+ }
115
+
116
+ /**
117
+ * Resolve the drizzle config path for a project.
118
+ *
119
+ * @param cwd - Project root
120
+ * @param options - CLI / config overrides
121
+ */
122
+ export async function resolveDrizzleConfigPath(
123
+ cwd: string,
124
+ options: {
125
+ readonly config?: string;
126
+ readonly loadedConfig?: OkeConfig | null;
127
+ } = {},
128
+ ): Promise<string> {
129
+ if (options.config) return resolve(cwd, options.config);
130
+ const loaded = options.loadedConfig ?? (await loadOkeConfig(cwd).catch(() => null))?.config;
131
+ const fromConfig = loaded?.db?.config;
132
+ return resolve(cwd, fromConfig ?? "drizzle.config.ts");
133
+ }
134
+
135
+ /**
136
+ * Run `oke db <subcommand>`.
137
+ *
138
+ * @param sub - push | generate | migrate
139
+ * @param options - Paths / injectables
140
+ */
141
+ export async function runDb(sub: DbSubcommand, options: DbOptions = {}): Promise<number> {
142
+ const write = options.write ?? ((t) => process.stdout.write(t));
143
+ const cwd = options.cwd ?? process.cwd();
144
+ const loaded = await loadOkeConfig(cwd).catch(() => null);
145
+ const env = options.env ?? (await resolveDevSqlEnv(cwd));
146
+ if (!options.skipEmit) {
147
+ await emitAbstractSchemaPrestep(cwd, loaded?.config, write, env, {
148
+ pluginTables: options.pluginTables,
149
+ entry: options.entry,
150
+ });
151
+ }
152
+ const configPath = await resolveDrizzleConfigPath(cwd, {
153
+ config: options.config,
154
+ loadedConfig: loaded?.config,
155
+ });
156
+ const resolved = { ...options, skipEmit: true, env };
157
+
158
+ if (sub === "push") {
159
+ return runPush(configPath, write, resolved);
160
+ }
161
+ if (sub === "generate") {
162
+ return runGenerate(configPath, write, resolved);
163
+ }
164
+ if (sub === "migrate") {
165
+ return runMigrate(configPath, cwd, write, resolved);
166
+ }
167
+ write(`oke db: unknown subcommand\n`);
168
+ return EXIT_USAGE;
169
+ }
170
+
171
+ /**
172
+ * Emit `schema.generated.ts` from abstract decls + live plugged plugin tables.
173
+ *
174
+ * @param cwd - Project root
175
+ * @param config - Loaded oke config
176
+ * @param write - Output
177
+ * @param env - Active env for dialect
178
+ * @param options - Injectables / entry override
179
+ */
180
+ export async function emitAbstractSchemaPrestep(
181
+ cwd: string,
182
+ config: OkeConfig | null | undefined,
183
+ write: (text: string) => void = () => {},
184
+ env: ConfigEnv = "local",
185
+ options: {
186
+ readonly pluginTables?: readonly TableContribution[];
187
+ readonly entry?: string;
188
+ } = {},
189
+ ): Promise<boolean> {
190
+ const driverId = resolveDriverId(config?.drivers?.store?.sql, env);
191
+ const dialect: SqlDialect = dialectFromDriverId(driverId);
192
+ const pluginTables =
193
+ options.pluginTables ??
194
+ (await loadPluginTablesFromAppEntry(cwd, {
195
+ entry: options.entry ?? config?.db?.entry,
196
+ write,
197
+ }));
198
+ const result = await maybeEmitDomainSchema({
199
+ cwd,
200
+ dialect,
201
+ declarePath: config?.db?.declare,
202
+ outPath: config?.db?.generated,
203
+ pluginTables,
204
+ write,
205
+ });
206
+ return result.emitted;
207
+ }
208
+
209
+ /**
210
+ * Push domain schema to the live database (dev).
211
+ *
212
+ * @param configPath - Absolute drizzle.config.ts
213
+ * @param write - Output
214
+ * @param options - Injectables / explain
215
+ */
216
+ export async function runPush(
217
+ configPath: string,
218
+ write: (text: string) => void = (t) => process.stdout.write(t),
219
+ options: DbOptions = {},
220
+ ): Promise<number> {
221
+ const cwd = options.cwd ?? process.cwd();
222
+ const loaded = await loadOkeConfig(cwd).catch(() => null);
223
+ const env = options.env ?? (await resolveDevSqlEnv(cwd));
224
+ if (!options.skipEmit) {
225
+ await emitAbstractSchemaPrestep(cwd, loaded?.config, write, env, {
226
+ pluginTables: options.pluginTables,
227
+ entry: options.entry,
228
+ });
229
+ }
230
+
231
+ const pushFn =
232
+ options.pushFn ??
233
+ (async (opts: { config: string }) => {
234
+ const { push } = await import("drizzle-kit/cli");
235
+ return (await push({
236
+ config: opts.config,
237
+ ...(options.explain ? { explain: true } : {}),
238
+ })) as DbKitResult;
239
+ });
240
+
241
+ let result: DbKitResult;
242
+ try {
243
+ result = await withDrizzleKitEnv(cwd, loaded?.config, env, () =>
244
+ pushFn({ config: configPath }),
245
+ );
246
+ } catch (err) {
247
+ write(`oke db push: ${err instanceof Error ? err.message : String(err)}\n`);
248
+ write(" → install drizzle-kit and ensure drizzle.config.ts exists\n");
249
+ return EXIT_RUNTIME;
250
+ }
251
+
252
+ return reportKitResult("push", result, write);
253
+ }
254
+
255
+ /**
256
+ * Generate versioned migration SQL under `out` (prod artefact folder).
257
+ *
258
+ * @param configPath - Absolute drizzle.config.ts
259
+ * @param write - Output
260
+ * @param options - Injectables
261
+ */
262
+ export async function runGenerate(
263
+ configPath: string,
264
+ write: (text: string) => void = (t) => process.stdout.write(t),
265
+ options: DbOptions = {},
266
+ ): Promise<number> {
267
+ const cwd = options.cwd ?? process.cwd();
268
+ const loaded = await loadOkeConfig(cwd).catch(() => null);
269
+ const env = options.env ?? (await resolveDevSqlEnv(cwd));
270
+ if (!options.skipEmit) {
271
+ await emitAbstractSchemaPrestep(cwd, loaded?.config, write, env, {
272
+ pluginTables: options.pluginTables,
273
+ entry: options.entry,
274
+ });
275
+ }
276
+
277
+ const generateFn =
278
+ options.generateFn ??
279
+ (async (opts: { config: string }) => {
280
+ const { generate } = await import("drizzle-kit/cli");
281
+ return (await generate({ config: opts.config })) as DbKitResult & {
282
+ readonly migration_path?: string;
283
+ };
284
+ });
285
+
286
+ let result: DbKitResult & { readonly migration_path?: string };
287
+ try {
288
+ result = await withDrizzleKitEnv(cwd, loaded?.config, env, () =>
289
+ generateFn({ config: configPath }),
290
+ );
291
+ } catch (err) {
292
+ write(`oke db generate: ${err instanceof Error ? err.message : String(err)}\n`);
293
+ write(" → install drizzle-kit and ensure drizzle.config.ts exists\n");
294
+ return EXIT_RUNTIME;
295
+ }
296
+
297
+ if (result.status === "ok" && result.migration_path) {
298
+ write(`oke db generate: wrote ${result.migration_path}\n`);
299
+ return EXIT_OK;
300
+ }
301
+ return reportKitResult("generate", result, write);
302
+ }
303
+
304
+ /**
305
+ * Apply versioned migrations (`drizzle-kit migrate`).
306
+ *
307
+ * @param configPath - Absolute drizzle.config.ts
308
+ * @param cwd - Project root
309
+ * @param write - Output
310
+ * @param options - Injectables
311
+ */
312
+ export async function runMigrate(
313
+ configPath: string,
314
+ cwd: string,
315
+ write: (text: string) => void = (t) => process.stdout.write(t),
316
+ options: DbOptions = {},
317
+ ): Promise<number> {
318
+ const loaded = await loadOkeConfig(cwd).catch(() => null);
319
+ const env = options.env ?? (await resolveDevSqlEnv(cwd));
320
+ if (!options.skipEmit) {
321
+ await emitAbstractSchemaPrestep(cwd, loaded?.config, write, env, {
322
+ pluginTables: options.pluginTables,
323
+ entry: options.entry,
324
+ });
325
+ }
326
+
327
+ const migrateFn =
328
+ options.migrateFn ??
329
+ (async (opts: { config: string; cwd: string; env: Record<string, string> }) => {
330
+ const proc = Bun.spawn(["bunx", "drizzle-kit", "migrate", "--config", opts.config], {
331
+ cwd: opts.cwd,
332
+ stdout: "inherit",
333
+ stderr: "inherit",
334
+ env: opts.env,
335
+ });
336
+ return await proc.exited;
337
+ });
338
+
339
+ const { overlay } = await resolveDrizzleKitEnv(cwd, loaded?.config, env);
340
+ try {
341
+ const code = await migrateFn({
342
+ config: configPath,
343
+ cwd,
344
+ env: { ...(process.env as Record<string, string>), ...overlay },
345
+ });
346
+ if (code === 0) {
347
+ write("oke db migrate: applied\n");
348
+ return EXIT_OK;
349
+ }
350
+ write(`oke db migrate: exited ${code}\n`);
351
+ return EXIT_RUNTIME;
352
+ } catch (err) {
353
+ write(`oke db migrate: ${err instanceof Error ? err.message : String(err)}\n`);
354
+ return EXIT_RUNTIME;
355
+ }
356
+ }
357
+
358
+ /**
359
+ * Whether domain schema differs from the live DB (drizzle-kit push explain).
360
+ *
361
+ * @param options - Paths / injectables
362
+ */
363
+ export async function detectDbDrift(options: DbOptions = {}): Promise<{
364
+ readonly drifted: boolean;
365
+ readonly detail?: string;
366
+ }> {
367
+ const cwd = options.cwd ?? process.cwd();
368
+ const loaded = await loadOkeConfig(cwd).catch(() => null);
369
+ const env = options.env ?? (await resolveDevSqlEnv(cwd));
370
+ const configPath = await resolveDrizzleConfigPath(cwd, { config: options.config });
371
+ const pushFn =
372
+ options.pushFn ??
373
+ (async (opts: { config: string }) => {
374
+ const { push } = await import("drizzle-kit/cli");
375
+ return (await push({ config: opts.config, explain: true })) as DbKitResult;
376
+ });
377
+
378
+ try {
379
+ const result = await withDrizzleKitEnv(cwd, loaded?.config, env, () =>
380
+ pushFn({ config: configPath }),
381
+ );
382
+ if (result.status === "no_changes") return { drifted: false };
383
+ if (result.status === "ok" || result.status === "missing_hints") {
384
+ return { drifted: true, detail: `drizzle-kit push explain: ${result.status}` };
385
+ }
386
+ if (result.status === "error") {
387
+ return {
388
+ drifted: false,
389
+ detail: result.error?.message ?? "drizzle-kit push explain failed",
390
+ };
391
+ }
392
+ return { drifted: false };
393
+ } catch (err) {
394
+ return {
395
+ drifted: false,
396
+ detail: err instanceof Error ? err.message : String(err),
397
+ };
398
+ }
399
+ }
400
+
401
+ /**
402
+ * CLI entry: parse `oke db <push|generate|migrate> [--config path]`.
403
+ *
404
+ * @param args - Args after `db`
405
+ */
406
+ export async function dbCli(args: readonly string[]): Promise<number> {
407
+ const sub = args[0];
408
+ if (!sub || sub === "--help" || sub === "-h") {
409
+ console.log(`oke db push|generate|migrate [--config|-c drizzle.config.ts]
410
+
411
+ Domain schema sync via drizzle-kit.
412
+ When src/schema.decl.ts and/or a plugged app entry exists, emits
413
+ schema.generated.ts from store.schema.table + live plugin .table()
414
+ contributions — then runs drizzle-kit.
415
+ Hand-written src/schema.ts remains supported (emit skipped if nothing to emit).
416
+ Not the same as \`oke schema generate\` (core/plugin stub tables).
417
+
418
+ push Apply schema to the live local DB (dev; no migration files)
419
+ generate Write versioned SQL under drizzle/ for review
420
+ migrate Apply generated migrations (explicit; never automatic in prod)
421
+ `);
422
+ return sub ? EXIT_OK : EXIT_USAGE;
423
+ }
424
+ if (sub !== "push" && sub !== "generate" && sub !== "migrate") {
425
+ console.error(`oke db: unknown subcommand "${sub}"`);
426
+ return EXIT_USAGE;
427
+ }
428
+
429
+ let config: string | undefined;
430
+ for (let i = 1; i < args.length; i++) {
431
+ const a = args[i]!;
432
+ if (a === "--config" || a === "-c") config = args[++i];
433
+ else if (a === "--help" || a === "-h") {
434
+ return dbCli(["--help"]);
435
+ }
436
+ }
437
+
438
+ return runDb(sub, { config });
439
+ }
440
+
441
+ function reportKitResult(verb: string, result: DbKitResult, write: (text: string) => void): number {
442
+ if (result.status === "ok" || result.status === "no_changes") {
443
+ write(`oke db ${verb}: ${result.status}\n`);
444
+ return EXIT_OK;
445
+ }
446
+ if (result.status === "missing_hints") {
447
+ write(
448
+ `oke db ${verb}: missing_hints — resolve destructive changes manually (not auto-applied)\n`,
449
+ );
450
+ return EXIT_RUNTIME;
451
+ }
452
+ write(
453
+ `oke db ${verb}: ${result.status}${result.error?.message ? ` — ${result.error.message}` : ""}\n`,
454
+ );
455
+ return EXIT_RUNTIME;
456
+ }
@@ -19,11 +19,7 @@ import { resolve } from "node:path";
19
19
  import { pathToFileURL } from "node:url";
20
20
  import { createBunRuntime } from "../runtime/bun.ts";
21
21
  import { APP_PORT, type FetchApp } from "../runtime/types.ts";
22
- import {
23
- clearTerminalScreen,
24
- formatAppReadyLine,
25
- formatDevHero,
26
- } from "../term.ts";
22
+ import { clearTerminalScreen, formatAppReadyLine, formatDevHero } from "../term.ts";
27
23
  import { decodeHeroSnapshot } from "./hero-meta.ts";
28
24
 
29
25
  /** Stable Bun.serve id so `--hot` reuses the socket across soft reloads. */
@@ -62,9 +58,7 @@ if (
62
58
  typeof mod.app.boot !== "function" ||
63
59
  typeof mod.app.fetch !== "function"
64
60
  ) {
65
- console.error(
66
- `oke dev: ${absoluteEntry} must export app with boot() and fetch()`,
67
- );
61
+ console.error(`oke dev: ${absoluteEntry} must export app with boot() and fetch()`);
68
62
  process.exit(1);
69
63
  }
70
64