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
@@ -1,405 +0,0 @@
1
- ---
2
- title: "Vault"
3
- description: "Secrets, API keys, and config — declared once as typed contracts, resolved from a real vault in production, never leaked into logs."
4
- icon: "KeyRound"
5
- source: "docs/spec/unified-theory.md"
6
- ---
7
-
8
- Vault is where your app's **protected knowledge** lives: API keys, database URLs, tokens — plus non-secret config like a public app URL. This page shows how to declare a secret, give it a value, and read it in a Flow, then how OKE keeps it safe in production.
9
-
10
- <Callout title="The one rule">
11
- You declare **contracts**, never values, in code. Values come from the environment at boot — a
12
- secret that has no value anywhere fails the boot loudly, with every gap listed at once.
13
- </Callout>
14
-
15
- ## Quick start
16
-
17
- <Steps>
18
-
19
- <Step>
20
- ### Declare the contract
21
-
22
- In `src/vault.ts`, declare what your app needs. This says "a secret named `STRIPE_KEY` exists" — it does **not** contain the key itself:
23
-
24
- ```typescript title="src/vault.ts"
25
- import { vault } from "okengine";
26
- import { z } from "zod";
27
-
28
- export const stripeKey = vault.secret("STRIPE_KEY", {
29
- description: "Payments gateway key",
30
- rotate: "90d",
31
- schema: z.string().startsWith("sk_"),
32
- dev: "sk_test_local", // used only by `oke dev` (local) when nothing else provides a value
33
- });
34
- ```
35
-
36
- </Step>
37
-
38
- <Step>
39
- ### Give it a value
40
-
41
- For local development, put the real value in `.env.local` (gitignored):
42
-
43
- ```bash title=".env.local"
44
- STRIPE_KEY=sk_test_your_key_here
45
- ```
46
-
47
- Or set it from the CLI — it writes to the right place for the active mode:
48
-
49
- ```bash
50
- oke vault set STRIPE_KEY sk_test_your_key_here
51
- ```
52
-
53
- </Step>
54
-
55
- <Step>
56
- ### Read it in a Flow
57
-
58
- Flows read secrets through `fx.vault.get` — never through `process.env`. It resolves to a
59
- `Redacted<string>`: printing, logging, or serializing it yields a placeholder, never the value.
60
- Call `.reveal()` once at the boundary that needs the real credential:
61
-
62
- ```typescript title="src/flows/billing/charge.ts"
63
- export const charge = on(
64
- http.post("/charge"),
65
- flow("billing.charge", {
66
- in: ChargeInput,
67
- out: z.object({ id: z.string() }),
68
- do: async (input, fx) => {
69
- const key = await fx.vault.get(stripeKey); // Redacted — safe to pass to fx.log
70
- const intent = await stripe(key.reveal()).create(input);
71
- return { id: intent.id };
72
- },
73
- }),
74
- );
75
- ```
76
-
77
- `fx.log` masks any `Redacted` found in the logged data (nested included). A revealed string that
78
- still reaches `fx.log` is scrubbed by the boot redactor as before.
79
-
80
- </Step>
81
-
82
- </Steps>
83
-
84
- That's the whole loop: declare → set → read. Everything below is what OKE guarantees on top of it.
85
-
86
- ## Redacted until you reveal
87
-
88
- <VaultRedacted />
89
-
90
- Pass the wrapper freely — `fx.log`, `String()`, `JSON.stringify`, and
91
- `console.log` / `util.inspect` all yield `[redacted]` (or a `Redacted<…>` label).
92
- Call `.reveal()` once at the provider boundary that needs the credential.
93
-
94
- ## Two kinds of contracts
95
-
96
- | Declaration | Sensitive? | Console shows | Use for |
97
- | ----------------------------------- | ---------- | ----------------------------------- | --------------------------- |
98
- | `vault.secret("STRIPE_KEY", …)` | yes | fingerprint only | API keys, tokens, passwords |
99
- | `vault.config("PUBLIC_APP_URL", …)` | no | **Config** band, value in the clear | Public URLs, feature flags |
100
-
101
- `vault(name, …)` is shorthand for `vault.secret(name, …)`.
102
-
103
- <Callout title="Config is the one place for non-secret variables">
104
- `vault.config()` is the contract the Console **Config** band lists and edits. Declare it once; set
105
- the value from Console, `oke vault set`, or the resolution chain. Do not use `vault.env` for
106
- values you want to see or change on `/vault`.
107
- </Callout>
108
-
109
- ```typescript title="src/vault.ts"
110
- export const publicAppUrl = vault.config("PUBLIC_APP_URL", {
111
- description: "Public site origin",
112
- dev: "http://127.0.0.1:6530",
113
- });
114
- ```
115
-
116
- ```bash title=".env.local"
117
- PUBLIC_APP_URL=https://app.example.com
118
- ```
119
-
120
- ```typescript title="src/flows/site/render.ts"
121
- do: async (_input, fx) => {
122
- const origin = (await fx.vault.get(publicAppUrl)).reveal();
123
- return { canonical: `${origin}/` };
124
- },
125
- ```
126
-
127
- **Consequence:** `/vault` lists this under **Config** in the clear. `fx.vault.get` still
128
- returns `Redacted` — `.reveal()` is the read. `vault.env("PUBLIC_APP_URL")` never appears
129
- on that page.
130
-
131
- ### Plain environment variables
132
-
133
- `vault.env` reads `process.env` synchronously for values that need no contract — a port, a feature flag, a log level. It never joins the resolution chain, never appears in the Console, never gets a fingerprint, and never gets redacted.
134
-
135
- | Call | Returns | On a missing value |
136
- | -------------------------------- | --------------------- | -------------------------------------- |
137
- | `vault.env("LOG_LEVEL")` | `string \| undefined` | `undefined` (empty counts as missing) |
138
- | `vault.env.required("REGION")` | `string` | Throws, and boot lists it as a gap |
139
- | `vault.env.int("PORT", 3000)` | `number` | The default; throws when none is given |
140
- | `vault.env.bool("DEBUG", false)` | `boolean` | The default; throws when none is given |
141
- | `vault.env.json("FLAGS")` | `T \| undefined` | `undefined`; throws on malformed JSON |
142
-
143
- Every name passed to `vault.env.required` is registered, so boot reports missing variables in the same `VaultBootError` as missing secrets — before it opens a database connection.
144
-
145
- ### Contract options
146
-
147
- | Option | Type | Meaning |
148
- | ------------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
149
- | `description` | string | Human title in boot-gap listings and the Console (falls back to the key) |
150
- | `rotate` | string | Cadence (`"90d"`) or `"never"` when the secret must not rotate. Omit is the same as `"never"`. Console shows `no rotate` and skips `is:overdue`. |
151
- | `schema` | zod / Standard Schema | Validated at boot; a bad value fails boot like a missing one |
152
- | `dev` | string | Local-only fallback when no source provides a value (never used in prod) |
153
- | `sensitive` | boolean | Override the default (`true` for secrets, `false` for config) |
154
- | `perTenant` | boolean | Resolve at request time under `{tenantId}/{contract}`. Default `true` when `gate.auth.tenant` is on. Boot skips these contracts. |
155
-
156
- ### Zero-setup Compose fallback
157
-
158
- `dev: vault.fromDocker("store.sql")` resolves the connection URL that `oke dev` generated for that role — no manual copying of Postgres URLs:
159
-
160
- ```typescript
161
- export const dbUrl = vault.secret("DATABASE_URL", {
162
- dev: vault.fromDocker("store.sql"),
163
- });
164
- ```
165
-
166
- ## Where values come from
167
-
168
- At boot, each contract is resolved through this chain — **first hit wins**.
169
- A value already in the vault / managed backend wins over a leftover env pin.
170
-
171
- <VaultResolution />
172
-
173
- If every layer misses a contract, boot **fails** before any request is served:
174
-
175
- ```text
176
- vault boot failed — 1 missing secret(s):
177
- - STRIPE_KEY: Payments gateway key
178
- ```
179
-
180
- <Callout title="Good to know">
181
- This is the fail-loud contract: an app with a missing secret **never** boots halfway and fails
182
- later at request time. All gaps are listed in one error, not one at a time.
183
- </Callout>
184
-
185
- ## Setting and rotating values
186
-
187
- | Command | What it does |
188
- | -------------------------------------------------- | ----------------------------------------------------------------------------- |
189
- | `oke vault set NAME value` | Write a value to the env file (`.env.local` by default) |
190
- | `oke vault list` | List names present in the active store |
191
- | `oke vault import <file>` | Bulk-import names from a dotenv file |
192
- | `oke vault init` | Initialize the built-in encrypted store (prints the master key once) |
193
- | `oke vault status` / `seal` / `unseal` | Built-in seal lifecycle |
194
- | `oke vault rotate <path>` / `rotate-master` | Re-encrypt a secret, or rewrap every DEK under a new master (exclusive lease) |
195
- | `oke vault audit` / `audit verify` / `audit purge` | Hash-chained audit (serialized appends; no secret values) |
196
- | `oke vault purge-expired [--dry-run] [--before]` | Hard-delete secret rows past `expires_at` (operator cleanup) |
197
- | `oke vault backup` / `restore` | Encrypted backup (atomic write + end marker; separate backup KEK) |
198
-
199
- Flows can write too, through the same capability gate as reads: `fx.vault.set(path, value, { ttlMs?, metadata? })`, `fx.vault.rotate(path, value)`, `fx.vault.delete(path)`, plus `fx.vault.list(prefix?)` and `fx.vault.status()`. These need the encrypted-at-rest backend (`drivers.vault = "vault"`) and throw without it; `fx.vault.get` works on every app.
200
-
201
- The **Console** (`:6533`) **Vault** page (`/vault`) groups **Secrets** and
202
- **Config**. Secrets are write-only: a salted fingerprint (`sha256:…`), never
203
- the cleartext. Config rows show the value — that is `vault.config()`.
204
-
205
- API keys are principals — mint them on **Access** (`/access`), not Vault.
206
- See [Gate](/docs/elements/gate#api-keys).
207
-
208
- Add (`+`) creates a contract from Console as well as from source. Those rows
209
- show `console` until you declare the same name in the Manifest.
210
-
211
- Search matches name, description, fingerprint, reader, and winner. Operators
212
- AND together. `/` focuses the field.
213
-
214
- | Token | Matches |
215
- | ------------------------------------------------------ | ------------------------------- |
216
- | `is:unset` / `is:set` / `is:healthy` | Value present or not |
217
- | `is:blast` / `is:shared` / `is:dormant` / `is:overdue` | Posture |
218
- | `kind:secret` / `kind:config` | Contract kind |
219
- | `from:.env.local` | Resolution winner |
220
- | `reader:payments` / `fp:sha256` | Flow id / fingerprint |
221
- | `has:readers` / `has:rotate` | Declared readers or rotate hint |
222
-
223
- The empty pane is a posture board (unset, blast, shared, dormant, overdue).
224
- Rotate shows **blast radius** — in-flight durable runs that will wake holding
225
- the new value.
226
-
227
- Verify, rotate-master, fingerprint export, and CLI copy live in the security
228
- sheet.
229
-
230
- | Action | Confirm | HTTP |
231
- | -------------------- | ---------------------------- | -------------------------------------------------------------------------- |
232
- | Add a contract | review dialog | `POST /console/vault/create` — lists as `console` until declared in source |
233
- | Set / rotate a value | reason + review dialog | `POST /console/vault/set` · `/rotate` |
234
- | Rotate master key | `ROTATE_MASTER` + reason ≥ 3 | `POST /console/vault/rotate-master` — one batch; `remaining` is honest |
235
- | Verify audit chain | session only | `GET /console/vault/audit/verify` → `{ ok, brokenAt, reason, row }` |
236
-
237
- Master rotation is process-global: any operator in the same Console process may
238
- continue. Overlapping batches return `VaultRotateBusy`. A generated master key
239
- is shown once and never logged.
240
-
241
- Backup stays on the CLI (`oke vault backup` / `restore`). The Console never
242
- accepts a master key in the HTTP body — unseal via `OKE_VAULT_MASTER_KEY`.
243
-
244
- <Callout title="Builtin concurrency (rotate / audit / backup)">
245
- `rotate-master` holds a lease (`FOR UPDATE` + lease TTL) so exactly one batch runs at a time; a
246
- busy audit append briefly waits rather than being misread as "lease held". Audit appends serialize
247
- under a transactional write lock; backups use temp → fsync → rename with end marker + checksum.
248
- </Callout>
249
-
250
- <Callout title="Builtin master keys and expired rows">
251
- Resolve the master key with `--key -` (stdin), `OKE_VAULT_MASTER_KEY`, or a hidden TTY prompt —
252
- never put keys on argv in shared shells (history risk). Expired rows stay until `oke vault
253
- purge-expired` (use `--dry-run` first, or schedule via cron).
254
- </Callout>
255
-
256
- <Callout title="Secrets never reach logs">
257
- `fx.vault.get` returns `Redacted` — `fx.log` shows `[redacted]`. A revealed string that still
258
- reaches a log is scrubbed by the boot redactor to `[redacted:secret]`. Traces and the Console get
259
- fingerprints, never cleartext.
260
- </Callout>
261
-
262
- ## Per-environment drivers
263
-
264
- Which backend holds your values depends on the environment — configured once in `oke.config.ts`.
265
- App boot and the Console share the same chain: **backend first**, then env files:
266
-
267
- ```typescript title="oke.config.ts"
268
- drivers: {
269
- vault: {
270
- dev: "env", // process env / .env.local
271
- test: "memory",
272
- prod: "vault", // built-in encrypted store (Postgres you already run)
273
- },
274
- },
275
- ```
276
-
277
- Defaults are `env` / `memory` / `vault`. create-oke templates pin the built-in store for prod.
278
-
279
- | Driver | Backend | Best for |
280
- | --------- | ----------------------------------------------------------- | ---------------------------------- |
281
- | `env` | process env | Local pins — no encryption at rest |
282
- | `vault` | Postgres/PGlite envelope (AES-256-GCM) | Default prod — no extra container |
283
- | `managed` | Official SM (`OKE_VAULT_PROVIDER`) or platform-injected env | Cloud SM / Fly / Railway / K8s |
284
- | `memory` | in-process map | Tests |
285
-
286
- ### Threat model (honest)
287
-
288
- Built-in Vault protects a **database dump** (ciphertext + wrapped DEKs). It does **not** equal a separate process-isolated vault:
289
-
290
- | Threat | Built-in `vault` | Managed remote vault |
291
- | --------------------------------------------- | ---------------------------------- | --------------------------- |
292
- | Postgres dump / backup leak | Protected (need master/KEK) | Protected |
293
- | App RCE / memory dump | Game over (same process) | Better if vault is isolated |
294
- | Master key only in `.env` next to app secrets | Weak — use KMS auto-unseal in prod | Prefer non-exportable KEK |
295
- | JS `Buffer.fill(0)` vs remote `mlock` | Hygiene only — not claimed | Stronger outside the app |
296
-
297
- For production built-in stores, set `vault.encryption.masterKey` to a KMS source (optional peer
298
- `@aws-sdk/client-kms`) or use `managed` with a provider below. `oke doctor` warns when prod would
299
- take the master key from the environment.
300
-
301
- ## Tenant isolation (built-in store)
302
-
303
- When `gate.auth.tenant` is on, `perTenant` contracts resolve at request time under
304
- `{tenantId}/{contract}`. Boot skips those contracts.
305
-
306
- The built-in Postgres table `oke_vault_secrets` carries `tenant_id` and the same
307
- `oke.tenant()` helper as domain tables — not a second GUC.
308
-
309
- <Callout title="RLS on ciphertext rows">
310
- `tenant_id = oke.tenant() OR tenant_id IS NULL`. ENABLE without FORCE: the adapter (owner) still
311
- sees every row; Console / `oke_app` cannot list another tenant's ciphertext. Global `NULL` rows
312
- stay visible to every stamped tenant.
313
- </Callout>
314
-
315
- ## Managed providers (official)
316
-
317
- Set `drivers.vault` to `"managed"` and `OKE_VAULT_PROVIDER` to an id below. Omit the provider when
318
- the platform already injects secrets as env vars (Fly, Railway, Kubernetes).
319
-
320
- | Provider | `OKE_VAULT_PROVIDER` | Connection | Optional peer |
321
- | ------------------- | --------------------- | --------------------------------------------------------------------------------- | --------------------------------------------- |
322
- | AWS Secrets Manager | `aws-secrets-manager` | `OKE_VAULT_REGION`, `OKE_VAULT_MOUNT` (name prefix) | `@aws-sdk/client-secrets-manager` |
323
- | Azure Key Vault | `azure-key-vault` | `OKE_VAULT_URL` (vault URI), `OKE_VAULT_MOUNT` (prefix) | `@azure/keyvault-secrets` + `@azure/identity` |
324
- | GCP Secret Manager | `gcp-secret-manager` | `OKE_VAULT_MOUNT` (`project` or `project/prefix`) | `@google-cloud/secret-manager` |
325
- | Doppler | `doppler` | `OKE_VAULT_TOKEN`; `OKE_VAULT_MOUNT` as `project/config` for personal tokens | — |
326
- | 1Password Connect | `1password` | `OKE_VAULT_URL` (Connect host), `OKE_VAULT_TOKEN`, `OKE_VAULT_MOUNT` (vault name) | — |
327
-
328
- AWS, Azure, and GCP use that cloud's default credential chain. Azure names allow only letters,
329
- numbers, and hyphens — OKE maps `_` in the contract name to `-` on the wire.
330
-
331
- ## Community / plugin
332
-
333
- OpenBao and HashiCorp Vault are not shipped in core. Implement a community adapter for the
334
- `managed` driver surface, or keep using built-in `vault` / `env`.
335
-
336
- ## Troubleshooting
337
-
338
- <Accordions>
339
- <Accordion title="Boot fails with VaultBootError listing missing secrets">
340
-
341
- A contract has no value in any layer of the chain. Fix by providing it in exactly one place:
342
-
343
- - locally: add `NAME=value` to `.env.local` (or run `oke vault set NAME value`)
344
- - built-in store: `oke vault init` then unseal, or set via Console (write-only)
345
- - CI / hosting: set a real environment variable (or the managed provider when `managed`)
346
-
347
- </Accordion>
348
- <Accordion title="Does the keel example put secrets in Vault?">
349
-
350
- Yes — this example only (prod posture). `oke db seed` (dev) writes the keel
351
- stubs and copies minted stack URLs into the built-in store. `.env.local` keeps
352
- `OKE_VAULT_MASTER_KEY` and `PORT`; other apps leave Vault empty.
353
-
354
- </Accordion>
355
- <Accordion title="How do I rotate a key safely?">
356
-
357
- Set the new value (`oke vault set` or the Console). The Console shows blast
358
- radius before you rotate, and `is:overdue` when a secret is past its
359
- `rotate: "90d"` hint. `rotate: "never"` (or omit `rotate`) shows `no rotate`.
360
-
361
- </Accordion>
362
- <Accordion title="How do I pass the builtin master key without shell history?">
363
-
364
- Prefer `oke vault unseal --key -` and pipe the key on stdin, or omit `--key` on a
365
- TTY and type it at the hidden prompt. Avoid `--key <base64>` on shared hosts.
366
-
367
- </Accordion>
368
- <Accordion title="Console SQL lists another tenant's vault rows">
369
-
370
- User-plane SQL is stamped `oke.tenant()`. The policy hides other tenants' ciphertext
371
- and keeps global `NULL` rows. The Vault adapter is table owner, so ENABLE (not FORCE)
372
- does not hide rows from itself.
373
-
374
- </Accordion>
375
- <Accordion title="Expired secrets still take space in Postgres">
376
-
377
- `expires_at` fails closed on read, but rows stay until you hard-delete them:
378
-
379
- ```bash
380
- oke vault purge-expired --dry-run
381
- oke vault purge-expired
382
- ```
383
-
384
- Schedule the live command with cron when you want automatic cleanup.
385
-
386
- </Accordion>
387
- </Accordions>
388
-
389
- ## Learn more
390
-
391
- - [Project structure](/docs/get-started/project-structure) — `flow({…})` names as `unit.export`; `flow("billing.charge")` still wins
392
- - [Flow](/docs/elements/flow) — how `fx.vault.get` reads secrets inside `do`
393
- - [Gate](/docs/elements/gate) — `perTenant` contracts when `gate.auth.tenant` is on
394
- - [CLI Reference](/docs/reference/cli) — `oke vault set` · `list` · `import`
395
-
396
- ## Next
397
-
398
- <Cards>
399
- <Card title="Channel" description="Continue to Channel." href="/docs/elements/channel" />
400
- <Card
401
- title="Introduction"
402
- description="Eight elements overview."
403
- href="/docs/get-started/introduction"
404
- />
405
- </Cards>
@@ -1,173 +0,0 @@
1
- ---
2
- title: Basic Usage
3
- description: Scaffold the standard Notes starter, call health and notes Flows, and inspect them in the Console.
4
- source: packages/create-oke/templates/standard
5
- icon: SquareTerminal
6
- ---
7
-
8
- Write your first Flow, call it from a typed client, and prove it with
9
- `bun:test` — using the same standard Notes starter `create-oke` scaffolds.
10
-
11
- <Callout title="The one rule">
12
- All reads, writes, emits, sends, and external calls belong behind `fx`. That is what makes effects
13
- inspectable and tests deterministic.
14
- </Callout>
15
-
16
- ## Quick start
17
-
18
- <Steps>
19
-
20
- <Step>
21
- ### Scaffold and run
22
-
23
- ```bash title="Terminal"
24
- bunx create-oke@latest my-app
25
- cd my-app
26
- oke dev
27
- bun run web
28
- ```
29
-
30
- Use `--template advanced` for the same Notes domain with files attach, a daily
31
- digest Clock, and an AI summarize stub.
32
-
33
- To exercise Docker with a larger domain, run `examples/keel` from the okengine
34
- repo (`bun run dev:keel`) — not a create-oke template.
35
-
36
- Open **6530** in a browser to read the envelope in a code block. The right rail
37
- lists HTTP routes — static GET paths are links. `curl` still gets `{ data, error }`.
38
-
39
- <Surfaces />
40
-
41
- </Step>
42
-
43
- <Step>
44
- ### Read the health Flow
45
-
46
- The standard starter already exports a named health Flow:
47
-
48
- ```typescript title="flows/main/health.ts"
49
- import { on, flow, http } from "okengine/http";
50
-
51
- export const health = on(http.get().public(), flow({ do: () => ({ ok: true }) }));
52
- ```
53
-
54
- `main` omits the URL prefix, so this file is `GET /health` named `main.health`. See [Project structure](/docs/get-started/project-structure).
55
-
56
- Named flows show up as `main.health` (not `flow_1`) in `oke dev` logs, with the run id after the timestamp.
57
- Change the route or output and save — App and Console update together from the
58
- same Manifest.
59
-
60
- </Step>
61
-
62
- <Step>
63
- ### Call it from a typed client
64
-
65
- Generated units become namespaces on the client:
66
-
67
- ```typescript title="app"
68
- import "@/core";
69
- import "@/flows/generated";
70
- import { oke } from "okengine/http";
71
-
72
- export const app = oke({ name: "notes" });
73
- export type App = typeof app;
74
- ```
75
-
76
- `import "@/core"` loads stores, secrets, gates, clocks, channels, and
77
- message catalogs (via `locales/index.ts`) so they auto-register before `oke()`.
78
-
79
- ```typescript title="client"
80
- import { createClient } from "okengine/client";
81
- import type { App } from "./app";
82
-
83
- const api = createClient<App>("http://localhost:6530");
84
- const { data, error } = await api.main.health({});
85
- ```
86
-
87
- `data` and `error` are inferred from the Flow contracts.
88
-
89
- The starter `web/` app uses `createClient("")` so Vite proxies `/notes` and
90
- `/health` to the app. Bearer: `auth: { getToken, refresh }`. See [Client](/docs/reference/client).
91
-
92
- </Step>
93
-
94
- </Steps>
95
-
96
- ## Mental model
97
-
98
- Every backend behavior has one shape:
99
-
100
- <FlowShape />
101
-
102
- ## From Flow to client
103
-
104
- Export → generated barrel → call or test. Same App type — no separate codegen project.
105
-
106
- <ClientLoop />
107
-
108
- ## Test
109
-
110
- Boot the same app with test drivers:
111
-
112
- ```typescript title="tests/standard.test.ts"
113
- import { expect, test } from "bun:test";
114
- import { createTestApp } from "okengine/test";
115
- import { app } from "../src/app";
116
-
117
- test("boots — health flow", async () => {
118
- const t = await createTestApp(app);
119
- const { data, error } = await t.api.main.health({});
120
- expect(error).toBeNull();
121
- expect(data).toEqual({ ok: true });
122
- });
123
- ```
124
-
125
- ```bash title="Terminal"
126
- bun test
127
- ```
128
-
129
- ## Troubleshooting
130
-
131
- <Accordions>
132
-
133
- <Accordion title="api.main.health is not a function / type error">
134
- Confirm the Flow is `export`ed from a generated unit (`import "@/flows/generated"` then `oke({ name })`), or from a module you still `.adopt({ main })`.
135
-
136
- Type `createClient` with your `App` type. Restart `oke dev` after renaming exports so the Manifest refreshes.
137
-
138
- </Accordion>
139
-
140
- <Accordion title="createTestApp fails to boot">
141
- The starter patches test env and stores on the app options. Keep the template's side-imports
142
- (vault, gates, channels, core db) — removing them can leave Vault or Store unresolved under test
143
- drivers.
144
- </Accordion>
145
-
146
- </Accordions>
147
-
148
- ## Learn more
149
-
150
- - [Project structure](/docs/get-started/project-structure) — folders are the URL
151
- - [Flow](/docs/elements/flow) — triggers, contracts, effects, and composition
152
- - [Store](/docs/elements/store) — SQL, KV, files, index, and the preferred list envelope
153
- - [fx](/docs/reference/fx) — the full effect surface
154
-
155
- ## Next
156
-
157
- <Cards>
158
- <Card
159
- title="Project structure"
160
- description="Folders are the URL; unit plus export is the name."
161
- href="/docs/get-started/project-structure"
162
- />
163
- <Card
164
- title="Flow"
165
- description="Triggers, contracts, effects, and composition."
166
- href="/docs/elements/flow"
167
- />
168
- <Card
169
- title="Store"
170
- description="SQL, KV, files, index, and declarative resources."
171
- href="/docs/elements/store"
172
- />
173
- </Cards>
@@ -1,43 +0,0 @@
1
- ---
2
- title: "Get Started"
3
- description: "From the one law to a running app — introduction, why OKE, install, and first flows."
4
- icon: "Rocket"
5
- source: "docs/spec/unified-theory.md"
6
- ---
7
-
8
- Learn the shape once, install on Bun, then write your first Flow from the standard starter.
9
-
10
- ## Pages
11
-
12
- <Cards>
13
- <Card
14
- title="Introduction"
15
- description="One law, eight elements, one contract."
16
- href="/docs/get-started/introduction"
17
- />
18
- <Card
19
- title="Why OKE"
20
- description="Six seams every backend maintains by hand."
21
- href="/docs/get-started/why"
22
- />
23
- <Card
24
- title="Installation"
25
- description="Scaffold with create-oke and open the Console."
26
- href="/docs/get-started/installation"
27
- />
28
- <Card
29
- title="Basic Usage"
30
- description="Health Flow, typed client, Console proof."
31
- href="/docs/get-started/basic-usage"
32
- />
33
- <Card
34
- title="Project structure"
35
- description="Folder and file conventions — URL, name, and the generated barrel."
36
- href="/docs/get-started/project-structure"
37
- />
38
- <Card
39
- title="Deployment"
40
- description="Compose, Swarm, Kubernetes, and reverse proxy."
41
- href="/docs/deployment"
42
- />
43
- </Cards>