okengine 0.18.4 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (512) hide show
  1. package/AGENTS.md +18 -10
  2. package/README.md +2 -2
  3. package/package.json +51 -50
  4. package/site/content/docs/ai/index.mdx +25 -6
  5. package/site/content/docs/ai/llms-txt.mdx +1 -1
  6. package/site/content/docs/ai/meta.json +1 -1
  7. package/site/content/docs/ai/skills.mdx +4 -1
  8. package/site/content/docs/ai/try-it.mdx +58 -0
  9. package/site/content/docs/client/auth.mdx +208 -0
  10. package/site/content/docs/client/calling.mdx +451 -0
  11. package/site/content/docs/client/index.mdx +209 -0
  12. package/site/content/docs/client/live.mdx +234 -0
  13. package/site/content/docs/client/meta.json +5 -0
  14. package/site/content/docs/client/react.mdx +249 -0
  15. package/site/content/docs/elements/ai/agents.mdx +232 -0
  16. package/site/content/docs/elements/ai/index.mdx +341 -0
  17. package/site/content/docs/elements/ai/mcp.mdx +275 -0
  18. package/site/content/docs/elements/ai/meta.json +5 -0
  19. package/site/content/docs/elements/ai/models.mdx +283 -0
  20. package/site/content/docs/elements/ai/prompts.mdx +256 -0
  21. package/site/content/docs/elements/channel/email.mdx +266 -0
  22. package/site/content/docs/elements/channel/index.mdx +344 -0
  23. package/site/content/docs/elements/channel/meta.json +5 -0
  24. package/site/content/docs/elements/channel/push.mdx +218 -0
  25. package/site/content/docs/elements/channel/receipts.mdx +206 -0
  26. package/site/content/docs/elements/channel/sms.mdx +264 -0
  27. package/site/content/docs/elements/channel/whatsapp.mdx +220 -0
  28. package/site/content/docs/elements/clock/index.mdx +300 -0
  29. package/site/content/docs/elements/clock/meta.json +5 -0
  30. package/site/content/docs/elements/clock/schedules.mdx +508 -0
  31. package/site/content/docs/elements/clock/sleep.mdx +445 -0
  32. package/site/content/docs/elements/flow/consumers.mdx +707 -0
  33. package/site/content/docs/elements/flow/http.mdx +1080 -0
  34. package/site/content/docs/elements/flow/index.mdx +618 -0
  35. package/site/content/docs/elements/flow/meta.json +5 -0
  36. package/site/content/docs/elements/flow/routing.mdx +559 -0
  37. package/site/content/docs/elements/flow/workflows.mdx +640 -0
  38. package/site/content/docs/elements/gate/auth.mdx +371 -0
  39. package/site/content/docs/elements/gate/authorization.mdx +298 -0
  40. package/site/content/docs/elements/gate/index.mdx +418 -0
  41. package/site/content/docs/elements/gate/meta.json +5 -0
  42. package/site/content/docs/elements/gate/rate-limits.mdx +365 -0
  43. package/site/content/docs/elements/gate/rls.mdx +303 -0
  44. package/site/content/docs/elements/gate/tenancy.mdx +372 -0
  45. package/site/content/docs/elements/index.mdx +52 -11
  46. package/site/content/docs/elements/signal/broadcast.mdx +517 -0
  47. package/site/content/docs/elements/signal/index.mdx +352 -0
  48. package/site/content/docs/elements/signal/live.mdx +590 -0
  49. package/site/content/docs/elements/signal/meta.json +5 -0
  50. package/site/content/docs/elements/signal/once.mdx +596 -0
  51. package/site/content/docs/elements/store/files.mdx +659 -0
  52. package/site/content/docs/elements/store/index.mdx +310 -0
  53. package/site/content/docs/elements/store/kv.mdx +629 -0
  54. package/site/content/docs/elements/store/meta.json +5 -0
  55. package/site/content/docs/elements/store/search.mdx +946 -0
  56. package/site/content/docs/elements/store/sql.mdx +937 -0
  57. package/site/content/docs/elements/vault/config.mdx +256 -0
  58. package/site/content/docs/elements/vault/index.mdx +356 -0
  59. package/site/content/docs/elements/vault/meta.json +5 -0
  60. package/site/content/docs/elements/vault/rotation.mdx +273 -0
  61. package/site/content/docs/elements/vault/secrets.mdx +285 -0
  62. package/site/content/docs/index.mdx +78 -30
  63. package/site/content/docs/meta.json +11 -8
  64. package/site/content/docs/plugins/cors.mdx +2 -1
  65. package/site/content/docs/plugins/csrf.mdx +4 -1
  66. package/site/content/docs/plugins/headers.mdx +2 -1
  67. package/site/content/docs/plugins/ip-allowlist.mdx +2 -1
  68. package/site/content/docs/plugins/magic-link.mdx +6 -0
  69. package/site/content/docs/plugins/maintenance-mode.mdx +2 -1
  70. package/site/content/docs/plugins/oauth.mdx +1 -1
  71. package/site/content/docs/plugins/otp.mdx +12 -1
  72. package/site/content/docs/plugins/passkey.mdx +39 -15
  73. package/site/content/docs/plugins/two-factor.mdx +91 -34
  74. package/site/content/docs/plugins/username.mdx +1 -1
  75. package/site/content/docs/recipes/caddy.mdx +3 -3
  76. package/site/content/docs/recipes/index.mdx +18 -28
  77. package/site/content/docs/recipes/mailpit.mdx +1 -1
  78. package/site/content/docs/recipes/meilisearch.mdx +3 -3
  79. package/site/content/docs/recipes/meta.json +1 -4
  80. package/site/content/docs/recipes/nginx.mdx +2 -2
  81. package/site/content/docs/recipes/openrouter.mdx +283 -0
  82. package/site/content/docs/recipes/pgdog.mdx +3 -3
  83. package/site/content/docs/recipes/postgres.mdx +1 -2
  84. package/site/content/docs/recipes/rustfs.mdx +2 -2
  85. package/site/content/docs/recipes/traefik.mdx +3 -3
  86. package/site/content/docs/reference/cli.mdx +231 -0
  87. package/site/content/docs/reference/configuration.mdx +30 -10
  88. package/site/content/docs/reference/environment-variables.mdx +93 -20
  89. package/site/content/docs/reference/errors.mdx +132 -29
  90. package/site/content/docs/reference/fx.mdx +137 -73
  91. package/site/content/docs/reference/index.mdx +13 -21
  92. package/site/content/docs/reference/meta.json +4 -5
  93. package/site/content/docs/reference/okid.mdx +42 -17
  94. package/site/content/docs/reference/plugins.mdx +4 -3
  95. package/site/content/docs/reference/security.mdx +197 -0
  96. package/site/content/docs/understand/meta.json +5 -0
  97. package/site/content/docs/understand/the-anatomy.mdx +132 -0
  98. package/site/content/docs/understand/the-model.mdx +32 -0
  99. package/site/content/docs/understand/the-problem.mdx +74 -0
  100. package/site/content/docs/understand/the-vocabulary.mdx +26 -0
  101. package/src/auth/api-keys.ts +2 -1
  102. package/src/auth/bindings.ts +64 -16
  103. package/src/auth/gate-auth.test.ts +6 -1
  104. package/src/auth/identity.ts +152 -5
  105. package/src/auth/index.ts +29 -0
  106. package/src/auth/invites.ts +2 -1
  107. package/src/auth/method-context.ts +41 -0
  108. package/src/auth/oauth-as/crypto.ts +2 -1
  109. package/src/auth/oauth-as/stores.ts +2 -1
  110. package/src/auth/operator.ts +2 -1
  111. package/src/auth/sessions-jwt.test.ts +77 -0
  112. package/src/auth/sessions.ts +20 -4
  113. package/src/auth/tenants.ts +3 -2
  114. package/src/auth/two-factor-challenge.test.ts +61 -0
  115. package/src/auth/two-factor-challenge.ts +284 -0
  116. package/src/auth/verification.ts +5 -0
  117. package/src/bench/REPORT.md +49 -0
  118. package/src/bench/g03-signal-once.bench.ts +1 -1
  119. package/src/bench/g10-observability-contention.bench.ts +1 -1
  120. package/src/bench/g17-hybrid-search.bench.ts +572 -0
  121. package/src/bench/load-app.ts +2 -10
  122. package/src/cli/ai-setup/ai-setup.test.ts +331 -42
  123. package/src/cli/ai-setup/apply.ts +294 -52
  124. package/src/cli/ai-setup/catalog.ts +238 -1342
  125. package/src/cli/ai-setup/index.ts +14 -99
  126. package/src/cli/ai-setup/prompts.ts +60 -443
  127. package/src/cli/ask-seed.test.ts +96 -0
  128. package/src/cli/ask-seed.ts +82 -0
  129. package/src/cli/ask-vault-gaps.test.ts +84 -0
  130. package/src/cli/ask-vault-gaps.ts +146 -0
  131. package/src/cli/build.ts +2 -2
  132. package/src/cli/client-add.test.ts +26 -1
  133. package/src/cli/client-add.ts +106 -27
  134. package/src/cli/competitor-mention-removal.test.ts +1 -1
  135. package/src/cli/db-seed.ts +2 -0
  136. package/src/cli/db.ts +150 -11
  137. package/src/cli/dev.ts +119 -211
  138. package/src/cli/docker-clean.ts +2 -2
  139. package/src/cli/docker-cli.test.ts +1 -1
  140. package/src/cli/doctor-diff.ts +4 -2
  141. package/src/cli/doctor-pii.test.ts +1 -1
  142. package/src/cli/doctor.ts +14 -1
  143. package/src/cli/hero-meta.test.ts +4 -2
  144. package/src/cli/load-config.images.test.ts +8 -10
  145. package/src/cli/load-config.ts +1 -1
  146. package/src/cli/registry.ts +22 -10
  147. package/src/cli/replay.ts +3 -1
  148. package/src/cli/start.ts +1 -1
  149. package/src/cli/tui/keys.ts +2 -3
  150. package/src/client/auth/cookies.ts +74 -0
  151. package/src/client/auth/create-auth-client.ts +636 -0
  152. package/src/client/auth/denials.ts +99 -0
  153. package/src/client/auth/session.ts +283 -0
  154. package/src/client/auth.test.ts +251 -0
  155. package/src/client/auth.ts +39 -114
  156. package/src/client/create-with-session.ts +245 -0
  157. package/src/client/create.ts +51 -5
  158. package/src/client/index.ts +11 -1
  159. package/src/client/live.ts +11 -79
  160. package/src/client/notes-contract.test.ts +5 -10
  161. package/src/client/sse.ts +137 -0
  162. package/src/client/stream.ts +147 -0
  163. package/src/client/transport.test.ts +32 -0
  164. package/src/client/transport.ts +123 -26
  165. package/src/client/types.ts +118 -14
  166. package/src/client-react/index.ts +185 -24
  167. package/src/client-react/use-live-query.ts +13 -3
  168. package/src/compiler/aot.test.ts +7 -4
  169. package/src/compiler/effects-embed.test.ts +56 -0
  170. package/src/compiler/effects-fetch.test.ts +43 -0
  171. package/src/compiler/effects-infer.ts +58 -2
  172. package/src/compiler/extract.test.ts +258 -44
  173. package/src/compiler/extract.ts +566 -48
  174. package/src/compiler/fixtures/skyport/src/flows/bookings/index.ts +7 -4
  175. package/src/compiler/fixtures/skyport/src/flows/bookings/signals.ts +2 -8
  176. package/src/compiler/fixtures/skyport.expected.json +4 -4
  177. package/src/compiler/fixtures/triggers/five-triggers.ts +14 -10
  178. package/src/compiler/response.ts +2 -2
  179. package/src/compiler/search-writer-isolation.test.ts +40 -0
  180. package/src/config/index.ts +11 -0
  181. package/src/console/server/app.ts +17 -23
  182. package/src/console/server/bind.ts +4 -0
  183. package/src/console/server/console.test.ts +2 -2
  184. package/src/console/server/flows-invoke.test.ts +50 -34
  185. package/src/console/server/flows.ts +436 -255
  186. package/src/console/server/runs-ingest.test.ts +6 -3
  187. package/src/console/server/serve.ts +1 -1
  188. package/src/console/server/signals.test.ts +1 -5
  189. package/src/console/server/signals.ts +8 -6
  190. package/src/console/server/state.ts +6 -1
  191. package/src/console/server/store.ts +1 -1
  192. package/src/console/ui-next/dist/assets/FileExportIcon-Ck-5od4R.js +1 -0
  193. package/src/console/ui-next/dist/assets/MoreHorizontalCircle01Icon-gMNGsE37.js +1 -0
  194. package/src/console/ui-next/dist/assets/PlusSignIcon-CwG3nxfu.js +1 -0
  195. package/src/console/ui-next/dist/assets/UnavailableIcon-D9cvHVPr.js +1 -0
  196. package/src/console/ui-next/dist/assets/UserIcon-DaE2PB5_.js +1 -0
  197. package/src/console/ui-next/dist/assets/access-page-DFeymU07.js +4 -0
  198. package/src/console/ui-next/dist/assets/agent-disclosure-U1rdfblp.js +1 -0
  199. package/src/console/ui-next/dist/assets/cache-glyph-BeFJeqBG.js +1 -0
  200. package/src/console/ui-next/dist/assets/call-pii-button-CVAONPii.js +1 -0
  201. package/src/console/ui-next/dist/assets/collapsible-D2A6NJ-3.js +1 -0
  202. package/src/console/ui-next/dist/assets/copy-inline-button-CAYD18cr.js +1 -0
  203. package/src/console/ui-next/dist/assets/dagre.esm-B1_XeuLP.js +1 -0
  204. package/src/console/ui-next/dist/assets/detail-header-DVWNjWjg.js +1 -0
  205. package/src/console/ui-next/dist/assets/dropdown-menu-4h2LOVXM.js +1 -0
  206. package/src/console/ui-next/dist/assets/duration-tone-Cgk_h5ja.js +9 -0
  207. package/src/console/ui-next/dist/assets/element-icons-BI8cJgdh.js +1 -0
  208. package/src/console/ui-next/dist/assets/explorer-empty-CJs5A-wm.js +1 -0
  209. package/src/console/ui-next/dist/assets/flows-page-Dss7941e.js +1 -0
  210. package/src/console/ui-next/dist/assets/highlighted-json-MYZQtRnw.js +154 -0
  211. package/src/console/ui-next/dist/assets/http-method-Jrh39p7A.js +1 -0
  212. package/src/console/ui-next/dist/assets/index-D0zS5rKO.css +2 -0
  213. package/src/console/ui-next/dist/assets/index-DXP2dBIF.js +63 -0
  214. package/src/console/ui-next/dist/assets/observability-page-HvolXxTI.js +4 -0
  215. package/src/console/ui-next/dist/assets/react-dom-Ddte4I-Q.js +9 -0
  216. package/src/console/ui-next/dist/assets/replica-lag-CSh2dzrb.js +18 -0
  217. package/src/console/ui-next/dist/assets/request-meta-BatF8KrK.js +1 -0
  218. package/src/console/ui-next/dist/assets/shortcut-keys-3ILd8oGn.js +1 -0
  219. package/src/console/ui-next/dist/assets/{sql-BskegiFM.js → sql-BsFa4tDR.js} +1 -1
  220. package/src/console/ui-next/dist/assets/store-page-eiKiHnNe.js +41 -0
  221. package/src/console/ui-next/dist/assets/trace-detail-sheet-CZkMeKS-.js +2 -0
  222. package/src/console/ui-next/dist/assets/tree-expand-toggle-CW8y5A2h.js +55 -0
  223. package/src/console/ui-next/dist/assets/units-page-B_RWJrEO.js +1 -0
  224. package/src/console/ui-next/dist/assets/{use-vault-list-uk4WVboC.js → use-vault-list-CT4-gajj.js} +1 -1
  225. package/src/console/ui-next/dist/assets/vault-page-CWrg-A68.js +2 -0
  226. package/src/console/ui-next/dist/assets/xyflow-CSyC6ryz.css +1 -0
  227. package/src/console/ui-next/dist/assets/xyflow-yApv7D4e.js +7 -0
  228. package/src/console/ui-next/dist/index.html +6 -13
  229. package/src/console/ui-next/seed-invoke-host.ts +21 -18
  230. package/src/console/ui-next/src/client.ts +7 -2
  231. package/src/console/ui-next/src/features/flows/graph/element-map.ts +2 -0
  232. package/src/console/ui-next/src/features/flows/traces/effect-kind.ts +12 -2
  233. package/src/console/ui-next/src/features/flows/traces/effect-summary.ts +4 -0
  234. package/src/console/ui-next/src/features/flows/traces/trace-detail-sheet.tsx +8 -0
  235. package/src/console/ui-next/src/features/flows/traces/waterfall-bars.ts +4 -0
  236. package/src/console/ui-next/src/features/flows/traces/waterfall-tooltip.ts +9 -3
  237. package/src/console/ui-next/src/features/store/detail/reveal-cell.tsx +7 -11
  238. package/src/console/ui-next/src/features/store/detail/store-row-detail-sheet.tsx +2 -2
  239. package/src/console/ui-next/src/features/store/lib/fields-from-table.ts +2 -0
  240. package/src/console/ui-next/src/features/store/lib/grid-model.test.ts +25 -1
  241. package/src/console/ui-next/src/features/store/lib/grid-model.ts +36 -1
  242. package/src/console/ui-next/src/features/store/query/query-results.tsx +3 -3
  243. package/src/console/ui-next/src/features/units/detail/effects-summary.tsx +2 -0
  244. package/src/console/ui-next/src/features/units/lib/call-read-safe.ts +3 -1
  245. package/src/console/ui-next/src/features/units/lib/fields-from-schema.ts +6 -0
  246. package/src/docker/ai-model-status.test.ts +1 -12
  247. package/src/docker/ai-model-status.ts +10 -38
  248. package/src/docker/compose-up.test.ts +100 -0
  249. package/src/docker/compose-up.ts +292 -0
  250. package/src/docker/compose.ts +4 -14
  251. package/src/docker/derive.ts +9 -34
  252. package/src/docker/docker.test.ts +16 -261
  253. package/src/docker/images-config.test.ts +13 -25
  254. package/src/docker/index.ts +1 -24
  255. package/src/docker/recipes/index.ts +0 -23
  256. package/src/docker/recipes/pgdog.ts +6 -4
  257. package/src/docker/stack-id.test.ts +2 -2
  258. package/src/docker/stack-id.ts +0 -1
  259. package/src/docker/types.ts +2 -2
  260. package/src/drivers/ai-anthropic.ts +10 -0
  261. package/src/drivers/ai-openai-compatible.ts +34 -7
  262. package/src/drivers/ai-providers.test.ts +0 -107
  263. package/src/drivers/ai-stream.test.ts +0 -34
  264. package/src/drivers/ai-types.ts +17 -8
  265. package/src/drivers/channel-fcm.ts +6 -1
  266. package/src/drivers/channel-msegat.ts +6 -1
  267. package/src/drivers/channel-resend.ts +5 -1
  268. package/src/drivers/channel-smtp.ts +5 -1
  269. package/src/drivers/channel-sndr.ts +10 -1
  270. package/src/drivers/channel-taqnyat-mail.ts +5 -1
  271. package/src/drivers/channel-taqnyat-whatsapp.ts +6 -1
  272. package/src/drivers/channel-taqnyat.ts +6 -1
  273. package/src/drivers/channel-types.ts +10 -0
  274. package/src/drivers/channel-unifonic.ts +6 -1
  275. package/src/drivers/channel-wa-cloud.ts +6 -1
  276. package/src/drivers/channel-webpush.ts +6 -1
  277. package/src/drivers/external.ts +33 -0
  278. package/src/drivers/index.ts +0 -10
  279. package/src/drivers/meilisearch.ts +6 -0
  280. package/src/drivers/oauth-types.ts +4 -0
  281. package/src/drivers/postgres.test.ts +74 -3
  282. package/src/drivers/postgres.ts +175 -6
  283. package/src/drivers/signal-types.ts +5 -5
  284. package/src/drivers/types.ts +7 -0
  285. package/src/drivers/vault-types.ts +5 -0
  286. package/src/elements/ai/declare.ts +17 -4
  287. package/src/elements/ai/eval.ts +1 -1
  288. package/src/elements/ai/mcp-http.ts +1 -1
  289. package/src/elements/ai/pii.ts +1 -1
  290. package/src/elements/ai/providers.test.ts +289 -0
  291. package/src/elements/ai/providers.ts +169 -0
  292. package/src/elements/ai/runtime.ts +68 -5
  293. package/src/elements/ai/schema.ts +2 -2
  294. package/src/elements/ai.test.ts +7 -7
  295. package/src/elements/ai.ts +17 -1
  296. package/src/elements/channel/runtime.ts +105 -12
  297. package/src/elements/clock/cron-fields.test.ts +144 -0
  298. package/src/elements/clock/cron-fields.ts +185 -0
  299. package/src/elements/clock/declare.ts +247 -3
  300. package/src/elements/clock.ts +21 -1
  301. package/src/elements/index.ts +15 -0
  302. package/src/elements/signal/chaos-child.ts +1 -2
  303. package/src/elements/signal/declare.ts +65 -37
  304. package/src/elements/signal/delivery-modes.test.ts +11 -31
  305. package/src/elements/signal/dry-run-replay.test.ts +1 -7
  306. package/src/elements/signal/dry-run-write-isolation.test.ts +1 -7
  307. package/src/elements/signal/key-ordering.test.ts +6 -26
  308. package/src/elements/signal/lease-reclaim.test.ts +2 -6
  309. package/src/elements/signal/optional-emit.test.ts +6 -9
  310. package/src/elements/signal/order-lifecycle.test.ts +4 -17
  311. package/src/elements/signal/orphan-messages.test.ts +4 -15
  312. package/src/elements/signal/reconcile.test.ts +2 -2
  313. package/src/elements/signal/runtime.ts +1 -1
  314. package/src/elements/signal/schema-emit.test.ts +4 -8
  315. package/src/elements/signal.test.ts +24 -49
  316. package/src/elements/signal.ts +9 -2
  317. package/src/elements/store/domain-ddl.test.ts +1 -1
  318. package/src/elements/store/live-http.test.ts +9 -4
  319. package/src/elements/store/prepare-row.test.ts +123 -0
  320. package/src/elements/store/resource.ts +43 -12
  321. package/src/elements/store/schema-decl.ts +117 -0
  322. package/src/elements/store/search-backfill.ts +205 -0
  323. package/src/elements/store/search-bind.ts +66 -0
  324. package/src/elements/store/search-bm25.ts +78 -0
  325. package/src/elements/store/search-ddl.ts +156 -0
  326. package/src/elements/store/search-embed-flow.ts +141 -0
  327. package/src/elements/store/search-errors.ts +34 -0
  328. package/src/elements/store/search-fusion.ts +112 -0
  329. package/src/elements/store/search-lsh.ts +179 -0
  330. package/src/elements/store/search-runtime.ts +300 -0
  331. package/src/elements/store/search.test.ts +144 -0
  332. package/src/elements/store/sql-session.test.ts +1 -0
  333. package/src/elements/store/sql-session.ts +83 -3
  334. package/src/elements/store/table.ts +23 -2
  335. package/src/elements/store/upsert-app.test.ts +1 -3
  336. package/src/elements/store.ts +50 -0
  337. package/src/full.ts +4 -2
  338. package/src/http.ts +4 -1
  339. package/src/i18n/catalogs/ar.ts +14 -6
  340. package/src/i18n/catalogs/en.ts +14 -6
  341. package/src/index.ts +6 -1
  342. package/src/kernel/adopt-barrel-fresh.test.ts +7 -7
  343. package/src/kernel/adopt-routes.ts +9 -1
  344. package/src/kernel/app-auth.ts +5 -0
  345. package/src/kernel/app.ts +102 -9
  346. package/src/kernel/auto-cache.test.ts +6 -12
  347. package/src/kernel/auto-registry.test.ts +3 -3
  348. package/src/kernel/boot-bind/ai.test.ts +22 -19
  349. package/src/kernel/boot-bind/ai.ts +5 -43
  350. package/src/kernel/boot-bind/clock.ts +23 -5
  351. package/src/kernel/boot-bind/honor-config.test.ts +4 -4
  352. package/src/kernel/boot.test.ts +11 -6
  353. package/src/kernel/boot.ts +66 -16
  354. package/src/kernel/boundary-contract.ts +93 -0
  355. package/src/kernel/budget.test.ts +1 -1
  356. package/src/kernel/call.ts +89 -0
  357. package/src/kernel/capability.ts +6 -0
  358. package/src/kernel/client-descriptor.ts +123 -0
  359. package/src/kernel/clock-timezone.test.ts +80 -0
  360. package/src/kernel/correlation.test.ts +1 -1
  361. package/src/kernel/dry-run.ts +11 -8
  362. package/src/kernel/effects-stamping.test.ts +42 -9
  363. package/src/kernel/effects.test.ts +4 -2
  364. package/src/kernel/effects.ts +51 -9
  365. package/src/kernel/errors-channel.ts +17 -0
  366. package/src/kernel/errors-live-resume.ts +3 -2
  367. package/src/kernel/errors-tenant.ts +7 -4
  368. package/src/kernel/errors.registry-helpers.ts +96 -0
  369. package/src/kernel/errors.registry.test.ts +139 -25
  370. package/src/kernel/errors.ts +102 -23
  371. package/src/kernel/external-effects.test.ts +196 -0
  372. package/src/kernel/flow.test.ts +13 -4
  373. package/src/kernel/flow.ts +69 -71
  374. package/src/kernel/fx-ask-telemetry.test.ts +2 -2
  375. package/src/kernel/fx-dead-letters.test.ts +3 -3
  376. package/src/kernel/fx-fetch.ts +55 -0
  377. package/src/kernel/fx-live-stream.ts +2 -2
  378. package/src/kernel/fx-live.test.ts +8 -8
  379. package/src/kernel/fx.test.ts +17 -11
  380. package/src/kernel/fx.ts +180 -57
  381. package/src/kernel/horizontal-child.ts +1 -1
  382. package/src/kernel/http-query.test.ts +3 -6
  383. package/src/kernel/index.ts +13 -3
  384. package/src/kernel/instance-id.ts +1 -1
  385. package/src/kernel/instances.test.ts +40 -0
  386. package/src/kernel/instances.ts +47 -9
  387. package/src/kernel/live-http.test.ts +6 -7
  388. package/src/kernel/live-http.ts +6 -2
  389. package/src/kernel/live-resume.test.ts +1 -1
  390. package/src/kernel/mcp-tool.test.ts +3 -3
  391. package/src/kernel/on.ts +98 -4
  392. package/src/kernel/pipeline.test.ts +12 -15
  393. package/src/kernel/plugin-elements.test.ts +1 -1
  394. package/src/kernel/stamp-http.test.ts +3 -3
  395. package/src/kernel/triggers.ts +210 -95
  396. package/src/kernel-entry.ts +0 -1
  397. package/src/manifest/diff.ts +11 -1
  398. package/src/manifest/fixtures/skyport.excerpt.json +1 -1
  399. package/src/manifest/types.ts +46 -2
  400. package/src/mcp/docs-index.ts +3 -3
  401. package/src/mcp/docs-mcp.test.ts +2 -2
  402. package/src/mcp/docs-tools.ts +1 -1
  403. package/src/okid.test.ts +56 -0
  404. package/src/okid.ts +55 -11
  405. package/src/plugins/anonymous.ts +8 -4
  406. package/src/plugins/auth/shared.ts +27 -3
  407. package/src/plugins/auth-delivery.mailpit.integration.test.ts +1 -1
  408. package/src/plugins/auth-methods.security.test.ts +561 -23
  409. package/src/plugins/config-source.ts +1 -1
  410. package/src/plugins/csrf.test.ts +65 -0
  411. package/src/plugins/index.ts +2 -0
  412. package/src/plugins/magic-link.ts +36 -16
  413. package/src/plugins/oauth/shared.ts +3 -1
  414. package/src/plugins/oauth.ts +22 -14
  415. package/src/plugins/otp.ts +37 -21
  416. package/src/plugins/passkey-webauthn.ts +9 -6
  417. package/src/plugins/passkey.ts +98 -26
  418. package/src/plugins/pre-account-hijack.test.ts +223 -0
  419. package/src/plugins/two-factor.ts +466 -37
  420. package/src/plugins/username.ts +19 -7
  421. package/src/release/build-lib.ts +1 -0
  422. package/src/release/limits.ts +2 -2
  423. package/src/release/measure.ts +1 -1
  424. package/src/runs/collect.test.ts +0 -2
  425. package/src/runtime/json-code-block.test.ts +250 -20
  426. package/src/runtime/json-code-block.ts +1261 -41
  427. package/src/term.test.ts +1 -1
  428. package/src/test/create-test-app.test.ts +12 -12
  429. package/src/test/live-signals.test.ts +6 -6
  430. package/src/test/provisions.integration.test.ts +10 -14
  431. package/src/test/reset-element-registries.ts +1 -1
  432. package/src/test/tenant-isolation.test.ts +12 -6
  433. package/site/content/docs/deployment/docker-swarm.mdx +0 -164
  434. package/site/content/docs/deployment/docker.mdx +0 -227
  435. package/site/content/docs/deployment/index.mdx +0 -83
  436. package/site/content/docs/deployment/kubernetes.mdx +0 -176
  437. package/site/content/docs/deployment/meta.json +0 -5
  438. package/site/content/docs/deployment/reverse-proxy.mdx +0 -234
  439. package/site/content/docs/elements/ai.mdx +0 -385
  440. package/site/content/docs/elements/channel.mdx +0 -346
  441. package/site/content/docs/elements/clock.mdx +0 -244
  442. package/site/content/docs/elements/flow.mdx +0 -420
  443. package/site/content/docs/elements/gate.mdx +0 -436
  444. package/site/content/docs/elements/signal.mdx +0 -380
  445. package/site/content/docs/elements/store.mdx +0 -1099
  446. package/site/content/docs/elements/vault.mdx +0 -405
  447. package/site/content/docs/get-started/basic-usage.mdx +0 -173
  448. package/site/content/docs/get-started/index.mdx +0 -43
  449. package/site/content/docs/get-started/installation.mdx +0 -220
  450. package/site/content/docs/get-started/introduction.mdx +0 -132
  451. package/site/content/docs/get-started/meta.json +0 -13
  452. package/site/content/docs/get-started/project-structure.mdx +0 -925
  453. package/site/content/docs/get-started/testing.mdx +0 -328
  454. package/site/content/docs/get-started/why.mdx +0 -162
  455. package/site/content/docs/recipes/llama-cpp.mdx +0 -151
  456. package/site/content/docs/recipes/ollama.mdx +0 -142
  457. package/site/content/docs/recipes/sglang.mdx +0 -105
  458. package/site/content/docs/recipes/vllm.mdx +0 -106
  459. package/site/content/docs/reference/cli.md +0 -232
  460. package/site/content/docs/reference/client.mdx +0 -469
  461. package/site/content/docs/reference/security.md +0 -74
  462. package/src/cli/ai-setup/detect-ollama.ts +0 -213
  463. package/src/cli/ai-setup/recommend.test.ts +0 -225
  464. package/src/cli/ai-setup/recommend.ts +0 -225
  465. package/src/cli/dev-controls.test.ts +0 -122
  466. package/src/cli/dev-controls.ts +0 -164
  467. package/src/cli/tui/DevLive.tsx +0 -126
  468. package/src/console/ui-next/dist/assets/access-page-De7Lc2JC.js +0 -4
  469. package/src/console/ui-next/dist/assets/agent-disclosure-BP0Y0Sux.js +0 -1
  470. package/src/console/ui-next/dist/assets/cache-glyph-B5X-NM0-.js +0 -1
  471. package/src/console/ui-next/dist/assets/call-pii-button-ChAUiLo9.js +0 -1
  472. package/src/console/ui-next/dist/assets/collapsible-DGnOM2ph.js +0 -1
  473. package/src/console/ui-next/dist/assets/copy-inline-button-DBHhgHKP.js +0 -1
  474. package/src/console/ui-next/dist/assets/dagre.esm-ZwcdTuZZ.js +0 -1
  475. package/src/console/ui-next/dist/assets/detail-header-DhHM1iaZ.js +0 -1
  476. package/src/console/ui-next/dist/assets/dropdown-menu-_NjTEo5_.js +0 -1
  477. package/src/console/ui-next/dist/assets/duration-tone-sC3lGABz.js +0 -9
  478. package/src/console/ui-next/dist/assets/element-icons-BVXtRyd3.js +0 -1
  479. package/src/console/ui-next/dist/assets/explorer-empty-2uIhBu0_.js +0 -1
  480. package/src/console/ui-next/dist/assets/flows-page-RGy7VEA_.js +0 -1
  481. package/src/console/ui-next/dist/assets/highlighted-json-Awq7gYdu.js +0 -154
  482. package/src/console/ui-next/dist/assets/http-method-_UHM2ODJ.js +0 -1
  483. package/src/console/ui-next/dist/assets/index-Ck88Jmv8.css +0 -2
  484. package/src/console/ui-next/dist/assets/index-_rgpdVzo.js +0 -66
  485. package/src/console/ui-next/dist/assets/link-BX6Vqztd.js +0 -1
  486. package/src/console/ui-next/dist/assets/observability-page-Ds6pcnh-.js +0 -4
  487. package/src/console/ui-next/dist/assets/preload-helper-oH4irX4C.js +0 -1
  488. package/src/console/ui-next/dist/assets/react-D8E3mtu1.js +0 -1
  489. package/src/console/ui-next/dist/assets/react-dom-Bph1y7z7.js +0 -9
  490. package/src/console/ui-next/dist/assets/replica-lag-DKRrbvdo.js +0 -18
  491. package/src/console/ui-next/dist/assets/request-meta-DV0ywz7t.js +0 -1
  492. package/src/console/ui-next/dist/assets/shortcut-JQIZlWfm.js +0 -1
  493. package/src/console/ui-next/dist/assets/shortcut-keys-DKxNTe_m.js +0 -1
  494. package/src/console/ui-next/dist/assets/skeleton-D-czQJT6.js +0 -1
  495. package/src/console/ui-next/dist/assets/store-page-02xOiqIK.js +0 -41
  496. package/src/console/ui-next/dist/assets/trace-detail-sheet-B09O8rA6.js +0 -2
  497. package/src/console/ui-next/dist/assets/tree-expand-toggle-BtyhmWb4.js +0 -55
  498. package/src/console/ui-next/dist/assets/units-page-4rHOePuE.js +0 -1
  499. package/src/console/ui-next/dist/assets/useMutation-B8EO02Ej.js +0 -1
  500. package/src/console/ui-next/dist/assets/useRender-BE2A9BWC.js +0 -1
  501. package/src/console/ui-next/dist/assets/vault-page-DISPgxLM.js +0 -2
  502. package/src/console/ui-next/dist/assets/xyflow-D7n4g6go.js +0 -7
  503. package/src/console/ui-next/dist/assets/xyflow-DZ0Ws1xk.css +0 -1
  504. package/src/docker/ollama-pull.ts +0 -232
  505. package/src/docker/recipes/llama-cpp.ts +0 -298
  506. package/src/docker/recipes/ollama.ts +0 -44
  507. package/src/docker/recipes/sglang.ts +0 -55
  508. package/src/docker/recipes/vllm.ts +0 -44
  509. package/src/drivers/ai-ollama-tools.integration.test.ts +0 -109
  510. package/src/drivers/ai-ollama.integration.test.ts +0 -184
  511. package/src/drivers/ai-ollama.ts +0 -389
  512. package/src/drivers/ollama.ts +0 -14
