okengine 0.2.6 → 0.2.8

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 (584) hide show
  1. package/AGENTS.md +24 -23
  2. package/README.md +52 -346
  3. package/docs/spec/console.md +165 -142
  4. package/docs/spec/example.md +490 -312
  5. package/docs/spec/four-applications.md +495 -314
  6. package/docs/spec/unified-theory.md +184 -175
  7. package/package.json +45 -37
  8. package/spec/manifest.v1.schema.json +40 -9
  9. package/src/auth/api-keys.ts +2 -5
  10. package/src/auth/attenuation.ts +2 -6
  11. package/src/auth/auth.test.ts +53 -31
  12. package/src/auth/invoke-as.ts +1 -3
  13. package/src/auth/operator.ts +8 -26
  14. package/src/auth/planes.ts +2 -7
  15. package/src/auth/plugin.ts +4 -7
  16. package/src/auth/roles.ts +1 -5
  17. package/src/auth/sessions.ts +10 -39
  18. package/src/cli/args.ts +1 -5
  19. package/src/cli/ask-dev-mode.ts +40 -0
  20. package/src/cli/build.ts +1 -2
  21. package/src/cli/client-add.test.ts +8 -15
  22. package/src/cli/client-add.ts +5 -14
  23. package/src/cli/completion.test.ts +1 -5
  24. package/src/cli/completion.ts +4 -17
  25. package/src/cli/db-auto-push.test.ts +64 -0
  26. package/src/cli/db-auto-push.ts +72 -0
  27. package/src/cli/db.test.ts +189 -0
  28. package/src/cli/db.ts +386 -0
  29. package/src/cli/dev-app-runner.ts +2 -8
  30. package/src/cli/dev-db-push.test.ts +163 -0
  31. package/src/cli/dev-mode.test.ts +45 -0
  32. package/src/cli/dev-mode.ts +78 -0
  33. package/src/cli/dev.test.ts +148 -21
  34. package/src/cli/dev.ts +208 -134
  35. package/src/cli/doc-drift.test.ts +3 -2
  36. package/src/cli/doc-drift.ts +21 -50
  37. package/src/cli/doc-staleness.test.ts +69 -0
  38. package/src/cli/docker-cli.test.ts +7 -8
  39. package/src/cli/docker.ts +1 -3
  40. package/src/cli/doctor-diff-examples.ts +1 -3
  41. package/src/cli/doctor-diff.test.ts +1 -5
  42. package/src/cli/doctor-diff.ts +17 -46
  43. package/src/cli/doctor-pii.ts +2 -7
  44. package/src/cli/doctor.test.ts +26 -4
  45. package/src/cli/doctor.ts +35 -11
  46. package/src/cli/eval.ts +4 -14
  47. package/src/cli/gates-list.ts +1 -4
  48. package/src/cli/hero-meta.test.ts +17 -19
  49. package/src/cli/hero-meta.ts +20 -30
  50. package/src/cli/images.ts +3 -8
  51. package/src/cli/index.ts +11 -2
  52. package/src/cli/load-config.images.test.ts +14 -14
  53. package/src/cli/load-config.ts +41 -47
  54. package/src/cli/mcp-from-console.ts +1 -4
  55. package/src/cli/mode.ts +45 -0
  56. package/src/cli/ports.test.ts +4 -13
  57. package/src/cli/ports.ts +1 -3
  58. package/src/cli/privacy-erase.ts +1 -3
  59. package/src/cli/registry.ts +75 -25
  60. package/src/cli/schema.ts +3 -10
  61. package/src/cli/stack.ts +2 -7
  62. package/src/cli/start.ts +4 -15
  63. package/src/cli/upgrade.ts +1 -4
  64. package/src/client/budget-entry.ts +1 -6
  65. package/src/client/create.test.ts +6 -12
  66. package/src/client/create.ts +2 -8
  67. package/src/client/errors.ts +1 -4
  68. package/src/client/index.ts +1 -6
  69. package/src/client/notes-contract.test.ts +4 -13
  70. package/src/client/transport.ts +9 -30
  71. package/src/client/types.ts +8 -29
  72. package/src/compiler/aot.test.ts +2 -9
  73. package/src/compiler/aot.ts +1 -4
  74. package/src/compiler/differential.test.ts +3 -11
  75. package/src/compiler/dynamic.ts +1 -4
  76. package/src/compiler/effects-infer.ts +8 -34
  77. package/src/compiler/emit.ts +1 -3
  78. package/src/compiler/extract.test.ts +96 -30
  79. package/src/compiler/extract.ts +362 -156
  80. package/src/compiler/fixtures/skyport/oke.config.ts +1 -1
  81. package/src/compiler/fixtures/skyport/src/flows/bookings/index.ts +7 -3
  82. package/src/compiler/fixtures/skyport/src/flows/payments/index.ts +1 -3
  83. package/src/compiler/fixtures/skyport/src/flows/support/index.ts +4 -1
  84. package/src/compiler/fixtures/skyport.expected.json +24 -83
  85. package/src/compiler/fixtures/triggers/five-triggers.ts +1 -2
  86. package/src/compiler/http-parse.ts +2 -9
  87. package/src/compiler/index.ts +1 -5
  88. package/src/compiler/response.ts +4 -7
  89. package/src/compiler/sucrose.ts +11 -31
  90. package/src/config/define-config.test.ts +57 -34
  91. package/src/config/index.ts +181 -37
  92. package/src/config/resolve-driver.test.ts +28 -17
  93. package/src/console/budget.test.ts +1 -4
  94. package/src/console/index.ts +1 -4
  95. package/src/console/server/access.test.ts +15 -43
  96. package/src/console/server/access.ts +19 -49
  97. package/src/console/server/ai.test.ts +3 -11
  98. package/src/console/server/ai.ts +23 -46
  99. package/src/console/server/app.ts +14 -45
  100. package/src/console/server/auth-rate.test.ts +4 -12
  101. package/src/console/server/bind.ts +1 -5
  102. package/src/console/server/channels.test.ts +2 -6
  103. package/src/console/server/channels.ts +10 -35
  104. package/src/console/server/claim.ts +2 -8
  105. package/src/console/server/clock.test.ts +2 -6
  106. package/src/console/server/clock.ts +8 -26
  107. package/src/console/server/console.test.ts +1 -3
  108. package/src/console/server/diff.test.ts +5 -17
  109. package/src/console/server/diff.ts +10 -31
  110. package/src/console/server/dry-run.audit.test.ts +2 -8
  111. package/src/console/server/flows.ts +64 -233
  112. package/src/console/server/gates.test.ts +14 -50
  113. package/src/console/server/gates.ts +13 -48
  114. package/src/console/server/index.ts +2 -9
  115. package/src/console/server/live.ts +3 -12
  116. package/src/console/server/operator-db.test.ts +4 -15
  117. package/src/console/server/operator-db.ts +13 -32
  118. package/src/console/server/plugin.ts +50 -53
  119. package/src/console/server/plugins.test.ts +2 -6
  120. package/src/console/server/plugins.ts +17 -56
  121. package/src/console/server/runs-pii.ts +2 -7
  122. package/src/console/server/security.gate.test.ts +18 -40
  123. package/src/console/server/serve.ts +10 -25
  124. package/src/console/server/signals.test.ts +1 -3
  125. package/src/console/server/signals.ts +17 -40
  126. package/src/console/server/state.ts +21 -59
  127. package/src/console/server/store.test.ts +20 -22
  128. package/src/console/server/store.ts +31 -76
  129. package/src/console/server/vault.test.ts +12 -29
  130. package/src/console/server/vault.ts +23 -60
  131. package/src/console/ui/access/AccessA11yView.tsx +6 -21
  132. package/src/console/ui/access/a11y.test.tsx +3 -12
  133. package/src/console/ui/access/acknowledgement.test.ts +1 -4
  134. package/src/console/ui/access/acknowledgement.ts +1 -3
  135. package/src/console/ui/access/blast-radius.ts +1 -3
  136. package/src/console/ui/access/confirmation.test.ts +1 -5
  137. package/src/console/ui/access/confirmation.ts +1 -4
  138. package/src/console/ui/access/fixture.ts +1 -5
  139. package/src/console/ui/access/grantable.test.ts +1 -3
  140. package/src/console/ui/access/grantable.ts +2 -7
  141. package/src/console/ui/access/index.ts +2 -9
  142. package/src/console/ui/access/provenance.test.ts +1 -3
  143. package/src/console/ui/access/provenance.ts +2 -6
  144. package/src/console/ui/access/search.test.ts +1 -5
  145. package/src/console/ui/access/search.ts +2 -6
  146. package/src/console/ui/ai/AiA11yView.tsx +6 -17
  147. package/src/console/ui/ai/a11y.test.tsx +2 -5
  148. package/src/console/ui/ai/fixture.ts +2 -7
  149. package/src/console/ui/ai/format.ts +1 -3
  150. package/src/console/ui/ai/group.test.ts +1 -3
  151. package/src/console/ui/ai/group.ts +4 -12
  152. package/src/console/ui/ai/index.ts +2 -9
  153. package/src/console/ui/ai/promotion.test.ts +2 -7
  154. package/src/console/ui/ai/promotion.ts +4 -13
  155. package/src/console/ui/ai/search.test.ts +2 -11
  156. package/src/console/ui/ai/search.ts +3 -13
  157. package/src/console/ui/ai/types.ts +1 -8
  158. package/src/console/ui/architecture/ArchitectureA11yView.tsx +8 -29
  159. package/src/console/ui/architecture/a11y.test.tsx +1 -2
  160. package/src/console/ui/architecture/declared.ts +1 -5
  161. package/src/console/ui/architecture/index.ts +7 -35
  162. package/src/console/ui/architecture/layout.ts +1 -3
  163. package/src/console/ui/architecture/pathologies.ts +10 -19
  164. package/src/console/ui/architecture/search.ts +6 -15
  165. package/src/console/ui/architecture/traffic.ts +4 -14
  166. package/src/console/ui/architecture/types.ts +2 -10
  167. package/src/console/ui/architecture/view.test.ts +7 -19
  168. package/src/console/ui/architecture/view.ts +9 -36
  169. package/src/console/ui/channels/ChannelsA11yView.tsx +4 -13
  170. package/src/console/ui/channels/a11y.test.tsx +1 -2
  171. package/src/console/ui/channels/confirmation.test.ts +1 -4
  172. package/src/console/ui/channels/confirmation.ts +1 -4
  173. package/src/console/ui/channels/findings.ts +1 -5
  174. package/src/console/ui/channels/index.ts +2 -8
  175. package/src/console/ui/channels/locale.test.ts +1 -3
  176. package/src/console/ui/channels/locale.ts +2 -8
  177. package/src/console/ui/channels/search.ts +4 -13
  178. package/src/console/ui/channels/taxonomy.ts +1 -3
  179. package/src/console/ui/clock/ClockA11yView.tsx +9 -26
  180. package/src/console/ui/clock/a11y.test.tsx +2 -5
  181. package/src/console/ui/clock/confirmation.test.ts +1 -3
  182. package/src/console/ui/clock/confirmation.ts +1 -4
  183. package/src/console/ui/clock/findings.ts +1 -4
  184. package/src/console/ui/clock/health.ts +2 -7
  185. package/src/console/ui/clock/index.ts +2 -10
  186. package/src/console/ui/clock/search.test.ts +1 -3
  187. package/src/console/ui/clock/search.ts +2 -6
  188. package/src/console/ui/clock/timeline.test.ts +1 -3
  189. package/src/console/ui/clock/waiting-on.test.ts +1 -5
  190. package/src/console/ui/clock/waiting-on.ts +2 -7
  191. package/src/console/ui/diff/DiffA11yView.tsx +8 -17
  192. package/src/console/ui/diff/a11y.test.tsx +2 -5
  193. package/src/console/ui/diff/group.test.ts +3 -13
  194. package/src/console/ui/diff/group.ts +2 -8
  195. package/src/console/ui/diff/index.ts +2 -8
  196. package/src/console/ui/diff/search.test.ts +1 -5
  197. package/src/console/ui/diff/search.ts +4 -16
  198. package/src/console/ui/diff/summary.ts +1 -2
  199. package/src/console/ui/dist/assets/{index-Dy4jht9P.js → index-BWo8R7NR.js} +2 -2
  200. package/src/console/ui/dist/assets/{panel-access-Dd37LU2c.js → panel-access-C0J2D-a2.js} +1 -1
  201. package/src/console/ui/dist/assets/{panel-ai-CC7LR6-J.js → panel-ai-D_m6WQI8.js} +1 -1
  202. package/src/console/ui/dist/assets/{panel-architecture-B5b3iKCz.js → panel-architecture-CKnXFyUx.js} +1 -1
  203. package/src/console/ui/dist/assets/{panel-channels-CeNjTKXp.js → panel-channels-BOmQ-onL.js} +1 -1
  204. package/src/console/ui/dist/assets/{panel-clock-DgFTLoHV.js → panel-clock-giAq0Ccv.js} +1 -1
  205. package/src/console/ui/dist/assets/{panel-diff-DxehccqB.js → panel-diff-cdonmH8c.js} +1 -1
  206. package/src/console/ui/dist/assets/{panel-flows-BtrVn-Eg.js → panel-flows-DlCU5zjA.js} +2 -2
  207. package/src/console/ui/dist/assets/{panel-gates-Z9MKRGdH.js → panel-gates-XclZxWD5.js} +1 -1
  208. package/src/console/ui/dist/assets/{panel-overview-Dt_AeXgd.js → panel-overview-BznEOTnb.js} +1 -1
  209. package/src/console/ui/dist/assets/{panel-plugins-DWd0TowH.js → panel-plugins-CcGM1g64.js} +1 -1
  210. package/src/console/ui/dist/assets/{panel-runs-DGstFHeq.js → panel-runs-CGWNHLR4.js} +1 -1
  211. package/src/console/ui/dist/assets/{panel-signals-DzEa2Fnt.js → panel-signals-CNywkdak.js} +1 -1
  212. package/src/console/ui/dist/assets/{panel-store-BJkbNgxx.js → panel-store-KmTbFHMH.js} +1 -1
  213. package/src/console/ui/dist/assets/{panel-traces-BaRVO3gM.js → panel-traces-DBLx2ilD.js} +1 -1
  214. package/src/console/ui/dist/assets/panel-vault-CEnFc0dk.js +1 -0
  215. package/src/console/ui/dist/index.html +1 -1
  216. package/src/console/ui/flows/FlowsA11yView.tsx +7 -22
  217. package/src/console/ui/flows/a11y.test.tsx +2 -8
  218. package/src/console/ui/flows/buffer.test.ts +3 -11
  219. package/src/console/ui/flows/buffer.ts +4 -11
  220. package/src/console/ui/flows/confirmation.ts +1 -3
  221. package/src/console/ui/flows/contract.test.ts +3 -7
  222. package/src/console/ui/flows/contract.ts +12 -36
  223. package/src/console/ui/flows/graph.test.ts +3 -11
  224. package/src/console/ui/flows/graph.ts +5 -15
  225. package/src/console/ui/flows/index.ts +1 -6
  226. package/src/console/ui/flows/save-as-test.ts +1 -3
  227. package/src/console/ui/flows/search.ts +8 -25
  228. package/src/console/ui/flows/tiers.ts +2 -9
  229. package/src/console/ui/gates/GatesA11yView.tsx +4 -13
  230. package/src/console/ui/gates/a11y.test.tsx +2 -5
  231. package/src/console/ui/gates/audit.ts +1 -3
  232. package/src/console/ui/gates/denial.test.ts +1 -3
  233. package/src/console/ui/gates/denial.ts +4 -12
  234. package/src/console/ui/gates/findings.ts +1 -3
  235. package/src/console/ui/gates/group.test.ts +3 -3
  236. package/src/console/ui/gates/group.ts +3 -11
  237. package/src/console/ui/gates/index.ts +2 -10
  238. package/src/console/ui/gates/search.ts +3 -10
  239. package/src/console/ui/overview/OverviewA11yView.tsx +9 -27
  240. package/src/console/ui/overview/a11y.test.tsx +1 -2
  241. package/src/console/ui/overview/busiest.ts +1 -3
  242. package/src/console/ui/overview/compose.ts +1 -13
  243. package/src/console/ui/overview/cost.ts +34 -38
  244. package/src/console/ui/overview/fixture.ts +21 -26
  245. package/src/console/ui/overview/golden.ts +4 -14
  246. package/src/console/ui/overview/index.ts +2 -9
  247. package/src/console/ui/overview/rank.test.ts +3 -10
  248. package/src/console/ui/overview/rank.ts +2 -7
  249. package/src/console/ui/overview/slo.test.ts +5 -9
  250. package/src/console/ui/overview/slo.ts +6 -23
  251. package/src/console/ui/overview/verdict.ts +3 -10
  252. package/src/console/ui/plugins/PluginsA11yView.tsx +8 -18
  253. package/src/console/ui/plugins/a11y.test.tsx +1 -2
  254. package/src/console/ui/plugins/fixture.ts +2 -4
  255. package/src/console/ui/plugins/group.test.ts +1 -3
  256. package/src/console/ui/plugins/group.ts +1 -6
  257. package/src/console/ui/plugins/index.ts +3 -13
  258. package/src/console/ui/plugins/search.ts +7 -19
  259. package/src/console/ui/runs/RunsA11yView.tsx +5 -20
  260. package/src/console/ui/runs/a11y.test.tsx +2 -5
  261. package/src/console/ui/runs/explain.ts +2 -6
  262. package/src/console/ui/runs/group.ts +3 -12
  263. package/src/console/ui/runs/histogram.test.ts +2 -11
  264. package/src/console/ui/runs/histogram.ts +1 -4
  265. package/src/console/ui/runs/index.ts +4 -18
  266. package/src/console/ui/runs/project.ts +2 -6
  267. package/src/console/ui/runs/query.test.ts +1 -3
  268. package/src/console/ui/runs/query.ts +12 -35
  269. package/src/console/ui/runs/search.ts +5 -19
  270. package/src/console/ui/runs/trace-link.test.ts +2 -6
  271. package/src/console/ui/runs/trace-link.ts +4 -16
  272. package/src/console/ui/runs/types.ts +1 -3
  273. package/src/console/ui/shell/App.tsx +2 -10
  274. package/src/console/ui/shell/client.ts +22 -115
  275. package/src/console/ui/shell/components/ui.tsx +1 -4
  276. package/src/console/ui/shell/layout/Shell.tsx +2 -4
  277. package/src/console/ui/shell/main.tsx +31 -96
  278. package/src/console/ui/shell/panels/access/AccessPanel.tsx +34 -98
  279. package/src/console/ui/shell/panels/ai/AiPanel.tsx +35 -106
  280. package/src/console/ui/shell/panels/architecture/ArchitecturePanel.tsx +18 -66
  281. package/src/console/ui/shell/panels/channels/ChannelsPanel.tsx +20 -57
  282. package/src/console/ui/shell/panels/clock/ClockPanel.tsx +22 -54
  283. package/src/console/ui/shell/panels/diff/DiffPanel.tsx +20 -61
  284. package/src/console/ui/shell/panels/flows/ContractEditor.tsx +6 -23
  285. package/src/console/ui/shell/panels/flows/FlowDrawer.tsx +13 -28
  286. package/src/console/ui/shell/panels/flows/FlowsPanel.tsx +9 -29
  287. package/src/console/ui/shell/panels/gates/GatesPanel.tsx +24 -80
  288. package/src/console/ui/shell/panels/overview/OverviewPanel.tsx +20 -58
  289. package/src/console/ui/shell/panels/plugins/PluginsPanel.tsx +16 -41
  290. package/src/console/ui/shell/panels/runs/RunsPanel.tsx +31 -99
  291. package/src/console/ui/shell/panels/signals/SignalsPanel.tsx +38 -101
  292. package/src/console/ui/shell/panels/store/StorePanel.tsx +27 -66
  293. package/src/console/ui/shell/panels/traces/TracesPanel.tsx +28 -89
  294. package/src/console/ui/shell/panels/vault/VaultPanel.tsx +22 -53
  295. package/src/console/ui/shell/setup/Wizard.tsx +3 -5
  296. package/src/console/ui/shell/styles.css +1 -2
  297. package/src/console/ui/signals/SignalsA11yView.tsx +9 -33
  298. package/src/console/ui/signals/a11y.test.tsx +2 -5
  299. package/src/console/ui/signals/confirmation.test.ts +1 -5
  300. package/src/console/ui/signals/confirmation.ts +2 -6
  301. package/src/console/ui/signals/dry-run.ts +1 -3
  302. package/src/console/ui/signals/durable.ts +1 -3
  303. package/src/console/ui/signals/findings.ts +1 -3
  304. package/src/console/ui/signals/group.test.ts +2 -8
  305. package/src/console/ui/signals/group.ts +2 -10
  306. package/src/console/ui/signals/index.ts +1 -4
  307. package/src/console/ui/signals/monitor.ts +2 -7
  308. package/src/console/ui/signals/schema-form.test.ts +3 -14
  309. package/src/console/ui/signals/schema-form.ts +1 -4
  310. package/src/console/ui/signals/search.ts +4 -13
  311. package/src/console/ui/store/StoreA11yView.tsx +3 -9
  312. package/src/console/ui/store/a11y.test.tsx +2 -5
  313. package/src/console/ui/store/confirmation.test.ts +1 -3
  314. package/src/console/ui/store/confirmation.ts +1 -4
  315. package/src/console/ui/store/dry-run.ts +2 -5
  316. package/src/console/ui/store/fixture.ts +1 -2
  317. package/src/console/ui/store/group.test.ts +1 -6
  318. package/src/console/ui/store/group.ts +1 -4
  319. package/src/console/ui/store/index.ts +1 -5
  320. package/src/console/ui/store/search.ts +2 -6
  321. package/src/console/ui/store/will-not-fire.ts +1 -2
  322. package/src/console/ui/traces/TracesA11yView.tsx +10 -29
  323. package/src/console/ui/traces/a11y.test.tsx +1 -2
  324. package/src/console/ui/traces/chain.test.ts +5 -19
  325. package/src/console/ui/traces/chain.ts +1 -3
  326. package/src/console/ui/traces/critical-path.test.ts +1 -3
  327. package/src/console/ui/traces/critical-path.ts +2 -6
  328. package/src/console/ui/traces/filter.test.ts +2 -6
  329. package/src/console/ui/traces/filter.ts +5 -13
  330. package/src/console/ui/traces/fold.test.ts +4 -12
  331. package/src/console/ui/traces/fold.ts +1 -3
  332. package/src/console/ui/traces/mini.ts +1 -3
  333. package/src/console/ui/traces/replay.test.ts +1 -3
  334. package/src/console/ui/traces/replay.ts +1 -3
  335. package/src/console/ui/traces/sampling.ts +1 -4
  336. package/src/console/ui/traces/search.ts +4 -17
  337. package/src/console/ui/traces/tier.ts +1 -3
  338. package/src/console/ui/vault/VaultA11yView.tsx +5 -17
  339. package/src/console/ui/vault/a11y.test.tsx +1 -2
  340. package/src/console/ui/vault/blast-radius.ts +1 -3
  341. package/src/console/ui/vault/confirmation.test.ts +1 -5
  342. package/src/console/ui/vault/confirmation.ts +1 -4
  343. package/src/console/ui/vault/dormant.test.ts +1 -4
  344. package/src/console/ui/vault/export-safe.test.ts +1 -5
  345. package/src/console/ui/vault/export-safe.ts +1 -4
  346. package/src/console/ui/vault/fixture.ts +3 -3
  347. package/src/console/ui/vault/group.ts +1 -2
  348. package/src/console/ui/vault/index.ts +2 -10
  349. package/src/console/ui/vault/search.ts +2 -6
  350. package/src/console/ui/vault/types.ts +1 -1
  351. package/src/console/xss.gate.test.ts +1 -3
  352. package/src/docker/compose.ts +112 -20
  353. package/src/docker/derive.ts +5 -19
  354. package/src/docker/docker.test.ts +15 -15
  355. package/src/docker/dockerfile.integration.test.ts +12 -21
  356. package/src/docker/helpers.ts +5 -4
  357. package/src/docker/index.ts +4 -11
  358. package/src/docker/pin.ts +1 -9
  359. package/src/docker/recipes/index.ts +5 -6
  360. package/src/docker/recipes/mailpit.ts +22 -0
  361. package/src/docker/recipes/postgres.ts +17 -6
  362. package/src/docker/recipes/redis.ts +6 -1
  363. package/src/docker/recipes/rustfs.ts +33 -0
  364. package/src/docker/stack-id.test.ts +33 -0
  365. package/src/docker/stack-id.ts +25 -13
  366. package/src/docker/stack.integration.test.ts +6 -21
  367. package/src/docker/types.ts +13 -4
  368. package/src/drivers/ai-anthropic.ts +5 -14
  369. package/src/drivers/ai-mock.ts +2 -5
  370. package/src/drivers/ai-openai-compatible.ts +4 -10
  371. package/src/drivers/ai-providers.test.ts +6 -13
  372. package/src/drivers/bun-native-completeness.test.ts +6 -15
  373. package/src/drivers/channel-console.ts +6 -7
  374. package/src/drivers/channel-fcm.ts +20 -30
  375. package/src/drivers/channel-resend.ts +1 -3
  376. package/src/drivers/channel-smtp.ts +2 -6
  377. package/src/drivers/channel-types.ts +2 -12
  378. package/src/drivers/channel-unifonic.ts +2 -6
  379. package/src/drivers/channel-wa-cloud.ts +2 -6
  380. package/src/drivers/channel-webpush.ts +21 -60
  381. package/src/drivers/conformance.test.ts +2 -10
  382. package/src/drivers/conformance.ts +8 -21
  383. package/src/drivers/fs.ts +2 -8
  384. package/src/drivers/index.ts +12 -56
  385. package/src/drivers/memory.ts +14 -41
  386. package/src/drivers/pgvector.ts +7 -11
  387. package/src/drivers/postgres.ts +7 -13
  388. package/src/drivers/redis.ts +13 -37
  389. package/src/drivers/s3.ts +5 -17
  390. package/src/drivers/signal-engine.ts +12 -49
  391. package/src/drivers/signal-memory.ts +2 -8
  392. package/src/drivers/signal-nats.ts +4 -9
  393. package/src/drivers/signal-postgres.ts +62 -129
  394. package/src/drivers/signal-redis.ts +7 -21
  395. package/src/drivers/signal-types.ts +1 -4
  396. package/src/drivers/sqlite.ts +3 -12
  397. package/src/drivers/types.ts +4 -23
  398. package/src/drivers/vault-env.ts +2 -6
  399. package/src/drivers/vault-infisical.ts +1 -5
  400. package/src/drivers/vault-managed.ts +1 -5
  401. package/src/drivers/vault-memory.ts +1 -5
  402. package/src/drivers/vault-openbao.ts +1 -5
  403. package/src/drivers/vault-sops.ts +10 -35
  404. package/src/drivers/vault-types.ts +1 -7
  405. package/src/elements/ai/declare.ts +4 -14
  406. package/src/elements/ai/eval.ts +2 -6
  407. package/src/elements/ai/pii.ts +1 -3
  408. package/src/elements/ai/runtime.ts +12 -50
  409. package/src/elements/ai/schema.ts +4 -15
  410. package/src/elements/ai.test.ts +13 -24
  411. package/src/elements/ai.ts +1 -5
  412. package/src/elements/channel/consent.ts +3 -12
  413. package/src/elements/channel/costs.ts +4 -15
  414. package/src/elements/channel/declare.ts +1 -4
  415. package/src/elements/channel/email-auth.ts +1 -4
  416. package/src/elements/channel/locale.ts +2 -10
  417. package/src/elements/channel/mask.ts +1 -3
  418. package/src/elements/channel/mime.ts +2 -12
  419. package/src/elements/channel/outcomes.test.ts +1 -5
  420. package/src/elements/channel/outcomes.ts +5 -15
  421. package/src/elements/channel/receipts.ts +2 -7
  422. package/src/elements/channel/runtime.ts +28 -74
  423. package/src/elements/channel/suppression.ts +8 -14
  424. package/src/elements/channel.test.ts +8 -31
  425. package/src/elements/channel.ts +3 -14
  426. package/src/elements/clock/actions.ts +6 -18
  427. package/src/elements/clock/declare.ts +1 -3
  428. package/src/elements/clock/dst.ts +1 -5
  429. package/src/elements/clock/durable.ts +4 -16
  430. package/src/elements/clock/health.ts +2 -7
  431. package/src/elements/clock/leader.ts +2 -9
  432. package/src/elements/clock/reconcile.ts +4 -15
  433. package/src/elements/clock/runtime.ts +2 -5
  434. package/src/elements/clock/schedule.ts +4 -20
  435. package/src/elements/clock.test.ts +2 -7
  436. package/src/elements/clock.ts +5 -23
  437. package/src/elements/gate/permissions.ts +1 -4
  438. package/src/elements/gate/runtime.ts +7 -28
  439. package/src/elements/gate.ts +1 -5
  440. package/src/elements/index.ts +9 -7
  441. package/src/elements/signal/declare.ts +2 -7
  442. package/src/elements/signal/reconcile.test.ts +1 -4
  443. package/src/elements/signal/runtime.ts +1 -3
  444. package/src/elements/signal.test.ts +3 -15
  445. package/src/elements/signal.ts +2 -8
  446. package/src/elements/store/cache.test.ts +46 -0
  447. package/src/elements/store/cache.ts +3 -11
  448. package/src/elements/store/classify.ts +5 -22
  449. package/src/elements/store/declare.ts +8 -17
  450. package/src/elements/store/domain-ddl.test.ts +86 -0
  451. package/src/elements/store/emit-drizzle.ts +363 -0
  452. package/src/elements/store/files-policy.test.ts +1 -5
  453. package/src/elements/store/files-policy.ts +4 -12
  454. package/src/elements/store/load-plugin-tables.ts +103 -0
  455. package/src/elements/store/missing-relation.test.ts +83 -0
  456. package/src/elements/store/missing-relation.ts +38 -0
  457. package/src/elements/store/replica.ts +1 -4
  458. package/src/elements/store/runtime.ts +25 -28
  459. package/src/elements/store/schema-decl.test.ts +227 -0
  460. package/src/elements/store/schema-decl.ts +516 -0
  461. package/src/elements/store/sql-condition.ts +11 -21
  462. package/src/elements/store/sql-session.test.ts +50 -0
  463. package/src/elements/store/sql-session.ts +60 -63
  464. package/src/elements/store/table.ts +35 -19
  465. package/src/elements/store.test.ts +17 -39
  466. package/src/elements/store.ts +37 -31
  467. package/src/elements/vault/chain.ts +34 -0
  468. package/src/elements/vault/declare.ts +22 -32
  469. package/src/elements/vault/fingerprint.ts +2 -7
  470. package/src/elements/vault/redact.ts +2 -6
  471. package/src/elements/vault/runtime.ts +18 -32
  472. package/src/elements/vault.test.ts +12 -28
  473. package/src/elements/vault.ts +8 -12
  474. package/src/index.ts +5 -2
  475. package/src/kernel/adopt-routes.ts +15 -29
  476. package/src/kernel/app.ts +34 -94
  477. package/src/kernel/auth-resolve.ts +2 -9
  478. package/src/kernel/boot-bind/ai.ts +1 -4
  479. package/src/kernel/boot-bind/channel.ts +2 -8
  480. package/src/kernel/boot-bind/clock.ts +2 -6
  481. package/src/kernel/boot-bind/gate.ts +2 -8
  482. package/src/kernel/boot-bind/runs.ts +1 -3
  483. package/src/kernel/boot-bind/signal.ts +3 -10
  484. package/src/kernel/boot-bind/store.test.ts +17 -17
  485. package/src/kernel/boot-bind/store.ts +44 -50
  486. package/src/kernel/boot-bind/vault.ts +2 -8
  487. package/src/kernel/boot.test.ts +4 -9
  488. package/src/kernel/boot.ts +29 -76
  489. package/src/kernel/budget.test.ts +1 -3
  490. package/src/kernel/capability.ts +3 -10
  491. package/src/kernel/dry-run.test.ts +1 -4
  492. package/src/kernel/dry-run.ts +3 -11
  493. package/src/kernel/effects.test.ts +1 -5
  494. package/src/kernel/effects.ts +4 -11
  495. package/src/kernel/errors.registry.test.ts +2 -8
  496. package/src/kernel/errors.ts +23 -32
  497. package/src/kernel/flow.test.ts +12 -25
  498. package/src/kernel/flow.ts +5 -25
  499. package/src/kernel/fx.test.ts +15 -44
  500. package/src/kernel/fx.ts +27 -79
  501. package/src/kernel/hook-timing.test.ts +3 -6
  502. package/src/kernel/hook-timing.ts +5 -14
  503. package/src/kernel/hooks.test.ts +10 -10
  504. package/src/kernel/hooks.ts +3 -12
  505. package/src/kernel/index.ts +4 -17
  506. package/src/kernel/journal.ts +7 -31
  507. package/src/kernel/on.ts +1 -6
  508. package/src/kernel/pipeline.test.ts +10 -19
  509. package/src/kernel/pipeline.ts +5 -17
  510. package/src/kernel/plug.ts +4 -11
  511. package/src/kernel/plugin/conflicts.test.ts +13 -25
  512. package/src/kernel/plugin/decorate.test.ts +8 -13
  513. package/src/kernel/plugin/scoping.test.ts +4 -11
  514. package/src/kernel/plugin.ts +48 -24
  515. package/src/kernel/registry.ts +80 -29
  516. package/src/kernel/router.test.ts +15 -13
  517. package/src/kernel/router.ts +9 -29
  518. package/src/kernel/routing-budget.test.ts +1 -3
  519. package/src/kernel/run-telemetry.ts +1 -3
  520. package/src/kernel/triggers.ts +4 -21
  521. package/src/manifest/diff.test.ts +26 -91
  522. package/src/manifest/diff.ts +95 -225
  523. package/src/manifest/index.ts +2 -9
  524. package/src/manifest/types.ts +29 -5
  525. package/src/manifest/undeclared.test.ts +4 -12
  526. package/src/manifest/undeclared.ts +1 -2
  527. package/src/manifest/validate.test.ts +2 -6
  528. package/src/manifest/validate.ts +4 -14
  529. package/src/mcp/authorization.ts +8 -27
  530. package/src/mcp/confirmation.ts +3 -10
  531. package/src/mcp/data.ts +2 -6
  532. package/src/mcp/docs-index.ts +4 -7
  533. package/src/mcp/docs-mcp.test.ts +3 -12
  534. package/src/mcp/docs-server.ts +7 -27
  535. package/src/mcp/docs-tools.ts +2 -6
  536. package/src/mcp/index.ts +1 -6
  537. package/src/mcp/injection.gate.test.ts +4 -18
  538. package/src/mcp/mcp.test.ts +18 -49
  539. package/src/mcp/protocol.ts +3 -10
  540. package/src/mcp/server.ts +11 -52
  541. package/src/mcp/session.ts +4 -14
  542. package/src/mcp/tools.ts +14 -50
  543. package/src/plugins/catalogue.test.ts +3 -7
  544. package/src/plugins/catalogue.ts +1 -3
  545. package/src/plugins/node-import-scan.ts +2 -5
  546. package/src/plugins/supply-chain.ts +5 -17
  547. package/src/release/exports.ts +3 -8
  548. package/src/release/measure.exports.test.ts +1 -3
  549. package/src/release/measure.ts +15 -43
  550. package/src/runs/bench.test.ts +1 -3
  551. package/src/runs/collect.ts +8 -25
  552. package/src/runs/drivers/clickhouse.ts +2 -9
  553. package/src/runs/drivers/files.ts +9 -31
  554. package/src/runs/drivers/memory.ts +5 -22
  555. package/src/runs/drivers/postgres.ts +8 -20
  556. package/src/runs/duckdb.ts +2 -8
  557. package/src/runs/index.ts +3 -14
  558. package/src/runs/outlier.ts +3 -10
  559. package/src/runs/parquet.ts +8 -26
  560. package/src/runs/privacy.ts +2 -8
  561. package/src/runs/runs.test.ts +3 -9
  562. package/src/runs/runtime.ts +7 -32
  563. package/src/runs/shred.ts +10 -29
  564. package/src/runs/types.ts +1 -4
  565. package/src/runtime/bun.ts +4 -15
  566. package/src/runtime/cold-start.bench.ts +1 -3
  567. package/src/runtime/dev-request-log.test.ts +1 -4
  568. package/src/runtime/dev-request-log.ts +1 -4
  569. package/src/runtime/index.ts +1 -6
  570. package/src/runtime/primitives.ts +5 -4
  571. package/src/runtime/security.ts +3 -13
  572. package/src/runtime/serve.test.ts +4 -7
  573. package/src/runtime/types.ts +1 -4
  574. package/src/runtime/web-standard.ts +3 -15
  575. package/src/term.test.ts +4 -6
  576. package/src/term.ts +49 -98
  577. package/src/test/create-test-app.test.ts +4 -14
  578. package/src/test/create-test-app.ts +13 -31
  579. package/src/test/provisions.integration.test.ts +3 -11
  580. package/src/upgrade/codemods.test.ts +25 -6
  581. package/src/upgrade/codemods.ts +116 -3
  582. package/src/validation/standard-schema.test.ts +2 -5
  583. package/src/validation/standard-schema.ts +13 -33
  584. package/src/console/ui/dist/assets/panel-vault-BbfWdox0.js +0 -1
