okengine 0.2.6 → 0.3.2

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 (681) hide show
  1. package/AGENTS.md +33 -30
  2. package/README.md +74 -340
  3. package/{spec/manifest.v1.schema.json → manifest.v1.schema.json} +40 -9
  4. package/package.json +47 -44
  5. package/site/content/docs/ai/llms-txt.mdx +54 -0
  6. package/site/content/docs/ai/mcp.mdx +123 -0
  7. package/site/content/docs/ai/meta.json +5 -0
  8. package/site/content/docs/ai/skills.mdx +53 -0
  9. package/site/content/docs/console/access.mdx +29 -0
  10. package/site/content/docs/console/ai.mdx +35 -0
  11. package/site/content/docs/console/architecture.mdx +35 -0
  12. package/site/content/docs/console/channels.mdx +37 -0
  13. package/site/content/docs/console/clock.mdx +31 -0
  14. package/site/content/docs/console/flows.mdx +31 -0
  15. package/site/content/docs/console/gates.mdx +35 -0
  16. package/site/content/docs/console/manifest-diff.mdx +34 -0
  17. package/site/content/docs/console/meta.json +23 -0
  18. package/site/content/docs/console/overview.mdx +40 -0
  19. package/site/content/docs/console/plugins.mdx +41 -0
  20. package/site/content/docs/console/privacy.mdx +32 -0
  21. package/site/content/docs/console/runs.mdx +40 -0
  22. package/site/content/docs/console/signals.mdx +31 -0
  23. package/site/content/docs/console/store.mdx +32 -0
  24. package/site/content/docs/console/tenancy.mdx +32 -0
  25. package/site/content/docs/console/traces.mdx +34 -0
  26. package/site/content/docs/console/vault.mdx +37 -0
  27. package/site/content/docs/elements/ai.mdx +180 -0
  28. package/site/content/docs/elements/channel.mdx +167 -0
  29. package/site/content/docs/elements/clock.mdx +182 -0
  30. package/site/content/docs/elements/flow.mdx +288 -0
  31. package/site/content/docs/elements/gate.mdx +171 -0
  32. package/site/content/docs/elements/meta.json +5 -0
  33. package/site/content/docs/elements/signal.mdx +171 -0
  34. package/site/content/docs/elements/store.mdx +320 -0
  35. package/site/content/docs/elements/vault.mdx +263 -0
  36. package/site/content/docs/get-started/basic-usage.mdx +124 -0
  37. package/site/content/docs/get-started/comparison.mdx +65 -0
  38. package/site/content/docs/get-started/installation.mdx +113 -0
  39. package/site/content/docs/get-started/introduction.mdx +123 -0
  40. package/site/content/docs/get-started/meta.json +5 -0
  41. package/site/content/docs/index.mdx +63 -0
  42. package/site/content/docs/meta.json +5 -0
  43. package/site/content/docs/plugins/compression.mdx +60 -0
  44. package/site/content/docs/plugins/cors.mdx +92 -0
  45. package/site/content/docs/plugins/csrf.mdx +96 -0
  46. package/site/content/docs/plugins/ip-allowlist.mdx +92 -0
  47. package/site/content/docs/plugins/maintenance-mode.mdx +101 -0
  48. package/site/content/docs/plugins/meta.json +15 -0
  49. package/site/content/docs/plugins/security-headers.mdx +136 -0
  50. package/site/content/docs/reference/cli.md +101 -0
  51. package/site/content/docs/reference/configuration.mdx +159 -0
  52. package/site/content/docs/reference/environment-variables.mdx +87 -0
  53. package/site/content/docs/reference/errors.mdx +80 -0
  54. package/site/content/docs/reference/fx.mdx +117 -0
  55. package/site/content/docs/reference/meta.json +5 -0
  56. package/site/content/docs/reference/plugins.mdx +249 -0
  57. package/site/content/docs/reference/security.md +63 -0
  58. package/src/auth/api-keys.ts +2 -5
  59. package/src/auth/attenuation.ts +2 -6
  60. package/src/auth/auth.test.ts +56 -31
  61. package/src/auth/invoke-as.ts +1 -3
  62. package/src/auth/operator.ts +8 -26
  63. package/src/auth/planes.ts +2 -7
  64. package/src/auth/plugin.ts +4 -7
  65. package/src/auth/roles.ts +1 -5
  66. package/src/auth/sessions.ts +10 -39
  67. package/src/cli/args.ts +1 -5
  68. package/src/cli/ask-dev-mode.ts +40 -0
  69. package/src/cli/build.ts +1 -2
  70. package/src/cli/client-add.test.ts +8 -15
  71. package/src/cli/client-add.ts +5 -14
  72. package/src/cli/completion.test.ts +1 -5
  73. package/src/cli/completion.ts +4 -17
  74. package/src/cli/db-auto-push.test.ts +64 -0
  75. package/src/cli/db-auto-push.ts +72 -0
  76. package/src/cli/db.test.ts +189 -0
  77. package/src/cli/db.ts +456 -0
  78. package/src/cli/dev-app-runner.ts +2 -8
  79. package/src/cli/dev-db-push.test.ts +193 -0
  80. package/src/cli/dev-mode.test.ts +45 -0
  81. package/src/cli/dev-mode.ts +78 -0
  82. package/src/cli/dev-schema-sync.test.ts +66 -0
  83. package/src/cli/dev-schema-sync.ts +139 -0
  84. package/src/cli/dev.test.ts +264 -15
  85. package/src/cli/dev.ts +355 -139
  86. package/src/cli/doc-staleness.test.ts +69 -0
  87. package/src/cli/docker-cli.test.ts +27 -8
  88. package/src/cli/docker.ts +11 -3
  89. package/src/cli/doctor-diff.test.ts +1 -5
  90. package/src/cli/doctor-diff.ts +17 -46
  91. package/src/cli/doctor-pii.ts +2 -7
  92. package/src/cli/doctor.test.ts +26 -4
  93. package/src/cli/doctor.ts +35 -11
  94. package/src/cli/drizzle-env.test.ts +67 -0
  95. package/src/cli/drizzle-env.ts +78 -0
  96. package/src/cli/ensure-drizzle-config.ts +50 -0
  97. package/src/cli/eval.ts +4 -14
  98. package/src/cli/gates-list.ts +1 -4
  99. package/src/cli/hero-meta.test.ts +17 -19
  100. package/src/cli/hero-meta.ts +20 -30
  101. package/src/cli/images.ts +3 -8
  102. package/src/cli/index.ts +11 -2
  103. package/src/cli/load-config.images.test.ts +14 -14
  104. package/src/cli/load-config.ts +47 -47
  105. package/src/cli/mcp-from-console.ts +1 -4
  106. package/src/cli/mode.ts +65 -0
  107. package/src/cli/openbao-bootstrap.test.ts +147 -0
  108. package/src/cli/openbao-bootstrap.ts +280 -0
  109. package/src/cli/openbao-restart.integration.test.ts +136 -0
  110. package/src/cli/ports.test.ts +7 -14
  111. package/src/cli/ports.ts +7 -5
  112. package/src/cli/privacy-erase.ts +1 -3
  113. package/src/cli/registry.ts +75 -25
  114. package/src/cli/resolve-dev-sql-env.test.ts +48 -0
  115. package/src/cli/resolve-dev-sql-env.ts +42 -0
  116. package/src/cli/schema.ts +3 -10
  117. package/src/cli/stack.ts +8 -10
  118. package/src/cli/start.ts +4 -15
  119. package/src/cli/upgrade.ts +1 -4
  120. package/src/cli/vault-cmd.ts +63 -0
  121. package/src/client/budget-entry.ts +1 -6
  122. package/src/client/create.test.ts +6 -12
  123. package/src/client/create.ts +2 -8
  124. package/src/client/errors.ts +1 -4
  125. package/src/client/index.ts +1 -6
  126. package/src/client/notes-contract.test.ts +4 -13
  127. package/src/client/transport.ts +9 -30
  128. package/src/client/types.ts +15 -30
  129. package/src/compiler/aot.test.ts +2 -9
  130. package/src/compiler/aot.ts +1 -4
  131. package/src/compiler/differential.test.ts +3 -11
  132. package/src/compiler/dynamic.ts +1 -4
  133. package/src/compiler/effects-infer.ts +8 -34
  134. package/src/compiler/emit.ts +1 -3
  135. package/src/compiler/extract.test.ts +136 -30
  136. package/src/compiler/extract.ts +485 -157
  137. package/src/compiler/fixtures/skyport/oke.config.ts +3 -3
  138. package/src/compiler/fixtures/skyport/src/flows/bookings/index.ts +7 -3
  139. package/src/compiler/fixtures/skyport/src/flows/payments/index.ts +1 -3
  140. package/src/compiler/fixtures/skyport/src/flows/support/index.ts +4 -1
  141. package/src/compiler/fixtures/skyport.expected.json +24 -83
  142. package/src/compiler/fixtures/triggers/five-triggers.ts +1 -2
  143. package/src/compiler/http-parse.ts +2 -9
  144. package/src/compiler/index.ts +1 -5
  145. package/src/compiler/response.ts +16 -7
  146. package/src/compiler/sucrose.ts +11 -31
  147. package/src/config/define-config.test.ts +55 -34
  148. package/src/config/index.ts +177 -46
  149. package/src/config/resolve-driver.test.ts +28 -17
  150. package/src/console/budget.test.ts +1 -4
  151. package/src/console/index.ts +1 -4
  152. package/src/console/server/access.test.ts +15 -43
  153. package/src/console/server/access.ts +19 -49
  154. package/src/console/server/ai.test.ts +3 -11
  155. package/src/console/server/ai.ts +23 -46
  156. package/src/console/server/app.ts +16 -45
  157. package/src/console/server/auth-rate.test.ts +4 -12
  158. package/src/console/server/bind.ts +1 -5
  159. package/src/console/server/channels.test.ts +2 -6
  160. package/src/console/server/channels.ts +10 -35
  161. package/src/console/server/claim.ts +2 -8
  162. package/src/console/server/clock.test.ts +2 -6
  163. package/src/console/server/clock.ts +8 -26
  164. package/src/console/server/console.test.ts +1 -3
  165. package/src/console/server/diff.test.ts +5 -17
  166. package/src/console/server/diff.ts +10 -31
  167. package/src/console/server/dry-run.audit.test.ts +2 -8
  168. package/src/console/server/flows.ts +64 -233
  169. package/src/console/server/gates.test.ts +14 -50
  170. package/src/console/server/gates.ts +13 -48
  171. package/src/console/server/index.ts +2 -9
  172. package/src/console/server/live.ts +3 -12
  173. package/src/console/server/operator-db.test.ts +4 -15
  174. package/src/console/server/operator-db.ts +13 -32
  175. package/src/console/server/plugin.ts +50 -53
  176. package/src/console/server/plugins.test.ts +2 -6
  177. package/src/console/server/plugins.ts +17 -56
  178. package/src/console/server/runs-pii.ts +2 -7
  179. package/src/console/server/security.gate.test.ts +18 -40
  180. package/src/console/server/serve.ts +10 -25
  181. package/src/console/server/signals.test.ts +1 -3
  182. package/src/console/server/signals.ts +17 -40
  183. package/src/console/server/state.ts +21 -59
  184. package/src/console/server/store.test.ts +20 -22
  185. package/src/console/server/store.ts +31 -76
  186. package/src/console/server/vault.test.ts +12 -29
  187. package/src/console/server/vault.ts +44 -66
  188. package/src/console/ui/access/AccessA11yView.tsx +6 -21
  189. package/src/console/ui/access/a11y.test.tsx +3 -12
  190. package/src/console/ui/access/acknowledgement.test.ts +1 -4
  191. package/src/console/ui/access/acknowledgement.ts +1 -3
  192. package/src/console/ui/access/blast-radius.ts +1 -3
  193. package/src/console/ui/access/confirmation.test.ts +1 -5
  194. package/src/console/ui/access/confirmation.ts +1 -4
  195. package/src/console/ui/access/fixture.ts +1 -5
  196. package/src/console/ui/access/grantable.test.ts +1 -3
  197. package/src/console/ui/access/grantable.ts +2 -7
  198. package/src/console/ui/access/index.ts +2 -9
  199. package/src/console/ui/access/provenance.test.ts +1 -3
  200. package/src/console/ui/access/provenance.ts +2 -6
  201. package/src/console/ui/access/search.test.ts +1 -5
  202. package/src/console/ui/access/search.ts +2 -6
  203. package/src/console/ui/ai/AiA11yView.tsx +6 -17
  204. package/src/console/ui/ai/a11y.test.tsx +2 -5
  205. package/src/console/ui/ai/fixture.ts +2 -7
  206. package/src/console/ui/ai/format.ts +1 -3
  207. package/src/console/ui/ai/group.test.ts +1 -3
  208. package/src/console/ui/ai/group.ts +4 -12
  209. package/src/console/ui/ai/index.ts +2 -9
  210. package/src/console/ui/ai/promotion.test.ts +2 -7
  211. package/src/console/ui/ai/promotion.ts +4 -13
  212. package/src/console/ui/ai/search.test.ts +2 -11
  213. package/src/console/ui/ai/search.ts +3 -13
  214. package/src/console/ui/ai/types.ts +1 -8
  215. package/src/console/ui/architecture/ArchitectureA11yView.tsx +8 -29
  216. package/src/console/ui/architecture/a11y.test.tsx +1 -2
  217. package/src/console/ui/architecture/declared.ts +1 -5
  218. package/src/console/ui/architecture/index.ts +7 -35
  219. package/src/console/ui/architecture/layout.ts +1 -3
  220. package/src/console/ui/architecture/pathologies.ts +10 -19
  221. package/src/console/ui/architecture/search.ts +6 -15
  222. package/src/console/ui/architecture/traffic.ts +4 -14
  223. package/src/console/ui/architecture/types.ts +2 -10
  224. package/src/console/ui/architecture/view.test.ts +7 -19
  225. package/src/console/ui/architecture/view.ts +9 -36
  226. package/src/console/ui/channels/ChannelsA11yView.tsx +4 -13
  227. package/src/console/ui/channels/a11y.test.tsx +1 -2
  228. package/src/console/ui/channels/confirmation.test.ts +1 -4
  229. package/src/console/ui/channels/confirmation.ts +1 -4
  230. package/src/console/ui/channels/findings.ts +1 -5
  231. package/src/console/ui/channels/index.ts +2 -8
  232. package/src/console/ui/channels/locale.test.ts +1 -3
  233. package/src/console/ui/channels/locale.ts +2 -8
  234. package/src/console/ui/channels/search.ts +4 -13
  235. package/src/console/ui/channels/taxonomy.ts +1 -3
  236. package/src/console/ui/clock/ClockA11yView.tsx +9 -26
  237. package/src/console/ui/clock/a11y.test.tsx +2 -5
  238. package/src/console/ui/clock/confirmation.test.ts +1 -3
  239. package/src/console/ui/clock/confirmation.ts +1 -4
  240. package/src/console/ui/clock/findings.ts +1 -4
  241. package/src/console/ui/clock/health.ts +2 -7
  242. package/src/console/ui/clock/index.ts +2 -10
  243. package/src/console/ui/clock/search.test.ts +1 -3
  244. package/src/console/ui/clock/search.ts +2 -6
  245. package/src/console/ui/clock/timeline.test.ts +1 -3
  246. package/src/console/ui/clock/waiting-on.test.ts +1 -5
  247. package/src/console/ui/clock/waiting-on.ts +2 -7
  248. package/src/console/ui/diff/DiffA11yView.tsx +8 -17
  249. package/src/console/ui/diff/a11y.test.tsx +2 -5
  250. package/src/console/ui/diff/group.test.ts +3 -13
  251. package/src/console/ui/diff/group.ts +2 -8
  252. package/src/console/ui/diff/index.ts +2 -8
  253. package/src/console/ui/diff/search.test.ts +1 -5
  254. package/src/console/ui/diff/search.ts +4 -16
  255. package/src/console/ui/diff/summary.ts +1 -2
  256. package/src/console/ui/dist/assets/{index-Dy4jht9P.js → index-BWo8R7NR.js} +2 -2
  257. package/src/console/ui/dist/assets/{panel-access-Dd37LU2c.js → panel-access-C0J2D-a2.js} +1 -1
  258. package/src/console/ui/dist/assets/{panel-ai-CC7LR6-J.js → panel-ai-D_m6WQI8.js} +1 -1
  259. package/src/console/ui/dist/assets/{panel-architecture-B5b3iKCz.js → panel-architecture-CKnXFyUx.js} +1 -1
  260. package/src/console/ui/dist/assets/{panel-channels-CeNjTKXp.js → panel-channels-BOmQ-onL.js} +1 -1
  261. package/src/console/ui/dist/assets/{panel-clock-DgFTLoHV.js → panel-clock-giAq0Ccv.js} +1 -1
  262. package/src/console/ui/dist/assets/{panel-diff-DxehccqB.js → panel-diff-cdonmH8c.js} +1 -1
  263. package/src/console/ui/dist/assets/{panel-flows-BtrVn-Eg.js → panel-flows-DlCU5zjA.js} +2 -2
  264. package/src/console/ui/dist/assets/{panel-gates-Z9MKRGdH.js → panel-gates-XclZxWD5.js} +1 -1
  265. package/src/console/ui/dist/assets/{panel-overview-Dt_AeXgd.js → panel-overview-BznEOTnb.js} +1 -1
  266. package/src/console/ui/dist/assets/{panel-plugins-DWd0TowH.js → panel-plugins-CcGM1g64.js} +1 -1
  267. package/src/console/ui/dist/assets/{panel-runs-DGstFHeq.js → panel-runs-CGWNHLR4.js} +1 -1
  268. package/src/console/ui/dist/assets/{panel-signals-DzEa2Fnt.js → panel-signals-CNywkdak.js} +1 -1
  269. package/src/console/ui/dist/assets/{panel-store-BJkbNgxx.js → panel-store-KmTbFHMH.js} +1 -1
  270. package/src/console/ui/dist/assets/{panel-traces-BaRVO3gM.js → panel-traces-DBLx2ilD.js} +1 -1
  271. package/src/console/ui/dist/assets/panel-vault-CEnFc0dk.js +1 -0
  272. package/src/console/ui/dist/index.html +1 -1
  273. package/src/console/ui/flows/FlowsA11yView.tsx +7 -22
  274. package/src/console/ui/flows/a11y.test.tsx +2 -8
  275. package/src/console/ui/flows/buffer.test.ts +3 -11
  276. package/src/console/ui/flows/buffer.ts +4 -11
  277. package/src/console/ui/flows/confirmation.ts +1 -3
  278. package/src/console/ui/flows/contract.test.ts +3 -7
  279. package/src/console/ui/flows/contract.ts +12 -36
  280. package/src/console/ui/flows/graph.test.ts +3 -11
  281. package/src/console/ui/flows/graph.ts +5 -15
  282. package/src/console/ui/flows/index.ts +1 -6
  283. package/src/console/ui/flows/save-as-test.ts +1 -3
  284. package/src/console/ui/flows/search.ts +8 -25
  285. package/src/console/ui/flows/tiers.ts +2 -9
  286. package/src/console/ui/gates/GatesA11yView.tsx +4 -13
  287. package/src/console/ui/gates/a11y.test.tsx +2 -5
  288. package/src/console/ui/gates/audit.ts +1 -3
  289. package/src/console/ui/gates/denial.test.ts +1 -3
  290. package/src/console/ui/gates/denial.ts +4 -12
  291. package/src/console/ui/gates/findings.ts +1 -3
  292. package/src/console/ui/gates/group.test.ts +3 -3
  293. package/src/console/ui/gates/group.ts +3 -11
  294. package/src/console/ui/gates/index.ts +2 -10
  295. package/src/console/ui/gates/search.ts +3 -10
  296. package/src/console/ui/overview/OverviewA11yView.tsx +9 -27
  297. package/src/console/ui/overview/a11y.test.tsx +1 -2
  298. package/src/console/ui/overview/busiest.ts +1 -3
  299. package/src/console/ui/overview/compose.ts +1 -13
  300. package/src/console/ui/overview/cost.ts +34 -38
  301. package/src/console/ui/overview/fixture.ts +21 -26
  302. package/src/console/ui/overview/golden.ts +4 -14
  303. package/src/console/ui/overview/index.ts +2 -9
  304. package/src/console/ui/overview/rank.test.ts +3 -10
  305. package/src/console/ui/overview/rank.ts +2 -7
  306. package/src/console/ui/overview/slo.test.ts +5 -9
  307. package/src/console/ui/overview/slo.ts +6 -23
  308. package/src/console/ui/overview/verdict.ts +3 -10
  309. package/src/console/ui/plugins/PluginsA11yView.tsx +8 -18
  310. package/src/console/ui/plugins/a11y.test.tsx +1 -2
  311. package/src/console/ui/plugins/fixture.ts +2 -4
  312. package/src/console/ui/plugins/group.test.ts +1 -3
  313. package/src/console/ui/plugins/group.ts +1 -6
  314. package/src/console/ui/plugins/index.ts +3 -13
  315. package/src/console/ui/plugins/search.ts +7 -19
  316. package/src/console/ui/runs/RunsA11yView.tsx +5 -20
  317. package/src/console/ui/runs/a11y.test.tsx +2 -5
  318. package/src/console/ui/runs/explain.ts +2 -6
  319. package/src/console/ui/runs/group.ts +3 -12
  320. package/src/console/ui/runs/histogram.test.ts +2 -11
  321. package/src/console/ui/runs/histogram.ts +1 -4
  322. package/src/console/ui/runs/index.ts +4 -18
  323. package/src/console/ui/runs/project.ts +2 -6
  324. package/src/console/ui/runs/query.test.ts +1 -3
  325. package/src/console/ui/runs/query.ts +12 -35
  326. package/src/console/ui/runs/search.ts +5 -19
  327. package/src/console/ui/runs/trace-link.test.ts +2 -6
  328. package/src/console/ui/runs/trace-link.ts +4 -16
  329. package/src/console/ui/runs/types.ts +1 -3
  330. package/src/console/ui/shell/App.tsx +2 -10
  331. package/src/console/ui/shell/client.ts +22 -115
  332. package/src/console/ui/shell/components/ui.tsx +1 -4
  333. package/src/console/ui/shell/layout/Shell.tsx +2 -4
  334. package/src/console/ui/shell/main.tsx +31 -96
  335. package/src/console/ui/shell/panels/access/AccessPanel.tsx +34 -98
  336. package/src/console/ui/shell/panels/ai/AiPanel.tsx +35 -106
  337. package/src/console/ui/shell/panels/architecture/ArchitecturePanel.tsx +18 -66
  338. package/src/console/ui/shell/panels/channels/ChannelsPanel.tsx +20 -57
  339. package/src/console/ui/shell/panels/clock/ClockPanel.tsx +22 -54
  340. package/src/console/ui/shell/panels/diff/DiffPanel.tsx +20 -61
  341. package/src/console/ui/shell/panels/flows/ContractEditor.tsx +6 -23
  342. package/src/console/ui/shell/panels/flows/FlowDrawer.tsx +13 -28
  343. package/src/console/ui/shell/panels/flows/FlowsPanel.tsx +9 -29
  344. package/src/console/ui/shell/panels/gates/GatesPanel.tsx +24 -80
  345. package/src/console/ui/shell/panels/overview/OverviewPanel.tsx +20 -58
  346. package/src/console/ui/shell/panels/plugins/PluginsPanel.tsx +16 -41
  347. package/src/console/ui/shell/panels/runs/RunsPanel.tsx +31 -99
  348. package/src/console/ui/shell/panels/signals/SignalsPanel.tsx +38 -101
  349. package/src/console/ui/shell/panels/store/StorePanel.tsx +27 -66
  350. package/src/console/ui/shell/panels/traces/TracesPanel.tsx +28 -89
  351. package/src/console/ui/shell/panels/vault/VaultPanel.tsx +22 -53
  352. package/src/console/ui/shell/setup/Wizard.tsx +3 -5
  353. package/src/console/ui/shell/styles.css +1 -2
  354. package/src/console/ui/signals/SignalsA11yView.tsx +9 -33
  355. package/src/console/ui/signals/a11y.test.tsx +2 -5
  356. package/src/console/ui/signals/confirmation.test.ts +1 -5
  357. package/src/console/ui/signals/confirmation.ts +2 -6
  358. package/src/console/ui/signals/dry-run.ts +1 -3
  359. package/src/console/ui/signals/durable.ts +1 -3
  360. package/src/console/ui/signals/findings.ts +1 -3
  361. package/src/console/ui/signals/group.test.ts +2 -8
  362. package/src/console/ui/signals/group.ts +2 -10
  363. package/src/console/ui/signals/index.ts +1 -4
  364. package/src/console/ui/signals/monitor.ts +2 -7
  365. package/src/console/ui/signals/schema-form.test.ts +3 -14
  366. package/src/console/ui/signals/schema-form.ts +1 -4
  367. package/src/console/ui/signals/search.ts +4 -13
  368. package/src/console/ui/store/StoreA11yView.tsx +3 -9
  369. package/src/console/ui/store/a11y.test.tsx +2 -5
  370. package/src/console/ui/store/confirmation.test.ts +1 -3
  371. package/src/console/ui/store/confirmation.ts +1 -4
  372. package/src/console/ui/store/dry-run.ts +2 -5
  373. package/src/console/ui/store/fixture.ts +1 -2
  374. package/src/console/ui/store/group.test.ts +1 -6
  375. package/src/console/ui/store/group.ts +1 -4
  376. package/src/console/ui/store/index.ts +1 -5
  377. package/src/console/ui/store/search.ts +2 -6
  378. package/src/console/ui/store/will-not-fire.ts +1 -2
  379. package/src/console/ui/traces/TracesA11yView.tsx +10 -29
  380. package/src/console/ui/traces/a11y.test.tsx +1 -2
  381. package/src/console/ui/traces/chain.test.ts +5 -19
  382. package/src/console/ui/traces/chain.ts +1 -3
  383. package/src/console/ui/traces/critical-path.test.ts +1 -3
  384. package/src/console/ui/traces/critical-path.ts +2 -6
  385. package/src/console/ui/traces/filter.test.ts +2 -6
  386. package/src/console/ui/traces/filter.ts +5 -13
  387. package/src/console/ui/traces/fold.test.ts +4 -12
  388. package/src/console/ui/traces/fold.ts +1 -3
  389. package/src/console/ui/traces/mini.ts +1 -3
  390. package/src/console/ui/traces/replay.test.ts +1 -3
  391. package/src/console/ui/traces/replay.ts +1 -3
  392. package/src/console/ui/traces/sampling.ts +1 -4
  393. package/src/console/ui/traces/search.ts +4 -17
  394. package/src/console/ui/traces/tier.ts +1 -3
  395. package/src/console/ui/vault/VaultA11yView.tsx +5 -17
  396. package/src/console/ui/vault/a11y.test.tsx +1 -2
  397. package/src/console/ui/vault/blast-radius.ts +1 -3
  398. package/src/console/ui/vault/confirmation.test.ts +1 -5
  399. package/src/console/ui/vault/confirmation.ts +1 -4
  400. package/src/console/ui/vault/dormant.test.ts +1 -4
  401. package/src/console/ui/vault/export-safe.test.ts +1 -5
  402. package/src/console/ui/vault/export-safe.ts +1 -4
  403. package/src/console/ui/vault/fixture.ts +3 -3
  404. package/src/console/ui/vault/group.ts +1 -2
  405. package/src/console/ui/vault/index.ts +2 -10
  406. package/src/console/ui/vault/search.ts +2 -6
  407. package/src/console/ui/vault/types.ts +1 -1
  408. package/src/console/xss.gate.test.ts +1 -3
  409. package/src/docker/compose.ts +215 -27
  410. package/src/docker/derive.ts +6 -14
  411. package/src/docker/docker.test.ts +118 -15
  412. package/src/docker/dockerfile.integration.test.ts +12 -21
  413. package/src/docker/helpers.ts +5 -4
  414. package/src/docker/index.ts +9 -6
  415. package/src/docker/pin.ts +1 -9
  416. package/src/docker/recipes/index.ts +6 -6
  417. package/src/docker/recipes/mailpit.ts +22 -0
  418. package/src/docker/recipes/openbao.ts +47 -0
  419. package/src/docker/recipes/postgres.ts +17 -6
  420. package/src/docker/recipes/redis.ts +11 -2
  421. package/src/docker/recipes/rustfs.ts +32 -0
  422. package/src/docker/stack-id.test.ts +73 -5
  423. package/src/docker/stack-id.ts +124 -33
  424. package/src/docker/stack.integration.test.ts +6 -21
  425. package/src/docker/stack.ts +36 -4
  426. package/src/docker/types.ts +16 -4
  427. package/src/docs-origin.ts +4 -4
  428. package/src/drivers/ai-anthropic.ts +5 -14
  429. package/src/drivers/ai-mock.ts +2 -5
  430. package/src/drivers/ai-openai-compatible.ts +4 -10
  431. package/src/drivers/ai-providers.test.ts +6 -13
  432. package/src/drivers/bun-native-completeness.test.ts +6 -15
  433. package/src/drivers/channel-console.ts +6 -7
  434. package/src/drivers/channel-fcm.ts +20 -30
  435. package/src/drivers/channel-resend.ts +1 -3
  436. package/src/drivers/channel-smtp.ts +2 -6
  437. package/src/drivers/channel-types.ts +2 -12
  438. package/src/drivers/channel-unifonic.ts +2 -6
  439. package/src/drivers/channel-wa-cloud.ts +2 -6
  440. package/src/drivers/channel-webpush.ts +21 -60
  441. package/src/drivers/conformance.test.ts +2 -10
  442. package/src/drivers/conformance.ts +8 -21
  443. package/src/drivers/drizzle-dialect.test.ts +20 -0
  444. package/src/drivers/drizzle-dialect.ts +37 -0
  445. package/src/drivers/fs.ts +2 -8
  446. package/src/drivers/index.ts +12 -57
  447. package/src/drivers/memory.ts +287 -75
  448. package/src/drivers/pgvector.ts +7 -11
  449. package/src/drivers/postgres.ts +7 -13
  450. package/src/drivers/redis.ts +13 -37
  451. package/src/drivers/s3.ts +15 -18
  452. package/src/drivers/signal-engine.ts +12 -49
  453. package/src/drivers/signal-memory.ts +2 -8
  454. package/src/drivers/signal-nats.ts +4 -9
  455. package/src/drivers/signal-postgres.ts +62 -129
  456. package/src/drivers/signal-redis.ts +7 -21
  457. package/src/drivers/signal-types.ts +1 -4
  458. package/src/drivers/sqlite.ts +3 -12
  459. package/src/drivers/types.ts +4 -23
  460. package/src/drivers/vault-driver-removal.test.ts +55 -0
  461. package/src/drivers/vault-env.ts +2 -6
  462. package/src/drivers/vault-infisical.ts +1 -5
  463. package/src/drivers/vault-managed.ts +1 -5
  464. package/src/drivers/vault-memory.ts +1 -5
  465. package/src/drivers/vault-openbao.test.ts +97 -0
  466. package/src/drivers/vault-openbao.ts +103 -40
  467. package/src/drivers/vault-types.ts +3 -16
  468. package/src/elements/ai/declare.ts +4 -14
  469. package/src/elements/ai/eval.ts +2 -6
  470. package/src/elements/ai/pii.ts +1 -3
  471. package/src/elements/ai/runtime.ts +12 -50
  472. package/src/elements/ai/schema.ts +4 -15
  473. package/src/elements/ai.test.ts +13 -24
  474. package/src/elements/ai.ts +1 -5
  475. package/src/elements/channel/consent.ts +3 -12
  476. package/src/elements/channel/costs.ts +4 -15
  477. package/src/elements/channel/declare.ts +1 -4
  478. package/src/elements/channel/email-auth.ts +1 -4
  479. package/src/elements/channel/locale.ts +2 -10
  480. package/src/elements/channel/mask.ts +1 -3
  481. package/src/elements/channel/mime.ts +2 -12
  482. package/src/elements/channel/outcomes.test.ts +1 -5
  483. package/src/elements/channel/outcomes.ts +5 -15
  484. package/src/elements/channel/receipts.ts +2 -7
  485. package/src/elements/channel/runtime.ts +28 -74
  486. package/src/elements/channel/suppression.ts +8 -14
  487. package/src/elements/channel.test.ts +8 -31
  488. package/src/elements/channel.ts +3 -14
  489. package/src/elements/clock/actions.ts +6 -18
  490. package/src/elements/clock/declare.ts +1 -3
  491. package/src/elements/clock/dst.ts +1 -5
  492. package/src/elements/clock/durable.ts +4 -16
  493. package/src/elements/clock/health.ts +2 -7
  494. package/src/elements/clock/leader.ts +2 -9
  495. package/src/elements/clock/reconcile.ts +4 -15
  496. package/src/elements/clock/runtime.ts +2 -5
  497. package/src/elements/clock/schedule.ts +4 -20
  498. package/src/elements/clock.test.ts +2 -7
  499. package/src/elements/clock.ts +5 -23
  500. package/src/elements/gate/permissions.ts +1 -4
  501. package/src/elements/gate/runtime.ts +7 -28
  502. package/src/elements/gate.ts +1 -5
  503. package/src/elements/index.ts +9 -7
  504. package/src/elements/signal/declare.ts +2 -7
  505. package/src/elements/signal/reconcile.test.ts +1 -4
  506. package/src/elements/signal/runtime.ts +1 -3
  507. package/src/elements/signal.test.ts +3 -15
  508. package/src/elements/signal.ts +2 -8
  509. package/src/elements/store/cache.test.ts +46 -0
  510. package/src/elements/store/cache.ts +3 -11
  511. package/src/elements/store/classify.ts +5 -22
  512. package/src/elements/store/declare.ts +11 -17
  513. package/src/elements/store/domain-ddl.test.ts +86 -0
  514. package/src/elements/store/emit-drizzle.ts +363 -0
  515. package/src/elements/store/files-policy.test.ts +1 -5
  516. package/src/elements/store/files-policy.ts +4 -12
  517. package/src/elements/store/load-plugin-tables.ts +103 -0
  518. package/src/elements/store/missing-relation.test.ts +83 -0
  519. package/src/elements/store/missing-relation.ts +38 -0
  520. package/src/elements/store/replica.ts +1 -4
  521. package/src/elements/store/resource-list-docs.fixture.ts +56 -0
  522. package/src/elements/store/resource-list-docs.test.ts +79 -0
  523. package/src/elements/store/resource.test.ts +253 -0
  524. package/src/elements/store/resource.ts +786 -0
  525. package/src/elements/store/runtime.ts +25 -28
  526. package/src/elements/store/schema-decl.test.ts +227 -0
  527. package/src/elements/store/schema-decl.ts +516 -0
  528. package/src/elements/store/sql-condition.test.ts +132 -0
  529. package/src/elements/store/sql-condition.ts +293 -65
  530. package/src/elements/store/sql-session.test.ts +135 -0
  531. package/src/elements/store/sql-session.ts +241 -84
  532. package/src/elements/store/table.ts +69 -23
  533. package/src/elements/store.test.ts +17 -39
  534. package/src/elements/store.ts +53 -31
  535. package/src/elements/vault/chain.ts +34 -0
  536. package/src/elements/vault/declare.ts +22 -32
  537. package/src/elements/vault/fingerprint.ts +2 -7
  538. package/src/elements/vault/redact.ts +2 -6
  539. package/src/elements/vault/runtime.ts +19 -33
  540. package/src/elements/vault.test.ts +12 -55
  541. package/src/elements/vault.ts +9 -13
  542. package/src/index.ts +5 -2
  543. package/src/kernel/adopt-routes.ts +15 -29
  544. package/src/kernel/app.ts +92 -118
  545. package/src/kernel/auth-resolve.ts +2 -9
  546. package/src/kernel/boot-bind/ai.ts +1 -4
  547. package/src/kernel/boot-bind/channel.test.ts +60 -0
  548. package/src/kernel/boot-bind/channel.ts +61 -5
  549. package/src/kernel/boot-bind/clock.ts +2 -6
  550. package/src/kernel/boot-bind/gate.ts +2 -8
  551. package/src/kernel/boot-bind/runs.ts +1 -3
  552. package/src/kernel/boot-bind/signal.ts +3 -10
  553. package/src/kernel/boot-bind/store.test.ts +27 -18
  554. package/src/kernel/boot-bind/store.ts +93 -52
  555. package/src/kernel/boot-bind/vault.ts +2 -8
  556. package/src/kernel/boot.test.ts +4 -10
  557. package/src/kernel/boot.ts +30 -77
  558. package/src/kernel/budget.test.ts +1 -3
  559. package/src/kernel/capability.ts +3 -10
  560. package/src/kernel/dry-run.test.ts +1 -4
  561. package/src/kernel/dry-run.ts +3 -11
  562. package/src/kernel/edge.test.ts +68 -0
  563. package/src/kernel/effects.test.ts +1 -5
  564. package/src/kernel/effects.ts +4 -11
  565. package/src/kernel/errors.registry.test.ts +2 -8
  566. package/src/kernel/errors.ts +23 -32
  567. package/src/kernel/flow.test.ts +12 -25
  568. package/src/kernel/flow.ts +13 -25
  569. package/src/kernel/fx.test.ts +31 -40
  570. package/src/kernel/fx.ts +135 -90
  571. package/src/kernel/hook-timing.test.ts +3 -6
  572. package/src/kernel/hook-timing.ts +5 -14
  573. package/src/kernel/hooks.test.ts +43 -10
  574. package/src/kernel/hooks.ts +25 -12
  575. package/src/kernel/index.ts +11 -17
  576. package/src/kernel/journal.ts +7 -31
  577. package/src/kernel/on.ts +45 -9
  578. package/src/kernel/pipeline.test.ts +10 -19
  579. package/src/kernel/pipeline.ts +5 -17
  580. package/src/kernel/plug.ts +4 -11
  581. package/src/kernel/plugin/conflicts.test.ts +13 -25
  582. package/src/kernel/plugin/decorate.test.ts +8 -13
  583. package/src/kernel/plugin/scoping.test.ts +4 -11
  584. package/src/kernel/plugin.ts +81 -27
  585. package/src/kernel/registry-isolation.test.ts +74 -0
  586. package/src/kernel/registry.ts +102 -30
  587. package/src/kernel/router.test.ts +15 -13
  588. package/src/kernel/router.ts +9 -29
  589. package/src/kernel/routing-budget.test.ts +1 -3
  590. package/src/kernel/run-telemetry.ts +1 -3
  591. package/src/kernel/triggers.ts +63 -21
  592. package/src/manifest/diff.test.ts +26 -91
  593. package/src/manifest/diff.ts +95 -225
  594. package/src/manifest/fixtures/skyport.excerpt.json +1 -1
  595. package/src/manifest/fixtures/skyport.manifest.json +1 -1
  596. package/src/manifest/index.ts +3 -10
  597. package/src/manifest/types.ts +30 -6
  598. package/src/manifest/undeclared.test.ts +4 -12
  599. package/src/manifest/undeclared.ts +1 -2
  600. package/src/manifest/validate.test.ts +2 -6
  601. package/src/manifest/validate.ts +5 -15
  602. package/src/mcp/authorization.ts +8 -27
  603. package/src/mcp/confirmation.ts +3 -10
  604. package/src/mcp/data.ts +2 -6
  605. package/src/mcp/docs-index.ts +4 -7
  606. package/src/mcp/docs-mcp.test.ts +3 -12
  607. package/src/mcp/docs-server.ts +7 -27
  608. package/src/mcp/docs-tools.ts +2 -6
  609. package/src/mcp/index.ts +1 -6
  610. package/src/mcp/injection.gate.test.ts +4 -18
  611. package/src/mcp/mcp.test.ts +18 -49
  612. package/src/mcp/protocol.ts +3 -10
  613. package/src/mcp/server.ts +11 -52
  614. package/src/mcp/session.ts +4 -14
  615. package/src/mcp/tools.ts +14 -50
  616. package/src/plugins/catalogue.test.ts +3 -7
  617. package/src/plugins/catalogue.ts +1 -3
  618. package/src/plugins/compression.test.ts +127 -0
  619. package/src/plugins/compression.ts +94 -0
  620. package/src/plugins/config-source.test.ts +204 -0
  621. package/src/plugins/config-source.ts +209 -0
  622. package/src/plugins/cors.test.ts +138 -0
  623. package/src/plugins/cors.ts +129 -0
  624. package/src/plugins/csrf.test.ts +102 -0
  625. package/src/plugins/csrf.ts +86 -0
  626. package/src/plugins/headers.ts +54 -0
  627. package/src/plugins/index.ts +26 -0
  628. package/src/plugins/ip-allowlist.test.ts +105 -0
  629. package/src/plugins/ip-allowlist.ts +76 -0
  630. package/src/plugins/maintenance-mode.test.ts +91 -0
  631. package/src/plugins/maintenance-mode.ts +85 -0
  632. package/src/plugins/node-import-scan.ts +2 -5
  633. package/src/plugins/security-headers.test.ts +243 -0
  634. package/src/plugins/security-headers.ts +255 -0
  635. package/src/plugins/supply-chain.ts +5 -17
  636. package/src/release/exports.ts +3 -8
  637. package/src/release/measure.exports.test.ts +1 -3
  638. package/src/release/measure.ts +16 -45
  639. package/src/runs/bench.test.ts +1 -3
  640. package/src/runs/collect.ts +8 -25
  641. package/src/runs/drivers/clickhouse.ts +2 -9
  642. package/src/runs/drivers/files.ts +9 -31
  643. package/src/runs/drivers/memory.ts +5 -22
  644. package/src/runs/drivers/postgres.ts +8 -20
  645. package/src/runs/duckdb.ts +2 -8
  646. package/src/runs/index.ts +3 -14
  647. package/src/runs/outlier.ts +3 -10
  648. package/src/runs/parquet.ts +8 -26
  649. package/src/runs/privacy.ts +2 -8
  650. package/src/runs/runs.test.ts +3 -9
  651. package/src/runs/runtime.ts +7 -32
  652. package/src/runs/shred.ts +10 -29
  653. package/src/runs/types.ts +1 -4
  654. package/src/runtime/bun.ts +4 -15
  655. package/src/runtime/cold-start.bench.ts +1 -3
  656. package/src/runtime/dev-request-log.test.ts +1 -4
  657. package/src/runtime/dev-request-log.ts +1 -4
  658. package/src/runtime/index.ts +1 -6
  659. package/src/runtime/primitives.ts +5 -4
  660. package/src/runtime/security.ts +3 -13
  661. package/src/runtime/serve.test.ts +4 -7
  662. package/src/runtime/types.ts +1 -4
  663. package/src/runtime/web-standard.ts +3 -15
  664. package/src/term.test.ts +4 -6
  665. package/src/term.ts +49 -98
  666. package/src/test/create-test-app.test.ts +4 -14
  667. package/src/test/create-test-app.ts +27 -33
  668. package/src/test/provisions.integration.test.ts +3 -11
  669. package/src/upgrade/codemods.test.ts +25 -6
  670. package/src/upgrade/codemods.ts +116 -3
  671. package/src/validation/standard-schema.test.ts +2 -5
  672. package/src/validation/standard-schema.ts +13 -33
  673. package/docs/spec/console.md +0 -739
  674. package/docs/spec/example.md +0 -1196
  675. package/docs/spec/four-applications.md +0 -1195
  676. package/docs/spec/unified-theory.md +0 -489
  677. package/src/cli/doc-drift.test.ts +0 -146
  678. package/src/cli/doc-drift.ts +0 -430
  679. package/src/cli/doctor-diff-examples.ts +0 -92
  680. package/src/console/ui/dist/assets/panel-vault-BbfWdox0.js +0 -1
  681. package/src/drivers/vault-sops.ts +0 -271
