okengine 0.10.2 → 0.11.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/package.json +76 -10
- package/site/content/docs/ai/mcp.mdx +0 -1
- package/site/content/docs/deployment/docker-swarm.mdx +48 -111
- package/site/content/docs/deployment/docker.mdx +43 -36
- package/site/content/docs/deployment/index.mdx +9 -9
- package/site/content/docs/deployment/kubernetes.mdx +4 -4
- package/site/content/docs/elements/ai.mdx +7 -13
- package/site/content/docs/elements/channel.mdx +9 -13
- package/site/content/docs/elements/clock.mdx +8 -14
- package/site/content/docs/elements/flow.mdx +46 -54
- package/site/content/docs/elements/gate.mdx +6 -11
- package/site/content/docs/elements/signal.mdx +2 -8
- package/site/content/docs/elements/store.mdx +79 -93
- package/site/content/docs/elements/vault.mdx +89 -76
- package/site/content/docs/get-started/basic-usage.mdx +8 -14
- package/site/content/docs/get-started/installation.mdx +36 -36
- package/site/content/docs/get-started/introduction.mdx +11 -0
- package/site/content/docs/get-started/why.mdx +3 -4
- package/site/content/docs/index.mdx +0 -1
- package/site/content/docs/meta.json +0 -1
- package/site/content/docs/plugins/anonymous.mdx +1 -1
- package/site/content/docs/plugins/magic-link.mdx +11 -11
- package/site/content/docs/plugins/otp.mdx +2 -2
- package/site/content/docs/plugins/passkey.mdx +1 -1
- package/site/content/docs/plugins/two-factor.mdx +1 -1
- package/site/content/docs/plugins/username.mdx +1 -1
- package/site/content/docs/recipes/caddy.mdx +1 -1
- package/site/content/docs/recipes/cockroachdb.mdx +2 -2
- package/site/content/docs/recipes/dragonfly.mdx +1 -1
- package/site/content/docs/recipes/index.mdx +1 -2
- package/site/content/docs/recipes/llama-cpp.mdx +21 -23
- package/site/content/docs/recipes/mailpit.mdx +11 -11
- package/site/content/docs/recipes/meilisearch.mdx +10 -10
- package/site/content/docs/recipes/meta.json +0 -1
- package/site/content/docs/recipes/ollama.mdx +1 -1
- package/site/content/docs/recipes/pgdog.mdx +12 -9
- package/site/content/docs/recipes/postgres.mdx +3 -3
- package/site/content/docs/recipes/redis.mdx +2 -2
- package/site/content/docs/recipes/rustfs.mdx +10 -7
- package/site/content/docs/recipes/sglang.mdx +1 -1
- package/site/content/docs/recipes/supabase-docker.mdx +1 -1
- package/site/content/docs/recipes/timescale.mdx +2 -2
- package/site/content/docs/recipes/valkey.mdx +1 -1
- package/site/content/docs/recipes/vllm.mdx +1 -1
- package/site/content/docs/recipes/yugabytedb.mdx +2 -2
- package/site/content/docs/reference/cli.md +61 -38
- package/site/content/docs/reference/configuration.mdx +145 -70
- package/site/content/docs/reference/environment-variables.mdx +36 -28
- package/site/content/docs/reference/errors.mdx +28 -29
- package/site/content/docs/reference/fx.mdx +14 -7
- package/site/content/docs/reference/i18n.mdx +17 -6
- package/site/content/docs/reference/index.mdx +5 -0
- package/site/content/docs/reference/meta.json +1 -0
- package/site/content/docs/reference/migrating-environments.mdx +158 -0
- package/site/content/docs/reference/plugins.mdx +2 -2
- package/src/auth/gate-auth.test.ts +12 -10
- package/src/cli/ai-setup/ai-setup.test.ts +30 -16
- package/src/cli/ai-setup/apply.ts +111 -15
- package/src/cli/ai-setup/catalog.ts +3 -3
- package/src/cli/ai-setup/index.ts +1 -1
- package/src/cli/ai-setup/prompts.ts +1 -1
- package/src/cli/ai-setup/recommend.test.ts +1 -1
- package/src/cli/ask-seed.test.ts +3 -3
- package/src/cli/build.ts +8 -9
- package/src/cli/db-auto-push.test.ts +6 -3
- package/src/cli/db-auto-push.ts +7 -5
- package/src/cli/db-seed.ts +7 -8
- package/src/cli/db.test.ts +70 -71
- package/src/cli/db.ts +86 -12
- package/src/cli/dev-controller.test.ts +35 -0
- package/src/cli/dev-controller.ts +298 -0
- package/src/cli/dev-controls.ts +11 -65
- package/src/cli/dev-db-push.test.ts +47 -15
- package/src/cli/dev-schema-sync.test.ts +11 -11
- package/src/cli/dev-schema-sync.ts +10 -10
- package/src/cli/dev-session-lock.test.ts +106 -0
- package/src/cli/dev-session-lock.ts +209 -0
- package/src/cli/dev.test.ts +246 -114
- package/src/cli/dev.ts +153 -205
- package/src/cli/doc-staleness.test.ts +3 -6
- package/src/cli/docker-clean.test.ts +33 -1
- package/src/cli/docker-clean.ts +28 -33
- package/src/cli/docker-cli.test.ts +12 -11
- package/src/cli/docker.ts +95 -20
- package/src/cli/doctor.test.ts +40 -0
- package/src/cli/doctor.ts +142 -9
- package/src/cli/drizzle-env.test.ts +11 -13
- package/src/cli/drizzle-env.ts +18 -11
- package/src/cli/ensure-drizzle-config.ts +11 -14
- package/src/cli/hero-meta.test.ts +15 -15
- package/src/cli/hero-meta.ts +10 -9
- package/src/cli/index.ts +36 -6
- package/src/cli/load-config.images.test.ts +44 -10
- package/src/cli/load-config.source.test.ts +50 -0
- package/src/cli/load-config.ts +35 -29
- package/src/cli/meilisearch-local.ts +1 -2
- package/src/cli/mode.ts +7 -58
- package/src/cli/registry.ts +175 -19
- package/src/cli/resolve-dev-sql-env.test.ts +8 -16
- package/src/cli/resolve-dev-sql-env.ts +13 -15
- package/src/cli/safe-defaults.test.ts +29 -11
- package/src/cli/schema.ts +65 -16
- package/src/cli/test.ts +58 -0
- package/src/cli/tui/App.tsx +252 -0
- package/src/cli/tui/DevLive.tsx +116 -0
- package/src/cli/tui/components/ConfirmDialog.tsx +48 -0
- package/src/cli/tui/components/HeaderBar.tsx +67 -0
- package/src/cli/tui/components/LogStream.tsx +47 -0
- package/src/cli/tui/components/PanelCard.tsx +39 -0
- package/src/cli/tui/components/SelectRow.tsx +37 -0
- package/src/cli/tui/components/SlashPalette.tsx +172 -0
- package/src/cli/tui/components/Spinner.tsx +32 -0
- package/src/cli/tui/components/StatusBar.tsx +51 -0
- package/src/cli/tui/components/StatusDot.tsx +37 -0
- package/src/cli/tui/components/TabBar.tsx +49 -0
- package/src/cli/tui/components/Wordmark.tsx +43 -0
- package/src/cli/tui/format.ts +38 -0
- package/src/cli/tui/keys.test.ts +18 -0
- package/src/cli/tui/keys.ts +26 -0
- package/src/cli/tui/launch.test.ts +18 -0
- package/src/cli/tui/launch.ts +57 -0
- package/src/cli/tui/panels/Dashboard.tsx +201 -0
- package/src/cli/tui/panels/Database.tsx +198 -0
- package/src/cli/tui/panels/Dev.tsx +257 -0
- package/src/cli/tui/panels/Docker.tsx +357 -0
- package/src/cli/tui/panels/Navigator.test.ts +22 -0
- package/src/cli/tui/panels/Navigator.tsx +213 -0
- package/src/cli/tui/slash-catalog.test.ts +31 -0
- package/src/cli/tui/slash-catalog.ts +184 -0
- package/src/cli/tui/slash-run.ts +54 -0
- package/src/cli/tui/state/ports.ts +95 -0
- package/src/cli/tui/theme.ts +24 -0
- package/src/cli/vault-cmd.test.ts +402 -0
- package/src/cli/vault-cmd.ts +727 -69
- package/src/cli/vault-secure-input.test.ts +56 -0
- package/src/cli/vault-secure-input.ts +124 -0
- package/src/compiler/effects-infer.ts +7 -0
- package/src/compiler/extract.ts +12 -0
- package/src/compiler/fixtures/skyport/oke.config.ts +7 -5
- package/src/compiler/fixtures/skyport/src/flows/payments/index.ts +1 -1
- package/src/compiler/fixtures/skyport.expected.json +1 -1
- package/src/compiler/generate-adopt.ts +27 -1
- package/src/compiler-entry.ts +7 -0
- package/src/config/define-config.test.ts +111 -47
- package/src/config/driver-defaults.test.ts +115 -0
- package/src/config/driver-defaults.ts +156 -0
- package/src/config/index.ts +246 -131
- package/src/config/resolve-driver.test.ts +14 -19
- package/src/console/server/app.ts +4 -2
- package/src/console/server/console.test.ts +58 -1
- package/src/console/server/flows.ts +22 -2
- package/src/console/server/index.ts +3 -0
- package/src/console/server/operator-db.test.ts +55 -13
- package/src/console/server/operator-db.ts +305 -263
- package/src/console/server/serve.ts +16 -7
- package/src/console/server/state.ts +31 -9
- package/src/console/server/vault.test.ts +120 -5
- package/src/console/server/vault.ts +208 -12
- package/src/console/ui/dist/assets/{index-D-9KFce5.js → index--Y0Uaz-m.js} +2 -2
- package/src/console/ui/dist/assets/panel-vault-BkZdJPX8.js +1 -0
- package/src/console/ui/dist/assets/style-C3L349iZ.css +3 -0
- package/src/console/ui/dist/index.html +2 -2
- package/src/console/ui/shell/client.ts +16 -0
- package/src/console/ui/shell/panels/vault/VaultPanel.tsx +54 -1
- package/src/console/ui/vault/VaultA11yView.tsx +33 -1
- package/src/console/ui/vault/backend.test.ts +75 -0
- package/src/console/ui/vault/backend.ts +117 -0
- package/src/console/ui/vault/fixture.ts +21 -2
- package/src/console/ui/vault/index.ts +11 -1
- package/src/console/ui/vault/types.ts +26 -0
- package/src/docker/compose.ts +164 -61
- package/src/docker/derive.ts +106 -12
- package/src/docker/docker.test.ts +156 -110
- package/src/docker/helpers.ts +98 -0
- package/src/docker/images-config.test.ts +163 -0
- package/src/docker/index.ts +30 -5
- package/src/docker/recipes/index.ts +0 -3
- package/src/docker/recipes/llama-cpp.ts +4 -4
- package/src/docker/recipes/pgdog.ts +9 -2
- package/src/docker/resources.test.ts +71 -0
- package/src/docker/resources.ts +176 -0
- package/src/docker/stack-id.test.ts +11 -4
- package/src/docker/stack-id.ts +42 -32
- package/src/docker/stack.integration.test.ts +4 -15
- package/src/docker/types.ts +35 -3
- package/src/drivers/ai-ollama.integration.test.ts +2 -2
- package/src/drivers/conformance.test.ts +11 -12
- package/src/drivers/drizzle-dialect.test.ts +0 -4
- package/src/drivers/drizzle-dialect.ts +7 -13
- package/src/drivers/index.ts +24 -7
- package/src/drivers/journal-postgres.test.ts +3 -1
- package/src/drivers/journal-postgres.ts +4 -2
- package/src/drivers/meilisearch.ts +1 -1
- package/src/drivers/pglite.ts +28 -5
- package/src/drivers/types.ts +9 -11
- package/src/drivers/vault-aws-secrets-manager.test.ts +159 -0
- package/src/drivers/vault-aws-secrets-manager.ts +333 -0
- package/src/drivers/vault-builtin.test.ts +110 -0
- package/src/drivers/vault-builtin.ts +184 -0
- package/src/drivers/vault-driver-removal.test.ts +13 -0
- package/src/drivers/vault-managed.test.ts +95 -0
- package/src/drivers/vault-managed.ts +101 -25
- package/src/drivers/vault-types.ts +25 -5
- package/src/elements/ai/runtime.ts +1 -1
- package/src/elements/clock/chaos.test.ts +4 -1
- package/src/elements/clock/durable.ts +57 -4
- package/src/elements/clock.test.ts +13 -14
- package/src/elements/gate/constants.ts +18 -0
- package/src/elements/gate.test.ts +1 -1
- package/src/elements/gate.ts +2 -2
- package/src/elements/store/domain-ddl.test.ts +5 -12
- package/src/elements/store/emit-drizzle.ts +44 -19
- package/src/elements/store/index-boot.test.ts +15 -116
- package/src/elements/store/load-plugin-tables.ts +1 -1
- package/src/elements/store/resource-list-docs.fixture.ts +12 -6
- package/src/elements/store/resource-list-docs.test.ts +64 -44
- package/src/elements/store/resource.test.ts +17 -10
- package/src/elements/store/runtime.ts +9 -12
- package/src/elements/store/schema-decl.test.ts +16 -32
- package/src/elements/store/seed.test.ts +1 -2
- package/src/elements/store/seed.ts +7 -8
- package/src/elements/store/sql-condition.test.ts +2 -2
- package/src/elements/store/sql-session.test.ts +8 -10
- package/src/elements/store/sql-session.ts +10 -2
- package/src/elements/store.test.ts +13 -13
- package/src/elements/vault/audit.ts +233 -0
- package/src/elements/vault/boot-chain.test.ts +78 -0
- package/src/elements/vault/boot-chain.ts +43 -39
- package/src/elements/vault/builtin-adapter.test.ts +479 -0
- package/src/elements/vault/builtin-adapter.ts +1184 -0
- package/src/elements/vault/crypto.test.ts +237 -0
- package/src/elements/vault/crypto.ts +431 -0
- package/src/elements/vault/declare.ts +164 -3
- package/src/elements/vault/errors.ts +56 -0
- package/src/elements/vault/kms-unseal.test.ts +76 -0
- package/src/elements/vault/kms-unseal.ts +181 -0
- package/src/elements/vault/path.ts +90 -0
- package/src/elements/vault/resilience.test.ts +102 -0
- package/src/elements/vault/resilience.ts +107 -0
- package/src/elements/vault/runtime.ts +36 -4
- package/src/elements/vault/security-checklist.test.ts +130 -0
- package/src/elements/vault/storage.ts +448 -0
- package/src/elements/vault/types.ts +288 -0
- package/src/elements/vault/unseal.ts +150 -0
- package/src/elements/vault.test.ts +72 -4
- package/src/elements/vault.ts +91 -2
- package/src/full.ts +248 -0
- package/src/http.ts +41 -0
- package/src/i18n/interpolate-simple.ts +37 -0
- package/src/i18n/messages.ts +51 -4
- package/src/i18n-entry.ts +7 -0
- package/src/index.ts +35 -145
- package/src/journal-entry.ts +20 -0
- package/src/kernel/adopt-barrel-fresh.test.ts +25 -10
- package/src/kernel/app.ts +40 -42
- package/src/kernel/auto-registry.test.ts +2 -2
- package/src/kernel/boot-bind/ai.test.ts +5 -5
- package/src/kernel/boot-bind/ai.ts +2 -1
- package/src/kernel/boot-bind/channel.test.ts +6 -6
- package/src/kernel/boot-bind/channel.ts +5 -4
- package/src/kernel/boot-bind/clock.ts +5 -5
- package/src/kernel/boot-bind/gate.ts +6 -7
- package/src/kernel/boot-bind/honor-config.test.ts +42 -42
- package/src/kernel/boot-bind/journal.ts +5 -5
- package/src/kernel/boot-bind/signal.ts +3 -1
- package/src/kernel/boot-bind/store.test.ts +55 -37
- package/src/kernel/boot-bind/store.ts +24 -34
- package/src/kernel/boot-bind/vault.ts +19 -4
- package/src/kernel/boot.test.ts +12 -4
- package/src/kernel/boot.ts +31 -19
- package/src/kernel/budget-entry.ts +1 -1
- package/src/kernel/compensate.test.ts +288 -1
- package/src/kernel/compensate.ts +126 -0
- package/src/kernel/concurrency.test.ts +10 -9
- package/src/kernel/effects-stamping.test.ts +27 -2
- package/src/kernel/element-registries.ts +5 -3
- package/src/kernel/flow.ts +4 -2
- package/src/kernel/fx.test.ts +119 -3
- package/src/kernel/fx.ts +215 -40
- package/src/kernel/index.ts +14 -0
- package/src/kernel/journal.ts +130 -7
- package/src/kernel/pipeline.test.ts +20 -6
- package/src/kernel/redacted.test.ts +35 -0
- package/src/kernel/redacted.ts +24 -2
- package/src/kernel/router/create-default.ts +16 -0
- package/src/kernel/router/create-edge.ts +18 -0
- package/src/kernel/router/create.ts +23 -0
- package/src/kernel/router/index.ts +23 -0
- package/src/kernel/router/linear.ts +88 -0
- package/src/kernel/router/regexp.ts +188 -0
- package/src/kernel/router/smart.ts +120 -0
- package/src/kernel/router/trie.ts +108 -0
- package/src/kernel/router/types.ts +56 -0
- package/src/kernel/router.ts +18 -532
- package/src/kernel-entry.ts +43 -0
- package/src/manifest/fixtures/skyport.excerpt.json +1 -1
- package/src/manifest/fixtures/skyport.manifest.json +1 -1
- package/src/plugins/config-source.test.ts +7 -7
- package/src/release/build-lib.ts +58 -0
- package/src/release/exports.test.ts +4 -2
- package/src/release/exports.ts +30 -4
- package/src/release/measure.ts +101 -22
- package/src/runs/duckdb.ts +7 -2
- package/src/shared/optional-peer.ts +41 -0
- package/src/term.test.ts +3 -44
- package/src/test/create-test-app.ts +12 -0
- package/src/test/provisions.integration.test.ts +1 -1
- package/src/test/reset-element-registries.ts +2 -0
- package/src/upgrade/codemods.test.ts +7 -20
- package/src/upgrade/codemods.ts +93 -60
- package/site/content/docs/console/access.mdx +0 -29
- package/site/content/docs/console/ai.mdx +0 -35
- package/site/content/docs/console/architecture.mdx +0 -35
- package/site/content/docs/console/channels.mdx +0 -37
- package/site/content/docs/console/clock.mdx +0 -51
- package/site/content/docs/console/flows.mdx +0 -31
- package/site/content/docs/console/gates.mdx +0 -73
- package/site/content/docs/console/index.mdx +0 -54
- package/site/content/docs/console/manifest-diff.mdx +0 -34
- package/site/content/docs/console/meta.json +0 -24
- package/site/content/docs/console/overview.mdx +0 -40
- package/site/content/docs/console/plugins.mdx +0 -41
- package/site/content/docs/console/privacy.mdx +0 -32
- package/site/content/docs/console/runs.mdx +0 -50
- package/site/content/docs/console/signals.mdx +0 -40
- package/site/content/docs/console/store.mdx +0 -32
- package/site/content/docs/console/tenancy.mdx +0 -32
- package/site/content/docs/console/traces.mdx +0 -38
- package/site/content/docs/console/vault.mdx +0 -41
- package/site/content/docs/recipes/openbao.mdx +0 -141
- package/src/cli/ask-dev-mode.ts +0 -40
- package/src/cli/dev-mode.test.ts +0 -45
- package/src/cli/dev-mode.ts +0 -78
- package/src/cli/openbao-bootstrap.test.ts +0 -150
- package/src/cli/openbao-bootstrap.ts +0 -321
- package/src/cli/openbao-restart.integration.test.ts +0 -145
- package/src/console/ui/dist/assets/panel-vault-Za1GyJfM.js +0 -1
- package/src/console/ui/dist/assets/style-C8MxEWPd.css +0 -3
- package/src/docker/recipes/openbao.ts +0 -47
- package/src/drivers/libsql.ts +0 -179
- package/src/drivers/sqlite.ts +0 -44
- package/src/drivers/vault-openbao.test.ts +0 -97
- package/src/drivers/vault-openbao.ts +0 -143
|
@@ -31,7 +31,7 @@ sticky network id to preserve. Scale with `replicas: N`.
|
|
|
31
31
|
<Step>
|
|
32
32
|
### Share backing services
|
|
33
33
|
|
|
34
|
-
Pin
|
|
34
|
+
Pin `dev`/`prod` drivers to shared stores:
|
|
35
35
|
|
|
36
36
|
| Concern | Driver | Shared backend |
|
|
37
37
|
| ----------------------------- | ---------------------------- | ------------------------------------------------- |
|
|
@@ -59,7 +59,7 @@ Wire `readinessProbe` to `/_/ready` and `livenessProbe` to `/health`.
|
|
|
59
59
|
Bun.SQL defaults to **10** connections per process — fine for one pod.
|
|
60
60
|
Scale the Deployment and `N × pool` can exceed Postgres `max_connections`.
|
|
61
61
|
|
|
62
|
-
When both `store.sql` and `pgdog` are pinned (
|
|
62
|
+
When both `store.sql` and `pgdog` are pinned (`dev`/`prod` default in templates),
|
|
63
63
|
`DATABASE_URL` points at PgDog on port `6432` — transaction pooling, wire-protocol
|
|
64
64
|
transparent to Bun.SQL / Drizzle. Point the cluster Service at that pooler.
|
|
65
65
|
|
|
@@ -137,12 +137,12 @@ so traffic does not hit a pod mid-takeover.
|
|
|
137
137
|
|
|
138
138
|
`drivers.store.kv` must be `redis` with `REDIS_URL` set. A missing URL now
|
|
139
139
|
**fails boot** (no silent memory fallback). Declaring `memory` for local is fine;
|
|
140
|
-
|
|
140
|
+
`dev`/`prod` should stay on redis.
|
|
141
141
|
|
|
142
142
|
</Accordion>
|
|
143
143
|
<Accordion title="Files uploaded on pod A are missing on pod B">
|
|
144
144
|
|
|
145
|
-
`drivers.store.files: "fs"` is single-host. Switch
|
|
145
|
+
`drivers.store.files: "fs"` is single-host. Switch `dev`/`prod` to `s3`
|
|
146
146
|
(create-oke templates already do).
|
|
147
147
|
|
|
148
148
|
</Accordion>
|
|
@@ -132,7 +132,7 @@ Use `keyBy: "ip"` on public unauthenticated AI edges. Cost caps stay on prompt/a
|
|
|
132
132
|
|
|
133
133
|
## Secrets stay out of prompts
|
|
134
134
|
|
|
135
|
-
`Redacted` values (e.g. from `fx.vault`) stringify to `[redacted]` in provider-facing messages — the same placeholder as logs. Never cleartext to a model.
|
|
135
|
+
`Redacted` values (e.g. from `fx.vault.get`) stringify to `[redacted]` in provider-facing messages — the same placeholder as logs. Never cleartext to a model.
|
|
136
136
|
|
|
137
137
|
## Streaming
|
|
138
138
|
|
|
@@ -176,8 +176,8 @@ oke ai setup --provider ollama --yes
|
|
|
176
176
|
```
|
|
177
177
|
|
|
178
178
|
Writes `drivers.ai`, commented AI overrides in `.env.local` (so they do not
|
|
179
|
-
shadow `docker/.env.docker`), and `src/core
|
|
180
|
-
lines only for a host-managed AI endpoint.
|
|
179
|
+
shadow `docker/.env.docker`), and AI models into `src/core.ts`. Uncomment
|
|
180
|
+
`.env.local` lines only for a host-managed AI endpoint.
|
|
181
181
|
|
|
182
182
|
**Recommended** defaults to llama.cpp (lightest local footprint). Customize
|
|
183
183
|
offers llama.cpp · Ollama · vLLM · SGLang · cloud providers.
|
|
@@ -209,7 +209,7 @@ import { defineConfig } from "okengine/config";
|
|
|
209
209
|
|
|
210
210
|
export default defineConfig({
|
|
211
211
|
drivers: {
|
|
212
|
-
ai: {
|
|
212
|
+
ai: { dev: "openai-compatible", test: "mock", prod: "anthropic" },
|
|
213
213
|
},
|
|
214
214
|
images: {
|
|
215
215
|
ai: "ghcr.io/ggml-org/llama.cpp:server-b10290", // ≥ b8146; never :latest
|
|
@@ -217,10 +217,10 @@ export default defineConfig({
|
|
|
217
217
|
});
|
|
218
218
|
```
|
|
219
219
|
|
|
220
|
-
```typescript title="src/core
|
|
220
|
+
```typescript title="src/core.ts"
|
|
221
221
|
export const smart = ai.model("smart", {
|
|
222
222
|
provider: "openai-compatible",
|
|
223
|
-
model: process.env.OKE_AI_MODEL ?? "
|
|
223
|
+
model: process.env.OKE_AI_MODEL ?? "granite3.3:2b", // Docker Hub ai/ id
|
|
224
224
|
});
|
|
225
225
|
```
|
|
226
226
|
|
|
@@ -270,7 +270,7 @@ The one you declared. There is no fallback or guess — if `prod` has no AI driv
|
|
|
270
270
|
</Accordion>
|
|
271
271
|
<Accordion title="oke boot: ollama driver needs OKE_AI_URL">
|
|
272
272
|
|
|
273
|
-
Docker mode expects `OKE_AI_URL` from `docker/.env.docker` (written when `images.ai` is pinned). Keep `OKE_AI_*` in `.env.local` commented — an active `OKE_AI_URL` there wins and shadows the compose URL. Locally, the Ollama default is `http://127.0.0.1:11434`. If asks fail with `OllamaUnavailableError`, confirm the server answers at that URL and that the model is listed under `GET /api/tags` (boot pulls via `POST /api/pull` against the container — do not rely on a host `ollama pull`, which may talk to a different install). Prefer `oke ai setup` to wire driver, commented env overrides, and `src/core
|
|
273
|
+
Docker mode expects `OKE_AI_URL` from `docker/.env.docker` (written when `images.ai` is pinned). Keep `OKE_AI_*` in `.env.local` commented — an active `OKE_AI_URL` there wins and shadows the compose URL. Locally, the Ollama default is `http://127.0.0.1:11434`. If asks fail with `OllamaUnavailableError`, confirm the server answers at that URL and that the model is listed under `GET /api/tags` (boot pulls via `POST /api/pull` against the container — do not rely on a host `ollama pull`, which may talk to a different install). Prefer `oke ai setup` to wire driver, commented env overrides, and AI models in `src/core.ts` in one pass.
|
|
274
274
|
|
|
275
275
|
</Accordion>
|
|
276
276
|
<Accordion title="A prompt edit made answers worse — how do I catch that pre-merge?">
|
|
@@ -289,7 +289,6 @@ Bound it at declaration: `maxSteps` caps iterations, `budget.maxCostPerRun` caps
|
|
|
289
289
|
|
|
290
290
|
- [Flow](/docs/elements/flow) — `fx.ask` and `fx.search` inside `do`
|
|
291
291
|
- [Store](/docs/elements/store) — `store.index`, the home of embeddings
|
|
292
|
-
- [Console · AI](/docs/console/ai) — prompts, versions, cost per run
|
|
293
292
|
|
|
294
293
|
## Next
|
|
295
294
|
|
|
@@ -304,9 +303,4 @@ Bound it at declaration: `maxSteps` caps iterations, `budget.maxCostPerRun` caps
|
|
|
304
303
|
description="Eight elements overview."
|
|
305
304
|
href="/docs/get-started/introduction"
|
|
306
305
|
/>
|
|
307
|
-
<Card
|
|
308
|
-
title="Console"
|
|
309
|
-
description="Panels derived from the Manifest."
|
|
310
|
-
href="/docs/console/overview"
|
|
311
|
-
/>
|
|
312
306
|
</Cards>
|
|
@@ -54,7 +54,9 @@ do: async (input, fx) => {
|
|
|
54
54
|
<Step>
|
|
55
55
|
### Read it in development
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
Under `oke test` the `console` driver captures mail into an inbox instead of sending; under `oke
|
|
58
|
+
dev` Compose runs **Mailpit**, a real SMTP catcher with a web UI — so you see the exact rendered
|
|
59
|
+
message without ever touching a real mailbox.
|
|
58
60
|
|
|
59
61
|
</Step>
|
|
60
62
|
|
|
@@ -199,20 +201,20 @@ push drivers are passed via `BootOptions.channel.drivers` when you need them.
|
|
|
199
201
|
```typescript title="oke.config.ts"
|
|
200
202
|
drivers: {
|
|
201
203
|
channel: {
|
|
202
|
-
email: {
|
|
204
|
+
email: { dev: "smtp", test: "console", prod: "smtp" },
|
|
203
205
|
// optional — omit until you need SMS at boot
|
|
204
|
-
sms: {
|
|
206
|
+
sms: { test: "console", prod: "taqnyat" },
|
|
205
207
|
},
|
|
206
208
|
},
|
|
207
209
|
images: {
|
|
208
|
-
|
|
210
|
+
channel: { email: "axllent/mailpit:v1.22.3" },
|
|
209
211
|
},
|
|
210
212
|
```
|
|
211
213
|
|
|
212
214
|
| Driver | Medium | Behavior |
|
|
213
215
|
| -------------- | -------- | ------------------------------------------------------------------- |
|
|
214
|
-
| `console` | any | Captures into a readable inbox —
|
|
215
|
-
| `smtp` | email | Real SMTP — Mailpit
|
|
216
|
+
| `console` | any | Captures into a readable inbox — tests |
|
|
217
|
+
| `smtp` | email | Real SMTP — Mailpit under `oke dev`, your provider in prod |
|
|
216
218
|
| `resend` | email | Resend HTTP API (`RESEND_API_KEY`) |
|
|
217
219
|
| `sndr` | email | SNDR HTTP API (`SNDR_API_KEY`) |
|
|
218
220
|
| `taqnyat-mail` | email | Taqnyat Mail API (`TAQNYAT_MAIL_TOKEN` + `TAQNYAT_CAMPAIGN`) |
|
|
@@ -258,7 +260,7 @@ openWebPushChannel({
|
|
|
258
260
|
<Accordions>
|
|
259
261
|
<Accordion title="I sent an email in dev but nothing arrived">
|
|
260
262
|
|
|
261
|
-
Nothing _should_ arrive — the `console` driver captures mail instead of sending. Read the dev inbox, or run `oke dev
|
|
263
|
+
Nothing _should_ arrive — the `console` driver captures mail instead of sending. Read the dev inbox, or run `oke dev` and open Mailpit's web UI to see the rendered message.
|
|
262
264
|
|
|
263
265
|
</Accordion>
|
|
264
266
|
<Accordion title="A user says they stopped receiving messages">
|
|
@@ -326,7 +328,6 @@ Confirm a visible OS notification titled `okengine webpush interop`.
|
|
|
326
328
|
## Learn more
|
|
327
329
|
|
|
328
330
|
- [Flow](/docs/elements/flow) — `fx.send` inside `do`
|
|
329
|
-
- [Console · Channels](/docs/console/channels) — receipts, attempts, suppression
|
|
330
331
|
- [Environment Variables](/docs/reference/environment-variables) — Channel boot credentials
|
|
331
332
|
- [Configuration](/docs/reference/configuration) — `drivers.channel.*` maps
|
|
332
333
|
- [i18n](/docs/reference/i18n) — ICU / `fx.t` vs Channel `{{field}}` catalogs
|
|
@@ -341,9 +342,4 @@ Confirm a visible OS notification titled `okengine webpush interop`.
|
|
|
341
342
|
description="Eight elements overview."
|
|
342
343
|
href="/docs/get-started/introduction"
|
|
343
344
|
/>
|
|
344
|
-
<Card
|
|
345
|
-
title="Console"
|
|
346
|
-
description="Panels derived from the Manifest."
|
|
347
|
-
href="/docs/console/overview"
|
|
348
|
-
/>
|
|
349
345
|
</Cards>
|
|
@@ -124,7 +124,7 @@ reclaimed after its lease expires and continues at the next unfinished step.
|
|
|
124
124
|
|
|
125
125
|
**Leader election needs a shared store.** The default in-memory CronStore is per process. Multi-replica
|
|
126
126
|
exclusivity holds when every instance opens the same durable CronStore — `postgres` (SKIP LOCKED +
|
|
127
|
-
lease reclaim,
|
|
127
|
+
lease reclaim, `dev`/`prod` default) or `file` (shared volume, single-host).
|
|
128
128
|
|
|
129
129
|
**Catch-up example:** an hourly clock down for five hours reports `missedRuns: 5` and
|
|
130
130
|
`catchUp: "one"`, then a single tick runs the handler once.
|
|
@@ -141,16 +141,16 @@ Detection attaches `dstAmbiguity` on the cron row and the Console shows it. `oke
|
|
|
141
141
|
|
|
142
142
|
```typescript title="oke.config.ts"
|
|
143
143
|
drivers: {
|
|
144
|
-
clock: {
|
|
144
|
+
clock: { dev: "postgres", test: "frozen", prod: "postgres" },
|
|
145
145
|
},
|
|
146
146
|
```
|
|
147
147
|
|
|
148
|
-
| Driver | Behavior
|
|
149
|
-
| ---------- |
|
|
150
|
-
| `memory` | In-process CronStore + timers — single process; lost on exit
|
|
151
|
-
| `postgres` | Postgres CronStore (`oke_crons`) — multi-host leader election via SKIP LOCKED + lease reclaim
|
|
152
|
-
| `file` | On-disk CronStore (`.oke/crons.json`) — multi-process on a shared volume (
|
|
153
|
-
| `frozen` | Deterministic test clock — time advances only when the test says so
|
|
148
|
+
| Driver | Behavior |
|
|
149
|
+
| ---------- | --------------------------------------------------------------------------------------------- |
|
|
150
|
+
| `memory` | In-process CronStore + timers — single process; lost on exit |
|
|
151
|
+
| `postgres` | Postgres CronStore (`oke_crons`) — multi-host leader election via SKIP LOCKED + lease reclaim |
|
|
152
|
+
| `file` | On-disk CronStore (`.oke/crons.json`) — multi-process on a shared volume (single-host) |
|
|
153
|
+
| `frozen` | Deterministic test clock — time advances only when the test says so |
|
|
154
154
|
|
|
155
155
|
`frozen` is why the no-`Date.now()` rule pays off: tests inject time travel through `fx.clock` and every flow obeys it automatically.
|
|
156
156
|
|
|
@@ -195,7 +195,6 @@ They are not sharing one CronStore. In-memory leases are per process. Point ever
|
|
|
195
195
|
|
|
196
196
|
- [Flow](/docs/elements/flow) — `on(trigger, flow)` and the `fx` surface
|
|
197
197
|
- [fx · Runs](/docs/reference/fx#runs-observability-read) — native SLO checkers via `on(every(…))` + `fx.runs`
|
|
198
|
-
- [Console · Clock](/docs/console/clock) — health numbers, pause / edit / wake early
|
|
199
198
|
- [Signal](/docs/elements/signal) — reacting to events instead of time
|
|
200
199
|
|
|
201
200
|
## Next
|
|
@@ -207,9 +206,4 @@ They are not sharing one CronStore. In-memory leases are per process. Point ever
|
|
|
207
206
|
description="Eight elements overview."
|
|
208
207
|
href="/docs/get-started/introduction"
|
|
209
208
|
/>
|
|
210
|
-
<Card
|
|
211
|
-
title="Console"
|
|
212
|
-
description="Panels derived from the Manifest."
|
|
213
|
-
href="/docs/console/overview"
|
|
214
|
-
/>
|
|
215
209
|
</Cards>
|
|
@@ -71,15 +71,15 @@ curl -X POST localhost:6530/orders -d '{"sku":"SKU-1","qty":2}' -H 'content-type
|
|
|
71
71
|
|
|
72
72
|
## Anatomy of a Flow
|
|
73
73
|
|
|
74
|
-
| Part | Role
|
|
75
|
-
| ------------ |
|
|
76
|
-
| trigger | What starts the flow — `http`, a signal, `every`, a row change
|
|
77
|
-
| `in` | Input contract — validated before `do` runs; bad input is a 422
|
|
78
|
-
| `out` | Output contract — the return value is checked against it
|
|
79
|
-
| `errors` | Typed failures — **returned** with `fx.fail`, never thrown
|
|
80
|
-
| `retry` | Optional whole-`do` backoff on thrown errors (same journal)
|
|
81
|
-
| `do` | The work — every read, write, emit, and call goes through `fx`
|
|
82
|
-
| `compensate` | Durable only —
|
|
74
|
+
| Part | Role |
|
|
75
|
+
| ------------ | -------------------------------------------------------------------------- |
|
|
76
|
+
| trigger | What starts the flow — `http`, a signal, `every`, a row change |
|
|
77
|
+
| `in` | Input contract — validated before `do` runs; bad input is a 422 |
|
|
78
|
+
| `out` | Output contract — the return value is checked against it |
|
|
79
|
+
| `errors` | Typed failures — **returned** with `fx.fail`, never thrown |
|
|
80
|
+
| `retry` | Optional whole-`do` backoff on thrown errors (same journal) |
|
|
81
|
+
| `do` | The work — every read, write, emit, and call goes through `fx` |
|
|
82
|
+
| `compensate` | Durable only — optional hook after auto per-step `{ undo }` (same journal) |
|
|
83
83
|
|
|
84
84
|
Failures are values, not exceptions:
|
|
85
85
|
|
|
@@ -181,22 +181,22 @@ const order = await fx.call(getOrder, { id: orderId }); // from any other flow
|
|
|
181
181
|
|
|
182
182
|
Everything a flow may touch, on one object:
|
|
183
183
|
|
|
184
|
-
| Surface | Effect recorded | What it does
|
|
185
|
-
| ------------------------------------------- | --------------- |
|
|
186
|
-
| `fx.store(db).select/insert/…` | read / write | SQL, KV, files, index sessions
|
|
187
|
-
| `fx.emit(signal, payload)` | emit | Publish a signal (transactional with writes)
|
|
188
|
-
| `fx.send(template, opts)` | send | Reach a human (email · SMS · …)
|
|
189
|
-
| `fx.ask(prompt, input)` | ask | Call a versioned AI prompt
|
|
190
|
-
| `fx.run(agent, input)` | ask | Run a bounded agent
|
|
191
|
-
| `fx.call(flow, input)` | call | Invoke another flow
|
|
192
|
-
| `fx.vault(contract)`
|
|
193
|
-
| `fx.clock.now()` / `.sleep(…)` | — | Injected time / durable sleep
|
|
194
|
-
| `fx.cache.get/set` | — | Shared cache with effect-aware invalidation
|
|
195
|
-
| `fx.step(name, fn)`
|
|
196
|
-
| `fx.all` / `fx.race` / `fx.retry` | — | Structured concurrency + backoff retry
|
|
197
|
-
| `fx.signal` | — | Ambient `AbortSignal` for the current branch
|
|
198
|
-
| `fx.id()` · `fx.log` · `fx.t` · `fx.locale` | — | UUIDs, redacting logger, ICU i18n
|
|
199
|
-
| `fx.auth` · `fx.operator` · `fx.tenant` | — | Who is calling (user / operator / tenant)
|
|
184
|
+
| Surface | Effect recorded | What it does |
|
|
185
|
+
| ------------------------------------------- | --------------- | -------------------------------------------------- |
|
|
186
|
+
| `fx.store(db).select/insert/…` | read / write | SQL, KV, files, index sessions |
|
|
187
|
+
| `fx.emit(signal, payload)` | emit | Publish a signal (transactional with writes) |
|
|
188
|
+
| `fx.send(template, opts)` | send | Reach a human (email · SMS · …) |
|
|
189
|
+
| `fx.ask(prompt, input)` | ask | Call a versioned AI prompt |
|
|
190
|
+
| `fx.run(agent, input)` | ask | Run a bounded agent |
|
|
191
|
+
| `fx.call(flow, input)` | call | Invoke another flow |
|
|
192
|
+
| `fx.vault.get(contract)` | secret | Read a secret (`Redacted`; logs masked) |
|
|
193
|
+
| `fx.clock.now()` / `.sleep(…)` | — | Injected time / durable sleep |
|
|
194
|
+
| `fx.cache.get/set` | — | Shared cache with effect-aware invalidation |
|
|
195
|
+
| `fx.step(name, fn, { undo? })` | — | Named durable step — optional LIFO undo on failure |
|
|
196
|
+
| `fx.all` / `fx.race` / `fx.retry` | — | Structured concurrency + backoff retry |
|
|
197
|
+
| `fx.signal` | — | Ambient `AbortSignal` for the current branch |
|
|
198
|
+
| `fx.id()` · `fx.log` · `fx.t` · `fx.locale` | — | UUIDs, redacting logger, ICU i18n |
|
|
199
|
+
| `fx.auth` · `fx.operator` · `fx.tenant` | — | Who is calling (user / operator / tenant) |
|
|
200
200
|
|
|
201
201
|
<Callout title="Why this strictness pays off">
|
|
202
202
|
Effects are inferred from `fx` usage, so the Manifest knows exactly which flows read `orders` or
|
|
@@ -216,28 +216,27 @@ export const chargeOrder = flow("payments.chargeOrder", {
|
|
|
216
216
|
in: OrderRef,
|
|
217
217
|
out: z.boolean(),
|
|
218
218
|
do: async ({ orderId }, fx) => {
|
|
219
|
-
const
|
|
220
|
-
|
|
221
|
-
);
|
|
219
|
+
const key = await fx.vault.get(stripeKey);
|
|
220
|
+
const intent = await fx.step("create-intent", () => stripe(key.reveal()).create(orderId));
|
|
222
221
|
|
|
223
222
|
await fx.clock.sleep("verify-window", "2m"); // journals wakeAt in a durable flow
|
|
224
223
|
|
|
225
|
-
return fx.step("confirm", () => stripe(
|
|
224
|
+
return fx.step("confirm", () => stripe(key.reveal()).confirm(intent));
|
|
226
225
|
},
|
|
227
226
|
});
|
|
228
227
|
```
|
|
229
228
|
|
|
230
229
|
**Consequence:** completed steps replay from the journal — on resume, `create-intent` does not re-run, so the card is not charged twice.
|
|
231
230
|
|
|
232
|
-
**Crash recovery needs a shared journal.** Set `drivers.journal: "postgres"` (the
|
|
231
|
+
**Crash recovery needs a shared journal.** Set `drivers.journal: "postgres"` (the `dev`/`prod` template default) and every run persists in `oke_journal_runs` under a per-run lease: boot scans for orphaned `running` / `compensating` / due `sleeping` runs and resumes them, and the lease lets exactly one instance execute a run at a time. The default `memory` journal is per process — replay holds for that process only.
|
|
233
232
|
|
|
234
233
|
Replay is **at-least-once** for a step whose body never persisted (crash mid-step, lease overrun): that step re-runs on reclaim, so keep step bodies short or internally idempotent. A client transport retry starts a _new_ run with a fresh `runId` — request-level idempotency is an application concern, not the journal's.
|
|
235
234
|
|
|
236
235
|
For flaky sub-steps, wrap the work in `fx.retry` **inside** `fx.step` so a completed charge is never retried on resume. Coarse whole-body retry is also available as `flow(name, { retry: { retries, delay, backoff, jitter } })` and reuses the same journal session.
|
|
237
236
|
|
|
238
|
-
After a **terminal** failure (`fx.fail` or exhausted retries / uncaught throw),
|
|
239
|
-
|
|
240
|
-
|
|
237
|
+
After a **terminal** failure (`fx.fail` or exhausted retries / uncaught throw), declare
|
|
238
|
+
undo next to each step. Only **persisted** steps undo (LIFO) — if `charge` throws before
|
|
239
|
+
it journals, `undo:charge` does not run:
|
|
241
240
|
|
|
242
241
|
```typescript
|
|
243
242
|
export const chargeOrder = flow("payments.chargeOrder", {
|
|
@@ -245,23 +244,23 @@ export const chargeOrder = flow("payments.chargeOrder", {
|
|
|
245
244
|
in: OrderRef,
|
|
246
245
|
out: z.boolean(),
|
|
247
246
|
do: async ({ orderId }, fx) => {
|
|
248
|
-
await fx.step("reserve", () => reserve(orderId)
|
|
249
|
-
|
|
247
|
+
await fx.step("reserve", () => reserve(orderId), {
|
|
248
|
+
undo: () => release(orderId),
|
|
249
|
+
});
|
|
250
|
+
await fx.step("charge", () => charge(orderId), {
|
|
251
|
+
undo: (intent) => refund(intent), // journaled value — resume-safe
|
|
252
|
+
});
|
|
250
253
|
return true;
|
|
251
254
|
},
|
|
252
|
-
compensate: async ({ input, completedSteps }, fx) => {
|
|
253
|
-
if (completedSteps.includes("charge")) {
|
|
254
|
-
await fx.step("undo:charge", () => refund(input.orderId));
|
|
255
|
-
}
|
|
256
|
-
if (completedSteps.includes("reserve")) {
|
|
257
|
-
await fx.step("undo:reserve", () => release(input.orderId));
|
|
258
|
-
}
|
|
259
|
-
},
|
|
260
255
|
});
|
|
261
256
|
```
|
|
262
257
|
|
|
263
|
-
|
|
264
|
-
`
|
|
258
|
+
The runtime journals undos as `undo:<name>` under status `compensating`, then commits
|
|
259
|
+
`failed`. Orphan reclaim resumes that phase without re-entering forward work.
|
|
260
|
+
`flow.compensate` remains an optional hook after auto undos for cross-cutting cleanup.
|
|
261
|
+
`JournalSuspend` (sleep) is park, not failure — undo does not run.
|
|
262
|
+
Use `fx.using` for same-attempt cleanup; `{ undo }` for durable external effects — not both
|
|
263
|
+
for the same release.
|
|
265
264
|
|
|
266
265
|
## Composition is just calls
|
|
267
266
|
|
|
@@ -298,9 +297,9 @@ Use `fx.all` (or `fx.race`) with thunks. The first rejection aborts siblings thr
|
|
|
298
297
|
Put `fx.retry` **inside** `fx.step`, not around it. Completed steps replay from the journal and never re-run. `flow(name, { retry })` is for coarse whole-body retries on the same session.
|
|
299
298
|
|
|
300
299
|
</Accordion>
|
|
301
|
-
<Accordion title="When does compensate run?">
|
|
300
|
+
<Accordion title="When does undo / compensate run?">
|
|
302
301
|
|
|
303
|
-
Only after terminal failure for that journal attempt — not on sleep, not mid-retry, not on success.
|
|
302
|
+
Only after terminal failure for that journal attempt — not on sleep, not mid-retry, not on success. Per-step `{ undo }` runs first (LIFO, only for persisted steps), then optional `flow.compensate`. The run stays `compensating` until undos finish so a crash mid-undo resumes the undo phase, not forward `do`. Undo bodies must be idempotent. Irreversible effects (`send` / `ask`) need developer-declared undos or an explicit no-op.
|
|
304
303
|
|
|
305
304
|
</Accordion>
|
|
306
305
|
<Accordion title="How do I share logic between flows — a private function?">
|
|
@@ -320,8 +319,6 @@ Only that run fails — the schedule keeps firing and the process does not exit.
|
|
|
320
319
|
- [fx](/docs/reference/fx) — full `fx` surface, including ICU `fx.t` / `fx.locale`
|
|
321
320
|
- [Signal](/docs/elements/signal) — delivery physics (`once` · `broadcast` · `live`)
|
|
322
321
|
- [Clock](/docs/elements/clock) — schedules and durable sleep
|
|
323
|
-
- [Console · Flows](/docs/console/flows) — the Manifest-derived panel
|
|
324
|
-
- [Runs](/docs/console/runs) — how a flow execution is observed
|
|
325
322
|
|
|
326
323
|
## Next
|
|
327
324
|
|
|
@@ -332,9 +329,4 @@ Only that run fails — the schedule keeps firing and the process does not exit.
|
|
|
332
329
|
description="Eight elements overview."
|
|
333
330
|
href="/docs/get-started/introduction"
|
|
334
331
|
/>
|
|
335
|
-
<Card
|
|
336
|
-
title="Console"
|
|
337
|
-
description="Panels derived from the Manifest."
|
|
338
|
-
href="/docs/console/overview"
|
|
339
|
-
/>
|
|
340
332
|
</Cards>
|
|
@@ -48,7 +48,7 @@ import { member, canBook, fair } from "./gates";
|
|
|
48
48
|
|
|
49
49
|
export const app = oke({
|
|
50
50
|
name: "shop",
|
|
51
|
-
env: "
|
|
51
|
+
env: "dev",
|
|
52
52
|
gate: { policies: [member, canBook, fair] },
|
|
53
53
|
});
|
|
54
54
|
```
|
|
@@ -166,7 +166,7 @@ Fine-grained authorization (`gate.scope`, roles) stays opt-in — attach it only
|
|
|
166
166
|
|
|
167
167
|
All five run as atomic Lua on the kv driver — correct under concurrency, identical on the memory
|
|
168
168
|
driver in tests. Boot opens a dedicated `oke:gates` namespace on **`drivers.store.kv`**
|
|
169
|
-
(`memory`
|
|
169
|
+
(`memory` in test · `redis` in `dev`/`prod`) so multi-instance rate limits share counters.
|
|
170
170
|
|
|
171
171
|
## Auth posture at boot
|
|
172
172
|
|
|
@@ -183,7 +183,7 @@ on(http.post("/bookings").gate(member, canBook), flow("bookings.create", {/* …
|
|
|
183
183
|
posture but does **not** authenticate.
|
|
184
184
|
|
|
185
185
|
`gate: { unguardedHttp: "allow" }` skips the audit **only** when `env === "test"`.
|
|
186
|
-
In `
|
|
186
|
+
In `dev` / `prod` migrate with per-trigger `gate.public`.
|
|
187
187
|
|
|
188
188
|
## Built-in auth (`gate.auth`)
|
|
189
189
|
|
|
@@ -196,7 +196,7 @@ import { member, canBook } from "./gates";
|
|
|
196
196
|
|
|
197
197
|
export const app = oke({
|
|
198
198
|
name: "shop",
|
|
199
|
-
env: "
|
|
199
|
+
env: "dev",
|
|
200
200
|
gate: {
|
|
201
201
|
auth: {
|
|
202
202
|
emailAndPassword: { enabled: true },
|
|
@@ -248,7 +248,8 @@ gate: {
|
|
|
248
248
|
}
|
|
249
249
|
```
|
|
250
250
|
|
|
251
|
-
Customize tables, then run `oke schema generate` (
|
|
251
|
+
Customize tables, then run `oke schema generate` (writes `.oke/schema/oke.ts`;
|
|
252
|
+
supports `--check` in CI). Extra sign-in
|
|
252
253
|
shapes: [Plugins](/docs/plugins) (username, magic link, OTP, TOTP, passkeys). Call auth from
|
|
253
254
|
[createClient](/docs/reference/client) — one client, helpers in `okengine/client/auth`.
|
|
254
255
|
|
|
@@ -308,7 +309,6 @@ Keying an authenticated endpoint by IP punishes shared NAT.
|
|
|
308
309
|
- [fx](/docs/reference/fx) — `fx.auth`, `fx.operator`, `fx.principal`
|
|
309
310
|
- [Client](/docs/reference/client) — Bearer `createClient` + `okengine/client/auth`
|
|
310
311
|
- [Plugins](/docs/plugins) — username, magic link, OTP, TOTP, passkeys
|
|
311
|
-
- [Console · Gates](/docs/console/gates) — decision audit and posture
|
|
312
312
|
- [Vault](/docs/elements/vault) — credentials your policies protect
|
|
313
313
|
|
|
314
314
|
## Next
|
|
@@ -316,9 +316,4 @@ Keying an authenticated endpoint by IP punishes shared NAT.
|
|
|
316
316
|
<Cards>
|
|
317
317
|
<Card title="Vault" description="Continue to Vault." href="/docs/elements/vault" />
|
|
318
318
|
<Card title="Plugins" description="Sign-in method plugins under /auth." href="/docs/plugins" />
|
|
319
|
-
<Card
|
|
320
|
-
title="Console"
|
|
321
|
-
description="Panels derived from the Manifest."
|
|
322
|
-
href="/docs/console/overview"
|
|
323
|
-
/>
|
|
324
319
|
</Cards>
|
|
@@ -238,13 +238,13 @@ When a signal disappears from code, reconciliation marks its config row `orphane
|
|
|
238
238
|
|
|
239
239
|
```typescript title="oke.config.ts"
|
|
240
240
|
drivers: {
|
|
241
|
-
signal: {
|
|
241
|
+
signal: { dev: "redis", test: "memory", prod: "redis" },
|
|
242
242
|
},
|
|
243
243
|
```
|
|
244
244
|
|
|
245
245
|
| Driver | Runs as | Boot today |
|
|
246
246
|
| ---------- | ------------------------------------ | --------------------------------------------------------------------------- |
|
|
247
|
-
| `memory` | in-process |
|
|
247
|
+
| `memory` | in-process | Tests — zero infrastructure |
|
|
248
248
|
| `redis` | Redis / Valkey / Dragonfly image pin | Boot-bound — **emit relay** via Streams / pub/sub; consume is process-local |
|
|
249
249
|
| `postgres` | Postgres | Driver exists; boot **fails loud** until a LISTEN/NOTIFY SQL client binds |
|
|
250
250
|
| `nats` | NATS | Driver exists; boot **fails loud** until a production NATS client binds |
|
|
@@ -291,7 +291,6 @@ At-least-once: crash-after-claim reclaims when the lease expires, and a handler
|
|
|
291
291
|
## Learn more
|
|
292
292
|
|
|
293
293
|
- [Flow](/docs/elements/flow) — `on(trigger, flow)` and `fx.emit`
|
|
294
|
-
- [Console · Signals](/docs/console/signals) — topology, delivery stats, DLQ replay
|
|
295
294
|
- [Clock](/docs/elements/clock) — scheduled and delayed work
|
|
296
295
|
|
|
297
296
|
## Next
|
|
@@ -303,9 +302,4 @@ At-least-once: crash-after-claim reclaims when the lease expires, and a handler
|
|
|
303
302
|
description="Eight elements overview."
|
|
304
303
|
href="/docs/get-started/introduction"
|
|
305
304
|
/>
|
|
306
|
-
<Card
|
|
307
|
-
title="Console"
|
|
308
|
-
description="Panels derived from the Manifest."
|
|
309
|
-
href="/docs/console/overview"
|
|
310
|
-
/>
|
|
311
305
|
</Cards>
|