okengine 0.18.5 → 0.19.1

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/llms-txt.mdx +1 -1
  5. package/site/content/docs/ai/skills.mdx +4 -1
  6. package/site/content/docs/client/auth.mdx +208 -0
  7. package/site/content/docs/client/calling.mdx +451 -0
  8. package/site/content/docs/client/index.mdx +208 -0
  9. package/site/content/docs/client/live.mdx +234 -0
  10. package/site/content/docs/client/meta.json +5 -0
  11. package/site/content/docs/client/react.mdx +249 -0
  12. package/site/content/docs/elements/ai/agents.mdx +235 -0
  13. package/site/content/docs/elements/ai/index.mdx +342 -0
  14. package/site/content/docs/elements/ai/mcp.mdx +275 -0
  15. package/site/content/docs/elements/ai/meta.json +5 -0
  16. package/site/content/docs/elements/ai/models.mdx +283 -0
  17. package/site/content/docs/elements/ai/prompts.mdx +257 -0
  18. package/site/content/docs/elements/channel/email.mdx +269 -0
  19. package/site/content/docs/elements/channel/index.mdx +344 -0
  20. package/site/content/docs/elements/channel/meta.json +5 -0
  21. package/site/content/docs/elements/channel/push.mdx +218 -0
  22. package/site/content/docs/elements/channel/receipts.mdx +206 -0
  23. package/site/content/docs/elements/channel/sms.mdx +264 -0
  24. package/site/content/docs/elements/channel/whatsapp.mdx +220 -0
  25. package/site/content/docs/elements/clock/index.mdx +301 -0
  26. package/site/content/docs/elements/clock/meta.json +5 -0
  27. package/site/content/docs/elements/clock/schedules.mdx +508 -0
  28. package/site/content/docs/elements/clock/sleep.mdx +448 -0
  29. package/site/content/docs/elements/flow/consumers.mdx +707 -0
  30. package/site/content/docs/elements/flow/http.mdx +1080 -0
  31. package/site/content/docs/elements/flow/index.mdx +618 -0
  32. package/site/content/docs/elements/flow/meta.json +5 -0
  33. package/site/content/docs/elements/flow/routing.mdx +559 -0
  34. package/site/content/docs/elements/flow/workflows.mdx +640 -0
  35. package/site/content/docs/elements/gate/auth.mdx +371 -0
  36. package/site/content/docs/elements/gate/authorization.mdx +298 -0
  37. package/site/content/docs/elements/gate/index.mdx +418 -0
  38. package/site/content/docs/elements/gate/meta.json +5 -0
  39. package/site/content/docs/elements/gate/rate-limits.mdx +365 -0
  40. package/site/content/docs/elements/gate/rls.mdx +303 -0
  41. package/site/content/docs/elements/gate/tenancy.mdx +375 -0
  42. package/site/content/docs/elements/index.mdx +20 -10
  43. package/site/content/docs/elements/signal/broadcast.mdx +519 -0
  44. package/site/content/docs/elements/signal/index.mdx +352 -0
  45. package/site/content/docs/elements/signal/live.mdx +591 -0
  46. package/site/content/docs/elements/signal/meta.json +5 -0
  47. package/site/content/docs/elements/signal/once.mdx +597 -0
  48. package/site/content/docs/elements/store/files.mdx +667 -0
  49. package/site/content/docs/elements/store/index.mdx +313 -0
  50. package/site/content/docs/elements/store/kv.mdx +637 -0
  51. package/site/content/docs/elements/store/meta.json +5 -0
  52. package/site/content/docs/elements/store/search.mdx +950 -0
  53. package/site/content/docs/elements/store/sql.mdx +941 -0
  54. package/site/content/docs/elements/vault/config.mdx +259 -0
  55. package/site/content/docs/elements/vault/index.mdx +356 -0
  56. package/site/content/docs/elements/vault/meta.json +5 -0
  57. package/site/content/docs/elements/vault/rotation.mdx +276 -0
  58. package/site/content/docs/elements/vault/secrets.mdx +288 -0
  59. package/site/content/docs/index.mdx +52 -40
  60. package/site/content/docs/meta.json +8 -7
  61. package/site/content/docs/plugins/cors.mdx +2 -1
  62. package/site/content/docs/plugins/csrf.mdx +4 -1
  63. package/site/content/docs/plugins/headers.mdx +2 -1
  64. package/site/content/docs/plugins/ip-allowlist.mdx +2 -1
  65. package/site/content/docs/plugins/magic-link.mdx +6 -0
  66. package/site/content/docs/plugins/maintenance-mode.mdx +2 -1
  67. package/site/content/docs/plugins/oauth.mdx +1 -1
  68. package/site/content/docs/plugins/otp.mdx +12 -1
  69. package/site/content/docs/plugins/passkey.mdx +39 -15
  70. package/site/content/docs/plugins/two-factor.mdx +91 -34
  71. package/site/content/docs/plugins/username.mdx +1 -1
  72. package/site/content/docs/recipes/caddy.mdx +3 -3
  73. package/site/content/docs/recipes/index.mdx +18 -28
  74. package/site/content/docs/recipes/mailpit.mdx +1 -1
  75. package/site/content/docs/recipes/meilisearch.mdx +3 -3
  76. package/site/content/docs/recipes/meta.json +1 -4
  77. package/site/content/docs/recipes/nginx.mdx +2 -2
  78. package/site/content/docs/recipes/openrouter.mdx +283 -0
  79. package/site/content/docs/recipes/pgdog.mdx +3 -3
  80. package/site/content/docs/recipes/postgres.mdx +1 -2
  81. package/site/content/docs/recipes/rustfs.mdx +2 -2
  82. package/site/content/docs/recipes/traefik.mdx +3 -3
  83. package/site/content/docs/reference/cli.mdx +231 -0
  84. package/site/content/docs/reference/configuration.mdx +30 -10
  85. package/site/content/docs/reference/environment-variables.mdx +93 -20
  86. package/site/content/docs/reference/errors.mdx +132 -29
  87. package/site/content/docs/reference/fx.mdx +138 -73
  88. package/site/content/docs/reference/index.mdx +13 -21
  89. package/site/content/docs/reference/meta.json +4 -5
  90. package/site/content/docs/reference/okid.mdx +42 -17
  91. package/site/content/docs/reference/plugins.mdx +4 -3
  92. package/site/content/docs/reference/security.mdx +197 -0
  93. package/site/content/docs/understand/meta.json +5 -0
  94. package/site/content/docs/understand/the-architecture.mdx +264 -0
  95. package/site/content/docs/understand/try-it.mdx +58 -0
  96. package/src/auth/api-keys.ts +2 -1
  97. package/src/auth/bindings.ts +64 -16
  98. package/src/auth/gate-auth.test.ts +6 -1
  99. package/src/auth/identity.ts +152 -5
  100. package/src/auth/index.ts +29 -0
  101. package/src/auth/invites.ts +2 -1
  102. package/src/auth/method-context.ts +41 -0
  103. package/src/auth/oauth-as/crypto.ts +2 -1
  104. package/src/auth/oauth-as/stores.ts +2 -1
  105. package/src/auth/operator.ts +2 -1
  106. package/src/auth/sessions-jwt.test.ts +77 -0
  107. package/src/auth/sessions.ts +20 -4
  108. package/src/auth/tenants.ts +3 -2
  109. package/src/auth/two-factor-challenge.test.ts +61 -0
  110. package/src/auth/two-factor-challenge.ts +284 -0
  111. package/src/auth/verification.ts +5 -0
  112. package/src/bench/REPORT.md +80 -0
  113. package/src/bench/g03-signal-once.bench.ts +1 -1
  114. package/src/bench/g10-observability-contention.bench.ts +1 -1
  115. package/src/bench/g17-hybrid-search.bench.ts +572 -0
  116. package/src/bench/load-app.ts +2 -10
  117. package/src/cli/ai-setup/ai-setup.test.ts +331 -42
  118. package/src/cli/ai-setup/apply.ts +294 -52
  119. package/src/cli/ai-setup/catalog.ts +238 -1342
  120. package/src/cli/ai-setup/index.ts +14 -99
  121. package/src/cli/ai-setup/prompts.ts +60 -443
  122. package/src/cli/ask-seed.test.ts +96 -0
  123. package/src/cli/ask-seed.ts +82 -0
  124. package/src/cli/ask-vault-gaps.test.ts +84 -0
  125. package/src/cli/ask-vault-gaps.ts +146 -0
  126. package/src/cli/build.ts +2 -2
  127. package/src/cli/client-add.test.ts +26 -1
  128. package/src/cli/client-add.ts +106 -27
  129. package/src/cli/db-seed.ts +2 -0
  130. package/src/cli/db.ts +150 -11
  131. package/src/cli/dev.ts +119 -211
  132. package/src/cli/docker-clean.ts +2 -2
  133. package/src/cli/docker-cli.test.ts +1 -1
  134. package/src/cli/doctor-diff.ts +4 -2
  135. package/src/cli/doctor-pii.test.ts +1 -1
  136. package/src/cli/doctor.ts +14 -1
  137. package/src/cli/hero-meta.test.ts +4 -2
  138. package/src/cli/load-config.images.test.ts +8 -10
  139. package/src/cli/load-config.ts +1 -1
  140. package/src/cli/registry.ts +22 -10
  141. package/src/cli/replay.ts +3 -1
  142. package/src/cli/start.ts +1 -1
  143. package/src/cli/tui/keys.ts +2 -3
  144. package/src/client/auth/cookies.ts +74 -0
  145. package/src/client/auth/create-auth-client.ts +636 -0
  146. package/src/client/auth/denials.ts +99 -0
  147. package/src/client/auth/session.ts +283 -0
  148. package/src/client/auth.test.ts +251 -0
  149. package/src/client/auth.ts +39 -114
  150. package/src/client/create-with-session.ts +245 -0
  151. package/src/client/create.ts +51 -5
  152. package/src/client/index.ts +11 -1
  153. package/src/client/live.ts +11 -79
  154. package/src/client/notes-contract.test.ts +5 -10
  155. package/src/client/sse.ts +137 -0
  156. package/src/client/stream.ts +147 -0
  157. package/src/client/transport.test.ts +32 -0
  158. package/src/client/transport.ts +123 -26
  159. package/src/client/types.ts +118 -14
  160. package/src/client-react/index.ts +185 -24
  161. package/src/client-react/use-live-query.ts +13 -3
  162. package/src/compiler/aot.test.ts +7 -4
  163. package/src/compiler/effects-embed.test.ts +56 -0
  164. package/src/compiler/effects-fetch.test.ts +43 -0
  165. package/src/compiler/effects-infer.ts +58 -2
  166. package/src/compiler/extract.test.ts +257 -43
  167. package/src/compiler/extract.ts +566 -48
  168. package/src/compiler/fixtures/skyport/src/flows/bookings/index.ts +7 -4
  169. package/src/compiler/fixtures/skyport/src/flows/bookings/signals.ts +2 -8
  170. package/src/compiler/fixtures/skyport.expected.json +4 -4
  171. package/src/compiler/fixtures/triggers/five-triggers.ts +14 -10
  172. package/src/compiler/response.ts +2 -2
  173. package/src/compiler/search-writer-isolation.test.ts +40 -0
  174. package/src/config/index.ts +11 -0
  175. package/src/console/server/app.ts +17 -23
  176. package/src/console/server/bind.ts +4 -0
  177. package/src/console/server/console.test.ts +2 -2
  178. package/src/console/server/flows-invoke.test.ts +50 -34
  179. package/src/console/server/flows.ts +436 -255
  180. package/src/console/server/runs-ingest.test.ts +6 -3
  181. package/src/console/server/serve.ts +1 -1
  182. package/src/console/server/signals.test.ts +1 -5
  183. package/src/console/server/signals.ts +8 -6
  184. package/src/console/server/state.ts +6 -1
  185. package/src/console/server/store.ts +1 -1
  186. package/src/console/ui-next/dist/assets/FileExportIcon-Ck-5od4R.js +1 -0
  187. package/src/console/ui-next/dist/assets/MoreHorizontalCircle01Icon-gMNGsE37.js +1 -0
  188. package/src/console/ui-next/dist/assets/PlusSignIcon-CwG3nxfu.js +1 -0
  189. package/src/console/ui-next/dist/assets/UnavailableIcon-D9cvHVPr.js +1 -0
  190. package/src/console/ui-next/dist/assets/UserIcon-DaE2PB5_.js +1 -0
  191. package/src/console/ui-next/dist/assets/access-page-C_qLDhTq.js +4 -0
  192. package/src/console/ui-next/dist/assets/agent-disclosure-BHVqr3TN.js +1 -0
  193. package/src/console/ui-next/dist/assets/cache-glyph-CKe92lRQ.js +1 -0
  194. package/src/console/ui-next/dist/assets/call-pii-button-DEwTl8ZX.js +1 -0
  195. package/src/console/ui-next/dist/assets/collapsible-BCBtDrCt.js +1 -0
  196. package/src/console/ui-next/dist/assets/copy-inline-button-CAYD18cr.js +1 -0
  197. package/src/console/ui-next/dist/assets/dagre.esm-B1_XeuLP.js +1 -0
  198. package/src/console/ui-next/dist/assets/detail-header-DVWNjWjg.js +1 -0
  199. package/src/console/ui-next/dist/assets/dropdown-menu-4h2LOVXM.js +1 -0
  200. package/src/console/ui-next/dist/assets/duration-tone-JroqeuCp.js +9 -0
  201. package/src/console/ui-next/dist/assets/element-icons-BI8cJgdh.js +1 -0
  202. package/src/console/ui-next/dist/assets/explorer-empty-CJs5A-wm.js +1 -0
  203. package/src/console/ui-next/dist/assets/flows-page-CVHa0RTt.js +1 -0
  204. package/src/console/ui-next/dist/assets/highlighted-json-DjJW6hqe.js +154 -0
  205. package/src/console/ui-next/dist/assets/http-method-DC5HBdLU.js +1 -0
  206. package/src/console/ui-next/dist/assets/index-CYjiZ3WO.js +63 -0
  207. package/src/console/ui-next/dist/assets/index-D0zS5rKO.css +2 -0
  208. package/src/console/ui-next/dist/assets/observability-page-CAYMyKb3.js +4 -0
  209. package/src/console/ui-next/dist/assets/react-dom-Ddte4I-Q.js +9 -0
  210. package/src/console/ui-next/dist/assets/replica-lag-yAQYLv75.js +18 -0
  211. package/src/console/ui-next/dist/assets/request-meta-D0yusGxJ.js +1 -0
  212. package/src/console/ui-next/dist/assets/shortcut-keys-3ILd8oGn.js +1 -0
  213. package/src/console/ui-next/dist/assets/{sql-BskegiFM.js → sql-BsFa4tDR.js} +1 -1
  214. package/src/console/ui-next/dist/assets/store-page-BTKJeJ02.js +41 -0
  215. package/src/console/ui-next/dist/assets/trace-detail-sheet-Bp-Yygs5.js +2 -0
  216. package/src/console/ui-next/dist/assets/tree-expand-toggle-DoaVDfAM.js +55 -0
  217. package/src/console/ui-next/dist/assets/units-page-BRz7xyYL.js +1 -0
  218. package/src/console/ui-next/dist/assets/{use-vault-list-uk4WVboC.js → use-vault-list-CT4-gajj.js} +1 -1
  219. package/src/console/ui-next/dist/assets/vault-page-3jQt-bOJ.js +2 -0
  220. package/src/console/ui-next/dist/assets/xyflow-CSyC6ryz.css +1 -0
  221. package/src/console/ui-next/dist/assets/xyflow-yApv7D4e.js +7 -0
  222. package/src/console/ui-next/dist/index.html +6 -13
  223. package/src/console/ui-next/seed-invoke-host.ts +21 -18
  224. package/src/console/ui-next/src/client.ts +7 -2
  225. package/src/console/ui-next/src/features/flows/graph/element-map.test.ts +1 -1
  226. package/src/console/ui-next/src/features/flows/graph/element-map.ts +5 -3
  227. package/src/console/ui-next/src/features/flows/traces/effect-kind.ts +12 -2
  228. package/src/console/ui-next/src/features/flows/traces/effect-summary.ts +4 -0
  229. package/src/console/ui-next/src/features/flows/traces/trace-detail-sheet.tsx +8 -0
  230. package/src/console/ui-next/src/features/flows/traces/trace-detail.test.ts +4 -5
  231. package/src/console/ui-next/src/features/flows/traces/trace-gates.ts +3 -6
  232. package/src/console/ui-next/src/features/flows/traces/waterfall-bars.ts +4 -0
  233. package/src/console/ui-next/src/features/flows/traces/waterfall-tooltip.ts +9 -3
  234. package/src/console/ui-next/src/features/store/detail/reveal-cell.tsx +7 -11
  235. package/src/console/ui-next/src/features/store/detail/store-row-detail-sheet.tsx +2 -2
  236. package/src/console/ui-next/src/features/store/lib/fields-from-table.ts +2 -0
  237. package/src/console/ui-next/src/features/store/lib/grid-model.test.ts +25 -1
  238. package/src/console/ui-next/src/features/store/lib/grid-model.ts +36 -1
  239. package/src/console/ui-next/src/features/store/query/query-results.tsx +3 -3
  240. package/src/console/ui-next/src/features/units/detail/effects-summary.tsx +2 -0
  241. package/src/console/ui-next/src/features/units/lib/call-read-safe.ts +3 -1
  242. package/src/console/ui-next/src/features/units/lib/fields-from-schema.ts +6 -0
  243. package/src/docker/ai-model-status.test.ts +1 -12
  244. package/src/docker/ai-model-status.ts +10 -38
  245. package/src/docker/compose-up.test.ts +100 -0
  246. package/src/docker/compose-up.ts +292 -0
  247. package/src/docker/compose.ts +4 -14
  248. package/src/docker/derive.ts +9 -34
  249. package/src/docker/docker.test.ts +16 -261
  250. package/src/docker/images-config.test.ts +13 -25
  251. package/src/docker/index.ts +1 -24
  252. package/src/docker/recipes/index.ts +0 -23
  253. package/src/docker/recipes/pgdog.ts +6 -4
  254. package/src/docker/stack-id.test.ts +2 -2
  255. package/src/docker/stack-id.ts +0 -1
  256. package/src/docker/types.ts +2 -2
  257. package/src/drivers/ai-anthropic.ts +10 -0
  258. package/src/drivers/ai-openai-compatible.ts +34 -7
  259. package/src/drivers/ai-providers.test.ts +0 -107
  260. package/src/drivers/ai-stream.test.ts +0 -34
  261. package/src/drivers/ai-types.ts +17 -8
  262. package/src/drivers/channel-fcm.ts +6 -1
  263. package/src/drivers/channel-msegat.ts +6 -1
  264. package/src/drivers/channel-resend.ts +5 -1
  265. package/src/drivers/channel-smtp.ts +5 -1
  266. package/src/drivers/channel-sndr.ts +10 -1
  267. package/src/drivers/channel-taqnyat-mail.ts +5 -1
  268. package/src/drivers/channel-taqnyat-whatsapp.ts +6 -1
  269. package/src/drivers/channel-taqnyat.ts +6 -1
  270. package/src/drivers/channel-types.ts +10 -0
  271. package/src/drivers/channel-unifonic.ts +6 -1
  272. package/src/drivers/channel-wa-cloud.ts +6 -1
  273. package/src/drivers/channel-webpush.ts +6 -1
  274. package/src/drivers/external.ts +33 -0
  275. package/src/drivers/index.ts +0 -10
  276. package/src/drivers/meilisearch.ts +6 -0
  277. package/src/drivers/oauth-types.ts +4 -0
  278. package/src/drivers/postgres.test.ts +74 -3
  279. package/src/drivers/postgres.ts +175 -6
  280. package/src/drivers/signal-types.ts +5 -5
  281. package/src/drivers/types.ts +7 -0
  282. package/src/drivers/vault-types.ts +5 -0
  283. package/src/elements/ai/declare.ts +17 -4
  284. package/src/elements/ai/eval.ts +1 -1
  285. package/src/elements/ai/mcp-http.ts +1 -1
  286. package/src/elements/ai/pii.ts +1 -1
  287. package/src/elements/ai/providers.test.ts +289 -0
  288. package/src/elements/ai/providers.ts +169 -0
  289. package/src/elements/ai/runtime.ts +68 -5
  290. package/src/elements/ai/schema.ts +2 -2
  291. package/src/elements/ai.test.ts +7 -7
  292. package/src/elements/ai.ts +17 -1
  293. package/src/elements/channel/runtime.ts +105 -12
  294. package/src/elements/clock/cron-fields.test.ts +144 -0
  295. package/src/elements/clock/cron-fields.ts +185 -0
  296. package/src/elements/clock/declare.ts +247 -3
  297. package/src/elements/clock.ts +21 -1
  298. package/src/elements/gate/declare.ts +1 -1
  299. package/src/elements/gate.ts +1 -1
  300. package/src/elements/index.ts +15 -0
  301. package/src/elements/signal/chaos-child.ts +1 -2
  302. package/src/elements/signal/declare.ts +65 -37
  303. package/src/elements/signal/delivery-modes.test.ts +11 -31
  304. package/src/elements/signal/dry-run-replay.test.ts +1 -7
  305. package/src/elements/signal/dry-run-write-isolation.test.ts +1 -7
  306. package/src/elements/signal/key-ordering.test.ts +6 -26
  307. package/src/elements/signal/lease-reclaim.test.ts +2 -6
  308. package/src/elements/signal/optional-emit.test.ts +6 -9
  309. package/src/elements/signal/order-lifecycle.test.ts +4 -17
  310. package/src/elements/signal/orphan-messages.test.ts +4 -15
  311. package/src/elements/signal/reconcile.test.ts +2 -2
  312. package/src/elements/signal/runtime.ts +1 -1
  313. package/src/elements/signal/schema-emit.test.ts +4 -8
  314. package/src/elements/signal.test.ts +24 -49
  315. package/src/elements/signal.ts +9 -2
  316. package/src/elements/store/domain-ddl.test.ts +1 -1
  317. package/src/elements/store/live-http.test.ts +9 -4
  318. package/src/elements/store/prepare-row.test.ts +123 -0
  319. package/src/elements/store/resource.ts +43 -12
  320. package/src/elements/store/schema-decl.ts +117 -0
  321. package/src/elements/store/search-backfill.ts +205 -0
  322. package/src/elements/store/search-bind.ts +66 -0
  323. package/src/elements/store/search-bm25.ts +78 -0
  324. package/src/elements/store/search-ddl.ts +156 -0
  325. package/src/elements/store/search-embed-flow.ts +141 -0
  326. package/src/elements/store/search-errors.ts +34 -0
  327. package/src/elements/store/search-fusion.ts +112 -0
  328. package/src/elements/store/search-lsh.ts +214 -0
  329. package/src/elements/store/search-runtime.pglite.test.ts +186 -0
  330. package/src/elements/store/search-runtime.ts +314 -0
  331. package/src/elements/store/search.test.ts +226 -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 +52 -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 +2 -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 -144
  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 -114
  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-3-EFj-2G.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-cVFnA4HH.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-CMIgUbD0.js +0 -66
  484. package/src/console/ui-next/dist/assets/index-Ck88Jmv8.css +0 -2
  485. package/src/console/ui-next/dist/assets/link-BX6Vqztd.js +0 -1
  486. package/src/console/ui-next/dist/assets/observability-page-CQ3p34ip.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-l8FeKfnP.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-CL-d_mLE.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
