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
@@ -0,0 +1,276 @@
1
+ ---
2
+ title: "Key Rotation"
3
+ description: "Rotate secret versions under a fresh data key, rewrap the master key, and seal or unseal the builtin vault."
4
+ icon: "RefreshCw"
5
+ source: "docs/spec/unified-theory.md"
6
+ ---
7
+
8
+ Key rotation keeps credentials and encryption keys moving without dropping the app. On the builtin
9
+ `vault` driver you rotate a **secret version** (fresh data key) or the **master key** (KEK rewrap).
10
+ Contract `rotate: "90d"` is a Console cadence hint — it does not rotate by itself.
11
+
12
+ For operators and Flows that must cut over keys safely — prefer CLI for master material; use
13
+ `fx.vault.rotate` for path versions inside privileged Flows.
14
+
15
+ <Callout title="The one rule">
16
+ Never pass master keys as CLI argv in shared shells — they land in history. Prefer `oke vault
17
+ unseal --key -`, the env `OKE_VAULT_MASTER_KEY`, or the hidden prompt.
18
+ </Callout>
19
+
20
+ ## Smallest Example
21
+
22
+ <Steps>
23
+
24
+ <Step>
25
+ ### Initialize and set a secret (builtin driver)
26
+
27
+ ```bash
28
+ # drivers.vault = "vault" — SQL-backed AES-256-GCM
29
+ oke vault init # prints master key once — store out of band
30
+ export OKE_VAULT_MASTER_KEY=… # or --key - from stdin
31
+
32
+ oke vault set STRIPE_KEY
33
+ # prompts for value, or: oke vault set STRIPE_KEY sk_live_…
34
+ ```
35
+
36
+ </Step>
37
+
38
+ <Step>
39
+ ### Rotate to a new version
40
+
41
+ ```bash
42
+ oke vault rotate STRIPE_KEY sk_live_new_key
43
+ # → oke vault: rotated STRIPE_KEY → v2 (fresh data key)
44
+ ```
45
+
46
+ Omit the value to re-encrypt the current cleartext under a new data key (version bumps, readers
47
+ still see the same string until you change it).
48
+
49
+ </Step>
50
+
51
+ <Step>
52
+ ### Confirm status
53
+
54
+ ```bash
55
+ oke vault status
56
+ # initialized, unsealed, kek version, secret count
57
+ ```
58
+
59
+ </Step>
60
+
61
+ </Steps>
62
+
63
+ ## Progressive Patterns
64
+
65
+ From CLI path rotate to Flow mutations, cadence hints, and master rewrap:
66
+
67
+ <Tabs items={["CLI rotate", "fx.vault.rotate", "Cadence", "Master"]}>
68
+
69
+ <Tab value="CLI rotate">
70
+
71
+ ```bash
72
+ oke vault rotate prod/api/stripe sk_live_new
73
+ oke vault rotate prod/api/stripe # same cleartext, fresh DEK
74
+ ```
75
+
76
+ Needs an unsealed builtin backend. Missing path:
77
+
78
+ ```text
79
+ oke vault: no such secret: prod/api/stripe
80
+ ```
81
+
82
+ </Tab>
83
+
84
+ <Tab value="fx.vault.rotate">
85
+
86
+ Privileged Flow — requires `drivers.vault = "vault"` (bound adapter):
87
+
88
+ ```typescript title="src/flows/ops/rotate-stripe.ts"
89
+ import { on, flow, http } from "okengine";
90
+ import { z } from "zod";
91
+ import { gate } from "okengine";
92
+
93
+ const operator = gate.policy("operator", ({ operator: op }) => !!op);
94
+
95
+ export const rotateStripe = on(
96
+ http
97
+ .post({
98
+ in: z.object({ value: z.string().min(1) }),
99
+ })
100
+ .gate(operator),
101
+ flow({
102
+ plane: "operator",
103
+ effects: { secrets: ["STRIPE_KEY"] },
104
+ do: async ({ value }, fx) => {
105
+ const result = await fx.vault.rotate("STRIPE_KEY", value);
106
+ return { path: result.path, version: result.version };
107
+ },
108
+ }),
109
+ );
110
+ ```
111
+
112
+ `fx.vault.set` writes a new version without forcing a fresh DEK policy the same way; prefer
113
+ `rotate` when retiring the previous data key is the point.
114
+
115
+ Dry-run refuses both (`DryRunWriteIsolationError`).
116
+
117
+ </Tab>
118
+
119
+ <Tab value="Cadence">
120
+
121
+ Declare intent for Console posture — operators still run rotate:
122
+
123
+ ```typescript
124
+ export const stripeKey = vault.secret("STRIPE_KEY", {
125
+ description: "Stripe secret API key",
126
+ rotate: "90d",
127
+ });
128
+ ```
129
+
130
+ Omit or `"never"` when the secret must not rotate on a schedule.
131
+
132
+ </Tab>
133
+
134
+ <Tab value="Master">
135
+
136
+ Rewrap every DEK under a new KEK generation:
137
+
138
+ ```bash
139
+ oke vault rotate-master
140
+ # prints the new master key once — store it, then update OKE_VAULT_MASTER_KEY
141
+
142
+ # Resume an interrupted rewrap:
143
+ oke vault rotate-master --new-key -
144
+ ```
145
+
146
+ Overlapping batches surface `VaultRotateBusy`. Console rotate-master while sealed → `VaultSealed`.
147
+
148
+ </Tab>
149
+
150
+ </Tabs>
151
+
152
+ ## Version physics
153
+
154
+ <VaultRotate />
155
+
156
+ Builtin storage encrypts each version with its own data key (DEK), wrapped by a KEK derived from
157
+ the master key:
158
+
159
+ | Operation | What changes | Readers see |
160
+ | ------------------------ | -------------------------------- | ------------------------------------ |
161
+ | `set` / `rotate` + value | New version + (rotate) fresh DEK | New cleartext on next `get` |
162
+ | `rotate` without value | New version + fresh DEK | Same cleartext |
163
+ | `rotate-master` | New KEK; DEKs re-wrapped | Same cleartexts; new master required |
164
+ | `delete` | Crypto-shred path | Subsequent `get` misses |
165
+
166
+ Paths are slash-separated with no leading slash (`prod/api/stripe`). Invalid paths throw
167
+ `VaultError` `INVALID_PATH`.
168
+
169
+ **Consequence:** secret access is not journaled — durable Flow replay re-reads live vault state
170
+ after a rotate instead of replaying a stale credential from the journal.
171
+
172
+ ## Seal & unseal
173
+
174
+ | Command / state | Meaning |
175
+ | ------------------ | ------------------------------------------------------- |
176
+ | `oke vault init` | Create backend state; print master key **once** |
177
+ | `oke vault seal` | Drop in-memory master; reads fail with `SEALED` |
178
+ | `oke vault unseal` | Restore master from `--key` / env / prompt |
179
+ | `oke vault status` | `initialized`, sealed flag, `kekVersion`, `secretCount` |
180
+
181
+ ```bash
182
+ oke vault unseal --key - # read base64 master from stdin
183
+ oke vault status --json
184
+ ```
185
+
186
+ ## CLI reference
187
+
188
+ Env / dotenv bag loop:
189
+
190
+ | Command | Purpose |
191
+ | ------------------------------ | ------------------------- |
192
+ | `oke vault set <NAME> [value]` | Write / overwrite a name |
193
+ | `oke vault list` | List names (never values) |
194
+ | `oke vault import <file>` | Bulk import |
195
+ | `oke vault key rotate` | Env-loop key helper |
196
+
197
+ Builtin encrypted store:
198
+
199
+ | Command | Purpose |
200
+ | --------------------------------- | ---------------------------- |
201
+ | `oke vault init` | First-time initialize |
202
+ | `oke vault status [--json]` | Seal / KEK / counts |
203
+ | `oke vault seal` / `unseal` | Master lifecycle |
204
+ | `oke vault rotate <path> [value]` | Version + fresh DEK |
205
+ | `oke vault rotate-master` | KEK rewrap |
206
+ | `oke vault audit` … | Audit trail / verify / purge |
207
+ | `oke vault purge-expired` | Drop expired rows |
208
+ | `oke vault backup` / `restore` | File snapshot |
209
+
210
+ `--url` overrides the SQL URL (`DATABASE_URL` / `OKE_STORE_SQL_URL`).
211
+
212
+ ## Troubleshooting
213
+
214
+ <Accordions>
215
+
216
+ <Accordion title="oke vault: no such secret">
217
+ Rotate/get targeted a path that was never set. `oke vault list` (or Console) for live paths;
218
+ remember per-tenant storage uses `{tenantId}/{name}`.
219
+ </Accordion>
220
+
221
+ <Accordion title="VaultSealed">
222
+ Process holds no master key. Export `OKE_VAULT_MASTER_KEY` or `oke vault unseal` before
223
+ rotate-master / reads that need the adapter.
224
+ </Accordion>
225
+
226
+ <Accordion title="VaultRotateBusy">
227
+ Another master-rotation lease or batch is in flight. Wait, or resume with `oke vault rotate-master
228
+ --new-key` (stdin `-` preferred).
229
+ </Accordion>
230
+
231
+ <Accordion title="VaultUnsupported / needs drivers.vault = vault">
232
+ Console or `fx.vault.rotate` hit a non-builtin bag (`env` / `memory` / `managed`). Pin
233
+ `drivers.vault` to `"vault"` and ensure SQL is available.
234
+ </Accordion>
235
+
236
+ <Accordion title="fx.vault.rotate needs a bound Vault backend">
237
+ Same as above — mutations need the encrypted adapter. `fx.vault.get` alone works on any driver.
238
+ </Accordion>
239
+
240
+ <Accordion title="DryRunWriteIsolationError on set / rotate">
241
+ Dry-run refuses vault writes so a live secret is never mutated. Use a real run for rotation.
242
+ </Accordion>
243
+
244
+ <Accordion title="VaultError EXPIRED">
245
+ A version’s absolute expiry passed on the builtin adapter. Rotate or set a new value; purge
246
+ expired rows with `oke vault purge-expired` when cleaning storage.
247
+ </Accordion>
248
+
249
+ </Accordions>
250
+
251
+ ## Learn more
252
+
253
+ - [Secrets](/docs/elements/vault/secrets) — contracts and `fx.vault.get`
254
+ - [Vault overview](/docs/elements/vault) — drivers and resolution
255
+ - [Errors](/docs/reference/errors) — `VaultSealed` · `VaultRotateBusy` · `VaultUnsupported`
256
+ - [Environment variables](/docs/reference/environment-variables) — `OKE_VAULT_MASTER_KEY`
257
+
258
+ ## Next
259
+
260
+ <Cards>
261
+ <Card
262
+ title="Channel Element"
263
+ description="Send email and other human reach through templates."
264
+ href="/docs/elements/channel"
265
+ />
266
+ <Card
267
+ title="Secrets"
268
+ description="Declare contracts readers will rotate."
269
+ href="/docs/elements/vault/secrets"
270
+ />
271
+ <Card
272
+ title="Vault Overview"
273
+ description="Resolution chain, Redacted, and drivers."
274
+ href="/docs/elements/vault"
275
+ />
276
+ </Cards>
@@ -0,0 +1,288 @@
1
+ ---
2
+ title: "Secrets"
3
+ description: "Typed vault.secret contracts, boot-time resolution, Redacted reads through fx.vault.get, and per-tenant paths."
4
+ icon: "Key"
5
+ source: "docs/spec/unified-theory.md"
6
+ ---
7
+
8
+ Secret contracts (`vault.secret`) declare the credentials your backend requires — Stripe keys,
9
+ webhook HMACs, SMTP URLs. Values resolve at boot; Flows read them as `Redacted` through
10
+ `fx.vault.get`.
11
+
12
+ For developers who must never leak credentials into logs or HTTP bodies — declare the name,
13
+ resolve it, reveal only at the provider edge.
14
+
15
+ <Callout title="The one rule">
16
+ Touch secrets only through `fx.vault.get(contract)`. That records the `secret` effect and returns
17
+ `Redacted` — `.reveal()` belongs at the SDK / HMAC boundary, not in return values.
18
+ </Callout>
19
+
20
+ ## Smallest Example
21
+
22
+ <Steps>
23
+
24
+ <Step>
25
+ ### Declare the contract
26
+
27
+ ```typescript title="src/core/vault.ts"
28
+ import { vault } from "okengine";
29
+ import { z } from "zod";
30
+
31
+ export const stripeKey = vault.secret("STRIPE_KEY", {
32
+ description: "Stripe secret API key",
33
+ schema: z.string().startsWith("sk_"),
34
+ rotate: "90d",
35
+ dev: "sk_test_local",
36
+ });
37
+ ```
38
+
39
+ Import this module before `oke()` so auto-registry can adopt the contract (or pass it in
40
+ `oke({ secrets: […] })`).
41
+
42
+ </Step>
43
+
44
+ <Step>
45
+ ### Read inside `do`
46
+
47
+ ```typescript title="src/flows/payments/charge.ts"
48
+ import { on, flow, http } from "okengine";
49
+ import { z } from "zod";
50
+ import { member } from "@/core/gate";
51
+ import { stripeKey } from "@/core/vault";
52
+
53
+ export const charge = on(
54
+ http
55
+ .post({
56
+ in: z.object({ amount: z.number().int().positive() }),
57
+ })
58
+ .gate(member),
59
+ flow({
60
+ do: async ({ amount }, fx) => {
61
+ const key = await fx.vault.get(stripeKey);
62
+ const stripe = new Stripe(key.reveal());
63
+ const intent = await stripe.paymentIntents.create({ amount, currency: "usd" });
64
+ return { id: intent.id };
65
+ },
66
+ }),
67
+ );
68
+ ```
69
+
70
+ </Step>
71
+
72
+ <Step>
73
+ ### Confirm the effect
74
+
75
+ Manifest / Console list `secrets: ["STRIPE_KEY"]` on `payments.charge`. Logs that stringify
76
+ `key` show `[redacted]`.
77
+
78
+ </Step>
79
+
80
+ </Steps>
81
+
82
+ ## Progressive Patterns
83
+
84
+ From a bare name to schema, cadence, tenancy, and sensitivity overrides:
85
+
86
+ <Tabs items={["Minimal", "Schema", "Per-tenant", "Shared"]}>
87
+
88
+ <Tab value="Minimal">
89
+
90
+ Name only — description helps boot gaps and Console:
91
+
92
+ ```typescript
93
+ export const webhookSecret = vault.secret("APP_WEBHOOK_SECRET", {
94
+ description: "HMAC secret for outbound webhooks",
95
+ });
96
+ ```
97
+
98
+ </Tab>
99
+
100
+ <Tab value="Schema">
101
+
102
+ Attach a schema for tooling and human contracts (Zod / Standard Schema). Prefer validating at the
103
+ provider edge when the remote value must match a prefix:
104
+
105
+ ```typescript
106
+ export const resendApiKey = vault.secret("RESEND_API_KEY", {
107
+ description: "Resend email delivery API key",
108
+ schema: z.string().startsWith("re_"),
109
+ });
110
+ ```
111
+
112
+ </Tab>
113
+
114
+ <Tab value="Per-tenant">
115
+
116
+ When `gate.auth.tenant` is on, contracts default to request-time paths
117
+ `{tenantId}/{name}` — they are **not** boot-gap fatal (value appears per tenant):
118
+
119
+ ```typescript
120
+ export const tenantStripe = vault.secret("STRIPE_KEY", {
121
+ description: "Per-workspace Stripe key",
122
+ perTenant: true, // explicit; also the default when tenancy is on
123
+ });
124
+ ```
125
+
126
+ `fx.vault.get(tenantStripe)` resolves under the active `fx.tenant.id`. Missing tenant throws
127
+ `TENANT_REQUIRED`. Opt out of isolation with `perTenant: false`.
128
+
129
+ **Consequence:** seed or `set` the tenant path (`acme/STRIPE_KEY`), not only the bare contract
130
+ name.
131
+
132
+ </Tab>
133
+
134
+ <Tab value="Shared">
135
+
136
+ A secret shared across all tenants while tenancy is enabled:
137
+
138
+ ```typescript
139
+ export const platformWebhook = vault.secret("PLATFORM_WEBHOOK", {
140
+ description: "Platform-wide webhook secret",
141
+ perTenant: false,
142
+ });
143
+ ```
144
+
145
+ Boot still requires a value for shared contracts.
146
+
147
+ </Tab>
148
+
149
+ </Tabs>
150
+
151
+ ## Options Reference
152
+
153
+ Third argument shape is `VaultSecretOptions` on `vault.secret(name, options)`:
154
+
155
+ | Option | Type | Default | Meaning |
156
+ | ------------- | --------- | ---------------------- | -------------------------------------------------------------------- |
157
+ | `description` | `string` | — | Boot-gap and Console label |
158
+ | `rotate` | `string` | omit ≈ `"never"` | Cadence hint (`"90d"`) for Console posture — not automatic rotation |
159
+ | `schema` | Schema | — | Declared validator for docs / tooling |
160
+ | `dev` | `string` | — | Dev-only fallback (`vault.fromDocker(role)` allowed) |
161
+ | `sensitive` | `boolean` | `true` | Fingerprinted; Console never shows cleartext |
162
+ | `perTenant` | `boolean` | `true` when tenancy on | Storage path `{tenantId}/{name}`; skipped in boot-gap scan when true |
163
+
164
+ Empty name throws `TypeError: vault.secret: name is required`.
165
+
166
+ ## Reading secrets
167
+
168
+ <VaultRedacted />
169
+
170
+ | Call | Returns | Notes |
171
+ | ---------------------------- | ------------------ | -------------------------------------- |
172
+ | `await fx.vault.get(handle)` | `Redacted<string>` | Preferred — capability from the handle |
173
+ | `await fx.vault.get("NAME")` | `Redacted<string>` | Same when the name is declared |
174
+ | `key.reveal()` | `string` | One explicit cleartext escape |
175
+ | `key.map(fn)` | `Redacted<U>` | Transform without exposing to callers |
176
+ | `String(key)` / `toJSON` | `"[redacted]"` | Safe for accidental serialization |
177
+
178
+ ```typescript
179
+ const key = await fx.vault.get(stripeKey);
180
+
181
+ fx.log.info(`using ${key}`); // message contains [redacted]
182
+ // JSON.stringify({ key }) → { "key": "[redacted]" }
183
+
184
+ const client = new Stripe(key.reveal());
185
+ ```
186
+
187
+ Secret access is **never journaled** — durable replay re-reads the live value so a rotated
188
+ credential is not resurrected from the journal.
189
+
190
+ ## Effects & Manifest
191
+
192
+ Calling `fx.vault.get` records `effects.secrets` with the contract name. Declare the same list
193
+ explicitly when you want Manifest truth without inference:
194
+
195
+ ```typescript
196
+ flow("payments.charge", {
197
+ effects: { secrets: ["STRIPE_KEY"] },
198
+ do: async (_, fx) => {
199
+ await fx.vault.get(stripeKey);
200
+ },
201
+ });
202
+ ```
203
+
204
+ Capability enforcement: reading a name not allowed by the Flow’s effects fails the `secret`
205
+ capability check.
206
+
207
+ ## Boot gaps
208
+
209
+ Missing non-tenant contracts fail boot with every hole listed once:
210
+
211
+ ```text
212
+ vault boot failed — 2 missing secret(s):
213
+ - STRIPE_KEY: Stripe secret API key
214
+ - APP_WEBHOOK_SECRET: HMAC secret for outbound webhooks
215
+ ```
216
+
217
+ Fill gaps with:
218
+
219
+ | Layer | How |
220
+ | ------------ | --------------------------------------------------------- |
221
+ | Driver | `oke vault set NAME`, managed provider write, memory seed |
222
+ | process.env | Export `NAME=…` in the host / CI |
223
+ | `.env.local` | Local override file (gitignored) |
224
+ | `dev:` | Contract fallback — only when dev fallbacks are allowed |
225
+
226
+ On a TTY, `oke dev` prompts for each gap before the app starts and writes values
227
+ into `.env.local` (same store as `oke vault set`). Non-interactive runs still
228
+ fail with `VaultBootError` listing every hole.
229
+
230
+ ## Troubleshooting
231
+
232
+ <Accordions>
233
+
234
+ <Accordion title="VaultBootError lists this secret">
235
+ No resolution layer supplied a value. On a TTY, `oke dev` prompts into `.env.local`; otherwise use
236
+ `oke vault set` / env / managed, or a `dev:` fallback. Per-tenant contracts are skipped at boot —
237
+ seed the tenant path.
238
+ </Accordion>
239
+
240
+ <Accordion title='vault: secret "…" is not loaded'>
241
+ Boot succeeded but the name is absent from the merged bag (or you never declared it). Import the
242
+ declaring module; confirm auto-registry or `oke({ secrets: [handle] })`.
243
+ </Accordion>
244
+
245
+ <Accordion title="TENANT_REQUIRED on fx.vault.get">
246
+ Tenancy is on, the contract is per-tenant, and `fx.tenant.id` is null. Resolve a tenant on the
247
+ request, or set `perTenant: false` for a platform-wide secret.
248
+ </Accordion>
249
+
250
+ <Accordion title="Capability / secret effect denied">
251
+ The Flow’s `effects.secrets` (inferred or declared) must include the name you `get`. Touch the
252
+ handle inside `do`, or list the name explicitly.
253
+ </Accordion>
254
+
255
+ <Accordion title="Redacted still leaked through a third-party logger">
256
+ Vault scrubs `fx.log` and known substrings. Direct `console.log(key.reveal())` or foreign sinks
257
+ are outside the redactor — keep cleartext off those paths.
258
+ </Accordion>
259
+
260
+ </Accordions>
261
+
262
+ ## Learn more
263
+
264
+ - [Vault overview](/docs/elements/vault) — resolution chain and drivers
265
+ - [Config](/docs/elements/vault/config) — cleartext contracts vs secrets
266
+ - [Key Rotation](/docs/elements/vault/rotation) — version and master-key rotate
267
+ - [Tenancy](/docs/elements/gate/tenancy) — `fx.tenant.id` for per-tenant paths
268
+ - [fx](/docs/reference/fx) — full `fx.vault` table
269
+
270
+ ## Next
271
+
272
+ <Cards>
273
+ <Card
274
+ title="Config"
275
+ description="Non-sensitive vault.config and vault.env helpers."
276
+ href="/docs/elements/vault/config"
277
+ />
278
+ <Card
279
+ title="Key Rotation"
280
+ description="Rotate secret versions and the master key."
281
+ href="/docs/elements/vault/rotation"
282
+ />
283
+ <Card
284
+ title="Vault Overview"
285
+ description="Resolution chain, Redacted, and drivers."
286
+ href="/docs/elements/vault"
287
+ />
288
+ </Cards>
@@ -12,75 +12,55 @@ Welcome to the OKEngine handbook. Keep the model small; let the backend grow wit
12
12
  </Callout>