@@ -0,0 +1,40 @@
1
+ /**
2
+ * One-time interactive `oke dev` mode choice via `@clack/prompts`.
3
+ */
4
+
5
+ import { isCancel, select } from "@clack/prompts";
6
+ import type { DevMode } from "./dev-mode.ts";
7
+
8
+ /**
9
+ * Injectable ask step — production uses {@link askDevMode}.
10
+ *
11
+ * @returns Chosen mode, or `null` if the user cancelled
12
+ */
13
+ export type AskDevModeFn = () => Promise<DevMode | null>;
14
+
15
+ /**
16
+ * Prompt once: local vs docker.
17
+ *
18
+ * @returns Chosen mode, or `null` on cancel
19
+ */
20
+ export async function askDevMode(): Promise<DevMode | null> {
21
+ const value = await select({
22
+ message: "Run against",
23
+ options: [
24
+ {
25
+ value: "local",
26
+ label: "local",
27
+ hint: "in-memory, instant, no Docker needed",
28
+ },
29
+ {
30
+ value: "docker",
31
+ label: "docker",
32
+ hint: "real Postgres/Redis via compose, closer to production",
33
+ },
34
+ ],
35
+ initialValue: "local",
36
+ });
37
+ if (isCancel(value)) return null;
38
+ if (value === "local" || value === "docker") return value;
39
+ return null;
40
+ }
package/src/cli/build.ts CHANGED
@@ -26,8 +26,7 @@ export async function runBuild(options: BuildOptions = {}): Promise<number> {
26
26
  const target = options.target ?? "bun";
27
27
  const entry = options.entry ?? "src/app.ts";
28
28
  const outdir = options.outdir ?? "dist";
29
- const bunTarget =
30
- target === "edge" ? "browser" : target === "node" ? "node" : "bun";
29
+ const bunTarget = target === "edge" ? "browser" : target === "node" ? "node" : "bun";
31
30
 
32
31
  const bundle =
33
32
  options.bundle ??
@@ -6,10 +6,7 @@ import { describe, expect, test } from "bun:test";
6
6
  import { mkdtemp } from "node:fs/promises";
7
7
  import { tmpdir } from "node:os";
8
8
  import { join } from "node:path";
9
- import {
10
- clientAdd,
11
- emitAmbient,
12
- } from "./client-add.ts";
9
+ import { clientAdd, emitAmbient } from "./client-add.ts";
13
10
  import type { ClientDescriptor } from "../client/types.ts";
14
11
 
15
12
  const fixture: ClientDescriptor = {
@@ -72,10 +69,7 @@ void seats;
72
69
  // Minimal stub so `import type { Register }` resolves.
73
70
  const stubDir = join(dir, "node_modules/okengine");
74
71
  await Bun.$`mkdir -p ${stubDir}`.quiet();
75
- await Bun.write(
76
- join(stubDir, "client.d.ts"),
77
- `export interface Register {}\n`,
78
- );
72
+ await Bun.write(join(stubDir, "client.d.ts"), `export interface Register {}\n`);
79
73
  await Bun.write(
80
74
  join(stubDir, "package.json"),
81
75
  JSON.stringify({
@@ -102,10 +96,11 @@ void seats;
102
96
  }),
103
97
  );
104
98
 
105
- const proc = Bun.spawn(
106
- ["bunx", "tsc", "--project", tsconfig],
107
- { cwd: dir, stdout: "pipe", stderr: "pipe" },
108
- );
99
+ const proc = Bun.spawn(["bunx", "tsc", "--project", tsconfig], {
100
+ cwd: dir,
101
+ stdout: "pipe",
102
+ stderr: "pipe",
103
+ });
109
104
  const [stdout, stderr, code] = await Promise.all([
110
105
  new Response(proc.stdout).text(),
111
106
  new Response(proc.stderr).text(),
@@ -113,9 +108,7 @@ void seats;
113
108
  ]);
114
109
 
115
110
  if (code !== 0) {
116
- throw new Error(
117
- `tsc failed (${code})\n${stdout}\n${stderr}\n--- d.ts ---\n${result.source}`,
118
- );
111
+ throw new Error(`tsc failed (${code})\n${stdout}\n${stderr}\n--- d.ts ---\n${result.source}`);
119
112
  }
120
113
  });
