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
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Config"
|
|
3
|
+
description: "vault.config cleartext settings, Console visibility, and vault.env helpers for plain process configuration."
|
|
4
|
+
icon: "SlidersHorizontal"
|
|
5
|
+
source: "docs/spec/unified-theory.md"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Config contracts (`vault.config`) hold **non-secret** operational settings — public origins,
|
|
9
|
+
feature flags, workspace labels. They resolve through the same boot chain as secrets, but Console
|
|
10
|
+
may show them in the clear.
|
|
11
|
+
|
|
12
|
+
For developers who need validated settings without fingerprinting — declare `vault.config`, read
|
|
13
|
+
with `fx.vault.get`, keep credentials on `vault.secret` instead.
|
|
14
|
+
|
|
15
|
+
<Callout title="The one rule">
|
|
16
|
+
Use `vault.config` only when cleartext in Console and logs is acceptable. API keys, tokens, and
|
|
17
|
+
connection passwords belong on `vault.secret`.
|
|
18
|
+
</Callout>
|
|
19
|
+
|
|
20
|
+
## Smallest Example
|
|
21
|
+
|
|
22
|
+
<Steps>
|
|
23
|
+
|
|
24
|
+
<Step>
|
|
25
|
+
### Declare a config contract
|
|
26
|
+
|
|
27
|
+
```typescript title="src/core/vault.ts"
|
|
28
|
+
import { vault } from "okengine";
|
|
29
|
+
import { z } from "zod";
|
|
30
|
+
|
|
31
|
+
export const publicAppUrl = vault.config("PUBLIC_APP_URL", {
|
|
32
|
+
description: "Public origin for email links and redirects",
|
|
33
|
+
schema: z.string().url(),
|
|
34
|
+
// Dev-only fallback — never used in prod boot
|
|
35
|
+
dev: "http://localhost:6530",
|
|
36
|
+
});
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
</Step>
|
|
40
|
+
|
|
41
|
+
<Step>
|
|
42
|
+
### Read it in a Flow
|
|
43
|
+
|
|
44
|
+
```typescript title="src/flows/invites/create.ts"
|
|
45
|
+
import { on, flow, http } from "okengine";
|
|
46
|
+
import { z } from "zod";
|
|
47
|
+
import { member } from "@/core/gate";
|
|
48
|
+
import { publicAppUrl, noteCreatedMail } from "@/core";
|
|
49
|
+
|
|
50
|
+
export const create = on(
|
|
51
|
+
http.post().gate(member),
|
|
52
|
+
flow({
|
|
53
|
+
in: z.object({ email: z.string().email() }),
|
|
54
|
+
do: async ({ email }, fx) => {
|
|
55
|
+
const origin = await fx.vault.get(publicAppUrl);
|
|
56
|
+
await fx.send(noteCreatedMail, {
|
|
57
|
+
to: email,
|
|
58
|
+
// Config may be revealed for URL building — still prefer holding Redacted
|
|
59
|
+
// until the send boundary when mixed with secrets
|
|
60
|
+
link: `${origin.reveal()}/accept`,
|
|
61
|
+
});
|
|
62
|
+
return fx.json.empty();
|
|
63
|
+
},
|
|
64
|
+
}),
|
|
65
|
+
);
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
</Step>
|
|
69
|
+
|
|
70
|
+
<Step>
|
|
71
|
+
### See it in Console
|
|
72
|
+
|
|
73
|
+
The Config band shows `PUBLIC_APP_URL` in the clear after boot (secrets stay fingerprinted). Update
|
|
74
|
+
via Console write or `oke vault set PUBLIC_APP_URL`.
|
|
75
|
+
|
|
76
|
+
</Step>
|
|
77
|
+
|
|
78
|
+
</Steps>
|
|
79
|
+
|
|
80
|
+
## Progressive Patterns
|
|
81
|
+
|
|
82
|
+
From a public URL to flags, registration, and the env escape hatch:
|
|
83
|
+
|
|
84
|
+
<Tabs items={["URL", "Flag", "Register", "Env"]}>
|
|
85
|
+
|
|
86
|
+
<Tab value="URL">
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
export const publicApiUrl = vault.config("PUBLIC_API_URL", {
|
|
90
|
+
description: "Browser-facing API origin",
|
|
91
|
+
schema: z.string().url(),
|
|
92
|
+
dev: "http://localhost:6530",
|
|
93
|
+
});
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
</Tab>
|
|
97
|
+
|
|
98
|
+
<Tab value="Flag">
|
|
99
|
+
|
|
100
|
+
Feature toggles as config (cleartext by design):
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
103
|
+
export const newDashboard = vault.config("FEATURE_NEW_DASHBOARD", {
|
|
104
|
+
description: "Enable the redesigned dashboard",
|
|
105
|
+
schema: z.enum(["on", "off"]),
|
|
106
|
+
dev: "off",
|
|
107
|
+
});
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
</Tab>
|
|
111
|
+
|
|
112
|
+
<Tab value="Register">
|
|
113
|
+
|
|
114
|
+
`vault.config` is **not** auto-drained into `oke({ secrets })` (unlike `vault.secret`). Pass
|
|
115
|
+
handles explicitly when the Manifest must list them:
|
|
116
|
+
|
|
117
|
+
```typescript title="src/app.ts"
|
|
118
|
+
import { oke } from "okengine";
|
|
119
|
+
import { publicAppUrl, publicApiUrl } from "@/core/vault";
|
|
120
|
+
|
|
121
|
+
export const app = oke({
|
|
122
|
+
name: "notes",
|
|
123
|
+
env: "dev",
|
|
124
|
+
secrets: [publicAppUrl, publicApiUrl],
|
|
125
|
+
});
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
</Tab>
|
|
129
|
+
|
|
130
|
+
<Tab value="Env">
|
|
131
|
+
|
|
132
|
+
Plain process configuration — no contract, no fingerprint, no driver bag:
|
|
133
|
+
|
|
134
|
+
```typescript
|
|
135
|
+
import { vault } from "okengine";
|
|
136
|
+
|
|
137
|
+
const port = vault.env.int("PORT", 6530);
|
|
138
|
+
const verbose = vault.env.bool("VERBOSE", false);
|
|
139
|
+
const bag = vault.env.json<{ region: string }>("DEPLOY_META");
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
`vault.env.required("NAME")` registers the name so a missing value joins `VaultBootError` gaps
|
|
143
|
+
alongside secret contracts.
|
|
144
|
+
|
|
145
|
+
</Tab>
|
|
146
|
+
|
|
147
|
+
</Tabs>
|
|
148
|
+
|
|
149
|
+
## Options Reference
|
|
150
|
+
|
|
151
|
+
Same option bag as secrets (`VaultSecretOptions`), with different defaults:
|
|
152
|
+
|
|
153
|
+
| Option | Type | Default | Meaning |
|
|
154
|
+
| ------------- | --------- | ------- | --------------------------------------------------------- |
|
|
155
|
+
| `description` | `string` | — | Boot-gap and Console label |
|
|
156
|
+
| `rotate` | `string` | omit | Optional cadence hint (rarely used for config) |
|
|
157
|
+
| `schema` | Schema | — | Declared shape for docs / tooling |
|
|
158
|
+
| `dev` | `string` | — | Dev-only fallback |
|
|
159
|
+
| `sensitive` | `boolean` | `false` | Set `true` only if this config must never show in Console |
|
|
160
|
+
|
|
161
|
+
Empty name throws `TypeError: vault.config: name is required`.
|
|
162
|
+
|
|
163
|
+
**Consequence:** `sensitive: true` on a config behaves like a secret for Console cleartext —
|
|
164
|
+
prefer `vault.secret` when that is the intent.
|
|
165
|
+
|
|
166
|
+
## `vault.env` helpers
|
|
167
|
+
|
|
168
|
+
Synchronous reads of process environment. Empty strings count as unset.
|
|
169
|
+
|
|
170
|
+
| Helper | Returns | Throws when |
|
|
171
|
+
| ---------------------------- | --------------------- | -------------------------------------------- |
|
|
172
|
+
| `vault.env(name)` | `string \| undefined` | — |
|
|
173
|
+
| `vault.env.required(name)` | `string` | unset — also registers for boot gaps |
|
|
174
|
+
| `vault.env.int(name, def?)` | `number` | unset without default, or not an integer |
|
|
175
|
+
| `vault.env.bool(name, def?)` | `boolean` | unset without default, or not boolean-shaped |
|
|
176
|
+
| `vault.env.json(name)` | `T \| undefined` | value present but not valid JSON |
|
|
177
|
+
|
|
178
|
+
Boolean true: `1` · `true` · `yes` · `on`. False: `0` · `false` · `no` · `off` (case-insensitive).
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
// TypeError: vault.env.required: CI_TOKEN is not set
|
|
182
|
+
vault.env.required("CI_TOKEN");
|
|
183
|
+
|
|
184
|
+
// TypeError: vault.env.int: PORT is not an integer
|
|
185
|
+
process.env.PORT = "abc";
|
|
186
|
+
vault.env.int("PORT");
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
Reach for `vault.secret` / `vault.config` when the value must participate in the resolution chain,
|
|
190
|
+
fingerprinting, or Console Vault.
|
|
191
|
+
|
|
192
|
+
## Cleartext vs fingerprint
|
|
193
|
+
|
|
194
|
+
| Kind | Console list | `runtime.cleartext(name)` | `runtime.fingerprint(name)` |
|
|
195
|
+
| -------- | ---------------- | ------------------------- | --------------------------- |
|
|
196
|
+
| `secret` | Fingerprint only | always `undefined` | defined when loaded |
|
|
197
|
+
| `config` | Shown in clear | loaded value | always `undefined` |
|
|
198
|
+
|
|
199
|
+
Both still return `Redacted` from `fx.vault.get` — reveal when you need a plain string.
|
|
200
|
+
|
|
201
|
+
## Troubleshooting
|
|
202
|
+
|
|
203
|
+
<Accordions>
|
|
204
|
+
|
|
205
|
+
<Accordion title="Config missing from Manifest / Console">
|
|
206
|
+
`vault.config` is not auto-registered. Pass `oke({ secrets: [publicAppUrl] })` or ensure the
|
|
207
|
+
declaring module is adopted the same way your app wires secrets.
|
|
208
|
+
</Accordion>
|
|
209
|
+
|
|
210
|
+
<Accordion title="VaultBootError includes a PUBLIC_* name">
|
|
211
|
+
Same resolution chain as secrets — set the value or provide `dev:` for local boot. Config gaps
|
|
212
|
+
fail boot just like secrets when registered.
|
|
213
|
+
</Accordion>
|
|
214
|
+
|
|
215
|
+
<Accordion title="TypeError: vault.env.required: NAME is not set">
|
|
216
|
+
Call site threw immediately. For boot-time collection, keep the `required` call so the name is
|
|
217
|
+
registered; boot then lists it with other gaps.
|
|
218
|
+
</Accordion>
|
|
219
|
+
|
|
220
|
+
<Accordion title="TypeError: vault.env.bool / int / json">
|
|
221
|
+
Value is present but malformed. Use the documented boolean tokens, an integer string, or valid
|
|
222
|
+
JSON — or supply a default for `int` / `bool` when unset is allowed.
|
|
223
|
+
</Accordion>
|
|
224
|
+
|
|
225
|
+
<Accordion title="Secret shown in the Config band">
|
|
226
|
+
You declared `vault.config` (or `sensitive: false`). Move credentials to `vault.secret`.
|
|
227
|
+
</Accordion>
|
|
228
|
+
|
|
229
|
+
</Accordions>
|
|
230
|
+
|
|
231
|
+
## Learn more
|
|
232
|
+
|
|
233
|
+
- [Secrets](/docs/elements/vault/secrets) — fingerprinted contracts and Redacted
|
|
234
|
+
- [Vault overview](/docs/elements/vault) — resolution order and drivers
|
|
235
|
+
- [Environment variables](/docs/reference/environment-variables) — `OKE_*` knobs
|
|
236
|
+
- [fx](/docs/reference/fx) — `fx.vault.get` on any contract
|
|
237
|
+
|
|
238
|
+
## Next
|
|
239
|
+
|
|
240
|
+
<Cards>
|
|
241
|
+
<Card
|
|
242
|
+
title="Key Rotation"
|
|
243
|
+
description="Rotate versions and the builtin master key."
|
|
244
|
+
href="/docs/elements/vault/rotation"
|
|
245
|
+
/>
|
|
246
|
+
<Card
|
|
247
|
+
title="Secrets"
|
|
248
|
+
description="Fingerprinted vault.secret contracts."
|
|
249
|
+
href="/docs/elements/vault/secrets"
|
|
250
|
+
/>
|
|
251
|
+
<Card
|
|
252
|
+
title="Vault Overview"
|
|
253
|
+
description="Resolution chain and fx.vault surface."
|
|
254
|
+
href="/docs/elements/vault"
|
|
255
|
+
/>
|
|
256
|
+
</Cards>
|
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Overview"
|
|
3
|
+
description: "Protected knowledge — declare secret and config contracts, resolve values at boot, read Redacted credentials through fx.vault."
|
|
4
|
+
icon: "KeyRound"
|
|
5
|
+
source: "docs/spec/unified-theory.md"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Vault is how your backend **holds secrets and configuration safely**. Declare a contract
|
|
9
|
+
(`vault.secret`, `vault.config`), resolve the value through the boot chain, and read it inside
|
|
10
|
+
Flows as `Redacted` — never as a plain string in logs or responses.
|
|
11
|
+
|
|
12
|
+
For developers wiring Stripe keys, SMTP URLs, and feature flags on okengine — contracts first,
|
|
13
|
+
values only at the provider edge.
|
|
14
|
+
|
|
15
|
+
<Callout title="The one rule">
|
|
16
|
+
**Contracts, never values.** Application code declares `vault.secret("STRIPE_KEY")` (or
|
|
17
|
+
`vault.config`). Cleartext crosses only at `.reveal()` on the credential boundary — never in
|
|
18
|
+
`console.log`, JSON, or the HTTP envelope.
|
|
19
|
+
</Callout>
|
|
20
|
+
|
|
21
|
+
<VaultResolution />
|
|
22
|
+
|
|
23
|
+
## Smallest Example
|
|
24
|
+
|
|
25
|
+
<Steps>
|
|
26
|
+
|
|
27
|
+
<Step>
|
|
28
|
+
### Declare a secret contract
|
|
29
|
+
|
|
30
|
+
```typescript title="src/core/vault.ts"
|
|
31
|
+
import { vault } from "okengine";
|
|
32
|
+
|
|
33
|
+
export const webhookSecret = vault.secret("APP_WEBHOOK_SECRET", {
|
|
34
|
+
description: "HMAC secret for outbound note webhooks",
|
|
35
|
+
// Dev-only fallback — never used in prod boot
|
|
36
|
+
dev: "dev-webhook-secret-change-me",
|
|
37
|
+
});
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
</Step>
|
|
41
|
+
|
|
42
|
+
<Step>
|
|
43
|
+
### Read it in a Flow
|
|
44
|
+
|
|
45
|
+
```typescript title="src/flows/notes/create.ts"
|
|
46
|
+
import { on, flow, http } from "okengine";
|
|
47
|
+
import { webhookSecret } from "@/core/vault";
|
|
48
|
+
import { notesMutate } from "@/core/gate";
|
|
49
|
+
|
|
50
|
+
export const create = on(
|
|
51
|
+
http.post().gate(notesMutate),
|
|
52
|
+
flow({
|
|
53
|
+
do: async (input, fx) => {
|
|
54
|
+
// Touches the contract → effects.secrets; reveal only at an SDK edge
|
|
55
|
+
await fx.vault.get(webhookSecret);
|
|
56
|
+
return fx.json.create({ id: fx.id(), title: input.title });
|
|
57
|
+
},
|
|
58
|
+
}),
|
|
59
|
+
);
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
The compiler stamps `secrets: ["APP_WEBHOOK_SECRET"]` on the Flow’s effects.
|
|
63
|
+
|
|
64
|
+
</Step>
|
|
65
|
+
|
|
66
|
+
<Step>
|
|
67
|
+
### Boot and call
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
# Missing value → VaultBootError lists every gap at once
|
|
71
|
+
oke vault set APP_WEBHOOK_SECRET
|
|
72
|
+
|
|
73
|
+
curl -X POST http://localhost:6530/notes \
|
|
74
|
+
-H "accept: application/json" \
|
|
75
|
+
-H "content-type: application/json" \
|
|
76
|
+
-d '{"title":"hello"}'
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
`fx.log` / `String(key)` / `JSON.stringify(key)` all show `[redacted]` — never the HMAC material.
|
|
80
|
+
|
|
81
|
+
</Step>
|
|
82
|
+
|
|
83
|
+
</Steps>
|
|
84
|
+
|
|
85
|
+
## Progressive Patterns
|
|
86
|
+
|
|
87
|
+
From a fingerprinted secret to cleartext config, plain env helpers, and Docker-local fallbacks:
|
|
88
|
+
|
|
89
|
+
<Tabs items={["Secret", "Config", "Env", "fromDocker"]}>
|
|
90
|
+
|
|
91
|
+
<Tab value="Secret">
|
|
92
|
+
|
|
93
|
+
Fingerprinted contract — Console shows a fingerprint, never the value:
|
|
94
|
+
|
|
95
|
+
```typescript title="src/core/vault.ts"
|
|
96
|
+
import { vault } from "okengine";
|
|
97
|
+
import { z } from "zod";
|
|
98
|
+
|
|
99
|
+
export const stripeKey = vault.secret("STRIPE_KEY", {
|
|
100
|
+
description: "Stripe secret API key",
|
|
101
|
+
schema: z.string().startsWith("sk_"),
|
|
102
|
+
rotate: "90d",
|
|
103
|
+
// Optional local fallback when drivers.vault.dev allows it
|
|
104
|
+
dev: "sk_test_local",
|
|
105
|
+
});
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
`vault("STRIPE_KEY", opts)` is the same as `vault.secret`.
|
|
109
|
+
|
|
110
|
+
</Tab>
|
|
111
|
+
|
|
112
|
+
<Tab value="Config">
|
|
113
|
+
|
|
114
|
+
Non-sensitive settings — Console may show them in the clear:
|
|
115
|
+
|
|
116
|
+
```typescript title="src/core/vault.ts"
|
|
117
|
+
import { vault } from "okengine";
|
|
118
|
+
import { z } from "zod";
|
|
119
|
+
|
|
120
|
+
export const publicAppUrl = vault.config("PUBLIC_APP_URL", {
|
|
121
|
+
description: "Public origin for email links",
|
|
122
|
+
schema: z.string().url(),
|
|
123
|
+
dev: "http://localhost:6530",
|
|
124
|
+
});
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
**Consequence:** `vault.config` is **not** auto-registered into `oke({ secrets })` — pass the
|
|
128
|
+
handle (or import the declaring module before `oke()` when you need it on the Manifest).
|
|
129
|
+
|
|
130
|
+
</Tab>
|
|
131
|
+
|
|
132
|
+
<Tab value="Env">
|
|
133
|
+
|
|
134
|
+
Plain process configuration — no boot chain, no redaction. Prefer contracts when the value must
|
|
135
|
+
fingerprint or fail boot:
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
import { vault } from "okengine";
|
|
139
|
+
|
|
140
|
+
const port = vault.env.int("PORT", 6530);
|
|
141
|
+
const debug = vault.env.bool("DEBUG", false);
|
|
142
|
+
const raw = vault.env("FEATURE_FLAG"); // string | undefined
|
|
143
|
+
const must = vault.env.required("CI_TOKEN"); // joins VaultBootError gaps when missing
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
</Tab>
|
|
147
|
+
|
|
148
|
+
<Tab value="fromDocker">
|
|
149
|
+
|
|
150
|
+
Local fallback that reads the URL the image recipe built for a role — kernel never sees the
|
|
151
|
+
underlying env-var names:
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
export const databaseUrl = vault.secret("DATABASE_URL", {
|
|
155
|
+
description: "Primary SQL URL",
|
|
156
|
+
dev: vault.fromDocker("store.sql"),
|
|
157
|
+
});
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Resolves from `OKE_STORE_SQL_URL` (and peers) when `allowDevFallbacks` is on.
|
|
161
|
+
|
|
162
|
+
</Tab>
|
|
163
|
+
|
|
164
|
+
</Tabs>
|
|
165
|
+
|
|
166
|
+
## Declaration Reference
|
|
167
|
+
|
|
168
|
+
| Declaration | Signature | Purpose |
|
|
169
|
+
| ------------------ | ------------------------------------------------------ | ------------------------------------- |
|
|
170
|
+
| `vault.secret` | `vault.secret(name, options?)` | Fingerprinted secret contract |
|
|
171
|
+
| `vault` | `vault(name, options?)` | Alias for `vault.secret` |
|
|
172
|
+
| `vault.config` | `vault.config(name, options?)` | Cleartext config contract |
|
|
173
|
+
| `vault.fromDocker` | `vault.fromDocker(role)` | Dev fallback marker for an image role |
|
|
174
|
+
| `vault.env` | `vault.env` / `.required` / `.int` / `.bool` / `.json` | Sync process env — no contract |
|
|
175
|
+
|
|
176
|
+
| Option | Type | Default | Meaning |
|
|
177
|
+
| ------------- | --------- | ------------------------------ | ---------------------------------------------------------------------- |
|
|
178
|
+
| `description` | `string` | — | Shown in boot-gap listings and Console |
|
|
179
|
+
| `rotate` | `string` | omit ≈ `"never"` | Cadence hint (`"90d"`) or `"never"` — Console posture, not auto-rotate |
|
|
180
|
+
| `schema` | Schema | — | Declared shape (Zod / Standard Schema) for docs and tooling |
|
|
181
|
+
| `dev` | `string` | — | Dev-only fallback; never used in prod boot |
|
|
182
|
+
| `sensitive` | `boolean` | `true` secret · `false` config | Whether cleartext must never leave the runtime |
|
|
183
|
+
| `perTenant` | `boolean` | `true` when tenancy on | Resolve `{tenantId}/{name}` at request time; not boot-gap fatal |
|
|
184
|
+
|
|
185
|
+
## Resolution Chain
|
|
186
|
+
|
|
187
|
+
<Callout title="Detailed section">
|
|
188
|
+
If you only need “declare and `fx.vault.get`”, the Smallest Example is enough. This section is how
|
|
189
|
+
boot finds a value — first hit wins.
|
|
190
|
+
</Callout>
|
|
191
|
+
|
|
192
|
+
Order (Console labels match these source ids):
|
|
193
|
+
|
|
194
|
+
1. **driver** — built-in encrypted store, managed bag, or `env` / `memory` driver
|
|
195
|
+
2. **process.env** — real environment (CI, hosting)
|
|
196
|
+
3. **`.env.local`** — local overrides (gitignored)
|
|
197
|
+
4. **dev-fallback** — `dev:` on the contract (dev boot only)
|
|
198
|
+
|
|
199
|
+
Miss every layer → `VaultBootError` listing **all** gaps in one pass (including
|
|
200
|
+
`vault.env.required` names):
|
|
201
|
+
|
|
202
|
+
```text
|
|
203
|
+
vault boot failed — 2 missing secret(s):
|
|
204
|
+
- STRIPE_KEY: Payments gateway key
|
|
205
|
+
- DATABASE_URL: Primary SQL URL
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
**Consequence:** fix every listed name before traffic — boot does not take a half-configured app.
|
|
209
|
+
|
|
210
|
+
See [Secrets](/docs/elements/vault/secrets) for contracts and [Config](/docs/elements/vault/config)
|
|
211
|
+
for cleartext + `vault.env`.
|
|
212
|
+
|
|
213
|
+
## Redacted until reveal
|
|
214
|
+
|
|
215
|
+
<VaultRedacted />
|
|
216
|
+
|
|
217
|
+
`fx.vault.get(contract)` returns `Promise<Redacted<string>>`. Printing, logging, and JSON all
|
|
218
|
+
yield `[redacted]`. Call `.reveal()` only at the Stripe / SMTP / SDK edge.
|
|
219
|
+
|
|
220
|
+
Loaded secret substrings are also scrubbed from `fx.log` even when you pass cleartext by mistake
|
|
221
|
+
(mask token `[redacted:secret]`).
|
|
222
|
+
|
|
223
|
+
## `fx.vault` surface
|
|
224
|
+
|
|
225
|
+
| Method | Needs backend | Meaning |
|
|
226
|
+
| ------------------------- | ------------- | ------------------------------------------- |
|
|
227
|
+
| `get(contract)` | No | `Redacted<string>` — every app has this |
|
|
228
|
+
| `set(path, value, opts?)` | Yes (`vault`) | New version; optional `ttlMs` / `metadata` |
|
|
229
|
+
| `rotate(path, value)` | Yes (`vault`) | New version under a fresh data key |
|
|
230
|
+
| `delete(path)` | Yes (`vault`) | Crypto-shred; returns whether anything went |
|
|
231
|
+
| `list(prefix?)` | Yes (`vault`) | Paths only — never values |
|
|
232
|
+
| `status()` | Yes (`vault`) | `{ sealed, initialized, backend }` |
|
|
233
|
+
|
|
234
|
+
Without a bound encrypted backend, mutations throw:
|
|
235
|
+
|
|
236
|
+
```text
|
|
237
|
+
fx.vault.set needs a bound Vault backend — configure the vault element (drivers.vault = "vault") …
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
Dry-run refuses writes rather than mutate a live secret (`DryRunWriteIsolationError`).
|
|
241
|
+
|
|
242
|
+
## Per-environment drivers
|
|
243
|
+
|
|
244
|
+
Defaults from `DRIVER_DEFAULTS.vault` — pin overrides in `oke.config.ts`:
|
|
245
|
+
|
|
246
|
+
```typescript title="oke.config.ts"
|
|
247
|
+
import { defineConfig } from "okengine/config";
|
|
248
|
+
|
|
249
|
+
export default defineConfig({
|
|
250
|
+
drivers: {
|
|
251
|
+
// Default vault.dev is "env"; Docker-first starters pin built-in:
|
|
252
|
+
vault: {
|
|
253
|
+
dev: "vault",
|
|
254
|
+
// test: "memory" (default)
|
|
255
|
+
// prod: "vault" (default)
|
|
256
|
+
},
|
|
257
|
+
},
|
|
258
|
+
});
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
| Driver | Runs as | Best for |
|
|
262
|
+
| --------- | -------------------------------- | -------------------------------------------- |
|
|
263
|
+
| `env` | Process / dotenv bag | Simple local / CI without SQL vault tables |
|
|
264
|
+
| `vault` | Built-in AES-256-GCM in Postgres | Docker-first apps; `oke vault init` / unseal |
|
|
265
|
+
| `memory` | In-process map | Tests |
|
|
266
|
+
| `managed` | Remote provider bag | AWS / Azure / GCP / Doppler / 1Password |
|
|
267
|
+
|
|
268
|
+
create-oke Notes starters pin `vault.dev: "vault"` and declare stack + app contracts in
|
|
269
|
+
`src/vault.ts` (`vault.secret` / `vault.config`). Console Vault lists those contracts —
|
|
270
|
+
values still resolve from `.env.local`, process env, `oke vault set`, or `dev:` /
|
|
271
|
+
`vault.fromDocker` fallbacks. Pass `oke({ secrets: NOTES_VAULT })` so configs resolve
|
|
272
|
+
(only `vault.secret` auto-registers).
|
|
273
|
+
|
|
274
|
+
Managed provider ids: `aws-secrets-manager` · `azure-key-vault` · `gcp-secret-manager` ·
|
|
275
|
+
`doppler` · `1password`. Env knobs: [Environment variables](/docs/reference/environment-variables).
|
|
276
|
+
|
|
277
|
+
## The Capabilities of Vault
|
|
278
|
+
|
|
279
|
+
<Cards>
|
|
280
|
+
<Card
|
|
281
|
+
title="Secrets"
|
|
282
|
+
description="Fingerprinted vault.secret contracts, Redacted reads, boot gaps."
|
|
283
|
+
href="/docs/elements/vault/secrets"
|
|
284
|
+
/>
|
|
285
|
+
<Card
|
|
286
|
+
title="Config"
|
|
287
|
+
description="vault.config cleartext settings and vault.env helpers."
|
|
288
|
+
href="/docs/elements/vault/config"
|
|
289
|
+
/>
|
|
290
|
+
<Card
|
|
291
|
+
title="Key Rotation"
|
|
292
|
+
description="Version rotate, master-key rewrap, seal / unseal, CLI."
|
|
293
|
+
href="/docs/elements/vault/rotation"
|
|
294
|
+
/>
|
|
295
|
+
</Cards>
|
|
296
|
+
|
|
297
|
+
## Troubleshooting
|
|
298
|
+
|
|
299
|
+
<Accordions>
|
|
300
|
+
|
|
301
|
+
<Accordion title="VaultBootError — N missing secret(s)">
|
|
302
|
+
Cause: `vault boot failed — N missing secret(s):` with every gap listed. On a TTY, `oke dev`
|
|
303
|
+
prompts each into `.env.local`; otherwise use `oke vault set` / env / managed, or a `dev:`
|
|
304
|
+
fallback. `vault.env.required` joins the same list.
|
|
305
|
+
</Accordion>
|
|
306
|
+
|
|
307
|
+
<Accordion title='vault: secret "…" is not loaded'>
|
|
308
|
+
`fx.vault.get` ran after boot without that name in the merged bag. Declare the contract, ensure a
|
|
309
|
+
resolution layer supplies it, and import the declaring module before `oke()`.
|
|
310
|
+
</Accordion>
|
|
311
|
+
|
|
312
|
+
<Accordion title="fx.vault.set / rotate needs a bound Vault backend">
|
|
313
|
+
Mutations require `drivers.vault = "vault"` (encrypted-at-rest adapter). `get` works on `env` /
|
|
314
|
+
`memory` / `managed` bags; writes need the builtin backend.
|
|
315
|
+
</Accordion>
|
|
316
|
+
|
|
317
|
+
<Accordion title="Logs still show a secret substring">
|
|
318
|
+
Prefer holding `Redacted` until `.reveal()` at the edge. Revealed cleartext is scrubbed from
|
|
319
|
+
`fx.log` when the value is registered — but third-party loggers bypass Vault redaction.
|
|
320
|
+
</Accordion>
|
|
321
|
+
|
|
322
|
+
<Accordion title="VaultSealed / cannot rotate while sealed">
|
|
323
|
+
Export `OKE_VAULT_MASTER_KEY` or run `oke vault unseal`. See [Key
|
|
324
|
+
Rotation](/docs/elements/vault/rotation).
|
|
325
|
+
</Accordion>
|
|
326
|
+
|
|
327
|
+
</Accordions>
|
|
328
|
+
|
|
329
|
+
## Learn more
|
|
330
|
+
|
|
331
|
+
- [Secrets](/docs/elements/vault/secrets) — options, Redacted, effects, tenancy paths
|
|
332
|
+
- [Config](/docs/elements/vault/config) — cleartext contracts and `vault.env`
|
|
333
|
+
- [Key Rotation](/docs/elements/vault/rotation) — `oke vault rotate` / `rotate-master`
|
|
334
|
+
- [fx](/docs/reference/fx) — `fx.vault.get` · `set` · `rotate` · `delete` · `list` · `status`
|
|
335
|
+
- [Errors](/docs/reference/errors) — `VaultBootError` · `VaultError` · `VaultSealed`
|
|
336
|
+
- [Environment variables](/docs/reference/environment-variables) — `OKE_VAULT_*`
|
|
337
|
+
|
|
338
|
+
## Next
|
|
339
|
+
|
|
340
|
+
<Cards>
|
|
341
|
+
<Card
|
|
342
|
+
title="Secrets"
|
|
343
|
+
description="Declare fingerprinted contracts and read Redacted values."
|
|
344
|
+
href="/docs/elements/vault/secrets"
|
|
345
|
+
/>
|
|
346
|
+
<Card
|
|
347
|
+
title="Channel Element"
|
|
348
|
+
description="Send email, SMS, and other human reach through templates."
|
|
349
|
+
href="/docs/elements/channel"
|
|
350
|
+
/>
|
|
351
|
+
<Card
|
|
352
|
+
title="Gate Element"
|
|
353
|
+
description="Attach policies and rates before do runs."
|
|
354
|
+
href="/docs/elements/gate"
|
|
355
|
+
/>
|
|
356
|
+
</Cards>
|