13
13
 
14
14
  ```ts
15
- on(http.post("/bookings"), createBooking);
16
- on(every("10m"), expireStale);
15
+ on(http.post(), createBooking); // path + name from the file tree
16
+ on(expireStaleClock, expireStale);
17
17
  on(orderPlaced, sendReceipt);
18
18
  ```
19
19
 
20
- ## 01 Understand (The Core Model)
20
+ ## 01 Understand
21
21
 
22
22
  Master the mental model before exploring features:
23
23
 
24
24
  <Cards>
25
25
  <Card
26
- title="Why OKE"
27
- description="The problem of seams across independent tools, the insight, and the smaller model."
28
- href="/docs/get-started/why"
26
+ title="The Architecture"
27
+ description="Why backends drift apart, the one rule that stops it, and the five pieces behind every Flow."
28
+ href="/docs/understand/the-architecture"
29
29
  />
30
30
  <Card
31
- title="Introduction"
32
- description="The Law, Flow anatomy, the fx rule, and the compiled Manifest contract."
33
- href="/docs/get-started/introduction"
34
- />
35
- <Card
36
- title="Eight Elements"
37
- description="The closed primitive set: Flow, Signal, Store, Clock, Gate, Vault, Channel, AI."
38
- href="/docs/elements"
39
- />
40
- <Card
41
- title="fx Surface"
42
- description="The single door to the outside world — where effects become structurally observable."
43
- href="/docs/reference/fx"
31
+ title="Try It"
32
+ description="From an empty folder to a Flow running in the Console — one sitting, minimal detour."
33
+ href="/docs/understand/try-it"
44
34
  />
