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.
- package/AGENTS.md +18 -10
- package/README.md +2 -2
- package/package.json +51 -50
- package/site/content/docs/ai/index.mdx +25 -6
- package/site/content/docs/ai/llms-txt.mdx +1 -1
- package/site/content/docs/ai/meta.json +1 -1
- package/site/content/docs/ai/skills.mdx +4 -1
- package/site/content/docs/ai/try-it.mdx +58 -0
- package/site/content/docs/client/auth.mdx +208 -0
- package/site/content/docs/client/calling.mdx +451 -0
- package/site/content/docs/client/index.mdx +209 -0
- package/site/content/docs/client/live.mdx +234 -0
- package/site/content/docs/client/meta.json +5 -0
- package/site/content/docs/client/react.mdx +249 -0
- package/site/content/docs/elements/ai/agents.mdx +232 -0
- package/site/content/docs/elements/ai/index.mdx +341 -0
- package/site/content/docs/elements/ai/mcp.mdx +275 -0
- package/site/content/docs/elements/ai/meta.json +5 -0
- package/site/content/docs/elements/ai/models.mdx +283 -0
- package/site/content/docs/elements/ai/prompts.mdx +256 -0
- package/site/content/docs/elements/channel/email.mdx +266 -0
- package/site/content/docs/elements/channel/index.mdx +344 -0
- package/site/content/docs/elements/channel/meta.json +5 -0
- package/site/content/docs/elements/channel/push.mdx +218 -0
- package/site/content/docs/elements/channel/receipts.mdx +206 -0
- package/site/content/docs/elements/channel/sms.mdx +264 -0
- package/site/content/docs/elements/channel/whatsapp.mdx +220 -0
- package/site/content/docs/elements/clock/index.mdx +300 -0
- package/site/content/docs/elements/clock/meta.json +5 -0
- package/site/content/docs/elements/clock/schedules.mdx +508 -0
- package/site/content/docs/elements/clock/sleep.mdx +445 -0
- package/site/content/docs/elements/flow/consumers.mdx +707 -0
- package/site/content/docs/elements/flow/http.mdx +1080 -0
- package/site/content/docs/elements/flow/index.mdx +618 -0
- package/site/content/docs/elements/flow/meta.json +5 -0
- package/site/content/docs/elements/flow/routing.mdx +559 -0
- package/site/content/docs/elements/flow/workflows.mdx +640 -0
- package/site/content/docs/elements/gate/auth.mdx +371 -0
- package/site/content/docs/elements/gate/authorization.mdx +298 -0
- package/site/content/docs/elements/gate/index.mdx +418 -0
- package/site/content/docs/elements/gate/meta.json +5 -0
- package/site/content/docs/elements/gate/rate-limits.mdx +365 -0
- package/site/content/docs/elements/gate/rls.mdx +303 -0
- package/site/content/docs/elements/gate/tenancy.mdx +372 -0
- package/site/content/docs/elements/index.mdx +52 -11
- package/site/content/docs/elements/signal/broadcast.mdx +517 -0
- package/site/content/docs/elements/signal/index.mdx +352 -0
- package/site/content/docs/elements/signal/live.mdx +590 -0
- package/site/content/docs/elements/signal/meta.json +5 -0
- package/site/content/docs/elements/signal/once.mdx +596 -0
- package/site/content/docs/elements/store/files.mdx +659 -0
- package/site/content/docs/elements/store/index.mdx +310 -0
- package/site/content/docs/elements/store/kv.mdx +629 -0
- package/site/content/docs/elements/store/meta.json +5 -0
- package/site/content/docs/elements/store/search.mdx +946 -0
- package/site/content/docs/elements/store/sql.mdx +937 -0
- package/site/content/docs/elements/vault/config.mdx +256 -0
- package/site/content/docs/elements/vault/index.mdx +356 -0
- package/site/content/docs/elements/vault/meta.json +5 -0
- package/site/content/docs/elements/vault/rotation.mdx +273 -0
- package/site/content/docs/elements/vault/secrets.mdx +285 -0
- package/site/content/docs/index.mdx +78 -30
- package/site/content/docs/meta.json +11 -8
- package/site/content/docs/plugins/cors.mdx +2 -1
- package/site/content/docs/plugins/csrf.mdx +4 -1
- package/site/content/docs/plugins/headers.mdx +2 -1
- package/site/content/docs/plugins/ip-allowlist.mdx +2 -1
- package/site/content/docs/plugins/magic-link.mdx +6 -0
- package/site/content/docs/plugins/maintenance-mode.mdx +2 -1
- package/site/content/docs/plugins/oauth.mdx +1 -1
- package/site/content/docs/plugins/otp.mdx +12 -1
- package/site/content/docs/plugins/passkey.mdx +39 -15
- package/site/content/docs/plugins/two-factor.mdx +91 -34
- package/site/content/docs/plugins/username.mdx +1 -1
- package/site/content/docs/recipes/caddy.mdx +3 -3
- package/site/content/docs/recipes/index.mdx +18 -28
- package/site/content/docs/recipes/mailpit.mdx +1 -1
- package/site/content/docs/recipes/meilisearch.mdx +3 -3
- package/site/content/docs/recipes/meta.json +1 -4
- package/site/content/docs/recipes/nginx.mdx +2 -2
- package/site/content/docs/recipes/openrouter.mdx +283 -0
- package/site/content/docs/recipes/pgdog.mdx +3 -3
- package/site/content/docs/recipes/postgres.mdx +1 -2
- package/site/content/docs/recipes/rustfs.mdx +2 -2
- package/site/content/docs/recipes/traefik.mdx +3 -3
- package/site/content/docs/reference/cli.mdx +231 -0
- package/site/content/docs/reference/configuration.mdx +30 -10
- package/site/content/docs/reference/environment-variables.mdx +93 -20
- package/site/content/docs/reference/errors.mdx +132 -29
- package/site/content/docs/reference/fx.mdx +137 -73
- package/site/content/docs/reference/index.mdx +13 -21
- package/site/content/docs/reference/meta.json +4 -5
- package/site/content/docs/reference/okid.mdx +42 -17
- package/site/content/docs/reference/plugins.mdx +4 -3
- package/site/content/docs/reference/security.mdx +197 -0
- package/site/content/docs/understand/meta.json +5 -0
- package/site/content/docs/understand/the-anatomy.mdx +132 -0
- package/site/content/docs/understand/the-model.mdx +32 -0
- package/site/content/docs/understand/the-problem.mdx +74 -0
- package/site/content/docs/understand/the-vocabulary.mdx +26 -0
- package/src/auth/api-keys.ts +2 -1
- package/src/auth/bindings.ts +64 -16
- package/src/auth/gate-auth.test.ts +6 -1
- package/src/auth/identity.ts +152 -5
- package/src/auth/index.ts +29 -0
- package/src/auth/invites.ts +2 -1
- package/src/auth/method-context.ts +41 -0
- package/src/auth/oauth-as/crypto.ts +2 -1
- package/src/auth/oauth-as/stores.ts +2 -1
- package/src/auth/operator.ts +2 -1
- package/src/auth/sessions-jwt.test.ts +77 -0
- package/src/auth/sessions.ts +20 -4
- package/src/auth/tenants.ts +3 -2
- package/src/auth/two-factor-challenge.test.ts +61 -0
- package/src/auth/two-factor-challenge.ts +284 -0
- package/src/auth/verification.ts +5 -0
- package/src/bench/REPORT.md +49 -0
- package/src/bench/g03-signal-once.bench.ts +1 -1
- package/src/bench/g10-observability-contention.bench.ts +1 -1
- package/src/bench/g17-hybrid-search.bench.ts +572 -0
- package/src/bench/load-app.ts +2 -10
- package/src/cli/ai-setup/ai-setup.test.ts +331 -42
- package/src/cli/ai-setup/apply.ts +294 -52
- package/src/cli/ai-setup/catalog.ts +238 -1342
- package/src/cli/ai-setup/index.ts +14 -99
- package/src/cli/ai-setup/prompts.ts +60 -443
- package/src/cli/ask-seed.test.ts +96 -0
- package/src/cli/ask-seed.ts +82 -0
- package/src/cli/ask-vault-gaps.test.ts +84 -0
- package/src/cli/ask-vault-gaps.ts +146 -0
- package/src/cli/build.ts +2 -2
- package/src/cli/client-add.test.ts +26 -1
- package/src/cli/client-add.ts +106 -27
- package/src/cli/competitor-mention-removal.test.ts +1 -1
- package/src/cli/db-seed.ts +2 -0
- package/src/cli/db.ts +150 -11
- package/src/cli/dev.ts +119 -211
- package/src/cli/docker-clean.ts +2 -2
- package/src/cli/docker-cli.test.ts +1 -1
- package/src/cli/doctor-diff.ts +4 -2
- package/src/cli/doctor-pii.test.ts +1 -1
- package/src/cli/doctor.ts +14 -1
- package/src/cli/hero-meta.test.ts +4 -2
- package/src/cli/load-config.images.test.ts +8 -10
- package/src/cli/load-config.ts +1 -1
- package/src/cli/registry.ts +22 -10
- package/src/cli/replay.ts +3 -1
- package/src/cli/start.ts +1 -1
- package/src/cli/tui/keys.ts +2 -3
- package/src/client/auth/cookies.ts +74 -0
- package/src/client/auth/create-auth-client.ts +636 -0
- package/src/client/auth/denials.ts +99 -0
- package/src/client/auth/session.ts +283 -0
- package/src/client/auth.test.ts +251 -0
- package/src/client/auth.ts +39 -114
- package/src/client/create-with-session.ts +245 -0
- package/src/client/create.ts +51 -5
- package/src/client/index.ts +11 -1
- package/src/client/live.ts +11 -79
- package/src/client/notes-contract.test.ts +5 -10
- package/src/client/sse.ts +137 -0
- package/src/client/stream.ts +147 -0
- package/src/client/transport.test.ts +32 -0
- package/src/client/transport.ts +123 -26
- package/src/client/types.ts +118 -14
- package/src/client-react/index.ts +185 -24
- package/src/client-react/use-live-query.ts +13 -3
- package/src/compiler/aot.test.ts +7 -4
- package/src/compiler/effects-embed.test.ts +56 -0
- package/src/compiler/effects-fetch.test.ts +43 -0
- package/src/compiler/effects-infer.ts +58 -2
- package/src/compiler/extract.test.ts +258 -44
- package/src/compiler/extract.ts +566 -48
- package/src/compiler/fixtures/skyport/src/flows/bookings/index.ts +7 -4
- package/src/compiler/fixtures/skyport/src/flows/bookings/signals.ts +2 -8
- package/src/compiler/fixtures/skyport.expected.json +4 -4
- package/src/compiler/fixtures/triggers/five-triggers.ts +14 -10
- package/src/compiler/response.ts +2 -2
- package/src/compiler/search-writer-isolation.test.ts +40 -0
- package/src/config/index.ts +11 -0
- package/src/console/server/app.ts +17 -23
- package/src/console/server/bind.ts +4 -0
- package/src/console/server/console.test.ts +2 -2
- package/src/console/server/flows-invoke.test.ts +50 -34
- package/src/console/server/flows.ts +436 -255
- package/src/console/server/runs-ingest.test.ts +6 -3
- package/src/console/server/serve.ts +1 -1
- package/src/console/server/signals.test.ts +1 -5
- package/src/console/server/signals.ts +8 -6
- package/src/console/server/state.ts +6 -1
- package/src/console/server/store.ts +1 -1
- package/src/console/ui-next/dist/assets/FileExportIcon-Ck-5od4R.js +1 -0
- package/src/console/ui-next/dist/assets/MoreHorizontalCircle01Icon-gMNGsE37.js +1 -0
- package/src/console/ui-next/dist/assets/PlusSignIcon-CwG3nxfu.js +1 -0
- package/src/console/ui-next/dist/assets/UnavailableIcon-D9cvHVPr.js +1 -0
- package/src/console/ui-next/dist/assets/UserIcon-DaE2PB5_.js +1 -0
- package/src/console/ui-next/dist/assets/access-page-DFeymU07.js +4 -0
- package/src/console/ui-next/dist/assets/agent-disclosure-U1rdfblp.js +1 -0
- package/src/console/ui-next/dist/assets/cache-glyph-BeFJeqBG.js +1 -0
- package/src/console/ui-next/dist/assets/call-pii-button-CVAONPii.js +1 -0
- package/src/console/ui-next/dist/assets/collapsible-D2A6NJ-3.js +1 -0
- package/src/console/ui-next/dist/assets/copy-inline-button-CAYD18cr.js +1 -0
- package/src/console/ui-next/dist/assets/dagre.esm-B1_XeuLP.js +1 -0
- package/src/console/ui-next/dist/assets/detail-header-DVWNjWjg.js +1 -0
- package/src/console/ui-next/dist/assets/dropdown-menu-4h2LOVXM.js +1 -0
- package/src/console/ui-next/dist/assets/duration-tone-Cgk_h5ja.js +9 -0
- package/src/console/ui-next/dist/assets/element-icons-BI8cJgdh.js +1 -0
- package/src/console/ui-next/dist/assets/explorer-empty-CJs5A-wm.js +1 -0
- package/src/console/ui-next/dist/assets/flows-page-Dss7941e.js +1 -0
- package/src/console/ui-next/dist/assets/highlighted-json-MYZQtRnw.js +154 -0
- package/src/console/ui-next/dist/assets/http-method-Jrh39p7A.js +1 -0
- package/src/console/ui-next/dist/assets/index-D0zS5rKO.css +2 -0
- package/src/console/ui-next/dist/assets/index-DXP2dBIF.js +63 -0
- package/src/console/ui-next/dist/assets/observability-page-HvolXxTI.js +4 -0
- package/src/console/ui-next/dist/assets/react-dom-Ddte4I-Q.js +9 -0
- package/src/console/ui-next/dist/assets/replica-lag-CSh2dzrb.js +18 -0
- package/src/console/ui-next/dist/assets/request-meta-BatF8KrK.js +1 -0
- package/src/console/ui-next/dist/assets/shortcut-keys-3ILd8oGn.js +1 -0
- package/src/console/ui-next/dist/assets/{sql-BskegiFM.js → sql-BsFa4tDR.js} +1 -1
- package/src/console/ui-next/dist/assets/store-page-eiKiHnNe.js +41 -0
- package/src/console/ui-next/dist/assets/trace-detail-sheet-CZkMeKS-.js +2 -0
- package/src/console/ui-next/dist/assets/tree-expand-toggle-CW8y5A2h.js +55 -0
- package/src/console/ui-next/dist/assets/units-page-B_RWJrEO.js +1 -0
- package/src/console/ui-next/dist/assets/{use-vault-list-uk4WVboC.js → use-vault-list-CT4-gajj.js} +1 -1
- package/src/console/ui-next/dist/assets/vault-page-CWrg-A68.js +2 -0
- package/src/console/ui-next/dist/assets/xyflow-CSyC6ryz.css +1 -0
- package/src/console/ui-next/dist/assets/xyflow-yApv7D4e.js +7 -0
- package/src/console/ui-next/dist/index.html +6 -13
- package/src/console/ui-next/seed-invoke-host.ts +21 -18
- package/src/console/ui-next/src/client.ts +7 -2
- package/src/console/ui-next/src/features/flows/graph/element-map.ts +2 -0
- package/src/console/ui-next/src/features/flows/traces/effect-kind.ts +12 -2
- package/src/console/ui-next/src/features/flows/traces/effect-summary.ts +4 -0
- package/src/console/ui-next/src/features/flows/traces/trace-detail-sheet.tsx +8 -0
- package/src/console/ui-next/src/features/flows/traces/waterfall-bars.ts +4 -0
- package/src/console/ui-next/src/features/flows/traces/waterfall-tooltip.ts +9 -3
- package/src/console/ui-next/src/features/store/detail/reveal-cell.tsx +7 -11
- package/src/console/ui-next/src/features/store/detail/store-row-detail-sheet.tsx +2 -2
- package/src/console/ui-next/src/features/store/lib/fields-from-table.ts +2 -0
- package/src/console/ui-next/src/features/store/lib/grid-model.test.ts +25 -1
- package/src/console/ui-next/src/features/store/lib/grid-model.ts +36 -1
- package/src/console/ui-next/src/features/store/query/query-results.tsx +3 -3
- package/src/console/ui-next/src/features/units/detail/effects-summary.tsx +2 -0
- package/src/console/ui-next/src/features/units/lib/call-read-safe.ts +3 -1
- package/src/console/ui-next/src/features/units/lib/fields-from-schema.ts +6 -0
- package/src/docker/ai-model-status.test.ts +1 -12
- package/src/docker/ai-model-status.ts +10 -38
- package/src/docker/compose-up.test.ts +100 -0
- package/src/docker/compose-up.ts +292 -0
- package/src/docker/compose.ts +4 -14
- package/src/docker/derive.ts +9 -34
- package/src/docker/docker.test.ts +16 -261
- package/src/docker/images-config.test.ts +13 -25
- package/src/docker/index.ts +1 -24
- package/src/docker/recipes/index.ts +0 -23
- package/src/docker/recipes/pgdog.ts +6 -4
- package/src/docker/stack-id.test.ts +2 -2
- package/src/docker/stack-id.ts +0 -1
- package/src/docker/types.ts +2 -2
- package/src/drivers/ai-anthropic.ts +10 -0
- package/src/drivers/ai-openai-compatible.ts +34 -7
- package/src/drivers/ai-providers.test.ts +0 -107
- package/src/drivers/ai-stream.test.ts +0 -34
- package/src/drivers/ai-types.ts +17 -8
- package/src/drivers/channel-fcm.ts +6 -1
- package/src/drivers/channel-msegat.ts +6 -1
- package/src/drivers/channel-resend.ts +5 -1
- package/src/drivers/channel-smtp.ts +5 -1
- package/src/drivers/channel-sndr.ts +10 -1
- package/src/drivers/channel-taqnyat-mail.ts +5 -1
- package/src/drivers/channel-taqnyat-whatsapp.ts +6 -1
- package/src/drivers/channel-taqnyat.ts +6 -1
- package/src/drivers/channel-types.ts +10 -0
- package/src/drivers/channel-unifonic.ts +6 -1
- package/src/drivers/channel-wa-cloud.ts +6 -1
- package/src/drivers/channel-webpush.ts +6 -1
- package/src/drivers/external.ts +33 -0
- package/src/drivers/index.ts +0 -10
- package/src/drivers/meilisearch.ts +6 -0
- package/src/drivers/oauth-types.ts +4 -0
- package/src/drivers/postgres.test.ts +74 -3
- package/src/drivers/postgres.ts +175 -6
- package/src/drivers/signal-types.ts +5 -5
- package/src/drivers/types.ts +7 -0
- package/src/drivers/vault-types.ts +5 -0
- package/src/elements/ai/declare.ts +17 -4
- package/src/elements/ai/eval.ts +1 -1
- package/src/elements/ai/mcp-http.ts +1 -1
- package/src/elements/ai/pii.ts +1 -1
- package/src/elements/ai/providers.test.ts +289 -0
- package/src/elements/ai/providers.ts +169 -0
- package/src/elements/ai/runtime.ts +68 -5
- package/src/elements/ai/schema.ts +2 -2
- package/src/elements/ai.test.ts +7 -7
- package/src/elements/ai.ts +17 -1
- package/src/elements/channel/runtime.ts +105 -12
- package/src/elements/clock/cron-fields.test.ts +144 -0
- package/src/elements/clock/cron-fields.ts +185 -0
- package/src/elements/clock/declare.ts +247 -3
- package/src/elements/clock.ts +21 -1
- package/src/elements/index.ts +15 -0
- package/src/elements/signal/chaos-child.ts +1 -2
- package/src/elements/signal/declare.ts +65 -37
- package/src/elements/signal/delivery-modes.test.ts +11 -31
- package/src/elements/signal/dry-run-replay.test.ts +1 -7
- package/src/elements/signal/dry-run-write-isolation.test.ts +1 -7
- package/src/elements/signal/key-ordering.test.ts +6 -26
- package/src/elements/signal/lease-reclaim.test.ts +2 -6
- package/src/elements/signal/optional-emit.test.ts +6 -9
- package/src/elements/signal/order-lifecycle.test.ts +4 -17
- package/src/elements/signal/orphan-messages.test.ts +4 -15
- package/src/elements/signal/reconcile.test.ts +2 -2
- package/src/elements/signal/runtime.ts +1 -1
- package/src/elements/signal/schema-emit.test.ts +4 -8
- package/src/elements/signal.test.ts +24 -49
- package/src/elements/signal.ts +9 -2
- package/src/elements/store/domain-ddl.test.ts +1 -1
- package/src/elements/store/live-http.test.ts +9 -4
- package/src/elements/store/prepare-row.test.ts +123 -0
- package/src/elements/store/resource.ts +43 -12
- package/src/elements/store/schema-decl.ts +117 -0
- package/src/elements/store/search-backfill.ts +205 -0
- package/src/elements/store/search-bind.ts +66 -0
- package/src/elements/store/search-bm25.ts +78 -0
- package/src/elements/store/search-ddl.ts +156 -0
- package/src/elements/store/search-embed-flow.ts +141 -0
- package/src/elements/store/search-errors.ts +34 -0
- package/src/elements/store/search-fusion.ts +112 -0
- package/src/elements/store/search-lsh.ts +179 -0
- package/src/elements/store/search-runtime.ts +300 -0
- package/src/elements/store/search.test.ts +144 -0
- package/src/elements/store/sql-session.test.ts +1 -0
- package/src/elements/store/sql-session.ts +83 -3
- package/src/elements/store/table.ts +23 -2
- package/src/elements/store/upsert-app.test.ts +1 -3
- package/src/elements/store.ts +50 -0
- package/src/full.ts +4 -2
- package/src/http.ts +4 -1
- package/src/i18n/catalogs/ar.ts +14 -6
- package/src/i18n/catalogs/en.ts +14 -6
- package/src/index.ts +6 -1
- package/src/kernel/adopt-barrel-fresh.test.ts +7 -7
- package/src/kernel/adopt-routes.ts +9 -1
- package/src/kernel/app-auth.ts +5 -0
- package/src/kernel/app.ts +102 -9
- package/src/kernel/auto-cache.test.ts +6 -12
- package/src/kernel/auto-registry.test.ts +3 -3
- package/src/kernel/boot-bind/ai.test.ts +22 -19
- package/src/kernel/boot-bind/ai.ts +5 -43
- package/src/kernel/boot-bind/clock.ts +23 -5
- package/src/kernel/boot-bind/honor-config.test.ts +4 -4
- package/src/kernel/boot.test.ts +11 -6
- package/src/kernel/boot.ts +66 -16
- package/src/kernel/boundary-contract.ts +93 -0
- package/src/kernel/budget.test.ts +1 -1
- package/src/kernel/call.ts +89 -0
- package/src/kernel/capability.ts +6 -0
- package/src/kernel/client-descriptor.ts +123 -0
- package/src/kernel/clock-timezone.test.ts +80 -0
- package/src/kernel/correlation.test.ts +1 -1
- package/src/kernel/dry-run.ts +11 -8
- package/src/kernel/effects-stamping.test.ts +42 -9
- package/src/kernel/effects.test.ts +4 -2
- package/src/kernel/effects.ts +51 -9
- package/src/kernel/errors-channel.ts +17 -0
- package/src/kernel/errors-live-resume.ts +3 -2
- package/src/kernel/errors-tenant.ts +7 -4
- package/src/kernel/errors.registry-helpers.ts +96 -0
- package/src/kernel/errors.registry.test.ts +139 -25
- package/src/kernel/errors.ts +102 -23
- package/src/kernel/external-effects.test.ts +196 -0
- package/src/kernel/flow.test.ts +13 -4
- package/src/kernel/flow.ts +69 -71
- package/src/kernel/fx-ask-telemetry.test.ts +2 -2
- package/src/kernel/fx-dead-letters.test.ts +3 -3
- package/src/kernel/fx-fetch.ts +55 -0
- package/src/kernel/fx-live-stream.ts +2 -2
- package/src/kernel/fx-live.test.ts +8 -8
- package/src/kernel/fx.test.ts +17 -11
- package/src/kernel/fx.ts +180 -57
- package/src/kernel/horizontal-child.ts +1 -1
- package/src/kernel/http-query.test.ts +3 -6
- package/src/kernel/index.ts +13 -3
- package/src/kernel/instance-id.ts +1 -1
- package/src/kernel/instances.test.ts +40 -0
- package/src/kernel/instances.ts +47 -9
- package/src/kernel/live-http.test.ts +6 -7
- package/src/kernel/live-http.ts +6 -2
- package/src/kernel/live-resume.test.ts +1 -1
- package/src/kernel/mcp-tool.test.ts +3 -3
- package/src/kernel/on.ts +98 -4
- package/src/kernel/pipeline.test.ts +12 -15
- package/src/kernel/plugin-elements.test.ts +1 -1
- package/src/kernel/stamp-http.test.ts +3 -3
- package/src/kernel/triggers.ts +210 -95
- package/src/kernel-entry.ts +0 -1
- package/src/manifest/diff.ts +11 -1
- package/src/manifest/fixtures/skyport.excerpt.json +1 -1
- package/src/manifest/types.ts +46 -2
- package/src/mcp/docs-index.ts +3 -3
- package/src/mcp/docs-mcp.test.ts +2 -2
- package/src/mcp/docs-tools.ts +1 -1
- package/src/okid.test.ts +56 -0
- package/src/okid.ts +55 -11
- package/src/plugins/anonymous.ts +8 -4
- package/src/plugins/auth/shared.ts +27 -3
- package/src/plugins/auth-delivery.mailpit.integration.test.ts +1 -1
- package/src/plugins/auth-methods.security.test.ts +561 -23
- package/src/plugins/config-source.ts +1 -1
- package/src/plugins/csrf.test.ts +65 -0
- package/src/plugins/index.ts +2 -0
- package/src/plugins/magic-link.ts +36 -16
- package/src/plugins/oauth/shared.ts +3 -1
- package/src/plugins/oauth.ts +22 -14
- package/src/plugins/otp.ts +37 -21
- package/src/plugins/passkey-webauthn.ts +9 -6
- package/src/plugins/passkey.ts +98 -26
- package/src/plugins/pre-account-hijack.test.ts +223 -0
- package/src/plugins/two-factor.ts +466 -37
- package/src/plugins/username.ts +19 -7
- package/src/release/build-lib.ts +1 -0
- package/src/release/limits.ts +2 -2
- package/src/release/measure.ts +1 -1
- package/src/runs/collect.test.ts +0 -2
- package/src/runtime/json-code-block.test.ts +250 -20
- package/src/runtime/json-code-block.ts +1261 -41
- package/src/term.test.ts +1 -1
- package/src/test/create-test-app.test.ts +12 -12
- package/src/test/live-signals.test.ts +6 -6
- package/src/test/provisions.integration.test.ts +10 -14
- package/src/test/reset-element-registries.ts +1 -1
- package/src/test/tenant-isolation.test.ts +12 -6
- package/site/content/docs/deployment/docker-swarm.mdx +0 -164
- package/site/content/docs/deployment/docker.mdx +0 -227
- package/site/content/docs/deployment/index.mdx +0 -83
- package/site/content/docs/deployment/kubernetes.mdx +0 -176
- package/site/content/docs/deployment/meta.json +0 -5
- package/site/content/docs/deployment/reverse-proxy.mdx +0 -234
- package/site/content/docs/elements/ai.mdx +0 -385
- package/site/content/docs/elements/channel.mdx +0 -346
- package/site/content/docs/elements/clock.mdx +0 -244
- package/site/content/docs/elements/flow.mdx +0 -420
- package/site/content/docs/elements/gate.mdx +0 -436
- package/site/content/docs/elements/signal.mdx +0 -380
- package/site/content/docs/elements/store.mdx +0 -1099
- package/site/content/docs/elements/vault.mdx +0 -405
- package/site/content/docs/get-started/basic-usage.mdx +0 -173
- package/site/content/docs/get-started/index.mdx +0 -43
- package/site/content/docs/get-started/installation.mdx +0 -220
- package/site/content/docs/get-started/introduction.mdx +0 -132
- package/site/content/docs/get-started/meta.json +0 -13
- package/site/content/docs/get-started/project-structure.mdx +0 -925
- package/site/content/docs/get-started/testing.mdx +0 -328
- package/site/content/docs/get-started/why.mdx +0 -162
- package/site/content/docs/recipes/llama-cpp.mdx +0 -151
- package/site/content/docs/recipes/ollama.mdx +0 -142
- package/site/content/docs/recipes/sglang.mdx +0 -105
- package/site/content/docs/recipes/vllm.mdx +0 -106
- package/site/content/docs/reference/cli.md +0 -232
- package/site/content/docs/reference/client.mdx +0 -469
- package/site/content/docs/reference/security.md +0 -74
- package/src/cli/ai-setup/detect-ollama.ts +0 -213
- package/src/cli/ai-setup/recommend.test.ts +0 -225
- package/src/cli/ai-setup/recommend.ts +0 -225
- package/src/cli/dev-controls.test.ts +0 -122
- package/src/cli/dev-controls.ts +0 -164
- package/src/cli/tui/DevLive.tsx +0 -126
- package/src/console/ui-next/dist/assets/access-page-De7Lc2JC.js +0 -4
- package/src/console/ui-next/dist/assets/agent-disclosure-BP0Y0Sux.js +0 -1
- package/src/console/ui-next/dist/assets/cache-glyph-B5X-NM0-.js +0 -1
- package/src/console/ui-next/dist/assets/call-pii-button-ChAUiLo9.js +0 -1
- package/src/console/ui-next/dist/assets/collapsible-DGnOM2ph.js +0 -1
- package/src/console/ui-next/dist/assets/copy-inline-button-DBHhgHKP.js +0 -1
- package/src/console/ui-next/dist/assets/dagre.esm-ZwcdTuZZ.js +0 -1
- package/src/console/ui-next/dist/assets/detail-header-DhHM1iaZ.js +0 -1
- package/src/console/ui-next/dist/assets/dropdown-menu-_NjTEo5_.js +0 -1
- package/src/console/ui-next/dist/assets/duration-tone-sC3lGABz.js +0 -9
- package/src/console/ui-next/dist/assets/element-icons-BVXtRyd3.js +0 -1
- package/src/console/ui-next/dist/assets/explorer-empty-2uIhBu0_.js +0 -1
- package/src/console/ui-next/dist/assets/flows-page-RGy7VEA_.js +0 -1
- package/src/console/ui-next/dist/assets/highlighted-json-Awq7gYdu.js +0 -154
- package/src/console/ui-next/dist/assets/http-method-_UHM2ODJ.js +0 -1
- package/src/console/ui-next/dist/assets/index-Ck88Jmv8.css +0 -2
- package/src/console/ui-next/dist/assets/index-_rgpdVzo.js +0 -66
- package/src/console/ui-next/dist/assets/link-BX6Vqztd.js +0 -1
- package/src/console/ui-next/dist/assets/observability-page-Ds6pcnh-.js +0 -4
- package/src/console/ui-next/dist/assets/preload-helper-oH4irX4C.js +0 -1
- package/src/console/ui-next/dist/assets/react-D8E3mtu1.js +0 -1
- package/src/console/ui-next/dist/assets/react-dom-Bph1y7z7.js +0 -9
- package/src/console/ui-next/dist/assets/replica-lag-DKRrbvdo.js +0 -18
- package/src/console/ui-next/dist/assets/request-meta-DV0ywz7t.js +0 -1
- package/src/console/ui-next/dist/assets/shortcut-JQIZlWfm.js +0 -1
- package/src/console/ui-next/dist/assets/shortcut-keys-DKxNTe_m.js +0 -1
- package/src/console/ui-next/dist/assets/skeleton-D-czQJT6.js +0 -1
- package/src/console/ui-next/dist/assets/store-page-02xOiqIK.js +0 -41
- package/src/console/ui-next/dist/assets/trace-detail-sheet-B09O8rA6.js +0 -2
- package/src/console/ui-next/dist/assets/tree-expand-toggle-BtyhmWb4.js +0 -55
- package/src/console/ui-next/dist/assets/units-page-4rHOePuE.js +0 -1
- package/src/console/ui-next/dist/assets/useMutation-B8EO02Ej.js +0 -1
- package/src/console/ui-next/dist/assets/useRender-BE2A9BWC.js +0 -1
- package/src/console/ui-next/dist/assets/vault-page-DISPgxLM.js +0 -2
- package/src/console/ui-next/dist/assets/xyflow-D7n4g6go.js +0 -7
- package/src/console/ui-next/dist/assets/xyflow-DZ0Ws1xk.css +0 -1
- package/src/docker/ollama-pull.ts +0 -232
- package/src/docker/recipes/llama-cpp.ts +0 -298
- package/src/docker/recipes/ollama.ts +0 -44
- package/src/docker/recipes/sglang.ts +0 -55
- package/src/docker/recipes/vllm.ts +0 -44
- package/src/drivers/ai-ollama-tools.integration.test.ts +0 -109
- package/src/drivers/ai-ollama.integration.test.ts +0 -184
- package/src/drivers/ai-ollama.ts +0 -389
- package/src/drivers/ollama.ts +0 -14
package/src/term.test.ts
CHANGED
|
@@ -50,7 +50,7 @@ describe("term", () => {
|
|
|
50
50
|
{ element: "flow", detail: "", status: "ready" },
|
|
51
51
|
{ element: "store", detail: "sql postgres · kv redis", status: "ready" },
|
|
52
52
|
{ element: "signal", detail: "memory", status: "ready" },
|
|
53
|
-
{ element: "ai", detail: "openai-compatible ·
|
|
53
|
+
{ element: "ai", detail: "openai-compatible · openrouter/free", status: "pending" },
|
|
54
54
|
],
|
|
55
55
|
});
|
|
56
56
|
expect(out).toContain("oke dev v0.2.4");
|
|
@@ -12,7 +12,7 @@ import { vault, VaultBootError } from "../elements/vault.ts";
|
|
|
12
12
|
import { oke } from "../kernel/app.ts";
|
|
13
13
|
import { flow, resetFlowSeq } from "../kernel/flow.ts";
|
|
14
14
|
import { on, resetBindings } from "../kernel/on.ts";
|
|
15
|
-
import {
|
|
15
|
+
import { http } from "../kernel/triggers.ts";
|
|
16
16
|
import { createTestApp } from "./create-test-app.ts";
|
|
17
17
|
|
|
18
18
|
describe("createTestApp — four-applications surface", () => {
|
|
@@ -21,11 +21,7 @@ describe("createTestApp — four-applications surface", () => {
|
|
|
21
21
|
resetFlowSeq();
|
|
22
22
|
|
|
23
23
|
const member = gate.policy("member", ({ auth }) => !!auth.verified);
|
|
24
|
-
const orderPlaced = signal("order-placed", {
|
|
25
|
-
delivery: "once",
|
|
26
|
-
retries: 2,
|
|
27
|
-
deadLetter: true,
|
|
28
|
-
});
|
|
24
|
+
const orderPlaced = signal.once("order-placed", { retries: 2, deadLetter: true });
|
|
29
25
|
const mail = channel.email({ from: "test@oke.dev" });
|
|
30
26
|
const orderConfirmed = mail.template("order-confirmed", {
|
|
31
27
|
schema: z.object({
|
|
@@ -36,10 +32,13 @@ describe("createTestApp — four-applications surface", () => {
|
|
|
36
32
|
});
|
|
37
33
|
|
|
38
34
|
on(
|
|
39
|
-
http
|
|
35
|
+
http
|
|
36
|
+
.post("/orders", {
|
|
37
|
+
in: z.object({ sku: z.string(), qty: z.number() }),
|
|
38
|
+
out: z.object({ id: z.string() }),
|
|
39
|
+
})
|
|
40
|
+
.gate(member),
|
|
40
41
|
flow("orders.create", {
|
|
41
|
-
in: z.object({ sku: z.string(), qty: z.number() }),
|
|
42
|
-
out: z.object({ id: z.string() }),
|
|
43
42
|
effects: { emits: ["order-placed"] },
|
|
44
43
|
do: async (input, fx) => {
|
|
45
44
|
const id = fx.id();
|
|
@@ -62,8 +61,9 @@ describe("createTestApp — four-applications surface", () => {
|
|
|
62
61
|
}),
|
|
63
62
|
);
|
|
64
63
|
|
|
64
|
+
const expireStale = clock("expire-stale", { every: "1h" });
|
|
65
65
|
on(
|
|
66
|
-
|
|
66
|
+
expireStale,
|
|
67
67
|
flow("orders.expire", {
|
|
68
68
|
do: (_i, fx) => {
|
|
69
69
|
fx.log.info("expire");
|
|
@@ -75,7 +75,7 @@ describe("createTestApp — four-applications surface", () => {
|
|
|
75
75
|
name: "harness",
|
|
76
76
|
gate: { policies: [member] },
|
|
77
77
|
signals: [orderPlaced],
|
|
78
|
-
clocks: [
|
|
78
|
+
clocks: [expireStale],
|
|
79
79
|
channel: { templates: [orderConfirmed] },
|
|
80
80
|
env: "test",
|
|
81
81
|
});
|
|
@@ -84,7 +84,7 @@ describe("createTestApp — four-applications surface", () => {
|
|
|
84
84
|
gates: [member],
|
|
85
85
|
signals: [orderPlaced],
|
|
86
86
|
boot: {
|
|
87
|
-
clocks: [
|
|
87
|
+
clocks: [expireStale],
|
|
88
88
|
channel: { templates: [orderConfirmed] },
|
|
89
89
|
},
|
|
90
90
|
});
|
|
@@ -17,15 +17,15 @@ describe("createTestApp live-signal subscriptions", () => {
|
|
|
17
17
|
resetBindings();
|
|
18
18
|
resetFlowSeq();
|
|
19
19
|
|
|
20
|
-
const orderStatus = signal("order-status", {
|
|
21
|
-
delivery: "live",
|
|
22
|
-
retention: { maxCount: 10 },
|
|
23
|
-
});
|
|
20
|
+
const orderStatus = signal.live("order-status", { retention: { maxCount: 10 } });
|
|
24
21
|
|
|
25
22
|
on(
|
|
26
|
-
http
|
|
23
|
+
http
|
|
24
|
+
.post("/orders/status", {
|
|
25
|
+
in: z.object({ orderId: z.string(), status: z.string() }),
|
|
26
|
+
})
|
|
27
|
+
.public(),
|
|
27
28
|
flow("orders.updateStatus", {
|
|
28
|
-
in: z.object({ orderId: z.string(), status: z.string() }),
|
|
29
29
|
effects: { emits: ["order-status"] },
|
|
30
30
|
do: async (input, fx) => {
|
|
31
31
|
await fx.emit(orderStatus, input);
|
|
@@ -11,6 +11,7 @@ import { gate } from "../elements/gate.ts";
|
|
|
11
11
|
import { signal } from "../elements/signal.ts";
|
|
12
12
|
import { vault } from "../elements/vault.ts";
|
|
13
13
|
import { oke } from "../kernel/app.ts";
|
|
14
|
+
import { call } from "../kernel/call.ts";
|
|
14
15
|
import { flow, resetFlowSeq } from "../kernel/flow.ts";
|
|
15
16
|
import { on, resetBindings } from "../kernel/on.ts";
|
|
16
17
|
import { http } from "../kernel/triggers.ts";
|
|
@@ -28,16 +29,8 @@ describe("Provisions integration", () => {
|
|
|
28
29
|
dev: "sk_test_local",
|
|
29
30
|
});
|
|
30
31
|
|
|
31
|
-
const orderPlaced = signal("order-placed", {
|
|
32
|
-
|
|
33
|
-
retries: 3,
|
|
34
|
-
deadLetter: true,
|
|
35
|
-
});
|
|
36
|
-
const orderNews = signal("order-news", {
|
|
37
|
-
delivery: "once",
|
|
38
|
-
retries: 3,
|
|
39
|
-
deadLetter: true,
|
|
40
|
-
});
|
|
32
|
+
const orderPlaced = signal.once("order-placed", { retries: 3, deadLetter: true });
|
|
33
|
+
const orderNews = signal.once("order-news", { retries: 3, deadLetter: true });
|
|
41
34
|
|
|
42
35
|
const mail = channel.email({ from: "Provisions <no-reply@provisions.sa>" });
|
|
43
36
|
const orderConfirmed = mail.template("order-confirmed", {
|
|
@@ -48,7 +41,7 @@ describe("Provisions integration", () => {
|
|
|
48
41
|
}),
|
|
49
42
|
});
|
|
50
43
|
|
|
51
|
-
const chargeOrder =
|
|
44
|
+
const chargeOrder = call("payments.chargeOrder", {
|
|
52
45
|
durable: true,
|
|
53
46
|
in: z.object({ orderId: z.string() }),
|
|
54
47
|
out: z.boolean(),
|
|
@@ -67,10 +60,13 @@ describe("Provisions integration", () => {
|
|
|
67
60
|
});
|
|
68
61
|
|
|
69
62
|
on(
|
|
70
|
-
http
|
|
63
|
+
http
|
|
64
|
+
.post("/orders", {
|
|
65
|
+
in: z.object({ sku: z.string(), qty: z.number() }),
|
|
66
|
+
out: z.object({ id: z.string() }),
|
|
67
|
+
})
|
|
68
|
+
.gate(member, canOrder),
|
|
71
69
|
flow("orders.create", {
|
|
72
|
-
in: z.object({ sku: z.string(), qty: z.number() }),
|
|
73
|
-
out: z.object({ id: z.string() }),
|
|
74
70
|
effects: { emits: ["order-placed"], calls: ["payments.chargeOrder"] },
|
|
75
71
|
do: async (input, fx) => {
|
|
76
72
|
const id = fx.id();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Global safety net for the `store.*` / `vault.secret` / `signal
|
|
2
|
+
* Global safety net for the `store.*` / `vault.secret` / `signal.*` /
|
|
3
3
|
* `clock()` / `gate.policy`·scope·rate / `channel.<medium>().template()` /
|
|
4
4
|
* `ai.model`·prompt·embed·agent auto-registries
|
|
5
5
|
* (`src/kernel/element-registries.ts`).
|
|
@@ -39,10 +39,13 @@ describe("createTestApp tenancy testing & RLS isolation", () => {
|
|
|
39
39
|
const docStore = store.sql("docs", { schema: { documents } });
|
|
40
40
|
|
|
41
41
|
on(
|
|
42
|
-
http
|
|
42
|
+
http
|
|
43
|
+
.post("/docs", {
|
|
44
|
+
in: z.object({ title: z.string() }),
|
|
45
|
+
out: z.object({ id: z.string(), tenantId: z.string().nullable() }),
|
|
46
|
+
})
|
|
47
|
+
.gate(memberGate),
|
|
43
48
|
flow("docs.create", {
|
|
44
|
-
in: z.object({ title: z.string() }),
|
|
45
|
-
out: z.object({ id: z.string(), tenantId: z.string().nullable() }),
|
|
46
49
|
effects: { writes: ["sql:docs"], reads: ["sql:docs"] },
|
|
47
50
|
do: async (input, fx) => {
|
|
48
51
|
const id = fx.id();
|
|
@@ -57,10 +60,13 @@ describe("createTestApp tenancy testing & RLS isolation", () => {
|
|
|
57
60
|
);
|
|
58
61
|
|
|
59
62
|
on(
|
|
60
|
-
http
|
|
63
|
+
http
|
|
64
|
+
.get("/docs", {
|
|
65
|
+
in: z.void(),
|
|
66
|
+
out: z.array(z.object({ id: z.string(), title: z.string() })),
|
|
67
|
+
})
|
|
68
|
+
.gate(memberGate),
|
|
61
69
|
flow("docs.list", {
|
|
62
|
-
in: z.void(),
|
|
63
|
-
out: z.array(z.object({ id: z.string(), title: z.string() })),
|
|
64
70
|
effects: { reads: ["sql:docs"] },
|
|
65
71
|
do: async (_input, fx) => {
|
|
66
72
|
const rows = await fx.store(docStore).select().from(documents);
|
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Docker Swarm
|
|
3
|
-
description: Deploy with docker stack deploy — docker-stack.yml, PgDog, HEALTHCHECK readiness, graceful SIGTERM, known multi-instance limits, and optional Caddy, Traefik, or nginx.
|
|
4
|
-
icon: Ship
|
|
5
|
-
source: README.md
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
Swarm consumes the stack file `oke docker --stack` writes. It adds built-in
|
|
9
|
-
orchestration (scale, rolling updates, routing mesh) with a lower learning
|
|
10
|
-
curve than Kubernetes. Scale replaceable replicas; share durable drivers.
|
|
11
|
-
|
|
12
|
-
<Callout title="The one rule">
|
|
13
|
-
Deploy with `docker stack deploy`. Docker’s single `HEALTHCHECK` targets `GET /_/ready`. Treat
|
|
14
|
-
every task as replaceable — shared Postgres / Redis / S3, SIGTERM via `stop_grace_period`, honest
|
|
15
|
-
Signal/Channel process-local limits.
|
|
16
|
-
</Callout>
|
|
17
|
-
|
|
18
|
-
## Quick start
|
|
19
|
-
|
|
20
|
-
<Steps>
|
|
21
|
-
|
|
22
|
-
<Step>
|
|
23
|
-
### Derive the Swarm stack file
|
|
24
|
-
|
|
25
|
-
```bash
|
|
26
|
-
oke docker --stack
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
Emits `Dockerfile` + **`docker-stack.yml`** (overlay network, `HEALTHCHECK` →
|
|
30
|
-
`/_/ready`, `deploy.*`, `stop_grace_period: 30s`, resource limits from the
|
|
31
|
-
default **4 CPU / 8 GiB** budget — override with `--cpus` / `--memory`).
|
|
32
|
-
|
|
33
|
-
Prefer `--stack` over composing many `-c` files. The default `oke docker`
|
|
34
|
-
(single `docker-compose.yml`) stays for plain Compose hosts.
|
|
35
|
-
|
|
36
|
-
</Step>
|
|
37
|
-
|
|
38
|
-
<Step>
|
|
39
|
-
### Build the app image, init Swarm, deploy
|
|
40
|
-
|
|
41
|
-
`docker stack deploy` ignores `build` — tag first (name matches the stack file).
|
|
42
|
-
|
|
43
|
-
```bash
|
|
44
|
-
docker build -t oke-<app>:latest -f docker/Dockerfile .
|
|
45
|
-
docker swarm init
|
|
46
|
-
cd docker
|
|
47
|
-
docker stack deploy -c docker-stack.yml myapp
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
Create `secrets:` names via `docker secret create` when you use secret refs,
|
|
51
|
-
or keep credentials in `.env.local` for single-node labs.
|
|
52
|
-
|
|
53
|
-
</Step>
|
|
54
|
-
|
|
55
|
-
<Step>
|
|
56
|
-
### Scale and roll
|
|
57
|
-
|
|
58
|
-
```bash
|
|
59
|
-
docker service scale myapp_app=3
|
|
60
|
-
docker service update --image oke-<app>:latest myapp_app
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
Prod deploy block: `update_config` (`parallelism: 1`, `order: start-first`,
|
|
64
|
-
`failure_action: rollback`) and `restart_policy.condition: on-failure`.
|
|
65
|
-
|
|
66
|
-
</Step>
|
|
67
|
-
|
|
68
|
-
</Steps>
|
|
69
|
-
|
|
70
|
-
## Share backing services
|
|
71
|
-
|
|
72
|
-
Pin `dev`/`prod` drivers to shared stores:
|
|
73
|
-
|
|
74
|
-
| Concern | Driver | Shared backend |
|
|
75
|
-
| ----------------------------- | ---------------------------- | ------------------------------------------------- |
|
|
76
|
-
| SQL / durable journal / clock | `postgres` | Postgres (optionally via PgDog) |
|
|
77
|
-
| Gate rate counters | `redis` (`drivers.store.kv`) | Redis / Valkey / Dragonfly (`images["store.kv"]`) |
|
|
78
|
-
| Files | `s3` | S3-compatible object store |
|
|
79
|
-
| Signal | see known limits below | — |
|
|
80
|
-
|
|
81
|
-
## PgDog pooling
|
|
82
|
-
|
|
83
|
-
Bun.SQL defaults to **10** connections per process — fine for one replica.
|
|
84
|
-
Scale the Swarm service and `N × pool` can exceed Postgres `max_connections`.
|
|
85
|
-
|
|
86
|
-
When both `store.sql` and `pgdog` are pinned (`dev`/`prod` template default),
|
|
87
|
-
`DATABASE_URL` points at PgDog `:6432` — transaction pooling, wire-transparent.
|
|
88
|
-
Configs: `docker/pgdog/pgdog.toml` + `docker/pgdog/users.toml`.
|
|
89
|
-
|
|
90
|
-
**Why PgDog.** Transaction pooling fixes the connection math. Naive poolers can
|
|
91
|
-
leak session state (`SET`, RLS vars, `LISTEN`/`NOTIFY`) across clients; PgDog
|
|
92
|
-
re-applies those under transaction mode.
|
|
93
|
-
|
|
94
|
-
Read-replica routing (`BEGIN READ ONLY` → replica) is documented readiness —
|
|
95
|
-
not configured in the generated stack yet.
|
|
96
|
-
|
|
97
|
-
## Redis-protocol images (Redis · Valkey · Dragonfly)
|
|
98
|
-
|
|
99
|
-
`images["store.kv"]` defaults to Redis (most mature). Pin Valkey or Dragonfly
|
|
100
|
-
the same way — driver id stays `redis`, same `REDIS_URL`. Image table + one-line
|
|
101
|
-
licenses: [Store · KV](/docs/elements/store#kv).
|
|
102
|
-
|
|
103
|
-
## Readiness and liveness
|
|
104
|
-
|
|
105
|
-
| Endpoint | Role | On Swarm |
|
|
106
|
-
| -------------- | ------------------------------------------------------ | ----------------------------------------------------- |
|
|
107
|
-
| `GET /_/ready` | Kernel readiness (`booting` → `orphan_scan` → `ready`) | Single Docker `HEALTHCHECK` — routing mesh waits here |
|
|
108
|
-
| `GET /health` | App liveness | External monitors only |
|
|
109
|
-
|
|
110
|
-
## Graceful shutdown
|
|
111
|
-
|
|
112
|
-
`stop_grace_period: 30s` gives `installGracefulShutdown` time to release Clock /
|
|
113
|
-
Journal leases before the task is killed. Signal message leases reclaim after
|
|
114
|
-
visibility TTL on survivors.
|
|
115
|
-
|
|
116
|
-
## Reverse proxy
|
|
117
|
-
|
|
118
|
-
Same opt-in `images.proxy` pins as plain Compose — Caddy, Traefik, or nginx. Re-run
|
|
119
|
-
`oke docker --stack` after pinning. Details:
|
|
120
|
-
[Reverse proxy](/docs/deployment/reverse-proxy).
|
|
121
|
-
|
|
122
|
-
## Known multi-instance limits
|
|
123
|
-
|
|
124
|
-
Same table as [Docker](/docs/deployment/docker#known-multi-instance-limits) —
|
|
125
|
-
Clock / Journal / Gate redis / Store shared; Signal consume and Channel consent
|
|
126
|
-
stores stay process-local until durable drivers ship.
|
|
127
|
-
|
|
128
|
-
## Troubleshooting
|
|
129
|
-
|
|
130
|
-
<Accordions>
|
|
131
|
-
<Accordion title="stack deploy ignores build">
|
|
132
|
-
|
|
133
|
-
Build and tag `oke-<app>:latest` first (`docker build -f docker/Dockerfile .`).
|
|
134
|
-
Swarm never runs Compose `build:`.
|
|
135
|
-
|
|
136
|
-
</Accordion>
|
|
137
|
-
<Accordion title="New task gets traffic before orphan scan finishes">
|
|
138
|
-
|
|
139
|
-
Confirm `HEALTHCHECK` targets `/_/ready` in `docker-stack.yml`. Without it,
|
|
140
|
-
Swarm treats “container started” as ready.
|
|
141
|
-
|
|
142
|
-
</Accordion>
|
|
143
|
-
<Accordion title="Overlay networking / multi-node volumes">
|
|
144
|
-
|
|
145
|
-
Multi-node needs shared Postgres / Redis / S3 — do not rely on local named
|
|
146
|
-
volumes for durable state across nodes.
|
|
147
|
-
|
|
148
|
-
</Accordion>
|
|
149
|
-
</Accordions>
|
|
150
|
-
|
|
151
|
-
## Learn more
|
|
152
|
-
|
|
153
|
-
- [Docker](/docs/deployment/docker) — plain compose default
|
|
154
|
-
- [Reverse proxy](/docs/deployment/reverse-proxy) — Caddy / Traefik / nginx
|
|
155
|
-
- [Kubernetes](/docs/deployment/kubernetes) — Deployment, probes, Ingress
|
|
156
|
-
- [CLI](/docs/reference/cli) — `oke docker --stack`
|
|
157
|
-
|
|
158
|
-
## Next
|
|
159
|
-
|
|
160
|
-
<Cards>
|
|
161
|
-
<Card title="Docker" href="/docs/deployment/docker" />
|
|
162
|
-
<Card title="Reverse proxy" href="/docs/deployment/reverse-proxy" />
|
|
163
|
-
<Card title="Kubernetes" href="/docs/deployment/kubernetes" />
|
|
164
|
-
</Cards>
|
|
@@ -1,227 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Docker
|
|
3
|
-
description: Deploy with plain docker compose — single production-grade docker-compose.yml, shared drivers, PgDog, readiness, graceful SIGTERM, and opt-in Caddy, Traefik, or nginx when you need an edge without an orchestrator.
|
|
4
|
-
icon: Package
|
|
5
|
-
source: README.md
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
Plain `docker compose` is the simplest production shape: single or few app
|
|
9
|
-
instances on one host (or a small set you manage yourself). Derive with
|
|
10
|
-
`oke docker`; opt into a proxy only when you need HTTPS at the edge.
|
|
11
|
-
|
|
12
|
-
<Callout title="The one rule">
|
|
13
|
-
Treat every app container as replaceable. Put durable state in Postgres / Redis / S3, wait on `GET
|
|
14
|
-
/_/ready`, give SIGTERM time to release leases, and leave `images.proxy` unset until you need TLS
|
|
15
|
-
or `--scale app=N`.
|
|
16
|
-
</Callout>
|
|
17
|
-
|
|
18
|
-
## Quick start
|
|
19
|
-
|
|
20
|
-
<Steps>
|
|
21
|
-
|
|
22
|
-
<Step>
|
|
23
|
-
### Derive compose
|
|
24
|
-
|
|
25
|
-
```bash
|
|
26
|
-
oke docker
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
Writes `Dockerfile` + production-grade **`docker-compose.yml`** under `docker/`
|
|
30
|
-
(readiness HEALTHCHECK on `/_/ready`, deploy policy, resource limits).
|
|
31
|
-
Default host budget is **4 CPU / 8 GiB** — override with `--cpus` / `--memory`.
|
|
32
|
-
|
|
33
|
-
Other layouts when you ask for them:
|
|
34
|
-
|
|
35
|
-
| Flag | Output |
|
|
36
|
-
| ----------- | --------------------------------------------------------- |
|
|
37
|
-
| _(default)_ | `docker-compose.yml` |
|
|
38
|
-
| `--split` | `compose.yml` + `compose.<role>.yml` + `compose.prod.yml` |
|
|
39
|
-
| `--stack` | `docker-stack.yml` for Swarm (`docker stack deploy -c`) |
|
|
40
|
-
|
|
41
|
-
Without a proxy, the app still publishes port `6530`.
|
|
42
|
-
|
|
43
|
-
</Step>
|
|
44
|
-
|
|
45
|
-
<Step>
|
|
46
|
-
### Share backing services
|
|
47
|
-
|
|
48
|
-
Pin `dev`/`prod` drivers to shared stores (create-oke templates already do —
|
|
49
|
-
same protocols locally via `oke dev` and in production):
|
|
50
|
-
|
|
51
|
-
| Concern | Driver | Shared backend |
|
|
52
|
-
| ----------------------------- | ---------------------------- | ---------------------------------------------- |
|
|
53
|
-
| SQL / durable journal / clock | `postgres` | Postgres (optionally via PgDog) |
|
|
54
|
-
| Gate rate counters | `redis` (`drivers.store.kv`) | Redis / Valkey / Dragonfly (`images.store.kv`) |
|
|
55
|
-
| Files | `s3` | S3-compatible object store |
|
|
56
|
-
| Signal | see known limits below | — |
|
|
57
|
-
|
|
58
|
-
<Callout>
|
|
59
|
-
The monorepo `examples/keel` app is the work-management Compose fixture — `bun run dev:keel`, then
|
|
60
|
-
`oke db seed` (Harbor GA story + ~500 tasks). Wipe with `bun run dev:keel:reset` (stops leftover
|
|
61
|
-
ports, fresh `.env.local`).
|
|
62
|
-
</Callout>
|
|
63
|
-
|
|
64
|
-
</Step>
|
|
65
|
-
|
|
66
|
-
<Step>
|
|
67
|
-
### Bring the stack up
|
|
68
|
-
|
|
69
|
-
```bash
|
|
70
|
-
cd docker
|
|
71
|
-
docker compose -f docker-compose.yml up -d
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
Add `-f docker-compose.override.yml` if you keep local tweaks (oke never writes
|
|
75
|
-
that file). With `--split`, pass every `-f` file `oke docker` prints.
|
|
76
|
-
|
|
77
|
-
</Step>
|
|
78
|
-
|
|
79
|
-
</Steps>
|
|
80
|
-
|
|
81
|
-
## PgDog pooling
|
|
82
|
-
|
|
83
|
-
Bun.SQL defaults to **10** connections per process — fine for one instance.
|
|
84
|
-
Scale out and `N × pool` can exceed Postgres `max_connections`.
|
|
85
|
-
|
|
86
|
-
When both `store.sql` and `pgdog` are pinned (templates' `dev`/`prod` default),
|
|
87
|
-
`DATABASE_URL` points at PgDog `:6432` — transaction pooling, wire-transparent.
|
|
88
|
-
Configs: `docker/pgdog/pgdog.toml` + `docker/pgdog/users.toml`.
|
|
89
|
-
|
|
90
|
-
**Why PgDog.** Transaction pooling fixes the connection math. Naive poolers can
|
|
91
|
-
leak session state (`SET`, RLS vars, `LISTEN`/`NOTIFY`) across clients; PgDog
|
|
92
|
-
re-applies those under transaction mode.
|
|
93
|
-
|
|
94
|
-
Read-replica routing (`BEGIN READ ONLY` → replica) is documented readiness —
|
|
95
|
-
not configured in the generated stack yet.
|
|
96
|
-
|
|
97
|
-
## Redis-protocol images (Redis · Valkey · Dragonfly)
|
|
98
|
-
|
|
99
|
-
`images["store.kv"]` defaults to Redis (most mature). Pin Valkey or Dragonfly
|
|
100
|
-
the same way — driver id stays `redis`, same `REDIS_URL`. Image table + one-line
|
|
101
|
-
licenses: [Store · KV](/docs/elements/store#kv).
|
|
102
|
-
|
|
103
|
-
## Readiness and liveness
|
|
104
|
-
|
|
105
|
-
| Endpoint | Role | On plain compose |
|
|
106
|
-
| -------------- | ----------------------------------------------------------- | ---------------------------------------------------- |
|
|
107
|
-
| `GET /_/ready` | Kernel readiness (`booting` → `orphan_scan` → `ready`) | HEALTHCHECK in `docker-compose.yml`; LBs should wait |
|
|
108
|
-
| `GET /health` | App liveness (create-oke ships one) — cheap “process alive” | External monitors only — not orphan-scan aware |
|
|
109
|
-
|
|
110
|
-
`/_/ready` returns `200 { ready: true }` only after boot and the durable orphan
|
|
111
|
-
scan finish. While booting or scanning it returns
|
|
112
|
-
`503 { ready: false, reason: "booting" | "orphan_scan" }`.
|
|
113
|
-
|
|
114
|
-
**Consequence:** orphan scan delays “healthy” (and traffic) on purpose so a
|
|
115
|
-
new replica is not hit mid-takeover.
|
|
116
|
-
|
|
117
|
-
## Graceful shutdown
|
|
118
|
-
|
|
119
|
-
On `SIGTERM` / `SIGINT`, `installGracefulShutdown` (wired by `oke dev`’s app
|
|
120
|
-
runner; call it next to `createBunRuntime().serve` in custom entries):
|
|
121
|
-
|
|
122
|
-
1. Stops accepting new connections
|
|
123
|
-
2. Releases **Clock** cron leases and **Journal** run leases held by this instance
|
|
124
|
-
3. Closes element runtimes and exits
|
|
125
|
-
|
|
126
|
-
Signal message leases have no proactive release today — survivors reclaim after
|
|
127
|
-
the visibility TTL (default 30s). Generated compose sets `stop_grace_period: 30s`
|
|
128
|
-
so the release path can finish (≥ typical Clock / Journal / Signal lease TTL).
|
|
129
|
-
|
|
130
|
-
## Reverse proxy
|
|
131
|
-
|
|
132
|
-
Omit `images.proxy` until you need HTTPS or horizontal scale without fighting a
|
|
133
|
-
host port bind. Then pick one:
|
|
134
|
-
|
|
135
|
-
| Choice | Best for | How routing works |
|
|
136
|
-
| ------------------------------- | ----------------------------------------- | ------------------------------------------------------------------ |
|
|
137
|
-
| **Caddy** (`caddy:2-alpine`) | Single instance, simplest automatic HTTPS | Generated `Caddyfile` → `reverse_proxy app:6530` |
|
|
138
|
-
| **Traefik** (`traefik:v3.7`) | `docker compose up --scale app=N` | Docker labels on `app`; replicas auto-discovered and load-balanced |
|
|
139
|
-
| **nginx** (`nginx:1.31-alpine`) | Static HTTP edge; TLS elsewhere | Generated `nginx.conf` → `proxy_pass` to `app:6530` on `:80` |
|
|
140
|
-
|
|
141
|
-
```typescript title="oke.config.ts"
|
|
142
|
-
images: {
|
|
143
|
-
// …
|
|
144
|
-
proxy: "caddy:2-alpine", // or "traefik:v3.7" / "nginx:1.31-alpine"
|
|
145
|
-
},
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
`create-oke` asks **Add a reverse proxy…?** (or `--proxy caddy|traefik|nginx|none`).
|
|
149
|
-
|
|
150
|
-
```bash title=".env.local"
|
|
151
|
-
OKE_PROXY_HOST=app.example.com
|
|
152
|
-
OKE_PROXY_ACME_EMAIL=admin@example.com
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
Re-run `oke docker`. Edge publishes `80`/`443`; `app` stays internal.
|
|
156
|
-
Set `allowedHosts` to your public hostname ([Security](/docs/reference/security)).
|
|
157
|
-
|
|
158
|
-
Traefik never mounts raw `docker.sock` — only a filtered
|
|
159
|
-
`tecnativa/docker-socket-proxy` on the internal network. Full custom-domain,
|
|
160
|
-
Let's Encrypt, and socket-proxy rationale → [Reverse proxy](/docs/deployment/reverse-proxy).
|
|
161
|
-
|
|
162
|
-
## Known multi-instance limits
|
|
163
|
-
|
|
164
|
-
| Surface | Multi-instance today |
|
|
165
|
-
| ---------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
|
|
166
|
-
| Clock (`postgres` / shared `file`) | Shared leader election |
|
|
167
|
-
| Journal (`postgres` / shared `file`) | Shared durable runs + orphan resume |
|
|
168
|
-
| Gate rates (`drivers.store.kv: redis`) | Shared counters |
|
|
169
|
-
| Store SQL / KV redis / files `s3` | Shared |
|
|
170
|
-
| Store files `fs` | **Per-instance filesystem** — boot warns; use `s3` when scaled |
|
|
171
|
-
| Signal `redis` | Emit relays to Redis; **consume / `live` / `drain` are process-local outbox** until Streams consume ships |
|
|
172
|
-
| Channel suppression / consent / receipts | **Default stores are process-local** — opt-out on replica A is invisible to B until a durable driver ships |
|
|
173
|
-
|
|
174
|
-
## Troubleshooting
|
|
175
|
-
|
|
176
|
-
<Accordions>
|
|
177
|
-
<Accordion title="compose up --scale app=N fails with port already allocated">
|
|
178
|
-
|
|
179
|
-
You still have `6530:6530` on `app`. Confirm `images.proxy` is set and
|
|
180
|
-
re-derived so the host bind was omitted.
|
|
181
|
-
|
|
182
|
-
</Accordion>
|
|
183
|
-
<Accordion title="New replica gets traffic before orphan scan finishes">
|
|
184
|
-
|
|
185
|
-
Confirm the healthcheck hits `/_/ready` (default `oke docker` output). Without
|
|
186
|
-
it, compose treats “container started” as ready. Pass `--no-prod` only when you
|
|
187
|
-
intentionally want a bare derive.
|
|
188
|
-
|
|
189
|
-
</Accordion>
|
|
190
|
-
<Accordion title="Rate limits look twice as high after scaling to 2">
|
|
191
|
-
|
|
192
|
-
`drivers.store.kv` must be `redis` with `REDIS_URL` set. A missing URL **fails
|
|
193
|
-
boot** (no silent memory fallback). Declaring `memory` for local is fine;
|
|
194
|
-
`dev`/`prod` should stay on redis.
|
|
195
|
-
|
|
196
|
-
</Accordion>
|
|
197
|
-
<Accordion title="Files uploaded on instance A are missing on B">
|
|
198
|
-
|
|
199
|
-
`drivers.store.files: "fs"` is single-host. Switch `dev`/`prod` to `s3`
|
|
200
|
-
(create-oke templates already do).
|
|
201
|
-
|
|
202
|
-
</Accordion>
|
|
203
|
-
<Accordion title="Host header rejected (403)">
|
|
204
|
-
|
|
205
|
-
Serve validates `Host`. Add your public hostname to `allowedHosts`
|
|
206
|
-
([Security](/docs/reference/security)).
|
|
207
|
-
|
|
208
|
-
</Accordion>
|
|
209
|
-
</Accordions>
|
|
210
|
-
|
|
211
|
-
## Learn more
|
|
212
|
-
|
|
213
|
-
- [Deployment](/docs/deployment) — choose compose, Swarm, or Kubernetes
|
|
214
|
-
- [Reverse proxy](/docs/deployment/reverse-proxy) — Caddy / Traefik / nginx in full
|
|
215
|
-
- [Docker Swarm](/docs/deployment/docker-swarm) — `docker stack deploy`
|
|
216
|
-
- [Kubernetes](/docs/deployment/kubernetes) — Deployment, probes, Ingress
|
|
217
|
-
- [CLI](/docs/reference/cli) — `oke docker`, layouts, budget flags
|
|
218
|
-
- [Store](/docs/elements/store) — PgDog and facets
|
|
219
|
-
- [Security](/docs/reference/security) — `allowedHosts`
|
|
220
|
-
|
|
221
|
-
## Next
|
|
222
|
-
|
|
223
|
-
<Cards>
|
|
224
|
-
<Card title="Deployment" href="/docs/deployment" />
|
|
225
|
-
<Card title="Reverse proxy" href="/docs/deployment/reverse-proxy" />
|
|
226
|
-
<Card title="Docker Swarm" href="/docs/deployment/docker-swarm" />
|
|
227
|
-
</Cards>
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Deployment
|
|
3
|
-
description: Choose plain docker compose, Docker Swarm, or Kubernetes — then follow that path's complete page for PgDog, probes, graceful shutdown, and TLS.
|
|
4
|
-
icon: Server
|
|
5
|
-
source: README.md
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
OKE apps are process-stateless when shared drivers back Store, Clock, Journal,
|
|
9
|
-
and Gate. Pick an orchestrator (or none) first; each path page below is
|
|
10
|
-
self-contained after you choose.
|
|
11
|
-
|
|
12
|
-
<Callout title="The one rule">
|
|
13
|
-
Decide the deploy shape here, then open **one** path page and follow it end to end. Do not mix
|
|
14
|
-
recipes across pages — Docker proxy compose ≠ Kubernetes Ingress.
|
|
15
|
-
</Callout>
|
|
16
|
-
|
|
17
|
-
## Which path?
|
|
18
|
-
|
|
19
|
-
| Path | Best for | Trade-off |
|
|
20
|
-
| --------------------------------------------- | -------------------------------------------- | ---------------------------------------------------- |
|
|
21
|
-
| [Docker](/docs/deployment/docker) (compose) | Simplest — single or few instances | You run scale / restart / TLS yourself (or opt in) |
|
|
22
|
-
| [Docker Swarm](/docs/deployment/docker-swarm) | Built-in orchestration, lower learning curve | Smaller ecosystem than Kubernetes; mesh ≠ certs |
|
|
23
|
-
| [Kubernetes](/docs/deployment/kubernetes) | Full orchestration, largest ecosystem | Highest operational surface (Ingress, probes, RBAC…) |
|
|
24
|
-
|
|
25
|
-
**Consequence:** start with plain compose until you need Swarm's service mesh /
|
|
26
|
-
rolling updates or Kubernetes' cluster ecosystem. Same multi-instance contract
|
|
27
|
-
on every path — shared Postgres/Redis/S3, not sticky pod identity.
|
|
28
|
-
|
|
29
|
-
## Capabilities (every path)
|
|
30
|
-
|
|
31
|
-
These already ship. Each path page explains them in full in that page's words:
|
|
32
|
-
|
|
33
|
-
| Capability | What it guarantees | Deep dive |
|
|
34
|
-
| --------------------------------- | --------------------------------------------------------------------------------------- | ------------------------------------------------ |
|
|
35
|
-
| **PgDog pooling** | `dev`/`prod` SQL goes through transaction pooler (`DATABASE_URL` → `:6432`) when pinned | Path pages · [Store](/docs/elements/store) |
|
|
36
|
-
| **Graceful SIGTERM** | `installGracefulShutdown` releases Clock + Journal leases, then drains | Path pages |
|
|
37
|
-
| **Readiness vs liveness** | `GET /_/ready` (kernel) vs app `GET /health` | Path pages |
|
|
38
|
-
| **Horizontal proof** | Two-process integration test against live Postgres + Redis | Changelog / CI (`OKE_TEST_POSTGRES_URL` + Redis) |
|
|
39
|
-
| **Reverse proxy (compose/Swarm)** | Opt-in Caddy, Traefik, or nginx (`images.proxy`) | [Reverse proxy](/docs/deployment/reverse-proxy) |
|
|
40
|
-
| **Ingress (Kubernetes)** | Cluster-native Ingress / Gateway API | [Kubernetes](/docs/deployment/kubernetes) |
|
|
41
|
-
|
|
42
|
-
Honesty notes (Signal consume / Channel suppression still process-local) live
|
|
43
|
-
on each path page — not papered over here.
|
|
44
|
-
|
|
45
|
-
## Pick a path
|
|
46
|
-
|
|
47
|
-
<Cards>
|
|
48
|
-
<Card
|
|
49
|
-
title="Docker"
|
|
50
|
-
description="Plain compose — simplest single or few-instance deploy."
|
|
51
|
-
href="/docs/deployment/docker"
|
|
52
|
-
/>
|
|
53
|
-
<Card
|
|
54
|
-
title="Docker Swarm"
|
|
55
|
-
description="stack deploy on the generated compose layers."
|
|
56
|
-
href="/docs/deployment/docker-swarm"
|
|
57
|
-
/>
|
|
58
|
-
<Card
|
|
59
|
-
title="Kubernetes"
|
|
60
|
-
description="Deployment, probes, shared drivers, Ingress."
|
|
61
|
-
href="/docs/deployment/kubernetes"
|
|
62
|
-
/>
|
|
63
|
-
<Card
|
|
64
|
-
title="Reverse proxy"
|
|
65
|
-
description="Caddy / Traefik / nginx — TLS, domains, socket-proxy why."
|
|
66
|
-
href="/docs/deployment/reverse-proxy"
|
|
67
|
-
/>
|
|
68
|
-
</Cards>
|
|
69
|
-
|
|
70
|
-
## Learn more
|
|
71
|
-
|
|
72
|
-
- [Installation](/docs/get-started/installation) — scaffold and `oke dev`
|
|
73
|
-
- [CLI](/docs/reference/cli) — `oke docker --prod`, `oke start`
|
|
74
|
-
- [Configuration](/docs/reference/configuration) — `images` and drivers
|
|
75
|
-
- [Store](/docs/elements/store) — PgDog and facets
|
|
76
|
-
|
|
77
|
-
## Next
|
|
78
|
-
|
|
79
|
-
<Cards>
|
|
80
|
-
<Card title="Docker" href="/docs/deployment/docker" />
|
|
81
|
-
<Card title="Docker Swarm" href="/docs/deployment/docker-swarm" />
|
|
82
|
-
<Card title="Kubernetes" href="/docs/deployment/kubernetes" />
|
|
83
|
-
</Cards>
|