@@ -1,38 +1,90 @@
1
1
  ---
2
2
  title: "fx"
3
- description: "The complete fx surface — every call a flow can make, its signature, and the effect it records."
3
+ description: "The complete fx surface — every call a Flow can make, its signature, and the effect it records."
4
4
  icon: "Braces"
5
+ source: "docs/spec/unified-theory.md"
5
6
  ---
6
7
 
7
- `fx` is the second argument of every `do` — the single door to the world. This page is the whole surface; each entry notes the **effect it records**, which is what feeds the Manifest, caching, and capability checks.
8
+ `fx` is the second argument of every `do` — the single door to the world. This page is the
9
+ whole surface; each entry notes the **effect it records**, which feeds the Manifest, caching,
10
+ and capability checks.
11
+
12
+ <Callout title="The one rule">
13
+ All world access goes through `fx`. No `node:` I/O, no raw `fetch` for side effects (use
14
+ `fx.fetch` instead), no `Date.now()` — clocks, stores, channels, vault, AI, and outbound HTTP only
15
+ through this object.
16
+ </Callout>
17
+
18
+ ## Smallest Example
19
+
20
+ <Steps>
21
+
22
+ <Step>
23
+ ### Use `fx` inside `do`
24
+
25
+ ```typescript title="src/flows/notes/create.ts"
26
+ import { on, flow, http } from "okengine";
27
+ import { z } from "zod";
28
+ import { db, notes } from "@/schema";
29
+
30
+ export const create = on(
31
+ http.post({
32
+ in: z.object({ title: z.string().min(1) }),
33
+ }),
34
+ flow({
35
+ do: async ({ title }, fx) => {
36
+ const id = fx.id();
37
+ await fx.store(db).insert(notes).values({ id, title });
38
+ return fx.json.create({ id, title });
39
+ },
40
+ }),
41
+ );
42
+ ```
43
+
44
+ </Step>
45
+
46
+ <Step>
47
+ ### Type extracted helpers as `Fx`
8
48
 