45
35
  </Cards>
46
36
 
47
- ## 02 Build (Development)
37
+ ## 02 Elements
48
38
 
49
- Build, test, and expose real applications:
39
+ Deep primitives and execution law:
50
40
 
51
41
  <Cards>
52
42
  <Card
53
- title="Get Started"
54
- description="Scaffold with create-oke, run the dev stack, and open the Console."
55
- href="/docs/get-started/installation"
56
- />
57
- <Card
58
- title="Basic Usage"
59
- description="Write your first flow, call it with the typed client, and test with bun:test."
60
- href="/docs/get-started/basic-usage"
43
+ title="Elements"
44
+ description="Flow, Signal, Store, Clock, Gate, Vault, Channel, AI."
45
+ href="/docs/elements"
61
46
  />
62
47
  <Card
63
- title="Project Structure"
64
- description="Folder layout, flow file routing conventions, and schema declarations."
65
- href="/docs/get-started/project-structure"
48
+ title="Reference"
49
+ description="CLI, configuration, fx, errors, security, and plugins."
50
+ href="/docs/reference"
66
51
  />
67
52
  <Card
68
- title="AI & MCP Surface"
53
+ title="AI Resources"
69
54
  description="Runtime MCP (:6535), docs MCP (:6536), agent skills, and machine-readable docs."
