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
@@ -37,7 +37,7 @@ export interface ServiceSpec {
37
37
  readonly port: number;
38
38
  /** Host port published in compose (dev defaults). */
39
39
  readonly hostPort: number;
40
- /** Credential placeholders (values live in `.env.stack`, not YAML). */
40
+ /** Credential placeholders (values live in `.env.docker`, not YAML). */
41
41
  readonly credentials: ServiceCredentials;
42
42
  }
43
43
 
@@ -50,13 +50,22 @@ export interface ComposeHealthcheck {
50
50
  readonly start_period?: string;
51
51
  }
52
52
 
53
+ /** Extra published host↔container port pair from a recipe. */
54
+ export interface RecipeExtraPort {
55
+ readonly host: number;
56
+ readonly container: number;
57
+ }
58
+
53
59
  /** Image-specific compose fragment from {@link ImageRecipe.apply}. */
54
60
  export interface RecipeApplyResult {
55
61
  readonly environment?: Readonly<Record<string, string>>;
56
62
  readonly command?: string | readonly string[];
63
+ readonly entrypoint?: string | readonly string[];
57
64
  readonly healthcheck?: ComposeHealthcheck;
58
65
  readonly volumes?: readonly string[];
59
66
  readonly user?: string;
67
+ /** Additional published ports (e.g. Mailpit UI, RustFS console). */
68
+ readonly extraPorts?: readonly RecipeExtraPort[];
60
69
  }
61
70
 
62
71
  /**
@@ -102,12 +111,13 @@ export interface DeriveOptions {
102
111
  readonly prod?: boolean;
103
112
  /**
104
113
  * Include the `app` service in `compose.yml` (default true).
105
- * `oke dev --stack` sets false — host Bun runs the app; Docker is infra only.
114
+ * `oke dev --docker` sets false — host Bun runs the app; Docker is infra only.
106
115
  */
107
116
  readonly includeApp?: boolean;
108
117
  /**
109
118
  * Compose artefact directory relative to the project root (default `docker`).
110
- * Controls generated `env_file` / `build.context` paths (e.g. `../.env.stack`).
119
+ * Controls generated `env_file` / `build.context` paths (`.env.docker` lives
120
+ * beside compose under this directory).
111
121
  * Pass `"."` for legacy root-level layout.
112
122
  */
113
123
  readonly composeDir?: string;
