okengine 0.18.4 → 0.19.0

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 (512) hide show
  1. package/AGENTS.md +18 -10
  2. package/README.md +2 -2
  3. package/package.json +51 -50
  4. package/site/content/docs/ai/index.mdx +25 -6
  5. package/site/content/docs/ai/llms-txt.mdx +1 -1
  6. package/site/content/docs/ai/meta.json +1 -1
  7. package/site/content/docs/ai/skills.mdx +4 -1
  8. package/site/content/docs/ai/try-it.mdx +58 -0
  9. package/site/content/docs/client/auth.mdx +208 -0
  10. package/site/content/docs/client/calling.mdx +451 -0
  11. package/site/content/docs/client/index.mdx +209 -0
  12. package/site/content/docs/client/live.mdx +234 -0
  13. package/site/content/docs/client/meta.json +5 -0
  14. package/site/content/docs/client/react.mdx +249 -0
  15. package/site/content/docs/elements/ai/agents.mdx +232 -0
  16. package/site/content/docs/elements/ai/index.mdx +341 -0
  17. package/site/content/docs/elements/ai/mcp.mdx +275 -0
  18. package/site/content/docs/elements/ai/meta.json +5 -0
  19. package/site/content/docs/elements/ai/models.mdx +283 -0
  20. package/site/content/docs/elements/ai/prompts.mdx +256 -0
  21. package/site/content/docs/elements/channel/email.mdx +266 -0
  22. package/site/content/docs/elements/channel/index.mdx +344 -0
  23. package/site/content/docs/elements/channel/meta.json +5 -0
  24. package/site/content/docs/elements/channel/push.mdx +218 -0
  25. package/site/content/docs/elements/channel/receipts.mdx +206 -0
  26. package/site/content/docs/elements/channel/sms.mdx +264 -0
  27. package/site/content/docs/elements/channel/whatsapp.mdx +220 -0
  28. package/site/content/docs/elements/clock/index.mdx +300 -0
  29. package/site/content/docs/elements/clock/meta.json +5 -0
  30. package/site/content/docs/elements/clock/schedules.mdx +508 -0
  31. package/site/content/docs/elements/clock/sleep.mdx +445 -0
  32. package/site/content/docs/elements/flow/consumers.mdx +707 -0
  33. package/site/content/docs/elements/flow/http.mdx +1080 -0
  34. package/site/content/docs/elements/flow/index.mdx +618 -0
  35. package/site/content/docs/elements/flow/meta.json +5 -0
  36. package/site/content/docs/elements/flow/routing.mdx +559 -0
  37. package/site/content/docs/elements/flow/workflows.mdx +640 -0
  38. package/site/content/docs/elements/gate/auth.mdx +371 -0
  39. package/site/content/docs/elements/gate/authorization.mdx +298 -0
  40. package/site/content/docs/elements/gate/index.mdx +418 -0
  41. package/site/content/docs/elements/gate/meta.json +5 -0
  42. package/site/content/docs/elements/gate/rate-limits.mdx +365 -0
  43. package/site/content/docs/elements/gate/rls.mdx +303 -0
  44. package/site/content/docs/elements/gate/tenancy.mdx +372 -0
  45. package/site/content/docs/elements/index.mdx +52 -11
  46. package/site/content/docs/elements/signal/broadcast.mdx +517 -0
  47. package/site/content/docs/elements/signal/index.mdx +352 -0
  48. package/site/content/docs/elements/signal/live.mdx +590 -0
  49. package/site/content/docs/elements/signal/meta.json +5 -0
  50. package/site/content/docs/elements/signal/once.mdx +596 -0
  51. package/site/content/docs/elements/store/files.mdx +659 -0
  52. package/site/content/docs/elements/store/index.mdx +310 -0
  53. package/site/content/docs/elements/store/kv.mdx +629 -0
  54. package/site/content/docs/elements/store/meta.json +5 -0
  55. package/site/content/docs/elements/store/search.mdx +946 -0
  56. package/site/content/docs/elements/store/sql.mdx +937 -0
  57. package/site/content/docs/elements/vault/config.mdx +256 -0
  58. package/site/content/docs/elements/vault/index.mdx +356 -0
  59. package/site/content/docs/elements/vault/meta.json +5 -0
  60. package/site/content/docs/elements/vault/rotation.mdx +273 -0
  61. package/site/content/docs/elements/vault/secrets.mdx +285 -0
  62. package/site/content/docs/index.mdx +78 -30
  63. package/site/content/docs/meta.json +11 -8
  64. package/site/content/docs/plugins/cors.mdx +2 -1
  65. package/site/content/docs/plugins/csrf.mdx +4 -1
  66. package/site/content/docs/plugins/headers.mdx +2 -1
  67. package/site/content/docs/plugins/ip-allowlist.mdx +2 -1
  68. package/site/content/docs/plugins/magic-link.mdx +6 -0
  69. package/site/content/docs/plugins/maintenance-mode.mdx +2 -1
  70. package/site/content/docs/plugins/oauth.mdx +1 -1
  71. package/site/content/docs/plugins/otp.mdx +12 -1
  72. package/site/content/docs/plugins/passkey.mdx +39 -15
  73. package/site/content/docs/plugins/two-factor.mdx +91 -34
  74. package/site/content/docs/plugins/username.mdx +1 -1
  75. package/site/content/docs/recipes/caddy.mdx +3 -3
  76. package/site/content/docs/recipes/index.mdx +18 -28
  77. package/site/content/docs/recipes/mailpit.mdx +1 -1
  78. package/site/content/docs/recipes/meilisearch.mdx +3 -3
  79. package/site/content/docs/recipes/meta.json +1 -4
  80. package/site/content/docs/recipes/nginx.mdx +2 -2
  81. package/site/content/docs/recipes/openrouter.mdx +283 -0
  82. package/site/content/docs/recipes/pgdog.mdx +3 -3
  83. package/site/content/docs/recipes/postgres.mdx +1 -2
  84. package/site/content/docs/recipes/rustfs.mdx +2 -2
  85. package/site/content/docs/recipes/traefik.mdx +3 -3
  86. package/site/content/docs/reference/cli.mdx +231 -0
  87. package/site/content/docs/reference/configuration.mdx +30 -10
  88. package/site/content/docs/reference/environment-variables.mdx +93 -20
  89. package/site/content/docs/reference/errors.mdx +132 -29
  90. package/site/content/docs/reference/fx.mdx +137 -73
  91. package/site/content/docs/reference/index.mdx +13 -21
  92. package/site/content/docs/reference/meta.json +4 -5
  93. package/site/content/docs/reference/okid.mdx +42 -17
  94. package/site/content/docs/reference/plugins.mdx +4 -3
  95. package/site/content/docs/reference/security.mdx +197 -0
  96. package/site/content/docs/understand/meta.json +5 -0
  97. package/site/content/docs/understand/the-anatomy.mdx +132 -0
  98. package/site/content/docs/understand/the-model.mdx +32 -0
  99. package/site/content/docs/understand/the-problem.mdx +74 -0
  100. package/site/content/docs/understand/the-vocabulary.mdx +26 -0
  101. package/src/auth/api-keys.ts +2 -1
  102. package/src/auth/bindings.ts +64 -16
  103. package/src/auth/gate-auth.test.ts +6 -1
  104. package/src/auth/identity.ts +152 -5
  105. package/src/auth/index.ts +29 -0
  106. package/src/auth/invites.ts +2 -1
  107. package/src/auth/method-context.ts +41 -0
  108. package/src/auth/oauth-as/crypto.ts +2 -1
  109. package/src/auth/oauth-as/stores.ts +2 -1
  110. package/src/auth/operator.ts +2 -1
  111. package/src/auth/sessions-jwt.test.ts +77 -0
  112. package/src/auth/sessions.ts +20 -4
  113. package/src/auth/tenants.ts +3 -2
  114. package/src/auth/two-factor-challenge.test.ts +61 -0
  115. package/src/auth/two-factor-challenge.ts +284 -0
  116. package/src/auth/verification.ts +5 -0
  117. package/src/bench/REPORT.md +49 -0
  118. package/src/bench/g03-signal-once.bench.ts +1 -1
  119. package/src/bench/g10-observability-contention.bench.ts +1 -1
  120. package/src/bench/g17-hybrid-search.bench.ts +572 -0
  121. package/src/bench/load-app.ts +2 -10
  122. package/src/cli/ai-setup/ai-setup.test.ts +331 -42
  123. package/src/cli/ai-setup/apply.ts +294 -52
  124. package/src/cli/ai-setup/catalog.ts +238 -1342
  125. package/src/cli/ai-setup/index.ts +14 -99
  126. package/src/cli/ai-setup/prompts.ts +60 -443
  127. package/src/cli/ask-seed.test.ts +96 -0
  128. package/src/cli/ask-seed.ts +82 -0
  129. package/src/cli/ask-vault-gaps.test.ts +84 -0
  130. package/src/cli/ask-vault-gaps.ts +146 -0
  131. package/src/cli/build.ts +2 -2
  132. package/src/cli/client-add.test.ts +26 -1
  133. package/src/cli/client-add.ts +106 -27
  134. package/src/cli/competitor-mention-removal.test.ts +1 -1
  135. package/src/cli/db-seed.ts +2 -0
  136. package/src/cli/db.ts +150 -11
  137. package/src/cli/dev.ts +119 -211
  138. package/src/cli/docker-clean.ts +2 -2
  139. package/src/cli/docker-cli.test.ts +1 -1
  140. package/src/cli/doctor-diff.ts +4 -2
  141. package/src/cli/doctor-pii.test.ts +1 -1
  142. package/src/cli/doctor.ts +14 -1
  143. package/src/cli/hero-meta.test.ts +4 -2
  144. package/src/cli/load-config.images.test.ts +8 -10
  145. package/src/cli/load-config.ts +1 -1
  146. package/src/cli/registry.ts +22 -10
  147. package/src/cli/replay.ts +3 -1
  148. package/src/cli/start.ts +1 -1
  149. package/src/cli/tui/keys.ts +2 -3
  150. package/src/client/auth/cookies.ts +74 -0
  151. package/src/client/auth/create-auth-client.ts +636 -0
  152. package/src/client/auth/denials.ts +99 -0
  153. package/src/client/auth/session.ts +283 -0
  154. package/src/client/auth.test.ts +251 -0
  155. package/src/client/auth.ts +39 -114
  156. package/src/client/create-with-session.ts +245 -0
  157. package/src/client/create.ts +51 -5
  158. package/src/client/index.ts +11 -1
  159. package/src/client/live.ts +11 -79
  160. package/src/client/notes-contract.test.ts +5 -10
  161. package/src/client/sse.ts +137 -0
  162. package/src/client/stream.ts +147 -0
  163. package/src/client/transport.test.ts +32 -0
  164. package/src/client/transport.ts +123 -26
  165. package/src/client/types.ts +118 -14
  166. package/src/client-react/index.ts +185 -24
  167. package/src/client-react/use-live-query.ts +13 -3
  168. package/src/compiler/aot.test.ts +7 -4
  169. package/src/compiler/effects-embed.test.ts +56 -0
  170. package/src/compiler/effects-fetch.test.ts +43 -0
  171. package/src/compiler/effects-infer.ts +58 -2
  172. package/src/compiler/extract.test.ts +258 -44
  173. package/src/compiler/extract.ts +566 -48
  174. package/src/compiler/fixtures/skyport/src/flows/bookings/index.ts +7 -4
  175. package/src/compiler/fixtures/skyport/src/flows/bookings/signals.ts +2 -8
  176. package/src/compiler/fixtures/skyport.expected.json +4 -4
  177. package/src/compiler/fixtures/triggers/five-triggers.ts +14 -10
  178. package/src/compiler/response.ts +2 -2
  179. package/src/compiler/search-writer-isolation.test.ts +40 -0
  180. package/src/config/index.ts +11 -0
  181. package/src/console/server/app.ts +17 -23
  182. package/src/console/server/bind.ts +4 -0
  183. package/src/console/server/console.test.ts +2 -2
  184. package/src/console/server/flows-invoke.test.ts +50 -34
  185. package/src/console/server/flows.ts +436 -255
  186. package/src/console/server/runs-ingest.test.ts +6 -3
  187. package/src/console/server/serve.ts +1 -1
  188. package/src/console/server/signals.test.ts +1 -5
  189. package/src/console/server/signals.ts +8 -6
  190. package/src/console/server/state.ts +6 -1
  191. package/src/console/server/store.ts +1 -1
  192. package/src/console/ui-next/dist/assets/FileExportIcon-Ck-5od4R.js +1 -0
  193. package/src/console/ui-next/dist/assets/MoreHorizontalCircle01Icon-gMNGsE37.js +1 -0
  194. package/src/console/ui-next/dist/assets/PlusSignIcon-CwG3nxfu.js +1 -0
  195. package/src/console/ui-next/dist/assets/UnavailableIcon-D9cvHVPr.js +1 -0
  196. package/src/console/ui-next/dist/assets/UserIcon-DaE2PB5_.js +1 -0
  197. package/src/console/ui-next/dist/assets/access-page-DFeymU07.js +4 -0
  198. package/src/console/ui-next/dist/assets/agent-disclosure-U1rdfblp.js +1 -0
  199. package/src/console/ui-next/dist/assets/cache-glyph-BeFJeqBG.js +1 -0
  200. package/src/console/ui-next/dist/assets/call-pii-button-CVAONPii.js +1 -0
  201. package/src/console/ui-next/dist/assets/collapsible-D2A6NJ-3.js +1 -0
  202. package/src/console/ui-next/dist/assets/copy-inline-button-CAYD18cr.js +1 -0
  203. package/src/console/ui-next/dist/assets/dagre.esm-B1_XeuLP.js +1 -0
  204. package/src/console/ui-next/dist/assets/detail-header-DVWNjWjg.js +1 -0
  205. package/src/console/ui-next/dist/assets/dropdown-menu-4h2LOVXM.js +1 -0
  206. package/src/console/ui-next/dist/assets/duration-tone-Cgk_h5ja.js +9 -0
  207. package/src/console/ui-next/dist/assets/element-icons-BI8cJgdh.js +1 -0
  208. package/src/console/ui-next/dist/assets/explorer-empty-CJs5A-wm.js +1 -0
  209. package/src/console/ui-next/dist/assets/flows-page-Dss7941e.js +1 -0
  210. package/src/console/ui-next/dist/assets/highlighted-json-MYZQtRnw.js +154 -0
  211. package/src/console/ui-next/dist/assets/http-method-Jrh39p7A.js +1 -0
  212. package/src/console/ui-next/dist/assets/index-D0zS5rKO.css +2 -0
  213. package/src/console/ui-next/dist/assets/index-DXP2dBIF.js +63 -0
  214. package/src/console/ui-next/dist/assets/observability-page-HvolXxTI.js +4 -0
  215. package/src/console/ui-next/dist/assets/react-dom-Ddte4I-Q.js +9 -0
  216. package/src/console/ui-next/dist/assets/replica-lag-CSh2dzrb.js +18 -0
  217. package/src/console/ui-next/dist/assets/request-meta-BatF8KrK.js +1 -0
  218. package/src/console/ui-next/dist/assets/shortcut-keys-3ILd8oGn.js +1 -0
  219. package/src/console/ui-next/dist/assets/{sql-BskegiFM.js → sql-BsFa4tDR.js} +1 -1
  220. package/src/console/ui-next/dist/assets/store-page-eiKiHnNe.js +41 -0
  221. package/src/console/ui-next/dist/assets/trace-detail-sheet-CZkMeKS-.js +2 -0
  222. package/src/console/ui-next/dist/assets/tree-expand-toggle-CW8y5A2h.js +55 -0
  223. package/src/console/ui-next/dist/assets/units-page-B_RWJrEO.js +1 -0
  224. package/src/console/ui-next/dist/assets/{use-vault-list-uk4WVboC.js → use-vault-list-CT4-gajj.js} +1 -1
  225. package/src/console/ui-next/dist/assets/vault-page-CWrg-A68.js +2 -0
  226. package/src/console/ui-next/dist/assets/xyflow-CSyC6ryz.css +1 -0
  227. package/src/console/ui-next/dist/assets/xyflow-yApv7D4e.js +7 -0
  228. package/src/console/ui-next/dist/index.html +6 -13
  229. package/src/console/ui-next/seed-invoke-host.ts +21 -18
  230. package/src/console/ui-next/src/client.ts +7 -2
  231. package/src/console/ui-next/src/features/flows/graph/element-map.ts +2 -0
  232. package/src/console/ui-next/src/features/flows/traces/effect-kind.ts +12 -2
  233. package/src/console/ui-next/src/features/flows/traces/effect-summary.ts +4 -0
  234. package/src/console/ui-next/src/features/flows/traces/trace-detail-sheet.tsx +8 -0
  235. package/src/console/ui-next/src/features/flows/traces/waterfall-bars.ts +4 -0
  236. package/src/console/ui-next/src/features/flows/traces/waterfall-tooltip.ts +9 -3
  237. package/src/console/ui-next/src/features/store/detail/reveal-cell.tsx +7 -11
  238. package/src/console/ui-next/src/features/store/detail/store-row-detail-sheet.tsx +2 -2
  239. package/src/console/ui-next/src/features/store/lib/fields-from-table.ts +2 -0
  240. package/src/console/ui-next/src/features/store/lib/grid-model.test.ts +25 -1
  241. package/src/console/ui-next/src/features/store/lib/grid-model.ts +36 -1
  242. package/src/console/ui-next/src/features/store/query/query-results.tsx +3 -3
  243. package/src/console/ui-next/src/features/units/detail/effects-summary.tsx +2 -0
  244. package/src/console/ui-next/src/features/units/lib/call-read-safe.ts +3 -1
  245. package/src/console/ui-next/src/features/units/lib/fields-from-schema.ts +6 -0
  246. package/src/docker/ai-model-status.test.ts +1 -12
  247. package/src/docker/ai-model-status.ts +10 -38
  248. package/src/docker/compose-up.test.ts +100 -0
  249. package/src/docker/compose-up.ts +292 -0
  250. package/src/docker/compose.ts +4 -14
  251. package/src/docker/derive.ts +9 -34
  252. package/src/docker/docker.test.ts +16 -261
  253. package/src/docker/images-config.test.ts +13 -25
  254. package/src/docker/index.ts +1 -24
  255. package/src/docker/recipes/index.ts +0 -23
  256. package/src/docker/recipes/pgdog.ts +6 -4
  257. package/src/docker/stack-id.test.ts +2 -2
  258. package/src/docker/stack-id.ts +0 -1
  259. package/src/docker/types.ts +2 -2
  260. package/src/drivers/ai-anthropic.ts +10 -0
  261. package/src/drivers/ai-openai-compatible.ts +34 -7
  262. package/src/drivers/ai-providers.test.ts +0 -107
  263. package/src/drivers/ai-stream.test.ts +0 -34
  264. package/src/drivers/ai-types.ts +17 -8
  265. package/src/drivers/channel-fcm.ts +6 -1
  266. package/src/drivers/channel-msegat.ts +6 -1
  267. package/src/drivers/channel-resend.ts +5 -1
  268. package/src/drivers/channel-smtp.ts +5 -1
  269. package/src/drivers/channel-sndr.ts +10 -1
  270. package/src/drivers/channel-taqnyat-mail.ts +5 -1
  271. package/src/drivers/channel-taqnyat-whatsapp.ts +6 -1
  272. package/src/drivers/channel-taqnyat.ts +6 -1
  273. package/src/drivers/channel-types.ts +10 -0
  274. package/src/drivers/channel-unifonic.ts +6 -1
  275. package/src/drivers/channel-wa-cloud.ts +6 -1
  276. package/src/drivers/channel-webpush.ts +6 -1
  277. package/src/drivers/external.ts +33 -0
  278. package/src/drivers/index.ts +0 -10
  279. package/src/drivers/meilisearch.ts +6 -0
  280. package/src/drivers/oauth-types.ts +4 -0
  281. package/src/drivers/postgres.test.ts +74 -3
  282. package/src/drivers/postgres.ts +175 -6
  283. package/src/drivers/signal-types.ts +5 -5
  284. package/src/drivers/types.ts +7 -0
  285. package/src/drivers/vault-types.ts +5 -0
  286. package/src/elements/ai/declare.ts +17 -4
  287. package/src/elements/ai/eval.ts +1 -1
  288. package/src/elements/ai/mcp-http.ts +1 -1
  289. package/src/elements/ai/pii.ts +1 -1
  290. package/src/elements/ai/providers.test.ts +289 -0
  291. package/src/elements/ai/providers.ts +169 -0
  292. package/src/elements/ai/runtime.ts +68 -5
  293. package/src/elements/ai/schema.ts +2 -2
  294. package/src/elements/ai.test.ts +7 -7
  295. package/src/elements/ai.ts +17 -1
  296. package/src/elements/channel/runtime.ts +105 -12
  297. package/src/elements/clock/cron-fields.test.ts +144 -0
  298. package/src/elements/clock/cron-fields.ts +185 -0
  299. package/src/elements/clock/declare.ts +247 -3
  300. package/src/elements/clock.ts +21 -1
  301. package/src/elements/index.ts +15 -0
  302. package/src/elements/signal/chaos-child.ts +1 -2
  303. package/src/elements/signal/declare.ts +65 -37
  304. package/src/elements/signal/delivery-modes.test.ts +11 -31
  305. package/src/elements/signal/dry-run-replay.test.ts +1 -7
  306. package/src/elements/signal/dry-run-write-isolation.test.ts +1 -7
  307. package/src/elements/signal/key-ordering.test.ts +6 -26
  308. package/src/elements/signal/lease-reclaim.test.ts +2 -6
  309. package/src/elements/signal/optional-emit.test.ts +6 -9
  310. package/src/elements/signal/order-lifecycle.test.ts +4 -17
  311. package/src/elements/signal/orphan-messages.test.ts +4 -15
  312. package/src/elements/signal/reconcile.test.ts +2 -2
  313. package/src/elements/signal/runtime.ts +1 -1
  314. package/src/elements/signal/schema-emit.test.ts +4 -8
  315. package/src/elements/signal.test.ts +24 -49
  316. package/src/elements/signal.ts +9 -2
  317. package/src/elements/store/domain-ddl.test.ts +1 -1
  318. package/src/elements/store/live-http.test.ts +9 -4
  319. package/src/elements/store/prepare-row.test.ts +123 -0
  320. package/src/elements/store/resource.ts +43 -12
  321. package/src/elements/store/schema-decl.ts +117 -0
  322. package/src/elements/store/search-backfill.ts +205 -0
  323. package/src/elements/store/search-bind.ts +66 -0
  324. package/src/elements/store/search-bm25.ts +78 -0
  325. package/src/elements/store/search-ddl.ts +156 -0
  326. package/src/elements/store/search-embed-flow.ts +141 -0
  327. package/src/elements/store/search-errors.ts +34 -0
  328. package/src/elements/store/search-fusion.ts +112 -0
  329. package/src/elements/store/search-lsh.ts +179 -0
  330. package/src/elements/store/search-runtime.ts +300 -0
  331. package/src/elements/store/search.test.ts +144 -0
  332. package/src/elements/store/sql-session.test.ts +1 -0
  333. package/src/elements/store/sql-session.ts +83 -3
  334. package/src/elements/store/table.ts +23 -2
  335. package/src/elements/store/upsert-app.test.ts +1 -3
  336. package/src/elements/store.ts +50 -0
  337. package/src/full.ts +4 -2
  338. package/src/http.ts +4 -1
  339. package/src/i18n/catalogs/ar.ts +14 -6
  340. package/src/i18n/catalogs/en.ts +14 -6
  341. package/src/index.ts +6 -1
  342. package/src/kernel/adopt-barrel-fresh.test.ts +7 -7
  343. package/src/kernel/adopt-routes.ts +9 -1
  344. package/src/kernel/app-auth.ts +5 -0
  345. package/src/kernel/app.ts +102 -9
  346. package/src/kernel/auto-cache.test.ts +6 -12
  347. package/src/kernel/auto-registry.test.ts +3 -3
  348. package/src/kernel/boot-bind/ai.test.ts +22 -19
  349. package/src/kernel/boot-bind/ai.ts +5 -43
  350. package/src/kernel/boot-bind/clock.ts +23 -5
  351. package/src/kernel/boot-bind/honor-config.test.ts +4 -4
  352. package/src/kernel/boot.test.ts +11 -6
  353. package/src/kernel/boot.ts +66 -16
  354. package/src/kernel/boundary-contract.ts +93 -0
  355. package/src/kernel/budget.test.ts +1 -1
  356. package/src/kernel/call.ts +89 -0
  357. package/src/kernel/capability.ts +6 -0
  358. package/src/kernel/client-descriptor.ts +123 -0
  359. package/src/kernel/clock-timezone.test.ts +80 -0
  360. package/src/kernel/correlation.test.ts +1 -1
  361. package/src/kernel/dry-run.ts +11 -8
  362. package/src/kernel/effects-stamping.test.ts +42 -9
  363. package/src/kernel/effects.test.ts +4 -2
  364. package/src/kernel/effects.ts +51 -9
  365. package/src/kernel/errors-channel.ts +17 -0
  366. package/src/kernel/errors-live-resume.ts +3 -2
  367. package/src/kernel/errors-tenant.ts +7 -4
  368. package/src/kernel/errors.registry-helpers.ts +96 -0
  369. package/src/kernel/errors.registry.test.ts +139 -25
  370. package/src/kernel/errors.ts +102 -23
  371. package/src/kernel/external-effects.test.ts +196 -0
  372. package/src/kernel/flow.test.ts +13 -4
  373. package/src/kernel/flow.ts +69 -71
  374. package/src/kernel/fx-ask-telemetry.test.ts +2 -2
  375. package/src/kernel/fx-dead-letters.test.ts +3 -3
  376. package/src/kernel/fx-fetch.ts +55 -0
  377. package/src/kernel/fx-live-stream.ts +2 -2
  378. package/src/kernel/fx-live.test.ts +8 -8
  379. package/src/kernel/fx.test.ts +17 -11
  380. package/src/kernel/fx.ts +180 -57
  381. package/src/kernel/horizontal-child.ts +1 -1
  382. package/src/kernel/http-query.test.ts +3 -6
  383. package/src/kernel/index.ts +13 -3
  384. package/src/kernel/instance-id.ts +1 -1
  385. package/src/kernel/instances.test.ts +40 -0
  386. package/src/kernel/instances.ts +47 -9
  387. package/src/kernel/live-http.test.ts +6 -7
  388. package/src/kernel/live-http.ts +6 -2
  389. package/src/kernel/live-resume.test.ts +1 -1
  390. package/src/kernel/mcp-tool.test.ts +3 -3
  391. package/src/kernel/on.ts +98 -4
  392. package/src/kernel/pipeline.test.ts +12 -15
  393. package/src/kernel/plugin-elements.test.ts +1 -1
  394. package/src/kernel/stamp-http.test.ts +3 -3
  395. package/src/kernel/triggers.ts +210 -95
  396. package/src/kernel-entry.ts +0 -1
  397. package/src/manifest/diff.ts +11 -1
  398. package/src/manifest/fixtures/skyport.excerpt.json +1 -1
  399. package/src/manifest/types.ts +46 -2
  400. package/src/mcp/docs-index.ts +3 -3
  401. package/src/mcp/docs-mcp.test.ts +2 -2
  402. package/src/mcp/docs-tools.ts +1 -1
  403. package/src/okid.test.ts +56 -0
  404. package/src/okid.ts +55 -11
  405. package/src/plugins/anonymous.ts +8 -4
  406. package/src/plugins/auth/shared.ts +27 -3
  407. package/src/plugins/auth-delivery.mailpit.integration.test.ts +1 -1
  408. package/src/plugins/auth-methods.security.test.ts +561 -23
  409. package/src/plugins/config-source.ts +1 -1
  410. package/src/plugins/csrf.test.ts +65 -0
  411. package/src/plugins/index.ts +2 -0
  412. package/src/plugins/magic-link.ts +36 -16
  413. package/src/plugins/oauth/shared.ts +3 -1
  414. package/src/plugins/oauth.ts +22 -14
  415. package/src/plugins/otp.ts +37 -21
  416. package/src/plugins/passkey-webauthn.ts +9 -6
  417. package/src/plugins/passkey.ts +98 -26
  418. package/src/plugins/pre-account-hijack.test.ts +223 -0
  419. package/src/plugins/two-factor.ts +466 -37
  420. package/src/plugins/username.ts +19 -7
  421. package/src/release/build-lib.ts +1 -0
  422. package/src/release/limits.ts +2 -2
  423. package/src/release/measure.ts +1 -1
  424. package/src/runs/collect.test.ts +0 -2
  425. package/src/runtime/json-code-block.test.ts +250 -20
  426. package/src/runtime/json-code-block.ts +1261 -41
  427. package/src/term.test.ts +1 -1
  428. package/src/test/create-test-app.test.ts +12 -12
  429. package/src/test/live-signals.test.ts +6 -6
  430. package/src/test/provisions.integration.test.ts +10 -14
  431. package/src/test/reset-element-registries.ts +1 -1
  432. package/src/test/tenant-isolation.test.ts +12 -6
  433. package/site/content/docs/deployment/docker-swarm.mdx +0 -164
  434. package/site/content/docs/deployment/docker.mdx +0 -227
  435. package/site/content/docs/deployment/index.mdx +0 -83
  436. package/site/content/docs/deployment/kubernetes.mdx +0 -176
  437. package/site/content/docs/deployment/meta.json +0 -5
  438. package/site/content/docs/deployment/reverse-proxy.mdx +0 -234
  439. package/site/content/docs/elements/ai.mdx +0 -385
  440. package/site/content/docs/elements/channel.mdx +0 -346
  441. package/site/content/docs/elements/clock.mdx +0 -244
  442. package/site/content/docs/elements/flow.mdx +0 -420
  443. package/site/content/docs/elements/gate.mdx +0 -436
  444. package/site/content/docs/elements/signal.mdx +0 -380
  445. package/site/content/docs/elements/store.mdx +0 -1099
  446. package/site/content/docs/elements/vault.mdx +0 -405
  447. package/site/content/docs/get-started/basic-usage.mdx +0 -173
  448. package/site/content/docs/get-started/index.mdx +0 -43
  449. package/site/content/docs/get-started/installation.mdx +0 -220
  450. package/site/content/docs/get-started/introduction.mdx +0 -132
  451. package/site/content/docs/get-started/meta.json +0 -13
  452. package/site/content/docs/get-started/project-structure.mdx +0 -925
  453. package/site/content/docs/get-started/testing.mdx +0 -328
  454. package/site/content/docs/get-started/why.mdx +0 -162
  455. package/site/content/docs/recipes/llama-cpp.mdx +0 -151
  456. package/site/content/docs/recipes/ollama.mdx +0 -142
  457. package/site/content/docs/recipes/sglang.mdx +0 -105
  458. package/site/content/docs/recipes/vllm.mdx +0 -106
  459. package/site/content/docs/reference/cli.md +0 -232
  460. package/site/content/docs/reference/client.mdx +0 -469
  461. package/site/content/docs/reference/security.md +0 -74
  462. package/src/cli/ai-setup/detect-ollama.ts +0 -213
  463. package/src/cli/ai-setup/recommend.test.ts +0 -225
  464. package/src/cli/ai-setup/recommend.ts +0 -225
  465. package/src/cli/dev-controls.test.ts +0 -122
  466. package/src/cli/dev-controls.ts +0 -164
  467. package/src/cli/tui/DevLive.tsx +0 -126
  468. package/src/console/ui-next/dist/assets/access-page-De7Lc2JC.js +0 -4
  469. package/src/console/ui-next/dist/assets/agent-disclosure-BP0Y0Sux.js +0 -1
  470. package/src/console/ui-next/dist/assets/cache-glyph-B5X-NM0-.js +0 -1
  471. package/src/console/ui-next/dist/assets/call-pii-button-ChAUiLo9.js +0 -1
  472. package/src/console/ui-next/dist/assets/collapsible-DGnOM2ph.js +0 -1
  473. package/src/console/ui-next/dist/assets/copy-inline-button-DBHhgHKP.js +0 -1
  474. package/src/console/ui-next/dist/assets/dagre.esm-ZwcdTuZZ.js +0 -1
  475. package/src/console/ui-next/dist/assets/detail-header-DhHM1iaZ.js +0 -1
  476. package/src/console/ui-next/dist/assets/dropdown-menu-_NjTEo5_.js +0 -1
  477. package/src/console/ui-next/dist/assets/duration-tone-sC3lGABz.js +0 -9
  478. package/src/console/ui-next/dist/assets/element-icons-BVXtRyd3.js +0 -1
  479. package/src/console/ui-next/dist/assets/explorer-empty-2uIhBu0_.js +0 -1
  480. package/src/console/ui-next/dist/assets/flows-page-RGy7VEA_.js +0 -1
  481. package/src/console/ui-next/dist/assets/highlighted-json-Awq7gYdu.js +0 -154
  482. package/src/console/ui-next/dist/assets/http-method-_UHM2ODJ.js +0 -1
  483. package/src/console/ui-next/dist/assets/index-Ck88Jmv8.css +0 -2
  484. package/src/console/ui-next/dist/assets/index-_rgpdVzo.js +0 -66
  485. package/src/console/ui-next/dist/assets/link-BX6Vqztd.js +0 -1
  486. package/src/console/ui-next/dist/assets/observability-page-Ds6pcnh-.js +0 -4
  487. package/src/console/ui-next/dist/assets/preload-helper-oH4irX4C.js +0 -1
  488. package/src/console/ui-next/dist/assets/react-D8E3mtu1.js +0 -1
  489. package/src/console/ui-next/dist/assets/react-dom-Bph1y7z7.js +0 -9
  490. package/src/console/ui-next/dist/assets/replica-lag-DKRrbvdo.js +0 -18
  491. package/src/console/ui-next/dist/assets/request-meta-DV0ywz7t.js +0 -1
  492. package/src/console/ui-next/dist/assets/shortcut-JQIZlWfm.js +0 -1
  493. package/src/console/ui-next/dist/assets/shortcut-keys-DKxNTe_m.js +0 -1
  494. package/src/console/ui-next/dist/assets/skeleton-D-czQJT6.js +0 -1
  495. package/src/console/ui-next/dist/assets/store-page-02xOiqIK.js +0 -41
  496. package/src/console/ui-next/dist/assets/trace-detail-sheet-B09O8rA6.js +0 -2
  497. package/src/console/ui-next/dist/assets/tree-expand-toggle-BtyhmWb4.js +0 -55
  498. package/src/console/ui-next/dist/assets/units-page-4rHOePuE.js +0 -1
  499. package/src/console/ui-next/dist/assets/useMutation-B8EO02Ej.js +0 -1
  500. package/src/console/ui-next/dist/assets/useRender-BE2A9BWC.js +0 -1
  501. package/src/console/ui-next/dist/assets/vault-page-DISPgxLM.js +0 -2
  502. package/src/console/ui-next/dist/assets/xyflow-D7n4g6go.js +0 -7
  503. package/src/console/ui-next/dist/assets/xyflow-DZ0Ws1xk.css +0 -1
  504. package/src/docker/ollama-pull.ts +0 -232
  505. package/src/docker/recipes/llama-cpp.ts +0 -298
  506. package/src/docker/recipes/ollama.ts +0 -44
  507. package/src/docker/recipes/sglang.ts +0 -55
  508. package/src/docker/recipes/vllm.ts +0 -44
  509. package/src/drivers/ai-ollama-tools.integration.test.ts +0 -109
  510. package/src/drivers/ai-ollama.integration.test.ts +0 -184
  511. package/src/drivers/ai-ollama.ts +0 -389
  512. package/src/drivers/ollama.ts +0 -14
