okengine 0.1.4

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 (674) hide show
  1. package/AGENTS.md +91 -0
  2. package/README.md +327 -0
  3. package/docs/spec/complete-example.md +1188 -0
  4. package/docs/spec/console.md +739 -0
  5. package/docs/spec/four-applications.md +1188 -0
  6. package/docs/spec/unified-theory.md +489 -0
  7. package/package.json +152 -0
  8. package/spec/manifest.v1.schema.json +624 -0
  9. package/src/auth/api-keys.ts +168 -0
  10. package/src/auth/attenuation.ts +116 -0
  11. package/src/auth/auth.test.ts +273 -0
  12. package/src/auth/cross-plane.ts +98 -0
  13. package/src/auth/index.ts +112 -0
  14. package/src/auth/invites.ts +66 -0
  15. package/src/auth/invoke-as.ts +49 -0
  16. package/src/auth/operator.ts +178 -0
  17. package/src/auth/planes.ts +102 -0
  18. package/src/auth/plugin.ts +44 -0
  19. package/src/auth/roles.ts +84 -0
  20. package/src/auth/sessions.ts +418 -0
  21. package/src/auth/tables.ts +131 -0
  22. package/src/cli/args.ts +50 -0
  23. package/src/cli/branch.ts +75 -0
  24. package/src/cli/build.ts +86 -0
  25. package/src/cli/client-add.test.ts +140 -0
  26. package/src/cli/client-add.ts +164 -0
  27. package/src/cli/completion.test.ts +58 -0
  28. package/src/cli/completion.ts +296 -0
  29. package/src/cli/dev-app-runner.ts +77 -0
  30. package/src/cli/dev.test.ts +435 -0
  31. package/src/cli/dev.ts +594 -0
  32. package/src/cli/doc-drift.test.ts +146 -0
  33. package/src/cli/doc-drift.ts +397 -0
  34. package/src/cli/docker-cli.test.ts +221 -0
  35. package/src/cli/docker.ts +127 -0
  36. package/src/cli/doctor-diff-examples.ts +92 -0
  37. package/src/cli/doctor-diff.test.ts +91 -0
  38. package/src/cli/doctor-diff.ts +274 -0
  39. package/src/cli/doctor-pii.test.ts +98 -0
  40. package/src/cli/doctor-pii.ts +151 -0
  41. package/src/cli/doctor.test.ts +150 -0
  42. package/src/cli/doctor.ts +223 -0
  43. package/src/cli/eval.ts +122 -0
  44. package/src/cli/exit.ts +19 -0
  45. package/src/cli/gates-list.test.ts +47 -0
  46. package/src/cli/gates-list.ts +84 -0
  47. package/src/cli/images.ts +277 -0
  48. package/src/cli/index.ts +99 -0
  49. package/src/cli/json-out.test.ts +129 -0
  50. package/src/cli/load-config.ts +71 -0
  51. package/src/cli/mcp-from-console.ts +50 -0
  52. package/src/cli/privacy-erase.ts +73 -0
  53. package/src/cli/registry.ts +455 -0
  54. package/src/cli/safe-defaults.test.ts +92 -0
  55. package/src/cli/schema.ts +196 -0
  56. package/src/cli/stack.ts +82 -0
  57. package/src/cli/start.ts +106 -0
  58. package/src/cli/upgrade.ts +105 -0
  59. package/src/cli/vault-cmd.ts +140 -0
  60. package/src/client/budget-entry.ts +34 -0
  61. package/src/client/budget.test.ts +17 -0
  62. package/src/client/create.test.ts +159 -0
  63. package/src/client/create.ts +152 -0
  64. package/src/client/errors.ts +60 -0
  65. package/src/client/index.ts +35 -0
  66. package/src/client/notes-contract.test.ts +289 -0
  67. package/src/client/transport.test.ts +123 -0
  68. package/src/client/transport.ts +254 -0
  69. package/src/client/types.ts +282 -0
  70. package/src/compiler/aot.test.ts +248 -0
  71. package/src/compiler/aot.ts +182 -0
  72. package/src/compiler/differential.test.ts +241 -0
  73. package/src/compiler/dynamic.ts +54 -0
  74. package/src/compiler/effects-infer.ts +541 -0
  75. package/src/compiler/emit.ts +40 -0
  76. package/src/compiler/extract.test.ts +177 -0
  77. package/src/compiler/extract.ts +1368 -0
  78. package/src/compiler/fixtures/raw/raw-unannotated.ts +28 -0
  79. package/src/compiler/fixtures/skyport/oke.config.ts +24 -0
  80. package/src/compiler/fixtures/skyport/src/ai.ts +15 -0
  81. package/src/compiler/fixtures/skyport/src/app.ts +10 -0
  82. package/src/compiler/fixtures/skyport/src/channels.ts +6 -0
  83. package/src/compiler/fixtures/skyport/src/core.ts +3 -0
  84. package/src/compiler/fixtures/skyport/src/flows/bookings/index.ts +57 -0
  85. package/src/compiler/fixtures/skyport/src/flows/bookings/signals.ts +11 -0
  86. package/src/compiler/fixtures/skyport/src/flows/payments/index.ts +14 -0
  87. package/src/compiler/fixtures/skyport/src/flows/support/index.ts +20 -0
  88. package/src/compiler/fixtures/skyport/src/gates.ts +14 -0
  89. package/src/compiler/fixtures/skyport/src/journeys.ts +9 -0
  90. package/src/compiler/fixtures/skyport/src/schema.ts +3 -0
  91. package/src/compiler/fixtures/skyport/src/vault.ts +6 -0
  92. package/src/compiler/fixtures/skyport.expected.json +241 -0
  93. package/src/compiler/fixtures/triggers/five-triggers.ts +69 -0
  94. package/src/compiler/http-parse.ts +214 -0
  95. package/src/compiler/index.ts +67 -0
  96. package/src/compiler/response.ts +89 -0
  97. package/src/compiler/sucrose.ts +238 -0
  98. package/src/config/index.ts +167 -0
  99. package/src/console/budget.test.ts +73 -0
  100. package/src/console/index.ts +30 -0
  101. package/src/console/server/access.test.ts +370 -0
  102. package/src/console/server/access.ts +777 -0
  103. package/src/console/server/ai.test.ts +172 -0
  104. package/src/console/server/ai.ts +632 -0
  105. package/src/console/server/app.ts +294 -0
  106. package/src/console/server/auth-rate.test.ts +81 -0
  107. package/src/console/server/auth-rate.ts +72 -0
  108. package/src/console/server/bind.ts +25 -0
  109. package/src/console/server/channels.test.ts +179 -0
  110. package/src/console/server/channels.ts +469 -0
  111. package/src/console/server/claim.test.ts +66 -0
  112. package/src/console/server/claim.ts +134 -0
  113. package/src/console/server/clock.test.ts +239 -0
  114. package/src/console/server/clock.ts +390 -0
  115. package/src/console/server/console.test.ts +338 -0
  116. package/src/console/server/diff.test.ts +299 -0
  117. package/src/console/server/diff.ts +352 -0
  118. package/src/console/server/dry-run.audit.test.ts +118 -0
  119. package/src/console/server/flows-invoke.test.ts +148 -0
  120. package/src/console/server/flows.ts +3633 -0
  121. package/src/console/server/gates.test.ts +360 -0
  122. package/src/console/server/gates.ts +869 -0
  123. package/src/console/server/index.ts +141 -0
  124. package/src/console/server/live.test.ts +30 -0
  125. package/src/console/server/live.ts +109 -0
  126. package/src/console/server/plugin.ts +50 -0
  127. package/src/console/server/plugins.test.ts +131 -0
  128. package/src/console/server/plugins.ts +429 -0
  129. package/src/console/server/runs-pii.ts +98 -0
  130. package/src/console/server/security-headers.ts +97 -0
  131. package/src/console/server/security.gate.test.ts +286 -0
  132. package/src/console/server/serve.ts +319 -0
  133. package/src/console/server/signals.test.ts +88 -0
  134. package/src/console/server/signals.ts +282 -0
  135. package/src/console/server/state.ts +982 -0
  136. package/src/console/server/store.test.ts +233 -0
  137. package/src/console/server/store.ts +861 -0
  138. package/src/console/server/structural.ts +95 -0
  139. package/src/console/server/vault.test.ts +251 -0
  140. package/src/console/server/vault.ts +430 -0
  141. package/src/console/ui/access/AccessA11yView.tsx +237 -0
  142. package/src/console/ui/access/a11y.test.tsx +122 -0
  143. package/src/console/ui/access/acknowledgement.test.ts +13 -0
  144. package/src/console/ui/access/acknowledgement.ts +35 -0
  145. package/src/console/ui/access/blast-radius.test.ts +26 -0
  146. package/src/console/ui/access/blast-radius.ts +40 -0
  147. package/src/console/ui/access/confirmation.test.ts +38 -0
  148. package/src/console/ui/access/confirmation.ts +36 -0
  149. package/src/console/ui/access/fixture.ts +203 -0
  150. package/src/console/ui/access/grantable.test.ts +17 -0
  151. package/src/console/ui/access/grantable.ts +36 -0
  152. package/src/console/ui/access/hygiene.test.ts +12 -0
  153. package/src/console/ui/access/hygiene.ts +39 -0
  154. package/src/console/ui/access/index.ts +54 -0
  155. package/src/console/ui/access/provenance.test.ts +12 -0
  156. package/src/console/ui/access/provenance.ts +29 -0
  157. package/src/console/ui/access/search.test.ts +17 -0
  158. package/src/console/ui/access/search.ts +72 -0
  159. package/src/console/ui/access/types.ts +111 -0
  160. package/src/console/ui/ai/AiA11yView.tsx +265 -0
  161. package/src/console/ui/ai/a11y.test.tsx +99 -0
  162. package/src/console/ui/ai/findings.ts +41 -0
  163. package/src/console/ui/ai/fixture.ts +182 -0
  164. package/src/console/ui/ai/format.ts +90 -0
  165. package/src/console/ui/ai/group.test.ts +37 -0
  166. package/src/console/ui/ai/group.ts +88 -0
  167. package/src/console/ui/ai/index.ts +66 -0
  168. package/src/console/ui/ai/promotion.test.ts +77 -0
  169. package/src/console/ui/ai/promotion.ts +150 -0
  170. package/src/console/ui/ai/search.test.ts +40 -0
  171. package/src/console/ui/ai/search.ts +89 -0
  172. package/src/console/ui/ai/types.ts +139 -0
  173. package/src/console/ui/architecture/ArchitectureA11yView.tsx +163 -0
  174. package/src/console/ui/architecture/a11y.test.tsx +97 -0
  175. package/src/console/ui/architecture/boundary.ts +42 -0
  176. package/src/console/ui/architecture/declared.ts +165 -0
  177. package/src/console/ui/architecture/fixture.ts +74 -0
  178. package/src/console/ui/architecture/index.ts +84 -0
  179. package/src/console/ui/architecture/layers.ts +64 -0
  180. package/src/console/ui/architecture/layout.ts +68 -0
  181. package/src/console/ui/architecture/pathologies.ts +260 -0
  182. package/src/console/ui/architecture/search.ts +145 -0
  183. package/src/console/ui/architecture/traffic.ts +102 -0
  184. package/src/console/ui/architecture/types.ts +144 -0
  185. package/src/console/ui/architecture/view.test.ts +165 -0
  186. package/src/console/ui/architecture/view.ts +516 -0
  187. package/src/console/ui/channels/ChannelsA11yView.tsx +180 -0
  188. package/src/console/ui/channels/a11y.test.tsx +96 -0
  189. package/src/console/ui/channels/confirmation.test.ts +37 -0
  190. package/src/console/ui/channels/confirmation.ts +27 -0
  191. package/src/console/ui/channels/fallback.test.ts +15 -0
  192. package/src/console/ui/channels/fallback.ts +20 -0
  193. package/src/console/ui/channels/findings.ts +38 -0
  194. package/src/console/ui/channels/fixture.ts +134 -0
  195. package/src/console/ui/channels/group.ts +25 -0
  196. package/src/console/ui/channels/index.ts +57 -0
  197. package/src/console/ui/channels/locale.test.ts +17 -0
  198. package/src/console/ui/channels/locale.ts +31 -0
  199. package/src/console/ui/channels/mask.test.ts +14 -0
  200. package/src/console/ui/channels/mask.ts +12 -0
  201. package/src/console/ui/channels/search.ts +58 -0
  202. package/src/console/ui/channels/taxonomy.test.ts +17 -0
  203. package/src/console/ui/channels/taxonomy.ts +49 -0
  204. package/src/console/ui/channels/types.ts +117 -0
  205. package/src/console/ui/clock/ClockA11yView.tsx +182 -0
  206. package/src/console/ui/clock/a11y.test.tsx +99 -0
  207. package/src/console/ui/clock/confirmation.test.ts +32 -0
  208. package/src/console/ui/clock/confirmation.ts +34 -0
  209. package/src/console/ui/clock/findings.ts +40 -0
  210. package/src/console/ui/clock/fixture.ts +111 -0
  211. package/src/console/ui/clock/health.test.ts +25 -0
  212. package/src/console/ui/clock/health.ts +61 -0
  213. package/src/console/ui/clock/index.ts +49 -0
  214. package/src/console/ui/clock/search.test.ts +39 -0
  215. package/src/console/ui/clock/search.ts +76 -0
  216. package/src/console/ui/clock/timeline.test.ts +44 -0
  217. package/src/console/ui/clock/timeline.ts +41 -0
  218. package/src/console/ui/clock/types.ts +78 -0
  219. package/src/console/ui/clock/waiting-on.test.ts +34 -0
  220. package/src/console/ui/clock/waiting-on.ts +83 -0
  221. package/src/console/ui/confirmation.unify.test.ts +92 -0
  222. package/src/console/ui/diff/DiffA11yView.tsx +85 -0
  223. package/src/console/ui/diff/a11y.test.tsx +99 -0
  224. package/src/console/ui/diff/fixture.ts +85 -0
  225. package/src/console/ui/diff/group.test.ts +58 -0
  226. package/src/console/ui/diff/group.ts +97 -0
  227. package/src/console/ui/diff/index.ts +38 -0
  228. package/src/console/ui/diff/search.test.ts +32 -0
  229. package/src/console/ui/diff/search.ts +75 -0
  230. package/src/console/ui/diff/summary.ts +74 -0
  231. package/src/console/ui/diff/types.ts +48 -0
  232. package/src/console/ui/dist/assets/index-B71Yl_SS.js +10 -0
  233. package/src/console/ui/dist/assets/panel-access-Dd37LU2c.js +64 -0
  234. package/src/console/ui/dist/assets/panel-ai-CC7LR6-J.js +1 -0
  235. package/src/console/ui/dist/assets/panel-architecture-B5b3iKCz.js +1 -0
  236. package/src/console/ui/dist/assets/panel-channels-CeNjTKXp.js +1 -0
  237. package/src/console/ui/dist/assets/panel-clock-DgFTLoHV.js +1 -0
  238. package/src/console/ui/dist/assets/panel-diff-DxehccqB.js +1 -0
  239. package/src/console/ui/dist/assets/panel-flows-BtrVn-Eg.js +45 -0
  240. package/src/console/ui/dist/assets/panel-gates-Z9MKRGdH.js +1 -0
  241. package/src/console/ui/dist/assets/panel-overview-Bd48d9km.js +1 -0
  242. package/src/console/ui/dist/assets/panel-plugins-DWd0TowH.js +1 -0
  243. package/src/console/ui/dist/assets/panel-runs-BwsWqKeB.js +1 -0
  244. package/src/console/ui/dist/assets/panel-signals-9najbZY2.js +1 -0
  245. package/src/console/ui/dist/assets/panel-store-OHkP2pDp.js +1 -0
  246. package/src/console/ui/dist/assets/panel-traces-tn2JoY8U.js +1 -0
  247. package/src/console/ui/dist/assets/panel-vault-BbfWdox0.js +1 -0
  248. package/src/console/ui/dist/assets/rolldown-runtime-CNC7AqOf.js +1 -0
  249. package/src/console/ui/dist/assets/style-Cnl7WLya.css +3 -0
  250. package/src/console/ui/dist/index.html +14 -0
  251. package/src/console/ui/flows/FlowsA11yView.tsx +155 -0
  252. package/src/console/ui/flows/a11y.test.tsx +105 -0
  253. package/src/console/ui/flows/buffer.test.ts +91 -0
  254. package/src/console/ui/flows/buffer.ts +118 -0
  255. package/src/console/ui/flows/confirmation.ts +131 -0
  256. package/src/console/ui/flows/contract.test.ts +89 -0
  257. package/src/console/ui/flows/contract.ts +353 -0
  258. package/src/console/ui/flows/fixture.ts +81 -0
  259. package/src/console/ui/flows/graph.test.ts +101 -0
  260. package/src/console/ui/flows/graph.ts +549 -0
  261. package/src/console/ui/flows/index.ts +87 -0
  262. package/src/console/ui/flows/save-as-test.test.ts +47 -0
  263. package/src/console/ui/flows/save-as-test.ts +99 -0
  264. package/src/console/ui/flows/search.ts +255 -0
  265. package/src/console/ui/flows/tiers.ts +140 -0
  266. package/src/console/ui/gates/GatesA11yView.tsx +192 -0
  267. package/src/console/ui/gates/a11y.test.tsx +116 -0
  268. package/src/console/ui/gates/audit.test.ts +40 -0
  269. package/src/console/ui/gates/audit.ts +63 -0
  270. package/src/console/ui/gates/denial.test.ts +36 -0
  271. package/src/console/ui/gates/denial.ts +51 -0
  272. package/src/console/ui/gates/findings.ts +19 -0
  273. package/src/console/ui/gates/fixture.ts +189 -0
  274. package/src/console/ui/gates/group.test.ts +30 -0
  275. package/src/console/ui/gates/group.ts +102 -0
  276. package/src/console/ui/gates/index.ts +47 -0
  277. package/src/console/ui/gates/search.test.ts +49 -0
  278. package/src/console/ui/gates/search.ts +115 -0
  279. package/src/console/ui/gates/types.ts +121 -0
  280. package/src/console/ui/overview/OverviewA11yView.tsx +152 -0
  281. package/src/console/ui/overview/a11y.test.tsx +113 -0
  282. package/src/console/ui/overview/busiest.ts +26 -0
  283. package/src/console/ui/overview/compose.ts +133 -0
  284. package/src/console/ui/overview/cost.test.ts +39 -0
  285. package/src/console/ui/overview/cost.ts +138 -0
  286. package/src/console/ui/overview/fixture.ts +161 -0
  287. package/src/console/ui/overview/golden.ts +57 -0
  288. package/src/console/ui/overview/index.ts +59 -0
  289. package/src/console/ui/overview/rank.test.ts +136 -0
  290. package/src/console/ui/overview/rank.ts +210 -0
  291. package/src/console/ui/overview/slo.test.ts +73 -0
  292. package/src/console/ui/overview/slo.ts +229 -0
  293. package/src/console/ui/overview/types.ts +121 -0
  294. package/src/console/ui/overview/verdict.ts +131 -0
  295. package/src/console/ui/plugins/PluginsA11yView.tsx +227 -0
  296. package/src/console/ui/plugins/a11y.test.tsx +97 -0
  297. package/src/console/ui/plugins/command.test.ts +22 -0
  298. package/src/console/ui/plugins/command.ts +27 -0
  299. package/src/console/ui/plugins/findings.ts +39 -0
  300. package/src/console/ui/plugins/fixture.ts +233 -0
  301. package/src/console/ui/plugins/group.test.ts +38 -0
  302. package/src/console/ui/plugins/group.ts +67 -0
  303. package/src/console/ui/plugins/index.ts +40 -0
  304. package/src/console/ui/plugins/search.ts +67 -0
  305. package/src/console/ui/plugins/types.ts +115 -0
  306. package/src/console/ui/runs/RunsA11yView.tsx +267 -0
  307. package/src/console/ui/runs/a11y.test.tsx +99 -0
  308. package/src/console/ui/runs/explain.test.ts +23 -0
  309. package/src/console/ui/runs/explain.ts +32 -0
  310. package/src/console/ui/runs/fixture.ts +189 -0
  311. package/src/console/ui/runs/group.test.ts +24 -0
  312. package/src/console/ui/runs/group.ts +85 -0
  313. package/src/console/ui/runs/histogram.test.ts +31 -0
  314. package/src/console/ui/runs/histogram.ts +85 -0
  315. package/src/console/ui/runs/index.ts +75 -0
  316. package/src/console/ui/runs/project.ts +122 -0
  317. package/src/console/ui/runs/query.test.ts +50 -0
  318. package/src/console/ui/runs/query.ts +283 -0
  319. package/src/console/ui/runs/search.test.ts +45 -0
  320. package/src/console/ui/runs/search.ts +141 -0
  321. package/src/console/ui/runs/trace-link.test.ts +30 -0
  322. package/src/console/ui/runs/trace-link.ts +99 -0
  323. package/src/console/ui/runs/types.ts +137 -0
  324. package/src/console/ui/shell/App.tsx +56 -0
  325. package/src/console/ui/shell/client.ts +1715 -0
  326. package/src/console/ui/shell/components/ui.tsx +110 -0
  327. package/src/console/ui/shell/index.html +12 -0
  328. package/src/console/ui/shell/layout/Shell.tsx +95 -0
  329. package/src/console/ui/shell/main.tsx +281 -0
  330. package/src/console/ui/shell/panels/Access.tsx +5 -0
  331. package/src/console/ui/shell/panels/Ai.tsx +5 -0
  332. package/src/console/ui/shell/panels/Architecture.tsx +5 -0
  333. package/src/console/ui/shell/panels/Channels.tsx +5 -0
  334. package/src/console/ui/shell/panels/Clock.tsx +5 -0
  335. package/src/console/ui/shell/panels/Diff.tsx +5 -0
  336. package/src/console/ui/shell/panels/Flows.tsx +5 -0
  337. package/src/console/ui/shell/panels/Gates.tsx +5 -0
  338. package/src/console/ui/shell/panels/Overview.tsx +6 -0
  339. package/src/console/ui/shell/panels/Plugins.tsx +5 -0
  340. package/src/console/ui/shell/panels/Runs.tsx +5 -0
  341. package/src/console/ui/shell/panels/Signals.tsx +5 -0
  342. package/src/console/ui/shell/panels/Store.tsx +5 -0
  343. package/src/console/ui/shell/panels/Traces.tsx +5 -0
  344. package/src/console/ui/shell/panels/Vault.tsx +5 -0
  345. package/src/console/ui/shell/panels/access/AccessPanel.tsx +813 -0
  346. package/src/console/ui/shell/panels/ai/AiPanel.tsx +563 -0
  347. package/src/console/ui/shell/panels/architecture/ArchitecturePanel.tsx +377 -0
  348. package/src/console/ui/shell/panels/channels/ChannelsPanel.tsx +454 -0
  349. package/src/console/ui/shell/panels/clock/ClockPanel.tsx +479 -0
  350. package/src/console/ui/shell/panels/diff/DiffPanel.tsx +275 -0
  351. package/src/console/ui/shell/panels/flows/ContractEditor.tsx +301 -0
  352. package/src/console/ui/shell/panels/flows/FlowDrawer.tsx +350 -0
  353. package/src/console/ui/shell/panels/flows/FlowsPanel.tsx +502 -0
  354. package/src/console/ui/shell/panels/gates/GatesPanel.tsx +482 -0
  355. package/src/console/ui/shell/panels/overview/OverviewPanel.tsx +428 -0
  356. package/src/console/ui/shell/panels/plugins/PluginsPanel.tsx +413 -0
  357. package/src/console/ui/shell/panels/runs/RunsPanel.tsx +649 -0
  358. package/src/console/ui/shell/panels/signals/SignalsPanel.tsx +840 -0
  359. package/src/console/ui/shell/panels/store/StorePanel.tsx +787 -0
  360. package/src/console/ui/shell/panels/traces/TracesPanel.tsx +539 -0
  361. package/src/console/ui/shell/panels/vault/VaultPanel.tsx +449 -0
  362. package/src/console/ui/shell/plugin/Sandbox.tsx +29 -0
  363. package/src/console/ui/shell/setup/Wizard.tsx +189 -0
  364. package/src/console/ui/shell/styles.css +75 -0
  365. package/src/console/ui/signals/SignalsA11yView.tsx +276 -0
  366. package/src/console/ui/signals/a11y.test.tsx +99 -0
  367. package/src/console/ui/signals/confirmation.test.ts +39 -0
  368. package/src/console/ui/signals/confirmation.ts +63 -0
  369. package/src/console/ui/signals/dry-run.test.ts +18 -0
  370. package/src/console/ui/signals/dry-run.ts +36 -0
  371. package/src/console/ui/signals/durable.test.ts +22 -0
  372. package/src/console/ui/signals/durable.ts +41 -0
  373. package/src/console/ui/signals/findings.ts +33 -0
  374. package/src/console/ui/signals/fixture.ts +242 -0
  375. package/src/console/ui/signals/group.test.ts +32 -0
  376. package/src/console/ui/signals/group.ts +49 -0
  377. package/src/console/ui/signals/index.ts +52 -0
  378. package/src/console/ui/signals/monitor.test.ts +30 -0
  379. package/src/console/ui/signals/monitor.ts +79 -0
  380. package/src/console/ui/signals/schema-form.test.ts +34 -0
  381. package/src/console/ui/signals/schema-form.ts +112 -0
  382. package/src/console/ui/signals/search.ts +102 -0
  383. package/src/console/ui/signals/types.ts +71 -0
  384. package/src/console/ui/store/StoreA11yView.tsx +199 -0
  385. package/src/console/ui/store/a11y.test.tsx +99 -0
  386. package/src/console/ui/store/cache-view.test.ts +13 -0
  387. package/src/console/ui/store/cache-view.ts +36 -0
  388. package/src/console/ui/store/confirmation.test.ts +38 -0
  389. package/src/console/ui/store/confirmation.ts +55 -0
  390. package/src/console/ui/store/dry-run.test.ts +15 -0
  391. package/src/console/ui/store/dry-run.ts +29 -0
  392. package/src/console/ui/store/fixture.ts +163 -0
  393. package/src/console/ui/store/group.test.ts +21 -0
  394. package/src/console/ui/store/group.ts +41 -0
  395. package/src/console/ui/store/index.ts +40 -0
  396. package/src/console/ui/store/search.ts +78 -0
  397. package/src/console/ui/store/types.ts +65 -0
  398. package/src/console/ui/store/will-not-fire.test.ts +19 -0
  399. package/src/console/ui/store/will-not-fire.ts +40 -0
  400. package/src/console/ui/traces/TracesA11yView.tsx +200 -0
  401. package/src/console/ui/traces/a11y.test.tsx +97 -0
  402. package/src/console/ui/traces/chain.test.ts +61 -0
  403. package/src/console/ui/traces/chain.ts +144 -0
  404. package/src/console/ui/traces/critical-path.test.ts +24 -0
  405. package/src/console/ui/traces/critical-path.ts +59 -0
  406. package/src/console/ui/traces/filter.test.ts +78 -0
  407. package/src/console/ui/traces/filter.ts +112 -0
  408. package/src/console/ui/traces/fixture.ts +126 -0
  409. package/src/console/ui/traces/fold.test.ts +67 -0
  410. package/src/console/ui/traces/fold.ts +170 -0
  411. package/src/console/ui/traces/index.ts +64 -0
  412. package/src/console/ui/traces/mini.ts +65 -0
  413. package/src/console/ui/traces/replay.test.ts +24 -0
  414. package/src/console/ui/traces/replay.ts +35 -0
  415. package/src/console/ui/traces/sampling.test.ts +26 -0
  416. package/src/console/ui/traces/sampling.ts +66 -0
  417. package/src/console/ui/traces/search.ts +148 -0
  418. package/src/console/ui/traces/tier.ts +72 -0
  419. package/src/console/ui/traces/types.ts +125 -0
  420. package/src/console/ui/tsconfig.json +20 -0
  421. package/src/console/ui/vault/VaultA11yView.tsx +177 -0
  422. package/src/console/ui/vault/a11y.test.tsx +97 -0
  423. package/src/console/ui/vault/blast-radius.test.ts +35 -0
  424. package/src/console/ui/vault/blast-radius.ts +55 -0
  425. package/src/console/ui/vault/confirmation.test.ts +41 -0
  426. package/src/console/ui/vault/confirmation.ts +39 -0
  427. package/src/console/ui/vault/dormant.test.ts +37 -0
  428. package/src/console/ui/vault/dormant.ts +28 -0
  429. package/src/console/ui/vault/export-safe.test.ts +30 -0
  430. package/src/console/ui/vault/export-safe.ts +65 -0
  431. package/src/console/ui/vault/fixture.ts +75 -0
  432. package/src/console/ui/vault/group.test.ts +25 -0
  433. package/src/console/ui/vault/group.ts +50 -0
  434. package/src/console/ui/vault/index.ts +45 -0
  435. package/src/console/ui/vault/search.ts +62 -0
  436. package/src/console/ui/vault/types.ts +57 -0
  437. package/src/console/ui/vite.config.ts +84 -0
  438. package/src/console/xss.gate.test.ts +118 -0
  439. package/src/docker/compose.ts +226 -0
  440. package/src/docker/credentials.ts +25 -0
  441. package/src/docker/derive.ts +83 -0
  442. package/src/docker/docker.test.ts +185 -0
  443. package/src/docker/dockerfile.integration.test.ts +170 -0
  444. package/src/docker/dockerfile.ts +39 -0
  445. package/src/docker/helpers.ts +103 -0
  446. package/src/docker/index.ts +52 -0
  447. package/src/docker/pin.ts +90 -0
  448. package/src/docker/recipes/index.ts +33 -0
  449. package/src/docker/recipes/postgres.ts +18 -0
  450. package/src/docker/recipes/redis.ts +18 -0
  451. package/src/docker/stack.integration.test.ts +140 -0
  452. package/src/docker/stack.ts +62 -0
  453. package/src/docker/types.ts +134 -0
  454. package/src/drivers/ai-anthropic.ts +128 -0
  455. package/src/drivers/ai-mock.ts +82 -0
  456. package/src/drivers/ai-openai-compatible.ts +139 -0
  457. package/src/drivers/ai-providers.test.ts +163 -0
  458. package/src/drivers/ai-types.ts +83 -0
  459. package/src/drivers/bun-native-completeness.test.ts +155 -0
  460. package/src/drivers/channel-console.ts +118 -0
  461. package/src/drivers/channel-fcm.ts +96 -0
  462. package/src/drivers/channel-resend.ts +27 -0
  463. package/src/drivers/channel-smtp.ts +33 -0
  464. package/src/drivers/channel-types.ts +160 -0
  465. package/src/drivers/channel-unifonic.ts +79 -0
  466. package/src/drivers/channel-wa-cloud.ts +84 -0
  467. package/src/drivers/channel-webpush.ts +317 -0
  468. package/src/drivers/conformance.test.ts +89 -0
  469. package/src/drivers/conformance.ts +162 -0
  470. package/src/drivers/fs.ts +73 -0
  471. package/src/drivers/index.ts +194 -0
  472. package/src/drivers/kv-lua.ts +222 -0
  473. package/src/drivers/memory.ts +472 -0
  474. package/src/drivers/pgvector.ts +130 -0
  475. package/src/drivers/postgres.ts +221 -0
  476. package/src/drivers/redis.ts +254 -0
  477. package/src/drivers/s3.ts +129 -0
  478. package/src/drivers/signal-engine.ts +690 -0
  479. package/src/drivers/signal-memory.ts +27 -0
  480. package/src/drivers/signal-nats.ts +131 -0
  481. package/src/drivers/signal-postgres.ts +1089 -0
  482. package/src/drivers/signal-redis.ts +275 -0
  483. package/src/drivers/signal-types.ts +328 -0
  484. package/src/drivers/sqlite.ts +53 -0
  485. package/src/drivers/types.ts +334 -0
  486. package/src/drivers/vault-dotenv-parse.ts +56 -0
  487. package/src/drivers/vault-env.ts +101 -0
  488. package/src/drivers/vault-infisical.ts +61 -0
  489. package/src/drivers/vault-managed.ts +42 -0
  490. package/src/drivers/vault-memory.ts +38 -0
  491. package/src/drivers/vault-openbao.ts +80 -0
  492. package/src/drivers/vault-sops.ts +252 -0
  493. package/src/drivers/vault-types.ts +84 -0
  494. package/src/elements/ai/declare.ts +206 -0
  495. package/src/elements/ai/eval.ts +113 -0
  496. package/src/elements/ai/pii.ts +108 -0
  497. package/src/elements/ai/runtime.ts +540 -0
  498. package/src/elements/ai/schema.ts +194 -0
  499. package/src/elements/ai.test.ts +393 -0
  500. package/src/elements/ai.ts +56 -0
  501. package/src/elements/channel/consent.ts +81 -0
  502. package/src/elements/channel/costs.test.ts +62 -0
  503. package/src/elements/channel/costs.ts +130 -0
  504. package/src/elements/channel/declare.ts +141 -0
  505. package/src/elements/channel/email-auth.test.ts +47 -0
  506. package/src/elements/channel/email-auth.ts +109 -0
  507. package/src/elements/channel/locale.ts +97 -0
  508. package/src/elements/channel/mask.test.ts +19 -0
  509. package/src/elements/channel/mask.ts +60 -0
  510. package/src/elements/channel/mime.ts +23 -0
  511. package/src/elements/channel/outcomes.test.ts +40 -0
  512. package/src/elements/channel/outcomes.ts +126 -0
  513. package/src/elements/channel/receipts.ts +121 -0
  514. package/src/elements/channel/runtime.ts +500 -0
  515. package/src/elements/channel/suppression.ts +136 -0
  516. package/src/elements/channel.test.ts +232 -0
  517. package/src/elements/channel.ts +109 -0
  518. package/src/elements/clock/actions.ts +170 -0
  519. package/src/elements/clock/declare.ts +58 -0
  520. package/src/elements/clock/dst.ts +197 -0
  521. package/src/elements/clock/durable.ts +140 -0
  522. package/src/elements/clock/duration.ts +29 -0
  523. package/src/elements/clock/health.test.ts +103 -0
  524. package/src/elements/clock/health.ts +112 -0
  525. package/src/elements/clock/leader.ts +127 -0
  526. package/src/elements/clock/reconcile.ts +241 -0
  527. package/src/elements/clock/runtime.ts +243 -0
  528. package/src/elements/clock/schedule.ts +262 -0
  529. package/src/elements/clock/time-travel.ts +53 -0
  530. package/src/elements/clock.test.ts +365 -0
  531. package/src/elements/clock.ts +80 -0
  532. package/src/elements/gate/declare.ts +134 -0
  533. package/src/elements/gate/permissions.ts +104 -0
  534. package/src/elements/gate/runtime.ts +177 -0
  535. package/src/elements/gate/strategies.ts +388 -0
  536. package/src/elements/gate.test.ts +145 -0
  537. package/src/elements/gate.ts +41 -0
  538. package/src/elements/index.ts +169 -0
  539. package/src/elements/signal/chaos-child.ts +47 -0
  540. package/src/elements/signal/declare.ts +77 -0
  541. package/src/elements/signal/dry-run-replay.test.ts +95 -0
  542. package/src/elements/signal/dry-run-write-isolation.test.ts +94 -0
  543. package/src/elements/signal/reconcile.test.ts +23 -0
  544. package/src/elements/signal/reconcile.ts +122 -0
  545. package/src/elements/signal/runtime.ts +94 -0
  546. package/src/elements/signal.test.ts +457 -0
  547. package/src/elements/signal.ts +26 -0
  548. package/src/elements/store/cache.ts +197 -0
  549. package/src/elements/store/classify.ts +125 -0
  550. package/src/elements/store/declare.ts +200 -0
  551. package/src/elements/store/files-policy.test.ts +31 -0
  552. package/src/elements/store/files-policy.ts +70 -0
  553. package/src/elements/store/replica.ts +68 -0
  554. package/src/elements/store/runtime.ts +393 -0
  555. package/src/elements/store/sql-condition.ts +205 -0
  556. package/src/elements/store/sql-session.ts +579 -0
  557. package/src/elements/store/table.ts +282 -0
  558. package/src/elements/store.test.ts +370 -0
  559. package/src/elements/store.ts +99 -0
  560. package/src/elements/vault/declare.ts +143 -0
  561. package/src/elements/vault/fingerprint.ts +30 -0
  562. package/src/elements/vault/redact.ts +52 -0
  563. package/src/elements/vault/runtime.ts +461 -0
  564. package/src/elements/vault.test.ts +296 -0
  565. package/src/elements/vault.ts +44 -0
  566. package/src/index.ts +183 -0
  567. package/src/kernel/adopt-routes.ts +194 -0
  568. package/src/kernel/app.ts +1068 -0
  569. package/src/kernel/auth-resolve.ts +93 -0
  570. package/src/kernel/boot.test.ts +173 -0
  571. package/src/kernel/boot.ts +439 -0
  572. package/src/kernel/budget-entry.ts +55 -0
  573. package/src/kernel/budget.test.ts +19 -0
  574. package/src/kernel/call.test.ts +83 -0
  575. package/src/kernel/capability.ts +113 -0
  576. package/src/kernel/dry-run.test.ts +64 -0
  577. package/src/kernel/dry-run.ts +171 -0
  578. package/src/kernel/effects.test.ts +89 -0
  579. package/src/kernel/effects.ts +140 -0
  580. package/src/kernel/errors.registry.test.ts +39 -0
  581. package/src/kernel/errors.ts +225 -0
  582. package/src/kernel/flow.test.ts +154 -0
  583. package/src/kernel/flow.ts +290 -0
  584. package/src/kernel/fx.test.ts +245 -0
  585. package/src/kernel/fx.ts +996 -0
  586. package/src/kernel/hook-timing.test.ts +72 -0
  587. package/src/kernel/hook-timing.ts +190 -0
  588. package/src/kernel/hooks.test.ts +181 -0
  589. package/src/kernel/hooks.ts +275 -0
  590. package/src/kernel/index.ts +278 -0
  591. package/src/kernel/journal.ts +405 -0
  592. package/src/kernel/journey.ts +75 -0
  593. package/src/kernel/on.ts +74 -0
  594. package/src/kernel/pipeline.test.ts +349 -0
  595. package/src/kernel/pipeline.ts +245 -0
  596. package/src/kernel/plug.ts +82 -0
  597. package/src/kernel/plugin/capabilities.test.ts +84 -0
  598. package/src/kernel/plugin/conflicts.test.ts +106 -0
  599. package/src/kernel/plugin/decorate.test.ts +111 -0
  600. package/src/kernel/plugin/scoping.test.ts +138 -0
  601. package/src/kernel/plugin.ts +485 -0
  602. package/src/kernel/rate-limit.ts +25 -0
  603. package/src/kernel/registry.ts +398 -0
  604. package/src/kernel/router.test.ts +114 -0
  605. package/src/kernel/router.ts +556 -0
  606. package/src/kernel/routing-budget.test.ts +19 -0
  607. package/src/kernel/run-telemetry.ts +70 -0
  608. package/src/kernel/triggers.ts +324 -0
  609. package/src/kernel/unit.ts +88 -0
  610. package/src/manifest/diff.test.ts +866 -0
  611. package/src/manifest/diff.ts +1670 -0
  612. package/src/manifest/fixtures/base.manifest.json +112 -0
  613. package/src/manifest/fixtures/skyport.excerpt.json +51 -0
  614. package/src/manifest/fixtures/skyport.manifest.json +153 -0
  615. package/src/manifest/index.ts +27 -0
  616. package/src/manifest/types.ts +358 -0
  617. package/src/manifest/undeclared.test.ts +82 -0
  618. package/src/manifest/undeclared.ts +65 -0
  619. package/src/manifest/validate.test.ts +105 -0
  620. package/src/manifest/validate.ts +174 -0
  621. package/src/mcp/authorization.ts +340 -0
  622. package/src/mcp/confirmation.ts +174 -0
  623. package/src/mcp/data.ts +90 -0
  624. package/src/mcp/index.ts +80 -0
  625. package/src/mcp/injection.gate.test.ts +176 -0
  626. package/src/mcp/mcp.test.ts +348 -0
  627. package/src/mcp/protocol.ts +172 -0
  628. package/src/mcp/server.ts +283 -0
  629. package/src/mcp/session.ts +139 -0
  630. package/src/mcp/tools.ts +391 -0
  631. package/src/plugins/catalogue.test.ts +48 -0
  632. package/src/plugins/catalogue.ts +113 -0
  633. package/src/plugins/node-import-scan.test.ts +28 -0
  634. package/src/plugins/node-import-scan.ts +98 -0
  635. package/src/plugins/supply-chain.test.ts +48 -0
  636. package/src/plugins/supply-chain.ts +460 -0
  637. package/src/release/index.ts +30 -0
  638. package/src/release/limits.ts +20 -0
  639. package/src/release/measure.ts +443 -0
  640. package/src/release/publish.ts +56 -0
  641. package/src/runs/bench.test.ts +93 -0
  642. package/src/runs/collect.ts +144 -0
  643. package/src/runs/drivers/clickhouse.ts +108 -0
  644. package/src/runs/drivers/files.ts +201 -0
  645. package/src/runs/drivers/memory.ts +94 -0
  646. package/src/runs/drivers/postgres.ts +110 -0
  647. package/src/runs/duckdb.ts +99 -0
  648. package/src/runs/index.ts +82 -0
  649. package/src/runs/outlier.ts +180 -0
  650. package/src/runs/parquet.ts +210 -0
  651. package/src/runs/privacy.ts +49 -0
  652. package/src/runs/runs.test.ts +324 -0
  653. package/src/runs/runtime.ts +229 -0
  654. package/src/runs/shred.ts +243 -0
  655. package/src/runs/telemetry.ts +10 -0
  656. package/src/runs/types.ts +179 -0
  657. package/src/runtime/bun.ts +140 -0
  658. package/src/runtime/cold-start.bench.ts +20 -0
  659. package/src/runtime/index.ts +46 -0
  660. package/src/runtime/primitives.ts +242 -0
  661. package/src/runtime/security.test.ts +170 -0
  662. package/src/runtime/security.ts +168 -0
  663. package/src/runtime/serve.test.ts +223 -0
  664. package/src/runtime/types.ts +217 -0
  665. package/src/runtime/web-standard.ts +77 -0
  666. package/src/test/create-test-app.test.ts +161 -0
  667. package/src/test/create-test-app.ts +533 -0
  668. package/src/test/index.ts +21 -0
  669. package/src/test/provisions.integration.test.ts +174 -0
  670. package/src/upgrade/codemods.test.ts +58 -0
  671. package/src/upgrade/codemods.ts +83 -0
  672. package/src/validation/index.ts +23 -0
  673. package/src/validation/standard-schema.test.ts +96 -0
  674. package/src/validation/standard-schema.ts +316 -0