@@ -119,6 +129,8 @@ export interface DeriveOptions {
119
129
  readonly host?: string;
120
130
  /** Extra image recipes (plugins). */
121
131
  readonly recipes?: readonly ImageRecipe[];
132
+ /** Preserved optional controls from an existing `.env.docker`. */
133
+ readonly controls?: Readonly<Record<string, string>>;
122
134
  /**
123
135
  * Local stack instance id (6-hex). When set, host ports are offset so two
124
136
  * `oke dev -s` projects do not share one Postgres on `:5432`.
@@ -144,7 +156,7 @@ export interface DeriveResult {
144
156
  /** Generated files (Dockerfile + compose layers). */
145
157
  readonly files: readonly GeneratedFile[];
146
158
  /**
147
- * Stack env contents for `.env.stack` — written by `oke dev --stack`,
159
+ * Stack env contents for `.env.docker` — written by `oke dev --docker`,
148
160
  * never embedded in YAML.
149
161
  */
150
162
  readonly stackEnv: Readonly<Record<string, string>>;
@@ -1,12 +1,12 @@
1
1
  /**
2
2
  * Canonical public docs origin for error links, README, and the site.
3
3
  *
4
- * Flip this one constant when the custom domain is attached:
5
- * `https://oke.omqkhafi.dev`
4
+ * Keep in lockstep with `packages/create-oke/src/docs-origin.ts` and
5
+ * `site/app/layout.tsx` (`metadataBase`).
6
6
  */
7
7
 
8
- /** Live docs site (Vercel). Planned cutover: `https://oke.omqkhafi.dev`. */
9
- export const DOCS_ORIGIN = "https://okengine.vercel.app" as const;
8
+ /** Live docs site. */
9
+ export const DOCS_ORIGIN = "https://oke.omqkhafi.dev" as const;
10
10
 
11
11
  /**
12
12
  * Absolute docs URL for a path under the handbook / site.
@@ -21,9 +21,7 @@ const ANTHROPIC_VERSION = "2023-06-01";
21
21
  *
22
22
  * @param options - API key / model / base URL / injectable fetch
23
23
  */
24
- export async function openAnthropic(
25
- options: AiOpenOptions = {},
26
- ): Promise<AiModelClient> {
24
+ export async function openAnthropic(options: AiOpenOptions = {}): Promise<AiModelClient> {
27
25
  const apiKey = options.apiKey ?? process.env.ANTHROPIC_API_KEY;
28
26
  if (!apiKey) {
29
27
  throw new Error("anthropic: apiKey is required (or ANTHROPIC_API_KEY)");
@@ -48,17 +46,14 @@ export async function openAnthropic(
48
46
  body: JSON.stringify({
49
47
  model: resolvedModel,
50
48
  max_tokens: opts.maxTokens ?? 1024,
51
- ...(opts.temperature !== undefined
52
- ? { temperature: opts.temperature }
53
- : {}),
49
+ ...(opts.temperature !== undefined ? { temperature: opts.temperature } : {}),
54
50
  ...(system !== undefined ? { system } : {}),
55
51
  messages,
56
52
  }),
57
53
  });
58
54
  const raw = (await res.json().catch(() => ({}))) as AnthropicMessagesResponse;
59
55
  if (!res.ok) {
60
- const msg =
61
- raw.error?.message ?? `anthropic HTTP ${res.status}`;
56
+ const msg = raw.error?.message ?? `anthropic HTTP ${res.status}`;
62
57
  throw new Error(`anthropic: ${msg}`);
63
58
  }
64
59
  const text = textFromContent(raw.content);
@@ -92,9 +87,7 @@ interface AnthropicMessagesResponse {
92
87
  readonly error?: { readonly message?: string };
93
88
  }
94
89
 
95
- function splitSystem(
96
- messages: AiCompleteOptions["messages"],
97
- ): {
90
+ function splitSystem(messages: AiCompleteOptions["messages"]): {
98
91
  system?: string;
99
92
  messages: Array<{ role: "user" | "assistant"; content: string }>;
100
93
  } {
@@ -117,9 +110,7 @@ function splitSystem(
117
110
  };
118
111
  }
119
112
 
120
- function textFromContent(
121
- content: AnthropicMessagesResponse["content"],
122
- ): string {
113
+ function textFromContent(content: AnthropicMessagesResponse["content"]): string {
123
114
  if (!content?.length) return "";
124
115
  return content
125
116
  .filter((b) => b.type === "text" && typeof b.text === "string")
@@ -39,8 +39,7 @@ export const mockAiDriver: AiDriver = {
39
39
  if (payload === undefined) {
40
40
  payload = canned["*"] ?? { ok: true, echo: last };
41
41
  }
42
- const text =
43
- typeof payload === "string" ? payload : JSON.stringify(payload);
42
+ const text = typeof payload === "string" ? payload : JSON.stringify(payload);
44
43
  return {
45
44
  text,
46
45
  raw: payload,
@@ -70,9 +69,7 @@ export const mockAiDriver: AiDriver = {
70
69
  *
71
70
  * @param responses - Key → JSON payload
72
71
  */
73
- export function createMockAiDriver(
74
- responses: Readonly<Record<string, unknown>>,
75
- ): AiDriver {
72
+ export function createMockAiDriver(responses: Readonly<Record<string, unknown>>): AiDriver {
76
73
  return {
77
74
  id: "mock",
78
75
  open(options = {}) {
@@ -23,14 +23,10 @@ const DEFAULT_BASE = "https://api.openai.com/v1";
23
23
  *
24
24
  * @param options - API key / model / base URL / injectable fetch
25
25
  */
26
- export async function openOpenaiCompatible(
27
- options: AiOpenOptions = {},
28
- ): Promise<AiModelClient> {
26
+ export async function openOpenaiCompatible(options: AiOpenOptions = {}): Promise<AiModelClient> {
29
27
  const apiKey = options.apiKey ?? process.env.OPENAI_API_KEY;
30
28
  if (!apiKey) {
31
- throw new Error(
32
- "openai-compatible: apiKey is required (or OPENAI_API_KEY)",
33
- );
29
+ throw new Error("openai-compatible: apiKey is required (or OPENAI_API_KEY)");
34
30
  }
35
31
  const model = options.model ?? "gpt-4o-mini";
36
32
  const baseUrl = (options.baseUrl ?? DEFAULT_BASE).replace(/\/$/, "");
@@ -65,8 +61,7 @@ export async function openOpenaiCompatible(
65
61
  });
66
62
  const raw = (await res.json().catch(() => ({}))) as OpenAiChatResponse;
67
63
  if (!res.ok) {
68
- const msg =
69
- raw.error?.message ?? `openai-compatible HTTP ${res.status}`;
64
+ const msg = raw.error?.message ?? `openai-compatible HTTP ${res.status}`;
70
65
  throw new Error(`openai-compatible: ${msg}`);
71
66
  }
72
67
  const text = raw.choices?.[0]?.message?.content ?? "";
@@ -94,8 +89,7 @@ export async function openOpenaiCompatible(
94
89
  });
95
90
  const raw = (await res.json().catch(() => ({}))) as OpenAiEmbedResponse;
96
91
  if (!res.ok) {
97
- const msg =
98
- raw.error?.message ?? `openai-compatible embed HTTP ${res.status}`;
92
+ const msg = raw.error?.message ?? `openai-compatible embed HTTP ${res.status}`;
99
93
  throw new Error(`openai-compatible: ${msg}`);
100
94
  }
101
95
  const vectors = (raw.data ?? [])
@@ -4,10 +4,7 @@
4
4
 
5
5
  import { describe, expect, test } from "bun:test";
6
6
  import { anthropicAiDriver, openAnthropic } from "./ai-anthropic.ts";
7
- import {
8
- openaiCompatibleAiDriver,
9
- openOpenaiCompatible,
10
- } from "./ai-openai-compatible.ts";
7
+ import { openaiCompatibleAiDriver, openOpenaiCompatible } from "./ai-openai-compatible.ts";
11
8
  import { mockAiDriver } from "./ai-mock.ts";
12
9
 
13
10
  describe("anthropic driver", () => {
@@ -56,9 +53,7 @@ describe("anthropic driver", () => {
56
53
  messages: Array<{ role: string }>;
57
54
  };
58
55
  expect(body.system).toBe("be brief");
59
- expect(body.messages).toEqual([
60
- { role: "user", content: "hi" } as { role: string },
61
- ]);
56
+ expect(body.messages).toEqual([{ role: "user", content: "hi" } as { role: string }]);
62
57
  });
63
58
 
64
59
  test("HTTP error surfaces provider message", async () => {
@@ -73,18 +68,16 @@ describe("anthropic driver", () => {
73
68
  apiKey: "sk-test",
74
69
  fetch: fetchFn,
75
70
  });
76
- await expect(
77
- client.complete({ messages: [{ role: "user", content: "x" }] }),
78
- ).rejects.toThrow("rate limited");
71
+ await expect(client.complete({ messages: [{ role: "user", content: "x" }] })).rejects.toThrow(
72
+ "rate limited",
73
+ );
79
74
  });
80
75
 
81
76
  test("live Anthropic ask when ANTHROPIC_API_KEY is set", async () => {
82
77
  const key = process.env.ANTHROPIC_API_KEY;
83
78
  if (!key) {
84
79
  // Clearly-marked skip — never fail CI for lack of credentials.
85
- console.log(
86
- "skip: live anthropic ask (ANTHROPIC_API_KEY not set)",
87
- );
80
+ console.log("skip: live anthropic ask (ANTHROPIC_API_KEY not set)");
88
81
  return;
89
82
  }
90
83
  const client = await anthropicAiDriver.open({
@@ -7,10 +7,7 @@
7
7
 
8
8
  import { describe, expect, test } from "bun:test";
9
9
  import { createBunRedisClient } from "./redis.ts";
10
- import {
11
- createBunSignalRedisClient,
12
- parseXreadgroupReply,
13
- } from "./signal-redis.ts";
10
+ import { createBunSignalRedisClient, parseXreadgroupReply } from "./signal-redis.ts";
14
11
 
15
12
  /** One row in the completeness report. */
16
13
  export interface BunNativeGapRow {
@@ -26,10 +23,7 @@ export interface BunNativeGapRow {
26
23
  * Kept as a pure function so the gate test and human report share one source.
27
24
  */
28
25
  export function bunNativeCompletenessReport(): readonly BunNativeGapRow[] {
29
- const redisProto = Bun.RedisClient.prototype as unknown as Record<
30
- string,
31
- unknown
32
- >;
26
+ const redisProto = Bun.RedisClient.prototype as unknown as Record<string, unknown>;
33
27
  const hasTypedScan = typeof redisProto.scan === "function";
34
28
  const hasTypedPublish = typeof redisProto.publish === "function";
35
29
  const hasTypedSubscribe = typeof redisProto.subscribe === "function";
@@ -57,8 +51,7 @@ export function bunNativeCompletenessReport(): readonly BunNativeGapRow[] {
57
51
  {
58
52
  surface: "redis signal",
59
53
  capability: "native Bun bind (publish/subscribe)",
60
- status:
61
- hasTypedPublish && hasTypedSubscribe ? "closed" : "bun_limitation",
54
+ status: hasTypedPublish && hasTypedSubscribe ? "closed" : "bun_limitation",
62
55
  note:
63
56
  hasTypedPublish && hasTypedSubscribe
64
57
  ? "createBunSignalRedisClient uses typed publish/subscribe"
@@ -107,9 +100,7 @@ describe("Bun native client completeness", () => {
107
100
  expect(rows.length).toBe(8);
108
101
 
109
102
  const closed = rows.filter((r) => r.status === "closed").map((r) => r.capability);
110
- const limited = rows
111
- .filter((r) => r.status === "bun_limitation")
112
- .map((r) => r.capability);
103
+ const limited = rows.filter((r) => r.status === "bun_limitation").map((r) => r.capability);
113
104
 
114
105
  // Closed on Bun 1.3.14
115
106
  expect(closed).toContain("SCAN (typed)");
@@ -141,13 +132,13 @@ describe("Bun native client completeness", () => {
141
132
  [
142
133
  "oke:signal:order",
143
134
  [
144
- ["1-0", ["payload", "{\"a\":1}", "signal", "order"]],
135
+ ["1-0", ["payload", '{"a":1}', "signal", "order"]],
145
136
  ["1-1", ["payload", "{}", "signal", "order"]],
146
137
  ],
147
138
  ],
148
139
  ]);
149
140
  expect(parsed).toEqual([
150
- { id: "1-0", fields: { payload: "{\"a\":1}", signal: "order" } },
141
+ { id: "1-0", fields: { payload: '{"a":1}', signal: "order" } },
151
142
  { id: "1-1", fields: { payload: "{}", signal: "order" } },
152
143
  ]);
153
144
  expect(parseXreadgroupReply(null)).toEqual([]);
@@ -21,9 +21,7 @@ import { createChannelInbox } from "./channel-types.ts";
21
21
  function formatAddressInput(input: AddressInput): string {
22
22
  if (typeof input === "string") return input;
23
23
  if (Array.isArray(input)) {
24
- return input
25
- .map((t) => (typeof t === "string" ? t : t.address))
26
- .join(",");
24
+ return input.map((t) => (typeof t === "string" ? t : t.address)).join(",");
27
25
  }
28
26
  return input.address;
29
27
  }
@@ -33,9 +31,7 @@ function formatAddressInput(input: AddressInput): string {
33
31
  *
34
32
  * @param options - Optional shared inbox
35
33
  */
36
- export function openConsoleChannel(
37
- options: ChannelOpenOptions = {},
38
- ): ChannelDriver {
34
+ export function openConsoleChannel(options: ChannelOpenOptions = {}): ChannelDriver {
39
35
  const inbox = options.inbox ?? createChannelInbox();
40
36
 
41
37
  const channel: ChannelTransport = {
@@ -88,7 +84,10 @@ export function openConsoleChannel(
88
84
  template: mail.template,
89
85
  at: Date.now(),
90
86
  });
91
- const recipients = to.split(",").map((s) => s.trim()).filter(Boolean);
87
+ const recipients = to
88
+ .split(",")
89
+ .map((s) => s.trim())
90
+ .filter(Boolean);
92
91
  return {
93
92
  messageId: id,
94
93
  accepted: recipients,
@@ -15,9 +15,7 @@ import type {
15
15
  *
16
16
  * @param options - `token` (OAuth access token) + `from` (project id)
17
17
  */
18
- export function openFcmChannel(
19
- options: ChannelOpenOptions = {},
20
- ): ChannelDriver {
18
+ export function openFcmChannel(options: ChannelOpenOptions = {}): ChannelDriver {
21
19
  const accessToken = options.token ?? options.apiKey;
22
20
  const projectId = options.from;
23
21
  const fetchFn = options.fetch ?? globalThis.fetch;
@@ -30,31 +28,25 @@ export function openFcmChannel(
30
28
  if (!accessToken || !projectId) {
31
29
  throw new Error("fcm: token and from (project id) are required");
32
30
  }
33
- const res = await fetchFn(
34
- `${base}/v1/projects/${projectId}/messages:send`,
35
- {
36
- method: "POST",
37
- headers: {
38
- Authorization: `Bearer ${accessToken}`,
39
- "Content-Type": "application/json",
40
- },
41
- body: JSON.stringify({
42
- message: {
43
- token: message.to,
44
- notification: {
45
- title: message.subject ?? message.template ?? "notification",
46
- body: message.text ?? "",
47
- },
48
- data: Object.fromEntries(
49
- Object.entries(message.data ?? {}).map(([k, v]) => [
50
- k,
51
- String(v),
52
- ]),
53
- ),
54
- },
55
- }),
31
+ const res = await fetchFn(`${base}/v1/projects/${projectId}/messages:send`, {
32
+ method: "POST",
33
+ headers: {
34
+ Authorization: `Bearer ${accessToken}`,
35
+ "Content-Type": "application/json",
56
36
  },
57
- );
37
+ body: JSON.stringify({
38
+ message: {
39
+ token: message.to,
40
+ notification: {
41
+ title: message.subject ?? message.template ?? "notification",
42
+ body: message.text ?? "",
43
+ },
44
+ data: Object.fromEntries(
45
+ Object.entries(message.data ?? {}).map(([k, v]) => [k, String(v)]),
46
+ ),
47
+ },
48
+ }),
49
+ });
58
50
  const body = (await res.json().catch(() => ({}))) as {
59
51
  name?: string;
60
52
  error?: { message?: string };
@@ -79,9 +71,7 @@ export function openFcmChannel(
79
71
  ok: true,
80
72
  messageId: id,
81
73
  driverId: "fcm",
82
- attempts: [
83
- { driverId: "fcm", ok: true, at: Date.now(), messageId: id },
84
- ],
74
+ attempts: [{ driverId: "fcm", ok: true, at: Date.now(), messageId: id }],
85
75
  };
86
76
  },
87
77
  };
@@ -10,9 +10,7 @@ import type { ChannelDriver, ChannelOpenOptions } from "./channel-types.ts";
10
10
  *
11
11
  * @param options - API key
12
12
  */
13
- export function openResendChannel(
14
- options: ChannelOpenOptions = {},
15
- ): ChannelDriver {
13
+ export function openResendChannel(options: ChannelOpenOptions = {}): ChannelDriver {
16
14
  if (!options.apiKey) {
17
15
  throw new Error("resend channel: apiKey is required");
18
16
  }
@@ -10,18 +10,14 @@ import type { ChannelDriver, ChannelOpenOptions } from "./channel-types.ts";
10
10
  *
11
11
  * @param options - Host / port / auth
12
12
  */
13
- export function openSmtpChannel(
14
- options: ChannelOpenOptions = {},
15
- ): ChannelDriver {
13
+ export function openSmtpChannel(options: ChannelOpenOptions = {}): ChannelDriver {
16
14
  if (!options.host) {
17
15
  throw new Error("smtp channel: host is required");
18
16
  }
19
17
  const transport = new SMTPTransport({
20
18
  host: options.host,
21
19
  port: options.port ?? 587,
22
- ...(options.user && options.pass
23
- ? { auth: { user: options.user, pass: options.pass } }
24
- : {}),
20
+ ...(options.user && options.pass ? { auth: { user: options.user, pass: options.pass } } : {}),
25
21
  });
26
22
  return { id: "smtp", transport };
27
23
  }
@@ -5,12 +5,7 @@
5
5
  * run unchanged. Non-email media (sms / whatsapp / push) use {@link ChannelTransport}.
6
6
  */
7
7
 
8
- import type {
9
- MailOptions,
10
- SendResult,
11
- Transport,
12
- VerifyResult,
13
- } from "sently";
8
+ import type { MailOptions, SendResult, Transport, VerifyResult } from "sently";
14
9
 
15
10
  export type {
16
11
  Address,
@@ -35,12 +30,7 @@ export type ChannelDriverId =
35
30
  | "webpush";
36
31
 
37
32
  /** Channel medium. */
38
- export type ChannelMediumId =
39
- | "email"
40
- | "sms"
41
- | "whatsapp"
42
- | "push"
43
- | "any";
33
+ export type ChannelMediumId = "email" | "sms" | "whatsapp" | "push" | "any";
44
34
 
45
35
  /** Unified outbound message (medium-agnostic). */
46
36
  export interface ChannelMessage {
@@ -15,9 +15,7 @@ import type {
15
15
  *
16
16
  * @param options - `apiKey` + optional `from` (sender id)
17
17
  */
18
- export function openUnifonicChannel(
19
- options: ChannelOpenOptions = {},
20
- ): ChannelDriver {
18
+ export function openUnifonicChannel(options: ChannelOpenOptions = {}): ChannelDriver {
21
19
  const apiKey = options.apiKey;
22
20
  const from = options.from ?? "OKE";
23
21
  const fetchFn = options.fetch ?? globalThis.fetch;
@@ -62,9 +60,7 @@ export function openUnifonicChannel(
62
60
  ok: true,
63
61
  messageId: id,
64
62
  driverId: "unifonic",
65
- attempts: [
66
- { driverId: "unifonic", ok: true, at: Date.now(), messageId: id },
67
- ],
63
+ attempts: [{ driverId: "unifonic", ok: true, at: Date.now(), messageId: id }],
68
64
  };
69
65
  },
70
66
  };
@@ -15,9 +15,7 @@ import type {
15
15
  *
16
16
  * @param options - `token` (access token) + `from` (phone number id)
17
17
  */
18
- export function openWaCloudChannel(
19
- options: ChannelOpenOptions = {},
20
- ): ChannelDriver {
18
+ export function openWaCloudChannel(options: ChannelOpenOptions = {}): ChannelDriver {
21
19
  const token = options.token ?? options.apiKey;
22
20
  const phoneNumberId = options.from;
23
21
  const fetchFn = options.fetch ?? globalThis.fetch;
@@ -67,9 +65,7 @@ export function openWaCloudChannel(
67
65
  ok: true,
68
66
  messageId: id,
69
67
  driverId: "wa-cloud",
70
- attempts: [
71
- { driverId: "wa-cloud", ok: true, at: Date.now(), messageId: id },
72
- ],
68
+ attempts: [{ driverId: "wa-cloud", ok: true, at: Date.now(), messageId: id }],
73
69
  };
74
70
  },
75
71
  };
@@ -47,9 +47,7 @@ function b64urlEncode(bytes: Uint8Array): string {
47
47
  *
48
48
  * @param privateKeyB64 - Base64url private key
49
49
  */
50
- async function importVapidPrivateKey(
51
- privateKeyB64: string,
52
- ): Promise<CryptoKey> {
50
+ async function importVapidPrivateKey(privateKeyB64: string): Promise<CryptoKey> {
53
51
  const raw = b64urlDecode(privateKeyB64);
54
52
  // Prefer PKCS8; fall back to raw JWK construction for 32-byte seeds.
55
53
  if (raw.length > 32) {
@@ -64,11 +62,10 @@ async function importVapidPrivateKey(
64
62
  // Build a minimal JWK from d (and a synthetic public x/y via derive is hard);
65
63
  // tests inject fetch and only need Authorization header shape — use ECDSA
66
64
  // with a generated key when raw seed is provided without full PKCS8.
67
- const pair = await crypto.subtle.generateKey(
68
- { name: "ECDSA", namedCurve: "P-256" },
69
- true,
70
- ["sign", "verify"],
71
- );
65
+ const pair = await crypto.subtle.generateKey({ name: "ECDSA", namedCurve: "P-256" }, true, [
66
+ "sign",
67
+ "verify",
68
+ ]);
72
69
  return pair.privateKey;
73
70
  }
74
71
 
@@ -89,17 +86,11 @@ async function buildVapidJwt(
89
86
  );
90
87
  const exp = Math.floor(Date.now() / 1000) + 12 * 60 * 60;
91
88
  const payload = b64urlEncode(
92
- new TextEncoder().encode(
93
- JSON.stringify({ aud: audience, exp, sub: subject }),
94
- ),
89
+ new TextEncoder().encode(JSON.stringify({ aud: audience, exp, sub: subject })),
95
90
  );
96
91
  const data = new TextEncoder().encode(`${header}.${payload}`);
97
92
  const sig = new Uint8Array(
98
- await crypto.subtle.sign(
99
- { name: "ECDSA", hash: "SHA-256" },
100
- privateKey,
101
- data,
102
- ),
93
+ await crypto.subtle.sign({ name: "ECDSA", hash: "SHA-256" }, privateKey, data),
103
94
  );
104
95
  // Convert DER → raw r||s if needed; Web Crypto in Bun returns raw P-1363.
105
96
  return `${header}.${payload}.${b64urlEncode(sig)}`;
@@ -127,29 +118,19 @@ async function encryptPushBody(
127
118
  true,
128
119
  [],
129
120
  );
130
- const local = await crypto.subtle.generateKey(
131
- { name: "ECDH", namedCurve: "P-256" },
132
- true,
133
- ["deriveBits"],
134
- );
121
+ const local = await crypto.subtle.generateKey({ name: "ECDH", namedCurve: "P-256" }, true, [
122
+ "deriveBits",
123
+ ]);
135
124
  const shared = new Uint8Array(
136
- await crypto.subtle.deriveBits(
137
- { name: "ECDH", public: userPublic },
138
- local.privateKey,
139
- 256,
140
- ),
125
+ await crypto.subtle.deriveBits({ name: "ECDH", public: userPublic }, local.privateKey, 256),
141
126
  );
142
127
  const salt = crypto.getRandomValues(new Uint8Array(16));
143
128
  const authSecret = b64urlDecode(auth);
144
129
 
145
130
  // HKDF-SHA-256 as in RFC 8291
146
- const ikmKey = await crypto.subtle.importKey(
147
- "raw",
148
- asBufferSource(shared),
149
- "HKDF",
150
- false,
151
- ["deriveBits"],
152
- );
131
+ const ikmKey = await crypto.subtle.importKey("raw", asBufferSource(shared), "HKDF", false, [
132
+ "deriveBits",
133
+ ]);
153
134
  const prk = new Uint8Array(
154
135
  await crypto.subtle.deriveBits(
155
136
  {
@@ -163,9 +144,7 @@ async function encryptPushBody(
163
144
  ),
164
145
  );
165
146
  // Simplified content encryption key / nonce derivation for aes128gcm
166
- const prkKey = await crypto.subtle.importKey("raw", prk, "HKDF", false, [
167
- "deriveBits",
168
- ]);
147
+ const prkKey = await crypto.subtle.importKey("raw", prk, "HKDF", false, ["deriveBits"]);
169
148
  const cek = new Uint8Array(
170
149
  await crypto.subtle.deriveBits(
171
150
  {
@@ -190,13 +169,7 @@ async function encryptPushBody(
190
169
  96,
191
170
  ),
192
171
  );
193
- const aes = await crypto.subtle.importKey(
194
- "raw",
195
- cek,
196
- { name: "AES-GCM" },
197
- false,
198
- ["encrypt"],
199
- );
172
+ const aes = await crypto.subtle.importKey("raw", cek, { name: "AES-GCM" }, false, ["encrypt"]);
200
173
  // Add RFC 8188 padding delimiter (0x02) then encrypt
201
174
  const padded = new Uint8Array(plaintext.length + 1);
202
175
  padded.set(plaintext, 0);
@@ -204,17 +177,13 @@ async function encryptPushBody(
204
177
  const ciphertext = new Uint8Array(
205
178
  await crypto.subtle.encrypt({ name: "AES-GCM", iv: nonce }, aes, padded),
206
179
  );
207
- const localPublic = new Uint8Array(
208
- await crypto.subtle.exportKey("raw", local.publicKey),
209
- );
180
+ const localPublic = new Uint8Array(await crypto.subtle.exportKey("raw", local.publicKey));
210
181
 
211
182
  // Body = salt (16) || rs (4) || idlen (1) || keyid || ciphertext
212
183
  const rs = new Uint8Array(4);
213
184
  new DataView(rs.buffer).setUint32(0, 4096);
214
185
  const idlen = new Uint8Array([localPublic.length]);
215
- const body = new Uint8Array(
216
- 16 + 4 + 1 + localPublic.length + ciphertext.length,
217
- );
186
+ const body = new Uint8Array(16 + 4 + 1 + localPublic.length + ciphertext.length);
218
187
  body.set(salt, 0);
219
188
  body.set(rs, 16);
220
189
  body.set(idlen, 20);
@@ -228,9 +197,7 @@ async function encryptPushBody(
228
197
  *
229
198
  * @param options - VAPID keys + subject
230
199
  */
231
- export function openWebPushChannel(
232
- options: ChannelOpenOptions = {},
233
- ): ChannelDriver {
200
+ export function openWebPushChannel(options: ChannelOpenOptions = {}): ChannelDriver {
234
201
  const vapidPublic = options.vapidPublicKey;
235
202
  const vapidPrivate = options.vapidPrivateKey;
236
203
  const subject = options.vapidSubject ?? "mailto:ops@oke.local";
@@ -263,11 +230,7 @@ export function openWebPushChannel(
263
230
  };
264
231
 
265
232
  if (sub?.keys?.p256dh && sub.keys.auth) {
266
- const enc = await encryptPushBody(
267
- plaintext,
268
- sub.keys.p256dh,
269
- sub.keys.auth,
270
- );
233
+ const enc = await encryptPushBody(plaintext, sub.keys.p256dh, sub.keys.auth);
271
234
  body = enc.body;
272
235
  headers["Content-Encoding"] = "aes128gcm";
273
236
  headers["Content-Type"] = "application/octet-stream";
@@ -300,9 +263,7 @@ export function openWebPushChannel(
300
263
  ok: true,
301
264
  messageId: id,
302
265
  driverId: "webpush",
303
- attempts: [
304
- { driverId: "webpush", ok: true, at: Date.now(), messageId: id },
305
- ],
266
+ attempts: [{ driverId: "webpush", ok: true, at: Date.now(), messageId: id }],
306
267
  };
307
268
  },
308
269
  };