package/src/term.test.ts CHANGED
@@ -50,7 +50,7 @@ describe("term", () => {
50
50
  { element: "flow", detail: "", status: "ready" },
51
51
  { element: "store", detail: "sql postgres · kv redis", status: "ready" },
52
52
  { element: "signal", detail: "memory", status: "ready" },
53
- { element: "ai", detail: "openai-compatible · granite3.3:2b", status: "pending" },
53
+ { element: "ai", detail: "openai-compatible · openrouter/free", status: "pending" },
54
54
  ],
55
55
  });
56
56
  expect(out).toContain("oke dev v0.2.4");
@@ -12,7 +12,7 @@ import { vault, VaultBootError } from "../elements/vault.ts";
12
12
  import { oke } from "../kernel/app.ts";
13
13
  import { flow, resetFlowSeq } from "../kernel/flow.ts";
14
14
  import { on, resetBindings } from "../kernel/on.ts";
15
- import { every, http } from "../kernel/triggers.ts";
15
+ import { http } from "../kernel/triggers.ts";
16
16
  import { createTestApp } from "./create-test-app.ts";
17
17
 
18
18
  describe("createTestApp — four-applications surface", () => {
@@ -21,11 +21,7 @@ describe("createTestApp — four-applications surface", () => {
21
21
  resetFlowSeq();
22
22
 
23
23
  const member = gate.policy("member", ({ auth }) => !!auth.verified);
24
- const orderPlaced = signal("order-placed", {
25
- delivery: "once",
26
- retries: 2,
27
- deadLetter: true,
28
- });
24
+ const orderPlaced = signal.once("order-placed", { retries: 2, deadLetter: true });
29
25
  const mail = channel.email({ from: "test@oke.dev" });
30
26
  const orderConfirmed = mail.template("order-confirmed", {
31
27
  schema: z.object({
@@ -36,10 +32,13 @@ describe("createTestApp — four-applications surface", () => {
36
32
  });
37
33
 
38
34
  on(
39
- http.post("/orders").gate(member),
35
+ http
36
+ .post("/orders", {
37
+ in: z.object({ sku: z.string(), qty: z.number() }),
38
+ out: z.object({ id: z.string() }),
39
+ })
40
+ .gate(member),
40
41
  flow("orders.create", {
41
- in: z.object({ sku: z.string(), qty: z.number() }),
42
- out: z.object({ id: z.string() }),
43
42
  effects: { emits: ["order-placed"] },
44
43
  do: async (input, fx) => {
45
44
  const id = fx.id();
@@ -62,8 +61,9 @@ describe("createTestApp — four-applications surface", () => {
62
61
  }),
63
62
  );
64
63
 
64
+ const expireStale = clock("expire-stale", { every: "1h" });
65
65
  on(
66
- every("1h"),
66
+ expireStale,
67
67
  flow("orders.expire", {
68
68
  do: (_i, fx) => {
69
69
  fx.log.info("expire");
@@ -75,7 +75,7 @@ describe("createTestApp — four-applications surface", () => {
75
75
  name: "harness",
76
76
  gate: { policies: [member] },
77
77
  signals: [orderPlaced],
78
- clocks: [clock("expire-stale", { every: "1h" })],
78
+ clocks: [expireStale],
79
79
  channel: { templates: [orderConfirmed] },
80
80
  env: "test",
81
81
  });
@@ -84,7 +84,7 @@ describe("createTestApp — four-applications surface", () => {
84
84
  gates: [member],
85
85
  signals: [orderPlaced],
86
86
  boot: {
87
- clocks: [clock("expire-stale", { every: "1h" })],
87
+ clocks: [expireStale],
88
88
  channel: { templates: [orderConfirmed] },
89
89
  },
90
90
  });
@@ -17,15 +17,15 @@ describe("createTestApp live-signal subscriptions", () => {
17
17
  resetBindings();
18
18
  resetFlowSeq();
19
19
 
20
- const orderStatus = signal("order-status", {
21
- delivery: "live",
22
- retention: { maxCount: 10 },
23
- });
20
+ const orderStatus = signal.live("order-status", { retention: { maxCount: 10 } });
24
21
 
25
22
  on(
26
- http.post("/orders/status").public(),
23
+ http
24
+ .post("/orders/status", {
25
+ in: z.object({ orderId: z.string(), status: z.string() }),
26
+ })
27
+ .public(),
27
28
  flow("orders.updateStatus", {
28
- in: z.object({ orderId: z.string(), status: z.string() }),
29
29
  effects: { emits: ["order-status"] },
30
30
  do: async (input, fx) => {
31
31
  await fx.emit(orderStatus, input);
@@ -11,6 +11,7 @@ import { gate } from "../elements/gate.ts";
11
11
  import { signal } from "../elements/signal.ts";
12
12
  import { vault } from "../elements/vault.ts";
13
13
  import { oke } from "../kernel/app.ts";
14
+ import { call } from "../kernel/call.ts";
14
15
  import { flow, resetFlowSeq } from "../kernel/flow.ts";
15
16
  import { on, resetBindings } from "../kernel/on.ts";
16
17
  import { http } from "../kernel/triggers.ts";
@@ -28,16 +29,8 @@ describe("Provisions integration", () => {
28
29
  dev: "sk_test_local",
29
30
  });
30
31
 
31
- const orderPlaced = signal("order-placed", {
32
- delivery: "once",
33
- retries: 3,
34
- deadLetter: true,
35
- });
36
- const orderNews = signal("order-news", {
37
- delivery: "once",
38
- retries: 3,
39
- deadLetter: true,
40
- });
32
+ const orderPlaced = signal.once("order-placed", { retries: 3, deadLetter: true });
33
+ const orderNews = signal.once("order-news", { retries: 3, deadLetter: true });
41
34
 
42
35
  const mail = channel.email({ from: "Provisions <no-reply@provisions.sa>" });
43
36
  const orderConfirmed = mail.template("order-confirmed", {
@@ -48,7 +41,7 @@ describe("Provisions integration", () => {
48
41
  }),
49
42
  });
50
43
 
51
- const chargeOrder = flow("payments.chargeOrder", {
44
+ const chargeOrder = call("payments.chargeOrder", {
52
45
  durable: true,
53
46
  in: z.object({ orderId: z.string() }),
54
47
  out: z.boolean(),
@@ -67,10 +60,13 @@ describe("Provisions integration", () => {
67
60
  });
68
61
 
69
62
  on(
70
- http.post("/orders").gate(member, canOrder),
63
+ http
64
+ .post("/orders", {
65
+ in: z.object({ sku: z.string(), qty: z.number() }),
66
+ out: z.object({ id: z.string() }),
67
+ })
68
+ .gate(member, canOrder),
71
69
  flow("orders.create", {
72
- in: z.object({ sku: z.string(), qty: z.number() }),
73
- out: z.object({ id: z.string() }),
74
70
  effects: { emits: ["order-placed"], calls: ["payments.chargeOrder"] },
75
71
  do: async (input, fx) => {
76
72
  const id = fx.id();
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Global safety net for the `store.*` / `vault.secret` / `signal()` /
2
+ * Global safety net for the `store.*` / `vault.secret` / `signal.*` /
3
3
  * `clock()` / `gate.policy`·scope·rate / `channel.<medium>().template()` /
4
4
  * `ai.model`·prompt·embed·agent auto-registries
5
5
  * (`src/kernel/element-registries.ts`).
@@ -39,10 +39,13 @@ describe("createTestApp tenancy testing & RLS isolation", () => {
39
39
  const docStore = store.sql("docs", { schema: { documents } });
40
40
 
41
41
  on(
42
- http.post("/docs").gate(memberGate),
42
+ http
43
+ .post("/docs", {
44
+ in: z.object({ title: z.string() }),
45
+ out: z.object({ id: z.string(), tenantId: z.string().nullable() }),
46
+ })
47
+ .gate(memberGate),
43
48
  flow("docs.create", {
44
- in: z.object({ title: z.string() }),
45
- out: z.object({ id: z.string(), tenantId: z.string().nullable() }),
46
49
  effects: { writes: ["sql:docs"], reads: ["sql:docs"] },
47
50
  do: async (input, fx) => {
48
51
  const id = fx.id();
@@ -57,10 +60,13 @@ describe("createTestApp tenancy testing & RLS isolation", () => {
57
60
  );
58
61
 
59
62
  on(
60
- http.get("/docs").gate(memberGate),
63
+ http
64
+ .get("/docs", {
65
+ in: z.void(),
66
+ out: z.array(z.object({ id: z.string(), title: z.string() })),
67
+ })
68
+ .gate(memberGate),
61
69
  flow("docs.list", {
62
- in: z.void(),
63
- out: z.array(z.object({ id: z.string(), title: z.string() })),
64
70
  effects: { reads: ["sql:docs"] },
65
71
  do: async (_input, fx) => {
66
72
  const rows = await fx.store(docStore).select().from(documents);
@@ -1,164 +0,0 @@
1
- ---
2
- title: Docker Swarm
3
- description: Deploy with docker stack deploy — docker-stack.yml, PgDog, HEALTHCHECK readiness, graceful SIGTERM, known multi-instance limits, and optional Caddy, Traefik, or nginx.
4
- icon: Ship
5
- source: README.md
6
- ---
7
-
8
- Swarm consumes the stack file `oke docker --stack` writes. It adds built-in
9
- orchestration (scale, rolling updates, routing mesh) with a lower learning
10
- curve than Kubernetes. Scale replaceable replicas; share durable drivers.
11
-
12
- <Callout title="The one rule">
13
- Deploy with `docker stack deploy`. Docker’s single `HEALTHCHECK` targets `GET /_/ready`. Treat
14
- every task as replaceable — shared Postgres / Redis / S3, SIGTERM via `stop_grace_period`, honest
15
- Signal/Channel process-local limits.
16
- </Callout>
17
-
18
- ## Quick start
19
-
20
- <Steps>
21
-
22
- <Step>
23
- ### Derive the Swarm stack file
24
-
25
- ```bash
26
- oke docker --stack
27
- ```
28
-
29
- Emits `Dockerfile` + **`docker-stack.yml`** (overlay network, `HEALTHCHECK` →
30
- `/_/ready`, `deploy.*`, `stop_grace_period: 30s`, resource limits from the
31
- default **4 CPU / 8 GiB** budget — override with `--cpus` / `--memory`).
32
-
33
- Prefer `--stack` over composing many `-c` files. The default `oke docker`
34
- (single `docker-compose.yml`) stays for plain Compose hosts.
35
-
36
- </Step>
37
-
38
- <Step>
39
- ### Build the app image, init Swarm, deploy
40
-
41
- `docker stack deploy` ignores `build` — tag first (name matches the stack file).
42
-
43
- ```bash
44
- docker build -t oke-<app>:latest -f docker/Dockerfile .
45
- docker swarm init
46
- cd docker
47
- docker stack deploy -c docker-stack.yml myapp
48
- ```
49
-
50
- Create `secrets:` names via `docker secret create` when you use secret refs,
51
- or keep credentials in `.env.local` for single-node labs.
52
-
53
- </Step>
54
-
55
- <Step>
56
- ### Scale and roll
57
-
58
- ```bash
59
- docker service scale myapp_app=3
60
- docker service update --image oke-<app>:latest myapp_app
61
- ```
62
-
63
- Prod deploy block: `update_config` (`parallelism: 1`, `order: start-first`,
64
- `failure_action: rollback`) and `restart_policy.condition: on-failure`.
65
-
66
- </Step>
67
-
68
- </Steps>
69
-
70
- ## Share backing services
71
-
72
- Pin `dev`/`prod` drivers to shared stores:
73
-
74
- | Concern | Driver | Shared backend |
75
- | ----------------------------- | ---------------------------- | ------------------------------------------------- |
76
- | SQL / durable journal / clock | `postgres` | Postgres (optionally via PgDog) |
77
- | Gate rate counters | `redis` (`drivers.store.kv`) | Redis / Valkey / Dragonfly (`images["store.kv"]`) |
78
- | Files | `s3` | S3-compatible object store |
79
- | Signal | see known limits below | — |
80
-
81
- ## PgDog pooling
82
-
83
- Bun.SQL defaults to **10** connections per process — fine for one replica.
84
- Scale the Swarm service and `N × pool` can exceed Postgres `max_connections`.
85
-
86
- When both `store.sql` and `pgdog` are pinned (`dev`/`prod` template default),
87
- `DATABASE_URL` points at PgDog `:6432` — transaction pooling, wire-transparent.
88
- Configs: `docker/pgdog/pgdog.toml` + `docker/pgdog/users.toml`.
89
-
90
- **Why PgDog.** Transaction pooling fixes the connection math. Naive poolers can
91
- leak session state (`SET`, RLS vars, `LISTEN`/`NOTIFY`) across clients; PgDog
92
- re-applies those under transaction mode.
93
-
94
- Read-replica routing (`BEGIN READ ONLY` → replica) is documented readiness —
95
- not configured in the generated stack yet.
96
-
97
- ## Redis-protocol images (Redis · Valkey · Dragonfly)
98
-
99
- `images["store.kv"]` defaults to Redis (most mature). Pin Valkey or Dragonfly
100
- the same way — driver id stays `redis`, same `REDIS_URL`. Image table + one-line
101
- licenses: [Store · KV](/docs/elements/store#kv).
102
-
103
- ## Readiness and liveness
104
-
105
- | Endpoint | Role | On Swarm |
106
- | -------------- | ------------------------------------------------------ | ----------------------------------------------------- |
107
- | `GET /_/ready` | Kernel readiness (`booting` → `orphan_scan` → `ready`) | Single Docker `HEALTHCHECK` — routing mesh waits here |
108
- | `GET /health` | App liveness | External monitors only |
109
-
110
- ## Graceful shutdown
111
-
112
- `stop_grace_period: 30s` gives `installGracefulShutdown` time to release Clock /
113
- Journal leases before the task is killed. Signal message leases reclaim after
114
- visibility TTL on survivors.
115
-
116
- ## Reverse proxy
117
-
118
- Same opt-in `images.proxy` pins as plain Compose — Caddy, Traefik, or nginx. Re-run
119
- `oke docker --stack` after pinning. Details:
120
- [Reverse proxy](/docs/deployment/reverse-proxy).
121
-
122
- ## Known multi-instance limits
123
-
124
- Same table as [Docker](/docs/deployment/docker#known-multi-instance-limits) —
125
- Clock / Journal / Gate redis / Store shared; Signal consume and Channel consent
126
- stores stay process-local until durable drivers ship.
127
-
128
- ## Troubleshooting
129
-
130
- <Accordions>
131
- <Accordion title="stack deploy ignores build">
132
-
133
- Build and tag `oke-<app>:latest` first (`docker build -f docker/Dockerfile .`).
134
- Swarm never runs Compose `build:`.
135
-
136
- </Accordion>
137
- <Accordion title="New task gets traffic before orphan scan finishes">
138
-
139
- Confirm `HEALTHCHECK` targets `/_/ready` in `docker-stack.yml`. Without it,
140
- Swarm treats “container started” as ready.
141
-
142
- </Accordion>
143
- <Accordion title="Overlay networking / multi-node volumes">
144
-
145
- Multi-node needs shared Postgres / Redis / S3 — do not rely on local named
146
- volumes for durable state across nodes.
147
-
148
- </Accordion>
149
- </Accordions>
150
-
151
- ## Learn more
152
-
153
- - [Docker](/docs/deployment/docker) — plain compose default
154
- - [Reverse proxy](/docs/deployment/reverse-proxy) — Caddy / Traefik / nginx
155
- - [Kubernetes](/docs/deployment/kubernetes) — Deployment, probes, Ingress
156
- - [CLI](/docs/reference/cli) — `oke docker --stack`
157
-
158
- ## Next
159
-
160
- <Cards>
161
- <Card title="Docker" href="/docs/deployment/docker" />
162
- <Card title="Reverse proxy" href="/docs/deployment/reverse-proxy" />
163
- <Card title="Kubernetes" href="/docs/deployment/kubernetes" />
164
- </Cards>
@@ -1,227 +0,0 @@
1
- ---
2
- title: Docker
3
- description: Deploy with plain docker compose — single production-grade docker-compose.yml, shared drivers, PgDog, readiness, graceful SIGTERM, and opt-in Caddy, Traefik, or nginx when you need an edge without an orchestrator.
4
- icon: Package
5
- source: README.md
6
- ---
7
-
8
- Plain `docker compose` is the simplest production shape: single or few app
9
- instances on one host (or a small set you manage yourself). Derive with
10
- `oke docker`; opt into a proxy only when you need HTTPS at the edge.
11
-
12
- <Callout title="The one rule">
13
- Treat every app container as replaceable. Put durable state in Postgres / Redis / S3, wait on `GET
14
- /_/ready`, give SIGTERM time to release leases, and leave `images.proxy` unset until you need TLS
15
- or `--scale app=N`.
16
- </Callout>
17
-
18
- ## Quick start
19
-
20
- <Steps>
21
-
22
- <Step>
23
- ### Derive compose
24
-
25
- ```bash
26
- oke docker
27
- ```
28
-
29
- Writes `Dockerfile` + production-grade **`docker-compose.yml`** under `docker/`
30
- (readiness HEALTHCHECK on `/_/ready`, deploy policy, resource limits).
31
- Default host budget is **4 CPU / 8 GiB** — override with `--cpus` / `--memory`.
32
-
33
- Other layouts when you ask for them:
34
-
35
- | Flag | Output |
36
- | ----------- | --------------------------------------------------------- |
37
- | _(default)_ | `docker-compose.yml` |
38
- | `--split` | `compose.yml` + `compose.<role>.yml` + `compose.prod.yml` |
39
- | `--stack` | `docker-stack.yml` for Swarm (`docker stack deploy -c`) |
40
-
41
- Without a proxy, the app still publishes port `6530`.
42
-
43
- </Step>
44
-
45
- <Step>
46
- ### Share backing services
47
-
48
- Pin `dev`/`prod` drivers to shared stores (create-oke templates already do —
49
- same protocols locally via `oke dev` and in production):
50
-
51
- | Concern | Driver | Shared backend |
52
- | ----------------------------- | ---------------------------- | ---------------------------------------------- |
53
- | SQL / durable journal / clock | `postgres` | Postgres (optionally via PgDog) |
54
- | Gate rate counters | `redis` (`drivers.store.kv`) | Redis / Valkey / Dragonfly (`images.store.kv`) |
55
- | Files | `s3` | S3-compatible object store |
56
- | Signal | see known limits below | — |
57
-
58
- <Callout>
59
- The monorepo `examples/keel` app is the work-management Compose fixture — `bun run dev:keel`, then
60
- `oke db seed` (Harbor GA story + ~500 tasks). Wipe with `bun run dev:keel:reset` (stops leftover
61
- ports, fresh `.env.local`).
62
- </Callout>
63
-
64
- </Step>
65
-
66
- <Step>
67
- ### Bring the stack up
68
-
69
- ```bash
70
- cd docker
71
- docker compose -f docker-compose.yml up -d
72
- ```
73
-
74
- Add `-f docker-compose.override.yml` if you keep local tweaks (oke never writes
75
- that file). With `--split`, pass every `-f` file `oke docker` prints.
76
-
77
- </Step>
78
-
79
- </Steps>
80
-
81
- ## PgDog pooling
82
-
83
- Bun.SQL defaults to **10** connections per process — fine for one instance.
84
- Scale out and `N × pool` can exceed Postgres `max_connections`.
85
-
86
- When both `store.sql` and `pgdog` are pinned (templates' `dev`/`prod` default),
87
- `DATABASE_URL` points at PgDog `:6432` — transaction pooling, wire-transparent.
88
- Configs: `docker/pgdog/pgdog.toml` + `docker/pgdog/users.toml`.
89
-
90
- **Why PgDog.** Transaction pooling fixes the connection math. Naive poolers can
91
- leak session state (`SET`, RLS vars, `LISTEN`/`NOTIFY`) across clients; PgDog
92
- re-applies those under transaction mode.
93
-
94
- Read-replica routing (`BEGIN READ ONLY` → replica) is documented readiness —
95
- not configured in the generated stack yet.
96
-
97
- ## Redis-protocol images (Redis · Valkey · Dragonfly)
98
-
99
- `images["store.kv"]` defaults to Redis (most mature). Pin Valkey or Dragonfly
100
- the same way — driver id stays `redis`, same `REDIS_URL`. Image table + one-line
101
- licenses: [Store · KV](/docs/elements/store#kv).
102
-
103
- ## Readiness and liveness
104
-
105
- | Endpoint | Role | On plain compose |
106
- | -------------- | ----------------------------------------------------------- | ---------------------------------------------------- |
107
- | `GET /_/ready` | Kernel readiness (`booting` → `orphan_scan` → `ready`) | HEALTHCHECK in `docker-compose.yml`; LBs should wait |
108
- | `GET /health` | App liveness (create-oke ships one) — cheap “process alive” | External monitors only — not orphan-scan aware |
109
-
110
- `/_/ready` returns `200 { ready: true }` only after boot and the durable orphan
111
- scan finish. While booting or scanning it returns
112
- `503 { ready: false, reason: "booting" | "orphan_scan" }`.
113
-
114
- **Consequence:** orphan scan delays “healthy” (and traffic) on purpose so a
115
- new replica is not hit mid-takeover.
116
-
117
- ## Graceful shutdown
118
-
119
- On `SIGTERM` / `SIGINT`, `installGracefulShutdown` (wired by `oke dev`’s app
120
- runner; call it next to `createBunRuntime().serve` in custom entries):
121
-
122
- 1. Stops accepting new connections
123
- 2. Releases **Clock** cron leases and **Journal** run leases held by this instance
124
- 3. Closes element runtimes and exits
125
-
126
- Signal message leases have no proactive release today — survivors reclaim after
127
- the visibility TTL (default 30s). Generated compose sets `stop_grace_period: 30s`
128
- so the release path can finish (≥ typical Clock / Journal / Signal lease TTL).
129
-
130
- ## Reverse proxy
131
-
132
- Omit `images.proxy` until you need HTTPS or horizontal scale without fighting a
133
- host port bind. Then pick one:
134
-
135
- | Choice | Best for | How routing works |
136
- | ------------------------------- | ----------------------------------------- | ------------------------------------------------------------------ |
137
- | **Caddy** (`caddy:2-alpine`) | Single instance, simplest automatic HTTPS | Generated `Caddyfile` → `reverse_proxy app:6530` |
138
- | **Traefik** (`traefik:v3.7`) | `docker compose up --scale app=N` | Docker labels on `app`; replicas auto-discovered and load-balanced |
139
- | **nginx** (`nginx:1.31-alpine`) | Static HTTP edge; TLS elsewhere | Generated `nginx.conf` → `proxy_pass` to `app:6530` on `:80` |
140
-
141
- ```typescript title="oke.config.ts"
142
- images: {
143
- // …
144
- proxy: "caddy:2-alpine", // or "traefik:v3.7" / "nginx:1.31-alpine"
145
- },
146
- ```
147
-
148
- `create-oke` asks **Add a reverse proxy…?** (or `--proxy caddy|traefik|nginx|none`).
149
-
150
- ```bash title=".env.local"
151
- OKE_PROXY_HOST=app.example.com
152
- OKE_PROXY_ACME_EMAIL=admin@example.com
153
- ```
154
-
155
- Re-run `oke docker`. Edge publishes `80`/`443`; `app` stays internal.
156
- Set `allowedHosts` to your public hostname ([Security](/docs/reference/security)).
157
-
158
- Traefik never mounts raw `docker.sock` — only a filtered
159
- `tecnativa/docker-socket-proxy` on the internal network. Full custom-domain,
160
- Let's Encrypt, and socket-proxy rationale → [Reverse proxy](/docs/deployment/reverse-proxy).
161
-
162
- ## Known multi-instance limits
163
-
164
- | Surface | Multi-instance today |
165
- | ---------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
166
- | Clock (`postgres` / shared `file`) | Shared leader election |
167
- | Journal (`postgres` / shared `file`) | Shared durable runs + orphan resume |
168
- | Gate rates (`drivers.store.kv: redis`) | Shared counters |
169
- | Store SQL / KV redis / files `s3` | Shared |
170
- | Store files `fs` | **Per-instance filesystem** — boot warns; use `s3` when scaled |
171
- | Signal `redis` | Emit relays to Redis; **consume / `live` / `drain` are process-local outbox** until Streams consume ships |
172
- | Channel suppression / consent / receipts | **Default stores are process-local** — opt-out on replica A is invisible to B until a durable driver ships |
173
-
174
- ## Troubleshooting
175
-
176
- <Accordions>
177
- <Accordion title="compose up --scale app=N fails with port already allocated">
178
-
179
- You still have `6530:6530` on `app`. Confirm `images.proxy` is set and
180
- re-derived so the host bind was omitted.
181
-
182
- </Accordion>
183
- <Accordion title="New replica gets traffic before orphan scan finishes">
184
-
185
- Confirm the healthcheck hits `/_/ready` (default `oke docker` output). Without
186
- it, compose treats “container started” as ready. Pass `--no-prod` only when you
187
- intentionally want a bare derive.
188
-
189
- </Accordion>
190
- <Accordion title="Rate limits look twice as high after scaling to 2">
191
-
192
- `drivers.store.kv` must be `redis` with `REDIS_URL` set. A missing URL **fails
193
- boot** (no silent memory fallback). Declaring `memory` for local is fine;
194
- `dev`/`prod` should stay on redis.
195
-
196
- </Accordion>
197
- <Accordion title="Files uploaded on instance A are missing on B">
198
-
199
- `drivers.store.files: "fs"` is single-host. Switch `dev`/`prod` to `s3`
200
- (create-oke templates already do).
201
-
202
- </Accordion>
203
- <Accordion title="Host header rejected (403)">
204
-
205
- Serve validates `Host`. Add your public hostname to `allowedHosts`
206
- ([Security](/docs/reference/security)).
207
-
208
- </Accordion>
209
- </Accordions>
210
-
211
- ## Learn more
212
-
213
- - [Deployment](/docs/deployment) — choose compose, Swarm, or Kubernetes
214
- - [Reverse proxy](/docs/deployment/reverse-proxy) — Caddy / Traefik / nginx in full
215
- - [Docker Swarm](/docs/deployment/docker-swarm) — `docker stack deploy`
216
- - [Kubernetes](/docs/deployment/kubernetes) — Deployment, probes, Ingress
217
- - [CLI](/docs/reference/cli) — `oke docker`, layouts, budget flags
218
- - [Store](/docs/elements/store) — PgDog and facets
219
- - [Security](/docs/reference/security) — `allowedHosts`
220
-
221
- ## Next
222
-
223
- <Cards>
224
- <Card title="Deployment" href="/docs/deployment" />
225
- <Card title="Reverse proxy" href="/docs/deployment/reverse-proxy" />
226
- <Card title="Docker Swarm" href="/docs/deployment/docker-swarm" />
227
- </Cards>
@@ -1,83 +0,0 @@
1
- ---
2
- title: Deployment
3
- description: Choose plain docker compose, Docker Swarm, or Kubernetes — then follow that path's complete page for PgDog, probes, graceful shutdown, and TLS.
4
- icon: Server
5
- source: README.md
6
- ---
7
-
8
- OKE apps are process-stateless when shared drivers back Store, Clock, Journal,
9
- and Gate. Pick an orchestrator (or none) first; each path page below is
10
- self-contained after you choose.
11
-
12
- <Callout title="The one rule">
13
- Decide the deploy shape here, then open **one** path page and follow it end to end. Do not mix
14
- recipes across pages — Docker proxy compose ≠ Kubernetes Ingress.
15
- </Callout>
16
-
17
- ## Which path?
18
-
19
- | Path | Best for | Trade-off |
20
- | --------------------------------------------- | -------------------------------------------- | ---------------------------------------------------- |
21
- | [Docker](/docs/deployment/docker) (compose) | Simplest — single or few instances | You run scale / restart / TLS yourself (or opt in) |
22
- | [Docker Swarm](/docs/deployment/docker-swarm) | Built-in orchestration, lower learning curve | Smaller ecosystem than Kubernetes; mesh ≠ certs |
23
- | [Kubernetes](/docs/deployment/kubernetes) | Full orchestration, largest ecosystem | Highest operational surface (Ingress, probes, RBAC…) |
24
-
25
- **Consequence:** start with plain compose until you need Swarm's service mesh /
26
- rolling updates or Kubernetes' cluster ecosystem. Same multi-instance contract
27
- on every path — shared Postgres/Redis/S3, not sticky pod identity.
28
-
29
- ## Capabilities (every path)
30
-
31
- These already ship. Each path page explains them in full in that page's words:
32
-
33
- | Capability | What it guarantees | Deep dive |
34
- | --------------------------------- | --------------------------------------------------------------------------------------- | ------------------------------------------------ |
35
- | **PgDog pooling** | `dev`/`prod` SQL goes through transaction pooler (`DATABASE_URL` → `:6432`) when pinned | Path pages · [Store](/docs/elements/store) |
36
- | **Graceful SIGTERM** | `installGracefulShutdown` releases Clock + Journal leases, then drains | Path pages |
37
- | **Readiness vs liveness** | `GET /_/ready` (kernel) vs app `GET /health` | Path pages |
38
- | **Horizontal proof** | Two-process integration test against live Postgres + Redis | Changelog / CI (`OKE_TEST_POSTGRES_URL` + Redis) |
39
- | **Reverse proxy (compose/Swarm)** | Opt-in Caddy, Traefik, or nginx (`images.proxy`) | [Reverse proxy](/docs/deployment/reverse-proxy) |
40
- | **Ingress (Kubernetes)** | Cluster-native Ingress / Gateway API | [Kubernetes](/docs/deployment/kubernetes) |
41
-
42
- Honesty notes (Signal consume / Channel suppression still process-local) live
43
- on each path page — not papered over here.
44
-
45
- ## Pick a path
46
-
47
- <Cards>
48
- <Card
49
- title="Docker"
50
- description="Plain compose — simplest single or few-instance deploy."
51
- href="/docs/deployment/docker"
52
- />
53
- <Card
54
- title="Docker Swarm"
55
- description="stack deploy on the generated compose layers."
56
- href="/docs/deployment/docker-swarm"
57
- />
58
- <Card
59
- title="Kubernetes"
60
- description="Deployment, probes, shared drivers, Ingress."
61
- href="/docs/deployment/kubernetes"
62
- />
63
- <Card
64
- title="Reverse proxy"
65
- description="Caddy / Traefik / nginx — TLS, domains, socket-proxy why."
66
- href="/docs/deployment/reverse-proxy"
67
- />
68
- </Cards>
69
-
70
- ## Learn more
71
-
72
- - [Installation](/docs/get-started/installation) — scaffold and `oke dev`
73
- - [CLI](/docs/reference/cli) — `oke docker --prod`, `oke start`
74
- - [Configuration](/docs/reference/configuration) — `images` and drivers
75
- - [Store](/docs/elements/store) — PgDog and facets
76
-
77
- ## Next
78
-
79
- <Cards>
80
- <Card title="Docker" href="/docs/deployment/docker" />
81
- <Card title="Docker Swarm" href="/docs/deployment/docker-swarm" />
82
- <Card title="Kubernetes" href="/docs/deployment/kubernetes" />
83
- </Cards>