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,140 @@
1
+ /**
2
+ * Effect recording and the typed effect ledger.
3
+ *
4
+ * Every `fx` world access appends an {@link EffectEntry}. The ledger is what
5
+ * the journal, tests, runs store, and capability check all read.
6
+ */
7
+
8
+ /** The seven load-bearing effect kinds (manifest `effects` keys, singular). */
9
+ export type EffectKind =
10
+ | "read"
11
+ | "write"
12
+ | "emit"
13
+ | "send"
14
+ | "ask"
15
+ | "secret"
16
+ | "call";
17
+
18
+ /**
19
+ * Reversibility tier — console §9.1 ranking, applied to all seven kinds.
20
+ *
21
+ * - `none` — reads; no world change
22
+ * - `reversible` — writes; undoable in-transaction
23
+ * - `deferred` — emits; commit with the txn, then fan-out
24
+ * - `irreversible` — sends / asks; cannot be undone by the runtime
25
+ * - `capability` — secrets; authority held, not an effect caused
26
+ * - `portal` — calls; expands to the callee's transitive effects
27
+ */
28
+ export type ReversibilityTier =
29
+ | "none"
30
+ | "reversible"
31
+ | "deferred"
32
+ | "irreversible"
33
+ | "capability"
34
+ | "portal";
35
+
36
+ /** One recorded effect call. */
37
+ export interface EffectEntry {
38
+ /** Which of the seven kinds. */
39
+ readonly kind: EffectKind;
40
+ /** Resource / signal / template / prompt / secret / flow ref. */
41
+ readonly resource: string;
42
+ /** Epoch-ms when the call started. */
43
+ readonly timestamp: number;
44
+ /** Wall duration in milliseconds. */
45
+ readonly duration: number;
46
+ /** Reversibility tier for {@link kind}. */
47
+ readonly reversibility: ReversibilityTier;
48
+ }
49
+
50
+ /** Append-only ledger of effect entries for one flow invocation. */
51
+ export interface EffectLedger {
52
+ /** Snapshot of recorded entries in call order. */
53
+ readonly entries: readonly EffectEntry[];
54
+ /**
55
+ * Append a completed effect entry.
56
+ *
57
+ * @param entry - Entry to record
58
+ */
59
+ record(entry: EffectEntry): void;
60
+ /** Clear all entries (test helper). */
61
+ clear(): void;
62
+ }
63
+
64
+ /** Fixed mapping: kind → reversibility tier. */
65
+ const TIER_BY_KIND: Readonly<Record<EffectKind, ReversibilityTier>> = {
66
+ read: "none",
67
+ write: "reversible",
68
+ emit: "deferred",
69
+ send: "irreversible",
70
+ ask: "irreversible",
71
+ secret: "capability",
72
+ call: "portal",
73
+ };
74
+
75
+ /**
76
+ * Reversibility tier for an effect kind.
77
+ *
78
+ * @param kind - One of the seven effect kinds
79
+ */
80
+ export function reversibilityOf(kind: EffectKind): ReversibilityTier {
81
+ return TIER_BY_KIND[kind];
82
+ }
83
+
84
+ /**
85
+ * Create an empty in-memory effect ledger.
86
+ */
87
+ export function createEffectLedger(): EffectLedger {
88
+ const entries: EffectEntry[] = [];
89
+ return {
90
+ get entries() {
91
+ return entries;
92
+ },
93
+ record(entry: EffectEntry): void {
94
+ entries.push(entry);
95
+ },
96
+ clear(): void {
97
+ entries.length = 0;
98
+ },
99
+ };
100
+ }
101
+
102
+ /**
103
+ * Record an effect around an async (or sync) body, measuring duration.
104
+ *
105
+ * @param ledger - Target ledger
106
+ * @param kind - Effect kind
107
+ * @param resource - Resource ref
108
+ * @param now - Clock (injectable for tests)
109
+ * @param body - Work to time
110
+ */
111
+ export async function recordEffect<T>(
112
+ ledger: EffectLedger,
113
+ kind: EffectKind,
114
+ resource: string,
115
+ now: () => number,
116
+ body: () => T | Promise<T>,
117
+ ): Promise<T> {
118
+ const timestamp = now();
119
+ try {
120
+ return await body();
121
+ } finally {
122
+ ledger.record({
123
+ kind,
124
+ resource,
125
+ timestamp,
126
+ duration: Math.max(0, now() - timestamp),
127
+ reversibility: reversibilityOf(kind),
128
+ });
129
+ }
130
+ }
131
+
132
+ /**
133
+ * All seven kinds with their tiers — useful for exhaustive tests.
134
+ */
135
+ export const EFFECT_KIND_TIERS: ReadonlyArray<{
136
+ kind: EffectKind;
137
+ reversibility: ReversibilityTier;
138
+ }> = (
139
+ Object.entries(TIER_BY_KIND) as Array<[EffectKind, ReversibilityTier]>
140
+ ).map(([kind, reversibility]) => ({ kind, reversibility }));
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Error-code registry gate — unique codes, cause/fix/docsUrl shape (§21).
3
+ *
4
+ * Docs pages (docs/e/{code}.md) are deferred to a dedicated docs prompt;
5
+ * this gate enforces registry invariants only.
6
+ */
7
+
8
+ import { describe, expect, test } from "bun:test";
9
+ import {
10
+ OKE_ERRORS,
11
+ OkeError,
12
+ type OkeErrorDefinition,
13
+ } from "./errors.ts";
14
+
15
+ describe("OKE error-code registry", () => {
16
+ test("every code is unique", () => {
17
+ const codes = Object.values(OKE_ERRORS).map((d) => d.code);
18
+ expect(new Set(codes).size).toBe(codes.length);
19
+ });
20
+
21
+ test("every entry has non-empty cause and fix templates", () => {
22
+ for (const [key, def] of Object.entries(OKE_ERRORS)) {
23
+ expect(def.cause.trim().length, `${key}.cause`).toBeGreaterThan(0);
24
+ expect(def.fix.trim().length, `${key}.fix`).toBeGreaterThan(0);
25
+ expect(Number.isInteger(def.code), `${key}.code`).toBe(true);
26
+ expect(def.code, `${key}.code`).toBeGreaterThan(0);
27
+ }
28
+ });
29
+
30
+ test("OkeError docsUrl matches https://oke.dev/e/{code}", () => {
31
+ for (const def of Object.values(OKE_ERRORS) as OkeErrorDefinition[]) {
32
+ const err = new OkeError(def);
33
+ expect(err.docsUrl).toBe(`https://oke.dev/e/${def.code}`);
34
+ expect(err.message).toContain(err.docsUrl);
35
+ expect(err.message).toContain(`OKE${def.code}`);
36
+ expect(err.message).toContain("→");
37
+ }
38
+ });
39
+ });
@@ -0,0 +1,225 @@
1
+ /**
2
+ * Typed framework errors and flow-boundary failure values.
3
+ *
4
+ * Every framework error has a stable numeric code, a one-line cause,
5
+ * a suggested fix, and a docs URL (unified-theory §21). Codes are
6
+ * permanent from the moment they enter this registry.
7
+ */
8
+
9
+ /** Numeric OKE error code (permanent once published). */
10
+ export type OkeErrorCode = number;
11
+
12
+ /** One registry entry — cause/fix may include `{name}` placeholders. */
13
+ export interface OkeErrorDefinition {
14
+ /** Permanent numeric code. */
15
+ readonly code: OkeErrorCode;
16
+ /** One-line cause template. */
17
+ readonly cause: string;
18
+ /** Suggested fix template. */
19
+ readonly fix: string;
20
+ }
21
+
22
+ /** Context values interpolated into cause/fix templates. */
23
+ export type OkeErrorParams = Readonly<Record<string, string>>;
24
+
25
+ /**
26
+ * Framework error: thrown for invariant violations (capability, wiring).
27
+ * Distinct from flow-boundary failures returned by {@link fail}.
28
+ */
29
+ export class OkeError extends Error {
30
+ /** Permanent numeric code. */
31
+ readonly code: OkeErrorCode;
32
+ /** Interpolated one-line cause. */
33
+ readonly causeText: string;
34
+ /** Interpolated suggested fix. */
35
+ readonly fix: string;
36
+ /** Docs URL for this code. */
37
+ readonly docsUrl: string;
38
+ /** Interpolation params used to build the message. */
39
+ readonly params: OkeErrorParams;
40
+
41
+ /**
42
+ * @param definition - Registry entry
43
+ * @param params - Values for `{placeholders}` in cause/fix
44
+ */
45
+ constructor(definition: OkeErrorDefinition, params: OkeErrorParams = {}) {
46
+ const causeText = interpolate(definition.cause, params);
47
+ const fix = interpolate(definition.fix, params);
48
+ const docsUrl = `https://oke.dev/e/${definition.code}`;
49
+ const message = formatOkeMessage(definition.code, causeText, fix, docsUrl);
50
+ super(message);
51
+ this.name = "OkeError";
52
+ this.code = definition.code;
53
+ this.causeText = causeText;
54
+ this.fix = fix;
55
+ this.docsUrl = docsUrl;
56
+ this.params = params;
57
+ }
58
+ }
59
+
60
+ /**
61
+ * Flow-boundary failure value produced by {@link fail}.
62
+ * Errors are values (`{ data, error }`), not exceptions, at the flow boundary.
63
+ */
64
+ export interface FlowFailure<E = unknown> {
65
+ readonly data: null;
66
+ readonly error: FlowErrorValue<E>;
67
+ }
68
+
69
+ /** Payload carried by a flow-boundary failure. */
70
+ export interface FlowErrorValue<E = unknown> {
71
+ /**
72
+ * Declared error code from the flow's `errors` map
73
+ * (e.g. `"FlightFull"`, `"ValidationError"`) — not an OKE#### number.
74
+ * Clients narrow with `error?.code === "FlightFull"`.
75
+ */
76
+ readonly code: string;
77
+ /** Typed error data from the flow. */
78
+ readonly data: E;
79
+ /** Optional localized or custom message. */
80
+ readonly message?: string;
81
+ }
82
+
83
+ /** Optional extras for {@link fail}. */
84
+ export interface FailOptions {
85
+ /** Override message (often from `fx.t(...)`). */
86
+ readonly message?: string;
87
+ }
88
+
89
+ /**
90
+ * Permanent error registry. Codes never change meaning once published.
91
+ *
92
+ * Ranges (convention):
93
+ * - `1000–1099` — capability / undeclared-effect violations
94
+ * - `1042` — reserved by unified-theory §21 example (orphan emit)
95
+ */
96
+ export const OKE_ERRORS = {
97
+ /** Flow reads a store resource not listed in `effects.reads`. */
98
+ UNDECLARED_READ: {
99
+ code: 1001,
100
+ cause:
101
+ 'Flow "{flow}" reads "{resource}" without declaring it.',
102
+ fix: 'Add "{resource}" to this flow\'s effects.reads.',
103
+ },
104
+ /** Flow writes a store resource not listed in `effects.writes`. */
105
+ UNDECLARED_WRITE: {
106
+ code: 1002,
107
+ cause:
108
+ 'Flow "{flow}" writes "{resource}" without declaring it.',
109
+ fix: 'Add "{resource}" to this flow\'s effects.writes.',
110
+ },
111
+ /** Flow emits a signal not listed in `effects.emits`. */
112
+ UNDECLARED_EMIT: {
113
+ code: 1003,
114
+ cause:
115
+ 'Flow "{flow}" emits "{resource}" without declaring it.',
116
+ fix: 'Add "{resource}" to this flow\'s effects.emits.',
117
+ },
118
+ /** Flow sends a channel template not listed in `effects.sends`. */
119
+ UNDECLARED_SEND: {
120
+ code: 1004,
121
+ cause:
122
+ 'Flow "{flow}" sends "{resource}" without declaring it.',
123
+ fix: 'Add "{resource}" to this flow\'s effects.sends.',
124
+ },
125
+ /** Flow asks a prompt not listed in `effects.asks`. */
126
+ UNDECLARED_ASK: {
127
+ code: 1005,
128
+ cause:
129
+ 'Flow "{flow}" asks "{resource}" without declaring it.',
130
+ fix: 'Add "{resource}" to this flow\'s effects.asks.',
131
+ },
132
+ /** Flow reads a secret not listed in `effects.secrets`. */
133
+ UNDECLARED_SECRET: {
134
+ code: 1006,
135
+ cause:
136
+ 'Flow "{flow}" reads secret "{resource}" without declaring it.',
137
+ fix: 'Add "{resource}" to this flow\'s effects.secrets.',
138
+ },
139
+ /** Flow calls another flow not listed in `effects.calls`. */
140
+ UNDECLARED_CALL: {
141
+ code: 1007,
142
+ cause:
143
+ 'Flow "{flow}" calls "{resource}" without declaring it.',
144
+ fix: 'Add "{resource}" to this flow\'s effects.calls.',
145
+ },
146
+ /**
147
+ * Emit target has no subscriber (unified-theory §21 example).
148
+ * Reserved now so the number stays permanent.
149
+ */
150
+ ORPHAN_EMIT: {
151
+ code: 1042,
152
+ cause:
153
+ 'Flow "{flow}" emits signal "{resource}" with no subscriber.',
154
+ fix: 'Add `on({resource}, …)` or mark the signal `{ optional: true }`.',
155
+ },
156
+ } as const satisfies Record<string, OkeErrorDefinition>;
157
+
158
+ /**
159
+ * Build and throw a registered framework error.
160
+ *
161
+ * @param key - Key into {@link OKE_ERRORS}
162
+ * @param params - Interpolation params
163
+ * @returns Never
164
+ */
165
+ export function throwOke(
166
+ key: keyof typeof OKE_ERRORS,
167
+ params: OkeErrorParams = {},
168
+ ): never {
169
+ throw new OkeError(OKE_ERRORS[key], params);
170
+ }
171
+
172
+ /**
173
+ * Look up a registry entry by numeric code.
174
+ *
175
+ * @param code - Permanent numeric code
176
+ */
177
+ export function lookupOkeError(
178
+ code: OkeErrorCode,
179
+ ): OkeErrorDefinition | undefined {
180
+ for (const def of Object.values(OKE_ERRORS)) {
181
+ if (def.code === code) return def;
182
+ }
183
+ return undefined;
184
+ }
185
+
186
+ /**
187
+ * Create a flow-boundary failure value (does not throw).
188
+ *
189
+ * @param code - Declared error code from the flow's `errors` map
190
+ * @param data - Error payload
191
+ * @param opts - Optional message override
192
+ */
193
+ export function fail<E>(
194
+ code: string,
195
+ data: E,
196
+ opts?: FailOptions,
197
+ ): FlowFailure<E> {
198
+ const error: FlowErrorValue<E> = opts?.message !== undefined
199
+ ? { code, data, message: opts.message }
200
+ : { code, data };
201
+ return { data: null, error };
202
+ }
203
+
204
+ /**
205
+ * Format the canonical multi-line OKE error message (§21).
206
+ *
207
+ * @param code - Numeric code
208
+ * @param cause - Interpolated cause
209
+ * @param fix - Interpolated fix
210
+ * @param docsUrl - Docs URL
211
+ */
212
+ export function formatOkeMessage(
213
+ code: OkeErrorCode,
214
+ cause: string,
215
+ fix: string,
216
+ docsUrl: string,
217
+ ): string {
218
+ return `OKE${code} ${cause}\n → ${fix}\n ${docsUrl}`;
219
+ }
220
+
221
+ function interpolate(template: string, params: OkeErrorParams): string {
222
+ return template.replace(/\{([a-zA-Z0-9_]+)\}/g, (_, key: string) => {
223
+ return params[key] ?? `{${key}}`;
224
+ });
225
+ }
@@ -0,0 +1,154 @@
1
+ import { describe, expect, test, beforeEach } from "bun:test";
2
+ import { oke } from "./app.ts";
3
+ import { flow, isFlow, resetFlowSeq } from "./flow.ts";
4
+ import { on, resetBindings } from "./on.ts";
5
+ import {
6
+ every,
7
+ http,
8
+ internal,
9
+ table,
10
+ } from "./triggers.ts";
11
+
12
+ beforeEach(() => {
13
+ resetBindings();
14
+ resetFlowSeq();
15
+ });
16
+
17
+ describe("flow — one species", () => {
18
+ test("flow() returns a branded FlowDef", () => {
19
+ const f = flow({
20
+ name: "ping",
21
+ do: () => ({ ok: true }),
22
+ });
23
+ expect(isFlow(f)).toBe(true);
24
+ expect(f.name).toBe("ping");
25
+ expect(f.triggers).toEqual([]);
26
+ expect(f.durable).toBe(false);
27
+ });
28
+
29
+ test("on() returns the same flow object and records the trigger", () => {
30
+ const f = flow({ name: "create", do: () => 1 });
31
+ const bound = on(http.post("/notes"), f);
32
+ // Same runtime object; trigger stamp is type-only so identities differ at the type level.
33
+ expect(bound as object).toBe(f);
34
+ expect(f.triggers).toHaveLength(1);
35
+ expect(f.triggers[0]?.kind).toBe("http");
36
+ expect(bound.$trigger?.kind).toBe("http");
37
+ });
38
+
39
+ test("the same flow object is reachable from HTTP and signal triggers", async () => {
40
+ const calls: string[] = [];
41
+ const shared = flow({
42
+ name: "shared.work",
43
+ do: (input: { n: number }) => {
44
+ calls.push(`n=${input.n}`);
45
+ return { n: input.n * 2 };
46
+ },
47
+ });
48
+
49
+ const signal = { name: "order-placed", delivery: "once" as const };
50
+ on(http.post("/work"), shared);
51
+ on(signal, shared);
52
+
53
+ const app = oke({ name: "one-species" });
54
+ expect(app.bindings).toHaveLength(2);
55
+ expect(app.bindings[0]?.flow).toBe(shared);
56
+ expect(app.bindings[1]?.flow).toBe(shared);
57
+
58
+ const httpResult = await app.execute(
59
+ shared,
60
+ { n: 3 },
61
+ shared.triggers[0]!,
62
+ );
63
+ const signalResults = await app.dispatchSignal("order-placed", { n: 4 });
64
+
65
+ expect(httpResult.output).toEqual({ n: 6 });
66
+ expect(signalResults[0]?.output).toEqual({ n: 8 });
67
+ expect(calls).toEqual(["n=3", "n=4"]);
68
+ });
69
+ });
70
+
71
+ describe("five trigger kinds", () => {
72
+ test("http · every · signal · table.changed · internal", async () => {
73
+ const seen: string[] = [];
74
+
75
+ const httpFlow = on(
76
+ http.get("/:code"),
77
+ flow({
78
+ name: "t.http",
79
+ do: ({ code }: { code: string }) => {
80
+ seen.push(`http:${code}`);
81
+ return { code };
82
+ },
83
+ }),
84
+ );
85
+
86
+ on(
87
+ every("1h"),
88
+ flow({
89
+ name: "t.every",
90
+ do: () => {
91
+ seen.push("every");
92
+ },
93
+ }),
94
+ );
95
+
96
+ on(
97
+ { name: "link-clicked", delivery: "once" },
98
+ flow({
99
+ name: "t.signal",
100
+ do: ({ code }: { code: string }) => {
101
+ seen.push(`signal:${code}`);
102
+ },
103
+ }),
104
+ );
105
+
106
+ on(
107
+ table("orders").changed("status"),
108
+ flow({
109
+ name: "t.cdc",
110
+ do: (p: { before: { status: string }; after: { status: string } }) => {
111
+ seen.push(`cdc:${p.before.status}->${p.after.status}`);
112
+ },
113
+ }),
114
+ );
115
+
116
+ on(
117
+ internal,
118
+ flow({
119
+ name: "t.internal",
120
+ do: () => {
121
+ seen.push("internal");
122
+ return { ok: true };
123
+ },
124
+ }),
125
+ );
126
+
127
+ const app = oke({ name: "five" });
128
+
129
+ const res = await app.fetch(
130
+ new Request("http://localhost/abc", { method: "GET" }),
131
+ );
132
+ expect(res.status).toBe(200);
133
+ expect(await res.json()).toEqual({ data: { code: "abc" }, error: null });
134
+
135
+ await app.dispatchEvery("1h");
136
+ await app.dispatchSignal("link-clicked", { code: "sa" });
137
+ await app.dispatchCdc("orders", {
138
+ before: { status: "open" },
139
+ after: { status: "paid" },
140
+ }, "status");
141
+
142
+ const internalResult = await app.call("t.internal");
143
+ expect(internalResult).toEqual({ ok: true });
144
+
145
+ expect(seen).toEqual([
146
+ "http:abc",
147
+ "every",
148
+ "signal:sa",
149
+ "cdc:open->paid",
150
+ "internal",
151
+ ]);
152
+ expect(httpFlow.triggers[0]?.kind).toBe("http");
153
+ });
154
+ });