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
@@ -99,50 +99,43 @@ export const OKE_ERRORS = {
99
99
  /** Flow reads a store resource not listed in `effects.reads`. */
100
100
  UNDECLARED_READ: {
101
101
  code: 1001,
102
- cause:
103
- 'Flow "{flow}" reads "{resource}" without declaring it.',
102
+ cause: 'Flow "{flow}" reads "{resource}" without declaring it.',
104
103
  fix: 'Add "{resource}" to this flow\'s effects.reads.',
105
104
  },
106
105
  /** Flow writes a store resource not listed in `effects.writes`. */
107
106
  UNDECLARED_WRITE: {
108
107
  code: 1002,
109
- cause:
110
- 'Flow "{flow}" writes "{resource}" without declaring it.',
108
+ cause: 'Flow "{flow}" writes "{resource}" without declaring it.',
111
109
  fix: 'Add "{resource}" to this flow\'s effects.writes.',
112
110
  },
113
111
  /** Flow emits a signal not listed in `effects.emits`. */
114
112
  UNDECLARED_EMIT: {
115
113
  code: 1003,
116
- cause:
117
- 'Flow "{flow}" emits "{resource}" without declaring it.',
114
+ cause: 'Flow "{flow}" emits "{resource}" without declaring it.',
118
115
  fix: 'Add "{resource}" to this flow\'s effects.emits.',
119
116
  },
120
117
  /** Flow sends a channel template not listed in `effects.sends`. */
121
118
  UNDECLARED_SEND: {
122
119
  code: 1004,
123
- cause:
124
- 'Flow "{flow}" sends "{resource}" without declaring it.',
120
+ cause: 'Flow "{flow}" sends "{resource}" without declaring it.',
125
121
  fix: 'Add "{resource}" to this flow\'s effects.sends.',
126
122
  },
127
123
  /** Flow asks a prompt not listed in `effects.asks`. */
128
124
  UNDECLARED_ASK: {
129
125
  code: 1005,
130
- cause:
131
- 'Flow "{flow}" asks "{resource}" without declaring it.',
126
+ cause: 'Flow "{flow}" asks "{resource}" without declaring it.',
132
127
  fix: 'Add "{resource}" to this flow\'s effects.asks.',
133
128
  },
134
129
  /** Flow reads a secret not listed in `effects.secrets`. */
135
130
  UNDECLARED_SECRET: {
136
131
  code: 1006,
137
- cause:
138
- 'Flow "{flow}" reads secret "{resource}" without declaring it.',
132
+ cause: 'Flow "{flow}" reads secret "{resource}" without declaring it.',
139
133
  fix: 'Add "{resource}" to this flow\'s effects.secrets.',
140
134
  },
141
135
  /** Flow calls another flow not listed in `effects.calls`. */
142
136
  UNDECLARED_CALL: {
143
137
  code: 1007,
144
- cause:
145
- 'Flow "{flow}" calls "{resource}" without declaring it.',
138
+ cause: 'Flow "{flow}" calls "{resource}" without declaring it.',
146
139
  fix: 'Add "{resource}" to this flow\'s effects.calls.',
147
140
  },
148
141
  /**
@@ -151,9 +144,17 @@ export const OKE_ERRORS = {
151
144
  */
152
145
  ORPHAN_EMIT: {
153
146
  code: 1042,
154
- cause:
155
- 'Flow "{flow}" emits signal "{resource}" with no subscriber.',
156
- fix: 'Add `on({resource}, …)` or mark the signal `{ optional: true }`.',
147
+ cause: 'Flow "{flow}" emits signal "{resource}" with no subscriber.',
148
+ fix: "Add `on({resource}, …)` or mark the signal `{ optional: true }`.",
149
+ },
150
+ /**
151
+ * Domain table/column missing under docker/prod (migrations not applied).
152
+ * Store/DDL band starts at 1100.
153
+ */
154
+ DOMAIN_SCHEMA_MISSING: {
155
+ code: 1101,
156
+ cause: "domain table not found — migrations have not been applied.",
157
+ fix: "run `oke db migrate` against this environment.",
157
158
  },
158
159
  } as const satisfies Record<string, OkeErrorDefinition>;