@@ -0,0 +1,234 @@
1
+ ---
2
+ title: "Live"
3
+ description: "api.live SSE subscribe, exposure matching, resume gaps, and live resource queries."
4
+ icon: "Activity"
5
+ source: "docs/spec/unified-theory.md"
6
+ ---
7
+
8
+ `signal.live` is HTTP SSE. Expose with `.live(signal)` on GET (or `http.live(signal)` for
9
+ `GET /_oke/live/{name}`), then subscribe with a callback. `for await` stays on the server.
10
+
11
+ For developers streaming shipment status, checkout progress, or live inbox rows into a browser or
12
+ ops console.
13
+
14
+ <Callout title="The one rule">
15
+ Subscribe with a callback and an unsubscribe function. Reconnects send `Last-Event-ID` from the
16
+ last `id:` the client actually received. A **410** `LiveResumeGap` (**OKE1210**) means that cursor
17
+ is gone.
18
+ </Callout>
19
+
20
+ ## Smallest Example
21
+
22
+ <Steps>
23
+
24
+ <Step>
25
+ ### Subscribe to a shipment feed
26
+
27
+ ```typescript
28
+ import { shipmentStatus } from "@/signals/orders";
29
+
30
+ const stop = api.live(
31
+ shipmentStatus,
32
+ { orderId: "ord_9c2e" },
33
+ {
34
+ onEvent: (event) => {
35
+ // { orderId, status: "packed" | "shipped" | "delivered", eta? }
36
+ updateTrackingCard(event.status, event.eta);
37
+ },
38
+ onError: (err) => {
39
+ showTrackingBanner(err);
40
+ },
41
+ autoResubscribe: false, // default — true reopens after a drop (500ms…30s backoff)
42
+ },
43
+ );
44
+ ```
45
+
46
+ </Step>
47
+
48
+ <Step>
49
+ ### Clean up when the shopper leaves the page
50
+
51
+ ```typescript
52
+ stop(); // useEffect cleanup / process exit
53
+ ```
54
+
55
+ `api.orders.events({ orderId }, { onEvent })` is the same shape on the exposing Flow.
56
+
57
+ </Step>
58
+
59
+ </Steps>
60
+
61
+ ## Progressive Patterns
62
+
63
+ <Tabs items={["Callback", "Flow-shaped", "autoResubscribe", "Live query"]}>
64
+
65
+ <Tab value="Callback">
66
+
67
+ ```typescript
68
+ const stop = api.live(
69
+ shipmentStatus,
70
+ { orderId: "ord_9c2e" },
71
+ {
72
+ onEvent: (event) => updateTrackingCard(event.status, event.eta),
73
+ },
74
+ );
75
+ stop();
76
+ ```
77
+
78
+ </Tab>
79
+
80
+ <Tab value="Flow-shaped">
81
+
82
+ When the route is the exposing Flow itself:
83
+
84
+ ```typescript
85
+ const stop = api.orders.events(
86
+ { orderId: "ord_9c2e" },
87
+ {
88
+ onEvent: (event) => {
89
+ updateTrackingCard(event.status, event.eta);
90
+ },
91
+ },
92
+ );
93
+ stop();
94
+ ```
95
+
96
+ </Tab>
97
+
98
+ <Tab value="autoResubscribe">
99
+
100
+ ```typescript
101
+ const stop = api.live(
102
+ shipmentStatus,
103
+ { orderId: "ord_9c2e" },
104
+ {
105
+ onEvent: (event) => updateTrackingCard(event.status, event.eta),
106
+ onError: (err) => showTrackingBanner(err),
107
+ autoResubscribe: true, // reopen after a drop — 500ms…30s backoff
108
+ },
109
+ );
110
+ ```
111
+
112
+ Reconnects send `Last-Event-ID` from the last `id:` the client actually received.
113
+
114
+ </Tab>
115
+
116
+ <Tab value="Live query">
117
+
118
+ When a resource opts into `live: true`, the compiler mounts `GET <path>/live` next to the CRUD
119
+ verbs. That route streams **classified** row events — not a shared tape — so each subscriber only
120
+ sees rows that still pass their RLS stamp + list filters (e.g. open tickets for this tenant).
121
+
122
+ Prefer [React · useLiveQuery](/docs/client/react) for UI. Core transport helpers live on
123
+ `okengine/client`.
124
+
125
+ </Tab>
126
+
127
+ </Tabs>
128
+
129
+ ## Live handlers
130
+
131
+ | Option | Type | Default | Meaning |
132
+ | ----------------- | -------------------- | ------- | --------------------------------------------- |
133
+ | `onEvent` | `(event) => void` | — | Required — each SSE payload |
134
+ | `onError` | `(err) => void` | — | 4xx, envelope, network drop |
135
+ | `onOpen` | `() => void` | — | Stream connected |
136
+ | `autoResubscribe` | `boolean` | `false` | Reopen after drop (500ms…30s backoff) |
137
+ | `via` | `"unit.flow"` string | — | Disambiguate when two exposures match equally |
138
+
139
+ ## Exposure matching
140
+
141
+ The client picks the unique exposure whose `matchKey` fields are a subset of the input, preferring
142
+ the largest match (`{ orderId }` beats firehose). A tie needs `via: "unit.flow"`.
143
+
144
+ ```typescript
145
+ api.live(
146
+ shipmentStatus,
147
+ { orderId: "ord_9c2e" },
148
+ {
149
+ onEvent: updateTrackingCard,
150
+ via: "orders.events",
151
+ },
152
+ );
153
+ ```
154
+
155
+ Or call the exposing Flow directly: `api.orders.events(input, { onEvent })`.
156
+
157
+ ## Resume and LiveResumeGap
158
+
159
+ Reconnects send `Last-Event-ID` from the last `id:` the client actually received.
160
+
161
+ A **410** `LiveResumeGap` (**OKE1210**) means that cursor is gone — `onError` fires, the cursor is
162
+ dropped, and `autoResubscribe` replays the remaining tape after backoff.
163
+
164
+ Server exposure: [Signal · Live](/docs/elements/signal/live) and
165
+ [HTTP · Live Streams](/docs/elements/flow/http#live-streams).
166
+
167
+ ## Live queries (`store.resource({ live: true })`)
168
+
169
+ | `kind` | Meaning |
170
+ | --------- | -------------------------------------------------------------- |
171
+ | `upsert` | Row visible under stamp + query — merge/replace by primary key |
172
+ | `revoked` | Row left visibility (`reason: "rls"` \| `"query"`) — remove |
173
+ | `delete` | Row deleted in CDC — remove |
174
+
175
+ Every `mutate` from `useLiveQuery` generates a client UUID sent as the `X-Oke-Mutation-Id`
176
+ header — the server echoes it onto that write's CDC events, so:
177
+
178
+ - Your own late SSE echoes never double-apply (pending-set dedupe).
179
+ - Reconnects replay-guard by event `seq` (`isReplayedEvent`).
180
+ - Manual `refetch()` re-runs only the HTTP list read; reconnects always do a full
181
+ subscribe-protocol cycle (new snapshot + replay).
182
+
183
+ | State | Meaning |
184
+ | ---------------- | ------------------------------------------------------------------- |
185
+ | `isLoading` | Waiting for the first snapshot — no data yet |
186
+ | `isConnected` | SSE stream is open |
187
+ | `isReconnecting` | Stream dropped after a successful load; reconnect backoff in flight |
188
+
189
+ **Consequence:** optimistic patches roll back automatically when the Flow returns `error !== null`.
190
+ Server CDC / the successful response clear the override so the next upsert is authoritative.
191
+
192
+ Full React wiring: [React](/docs/client/react).
193
+
194
+ ## Troubleshooting
195
+
196
+ <Accordions>
197
+
198
+ <Accordion title="api.live throws Multiple live exposures">
199
+ Two routes share the same match shape. Pass `via: "unit.flow"` or call the exposing flow
200
+ (`api.orders.events(input, {onEvent})`).
201
+ </Accordion>
202
+
203
+ <Accordion title="onError sees LiveResumeGap / HTTP 410">
204
+ The last `id:` is not on the server tape. The client drops the cursor. With `autoResubscribe:
205
+ true` the next request omits `Last-Event-ID` and replays what remains.
206
+ </Accordion>
207
+
208
+ <Accordion title="No events after subscribe">
209
+ Confirm the server exposed the signal (`.live(signal)` on GET or `http.live(signal)`), the
210
+ `matchKey` fields are present in `input`, and gates allow the identity. See [Signal ·
211
+ Live](/docs/elements/signal/live).
212
+ </Accordion>
213
+
214
+ </Accordions>
215
+
216
+ ## Learn more
217
+
218
+ - [React](/docs/client/react) — `useLive`, `useLiveQuery`
219
+ - [Calling](/docs/client/calling) — typed proxy and envelopes
220
+ - [Signal · Live](/docs/elements/signal/live) — tape, resume, OKE1210
221
+ - [HTTP · Live Streams](/docs/elements/flow/http#live-streams) — server exposure
222
+ - [Store](/docs/elements/store) — `live: true` on resources
223
+
224
+ ## Next
225
+
226
+ <Cards>
227
+ <Card title="React" description="useLive and useLiveQuery hooks." href="/docs/client/react" />
228
+ <Card
229
+ title="Signal · Live"
230
+ description="Server tape, Last-Event-ID, resume gaps."
231
+ href="/docs/elements/signal/live"
232
+ />
233
+ <Card title="Calling" description="createClient and REST vs RPC." href="/docs/client/calling" />
234
+ </Cards>
@@ -0,0 +1,5 @@
1
+ {
2
+ "title": "Client",
3
+ "icon": "Cable",
4
+ "pages": ["index", "calling", "auth", "live", "react"]
5
+ }
@@ -0,0 +1,249 @@
1
+ ---
2
+ title: "React"
3
+ description: "useSession, Can, useLive, and useLiveQuery from okengine/client-react — React helpers over createClient."
4
+ icon: "Atom"
5
+ source: "docs/spec/unified-theory.md"
6
+ ---
7
+
8
+ `okengine/client-react` is a separate package so core `okengine/client` stays under the size
9
+ budget. Hooks wrap the same typed client: session status, live SSE, and live resource lists with
10
+ optimistic `mutate`.
11
+
12
+ For developers building React storefronts and ops consoles on top of `createClient`.
13
+
14
+ <Callout title="The one rule">
15
+ Pass the same `api` you built with `createClient`. Hooks never open a second client factory — they
16
+ subscribe, call Flows, and clean up on unmount.
17
+ </Callout>
18
+
19
+ ## Smallest Example
20
+
21
+ <Steps>
22
+
23
+ <Step>
24
+ ### Create the client and session
25
+
26
+ ```typescript title="web/src/session.ts"
27
+ import { createClient } from "okengine/client";
28
+ import { vault } from "okengine/vault";
29
+ import { app } from "../../src/app";
30
+
31
+ export const api = createClient(app, vault.env("PUBLIC_API_URL") ?? "", {
32
+ auth: { mode: "cookie", csrfConfigured: true },
33
+ });
34
+ ```
35
+
36
+ </Step>
37
+
38
+ <Step>
39
+ ### Show the signed-in shopper in the header
40
+
41
+ ```typescript title="web/src/AccountMenu.tsx"
42
+ import { Can, useSession } from "okengine/client-react";
43
+ import { api } from "./session";
44
+
45
+ export function AccountMenu() {
46
+ const { status, user, signOut } = useSession(api.auth!);
47
+
48
+ if (status === "loading") return null;
49
+ if (status === "unauthenticated") return <a href="/sign-in">Sign in</a>;
50
+
51
+ return (
52
+ <>
53
+ <Can auth={api.auth!} all={["orders:write"]} fallback={null}>
54
+ <a href="/fulfillment">Fulfillment</a>
55
+ </Can>
56
+ <button type="button" onClick={() => signOut()}>
57
+ {user?.email}
58
+ </button>
59
+ </>
60
+ );
61
+ }
62
+ ```
63
+
64
+ `Can` / `useAuthorize` are UI-only — Gate on Flows remains real authz.
65
+
66
+ </Step>
67
+
68
+ </Steps>
69
+
70
+ ## Progressive Patterns
71
+
72
+ <Tabs items={["useSession", "Can / useAuthorize", "useLive", "useLiveQuery", "mutate"]}>
73
+
74
+ <Tab value="useSession">
75
+
76
+ ```typescript
77
+ import { useSession } from "okengine/client-react";
78
+
79
+ const { status, user, accessToken, refresh, signOut } = useSession(api.auth!);
80
+ ```
81
+
82
+ | Field | Meaning |
83
+ | ------------- | ------------------------------------------------------- |
84
+ | `status` | `"loading"` \| `"authenticated"` \| `"unauthenticated"` |
85
+ | `user` | `auth.me` payload or `null` |
86
+ | `accessToken` | Current Bearer from `memorySession` (or `null`) |
87
+ | `refresh()` | Re-run `auth.me` |
88
+ | `signOut()` | `session.clear()` + unauthenticated |
89
+
90
+ </Tab>
91
+
92
+ <Tab value="Can / useAuthorize">
93
+
94
+ ```tsx
95
+ import { Can, useAuthorize } from "okengine/client-react";
96
+
97
+ <Can auth={api.auth!} all={["orders:write"]} fallback={<Denied />}>
98
+ <FulfillmentLink />
99
+ </Can>;
100
+
101
+ const { status, missing } = useAuthorize(api.auth!, { all: ["orders:write"] });
102
+ ```
103
+
104
+ UI chrome only — Gate on Flows is the security boundary. Prefer these over bare `useScope` /
105
+ `useCan`.
106
+
107
+ </Tab>
108
+
109
+ <Tab value="useLive">
110
+
111
+ ```typescript
112
+ import { useLive } from "okengine/client-react";
113
+ import { shipmentStatus } from "@/signals/orders";
114
+
115
+ const { events, latest, error, isConnected } = useLive(
116
+ api,
117
+ shipmentStatus,
118
+ { orderId: "ord_9c2e" },
119
+ {
120
+ autoResubscribe: true,
121
+ },
122
+ );
123
+
124
+ // latest?.status → "packed" | "shipped" | "delivered"
125
+ ```
126
+
127
+ Cleanup calls `stop()` on unmount. Changing `signal` / `input` / `via` resets `events`.
128
+
129
+ | Option | Meaning |
130
+ | ----------------- | -------------------------------------- |
131
+ | `autoResubscribe` | Reopen after drop (same as `api.live`) |
132
+ | `via` | Disambiguate equal exposure matches |
133
+
134
+ </Tab>
135
+
136
+ <Tab value="useLiveQuery">
137
+
138
+ ```typescript
139
+ import { useLiveQuery } from "okengine/client-react";
140
+
141
+ const { data, error, isLoading, isConnected, isReconnecting, refetch, mutate } = useLiveQuery({
142
+ api,
143
+ listFlow: api.inbox.list,
144
+ query: { status: "open", assignee: "me" },
145
+ live: { method: "GET", path: "/inbox/live" }, // from app.$routes
146
+ options: {
147
+ enabled: session.status === "authenticated", // default true — idle when false
148
+ refreshKey: workspaceId, // switch workspace → full re-subscribe
149
+ onAuthRefresh: onAuthRefreshed, // auth.refresh() → new snapshot + replay
150
+ },
151
+ });
152
+ ```
153
+
154
+ | State | Meaning |
155
+ | ---------------- | ------------------------------------------------------------------- |
156
+ | `isLoading` | Waiting for the first snapshot — no data yet |
157
+ | `isConnected` | SSE stream is open |
158
+ | `isReconnecting` | Stream dropped after a successful load; reconnect backoff in flight |
159
+
160
+ </Tab>
161
+
162
+ <Tab value="mutate">
163
+
164
+ ```typescript
165
+ await mutate(
166
+ api.inbox.update,
167
+ { id: ticketId, status: "resolved" },
168
+ {
169
+ optimistic: (rows) =>
170
+ rows.map((row) => (row.id === ticketId ? { ...row, status: "resolved" } : row)),
171
+ pkOf: (input) => input.id,
172
+ },
173
+ );
174
+ ```
175
+
176
+ Every `mutate` call generates a client UUID sent as the `X-Oke-Mutation-Id` header — the server
177
+ echoes it onto that write's CDC events for pending-set dedupe and replay guards.
178
+
179
+ **Consequence:** optimistic patches roll back automatically when the Flow returns `error !== null`.
180
+ Server CDC / the successful response clear the override so the next upsert is authoritative.
181
+
182
+ </Tab>
183
+
184
+ </Tabs>
185
+
186
+ ## Package boundary
187
+
188
+ | Export | Package | Role |
189
+ | ----------------------------------------- | ----------------------- | ------------------------------------------- |
190
+ | `createClient` / `api.live` | `okengine/client` | Typed proxy + SSE subscribe |
191
+ | `createAuthClient` / `memorySession` | `okengine/client/auth` | Secure session orchestration |
192
+ | `vault` / `vault.env` | `okengine/vault` | Env + config contracts (subpath — not root) |
193
+ | `useSession` / `useLive` / `useLiveQuery` | `okengine/client-react` | React hooks (`react` optional peer) |
194
+ | `subscribeLiveResource` | `okengine/client-react` | Non-hook live resource stream helper |
195
+
196
+ Prefer [`createAuthClient`](/docs/client/auth) for cookie/Bearer sessions and method helpers.
197
+ `useLiveQuery` accepts `listPath` to derive `GET ${listPath}/live` when `live` is omitted.
198
+
199
+ ## `useLiveQuery` options
200
+
201
+ | Option | Meaning |
202
+ | --------------- | ---------------------------------------------- |
203
+ | `enabled` | Default `true` — idle when `false` |
204
+ | `refreshKey` | Identity change → full re-subscribe |
205
+ | `onAuthRefresh` | After `auth.refresh()` → new snapshot + replay |
206
+
207
+ `refetch()` re-runs only the HTTP list read; reconnects always do a full subscribe-protocol cycle
208
+ (new snapshot + replay). Event kinds and resume physics: [Live](/docs/client/live).
209
+
210
+ ## Troubleshooting
211
+
212
+ <Accordions>
213
+
214
+ <Accordion title="Cannot find module okengine/client-react">
215
+ Install / import the React package separately. Core `okengine/client` does not re-export hooks —
216
+ that keeps the client runtime under budget.
217
+ </Accordion>
218
+
219
+ <Accordion title="useSession stuck on loading">
220
+ Confirm `auth.me` is adopted, Bearer `getToken` returns a token, and the me Flow is reachable.
221
+ Without a token, status becomes `"unauthenticated"`.
222
+ </Accordion>
223
+
224
+ <Accordion title="useLiveQuery never connects">
225
+ Pass `live: { method, path }` from `app.$routes` for the resource’s `/live` route. Set
226
+ `enabled: true` (or omit). See [Live](/docs/client/live) for exposure and resume errors.
227
+ </Accordion>
228
+
229
+ </Accordions>
230
+
231
+ ## Learn more
232
+
233
+ - [Auth](/docs/client/auth) — `memorySession` and gate denials
234
+ - [Live](/docs/client/live) — `api.live`, resume, live query kinds
235
+ - [Calling](/docs/client/calling) — envelopes and list pager
236
+ - [Signal · Live](/docs/elements/signal/live) — server tape
237
+ - [Store](/docs/elements/store) — `live: true` resources
238
+
239
+ ## Next
240
+
241
+ <Cards>
242
+ <Card
243
+ title="Live"
244
+ description="SSE subscribe and live resource physics."
245
+ href="/docs/client/live"
246
+ />
247
+ <Card title="Auth" description="Bearer sessions behind the hooks." href="/docs/client/auth" />
248
+ <Card title="Calling" description="createClient forms and options." href="/docs/client/calling" />
249
+ </Cards>