9
49
  ```typescript
10
- flow("orders.example", {
11
- do: async (input, fx) => {
12
- // everything below, on this one object
13
- },
14
- });
50
+ import type { Fx } from "okengine";
51
+
52
+ async function loadNote(id: string, fx: Fx) {
53
+ return fx.store(db).findById(notes, id);
54
+ }
15
55
  ```
16
56
 
17
- <Callout title="Extracted helpers">
18
- Type a helper's `fx` parameter as `Fx` (`import type {Fx} from "okengine"`). A narrower structural
19
- type will not match `store()` overloads. See [Flow](/docs/elements/flow).
20
- </Callout>
57
+ A narrower structural type will not match `store()` overloads. See [Flow](/docs/elements/flow).
58
+
59
+ </Step>
60
+
61
+ </Steps>
62
+
63
+ ## What the effects ledger powers
64
+
65
+ | Derived behavior | From |
66
+ | ---------------------- | -------------------------------------- |
67
+ | Cache invalidation | Inferred / ledgered `reads` · `writes` |
68
+ | Live queries / CDC | Store `writes` observed as row events |
69
+ | Least-privilege tokens | Effect matrices on Flows |
70
+ | Deterministic tests | Injectable clock · store · channel |
71
+ | Runs observability | Wide events per invocation (`fx.runs`) |
21
72
 