@@ -0,0 +1,223 @@
1
+ import { afterEach, beforeEach, describe, expect, test } from "bun:test";
2
+ import { oke } from "../kernel/app.ts";
3
+ import { flow, resetFlowSeq } from "../kernel/flow.ts";
4
+ import { on, resetBindings } from "../kernel/on.ts";
5
+ import { http } from "../kernel/triggers.ts";
6
+ import { createBunRuntime } from "./bun.ts";
7
+ import { createWebStandardRuntime } from "./web-standard.ts";
8
+ import type { ServerHandle } from "./types.ts";
9
+
10
+ beforeEach(() => {
11
+ resetBindings();
12
+ resetFlowSeq();
13
+ });
14
+
15
+ /**
16
+ * Send a raw HTTP/1.1 request so the Host header is not rewritten by fetch.
17
+ *
18
+ * @param port - Listening port
19
+ * @param payload - Full request bytes as text
20
+ */
21
+ function rawHttp(port: number, payload: string): Promise<string> {
22
+ return new Promise((resolve, reject) => {
23
+ const chunks: Buffer[] = [];
24
+ let settled = false;
25
+ const finish = () => {
26
+ if (settled) return;
27
+ settled = true;
28
+ resolve(Buffer.concat(chunks).toString("utf8"));
29
+ };
30
+ Bun.connect({
31
+ hostname: "127.0.0.1",
32
+ port,
33
+ socket: {
34
+ open(socket) {
35
+ socket.write(payload);
36
+ },
37
+ data(_socket, data) {
38
+ chunks.push(Buffer.from(data));
39
+ if (Buffer.concat(chunks).toString("utf8").includes("\r\n\r\n")) {
40
+ finish();
41
+ }
42
+ },
43
+ close: finish,
44
+ error(_socket, err) {
45
+ if (!settled) {
46
+ settled = true;
47
+ reject(err);
48
+ }
49
+ },
50
+ },
51
+ }).catch(reject);
52
+ setTimeout(() => finish(), 2000);
53
+ });
54
+ }
55
+
56
+ function buildApp() {
57
+ on(
58
+ http.get("/ping"),
59
+ flow({
60
+ name: "ping",
61
+ do: () => ({ ok: true as const, n: 1 }),
62
+ }),
63
+ );
64
+ on(
65
+ http.get("/notes/:id"),
66
+ flow({
67
+ name: "notes.get",
68
+ do: ({ id }: { id: string }) => ({ id }),
69
+ }),
70
+ );
71
+ return oke({ name: "runtime-serve" });
72
+ }
73
+
74
+ describe("Bun.serve — real HTTP", () => {
75
+ let handle: ServerHandle | undefined;
76
+
77
+ afterEach(() => {
78
+ handle?.stop(true);
79
+ handle = undefined;
80
+ });
81
+
82
+ test("a request to a flow returns its typed response", async () => {
83
+ const app = buildApp();
84
+ const rt = createBunRuntime();
85
+ handle = rt.serve(app, { port: 0, hostname: "127.0.0.1" });
86
+
87
+ const res = await fetch(new URL("/ping", handle.url));
88
+ expect(res.status).toBe(200);
89
+ expect(await res.json()).toEqual({
90
+ data: { ok: true, n: 1 },
91
+ error: null,
92
+ });
93
+ });
94
+
95
+ test("Host: attacker.com returns 403", async () => {
96
+ const app = buildApp();
97
+ const rt = createBunRuntime();
98
+ handle = rt.serve(app, { port: 0, hostname: "127.0.0.1" });
99
+
100
+ // Pipeline-level (fetch() clients rewrite Host to the URL host).
101
+ const direct = await handle.fetch(
102
+ new Request(new URL("/ping", handle.url).href, {
103
+ headers: { host: "attacker.com" },
104
+ }),
105
+ );
106
+ expect(direct.status).toBe(403);
107
+ expect(await direct.text()).toContain("Host");
108
+
109
+ // On the wire — the DNS-rebinding shape (CVE-2025-66414 class).
110
+ const wire = await rawHttp(handle.port, [
111
+ "GET /ping HTTP/1.1",
112
+ "Host: attacker.com",
113
+ "Connection: close",
114
+ "",
115
+ "",
116
+ ].join("\r\n"));
117
+ expect(wire).toContain("403");
118
+ expect(wire).toContain("Host");
119
+ });
120
+
121
+ test("allowedHosts accepts reverse-proxy hostname", async () => {
122
+ const app = buildApp();
123
+ const rt = createBunRuntime();
124
+ handle = rt.serve(app, {
125
+ port: 0,
126
+ hostname: "127.0.0.1",
127
+ allowedHosts: ["app.example.com"],
128
+ });
129
+
130
+ const ok = await handle.fetch(
131
+ new Request("http://app.example.com/ping", {
132
+ headers: { host: "app.example.com" },
133
+ }),
134
+ );
135
+ expect(ok.status).toBe(200);
136
+
137
+ const bad = await handle.fetch(
138
+ new Request("http://evil.example.com/ping", {
139
+ headers: { host: "evil.example.com" },
140
+ }),
141
+ );
142
+ expect(bad.status).toBe(403);
143
+ });
144
+
145
+ test("param route serves through Bun native routes + app pipeline", async () => {
146
+ const app = buildApp();
147
+ const rt = createBunRuntime();
148
+ handle = rt.serve(app, { port: 0, hostname: "127.0.0.1" });
149
+
150
+ const res = await fetch(new URL("/notes/abc", handle.url));
151
+ expect(res.status).toBe(200);
152
+ expect(await res.json()).toEqual({
153
+ data: { id: "abc" },
154
+ error: null,
155
+ });
156
+ });
157
+
158
+ test("sqlite and Bun.password are available", async () => {
159
+ const rt = createBunRuntime();
160
+ const db = rt.sqlite(":memory:");
161
+ db.run("CREATE TABLE t (id INTEGER PRIMARY KEY, v TEXT)");
162
+ db.run("INSERT INTO t (v) VALUES (?)", ["hello"]);
163
+ const row = db.query("SELECT v FROM t").get() as { v: string };
164
+ expect(row.v).toBe("hello");
165
+ db.close();
166
+
167
+ const hash = await rt.crypto.hashPassword("secret");
168
+ expect(await rt.crypto.verifyPassword("secret", hash)).toBe(true);
169
+ expect(await rt.crypto.verifyPassword("nope", hash)).toBe(false);
170
+ });
171
+ });
172
+
173
+ describe("web-standard adapter — identical behaviour", () => {
174
+ test("same app object, same secured responses as Bun handle.fetch", async () => {
175
+ const app = buildApp();
176
+ const bun = createBunRuntime().serve(app, {
177
+ port: 0,
178
+ hostname: "127.0.0.1",
179
+ allowedHosts: ["app.example.com"],
180
+ });
181
+ const web = createWebStandardRuntime().serve(app, {
182
+ port: bun.port,
183
+ hostname: "127.0.0.1",
184
+ allowedHosts: ["app.example.com"],
185
+ });
186
+
187
+ try {
188
+ const cases: Request[] = [
189
+ new Request("http://127.0.0.1/ping", {
190
+ headers: { host: "127.0.0.1" },
191
+ }),
192
+ new Request("http://127.0.0.1/notes/x", {
193
+ headers: { host: "127.0.0.1" },
194
+ }),
195
+ new Request("http://attacker.com/ping", {
196
+ headers: { host: "attacker.com" },
197
+ }),
198
+ new Request("http://127.0.0.1/ping", {
199
+ headers: {
200
+ host: "127.0.0.1",
201
+ origin: "http://attacker.com",
202
+ },
203
+ }),
204
+ new Request("http://app.example.com/ping", {
205
+ headers: { host: "app.example.com" },
206
+ }),
207
+ ];
208
+
209
+ for (const req of cases) {
210
+ const twin = new Request(req.url, {
211
+ method: req.method,
212
+ headers: req.headers,
213
+ });
214
+ const [a, b] = await Promise.all([bun.fetch(req), web.fetch(twin)]);
215
+ expect(b.status).toBe(a.status);
216
+ expect(await b.text()).toBe(await a.text());
217
+ }
218
+ } finally {
219
+ bun.stop(true);
220
+ web.stop();
221
+ }
222
+ });
223
+ });
@@ -0,0 +1,217 @@
1
+ /**
2
+ * Runtime adapter contract — WinterTC Minimum Common Web API surface
3
+ * plus the few host capabilities (serve, env, files, password) every
4
+ * adapter must expose.
5
+ *
6
+ * Bun is primary (`Bun.serve`); Node / Deno / edge use the web-standard
7
+ * fetch-handler path. Program against Web APIs (`Request`, `Response`,
8
+ * `crypto`, timers); native clients live behind this interface.
9
+ */
10
+
11
+ /** Default application listen port (O·K·E mnemonic). */
12
+ export const APP_PORT = 6530;
13
+
14
+ /** Default Console listen port (O·K·E mnemonic). */
15
+ export const CONSOLE_PORT = 6533;
16
+
17
+ /** Default MCP listen port (O·K·E mnemonic). */
18
+ export const MCP_PORT = 6535;
19
+
20
+ /**
21
+ * Minimal app surface a runtime can serve.
22
+ * Satisfied by {@link import("../kernel/app.ts").OkeApp}.
23
+ */
24
+ export interface FetchApp {
25
+ /** Application name (Manifest `app`). */
26
+ readonly name: string;
27
+ /**
28
+ * Web-standard fetch handler — the single request pipeline.
29
+ *
30
+ * @param request - Incoming request
31
+ */
32
+ fetch(request: Request): Response | Promise<Response>;
33
+ /**
34
+ * Adopted bindings (used by the Bun adapter for native `routes`).
35
+ * Optional so plain `{ fetch }` apps still serve.
36
+ */
37
+ readonly bindings?: ReadonlyArray<{
38
+ readonly trigger: {
39
+ readonly kind: string;
40
+ readonly method?: string;
41
+ readonly path?: string;
42
+ };
43
+ }>;
44
+ }
45
+
46
+ /**
47
+ * Options for {@link Runtime.serve}.
48
+ *
49
+ * Host / Origin validation is **mandatory and always on** (console §10.1).
50
+ * There is no flag to disable it.
51
+ */
52
+ export interface ServeOptions {
53
+ /** Listen port. Defaults to {@link APP_PORT}. Use `0` for an ephemeral port. */
54
+ readonly port?: number;
55
+ /** Listen hostname. Defaults to `127.0.0.1`. */
56
+ readonly hostname?: string;
57
+ /**
58
+ * Stable {@link Bun.serve} identity for `bun --hot` soft reload.
59
+ * When set, Bun updates handlers on the existing socket instead of
60
+ * opening a second listener.
61
+ */
62
+ readonly id?: string;
63
+ /**
64
+ * Extra hostnames accepted in `Host` / `Origin` (reverse proxies).
65
+ * Always merged with loopback defaults and the listen hostname —
66
+ * never replaces the mandatory check.
67
+ */
68
+ readonly allowedHosts?: readonly string[];
69
+ }
70
+
71
+ /** Handle returned by {@link Runtime.serve}. */
72
+ export interface ServerHandle {
73
+ /** Base URL of the listening server (`http://hostname:port/`). */
74
+ readonly url: URL;
75
+ /** Bound port (resolved when `port: 0`). */
76
+ readonly port: number;
77
+ /** Listen hostname. */
78
+ readonly hostname: string;
79
+ /**
80
+ * Secured fetch pipeline — identical to what the listener runs.
81
+ * Edge / Node / Deno adapters expose this as the exportable handler.
82
+ *
83
+ * @param request - Incoming request
84
+ */
85
+ fetch(request: Request): Promise<Response>;
86
+ /**
87
+ * Stop accepting connections.
88
+ *
89
+ * @param closeActiveConnections - When true, abort in-flight work
90
+ */
91
+ stop(closeActiveConnections?: boolean): void | Promise<void>;
92
+ }
93
+
94
+ /** Timer primitives (WinterTC / HTML timers). */
95
+ export interface RuntimeTimers {
96
+ /**
97
+ * Resolve after `ms` milliseconds.
98
+ *
99
+ * @param ms - Delay
100
+ */
101
+ sleep(ms: number): Promise<void>;
102
+ /**
103
+ * @param fn - Callback
104
+ * @param ms - Delay
105
+ */
106
+ setTimeout(fn: () => void, ms: number): unknown;
107
+ /**
108
+ * @param id - Handle from {@link RuntimeTimers.setTimeout}
109
+ */
110
+ clearTimeout(id: unknown): void;
111
+ /**
112
+ * @param fn - Callback
113
+ * @param ms - Interval
114
+ */
115
+ setInterval(fn: () => void, ms: number): unknown;
116
+ /**
117
+ * @param id - Handle from {@link RuntimeTimers.setInterval}
118
+ */
119
+ clearInterval(id: unknown): void;
120
+ /** High-resolution monotonic time in milliseconds. */
121
+ now(): number;
122
+ }
123
+
124
+ /** Password algorithm accepted by {@link RuntimeCrypto.hashPassword}. */
125
+ export type PasswordAlgorithm = "argon2id" | "bcrypt" | "pbkdf2";
126
+
127
+ /**
128
+ * Crypto surface — Web Crypto plus password hash/verify.
129
+ * Bun binds `Bun.password`; web-standard uses PBKDF2 via SubtleCrypto.
130
+ */
131
+ export interface RuntimeCrypto {
132
+ /** Web Crypto `subtle`. */
133
+ readonly subtle: SubtleCrypto;
134
+ /** RFC 4122 UUID via `crypto.randomUUID`. */
135
+ randomUUID(): string;
136
+ /**
137
+ * Fill a typed array with cryptographically strong random values.
138
+ *
139
+ * @param array - Destination buffer
140
+ */
141
+ getRandomValues<T extends ArrayBufferView>(array: T): T;
142
+ /**
143
+ * Hash a password.
144
+ *
145
+ * @param password - Plaintext
146
+ * @param algorithm - Hash algorithm (Bun default `argon2id`)
147
+ */
148
+ hashPassword(
149
+ password: string,
150
+ algorithm?: PasswordAlgorithm,
151
+ ): Promise<string>;
152
+ /**
153
+ * Verify a password against a hash from {@link RuntimeCrypto.hashPassword}.
154
+ *
155
+ * @param password - Plaintext
156
+ * @param hash - Stored hash
157
+ */
158
+ verifyPassword(password: string, hash: string): Promise<boolean>;
159
+ }
160
+
161
+ /** Process environment access. */
162
+ export interface RuntimeEnv {
163
+ /**
164
+ * @param key - Variable name
165
+ */
166
+ get(key: string): string | undefined;
167
+ /**
168
+ * @param key - Variable name
169
+ */
170
+ has(key: string): boolean;
171
+ }
172
+
173
+ /** Filesystem access for runtime adapters (not flow code — flows use `fx`). */
174
+ export interface RuntimeFiles {
175
+ /**
176
+ * Read a file as bytes.
177
+ *
178
+ * @param path - Absolute or cwd-relative path
179
+ */
180
+ read(path: string): Promise<Uint8Array>;
181
+ /**
182
+ * Write bytes or UTF-8 text to a file.
183
+ *
184
+ * @param path - Destination path
185
+ * @param data - Contents
186
+ */
187
+ write(path: string, data: Uint8Array | string): Promise<void>;
188
+ /**
189
+ * @param path - Path to test
190
+ */
191
+ exists(path: string): Promise<boolean>;
192
+ }
193
+
194
+ /** Discriminator for the active adapter. */
195
+ export type RuntimeName = "bun" | "web-standard";
196
+
197
+ /**
198
+ * Runtime adapter — serve HTTP and expose host primitives.
199
+ *
200
+ * All world-facing I/O for the process goes through an adapter; flow code
201
+ * still reaches the world only via `fx`.
202
+ */
203
+ export interface Runtime {
204
+ /** Adapter id. */
205
+ readonly name: RuntimeName;
206
+ /**
207
+ * Serve an app. Host / Origin checks run on every request.
208
+ *
209
+ * @param app - Fetch-capable application
210
+ * @param options - Listen + `allowedHosts`
211
+ */
212
+ serve(app: FetchApp, options?: ServeOptions): ServerHandle;
213
+ readonly timers: RuntimeTimers;
214
+ readonly crypto: RuntimeCrypto;
215
+ readonly env: RuntimeEnv;
216
+ readonly files: RuntimeFiles;
217
+ }
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Web-standard runtime adapter — fetch-handler path for Node / Deno / edge.
3
+ *
4
+ * Does not open a socket. {@link Runtime.serve} returns a {@link ServerHandle}
5
+ * whose `fetch` is the secured pipeline; hosts wire it as:
6
+ *
7
+ * ```ts
8
+ * const handle = createWebStandardRuntime().serve(app);
9
+ * export default { fetch: handle.fetch }; // edge
10
+ * Deno.serve(handle.fetch);
11
+ * ```
12
+ *
13
+ * Host / Origin validation is identical to the Bun adapter (console §10.1).
14
+ */
15
+
16
+ import {
17
+ createEnv,
18
+ createFiles,
19
+ createTimers,
20
+ createWebCrypto,
21
+ } from "./primitives.ts";
22
+ import { secureFetch } from "./security.ts";
23
+ import {
24
+ APP_PORT,
25
+ type FetchApp,
26
+ type Runtime,
27
+ type ServeOptions,
28
+ type ServerHandle,
29
+ } from "./types.ts";
30
+
31
+ /**
32
+ * Create the web-standard (Node / Deno / edge) runtime adapter.
33
+ */
34
+ export function createWebStandardRuntime(): Runtime {
35
+ return {
36
+ name: "web-standard",
37
+ timers: createTimers(),
38
+ crypto: createWebCrypto(),
39
+ env: createEnv(),
40
+ files: createFiles(),
41
+ serve(app, options) {
42
+ return createFetchHandle(app, options);
43
+ },
44
+ };
45
+ }
46
+
47
+ /**
48
+ * Build a secured fetch handle without listening.
49
+ *
50
+ * @param app - Application
51
+ * @param options - Port/hostname metadata + `allowedHosts`
52
+ */
53
+ function createFetchHandle(
54
+ app: FetchApp,
55
+ options?: ServeOptions,
56
+ ): ServerHandle {
57
+ const port = options?.port ?? APP_PORT;
58
+ const hostname = options?.hostname ?? "127.0.0.1";
59
+ const fetchHandler = secureFetch(
60
+ (req) => app.fetch(req),
61
+ options,
62
+ hostname,
63
+ );
64
+ const url = new URL(
65
+ `http://${hostname.includes(":") && !hostname.startsWith("[") ? `[${hostname}]` : hostname}:${port}/`,
66
+ );
67
+
68
+ return {
69
+ url,
70
+ port,
71
+ hostname,
72
+ fetch: fetchHandler,
73
+ stop() {
74
+ // No socket — nothing to close.
75
+ },
76
+ };
77
+ }
@@ -0,0 +1,161 @@
1
+ /**
2
+ * `createTestApp` surface assumed by four-applications test blocks.
3
+ */
4
+
5
+ import { describe, expect, test } from "bun:test";
6
+ import { z } from "zod";
7
+ import { channel } from "../elements/channel.ts";
8
+ import { clock } from "../elements/clock.ts";
9
+ import { gate } from "../elements/gate.ts";
10
+ import { signal } from "../elements/signal.ts";
11
+ import { vault, VaultBootError } from "../elements/vault.ts";
12
+ import { oke } from "../kernel/app.ts";
13
+ import { flow, resetFlowSeq } from "../kernel/flow.ts";
14
+ import { on, resetBindings } from "../kernel/on.ts";
15
+ import { every, http } from "../kernel/triggers.ts";
16
+ import { createTestApp } from "./create-test-app.ts";
17
+
18
+ describe("createTestApp — four-applications surface", () => {
19
+ test("auth.loginAs · api · signals.drain · clock.advance · cron.run · channels.sent · effects.of", async () => {
20
+ resetBindings();
21
+ resetFlowSeq();
22
+
23
+ const member = gate.policy("member", ({ auth }) => !!auth.verified);
24
+ const orderPlaced = signal("order-placed", {
25
+ delivery: "once",
26
+ retries: 2,
27
+ deadLetter: true,
28
+ });
29
+ const mail = channel.email({ from: "test@oke.dev" });
30
+ const orderConfirmed = mail.template("order-confirmed", {
31
+ schema: z.object({
32
+ name: z.string(),
33
+ orderId: z.string(),
34
+ total: z.number(),
35
+ }),
36
+ });
37
+
38
+ on(
39
+ http.post("/orders").gate(member),
40
+ flow({
41
+ name: "orders.create",
42
+ unit: "orders",
43
+ in: z.object({ sku: z.string(), qty: z.number() }),
44
+ out: z.object({ id: z.string() }),
45
+ effects: { emits: ["order-placed"] },
46
+ do: async (input, fx) => {
47
+ const id = fx.id();
48
+ await fx.emit(orderPlaced, { orderId: id, ...input });
49
+ return { id };
50
+ },
51
+ }),
52
+ );
53
+
54
+ on(
55
+ orderPlaced,
56
+ flow({
57
+ name: "orders.onPlaced",
58
+ effects: { sends: ["order-confirmed"] },
59
+ do: async ({ orderId }, fx) => {
60
+ await fx.send(orderConfirmed, {
61
+ to: fx.auth.userId ?? "anon",
62
+ data: { name: "Ali", orderId, total: 10 },
63
+ });
64
+ },
65
+ }),
66
+ );
67
+
68
+ on(
69
+ every("1h"),
70
+ flow({
71
+ name: "orders.expire",
72
+ do: (_i, fx) => {
73
+ fx.log.info("expire");
74
+ },
75
+ }),
76
+ );
77
+
78
+ const app = oke({
79
+ name: "harness",
80
+ gates: [member],
81
+ signals: [orderPlaced],
82
+ clocks: [clock("expire-stale", { every: "1h" })],
83
+ channel: { templates: [orderConfirmed] },
84
+ env: "test",
85
+ });
86
+
87
+ const t = await createTestApp(app, {
88
+ gates: [member],
89
+ signals: [orderPlaced],
90
+ boot: {
91
+ clocks: [clock("expire-stale", { every: "1h" })],
92
+ channel: { templates: [orderConfirmed] },
93
+ },
94
+ });
95
+
96
+ const u = await t.auth.loginAs({ scopes: ["order:create"] });
97
+ expect(u.verified).toBe(true);
98
+
99
+ const { data, error } = await t.api.orders!.create!(
100
+ { sku: "COFFEE", qty: 2 },
101
+ { as: u },
102
+ );
103
+ expect(error).toBeNull();
104
+ expect(data).toMatchObject({ id: expect.any(String) });
105
+
106
+ await t.signals.drain();
107
+ const sent = t.channels.sent();
108
+ expect(sent.length).toBeGreaterThanOrEqual(1);
109
+ expect(
110
+ sent.some((s) => "template" in s && s.template === "order-confirmed"),
111
+ ).toBe(true);
112
+
113
+ await t.clock.advance("2m");
114
+ expect(await t.cron.run("expire-stale")).toBe(true);
115
+
116
+ const events = await t.runs();
117
+ expect(events.some((e) => e.flow === "orders.create")).toBe(true);
118
+ const createRun = events.find((e) => e.flow === "orders.create")!;
119
+ expect(t.effects.of(createRun.id).some((e) => e.kind === "emit")).toBe(
120
+ true,
121
+ );
122
+
123
+ await t.close();
124
+ });
125
+
126
+ test("ai.mock and ai.cost are assertable", async () => {
127
+ resetBindings();
128
+ resetFlowSeq();
129
+ const app = oke({ name: "ai-harness", env: "test" });
130
+ const t = await createTestApp(app);
131
+ t.ai.mock("ticket-triage", { urgency: "high", team: "ops" });
132
+ expect(t.ai.cost()).toBeLessThan(0.02);
133
+ await t.close();
134
+ });
135
+ });
136
+
137
+ describe("createTestApp — vault gaps still fail boot", () => {
138
+ test("missing secrets listed together", async () => {
139
+ resetBindings();
140
+ resetFlowSeq();
141
+ const app = oke({ name: "vault-fail", env: "prod" });
142
+
143
+ try {
144
+ await createTestApp(app, {
145
+ secrets: [
146
+ vault("A", { description: "alpha" }),
147
+ vault("B", { description: "beta" }),
148
+ ],
149
+ boot: {
150
+ env: "prod",
151
+ vault: { allowDevFallbacks: false, chain: [] },
152
+ },
153
+ });
154
+ expect.unreachable("should fail");
155
+ } catch (err) {
156
+ expect(err).toBeInstanceOf(VaultBootError);
157
+ const gaps = (err as VaultBootError).gaps.map((g) => g.name).sort();
158
+ expect(gaps).toEqual(["A", "B"]);
159
+ }
160
+ });
161
+ });