@@ -63,51 +63,32 @@ export function RunsPanel() {
63
63
 
64
64
  const allRuns = runsQuery.data ?? [];
65
65
  const query = dimensionQueryOf(search);
66
- const filtered = useMemo(
67
- () => filterRuns(allRuns, query),
68
- [allRuns, query],
69
- );
66
+ const filtered = useMemo(() => filterRuns(allRuns, query), [allRuns, query]);
70
67
  const range = durationRangeOf(search);
71
- const buckets = useMemo(
72
- () => durationHistogram(filtered),
73
- [filtered],
74
- );
68
+ const buckets = useMemo(() => durationHistogram(filtered), [filtered]);
75
69
  const maxBucket = Math.max(1, ...buckets.map((b) => b.count));
76
70
  const groups = useMemo(
77
- () =>
78
- search.group ? groupByDimension(filtered, search.group) : [],
71
+ () => (search.group ? groupByDimension(filtered, search.group) : []),
79
72
  [filtered, search.group],
80
73
  );
81
74
  const findings = useMemo(
82
75
  () => (range ? explainDurationOutliers(filtered, range) : []),
83
76
  [filtered, range],
84
77
  );
85
- const dimensions = useMemo(
86
- () => discoverDimensions(allRuns),
87
- [allRuns],
88
- );
78
+ const dimensions = useMemo(() => discoverDimensions(allRuns), [allRuns]);
89
79
  const open = allRuns.find((r) => r.id === search.run);
90
80
 
91
81
  return (
92
82
  <div className="flex h-full min-h-0 flex-col">
93
83
  <header className="flex shrink-0 flex-wrap items-end gap-4 border-b border-[var(--oke-line)] px-6 py-4">
94
84
  <div className="flex flex-col gap-1">
95
- <p className="text-xs uppercase tracking-[0.2em] text-[var(--oke-muted)]">
96
- Runs
97
- </p>
98
- <h1 className="text-xl font-semibold tracking-tight">
99
- Population analysis
100
- </h1>
85
+ <p className="text-xs uppercase tracking-[0.2em] text-[var(--oke-muted)]">Runs</p>
86
+ <h1 className="text-xl font-semibold tracking-tight">Population analysis</h1>
101
87
  <p className="text-xs text-[var(--oke-muted)]">
102
- {filtered.length} of {allRuns.length} runs · wide events, not log
103
- lines
88
+ {filtered.length} of {allRuns.length} runs · wide events, not log lines
104
89
  </p>
105
90
  </div>
106
- <QueryBuilder
107
- search={search}
108
- dimensions={dimensions}
109
- onChange={setSearch}
110
- />
91
+ <QueryBuilder search={search} dimensions={dimensions} onChange={setSearch} />
111
92
  <label className="flex flex-col gap-1 text-sm">
112
93
  <span className="text-[var(--oke-muted)]">Group by</span>
113
94
  <select
@@ -132,18 +113,14 @@ export function RunsPanel() {
132
113
  <div className="grid min-h-0 flex-1 grid-cols-1 lg:grid-cols-[minmax(0,1.2fr)_minmax(0,1fr)]">
133
114
  <div className="min-h-0 overflow-auto border-r border-[var(--oke-line)] px-6 py-6">
134
115
  <section aria-label="Duration distribution" className="mb-8">
135
- <h2 className="mb-2 text-sm font-medium">
136
- Duration distribution
137
- </h2>
116
+ <h2 className="mb-2 text-sm font-medium">Duration distribution</h2>
138
117
  <p className="mb-3 text-xs text-[var(--oke-muted)]">
139
118
  Range-select a region to explain outliers against the rest.
140
119
  </p>
141
120
  {runsQuery.isLoading ? (
142
121
  <p className="text-sm text-[var(--oke-muted)]">Loading runs…</p>
143
122
  ) : buckets.length === 0 ? (
144
- <p className="text-sm text-[var(--oke-muted)]">
145
- No runs match the current query.
146
- </p>
123
+ <p className="text-sm text-[var(--oke-muted)]">No runs match the current query.</p>
147
124
  ) : (
148
125
  <DurationChart
149
126
  buckets={buckets}
@@ -155,8 +132,7 @@ export function RunsPanel() {
155
132
  {range ? (
156
133
  <div className="mt-3 flex flex-wrap items-center gap-2">
157
134
  <p className="text-xs text-[var(--oke-muted)]">
158
- Selected {formatDurationMs(range.minMs)} –{" "}
159
- {formatDurationMs(range.maxMs)}
135
+ Selected {formatDurationMs(range.minMs)} – {formatDurationMs(range.maxMs)}
160
136
  </p>
161
137
  <Button
162
138
  type="button"
@@ -171,9 +147,7 @@ export function RunsPanel() {
171
147
 
172
148
  {range ? (
173
149
  <section aria-label="Outlier explanation" className="mb-8">
174
- <h2 className="mb-2 text-sm font-medium">
175
- Outlier explanation
176
- </h2>
150
+ <h2 className="mb-2 text-sm font-medium">Outlier explanation</h2>
177
151
  {findings.length === 0 ? (
178
152
  <p className="text-sm text-[var(--oke-muted)]">
179
153
  No dimension separates this region strongly enough.
@@ -181,9 +155,7 @@ export function RunsPanel() {
181
155
  ) : (
182
156
  <ol className="flex list-decimal flex-col gap-1 pl-5 text-sm">
183
157
  {findings.map((f) => (
184
- <li key={`${f.dimension}:${f.value}`}>
185
- {f.explanation}
186
- </li>
158
+ <li key={`${f.dimension}:${f.value}`}>{f.explanation}</li>
187
159
  ))}
188
160
  </ol>
189
161
  )}
@@ -192,9 +164,7 @@ export function RunsPanel() {
192
164
 
193
165
  {search.group ? (
194
166
  <section aria-label="Group aggregates" className="mb-8">
195
- <h2 className="mb-2 text-sm font-medium">
196
- Group by {search.group}
197
- </h2>
167
+ <h2 className="mb-2 text-sm font-medium">Group by {search.group}</h2>
198
168
  <table className="w-full border-collapse text-left text-sm">
199
169
  <thead>
200
170
  <tr className="border-b border-[var(--oke-line)] text-[var(--oke-muted)]">
@@ -223,18 +193,10 @@ export function RunsPanel() {
223
193
  <tr key={g.key}>
224
194
  <td className="py-2 pr-3 font-mono text-xs">{g.key}</td>
225
195
  <td className="py-2 pr-3">{g.count}</td>
226
- <td className="py-2 pr-3">
227
- {formatDurationMs(g.avgDurationMs)}
228
- </td>
229
- <td className="py-2 pr-3">
230
- {formatDurationMs(g.p50DurationMs)}
231
- </td>
232
- <td className="py-2 pr-3">
233
- {formatDurationMs(g.p99DurationMs)}
234
- </td>
235
- <td className="py-2">
236
- {g.sumCost > 0 ? `$${g.sumCost.toFixed(3)}` : "—"}
237
- </td>
196
+ <td className="py-2 pr-3">{formatDurationMs(g.avgDurationMs)}</td>
197
+ <td className="py-2 pr-3">{formatDurationMs(g.p50DurationMs)}</td>
198
+ <td className="py-2 pr-3">{formatDurationMs(g.p99DurationMs)}</td>
199
+ <td className="py-2">{g.sumCost > 0 ? `$${g.sumCost.toFixed(3)}` : "—"}</td>
238
200
  </tr>
239
201
  ))}
240
202
  </tbody>
@@ -269,10 +231,7 @@ export function RunsPanel() {
269
231
  <span className="flex items-center gap-3 font-mono text-xs text-[var(--oke-muted)]">
270
232
  <span>{run.cache}</span>
271
233
  {run.error ? (
272
- <span
273
- role="status"
274
- className="text-[var(--oke-danger)]"
275
- >
234
+ <span role="status" className="text-[var(--oke-danger)]">
276
235
  {run.error}
277
236
  </span>
278
237
  ) : (
@@ -298,11 +257,7 @@ export function RunsPanel() {
298
257
  Select a run to see its flat dimension record.
299
258
  </p>
300
259
  ) : (
301
- <RunDetail
302
- run={open}
303
- allRuns={allRuns}
304
- onClose={() => setSearch(closeRun(search))}
305
- />
260
+ <RunDetail run={open} allRuns={allRuns} onClose={() => setSearch(closeRun(search))} />
306
261
  )}
307
262
  </section>
308
263
  </div>
@@ -320,9 +275,7 @@ function QueryBuilder({
320
275
  readonly onChange: (next: RunsSearch) => void;
321
276
  }) {
322
277
  const query = dimensionQueryOf(search);
323
- const dimOptions = [
324
- ...new Set([...BUILDER_DIMENSIONS, ...dimensions]),
325
- ].sort();
278
+ const dimOptions = [...new Set([...BUILDER_DIMENSIONS, ...dimensions])].sort();
326
279
  const [dim, setDim] = useState<string>("cache");
327
280
  const [op, setOp] = useState<QueryOp>("=");
328
281
  const [value, setValue] = useState("miss");
@@ -378,9 +331,7 @@ function QueryBuilder({
378
331
  type="button"
379
332
  variant="ghost"
380
333
  onClick={() => {
381
- const parsed = parseDimensionQuery(
382
- `${dim} ${op} ${value}`,
383
- );
334
+ const parsed = parseDimensionQuery(`${dim} ${op} ${value}`);
384
335
  const clause = parsed.clauses[0];
385
336
  if (!clause) return;
386
337
  const next = setWhere(search, upsertClause(query, clause));
@@ -393,20 +344,14 @@ function QueryBuilder({
393
344
  </div>
394
345
 
395
346
  {query.clauses.length > 0 ? (
396
- <ul
397
- aria-label="Active query clauses"
398
- className="flex flex-wrap gap-2"
399
- >
347
+ <ul aria-label="Active query clauses" className="flex flex-wrap gap-2">
400
348
  {query.clauses.map((c) => (
401
349
  <li key={c.dimension}>
402
350
  <button
403
351
  type="button"
404
352
  className="min-h-8 border border-[var(--oke-line)] px-2 font-mono text-xs"
405
353
  onClick={() => {
406
- const next = setWhere(
407
- search,
408
- removeClause(query, c.dimension),
409
- );
354
+ const next = setWhere(search, removeClause(query, c.dimension));
410
355
  setExprDraft(next.where ?? "");
411
356
  onChange(next);
412
357
  }}
@@ -419,9 +364,7 @@ function QueryBuilder({
419
364
  ) : null}
420
365
 
421
366
  <label className="flex flex-col gap-1 text-sm">
422
- <span className="text-[var(--oke-muted)]">
423
- Dimension query expression
424
- </span>
367
+ <span className="text-[var(--oke-muted)]">Dimension query expression</span>
425
368
  <input
426
369
  aria-label="Dimension query expression"
427
370
  className="min-h-8 border border-[var(--oke-line)] bg-transparent px-2 font-mono text-sm"
@@ -465,10 +408,7 @@ function DurationChart({
465
408
  onMouseLeave={() => setAnchor(null)}
466
409
  >
467
410
  {buckets.map((b, i) => {
468
- const selected =
469
- range !== null &&
470
- b.minMs <= range.maxMs &&
471
- b.maxMs >= range.minMs;
411
+ const selected = range !== null && b.minMs <= range.maxMs && b.maxMs >= range.minMs;
472
412
  const height = Math.max(4, (b.count / maxBucket) * 100);
473
413
  return (
474
414
  <button
@@ -533,9 +473,7 @@ function RunDetail({
533
473
  label: "replica",
534
474
  value:
535
475
  run.replica != null
536
- ? `${run.replica}${
537
- run.replicaLagMs != null ? ` · lag ${run.replicaLagMs}ms` : ""
538
- }`
476
+ ? `${run.replica}${run.replicaLagMs != null ? ` · lag ${run.replicaLagMs}ms` : ""}`
539
477
  : "—",
540
478
  },
541
479
  {
@@ -587,9 +525,7 @@ function RunDetail({
587
525
  <dd
588
526
  className={clsx(
589
527
  "font-mono text-xs",
590
- f.label === "error" && run.error
591
- ? "text-[var(--oke-danger)]"
592
- : "",
528
+ f.label === "error" && run.error ? "text-[var(--oke-danger)]" : "",
593
529
  )}
594
530
  >
595
531
  {f.value}
@@ -610,8 +546,7 @@ function RunDetail({
610
546
  className="flex min-h-8 items-center justify-between gap-3 py-1"
611
547
  >
612
548
  <span>
613
- {e.kind}{" "}
614
- <span className="font-mono text-xs">{e.resource}</span>
549
+ {e.kind} <span className="font-mono text-xs">{e.resource}</span>
615
550
  </span>
616
551
  <span className="font-mono text-xs text-[var(--oke-muted)]">
617
552
  {e.duration}ms · {e.reversibility}
@@ -623,17 +558,14 @@ function RunDetail({
623
558
  </div>
624
559
 
625
560
  <details className="group">
626
- <summary className="cursor-pointer text-sm font-medium">
627
- fx.log ({run.logs.length})
628
- </summary>
561
+ <summary className="cursor-pointer text-sm font-medium">fx.log ({run.logs.length})</summary>
629
562
  {run.logs.length === 0 ? (
630
563
  <p className="mt-2 text-sm text-[var(--oke-muted)]">No log lines</p>
631
564
  ) : (
632
565
  <ul className="mt-2 divide-y divide-[var(--oke-line)] font-mono text-xs">
633
566
  {run.logs.map((line, i) => (
634
567
  <li key={i} className="py-2">
635
- <span className="text-[var(--oke-muted)]">[{line.level}]</span>{" "}
636
- {line.message}
568
+ <span className="text-[var(--oke-muted)]">[{line.level}]</span> {line.message}
637
569
  {line.data ? (
638
570
  <pre className="mt-1 whitespace-pre-wrap text-[var(--oke-muted)]">
639
571
  {JSON.stringify(line.data, null, 2)}
@@ -43,9 +43,7 @@ export function SignalsPanel() {
43
43
  const [typed, setTyped] = useState("");
44
44
  const [reason, setReason] = useState("");
45
45
  const [dryRunSummary, setDryRunSummary] = useState<string | null>(null);
46
- const [monitor, setMonitor] = useState<LiveMonitorState>(() =>
47
- createLiveMonitor(),
48
- );
46
+ const [monitor, setMonitor] = useState<LiveMonitorState>(() => createLiveMonitor());
49
47
  const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set());
50
48
 
51
49
  const setSearch = (next: SignalsSearch) => {
@@ -68,20 +66,13 @@ export function SignalsPanel() {
68
66
  });
69
67
 
70
68
  const signals = signalsQuery.data ?? [];
71
- const groups = useMemo(
72
- () => groupByPhysics(signals, search.q ?? ""),
73
- [signals, search.q],
74
- );
69
+ const groups = useMemo(() => groupByPhysics(signals, search.q ?? ""), [signals, search.q]);
75
70
  const open = signals.find((s) => s.name === search.signal);
76
71
  const line = open ? durableLine(open.consumersDurable) : null;
77
72
  const dlq = open?.deadLetters.find((d) => d.id === search.dlq);
78
73
  const fields = open ? fieldsFromSchema(open.schema) : [];
79
- const replayConfirm = open
80
- ? replayConfirmation(open, { production: true })
81
- : null;
82
- const discardConfirm = open
83
- ? discardConfirmation(open, { production: true })
84
- : null;
74
+ const replayConfirm = open ? replayConfirmation(open, { production: true }) : null;
75
+ const discardConfirm = open ? discardConfirmation(open, { production: true }) : null;
85
76
  const dryOffer = open ? dryRunOffer(open) : null;
86
77
 
87
78
  useEffect(() => {
@@ -99,8 +90,7 @@ export function SignalsPanel() {
99
90
  }
100
91
  setMonitor((m) => ({
101
92
  ...setPaused(m, false),
102
- payloads:
103
- m.payloads.length === 0 ? [...open.recentLive] : m.payloads,
93
+ payloads: m.payloads.length === 0 ? [...open.recentLive] : m.payloads,
104
94
  }));
105
95
  }, [open?.name, open?.recentLive, open?.delivery, search.paused]);
106
96
 
@@ -110,10 +100,7 @@ export function SignalsPanel() {
110
100
  if (dryOffer && !dryOffer.ok) {
111
101
  throw new Error(dryOffer.reason);
112
102
  }
113
- const ids =
114
- selectedIds.size > 0
115
- ? [...selectedIds]
116
- : open.deadLetters.map((d) => d.id);
103
+ const ids = selectedIds.size > 0 ? [...selectedIds] : open.deadLetters.map((d) => d.id);
117
104
  const res = await consoleCalls.signalsDryRunReplay({
118
105
  signal: open.name,
119
106
  messageIds: ids,
@@ -129,14 +116,10 @@ export function SignalsPanel() {
129
116
  data.wouldHaveFired?.length > 0
130
117
  ? ` · ${data.wouldHaveFired.length} external effect(s) stubbed`
131
118
  : "";
132
- setDryRunSummary(
133
- `${data.succeeded} would succeed, ${data.failed} would still fail${stubs}`,
134
- );
119
+ setDryRunSummary(`${data.succeeded} would succeed, ${data.failed} would still fail${stubs}`);
135
120
  },
136
121
  onError: (err) => {
137
- setDryRunSummary(
138
- err instanceof Error ? err.message : "Dry-run refused",
139
- );
122
+ setDryRunSummary(err instanceof Error ? err.message : "Dry-run refused");
140
123
  },
141
124
  });
142
125
 
@@ -158,9 +141,7 @@ export function SignalsPanel() {
158
141
  ? [dlq.id]
159
142
  : open.deadLetters.map((d) => d.id);
160
143
  const payloads =
161
- dlq && fields
162
- ? { [dlq.id]: formValuesToPayload(formValues, fields) }
163
- : undefined;
144
+ dlq && fields ? { [dlq.id]: formValuesToPayload(formValues, fields) } : undefined;
164
145
  const res = await consoleCalls.signalsReplay({
165
146
  signal: open.name,
166
147
  messageIds: ids,
@@ -168,8 +149,7 @@ export function SignalsPanel() {
168
149
  ratePerSec: rate,
169
150
  dryRun: false,
170
151
  payloads,
171
- confirmation:
172
- replayConfirm.kind === "typed" ? typed : undefined,
152
+ confirmation: replayConfirm.kind === "typed" ? typed : undefined,
173
153
  reason: replayConfirm.kind === "typed" ? reason : undefined,
174
154
  });
175
155
  if (res.error) throw new Error(res.error.code);
@@ -202,8 +182,7 @@ export function SignalsPanel() {
202
182
  const res = await consoleCalls.signalsDiscard({
203
183
  signal: open.name,
204
184
  messageIds: ids,
205
- confirmation:
206
- discardConfirm.kind === "typed" ? typed : undefined,
185
+ confirmation: discardConfirm.kind === "typed" ? typed : undefined,
207
186
  reason: discardConfirm.kind === "typed" ? reason : undefined,
208
187
  });
209
188
  if (res.error) throw new Error(res.error.code);
@@ -220,15 +199,9 @@ export function SignalsPanel() {
220
199
  <div className="flex h-full min-h-0 flex-col">
221
200
  <header className="flex shrink-0 flex-wrap items-end gap-4 border-b border-[var(--oke-line)] px-6 py-4">
222
201
  <div className="flex flex-col gap-1">
223
- <p className="text-xs uppercase tracking-[0.2em] text-[var(--oke-muted)]">
224
- Signals
225
- </p>
226
- <h1 className="text-xl font-semibold tracking-tight">
227
- Delivery physics
228
- </h1>
229
- <p className="text-xs text-[var(--oke-muted)]">
230
- One list — once · broadcast · live
231
- </p>
202
+ <p className="text-xs uppercase tracking-[0.2em] text-[var(--oke-muted)]">Signals</p>
203
+ <h1 className="text-xl font-semibold tracking-tight">Delivery physics</h1>
204
+ <p className="text-xs text-[var(--oke-muted)]">One list — once · broadcast · live</p>
232
205
  </div>
233
206
  <label className="flex flex-col gap-1 text-sm">
234
207
  <span className="text-[var(--oke-muted)]">Filter</span>
@@ -236,9 +209,7 @@ export function SignalsPanel() {
236
209
  aria-label="Filter signals"
237
210
  className="min-h-8 border border-[var(--oke-line)] bg-transparent px-2 text-sm"
238
211
  value={search.q ?? ""}
239
- onChange={(e) =>
240
- setSearch({ ...search, q: e.target.value || undefined })
241
- }
212
+ onChange={(e) => setSearch({ ...search, q: e.target.value || undefined })}
242
213
  />
243
214
  </label>
244
215
  </header>
@@ -249,13 +220,9 @@ export function SignalsPanel() {
249
220
  className="min-h-0 overflow-auto border-r border-[var(--oke-line)]"
250
221
  >
251
222
  {signalsQuery.isLoading ? (
252
- <p className="px-6 py-8 text-sm text-[var(--oke-muted)]">
253
- Loading signals…
254
- </p>
223
+ <p className="px-6 py-8 text-sm text-[var(--oke-muted)]">Loading signals…</p>
255
224
  ) : groups.length === 0 ? (
256
- <p className="px-6 py-8 text-sm text-[var(--oke-muted)]">
257
- No signals declared.
258
- </p>
225
+ <p className="px-6 py-8 text-sm text-[var(--oke-muted)]">No signals declared.</p>
259
226
  ) : (
260
227
  groups.map((group) => (
261
228
  <section
@@ -283,10 +250,7 @@ export function SignalsPanel() {
283
250
  <span className="font-medium">
284
251
  {s.name}
285
252
  {s.orphaned ? (
286
- <span
287
- role="status"
288
- className="ml-2 text-xs text-[var(--oke-muted)]"
289
- >
253
+ <span role="status" className="ml-2 text-xs text-[var(--oke-muted)]">
290
254
  orphaned
291
255
  </span>
292
256
  ) : null}
@@ -294,8 +258,7 @@ export function SignalsPanel() {
294
258
  <span className="text-xs text-[var(--oke-muted)]">
295
259
  {s.delivery === "once" && (
296
260
  <>
297
- pending {s.pending} · in-flight {s.inflight} ·
298
- DLQ {s.dead}
261
+ pending {s.pending} · in-flight {s.inflight} · DLQ {s.dead}
299
262
  {s.outboxLagMs != null && s.outboxLagMs > 0
300
263
  ? ` · outbox ${s.outboxLagMs}ms`
301
264
  : ""}
@@ -388,9 +351,7 @@ export function SignalsPanel() {
388
351
  <div className="flex flex-col gap-2">
389
352
  <h3 className="text-sm font-medium">Subscribers</h3>
390
353
  <table className="w-full text-left text-sm">
391
- <caption className="sr-only">
392
- Per-subscriber lag and errors
393
- </caption>
354
+ <caption className="sr-only">Per-subscriber lag and errors</caption>
394
355
  <thead>
395
356
  <tr className="text-[var(--oke-muted)]">
396
357
  <th scope="col" className="py-1 font-normal">
@@ -421,10 +382,7 @@ export function SignalsPanel() {
421
382
  onClick={() =>
422
383
  setSearch({
423
384
  ...search,
424
- sub:
425
- search.sub === sub.id
426
- ? undefined
427
- : sub.id,
385
+ sub: search.sub === sub.id ? undefined : sub.id,
428
386
  })
429
387
  }
430
388
  >
@@ -439,10 +397,7 @@ export function SignalsPanel() {
439
397
  ) : null}
440
398
 
441
399
  {open.delivery === "live" ? (
442
- <section
443
- aria-label="Payload monitor"
444
- className="flex flex-col gap-2"
445
- >
400
+ <section aria-label="Payload monitor" className="flex flex-col gap-2">
446
401
  <div className="flex flex-wrap items-center gap-3">
447
402
  <h3 className="text-sm font-medium">Payload monitor</h3>
448
403
  <span className="text-xs text-[var(--oke-muted)]">
@@ -466,10 +421,9 @@ export function SignalsPanel() {
466
421
  type="button"
467
422
  variant="ghost"
468
423
  onClick={() => {
469
- const blob = new Blob(
470
- [exportLivePayloads(monitor.payloads)],
471
- { type: "application/json" },
472
- );
424
+ const blob = new Blob([exportLivePayloads(monitor.payloads)], {
425
+ type: "application/json",
426
+ });
473
427
  const url = URL.createObjectURL(blob);
474
428
  const a = document.createElement("a");
475
429
  a.href = url;
@@ -498,10 +452,7 @@ export function SignalsPanel() {
498
452
  });
499
453
  }}
500
454
  >
501
- {(monitor.payloads.length
502
- ? monitor.payloads
503
- : open.recentLive
504
- ).map((p, i) => (
455
+ {(monitor.payloads.length ? monitor.payloads : open.recentLive).map((p, i) => (
505
456
  <li key={i} className="border-b border-[var(--oke-line)]/50 py-1">
506
457
  {JSON.stringify(p)}
507
458
  </li>
@@ -569,18 +520,14 @@ export function SignalsPanel() {
569
520
 
570
521
  {open.dead > 0 ? (
571
522
  <section aria-label="Dead letters" className="flex flex-col gap-3">
572
- <h3 className="text-sm font-medium">
573
- Dead letters ({open.dead})
574
- </h3>
523
+ <h3 className="text-sm font-medium">Dead letters ({open.dead})</h3>
575
524
  <p className="text-xs text-[var(--oke-muted)]">
576
- Bulk repair: dry run first, then replay at a controlled rate
577
- — never an unthrottled flood.
525
+ Bulk repair: dry run first, then replay at a controlled rate — never an
526
+ unthrottled flood.
578
527
  </p>
579
528
  <div className="flex flex-wrap items-end gap-3">
580
529
  <label className="flex flex-col gap-1 text-sm">
581
- <span className="text-[var(--oke-muted)]">
582
- Rate (per second)
583
- </span>
530
+ <span className="text-[var(--oke-muted)]">Rate (per second)</span>
584
531
  <input
585
532
  aria-label="Replay rate (per second)"
586
533
  type="number"
@@ -600,9 +547,7 @@ export function SignalsPanel() {
600
547
  type="button"
601
548
  onClick={() => dryRun.mutate()}
602
549
  disabled={dryRun.isPending || (dryOffer !== null && !dryOffer.ok)}
603
- title={
604
- dryOffer && !dryOffer.ok ? dryOffer.reason : undefined
605
- }
550
+ title={dryOffer && !dryOffer.ok ? dryOffer.reason : undefined}
606
551
  >
607
552
  Dry run
608
553
  </Button>
@@ -632,12 +577,11 @@ export function SignalsPanel() {
632
577
  {dryRunSummary}
633
578
  </p>
634
579
  ) : null}
635
- {(replayConfirm?.kind === "typed" ||
636
- discardConfirm?.kind === "typed") && (
580
+ {(replayConfirm?.kind === "typed" || discardConfirm?.kind === "typed") && (
637
581
  <div className="flex flex-col gap-2 border border-[var(--oke-line)] p-3">
638
582
  <p className="text-xs text-[var(--oke-muted)]">
639
- This action re-triggers external effects or permanently
640
- discards messages. Type the phrase and a reason.
583
+ This action re-triggers external effects or permanently discards messages.
584
+ Type the phrase and a reason.
641
585
  </p>
642
586
  <label className="flex flex-col gap-1 text-sm">
643
587
  Confirmation
@@ -688,9 +632,7 @@ export function SignalsPanel() {
688
632
  type="button"
689
633
  aria-pressed={d.id === search.dlq}
690
634
  className="min-h-8 flex-1 text-left text-sm"
691
- onClick={() =>
692
- setSearch(openDeadLetter(search, d.id))
693
- }
635
+ onClick={() => setSearch(openDeadLetter(search, d.id))}
694
636
  >
695
637
  <span className="font-mono text-xs">{d.id}</span>
696
638
  {last ? (
@@ -712,9 +654,7 @@ export function SignalsPanel() {
712
654
  className="flex flex-col gap-3 border-t border-[var(--oke-line)] pt-4"
713
655
  >
714
656
  <div className="flex items-center justify-between">
715
- <h3 className="text-sm font-medium">
716
- Dead letter {dlq.id}
717
- </h3>
657
+ <h3 className="text-sm font-medium">Dead letter {dlq.id}</h3>
718
658
  <Button
719
659
  type="button"
720
660
  variant="ghost"
@@ -775,9 +715,7 @@ export function SignalsPanel() {
775
715
  aria-label="Payload JSON"
776
716
  className="min-h-24 border border-[var(--oke-line)] bg-transparent px-2 font-mono text-xs"
777
717
  value={formValues._raw ?? ""}
778
- onChange={(e) =>
779
- setFormValues({ _raw: e.target.value })
780
- }
718
+ onChange={(e) => setFormValues({ _raw: e.target.value })}
781
719
  rows={4}
782
720
  />
783
721
  </label>
@@ -790,8 +728,7 @@ export function SignalsPanel() {
790
728
  <ol className="list-decimal space-y-1 pl-5 text-sm">
791
729
  {dlq.failures.map((f) => (
792
730
  <li key={`${f.attempt}-${f.code}-${f.at}`}>
793
- Attempt {f.attempt}: <strong>{f.code}</strong> —{" "}
794
- {f.message}
731
+ Attempt {f.attempt}: <strong>{f.code}</strong> — {f.message}
795
732
  </li>
796
733
  ))}
797
734
  </ol>