70
55
  href="/docs/ai"
71
56
  />
72
57
  </Cards>
73
58
 
74
- ## 03 Operate & 04 Extend
59
+ ## 03 Extend
75
60
 
76
- Deploy to production and connect to infrastructure:
61
+ Connect to infrastructure and extend the model:
77
62
 
78
63
  <Cards>
79
- <Card
80
- title="Deployment"
81
- description="Production runtime operations: Docker, Swarm, Kubernetes, and reverse proxy."
82
- href="/docs/deployment"
83
- />
84
64
  <Card
85
65
  title="Plugins"
86
66
  description="Official extensions that add capabilities without creating a ninth element."
@@ -97,3 +77,35 @@ Deploy to production and connect to infrastructure:
97
77
  href="/docs/recipes"
98
78
  />
99
79
  </Cards>
80
+
81
+ ## 04 Client
82
+
83
+ Call your Flows from a browser, CLI, or another service — typed, zero separate codegen:
84
+
85
+ <Cards>
86
+ <Card
87
+ title="Overview"
88
+ description="createClient, envelopes as values, and how Client relates to the eight elements."
89
+ href="/docs/client"
90
+ />
91
+ <Card
92
+ title="Calling"
93
+ description="REST vs RPC, options, result helpers, resources, and remote types."
94
+ href="/docs/client/calling"
95
+ />
96
+ <Card
97
+ title="Auth"
98
+ description="Bearer sessions, refresh once on 401, and gate denials as values."
99
+ href="/docs/client/auth"
100
+ />
101
+ <Card
102
+ title="Live"
103
+ description="api.live SSE, resume, and live resource queries."
104
+ href="/docs/client/live"
105
+ />
106
+ <Card
107
+ title="React"
108
+ description="useSession, useLive, and useLiveQuery from okengine/client-react."
109
+ href="/docs/client/react"
110
+ />
111
+ </Cards>