159
160
 
@@ -164,10 +165,7 @@ export const OKE_ERRORS = {
164
165
  * @param params - Interpolation params
165
166
  * @returns Never
166
167
  */
167
- export function throwOke(
168
- key: keyof typeof OKE_ERRORS,
169
- params: OkeErrorParams = {},
170
- ): never {
168
+ export function throwOke(key: keyof typeof OKE_ERRORS, params: OkeErrorParams = {}): never {
171
169
  throw new OkeError(OKE_ERRORS[key], params);
172
170
  }
173
171
 
@@ -176,9 +174,7 @@ export function throwOke(
176
174
  *
177
175
  * @param code - Permanent numeric code
178
176
  */
179
- export function lookupOkeError(
180
- code: OkeErrorCode,
181
- ): OkeErrorDefinition | undefined {
177
+ export function lookupOkeError(code: OkeErrorCode): OkeErrorDefinition | undefined {
182
178
  for (const def of Object.values(OKE_ERRORS)) {
183
179
  if (def.code === code) return def;
184
180
  }
@@ -192,14 +188,9 @@ export function lookupOkeError(
192
188
  * @param data - Error payload
193
189
  * @param opts - Optional message override
194
190
  */
195
- export function fail<E>(
196
- code: string,
197
- data: E,
198
- opts?: FailOptions,
199
- ): FlowFailure<E> {
200
- const error: FlowErrorValue<E> = opts?.message !== undefined
201
- ? { code, data, message: opts.message }
202
- : { code, data };
191
+ export function fail<E>(code: string, data: E, opts?: FailOptions): FlowFailure<E> {
192
+ const error: FlowErrorValue<E> =
193
+ opts?.message !== undefined ? { code, data, message: opts.message } : { code, data };
203
194
  return { data: null, error };
204
195
  }
205
196
 
@@ -2,12 +2,7 @@ import { describe, expect, test, beforeEach } from "bun:test";
2
2
  import { oke } from "./app.ts";
3
3
  import { flow, isFlow, resetFlowSeq } from "./flow.ts";
4
4
  import { on, resetBindings } from "./on.ts";
5
- import {
6
- every,
7
- http,
8
- internal,
9
- table,
10
- } from "./triggers.ts";
5
+ import { every, http, internal, table } from "./triggers.ts";
11
6
 
12
7
  beforeEach(() => {
13
8
  resetBindings();
@@ -55,11 +50,7 @@ describe("flow — one species", () => {
55
50
  expect(app.bindings[0]?.flow).toBe(shared);
56
51
  expect(app.bindings[1]?.flow).toBe(shared);
57
52
 
58
- const httpResult = await app.execute(
59
- shared,
60
- { n: 3 },
61
- shared.triggers[0]!,
62
- );
53
+ const httpResult = await app.execute(shared, { n: 3 }, shared.triggers[0]!);
63
54
  const signalResults = await app.dispatchSignal("order-placed", { n: 4 });
64
55
 
65
56
  expect(httpResult.output).toEqual({ n: 6 });
@@ -126,29 +117,25 @@ describe("five trigger kinds", () => {
126
117
 
127
118
  const app = oke({ name: "five" });
128
119
 
129
- const res = await app.fetch(
130
- new Request("http://localhost/abc", { method: "GET" }),
131
- );
120
+ const res = await app.fetch(new Request("http://localhost/abc", { method: "GET" }));
132
121
  expect(res.status).toBe(200);
133
122
  expect(await res.json()).toEqual({ data: { code: "abc" }, error: null });
134
123
 
135
124
  await app.dispatchEvery("1h");
136
125
  await app.dispatchSignal("link-clicked", { code: "sa" });
137
- await app.dispatchCdc("orders", {
138
- before: { status: "open" },
139
- after: { status: "paid" },
140
- }, "status");
126
+ await app.dispatchCdc(
127
+ "orders",
128
+ {
129
+ before: { status: "open" },
130
+ after: { status: "paid" },
131
+ },
132
+ "status",
133
+ );
141
134
 
142
135
  const internalResult = await app.call("t.internal");
143
136
  expect(internalResult).toEqual({ ok: true });
144
137
 
145
- expect(seen).toEqual([
146
- "http:abc",
147
- "every",
148
- "signal:sa",
149
- "cdc:open->paid",
150
- "internal",
151
- ]);
138
+ expect(seen).toEqual(["http:abc", "every", "signal:sa", "cdc:open->paid", "internal"]);
152
139
  expect(httpFlow.triggers[0]?.kind).toBe("http");
153
140
  });
154
141
  });
@@ -7,20 +7,14 @@
7
7
  */
8
8
 
9
9
  import type { Effects, FlowPlane, Slo } from "../manifest/types.ts";
10
- import type {
11
- InferSchemaOutput,
12
- SchemaInput,
13
- } from "../validation/standard-schema.ts";
10
+ import type { InferSchemaOutput, SchemaInput } from "../validation/standard-schema.ts";
14
11
  import type { FlowFailure } from "./errors.ts";
15
12
  import type { Fx } from "./fx.ts";
16
13
  import type { HookFn, HookStage } from "./hooks.ts";
17
14
  import type { PluginDef } from "./plugin.ts";
18
15
  import type { Trigger } from "./triggers.ts";
19
16
 
20
- export type {
21
- SchemaInput,
22
- StandardSchemaV1,
23
- } from "../validation/standard-schema.ts";
17
+ export type { SchemaInput, StandardSchemaV1 } from "../validation/standard-schema.ts";
24
18
 
25
19
  /** Result of a Standard Schema validate call (re-export shape). */
26
20
  export type StandardSchemaResult<Output> =
@@ -42,11 +36,7 @@ export type FlowHandler<I = unknown, O = unknown> = (
42
36
  ) => O | FlowFailure | Promise<O | FlowFailure>;
43
37
 
44
38
  /** Options for {@link flow}. */
45
- export interface FlowOptions<
46
- I = unknown,
47
- O = unknown,
48
- E extends FlowErrorMap = FlowErrorMap,
49
- > {
39
+ export interface FlowOptions<I = unknown, O = unknown, E extends FlowErrorMap = FlowErrorMap> {
50
40
  /** Optional stable name (used by `fx.call` and the Manifest). */
51
41
  readonly name?: string;
52
42
  /** Optional unit scope for unit-level hooks. */
@@ -192,13 +182,7 @@ export interface FlowDef<
192
182
  */
193
183
  plug<P extends PluginDef>(
194
184
  pluginDef: P,
195
- ): FlowDef<
196
- I,
197
- O,
198
- E,
199
- D & (P extends PluginDef<infer PD> ? PD : Record<string, never>),
200
- T
201
- >;
185
+ ): FlowDef<I, O, E, D & (P extends PluginDef<infer PD> ? PD : Record<string, never>), T>;
202
186
  }
203
187
 
204
188
  /** Unique brand symbol for {@link FlowDef}. */
@@ -222,11 +206,7 @@ export function flow<Opts extends FlowOptions<any, any, any>>(
222
206
  const hooks: Partial<Record<HookStage, HookFn[]>> = {};
223
207
  const pendingPlugins: PluginDef[] = [];
224
208
 
225
- const def: FlowDef<
226
- InferFlowIn<Opts>,
227
- InferFlowOut<Opts>,
228
- InferFlowErrors<Opts>
229
- > = {
209
+ const def: FlowDef<InferFlowIn<Opts>, InferFlowOut<Opts>, InferFlowErrors<Opts>> = {
230
210
  [flowBrand]: true,
231
211
  name,
232
212
  unit: options.unit,
@@ -1,19 +1,8 @@
1
1
  import { describe, expect, test } from "bun:test";
2
2
  import { createCapabilityToken } from "./capability.ts";
3
3
  import { createEffectLedger, reversibilityOf } from "./effects.ts";
4
- import {
5
- fail,
6
- formatOkeMessage,
7
- lookupOkeError,
8
- OKE_ERRORS,
9
- OkeError,
10
- } from "./errors.ts";
11
- import {
12
- createFx,
13
- createFxContext,
14
- type Fx,
15
- type FxStubStoreHandle,
16
- } from "./fx.ts";
4
+ import { fail, formatOkeMessage, lookupOkeError, OKE_ERRORS, OkeError } from "./errors.ts";
5
+ import { createFx, createFxContext, type Fx, type FxStubStoreHandle } from "./fx.ts";
17
6
 
18
7
  /** Narrow stub handle for tests that exercise the in-memory store. */
19
8
  function stub(fx: Fx, ref: string): FxStubStoreHandle {
@@ -37,16 +26,10 @@ describe("fx — capability enforcement", () => {
37
26
  expect(err).toBeInstanceOf(OkeError);
38
27
  const oke = err as OkeError;
39
28
  expect(oke.code).toBe(1001);
40
- expect(oke.causeText).toBe(
41
- 'Flow "bookings.create" reads "sql:users" without declaring it.',
42
- );
43
- expect(oke.fix).toBe(
44
- 'Add "sql:users" to this flow\'s effects.reads.',
45
- );
29
+ expect(oke.causeText).toBe('Flow "bookings.create" reads "sql:users" without declaring it.');
30
+ expect(oke.fix).toBe('Add "sql:users" to this flow\'s effects.reads.');
46
31
  expect(oke.docsUrl).toBe("https://okengine.vercel.app/e/1001");
47
- expect(oke.message).toBe(
48
- formatOkeMessage(1001, oke.causeText, oke.fix, oke.docsUrl),
49
- );
32
+ expect(oke.message).toBe(formatOkeMessage(1001, oke.causeText, oke.fix, oke.docsUrl));
50
33
  });
51
34
 
52
35
  test("declared store read succeeds", async () => {
@@ -79,21 +62,13 @@ describe("fx — effect ledger", () => {
79
62
  await fx.emit("order-placed", { orderId: "o1" });
80
63
 
81
64
  expect(ledger.entries).toHaveLength(3);
82
- expect(ledger.entries.map((e) => e.kind)).toEqual([
83
- "read",
84
- "write",
85
- "emit",
86
- ]);
65
+ expect(ledger.entries.map((e) => e.kind)).toEqual(["read", "write", "emit"]);
87
66
  expect(ledger.entries.map((e) => e.resource)).toEqual([
88
67
  "sql:bookings",
89
68
  "sql:bookings",
90
69
  "order-placed",
91
70
  ]);
92
- expect(ledger.entries.map((e) => e.reversibility)).toEqual([
93
- "none",
94
- "reversible",
95
- "deferred",
96
- ]);
71
+ expect(ledger.entries.map((e) => e.reversibility)).toEqual(["none", "reversible", "deferred"]);
97
72
  });
98
73
 
99
74
  test("all seven kinds receive the correct reversibility tier via fx", async () => {
@@ -123,15 +98,7 @@ describe("fx — effect ledger", () => {
123
98
 
124
99
  expect(ledger.entries).toHaveLength(7);
125
100
  const kinds = ledger.entries.map((e) => e.kind);
126
- expect(kinds).toEqual([
127
- "read",
128
- "write",
129
- "emit",
130
- "send",
131
- "ask",
132
- "secret",
133
- "call",
134
- ]);
101
+ expect(kinds).toEqual(["read", "write", "emit", "send", "ask", "secret", "call"]);
135
102
  for (const entry of ledger.entries) {
136
103
  expect(entry.reversibility).toBe(reversibilityOf(entry.kind));
137
104
  }
@@ -224,9 +191,13 @@ describe("errors — registry", () => {
224
191
 
225
192
  test("fx.fail returns a value, not an exception", () => {
226
193
  const fx = createFx({ flow: "x", effects: {} });
227
- const result = fx.fail("FlightFull", { seatsLeft: 0 }, {
228
- message: "full",
229
- });
194
+ const result = fx.fail(
195
+ "FlightFull",
196
+ { seatsLeft: 0 },
197
+ {
198
+ message: "full",
199
+ },
200
+ );
230
201
  expect(result).toEqual({
231
202
  data: null,
232
203
  error: { code: "FlightFull", data: { seatsLeft: 0 }, message: "full" },
package/src/kernel/fx.ts CHANGED
@@ -10,27 +10,14 @@
10
10
  */
11
11
 
12
12
  import type { Effects, ResourceRef } from "../manifest/types.ts";
13
- import type {
14
- StoreDecl,
15
- StoreHandle,
16
- StoreRuntime,
17
- SqlStoreHandle,
18
- } from "../elements/store.ts";
13
+ import type { StoreDecl, StoreHandle, StoreRuntime, SqlStoreHandle } from "../elements/store.ts";
19
14
  import type { SignalRuntime } from "../elements/signal.ts";
20
15
  import type { VaultRuntime } from "../elements/vault.ts";
21
16
  import type { ChannelRuntime } from "../elements/channel.ts";
22
17
  import type { AiRuntime } from "../elements/ai.ts";
23
18
  import { parseDurationMs } from "../elements/clock/duration.ts";
24
- import {
25
- createCapabilityToken,
26
- type CapabilityToken,
27
- } from "./capability.ts";
28
- import {
29
- createEffectLedger,
30
- recordEffect,
31
- reversibilityOf,
32
- type EffectLedger,
33
- } from "./effects.ts";
19
+ import { createCapabilityToken, type CapabilityToken } from "./capability.ts";
20
+ import { createEffectLedger, recordEffect, reversibilityOf, type EffectLedger } from "./effects.ts";
34
21
  import {
35
22
  DryRunWriteIsolationError,
36
23
  isDryRun,
@@ -202,17 +189,15 @@ export interface FxSearchOptions {
202
189
  * Implementations must be plain objects so tests can replace `fx` wholesale.
203
190
  */
204
191
  export interface Fx {
205
- /**
206
- * Open a store handle for `ref` (capability checked on each op).
207
- *
208
- * When a {@link CreateFxOptions.storeRuntime} is bound and `ref` is a
209
- * registered store declaration, returns the driver-backed handle.
210
- *
211
- * @param ref - Store resource ref, named handle, or store declaration
212
- */
213
- store(
214
- ref: NamedRef | { readonly ref: ResourceRef } | StoreDecl,
215
- ): FxStoreHandle;
192
+ /**
193
+ * Open a store handle for `ref` (capability checked on each op).
194
+ *
195
+ * When a {@link CreateFxOptions.storeRuntime} is bound and `ref` is a
196
+ * registered store declaration, returns the driver-backed handle.
197
+ *
198
+ * @param ref - Store resource ref, named handle, or store declaration
199
+ */
200
+ store(ref: NamedRef | { readonly ref: ResourceRef } | StoreDecl): FxStoreHandle;
216
201
  /**
217
202
  * Emit a signal (records `emit`).
218
203
  *
@@ -251,11 +236,7 @@ export interface Fx {
251
236
  * @param input - Prompt input
252
237
  * @param opts - Model routing opts
253
238
  */
254
- ask(
255
- prompt: NamedRef,
256
- input?: unknown,
257
- opts?: FxAskOptions,
258
- ): Promise<Record<string, unknown>>;
239
+ ask(prompt: NamedRef, input?: unknown, opts?: FxAskOptions): Promise<Record<string, unknown>>;
259
240
  /**
260
241
  * Similarity search over an index/embed (records `read` on the embed ref).
261
242
  *
@@ -263,21 +244,14 @@ export interface Fx {
263
244
  * @param query - Query text or vector
264
245
  * @param opts - Search options
265
246
  */
266
- search(
267
- embed: NamedRef,
268
- query: unknown,
269
- opts?: FxSearchOptions,
270
- ): Promise<unknown[]>;
247
+ search(embed: NamedRef, query: unknown, opts?: FxSearchOptions): Promise<unknown[]>;
271
248
  /**
272
249
  * Run a bounded AI agent (records `ask`).
273
250
  *
274
251
  * @param agent - Agent name or handle
275
252
  * @param input - Agent input (`{ message }` or string)
276
253
  */
277
- run(
278
- agent: NamedRef,
279
- input?: unknown,
280
- ): Promise<unknown>;
254
+ run(agent: NamedRef, input?: unknown): Promise<unknown>;
281
255
  /**
282
256
  * Stream model tokens (records `ask`). Returns an async iterable of chunks.
283
257
  *
@@ -326,10 +300,7 @@ export interface Fx {
326
300
  * Dispatch target for {@link Fx.call}. Wired by the app so untriggered
327
301
  * flows execute through the same pipeline as triggered ones.
328
302
  */
329
- export type FxCallHandler = (
330
- name: string,
331
- input: unknown,
332
- ) => Promise<unknown>;
303
+ export type FxCallHandler = (name: string, input: unknown) => Promise<unknown>;
333
304
 
334
305
  /** Options for {@link createFx}. */
335
306
  export interface CreateFxOptions {
@@ -352,9 +323,7 @@ export interface CreateFxOptions {
352
323
  /** Secret name → value map for `fx.vault`. */
353
324
  readonly secrets?: Readonly<Record<string, string>>;
354
325
  /** Seed data for in-memory stores: ref → key → value. */
355
- readonly storeData?: Readonly<
356
- Record<string, Readonly<Record<string, unknown>>>
357
- >;
326
+ readonly storeData?: Readonly<Record<string, Readonly<Record<string, unknown>>>>;
358
327
  /** Optional log sink (defaults to no-op). */
359
328
  readonly onLog?: (
360
329
  level: "debug" | "info" | "warn" | "error",
@@ -435,9 +404,7 @@ export function createFx(options: CreateFxOptions): Fx {
435
404
  */
436
405
  export function createFxContext(options: CreateFxOptions): FxContext {
437
406
  const ledger = options.ledger ?? createEffectLedger();
438
- const capability =
439
- options.capability ??
440
- createCapabilityToken(options.flow, options.effects);
407
+ const capability = options.capability ?? createCapabilityToken(options.flow, options.effects);
441
408
  const now = options.now ?? (() => Date.now());
442
409
  const secrets = options.secrets ?? {};
443
410
  const onLog = options.onLog;
@@ -499,15 +466,12 @@ export function createFxContext(options: CreateFxOptions): FxContext {
499
466
  select(): Promise<unknown[]> {
500
467
  return gated("read", ref, () => {
501
468
  const values = [...table().values()];
502
- return isDryRun()
503
- ? values.map((v) => structuredClone(v))
504
- : values;
469
+ return isDryRun() ? values.map((v) => structuredClone(v)) : values;
505
470
  });
506
471
  },
507
472
  insert(row: Record<string, unknown>): Promise<{ id: string }> {
508
473
  return gated("write", ref, () => {
509
- const id =
510
- typeof row.id === "string" ? row.id : crypto.randomUUID();
474
+ const id = typeof row.id === "string" ? row.id : crypto.randomUUID();
511
475
  table().set(id, { ...row, id });
512
476
  return { id };
513
477
  });
@@ -532,10 +496,7 @@ export function createFxContext(options: CreateFxOptions): FxContext {
532
496
  * @param decl - Store declaration
533
497
  * @param open - Opens (and caches) the runtime handle
534
498
  */
535
- function gatedSqlHandle(
536
- decl: StoreDecl,
537
- open: () => Promise<SqlStoreHandle>,
538
- ): SqlStoreHandle {
499
+ function gatedSqlHandle(decl: StoreDecl, open: () => Promise<SqlStoreHandle>): SqlStoreHandle {
539
500
  const ref = decl.ref as `sql:${string}`;
540
501
  let cached: SqlStoreHandle | undefined;
541
502
  const ensure = async (): Promise<SqlStoreHandle> => {
@@ -684,9 +645,7 @@ export function createFxContext(options: CreateFxOptions): FxContext {
684
645
  } as SqlStoreHandle;
685
646
  }
686
647
 
687
- function storeHandle(
688
- ref: NamedRef | { readonly ref: ResourceRef } | StoreDecl,
689
- ): FxStoreHandle {
648
+ function storeHandle(ref: NamedRef | { readonly ref: ResourceRef } | StoreDecl): FxStoreHandle {
690
649
  const runtime = options.storeRuntime;
691
650
  if (runtime && typeof ref === "object" && ref !== null && "facet" in ref) {
692
651
  const decl = ref;
@@ -714,8 +673,7 @@ export function createFxContext(options: CreateFxOptions): FxContext {
714
673
  get(_t, prop) {
715
674
  if (prop === "ref") return baseRef;
716
675
  if (prop === "then") return undefined;
717
- const isRead =
718
- prop === "get" || prop === "search" || prop === "list";
676
+ const isRead = prop === "get" || prop === "search" || prop === "list";
719
677
  return (...args: unknown[]) =>
720
678
  gated(isRead ? "read" : "write", baseRef, async () => {
721
679
  if (!isRead && isDryRun()) {
@@ -724,18 +682,14 @@ export function createFxContext(options: CreateFxOptions): FxContext {
724
682
  );
725
683
  }
726
684
  const h = await open();
727
- const fn = (h as unknown as Record<string | symbol, unknown>)[
728
- prop
729
- ];
685
+ const fn = (h as unknown as Record<string | symbol, unknown>)[prop];
730
686
  if (typeof fn !== "function") return undefined;
731
687
  return (fn as (...a: unknown[]) => unknown).apply(h, args);
732
688
  });
733
689
  },
734
690
  });
735
691
  }
736
- return stubStoreHandle(
737
- resolveStoreRef(ref as NamedRef | { readonly ref: ResourceRef }),
738
- );
692
+ return stubStoreHandle(resolveStoreRef(ref as NamedRef | { readonly ref: ResourceRef }));
739
693
  }
740
694
 
741
695
  const clock: FxClock = {
@@ -768,11 +722,7 @@ export function createFxContext(options: CreateFxOptions): FxContext {
768
722
  if (aiDisablesCache) return;
769
723
  cacheStore.set(key, value);
770
724
  },
771
- async getOrSet<T>(
772
- key: string,
773
- _ttl: string,
774
- produce: () => T | Promise<T>,
775
- ): Promise<T> {
725
+ async getOrSet<T>(key: string, _ttl: string, produce: () => T | Promise<T>): Promise<T> {
776
726
  if (aiDisablesCache) return await produce();
777
727
  if (cacheStore.has(key)) {
778
728
  if (telemetry) telemetry.cacheHits += 1;
@@ -792,9 +742,7 @@ export function createFxContext(options: CreateFxOptions): FxContext {
792
742
  const vault = options.vaultRuntime;
793
743
  if (!vault) return { message, data };
794
744
  const safeMessage = vault.redactString(message);
795
- const safeData = data
796
- ? (vault.redact(data) as Record<string, unknown>)
797
- : undefined;
745
+ const safeData = data ? (vault.redact(data) as Record<string, unknown>) : undefined;
798
746
  return { message: safeMessage, data: safeData };
799
747
  }
800
748
 
@@ -49,12 +49,9 @@ describe("hook timing", () => {
49
49
 
50
50
  test("registry tags hooks at plug time", async () => {
51
51
  const registry = createPluginRegistry();
52
- const p = plugin("metered", { version: "1.0.0" }).hook(
53
- "onRequest",
54
- async () => {
55
- await Bun.sleep(1);
56
- },
57
- );
52
+ const p = plugin("metered", { version: "1.0.0" }).hook("onRequest", async () => {
53
+ await Bun.sleep(1);
54
+ });
58
55
  applyPlugin(registry, p, appPluginScope);
59
56
  const hooks = registry.hooksAt("app", undefined, "x");
60
57
  const ctx: InvocationContext = {
@@ -132,10 +132,7 @@ export function resetHookCosts(): void {
132
132
  filled = 0;
133
133
  }
134
134
 
135
- function summarize(
136
- pluginId: string,
137
- mine: readonly HookCostSample[],
138
- ): HookCostSummary {
135
+ function summarize(pluginId: string, mine: readonly HookCostSample[]): HookCostSummary {
139
136
  if (mine.length === 0) {
140
137
  return {
141
138
  pluginId,
@@ -149,18 +146,15 @@ function summarize(
149
146
  }
150
147
  const durations = mine.map((s) => s.durationMs).sort((a, b) => a - b);
151
148
  const sum = durations.reduce((a, b) => a + b, 0);
152
- const byStageAcc: Partial<
153
- Record<HookStage, { count: number; total: number }>
154
- > = {};
149
+ const byStageAcc: Partial<Record<HookStage, { count: number; total: number }>> = {};
155
150
  for (const s of mine) {
156
151
  const cur = byStageAcc[s.stage] ?? { count: 0, total: 0 };
157
152
  cur.count++;
158
153
  cur.total += s.durationMs;
159
154
  byStageAcc[s.stage] = cur;
160
155
  }
161
- const byStage: Partial<
162
- Record<HookStage, { readonly count: number; readonly meanMs: number }>
163
- > = {};
156
+ const byStage: Partial<Record<HookStage, { readonly count: number; readonly meanMs: number }>> =
157
+ {};
164
158
  for (const [stage, acc] of Object.entries(byStageAcc) as Array<
165
159
  [HookStage, { count: number; total: number }]
166
160
  >) {
@@ -182,9 +176,6 @@ function summarize(
182
176
 
183
177
  function percentile(sorted: readonly number[], p: number): number {
184
178
  if (sorted.length === 0) return 0;
185
- const idx = Math.min(
186
- sorted.length - 1,
187
- Math.max(0, Math.ceil(p * sorted.length) - 1),
188
- );
179
+ const idx = Math.min(sorted.length - 1, Math.max(0, Math.ceil(p * sorted.length) - 1));
189
180
  return sorted[idx]!;
190
181
  }
@@ -26,11 +26,9 @@ describe("hooks — order and composition", () => {
26
26
 
27
27
  test("mergeHooks is app → unit → flow, registration order within", () => {
28
28
  const order: string[] = [];
29
- const mark =
30
- (label: string) =>
31
- () => {
32
- order.push(label);
33
- };
29
+ const mark = (label: string) => () => {
30
+ order.push(label);
31
+ };
34
32
 
35
33
  const merged = mergeHooks(
36
34
  { onRequest: [mark("app1"), mark("app2")] },
@@ -66,11 +64,13 @@ describe("hooks — order and composition", () => {
66
64
  order.push("handler");
67
65
  return { ok: true };
68
66
  },
69
- }).hook("beforeHandle", () => {
70
- order.push("flow:beforeHandle");
71
- }).hook("afterHandle", () => {
72
- order.push("flow:afterHandle");
73
- });
67
+ })
68
+ .hook("beforeHandle", () => {
69
+ order.push("flow:beforeHandle");
70
+ })
71
+ .hook("afterHandle", () => {
72
+ order.push("flow:afterHandle");
73
+ });
74
74
 
75
75
  on(http.get("/ordered"), f);
76
76