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
@@ -0,0 +1,445 @@
1
+ ---
2
+ title: "Durable Sleep"
3
+ description: "Journaled pauses that resume across restarts — fx.clock.sleep(label, duration) on durable Flows."
4
+ icon: "Moon"
5
+ source: "docs/spec/unified-theory.md"
6
+ ---
7
+
8
+ Durable sleep suspends a Flow until a future instant without holding a worker thread.
9
+ Call `await fx.clock.sleep(label, duration)` inside a `durable: true` Flow — the journal
10
+ stores `wakeAt`, releases the run lease, and any instance may resume when due.
11
+
12
+ For developers building trial reminders, delayed digests, and multi-day provisions on okengine.
13
+
14
+ <Callout title="The one rule">
15
+ Signature is `fx.clock.sleep(label, duration)` — two arguments. A single duration string is
16
+ treated as the **label**, not the wait. Sleep only parks when the Flow is durable.
17
+ </Callout>
18
+
19
+ <ClockSleep />
20
+
21
+ ## Smallest Example
22
+
23
+ <Steps>
24
+
25
+ <Step>
26
+ ### Sleep inside a durable Flow
27
+
28
+ ```typescript title="src/flows/trials/start.ts"
29
+ import { on, flow, http } from "okengine";
30
+ import { z } from "zod";
31
+
32
+ export const start = on(
33
+ http.post(),
34
+ flow({
35
+ durable: true,
36
+ in: z.object({ email: z.string().email() }),
37
+ do: async ({ email }, fx) => {
38
+ await fx.step("mark-trial", async () => {
39
+ await fx.call(startTrial, { email });
40
+ });
41
+ await fx.clock.sleep("expiry-window", "3d");
42
+ await fx.step("notify", async () => {
43
+ await fx.send(trialExpiringEmail, { to: email });
44
+ });
45
+ },
46
+ }),
47
+ );
48
+ ```
49
+
50
+ </Step>
51
+
52
+ <Step>
53
+ ### Call the endpoint
54
+
55
+ ```bash
56
+ curl -X POST http://localhost:6530/trials/start \
57
+ -H "content-type: application/json" \
58
+ -d '{"email":"ada@example.com"}'
59
+ ```
60
+
61
+ Response: **`204 No Content`** (empty body). The HTTP client is done — wake continues on a
62
+ worker three days later. Wrap side effects in `fx.step` so replay does not re-send mail.
63
+
64
+ </Step>
65
+
66
+ </Steps>
67
+
68
+ <Callout title="Detailed section">
69
+ If you only need a pause, the example above is enough. Below: park physics, wake-early,
70
+ nested-call limits, non-durable no-ops, and how sleep fits with steps / compensation.
71
+ </Callout>
72
+
73
+ ## Progressive Patterns
74
+
75
+ From a labelled pause to HTTP parking, nested-call limits, and non-durable behavior:
76
+
77
+ <Tabs items={["Label + duration", "HTTP park", "After a step", "Non-durable"]}>
78
+
79
+ <Tab value="Label + duration">
80
+
81
+ Durations: `"200ms"` · `"30s"` · `"2m"` · `"1h"` · `"7d"`. Labels show up in the journal
82
+ and Console:
83
+
84
+ ```typescript
85
+ await fx.clock.sleep("morning-window", "8h");
86
+ await fx.clock.sleep("verify-window", "2m");
87
+ ```
88
+
89
+ **Wrong:** `fx.clock.sleep("8h")` — `"8h"` is the label; duration is missing → immediate
90
+ resolve / unexpected behavior.
91
+
92
+ </Tab>
93
+
94
+ <Tab value="HTTP park">
95
+
96
+ Sleep on an HTTP-triggered durable Flow returns success with an empty body (`204`). Return
97
+ a body **before** sleep if the caller must see an id:
98
+
99
+ ```typescript title="src/flows/workspaces/create.ts"
100
+ import { on, flow, http } from "okengine";
101
+ import { z } from "zod";
102
+
103
+ export const create = on(
104
+ http.post(),
105
+ flow({
106
+ durable: true,
107
+ in: z.object({ email: z.string().email() }),
108
+ do: async ({ email }, fx) => {
109
+ await fx.step("create", async () => {
110
+ await fx.call(createWorkspace, { email });
111
+ });
112
+ await fx.emit(workspaceProvisioned, { email });
113
+ await fx.clock.sleep("welcome-delay", "8h");
114
+ await fx.step("notify", async () => {
115
+ await fx.send(welcomeEmail, { to: email });
116
+ });
117
+ },
118
+ }),
119
+ );
120
+ ```
121
+
122
+ After sleep the HTTP client is already done (`204`). Need a JSON body? Return from a
123
+ Flow that does **not** sleep, and park on a Signal consumer instead. See
124
+ [Workflows · Durable Sleep](/docs/elements/flow/workflows#durable-sleep).
125
+
126
+ </Tab>
127
+
128
+ <Tab value="After a step">
129
+
130
+ Checkpoint work **before** the pause so a crash mid-provision does not re-run after wake:
131
+
132
+ ```typescript
133
+ await fx.step("provision", async () => {
134
+ await fx.call(createWorkspace, { email });
135
+ });
136
+ await fx.clock.sleep("morning-window", "8h");
137
+ await fx.step("notify", async () => {
138
+ await fx.send(welcomeEmail, { to: email });
139
+ });
140
+ ```
141
+
142
+ Do not hold `fx.using` resources across sleep — acquire again after wake.
143
+
144
+ </Tab>
145
+
146
+ <Tab value="Non-durable">
147
+
148
+ Without a journal, `fx.clock.sleep` resolves **immediately**. There is no thread sleep and
149
+ no `setTimeout`. Use durable Flows for real delays; use frozen clock + advance in tests.
150
+
151
+ </Tab>
152
+
153
+ </Tabs>
154
+
155
+ ## Sleep Reference
156
+
157
+ | Call / option | Type | Default | Meaning |
158
+ | --------------------------------- | ----------- | ------- | -------------------------------------------------- |
159
+ | `durable: true` | Flow option | `false` | Journals steps and sleep; required to park |
160
+ | `fx.clock.sleep(label, duration)` | park | — | Writes `wakeAt`, status `sleeping`, releases lease |
161
+ | `label` | `string` | — | Journal / Console step name |
162
+ | `duration` | `string` | — | `"200ms"` · `"30s"` · `"2m"` · `"1h"` · `"7d"` |
163
+
164
+ Outcomes of a durable attempt that hits sleep: status `"sleeping"` with `wakeAt` and
165
+ `label`. After wake, prior `fx.step` bodies replay from the journal and do not re-execute.
166
+
167
+ ### Duration units
168
+
169
+ Same grammar as `fx.clock.ago` / `fromNow` / `clock.every`:
170
+
171
+ | Unit | Example | Milliseconds |
172
+ | ---- | --------- | ------------ |
173
+ | `ms` | `"200ms"` | 200 |
174
+ | `s` | `"30s"` | 30_000 |
175
+ | `m` | `"2m"` | 120_000 |
176
+ | `h` | `"1h"` | 3_600_000 |
177
+ | `d` | `"7d"` | 604_800_000 |
178
+
179
+ Integer + unit only — no weeks. `"d"` is exactly 86_400_000 ms, not a calendar day across
180
+ DST. Unknown strings parse as `0` ms (wake immediately).
181
+
182
+ ## Park Physics
183
+
184
+ <Callout title="Detailed section">
185
+ If you only need `await fx.clock.sleep("label", "8h")`, jump past this section. The park writes a
186
+ journal entry, sets status `sleeping`, and **releases the run lease** so a parked flow does not
187
+ hold a 30s lock for days.
188
+ </Callout>
189
+
190
+ ```text
191
+ fx.clock.sleep(label, duration)
192
+ → journal entry { kind: "sleep", label, duration, wakeAt }
193
+ → status = sleeping, lease released
194
+ → HTTP / caller sees success (often 204)
195
+ → later: claim due sleep → resume → replay steps → continue after sleep
196
+ ```
197
+
198
+ Any instance may claim the row when `wakeAt` is due (shared journal + lease). Resume replays
199
+ completed `fx.step` values from the journal, then continues past the sleep entry.
200
+
201
+ | Phase | Status | Lease | What happens |
202
+ | -------------- | ---------------------- | ------------ | --------------------------------------------- |
203
+ | Before sleep | `running` | Held | Steps append; side effects execute once |
204
+ | At sleep | `sleeping` | **Released** | `wakeAt` stored; worker free |
205
+ | After `wakeAt` | claim → `running` | Re-acquired | Replay steps; sleep entry is a no-op past due |
206
+ | Done | `completed` / `failed` | Released | Terminal — resume refused |
207
+
208
+ **Consequence:** multi-day sleeps are safe across deploys — the journal row is the schedule,
209
+ not an in-memory timer.
210
+
211
+ ## With Steps
212
+
213
+ Each verb of durable work binds the same way — checkpoint, park, then more checkpoints:
214
+
215
+ <Tabs items={["Checkpoint sandwich", "HTTP body + sleep", "Signal consumer"]}>
216
+
217
+ <Tab value="Checkpoint sandwich">
218
+
219
+ Wrap every side effect in a uniquely named `fx.step`. Sleep sits **between** steps:
220
+
221
+ ```typescript title="src/flows/onboarding/welcome.ts"
222
+ import { on, flow } from "okengine";
223
+ import { userSignedUp } from "@/signals";
224
+ import { welcomeEmail } from "@/channels/welcome";
225
+
226
+ export const sendWelcome = on(
227
+ userSignedUp,
228
+ flow("onboarding.welcome", {
229
+ durable: true,
230
+ do: async ({ email }, fx) => {
231
+ await fx.step("provision", async () => {
232
+ await fx.call(createWorkspace, { email });
233
+ });
234
+ await fx.clock.sleep("morning-window", "8h");
235
+ await fx.step("notify", async () => {
236
+ await fx.send(welcomeEmail, { to: email });
237
+ });
238
+ },
239
+ }),
240
+ );
241
+ ```
242
+
243
+ **Consequence:** after wake, `provision` returns the journaled value and never re-runs;
244
+ `notify` runs for the first time.
245
+
246
+ </Tab>
247
+
248
+ <Tab value="HTTP body + sleep">
249
+
250
+ Parking an HTTP Flow always answers **`204`** (suspend returns `undefined`). When the
251
+ caller must see an id, **do not sleep on that route** — return the body, emit, and park
252
+ on a consumer:
253
+
254
+ ```typescript title="src/flows/trials/create.ts"
255
+ import { on, flow, http } from "okengine";
256
+ import { z } from "zod";
257
+
258
+ export const create = on(
259
+ http.post(),
260
+ flow({
261
+ durable: true,
262
+ in: z.object({ email: z.string().email() }),
263
+ out: z.object({ trialId: z.string() }),
264
+ do: async ({ email }, fx) => {
265
+ const trialId = await fx.step("create", async () => {
266
+ return await fx.call(createTrial, { email });
267
+ });
268
+ await fx.emit(trialStarted, { trialId, email });
269
+ return { trialId };
270
+ },
271
+ }),
272
+ );
273
+ ```
274
+
275
+ </Tab>
276
+
277
+ <Tab value="Signal consumer">
278
+
279
+ The consumer owns the multi-day wait (paired with the HTTP Flow above):
280
+
281
+ ```typescript title="src/flows/trials/remind.ts"
282
+ import { on, flow } from "okengine";
283
+ import { trialStarted } from "@/signals";
284
+ import { trialExpiringEmail } from "@/channels/trials";
285
+
286
+ export const remind = on(
287
+ trialStarted,
288
+ flow("trials.remind", {
289
+ durable: true,
290
+ do: async ({ trialId, email }, fx) => {
291
+ await fx.clock.sleep("expiry-window", "3d");
292
+ await fx.step("notify", async () => {
293
+ await fx.send(trialExpiringEmail, { to: email, trialId });
294
+ });
295
+ },
296
+ }),
297
+ );
298
+ ```
299
+
300
+ </Tab>
301
+
302
+ </Tabs>
303
+
304
+ ## Nested Calls
305
+
306
+ <Callout title="Detailed section">
307
+ If you sleep only on the root durable Flow, skip this section. `fx.call` waits for the callee to
308
+ return — a sleeping callee does not keep the caller parked.
309
+ </Callout>
310
+
311
+ `fx.call` of a durable sleeper: the caller receives `undefined` and continues; the child
312
+ wakes later as its own run.
313
+
314
+ | Pattern | Safe? | Why |
315
+ | --------------------------------------------- | ----- | ------------------------------------------ |
316
+ | Sleep on the root durable Flow | Yes | One journal row, clear park |
317
+ | `fx.emit` → durable consumer that sleeps | Yes | Separate run owns the wait |
318
+ | `fx.call(sleeperFlow, …)` then use the result | No | Caller gets `undefined`; child parks alone |
319
+
320
+ **Consequence:** sleep on the **root** durable Flow, or split with `fx.emit` to a consumer —
321
+ do not nest sleep behind `fx.call`.
322
+
323
+ ## Wake Early
324
+
325
+ Operators can advance `wakeAt` to **now** from Console (waiting-on / wake-early). With a
326
+ flow resolver, the run resumes immediately; without it, only the wake time moves forward.
327
+
328
+ | Outcome | Meaning |
329
+ | ---------------------------- | ---------------------------------------------------------------- |
330
+ | Resumed | `wakeAt` set to now and `runDurable` continued past the sleep |
331
+ | Wake time only | `wakeAt` advanced; scheduler / next claim picks it up |
332
+ | `ClockResourceNotFoundError` | `run "{id}" not found` — missing id, or status is not `sleeping` |
333
+
334
+ Missing or non-sleeping run id → `ClockResourceNotFoundError` — `run "{id}" not found`.
335
+
336
+ ## Non-durable & Tests
337
+
338
+ Without a journal session, `fx.clock.sleep` resolves immediately (tests and sync Flows).
339
+ There is no thread sleep and no `setTimeout`.
340
+
341
+ For deterministic waits in tests, use a frozen clock and advance:
342
+
343
+ ```typescript
344
+ import { createTimeTravel } from "okengine";
345
+
346
+ const t = createTimeTravel(0);
347
+ // Park a durable run with now: () => t.now()
348
+ t.advance("7d");
349
+ // Resume — sleep entry is past due and continues
350
+ ```
351
+
352
+ Pin journal for the env you need:
353
+
354
+ | Driver | Default env | Best for |
355
+ | ---------- | -------------- | ---------------------------------------------------- |
356
+ | `postgres` | `dev`, `prod` | Shared durable runs across replicas (`DATABASE_URL`) |
357
+ | `memory` | `test` | Process-local; lost on exit |
358
+ | `file` | pin explicitly | One machine — `.oke/journal.json` |
359
+
360
+ Unknown ids throw `oke boot: unknown journal driver "…" (expected memory · file · postgres)`.
361
+ Postgres without a URL throws `oke boot: journal driver "postgres" needs DATABASE_URL`.
362
+
363
+ Full lease / orphan / status tables live on [Workflows · Journal](/docs/elements/flow/workflows#journal).
364
+
365
+ ## Troubleshooting
366
+
367
+ <Accordions>
368
+
369
+ <Accordion title="Sleep returns immediately / work runs twice after wait">
370
+ Missing `durable: true`, or `fx.clock.sleep("8h")` with one argument. Use `fx.clock.sleep("label",
371
+ "8h")`. Non-durable sleep is a no-op.
372
+ </Accordion>
373
+
374
+ <Accordion title="HTTP 204 with empty body after POST">
375
+ The Flow parked on `fx.clock.sleep` — success, not a missing handler. The original client is done;
376
+ wake continues on a worker. Return a body before sleep if needed, or emit to a Signal consumer for
377
+ the long wait.
378
+ </Accordion>
379
+
380
+ <Accordion title="Mail / charge ran again after resume">
381
+ The side effect was outside `fx.step`. Wrap provider calls in uniquely named steps so replay
382
+ returns the journaled value.
383
+ </Accordion>
384
+
385
+ <Accordion title="Connection held across sleep">
386
+ `fx.using` is same-attempt cleanup — do not hold handles across `fx.clock.sleep`. Acquire again
387
+ after wake.
388
+ </Accordion>
389
+
390
+ <Accordion title="ClockResourceNotFoundError on wake">
391
+ Cause: `run "{id}" not found`. The wake-early target is missing or not `sleeping` — check the run
392
+ id from Console / durable result.
393
+ </Accordion>
394
+
395
+ <Accordion title="fx.call of a durable sleeper returned undefined">
396
+ The callee parked. Sleep on the root Flow, or emit to a durable consumer instead of calling a
397
+ sleeper inline.
398
+ </Accordion>
399
+
400
+ <Accordion title="Unknown duration wakes immediately">
401
+ Strings that do not match `integer + ms|s|m|h|d` parse as `0` ms. Use `"8h"`, not `"8 hours"` or
402
+ `"1w"`.
403
+ </Accordion>
404
+
405
+ <Accordion title='journal: run "…" is leased by another instance'>
406
+ Resume lost the lease race (`JournalLeaseBusy`). The other holder continues; this instance skips.
407
+ Shared `postgres` journal + default **30s** lease — same physics as Signal claims.
408
+ </Accordion>
409
+
410
+ <Accordion title="GET /_/ready is 503 reason orphan_scan">
411
+ Boot is still reclaiming `running` / `sleeping` / `compensating` rows with no live lease. Wait for
412
+ the orphan scan; future sleeps stay scheduled until `wakeAt`.
413
+ </Accordion>
414
+
415
+ </Accordions>
416
+
417
+ ## Learn more
418
+
419
+ - [Workflows](/docs/elements/flow/workflows) — `durable`, `fx.step`, compensate, full sleep section
420
+ - [HTTP](/docs/elements/flow/http) — request envelope; `204` from park / `undefined`
421
+ - [Clock overview](/docs/elements/clock) — schedules and `fx.clock` helpers
422
+ - [Schedules](/docs/elements/clock/schedules) — cron / every (calendar time, not durable pause)
423
+ - [fx](/docs/reference/fx) — `fx.clock.sleep`, `fx.step`, `fx.using`
424
+ - [Configuration](/docs/reference/configuration) — `drivers.journal`
425
+ - [Errors](/docs/reference/errors) — `ClockResourceNotFoundError`
426
+
427
+ ## Next
428
+
429
+ <Cards>
430
+ <Card
431
+ title="Durable Workflows"
432
+ description="Step journaling, undo, and multi-day runs."
433
+ href="/docs/elements/flow/workflows"
434
+ />
435
+ <Card
436
+ title="Schedules"
437
+ description="Cron helpers, intervals, and IANA timezones."
438
+ href="/docs/elements/clock/schedules"
439
+ />
440
+ <Card
441
+ title="Clock Overview"
442
+ description="Return to the Clock element overview."
443
+ href="/docs/elements/clock"
444
+ />
445
+ </Cards>