22
73
  ## Stores
23
74
 
24
- | Signature | Records | Returns |
25
- | ------------------------------------------------------------------- | ------------ | ------------------------------------------------------------------------------------------- |
26
- | `fx.store(sqlDecl).select().from(t)…` | `read` | inferred rows (`where` · `orderBy` · `limit` · `offset` chainable) |
27
- | `fx.store(sqlDecl).insert(t).values(v)` | `write` | `Promise<void>` |
28
- | `fx.store(sqlDecl).update(t).set(v).where(…)` | `write` | `Promise<void>` |
29
- | `fx.store(sqlDecl).delete(t).where(…)` | `write` | `Promise<void>` |
30
- | `fx.store(sqlDecl).findById(t, id)` | `read` | row \| undefined |
31
- | `fx.store(kv).get / set(key, value, ttl?) / delete / list(prefix?)` | read / write | per op |
32
- | `fx.store(files).put / get / delete / list(prefix?)` | read / write | per op |
33
- | `fx.store(files).image(key\|bytes).…` | read / write | Bun.Image chain; terminals gate (see [Store](/docs/elements/store#images--image--putimage)) |
34
- | `fx.store(files).putImage(key, data, opts?)` | `write` | original + variants (+ optional LQIP) |
35
- | `fx.store(index).upsert / search(vector, topK?) / delete` | read / write | per op |
75
+ | Signature | Records | Returns |
76
+ | ------------------------------------------------------------------- | -------------------------- | ------------------------------------------------------------------------------------------- |
77
+ | `fx.store(sqlDecl).select().from(t)…` | `read` | inferred rows (`where` · `orderBy` · `limit` · `offset` chainable) |
78
+ | `fx.store(sqlDecl).insert(t).values(v)` | `write` | `Promise<void>` |
79
+ | `fx.store(sqlDecl).update(t).set(v).where(…)` | `write` | `Promise<void>` |
80
+ | `fx.store(sqlDecl).delete(t).where(…)` | `write` | `Promise<void>` |
81
+ | `fx.store(sqlDecl).findById(t, id)` | `read` | row \| undefined |
82
+ | `fx.store(sqlDecl).search(table, { query, fuse?, rerank?, … })` | `read` (+ `ask` if rerank) | `{ data, meta }` hybrid BM25 ± LSH — see [Search](/docs/elements/store/search) |
83
+ | `fx.store(kv).get / set(key, value, ttl?) / delete / list(prefix?)` | read / write | per op |
84
+ | `fx.store(files).put / get / delete / list(prefix?)` | read / write | per op |
85
+ | `fx.store(files).image(key\|bytes).…` | read / write | Bun.Image chain; terminals gate (see [Store](/docs/elements/store#images--image--putimage)) |
86
+ | `fx.store(files).putImage(key, data, opts?)` | `write` | original + variants (+ optional LQIP) |
87
+ | `fx.store(index).upsert / search(vector, topK?) / delete` | read / write | per op |
36
88
 
37
89
  See [Store](/docs/elements/store) for the query-builder surface.
38
90
 
@@ -40,7 +92,7 @@ See [Store](/docs/elements/store) for the query-builder surface.
40
92
 
41
93
  | Signature | Records | Notes |
42
94
  | ------------------------------------- | ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
43
- | `fx.emit(signal, payload?, { key? })` | `emit` | Commits the signal outbox when the call resolves; optional `key` serializes `once` per key; stamps producer run id as `parentRunId` for trace chains; throws **OKE1042** (orphan) or **OKE1043** (schema) |
95
+ | `fx.emit(signal, payload?, { key? })` | `emit` | Commits the signal outbox when the call resolves; optional `key` serializes `once` per key; stamps producer run id as `parentRunId` for trace chains; throws **OKE1240** (orphan) or **OKE1250** (schema) |
44
96
  | `fx.deadLetters(signal)` | `read` `signal:<name>` | Dead-lettered messages for that signal. Payload typed from `SignalDecl<T>`. Page with `fx.json.withQuery`. Cross-signal throws **OKE1001**. |
45
97
  | `fx.live(signal, { match? })` | `read` `signal:<name>` | Live tape as SSE. Returns `JsonStreamResult` (object chunks, `id:` on the wire). Cross-signal throws **OKE1001**. Do not wrap with `fx.json.stream`. |
46
98
 
@@ -56,8 +108,10 @@ Declare `effects: { reads: ["runs"] }`. Powers native SLO checkers (Clock + Chan
56
108
  | `fx.runs.checkSlo(flow, slo, windowMs?)` | `read` `runs` | Availability / latency breaches |
57
109
 
58
110
  ```typescript
111
+ const sloCheckClock = clock("ops.slo-check", { every: "5m" });
112
+
59
113
  on(
60
- every("5m"),
114
+ sloCheckClock,
61
115
  flow("ops.slo-check", {
62
116
  effects: { reads: ["runs"], sends: ["slo-alert"] },
63
117
  do: async (_, fx) => {
@@ -159,6 +213,18 @@ const rows = await fx.using(
159
213
  Omit locale opts and the send uses `fx.locale`. Dry runs record _would have fired_ and never
160
214
  contact a provider. Channel bodies use `{{field}}` catalogs — not ICU (see [Channel](/docs/elements/channel)).
161
215
 
216
+ ## Outbound HTTP
217
+
218
+ | Signature | Records | Notes |
219
+ | ---------------------- | --------------------------- | ------------------------------------------------------------------------- |
220
+ | `fx.fetch(url, init?)` | `fetch` on the URL hostname | Always stamps `EffectEntry.external` with `{ host, kind: "third-party" }` |
221
+
222
+ Declare hosts in `effects.fetches` (e.g. `["api.stripe.com"]`). Prefer `fx.step`; use
223
+ `fx.retry` only when the remote API is safe to repeat. Dry runs never hit the network.
224
+
225
+ Use this for third-party REST outside Channel / AI / Store — not as a substitute for those
226
+ elements.
227
+
162
228
  ## AI
163
229
 
164
230
  | Signature | Records | Returns |
@@ -170,6 +236,10 @@ contact a provider. Channel bodies use `{{field}}` catalogs — not ICU (see [Ch
170
236
 
171
237
  AI calls are nondeterministic: journaling is forced on and auto-cache disabled around them. `tools` are Flow refs — each model tool call goes through `fx.call` (same capability and Runs path).
172
238
 
239
+ Driver-reported `EffectEntry.external` marks cloud providers as `third-party` and
240
+ self-hosted / `provider: "local"` as `infrastructure` (Console waterfall dashed egress +
241
+ host tooltip).
242
+
173
243
  ## Vault
174
244
 
175
245
  | Signature | Records | Returns / notes |
@@ -232,54 +302,9 @@ Returning a plain value instead answers 200 with `{ data: value, error: null }`
232
302
  | `fx.locale` | Active locale (`Accept-Language` matched to `i18n.locales`) |
233
303
  | `fx.id()` | OKID — 21-char native id from `okengine/okid` |
234
304
 
235
- See [OKID](/docs/reference/okid) for generation options and the entropy model.
236
-
237
- `fx.t` uses [ICU MessageFormat](https://unicode-org.github.io/icu/userguide/format_parse/messages/)
238
- (FormatJS): `{name}`, plurals, `select` / `selectordinal`, rich-text tags.
239
- Full syntax and escaping: [i18n · ICU](/docs/reference/i18n#icu-messageformat).
240
-
241
- Register catalogs with `defineLocale` before boot (nested trees → dot keys). Augment
242
- `Register` so keys autocomplete and typos fail at compile time:
243
-
244
- ```typescript
245
- import { defineLocale, defineMessages, type MessagesFor } from "okengine/i18n";
246
-
247
- export const en = defineMessages({
248
- greeting: "Hello, {name}",
249
- items: "{count, plural, one {# item} other {# items}}",
250
- place: "You finished {place, selectordinal, one {#st} two {#nd} few {#rd} other {#th}}!",
251
- status: "{status, select, online {Online} offline {Offline} other {Unknown}}",
252
- cta: "Read <docs>the docs</docs>",
253
- });
254
- defineLocale("en", en);
255
-
256
- defineLocale("ar", {
257
- greeting: "مرحباً، {name}",
258
- items: "{count, plural, zero {لا عناصر} one {عنصر واحد} other {# عناصر}}",
259
- place: "أنهيت في المرتبة {place, selectordinal, other {#}}!",
260
- status: "{status, select, online {متصل} offline {غير متصل} other {غير معروف}}",
261
- cta: "اقرأ <docs>التوثيق</docs>",
262
- } satisfies MessagesFor<typeof en>);
263
-
264
- declare module "okengine" {
265
- interface Register {
266
- messages: typeof en;
267
- }
268
- }
269
- ```
270
-
271
- ```typescript
272
- fx.t("greeting", { name: input.name });
273
- fx.t("items", { count: 3 });
274
- fx.t("cta", { docs: (chunks) => `<a href="/docs">${chunks.join("")}</a>` });
275
- ```
276
-
277
- Supported locales and the fallback come from `oke.config.ts` `i18n`.
278
- `create-oke` scaffolds English and Arabic locale modules already wired this way.
279
-
280
- Built-in `errors.*` / `oke.*` catalogs localize `fx.fail` messages and thrown
281
- `OkeError` cause/fix the same way — full i18n guide:
282
- [i18n](/docs/reference/i18n), [Errors](/docs/reference/errors).
305
+ Catalogs, ICU syntax, and `Register` augmentation live on [i18n](/docs/reference/i18n).
306
+ Id options: [OKID](/docs/reference/okid). Localized `fx.fail` / `OkeError` catalogs:
307
+ [Errors](/docs/reference/errors).
283
308
 
284
309
  ## Principals
285
310
 
@@ -302,9 +327,49 @@ to the key — see [Gate](/docs/elements/gate#api-keys).
302
327
  export for existing Grafana/Datadog stacks is additive and never required.
303
328
  </Callout>
304
329
 
330
+ ## Troubleshooting
331
+
332
+ <Accordions>
333
+
334
+ <Accordion title="OKE1001–1007 / 1008 / 1009 undeclared effect">
335
+ An explicit `effects` block drifted from what `do` touches. Add the missing ledger entry (`reads`
336
+ · `writes` · `emits` · `sends` · `asks` · `embeds` · `secrets` · `calls` · `fetches`), or drop the
337
+ block so inference covers the Flow ([Errors](/docs/reference/errors)).
338
+ </Accordion>
339
+
340
+ <Accordion title="OKE1240 orphan emit">
341
+ `fx.emit` with zero subscribers and `optional: false`. Add `on(signal, …)` or declare the signal
342
+ `optional: true`.
343
+ </Accordion>
344
+
345
+ <Accordion title="OKE1250 signal schema">
346
+ Emit payload failed the signal's `schema`. Pass a matching payload or remove the schema.
347
+ </Accordion>
348
+
349
+ <Accordion title="Cross-signal fx.live / fx.deadLetters">
350
+ Reading another signal's tape throws **OKE1001**. Declare
351
+ `effects.reads: ["signal:<name>"]` for that name.
352
+ </Accordion>
353
+
354
+ <Accordion title="Helper fx type errors on store()">
355
+ Type the parameter as `Fx` from `okengine`, not a hand-rolled structural type.
356
+ </Accordion>
357
+
358
+ </Accordions>
359
+
305
360
  ## Learn more
306
361
 
307
362
  - [Flow](/docs/elements/flow) — why `fx` is the only door
308
363
  - [Channel](/docs/elements/channel) — `fx.send`, consent, locale chain, `{{field}}` catalogs
364
+ - [i18n](/docs/reference/i18n) — `fx.t`, catalogs, locale matching
309
365
  - [Errors](/docs/reference/errors) — what `fx.fail` produces
310
366
  - [Configuration](/docs/reference/configuration) — drivers and the `i18n` block
367
+ - [OKID](/docs/reference/okid) — `fx.id()` options
368
+
369
+ ## Next
370
+
371
+ <Cards>
372
+ <Card title="Flow" description="Triggers, effects, and durability." href="/docs/elements/flow" />
373
+ <Card title="Errors" description="OKE codes and failure values." href="/docs/reference/errors" />
374
+ <Card title="Client" description="Call Flows with the same envelope." href="/docs/client" />
375
+ </Cards>
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "Reference"
3
- description: "Lookup pages — config, fx, i18n, client, env vars, errors, plugins API, CLI, and Console security."
3
+ description: "Lookup pages — CLI, config, fx, errors, security, and plugins."
4
4
  icon: "BookMarked"
5
5
  source: "docs/spec/unified-theory.md"
6
6
  ---
@@ -10,41 +10,33 @@ Dense tables and command lists. Reach for these when you already know what you a
10
10
  ## Pages
11
11
 
12
12
  <Cards>
13
+ <Card title="CLI" description="oke and create-oke commands." href="/docs/reference/cli" />
13
14
  <Card
14
15
  title="Configuration"
15
16
  description="Every option in oke.config.ts."
16
17
  href="/docs/reference/configuration"
17
18
  />
18
- <Card title="fx" description="The complete fx surface and effects." href="/docs/reference/fx" />
19
- <Card
20
- title="i18n"
21
- description="ICU catalogs, fx.t, typed keys, locale matching."
22
- href="/docs/reference/i18n"
23
- />
24
- <Card
25
- title="Client"
26
- description="Typed createClient — REST, RPC, envelope helpers."
27
- href="/docs/reference/client"
28
- />
29
19
  <Card
30
20
  title="Environment Variables"
31
21
  description="Every variable OKE reads."
32
22
  href="/docs/reference/environment-variables"
33
23
  />
24
+ <Card title="fx" description="The complete fx surface and effects." href="/docs/reference/fx" />
34
25
  <Card title="Errors" description="OKE codes, denials, fixes." href="/docs/reference/errors" />
35
26
  <Card
36
- title="Plugins"
37
- description="Plugin API — hooks, schemas, identity."
38
- href="/docs/reference/plugins"
27
+ title="Security"
28
+ description="Host, Origin, planes, MCP posture."
29
+ href="/docs/reference/security"
39
30
  />
40
31
  <Card
41
- title="CLI Reference"
42
- description="oke and create-oke commands."
43
- href="/docs/reference/cli"
32
+ title="i18n"
33
+ description="ICU catalogs, fx.t, typed keys, locale matching."
34
+ href="/docs/reference/i18n"
44
35
  />
45
36
  <Card
46
- title="Security"
47
- description="Console Host, Origin, MCP posture."
48
- href="/docs/reference/security"
37
+ title="Plugins"
38
+ description="Plugin API — hooks, schemas, identity."
39
+ href="/docs/reference/plugins"
49
40
  />
41
+ <Card title="OKID" description="Native id generator." href="/docs/reference/okid" />
50
42
  </Cards>
@@ -3,15 +3,14 @@
3
3
  "icon": "BookMarked",
4
4
  "pages": [
5
5
  "index",
6
+ "cli",
6
7
  "configuration",
7
- "fx",
8
- "i18n",
9
- "client",
10
8
  "environment-variables",
9
+ "fx",
11
10
  "errors",
12
- "plugins",
13
- "cli",
14
11
  "security",
12
+ "i18n",
13
+ "plugins",
15
14
  "okid"
16
15
  ]
17
16
  }
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "OKID"
3
- description: "OKE's native id generator — compact, URL-safe, cryptographically random ids from okengine/okid, with an opt-in time-sortable and alphabet-controlled variant."
3
+ description: "OKE's native id generator — compact, URL-safe, cryptographically random ids from okengine/okid, with opt-in prefix, time-sortable, and alphabet-controlled variants."
4
4
  icon: "Hash"
5
5
  source: "docs/spec/unified-theory.md"
6
6
  ---
@@ -31,6 +31,7 @@ import { okid } from "okengine/okid";
31
31
  ```typescript
32
32
  const userId = okid();
33
33
  const requestId = okid(16);
34
+ const typedId = okid({ prefix: "usr_" });
34
35
  const eventKey = okid({ sortable: true });
35
36
  const inviteCode = okid({ lookAlikes: false, uppercase: false });
36
37
  ```
@@ -55,21 +56,23 @@ The same 21-character id lands in your SQL primary keys, KV keys, and trace ids.
55
56
 
56
57
  ## Reference
57
58
 
58
- | Call | Result | Notes |
59
- | -------------------------------------------------- | ----------------------------------------- | --------------------------------------- |
60
- | `okid()` | 21-char URL-safe id, 126 bits of entropy | 64-char alphabet, `a-zA-Z0-9-_` |
61
- | `okid(length)` | id of exactly `length` characters | integer between 8 and 128 |
62
- | `okid({ length })` | options form, id of `length` | default 21 |
63
- | `okid({ sortable })` | time-prefixed id, 8 prefix + `length − 8` | lexicographic order ≈ creation order |
64
- | `okid({ numbers, lowercase, uppercase, symbols })` | charset control | each group defaults to on |
65
- | `okid({ lookAlikes })` | confusable-char control | `lookAlikes: false` drops `1lI0Oouv5Ss` |
59
+ | Call | Result | Notes |
60
+ | -------------------------------------------------- | ---------------------------------------- | --------------------------------------- |
61
+ | `okid()` | 21-char URL-safe id, 126 bits of entropy | 64-char alphabet, `a-zA-Z0-9-_` |
62
+ | `okid(length)` | id of exactly `length` characters | integer between 8 and 128 |
63
+ | `okid({ length })` | options form, body of `length` | default 21 |
64
+ | `okid({ prefix })` | `prefix` + body | body length unchanged; see Options |
65
+ | `okid({ sortable })` | time-prefixed body, 8 + `length − 8` | lexicographic order ≈ creation order |
66
+ | `okid({ numbers, lowercase, uppercase, symbols })` | charset control | each group defaults to on |
67
+ | `okid({ lookAlikes })` | confusable-char control | `lookAlikes: false` drops `1lI0Oouv5Ss` |
66
68
 
67
69
  ### Options
68
70
 
69
71
  | Option | Type | Default | Meaning |
70
72
  | ------------ | --------- | ------- | ----------------------------------------------------------- |
71
- | `length` | `number` | `21` | total id length in characters, between 8 and 128 |
72
- | `sortable` | `boolean` | `false` | prefix an 8-char epoch-ms timestamp so sorting follows time |
73
+ | `length` | `number` | `21` | generated body length (8–128); does not include `prefix` |
74
+ | `prefix` | `string` | `""` | fixed label prepended to the body (e.g. `"usr_"`, `"evt_"`) |
75
+ | `sortable` | `boolean` | `false` | prefix the body with an 8-char epoch-ms timestamp |
73
76
  | `numbers` | `boolean` | `true` | include `0-9` |
74
77
  | `lowercase` | `boolean` | `true` | include `a-z` |
75
78
  | `uppercase` | `boolean` | `true` | include `A-Z` |
@@ -83,10 +86,11 @@ The same 21-character id lands in your SQL primary keys, KV keys, and trace ids.
83
86
  | `OKID_ALPHABET` | `a-zA-Z0-9-_` | default, Base64URL order |
84
87
  | `OKID_SORTABLE_ALPHABET` | alphabet sorted by code unit (same chars) | used by the sortable encoder |
85
88
  | `OKID_LOOKALIKE_CHARS` | `1lI0Oouv5Ss` | dropped when `lookAlikes: false` |
86
- | `OKID_DEFAULT_LENGTH` | `21` | default length |
87
- | `OKID_MIN_LENGTH` | `8` | shortest non-sortable length |
88
- | `OKID_MAX_LENGTH` | `128` | longest length |
89
- | `OKID_SORTABLE_MIN_LENGTH` | `16` | shortest sortable length (8+8) |
89
+ | `OKID_DEFAULT_LENGTH` | `21` | default body length |
90
+ | `OKID_MIN_LENGTH` | `8` | shortest non-sortable body |
91
+ | `OKID_MAX_LENGTH` | `128` | longest body |
92
+ | `OKID_SORTABLE_MIN_LENGTH` | `16` | shortest sortable body (8+8) |
93
+ | `OKID_MAX_PREFIX_LENGTH` | `32` | longest semantic `prefix` |
90
94
 
91
95
  ## Collision resistance
92
96
 
@@ -94,6 +98,12 @@ Every character is drawn uniformly from the alphabet with `crypto.getRandomValue
94
98
 
95
99
  **Consequence:** two ids minted at the same millisecond are still distinct — the timestamp prefix never replaces entropy, it prefixes it.
96
100
 
101
+ ## Semantic prefixes
102
+
103
+ `prefix` is a fixed label (`"usr_"`, `"evt_"`, `"inst-"`) prepended to the generated body. Characters must belong to `OKID_ALPHABET` (max 32). `length` stays the body size; the returned string is `prefix + body`.
104
+
105
+ **Consequence:** `okid({ prefix: "usr_", sortable: true })` yields `usr_` + 8-char timestamp + random tail — the label sorts first, then time.
106
+
97
107
  ## Sortable ids
98
108
 
99
109
  `sortable: true` prepends 48 bits of `Date.now()` encoded in exactly 8 characters, in an alphabet whose sort order matches time order. Sorting a batch of these ids reproduces the creation order across milliseconds.
@@ -108,7 +118,7 @@ Turning groups off shrinks the alphabet. With a non-power-of-two alphabet, OKID
108
118
 
109
119
  ## Under the hood
110
120
 
111
- The generator is a pure function: no counters, no process or machine fingerprint, no shared mutable state. It is safe to call concurrently from any number of workers, and every id uses only the bytes it needs — no hidden timestamp, no hidden prefix.
121
+ The generator is a pure function: no counters, no process or machine fingerprint, no shared mutable state. It is safe to call concurrently from any number of workers, and every body uses only the bytes it needs — no hidden timestamp unless `sortable` is on.
112
122
 
113
123
  ## Troubleshooting
114
124
 
@@ -122,6 +132,13 @@ Passing `numbers: false, lowercase: false, uppercase: false, symbols: false` at
122
132
 
123
133
  `okid(0)`, `okid(-1)`, `okid(7)`, `okid(129)`, and non-integer lengths throw a `RangeError`. Sortable ids have a higher floor: passing a sortable length below 16 throws. Keep lengths between 8 and 128 (16–128 for sortable).
124
134
 
135
+ </Accordion>
136
+ <Accordion title="I get a RangeError for a prefix">
137
+
138
+ Characters outside `OKID_ALPHABET` (for example `usr:` or a space) throw
139
+ `okid: prefix contains invalid character … — use characters from OKID_ALPHABET`.
140
+ A prefix longer than 32 throws `okid: prefix length … exceeds max 32` — stick to `A-Za-z0-9-_`.
141
+
125
142
  </Accordion>
126
143
  <Accordion title="My ids are not sortable by the alphabet order I expected">
127
144
 
@@ -130,8 +147,16 @@ The default alphabet order is not lexicographic; `_` sorts between uppercase and
130
147
  </Accordion>
131
148
  </Accordions>
132
149
 
133
- ## References
150
+ ## Learn more
134
151
 
135
152
  - [Store](/docs/elements/store) — `defaultFn(id)` in table declarations delegates to `okid()`
136
153
  - [fx](/docs/reference/fx) — `fx.id()` in the runtime uses `okid()`
137
154
  - [Clock](/docs/elements/clock) — process `instanceId` (`inst-<okid>`) is an OKID
155
+
156
+ ## Next
157
+
158
+ <Cards>
159
+ <Card title="fx" description="fx.id() in Flows." href="/docs/reference/fx" />
160
+ <Card title="Store" description="defaultFn(id) on columns." href="/docs/elements/store" />
161
+ <Card title="Client" description="Ids round-trip on typed routes." href="/docs/client" />
162
+ </Cards>
@@ -82,7 +82,7 @@ Every method below exists on both the fluent definition and the boot-time builde
82
82
  | `.image(role, recipe)` | An image recipe for a docker role |
83
83
  | `.table(name, columns, options)` | A whole DB table, merged into the generated schema (`options.description` / `plane` optional) |
84
84
  | `.errors(map)` | Typed errors flows can fail with |
85
- | `.client(name, ext)` | A typed client extension (reserved seam — not yet merged into `createClient`) |
85
+ | `.client(name, ext)` | Reserved plugin seam — prefer `createAuthClient` method helpers for auth |
86
86
  | `.consolePanel(panel)` | A Console panel (ESM entry loaded at runtime) |
87
87
  | `.cli(name, handler)` | An `oke <name>` CLI command |
88
88
  | `.config(schema)` | A config schema; values live on the plugin identity |
@@ -133,7 +133,7 @@ Plugin options are static by default — changing them means a redeploy. Every o
133
133
  ### Declare the source and its sync flow
134
134
 
135
135
  ```typescript title="src/app.ts"
136
- import { every, oke, on, store } from "okengine";
136
+ import { clock, oke, on, store } from "okengine";
137
137
  import { configSource, maintenanceMode } from "okengine/plugins";
138
138
 
139
139
  const db = store.sql("app");
@@ -146,7 +146,8 @@ const maintenance = configSource({
146
146
  kv: cache, // read-through cache (optional)
147
147
  });
148
148
 
149
- on(every("30s"), maintenance.sync()); // one clock flow refreshes the box
149
+ const maintenanceSyncClock = clock("maintenance.sync", { every: "30s" });
150
+ on(maintenanceSyncClock, maintenance.sync()); // one clock flow refreshes the box
150
151
 
151
152
  export const app = oke({ name: "shop", env: "dev" }).plug(maintenanceMode(maintenance));
152
153
  ```