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,144 @@
1
+ /**
2
+ * Build a {@link WideEvent} from an execution context — zero instrumentation.
3
+ *
4
+ * Dimensions come from the flow contract, trigger, principals, effect ledger,
5
+ * and {@link RunTelemetry} accumulated through `fx`.
6
+ */
7
+
8
+ import type { EffectLedger } from "../kernel/effects.ts";
9
+ import type { FlowFailure } from "../kernel/errors.ts";
10
+ import type { AnyFlowDef } from "../kernel/flow.ts";
11
+ import type { Fx } from "../kernel/fx.ts";
12
+ import type { Trigger } from "../kernel/triggers.ts";
13
+ import type { FlowPlane } from "../manifest/types.ts";
14
+ import {
15
+ cacheDimensionOf,
16
+ type RunTelemetry,
17
+ } from "../kernel/run-telemetry.ts";
18
+ import type { RunError, WideEvent } from "./types.ts";
19
+
20
+ /** Inputs for {@link collectWideEvent}. */
21
+ export interface CollectWideEventInput {
22
+ /** Flow definition. */
23
+ readonly flow: AnyFlowDef;
24
+ /** Trigger that started the run. */
25
+ readonly trigger: Trigger;
26
+ /** Fx context (principals). */
27
+ readonly fx: Fx;
28
+ /** Effect ledger for this invocation. */
29
+ readonly ledger: EffectLedger;
30
+ /** Telemetry collector (logs, cache, gates, cost). */
31
+ readonly telemetry: RunTelemetry;
32
+ /** Epoch-ms when the run started. */
33
+ readonly startedAt: number;
34
+ /** Epoch-ms when the run ended. */
35
+ readonly endedAt: number;
36
+ /** Pipeline failure when present. */
37
+ readonly failure?: FlowFailure | null;
38
+ /** Optional parent run id (causal chain). */
39
+ readonly parentId?: string;
40
+ /** Optional run id (generated when omitted). */
41
+ readonly id?: string;
42
+ /** Build version stamp. */
43
+ readonly buildVersion?: string;
44
+ /**
45
+ * Personal field cleartext to archive under the subject key.
46
+ * Keys become ciphertext entries on {@link WideEvent.archived}.
47
+ */
48
+ readonly archiveFields?: Readonly<Record<string, string>>;
49
+ /** Pre-encrypted archived map (when shred already ran). */
50
+ readonly archived?: Readonly<Record<string, string>>;
51
+ }
52
+
53
+ /**
54
+ * Collect every declared / observed dimension into one wide event.
55
+ *
56
+ * @param input - Execution context
57
+ */
58
+ export function collectWideEvent(input: CollectWideEventInput): WideEvent {
59
+ const plane: FlowPlane = input.flow.plane ?? "user";
60
+ const principal =
61
+ plane === "operator"
62
+ ? input.fx.operator.id
63
+ : input.fx.auth.userId;
64
+ const tenant = input.fx.tenant.id;
65
+ const subjectId =
66
+ input.telemetry.subjectId ?? principal ?? tenant ?? null;
67
+ const cache = cacheDimensionOf(input.telemetry);
68
+ const gates =
69
+ input.telemetry.gates.length > 0
70
+ ? [...input.telemetry.gates]
71
+ : httpGates(input.trigger);
72
+
73
+ const error = failureToRunError(input.failure);
74
+ const durationMs = Math.max(0, input.endedAt - input.startedAt);
75
+
76
+ const dimensions: WideEvent["dimensions"] = {
77
+ flow: input.flow.name,
78
+ unit: input.flow.unit ?? null,
79
+ trigger: input.trigger.kind,
80
+ plane,
81
+ tenant: tenant ?? null,
82
+ principal: principal ?? null,
83
+ cache,
84
+ replica: input.telemetry.replica ?? null,
85
+ replica_lag_ms: input.telemetry.replicaLagMs ?? null,
86
+ cost: input.telemetry.cost || null,
87
+ prompt_version: input.telemetry.promptVersion ?? null,
88
+ build_version: input.buildVersion ?? null,
89
+ error_code: error?.code ?? null,
90
+ duration_ms: durationMs,
91
+ ...input.telemetry.dimensions,
92
+ };
93
+
94
+ return {
95
+ id: input.id ?? crypto.randomUUID(),
96
+ ...(input.parentId !== undefined ? { parentId: input.parentId } : {}),
97
+ flow: input.flow.name,
98
+ ...(input.flow.unit !== undefined ? { unit: input.flow.unit } : {}),
99
+ trigger: input.trigger.kind,
100
+ plane,
101
+ tenant,
102
+ principal,
103
+ subjectId,
104
+ gates,
105
+ cache,
106
+ ...(input.telemetry.replica !== undefined
107
+ ? { replica: input.telemetry.replica }
108
+ : {}),
109
+ ...(input.telemetry.replicaLagMs !== undefined
110
+ ? { replicaLagMs: input.telemetry.replicaLagMs }
111
+ : {}),
112
+ ...(input.telemetry.cost > 0 ? { cost: input.telemetry.cost } : {}),
113
+ ...(input.telemetry.promptVersion !== undefined
114
+ ? { promptVersion: input.telemetry.promptVersion }
115
+ : {}),
116
+ ...(input.buildVersion !== undefined
117
+ ? { buildVersion: input.buildVersion }
118
+ : {}),
119
+ error,
120
+ effects: [...input.ledger.entries],
121
+ logs: [...input.telemetry.logs],
122
+ durationMs,
123
+ startedAt: input.startedAt,
124
+ endedAt: input.endedAt,
125
+ ...(input.archived !== undefined ? { archived: input.archived } : {}),
126
+ dimensions,
127
+ };
128
+ }
129
+
130
+ function httpGates(trigger: Trigger): string[] {
131
+ if (trigger.kind !== "http") return [];
132
+ return trigger.gates.map((g) =>
133
+ typeof g === "string" ? g : g.name,
134
+ );
135
+ }
136
+
137
+ function failureToRunError(
138
+ failure: FlowFailure | null | undefined,
139
+ ): RunError | null {
140
+ if (!failure) return null;
141
+ const code = failure.error?.code ?? "failure";
142
+ const message = failure.error?.message;
143
+ return message !== undefined ? { code, message } : { code };
144
+ }
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Optional ClickHouse runs driver — sub-second over billions of rows at scale.
3
+ *
4
+ * Protocol-named (`clickhouse`). Fake HTTP client for tests; production uses
5
+ * the ClickHouse HTTP interface.
6
+ */
7
+
8
+ import type {
9
+ RunsDriver,
10
+ RunsOpenOptions,
11
+ RunsRow,
12
+ RunsStore,
13
+ WideEvent,
14
+ } from "../types.ts";
15
+
16
+ /** Minimal ClickHouse HTTP-like client. */
17
+ export interface RunsClickHouseClient {
18
+ /**
19
+ * Insert rows into a table.
20
+ *
21
+ * @param table - Table name
22
+ * @param rows - JSONEachRow rows
23
+ */
24
+ insert(table: string, rows: readonly RunsRow[]): Promise<void>;
25
+ /**
26
+ * Run a query returning JSON rows.
27
+ *
28
+ * @param sql - SQL text
29
+ */
30
+ query(sql: string): Promise<RunsRow[]>;
31
+ }
32
+
33
+ /**
34
+ * In-memory fake ClickHouse client for tests.
35
+ */
36
+ export function createRunsClickHouseFake(): RunsClickHouseClient & {
37
+ readonly events: WideEvent[];
38
+ } {
39
+ const events: WideEvent[] = [];
40
+ return {
41
+ events,
42
+ async insert(_table: string, rows: readonly RunsRow[]): Promise<void> {
43
+ for (const row of rows) {
44
+ if (row.payload && typeof row.payload === "object") {
45
+ events.push(row.payload as WideEvent);
46
+ } else if (typeof row.payload === "string") {
47
+ events.push(JSON.parse(row.payload) as WideEvent);
48
+ }
49
+ }
50
+ },
51
+ async query(sql: string): Promise<RunsRow[]> {
52
+ const lower = sql.toLowerCase();
53
+ if (lower.includes("count()")) {
54
+ return [{ count: events.length }];
55
+ }
56
+ return events.map((e) => ({
57
+ id: e.id,
58
+ flow: e.flow,
59
+ duration_ms: e.durationMs,
60
+ cache: e.cache,
61
+ tenant: e.tenant,
62
+ subject_id: e.subjectId,
63
+ }));
64
+ },
65
+ };
66
+ }
67
+
68
+ /**
69
+ * ClickHouse runs driver.
70
+ */
71
+ export const clickhouseRunsDriver: RunsDriver = {
72
+ id: "clickhouse",
73
+ async open(options: RunsOpenOptions = {}): Promise<RunsStore> {
74
+ const client =
75
+ (options.client as RunsClickHouseClient | undefined) ??
76
+ createRunsClickHouseFake();
77
+ const table = options.name ?? "oke_runs";
78
+
79
+ return {
80
+ driverId: "clickhouse",
81
+ async append(event: WideEvent): Promise<void> {
82
+ await client.insert(table, [
83
+ {
84
+ id: event.id,
85
+ flow: event.flow,
86
+ duration_ms: event.durationMs,
87
+ payload: event,
88
+ },
89
+ ]);
90
+ },
91
+ async flush(): Promise<void> {
92
+ /* inserts are immediate in the fake */
93
+ },
94
+ async query(sql: string): Promise<RunsRow[]> {
95
+ return client.query(sql);
96
+ },
97
+ async all(): Promise<WideEvent[]> {
98
+ if ("events" in client) {
99
+ return [...(client as { events: WideEvent[] }).events];
100
+ }
101
+ return [];
102
+ },
103
+ async close(): Promise<void> {
104
+ /* fake has no resources */
105
+ },
106
+ };
107
+ },
108
+ };
@@ -0,0 +1,201 @@
1
+ /**
2
+ * Files runs driver — Parquet + DuckDB (default in every environment).
3
+ *
4
+ * Locality is an engine detail: recent partitions sit on a local bucket;
5
+ * older ones on optional object storage. Queries span both as one result set.
6
+ * The user never declares archive tiers.
7
+ */
8
+
9
+ import { mkdtemp, rm, writeFile } from "node:fs/promises";
10
+ import { tmpdir } from "node:os";
11
+ import { join } from "node:path";
12
+
13
+ import { fsDriver } from "../../drivers/fs.ts";
14
+ import type { FilesBucket } from "../../drivers/types.ts";
15
+ import { duckPath, duckQuery, openDuckDB, type DuckSession } from "../duckdb.ts";
16
+ import {
17
+ partitionKey,
18
+ partitionObjectKey,
19
+ rowToWideEvent,
20
+ wideEventToRow,
21
+ writeParquet,
22
+ } from "../parquet.ts";
23
+ import type {
24
+ RunsDriver,
25
+ RunsOpenOptions,
26
+ RunsRow,
27
+ RunsStore,
28
+ WideEvent,
29
+ } from "../types.ts";
30
+
31
+ /** Default hot window — 7 days. Older writes go to object storage when present. */
32
+ const DEFAULT_HOT_WINDOW_MS = 7 * 24 * 60 * 60 * 1000;
33
+
34
+ /**
35
+ * Files (Parquet + DuckDB) runs driver.
36
+ */
37
+ export const filesRunsDriver: RunsDriver = {
38
+ id: "files",
39
+ async open(options: RunsOpenOptions = {}): Promise<RunsStore> {
40
+ const hotWindowMs = options.hotWindowMs ?? DEFAULT_HOT_WINDOW_MS;
41
+ const clock = () => Date.now();
42
+
43
+ const localRoot =
44
+ options.localRoot ??
45
+ (await mkdtemp(join(tmpdir(), "oke-runs-")));
46
+ const ownsLocalRoot = options.localRoot === undefined && !options.localBucket;
47
+
48
+ const local: FilesBucket =
49
+ options.localBucket ??
50
+ (await fsDriver.open({ name: "runs-local", root: localRoot }));
51
+
52
+ const remote = options.remote?.bucket;
53
+ const remotePrefix = options.remote?.prefix ?? "";
54
+
55
+ const buffer: WideEvent[] = [];
56
+ const catalog: WideEvent[] = [];
57
+ let queryScratch: string | undefined;
58
+ const session: DuckSession = await openDuckDB();
59
+
60
+ function chooseBucket(startedAt: number): {
61
+ bucket: FilesBucket;
62
+ keyPrefix: string;
63
+ locality: "local" | "remote";
64
+ } {
65
+ const age = clock() - startedAt;
66
+ if (remote && age > hotWindowMs) {
67
+ return {
68
+ bucket: remote,
69
+ keyPrefix: remotePrefix,
70
+ locality: "remote",
71
+ };
72
+ }
73
+ return { bucket: local, keyPrefix: "", locality: "local" };
74
+ }
75
+
76
+ async function flushBuffer(): Promise<void> {
77
+ if (buffer.length === 0) return;
78
+ const groups = new Map<string, WideEvent[]>();
79
+ for (const event of buffer) {
80
+ const { locality } = chooseBucket(event.startedAt);
81
+ const day = partitionKey(event.startedAt);
82
+ const gkey = `${locality}:${day}`;
83
+ const list = groups.get(gkey) ?? [];
84
+ list.push(event);
85
+ groups.set(gkey, list);
86
+ }
87
+ buffer.length = 0;
88
+
89
+ for (const [gkey, events] of groups) {
90
+ const [locality, day] = gkey.split(":") as ["local" | "remote", string];
91
+ const target =
92
+ locality === "remote" && remote
93
+ ? { bucket: remote, keyPrefix: remotePrefix }
94
+ : { bucket: local, keyPrefix: "" };
95
+ const fileId = crypto.randomUUID();
96
+ const objectKey = `${target.keyPrefix}${partitionObjectKey(day!, fileId)}`;
97
+ const tmpDir = await mkdtemp(join(tmpdir(), "oke-pq-"));
98
+ const tmp = join(tmpDir, `${fileId}.parquet`);
99
+ try {
100
+ await writeParquet(
101
+ tmp,
102
+ events.map((e) => wideEventToRow(e)),
103
+ );
104
+ const bytes = new Uint8Array(await Bun.file(tmp).arrayBuffer());
105
+ await target.bucket.put(objectKey, bytes);
106
+ for (const e of events) catalog.push(e);
107
+ } finally {
108
+ await rm(tmpDir, { recursive: true, force: true });
109
+ }
110
+ }
111
+ }
112
+
113
+ async function materialiseAllParquet(): Promise<string[]> {
114
+ if (queryScratch) {
115
+ await rm(queryScratch, { recursive: true, force: true }).catch(
116
+ () => undefined,
117
+ );
118
+ }
119
+ queryScratch = await mkdtemp(join(tmpdir(), "oke-runs-q-"));
120
+ const paths: string[] = [];
121
+
122
+ const localKeys = (await local.list("runs/")).filter((k) =>
123
+ k.endsWith(".parquet"),
124
+ );
125
+ for (const key of localKeys) {
126
+ const data = await local.get(key);
127
+ if (!data) continue;
128
+ const dest = join(queryScratch, key.replaceAll("/", "__"));
129
+ await writeFile(dest, data);
130
+ paths.push(dest);
131
+ }
132
+ if (remote) {
133
+ const prefix = `${remotePrefix}runs/`;
134
+ const remoteKeys = (await remote.list(prefix)).filter((k) =>
135
+ k.endsWith(".parquet"),
136
+ );
137
+ for (const key of remoteKeys) {
138
+ const data = await remote.get(key);
139
+ if (!data) continue;
140
+ const dest = join(
141
+ queryScratch,
142
+ `remote__${key.replaceAll("/", "__")}`,
143
+ );
144
+ await writeFile(dest, data);
145
+ paths.push(dest);
146
+ }
147
+ }
148
+ return paths;
149
+ }
150
+
151
+ return {
152
+ driverId: "files",
153
+ async append(event: WideEvent): Promise<void> {
154
+ buffer.push(event);
155
+ if (buffer.length >= 256) await flushBuffer();
156
+ },
157
+ async flush(): Promise<void> {
158
+ await flushBuffer();
159
+ },
160
+ async query(sql: string): Promise<RunsRow[]> {
161
+ await flushBuffer();
162
+ const paths = await materialiseAllParquet();
163
+ if (paths.length === 0) return [];
164
+ const list = paths.map((p) => `'${duckPath(p)}'`).join(", ");
165
+ await session.conn.run(`DROP VIEW IF EXISTS runs`);
166
+ await session.conn.run(
167
+ `CREATE VIEW runs AS SELECT * FROM read_parquet([${list}], union_by_name = true)`,
168
+ );
169
+ return duckQuery(session.conn, sql);
170
+ },
171
+ async all(): Promise<WideEvent[]> {
172
+ await flushBuffer();
173
+ if (catalog.length > 0) return [...catalog];
174
+ const paths = await materialiseAllParquet();
175
+ if (paths.length === 0) return [];
176
+ const list = paths.map((p) => `'${duckPath(p)}'`).join(", ");
177
+ const rows = await duckQuery(
178
+ session.conn,
179
+ `SELECT * FROM read_parquet([${list}], union_by_name = true)`,
180
+ );
181
+ return rows.map((r) => rowToWideEvent(r));
182
+ },
183
+ async close(): Promise<void> {
184
+ await flushBuffer();
185
+ session.close();
186
+ if (queryScratch) {
187
+ await rm(queryScratch, { recursive: true, force: true }).catch(
188
+ () => undefined,
189
+ );
190
+ }
191
+ await local.close();
192
+ await remote?.close();
193
+ if (ownsLocalRoot) {
194
+ await rm(localRoot, { recursive: true, force: true }).catch(
195
+ () => undefined,
196
+ );
197
+ }
198
+ },
199
+ };
200
+ },
201
+ };
@@ -0,0 +1,94 @@
1
+ /**
2
+ * In-memory runs driver — default for `test` environments.
3
+ *
4
+ * Uses DuckDB so queries match the `files` driver dialect (`FROM runs`).
5
+ */
6
+
7
+ import type { DuckDBConnection } from "@duckdb/node-api";
8
+
9
+ import {
10
+ duckLiteral,
11
+ duckQuery,
12
+ openDuckDB,
13
+ type DuckSession,
14
+ } from "../duckdb.ts";
15
+ import { wideEventToRow, type ParquetRow } from "../parquet.ts";
16
+ import type {
17
+ RunsDriver,
18
+ RunsOpenOptions,
19
+ RunsRow,
20
+ RunsStore,
21
+ WideEvent,
22
+ } from "../types.ts";
23
+
24
+ /**
25
+ * Memory runs driver (DuckDB `:memory:`).
26
+ */
27
+ export const memoryRunsDriver: RunsDriver = {
28
+ id: "memory",
29
+ async open(_options: RunsOpenOptions = {}): Promise<RunsStore> {
30
+ const session: DuckSession = await openDuckDB();
31
+ const events: WideEvent[] = [];
32
+
33
+ return {
34
+ driverId: "memory",
35
+ async append(event: WideEvent): Promise<void> {
36
+ events.push(event);
37
+ },
38
+ async flush(): Promise<void> {
39
+ /* nothing buffered */
40
+ },
41
+ async query(sql: string): Promise<RunsRow[]> {
42
+ await materialiseRunsTable(session.conn, events);
43
+ return duckQuery(session.conn, sql);
44
+ },
45
+ async all(): Promise<WideEvent[]> {
46
+ return [...events];
47
+ },
48
+ async close(): Promise<void> {
49
+ events.length = 0;
50
+ session.close();
51
+ },
52
+ };
53
+ },
54
+ };
55
+
56
+ /**
57
+ * Build / replace the `runs` table from wide events.
58
+ *
59
+ * @param conn - DuckDB connection
60
+ * @param events - Events to materialise
61
+ */
62
+ export async function materialiseRunsTable(
63
+ conn: DuckDBConnection,
64
+ events: readonly WideEvent[],
65
+ ): Promise<void> {
66
+ await conn.run(`DROP TABLE IF EXISTS runs`);
67
+ if (events.length === 0) {
68
+ await conn.run(
69
+ `CREATE TABLE runs AS SELECT * FROM (SELECT 1 AS id WHERE FALSE)`,
70
+ );
71
+ return;
72
+ }
73
+ // JSONL path avoids VALUES type-inference issues for mixed columns.
74
+ const rows = events.map(wideEventToRow);
75
+ const cols = unionKeys(rows);
76
+ // For small test sets, VALUES is fine and keeps the driver dependency-light.
77
+ const colList = cols.map((c) => `"${c.replaceAll('"', '""')}"`).join(", ");
78
+ const values = rows
79
+ .map(
80
+ (r) => `(${cols.map((c) => duckLiteral(r[c] ?? null)).join(", ")})`,
81
+ )
82
+ .join(",\n");
83
+ await conn.run(
84
+ `CREATE TABLE runs AS SELECT * FROM (VALUES ${values}) AS t(${colList})`,
85
+ );
86
+ }
87
+
88
+ function unionKeys(rows: readonly ParquetRow[]): string[] {
89
+ const keys = new Set<string>();
90
+ for (const r of rows) {
91
+ for (const k of Object.keys(r)) keys.add(k);
92
+ }
93
+ return [...keys];
94
+ }
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Optional Postgres runs driver — for teams who want a single store.
3
+ *
4
+ * Protocol-named. Uses an injected client in tests; production binds Bun.sql.
5
+ */
6
+
7
+ import type {
8
+ RunsDriver,
9
+ RunsOpenOptions,
10
+ RunsRow,
11
+ RunsStore,
12
+ WideEvent,
13
+ } from "../types.ts";
14
+
15
+ /** Minimal SQL surface used by the postgres runs driver. */
16
+ export interface RunsPostgresClient {
17
+ /**
18
+ * Run a query returning rows.
19
+ *
20
+ * @param sql - SQL text
21
+ * @param params - Bound parameters
22
+ */
23
+ query(sql: string, params?: readonly unknown[]): Promise<RunsRow[]>;
24
+ /**
25
+ * Execute a statement.
26
+ *
27
+ * @param sql - SQL text
28
+ * @param params - Bound parameters
29
+ */
30
+ exec(sql: string, params?: readonly unknown[]): Promise<void>;
31
+ }
32
+
33
+ /**
34
+ * In-memory fake Postgres client for tests.
35
+ */
36
+ export function createRunsPostgresFake(): RunsPostgresClient & {
37
+ readonly events: WideEvent[];
38
+ } {
39
+ const events: WideEvent[] = [];
40
+ return {
41
+ events,
42
+ async query(sql: string): Promise<RunsRow[]> {
43
+ const lower = sql.toLowerCase();
44
+ if (lower.includes("count(*)")) {
45
+ return [{ count: events.length }];
46
+ }
47
+ if (lower.includes("select payload")) {
48
+ return events.map((e) => ({ payload: e }));
49
+ }
50
+ return events.map((e) => ({
51
+ id: e.id,
52
+ flow: e.flow,
53
+ duration_ms: e.durationMs,
54
+ cache: e.cache,
55
+ tenant: e.tenant,
56
+ subject_id: e.subjectId,
57
+ }));
58
+ },
59
+ async exec(sql: string, params?: readonly unknown[]): Promise<void> {
60
+ const lower = sql.toLowerCase();
61
+ if (lower.includes("insert") && params && params.length >= 2) {
62
+ events.push(JSON.parse(String(params[1])) as WideEvent);
63
+ }
64
+ },
65
+ };
66
+ }
67
+
68
+ /**
69
+ * Postgres runs driver.
70
+ */
71
+ export const postgresRunsDriver: RunsDriver = {
72
+ id: "postgres",
73
+ async open(options: RunsOpenOptions = {}): Promise<RunsStore> {
74
+ const client =
75
+ (options.client as RunsPostgresClient | undefined) ??
76
+ createRunsPostgresFake();
77
+ const table = options.name ?? "oke_runs";
78
+ await client.exec(
79
+ `CREATE TABLE IF NOT EXISTS ${table} (id TEXT PRIMARY KEY, payload JSONB)`,
80
+ );
81
+
82
+ return {
83
+ driverId: "postgres",
84
+ async append(event: WideEvent): Promise<void> {
85
+ await client.exec(
86
+ `INSERT INTO ${table} (id, payload) VALUES ($1, $2::jsonb)`,
87
+ [event.id, JSON.stringify(event)],
88
+ );
89
+ },
90
+ async flush(): Promise<void> {
91
+ /* row-level writes are immediate */
92
+ },
93
+ async query(sql: string): Promise<RunsRow[]> {
94
+ return client.query(sql);
95
+ },
96
+ async all(): Promise<WideEvent[]> {
97
+ const result = await client.query(`SELECT payload FROM ${table}`);
98
+ return result.map((r) => {
99
+ const p = r.payload ?? r;
100
+ return typeof p === "string"
101
+ ? (JSON.parse(p) as WideEvent)
102
+ : (p as WideEvent);
103
+ });
104
+ },
105
+ async close(): Promise<void> {
106
+ /* fake has no resources */
107
+ },
108
+ };
109
+ },
110
+ };