121
114
 
@@ -32,12 +32,9 @@ export interface ClientAddResult {
32
32
  *
33
33
  * @param options - URL / out / test overrides
34
34
  */
35
- export async function clientAdd(
36
- options: ClientAddOptions,
37
- ): Promise<ClientAddResult> {
35
+ export async function clientAdd(options: ClientAddOptions): Promise<ClientAddResult> {
38
36
  const out = options.out ?? "oke-client.d.ts";
39
- const descriptor =
40
- options.descriptor ?? (await fetchDescriptor(options.url, options.fetch));
37
+ const descriptor = options.descriptor ?? (await fetchDescriptor(options.url, options.fetch));
41
38
  const source = emitAmbient(descriptor);
42
39
  await Bun.write(out, source);
43
40
  return { out, source };
@@ -102,12 +99,8 @@ export function emitAmbient(descriptor: ClientDescriptor): string {
102
99
  ` in: ${c.in ?? "unknown"};`,
103
100
  ` out: ${c.out ?? "unknown"};`,
104
101
  errorBlock,
105
- c.method
106
- ? ` method: ${JSON.stringify(c.method)};`
107
- : undefined,
108
- c.path
109
- ? ` path: ${JSON.stringify(c.path)};`
110
- : undefined,
102
+ c.method ? ` method: ${JSON.stringify(c.method)};` : undefined,
103
+ c.path ? ` path: ${JSON.stringify(c.path)};` : undefined,
111
104
  ` }`,
112
105
  ]
113
106
  .filter((line): line is string => line !== undefined)
@@ -147,9 +140,7 @@ async function fetchDescriptor(
147
140
  const base = url.replace(/\/+$/, "");
148
141
  const res = await fetchFn(`${base}/_oke/client.json`);
149
142
  if (!res.ok) {
150
- throw new Error(
151
- `Failed to fetch ${base}/_oke/client.json (${res.status})`,
152
- );
143
+ throw new Error(`Failed to fetch ${base}/_oke/client.json (${res.status})`);
153
144
  }
154
145
  const json: unknown = await res.json();
155
146
  if (
@@ -4,11 +4,7 @@
4
4
 
5
5
  import { describe, expect, test } from "bun:test";
6
6
  import { generateCompletion } from "./completion.ts";
7
- import {
8
- OKE_COMMANDS,
9
- commandNames,
10
- type CliCommand,
11
- } from "./registry.ts";
7
+ import { OKE_COMMANDS, commandNames, type CliCommand } from "./registry.ts";
12
8
 
13
9
  describe("oke completion", () => {
14
10
  test("bash script lists every registry command", () => {
@@ -3,12 +3,7 @@
3
3
  */
4
4
 
5
5
  import { EXIT_OK, EXIT_USAGE } from "./exit.ts";
6
- import {
7
- OKE_COMMANDS,
8
- commandNames,
9
- type CliCommand,
10
- type CliFlag,
11
- } from "./registry.ts";
6
+ import { OKE_COMMANDS, commandNames, type CliCommand, type CliFlag } from "./registry.ts";
12
7
 
13
8
  /** Supported completion shells. */
14
9
  export const COMPLETION_SHELLS = ["bash", "zsh", "fish"] as const;
@@ -63,9 +58,7 @@ Install:
63
58
 
64
59
  const shell = args[0];
65
60
  if (!shell || !isCompletionShell(shell)) {
66
- console.error(
67
- "oke completion: require bash, zsh, or fish — e.g. oke completion zsh",
68
- );
61
+ console.error("oke completion: require bash, zsh, or fish — e.g. oke completion zsh");
69
62
  return EXIT_USAGE;
70
63
  }
71
64
 
@@ -223,9 +216,7 @@ function fishScript(commands: readonly CliCommand[]): string {
223
216
  `complete -c oke -f -n "not __fish_seen_subcommand_from ${names}" -a "${cmd.name}" -d ${fishQuote(cmd.summary)}`,
224
217
  );
225
218
  }
226
- rebuilt.push(
227
- `complete -c oke -f -n "__fish_seen_subcommand_from completion" -a "bash zsh fish"`,
228
- );
219
+ rebuilt.push(`complete -c oke -f -n "__fish_seen_subcommand_from completion" -a "bash zsh fish"`);
229
220
  for (const cmd of commands) {
230
221
  const subs = cmd.subcommands ?? [];
231
222
  if (subs.length === 0) {
@@ -248,11 +239,7 @@ function fishScript(commands: readonly CliCommand[]): string {
248
239
  return `${rebuilt.join("\n")}\n`;
249
240
  }
250
241
 
251
- function fishFlagLine(
252
- command: string,
253
- sub: string | undefined,
254
- flag: CliFlag,
255
- ): string {
242
+ function fishFlagLine(command: string, sub: string | undefined, flag: CliFlag): string {
256
243
  const seen = sub
257
244
  ? `__fish_seen_subcommand_from ${command}; and __fish_seen_subcommand_from ${sub}`
258
245
  : `__fish_seen_subcommand_from ${command}`;
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Domain schema watch-path + auto-push policy.
3
+ */
4
+
5
+ import { describe, expect, test } from "bun:test";
6
+ import {
7
+ createDebouncedRunner,
8
+ isDomainSchemaWatchPath,
9
+ resolveDevAutoPush,
10
+ } from "./db-auto-push.ts";
11
+
12
+ describe("isDomainSchemaWatchPath", () => {
13
+ test("matches schema.ts and drizzle.config.ts", () => {
14
+ expect(isDomainSchemaWatchPath("schema.ts")).toBe(true);
15
+ expect(isDomainSchemaWatchPath("drizzle.config.ts")).toBe(true);
16
+ expect(isDomainSchemaWatchPath("flows/notes/schema.ts")).toBe(true);
17
+ expect(isDomainSchemaWatchPath("src/schema.decl.ts")).toBe(true);
18
+ expect(isDomainSchemaWatchPath("src/schema.generated.ts")).toBe(true);
19
+ });
20
+
21
+ test("ignores unrelated files", () => {
22
+ expect(isDomainSchemaWatchPath("flows/notes/index.ts")).toBe(false);
23
+ expect(isDomainSchemaWatchPath(undefined)).toBe(false);
24
+ });
25
+
26
+ test("matches app entry (plugin .table contributions)", () => {
27
+ expect(isDomainSchemaWatchPath("app.ts")).toBe(true);
28
+ expect(isDomainSchemaWatchPath("src/app.ts")).toBe(true);
29
+ });
30
+ });
31
+
32
+ describe("resolveDevAutoPush", () => {
33
+ test("default on for local", () => {
34
+ expect(resolveDevAutoPush({})).toBe(true);
35
+ });
36
+
37
+ test("off for docker", () => {
38
+ expect(resolveDevAutoPush({ docker: true })).toBe(false);
39
+ });
40
+
41
+ test("off for --no-db-push", () => {
42
+ expect(resolveDevAutoPush({ noDbPush: true })).toBe(false);
43
+ });
44
+
45
+ test("off when config.db.autoPush is false", () => {
46
+ expect(resolveDevAutoPush({ configAutoPush: false })).toBe(false);
47
+ });
48
+ });
49
+
50
+ describe("createDebouncedRunner", () => {
51
+ test("coalesces rapid triggers", async () => {
52
+ let count = 0;
53
+ const runner = createDebouncedRunner(() => {
54
+ count++;
55
+ }, 40);
56
+ runner.trigger();
57
+ runner.trigger();
58
+ runner.trigger();
59
+ expect(count).toBe(0);
60
+ await Bun.sleep(80);
61
+ expect(count).toBe(1);
62
+ runner.cancel();
63
+ });
64
+ });
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Debounced domain-schema auto-push for `oke dev` (local mode).
3
+ */
4
+
5
+ import { basename } from "node:path";
6
+
7
+ /** Default debounce for schema-change → push. */
8
+ export const DB_AUTO_PUSH_DEBOUNCE_MS = 300;
9
+
10
+ /**
11
+ * Whether a watched path should trigger `oke db push`.
12
+ *
13
+ * @param filename - Relative path from the watcher (may be undefined)
14
+ */
15
+ export function isDomainSchemaWatchPath(filename: string | null | undefined): boolean {
16
+ if (!filename) return false;
17
+ const normalized = filename.replace(/\\/g, "/");
18
+ const base = basename(normalized);
19
+ if (base === "schema.ts" || base === "schema.tsx") return true;
20
+ if (base === "schema.decl.ts" || base === "schema.decl.tsx") return true;
21
+ if (base === "schema.generated.ts" || base === "schema.generated.tsx") return true;
22
+ if (base === "drizzle.config.ts" || base === "drizzle.config.js") return true;
23
+ // App entry / plugins — `.plug()` table contributions feed emit.
24
+ if (base === "app.ts" || base === "app.tsx") return true;
25
+ // Nested domain schemas commonly live under src/**/schema.ts
26
+ if (/(^|\/)schema(\.decl|\.generated)?\.tsx?$/.test(normalized)) return true;
27
+ return false;
28
+ }
29
+
30
+ /**
31
+ * Resolve whether auto-push is enabled for this `oke dev` session.
32
+ *
33
+ * @param options - Explicit CLI opt-out, config, docker mode
34
+ */
35
+ export function resolveDevAutoPush(options: {
36
+ readonly noDbPush?: boolean;
37
+ readonly docker?: boolean;
38
+ readonly configAutoPush?: boolean;
39
+ }): boolean {
40
+ if (options.docker) return false;
41
+ if (options.noDbPush) return false;
42
+ return options.configAutoPush !== false;
43
+ }
44
+
45
+ /**
46
+ * Create a debounced callback runner.
47
+ *
48
+ * @param fn - Async work
49
+ * @param ms - Debounce window
50
+ */
51
+ export function createDebouncedRunner(
52
+ fn: () => void | Promise<void>,
53
+ ms = DB_AUTO_PUSH_DEBOUNCE_MS,
54
+ ): {
55
+ readonly trigger: () => void;
56
+ readonly cancel: () => void;
57
+ } {
58
+ let timer: ReturnType<typeof setTimeout> | null = null;
59
+ return {
60
+ trigger() {
61
+ if (timer) clearTimeout(timer);
62
+ timer = setTimeout(() => {
63
+ timer = null;
64
+ void fn();
65
+ }, ms);
66
+ },
67
+ cancel() {
68
+ if (timer) clearTimeout(timer);
69
+ timer = null;
70
+ },
71
+ };
72
+ }
@@ -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
+ });