okengine 0.2.6 → 0.3.2
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 +33 -30
- package/README.md +74 -340
- package/{spec/manifest.v1.schema.json → manifest.v1.schema.json} +40 -9
- package/package.json +47 -44
- package/site/content/docs/ai/llms-txt.mdx +54 -0
- package/site/content/docs/ai/mcp.mdx +123 -0
- package/site/content/docs/ai/meta.json +5 -0
- package/site/content/docs/ai/skills.mdx +53 -0
- package/site/content/docs/console/access.mdx +29 -0
- package/site/content/docs/console/ai.mdx +35 -0
- package/site/content/docs/console/architecture.mdx +35 -0
- package/site/content/docs/console/channels.mdx +37 -0
- package/site/content/docs/console/clock.mdx +31 -0
- package/site/content/docs/console/flows.mdx +31 -0
- package/site/content/docs/console/gates.mdx +35 -0
- package/site/content/docs/console/manifest-diff.mdx +34 -0
- package/site/content/docs/console/meta.json +23 -0
- package/site/content/docs/console/overview.mdx +40 -0
- package/site/content/docs/console/plugins.mdx +41 -0
- package/site/content/docs/console/privacy.mdx +32 -0
- package/site/content/docs/console/runs.mdx +40 -0
- package/site/content/docs/console/signals.mdx +31 -0
- package/site/content/docs/console/store.mdx +32 -0
- package/site/content/docs/console/tenancy.mdx +32 -0
- package/site/content/docs/console/traces.mdx +34 -0
- package/site/content/docs/console/vault.mdx +37 -0
- package/site/content/docs/elements/ai.mdx +180 -0
- package/site/content/docs/elements/channel.mdx +167 -0
- package/site/content/docs/elements/clock.mdx +182 -0
- package/site/content/docs/elements/flow.mdx +288 -0
- package/site/content/docs/elements/gate.mdx +171 -0
- package/site/content/docs/elements/meta.json +5 -0
- package/site/content/docs/elements/signal.mdx +171 -0
- package/site/content/docs/elements/store.mdx +320 -0
- package/site/content/docs/elements/vault.mdx +263 -0
- package/site/content/docs/get-started/basic-usage.mdx +124 -0
- package/site/content/docs/get-started/comparison.mdx +65 -0
- package/site/content/docs/get-started/installation.mdx +113 -0
- package/site/content/docs/get-started/introduction.mdx +123 -0
- package/site/content/docs/get-started/meta.json +5 -0
- package/site/content/docs/index.mdx +63 -0
- package/site/content/docs/meta.json +5 -0
- package/site/content/docs/plugins/compression.mdx +60 -0
- package/site/content/docs/plugins/cors.mdx +92 -0
- package/site/content/docs/plugins/csrf.mdx +96 -0
- package/site/content/docs/plugins/ip-allowlist.mdx +92 -0
- package/site/content/docs/plugins/maintenance-mode.mdx +101 -0
- package/site/content/docs/plugins/meta.json +15 -0
- package/site/content/docs/plugins/security-headers.mdx +136 -0
- package/site/content/docs/reference/cli.md +101 -0
- package/site/content/docs/reference/configuration.mdx +159 -0
- package/site/content/docs/reference/environment-variables.mdx +87 -0
- package/site/content/docs/reference/errors.mdx +80 -0
- package/site/content/docs/reference/fx.mdx +117 -0
- package/site/content/docs/reference/meta.json +5 -0
- package/site/content/docs/reference/plugins.mdx +249 -0
- package/site/content/docs/reference/security.md +63 -0
- package/src/auth/api-keys.ts +2 -5
- package/src/auth/attenuation.ts +2 -6
- package/src/auth/auth.test.ts +56 -31
- package/src/auth/invoke-as.ts +1 -3
- package/src/auth/operator.ts +8 -26
- package/src/auth/planes.ts +2 -7
- package/src/auth/plugin.ts +4 -7
- package/src/auth/roles.ts +1 -5
- package/src/auth/sessions.ts +10 -39
- package/src/cli/args.ts +1 -5
- package/src/cli/ask-dev-mode.ts +40 -0
- package/src/cli/build.ts +1 -2
- package/src/cli/client-add.test.ts +8 -15
- package/src/cli/client-add.ts +5 -14
- package/src/cli/completion.test.ts +1 -5
- package/src/cli/completion.ts +4 -17
- package/src/cli/db-auto-push.test.ts +64 -0
- package/src/cli/db-auto-push.ts +72 -0
- package/src/cli/db.test.ts +189 -0
- package/src/cli/db.ts +456 -0
- package/src/cli/dev-app-runner.ts +2 -8
- package/src/cli/dev-db-push.test.ts +193 -0
- package/src/cli/dev-mode.test.ts +45 -0
- package/src/cli/dev-mode.ts +78 -0
- package/src/cli/dev-schema-sync.test.ts +66 -0
- package/src/cli/dev-schema-sync.ts +139 -0
- package/src/cli/dev.test.ts +264 -15
- package/src/cli/dev.ts +355 -139
- package/src/cli/doc-staleness.test.ts +69 -0
- package/src/cli/docker-cli.test.ts +27 -8
- package/src/cli/docker.ts +11 -3
- package/src/cli/doctor-diff.test.ts +1 -5
- package/src/cli/doctor-diff.ts +17 -46
- package/src/cli/doctor-pii.ts +2 -7
- package/src/cli/doctor.test.ts +26 -4
- package/src/cli/doctor.ts +35 -11
- package/src/cli/drizzle-env.test.ts +67 -0
- package/src/cli/drizzle-env.ts +78 -0
- package/src/cli/ensure-drizzle-config.ts +50 -0
- package/src/cli/eval.ts +4 -14
- package/src/cli/gates-list.ts +1 -4
- package/src/cli/hero-meta.test.ts +17 -19
- package/src/cli/hero-meta.ts +20 -30
- package/src/cli/images.ts +3 -8
- package/src/cli/index.ts +11 -2
- package/src/cli/load-config.images.test.ts +14 -14
- package/src/cli/load-config.ts +47 -47
- package/src/cli/mcp-from-console.ts +1 -4
- package/src/cli/mode.ts +65 -0
- package/src/cli/openbao-bootstrap.test.ts +147 -0
- package/src/cli/openbao-bootstrap.ts +280 -0
- package/src/cli/openbao-restart.integration.test.ts +136 -0
- package/src/cli/ports.test.ts +7 -14
- package/src/cli/ports.ts +7 -5
- package/src/cli/privacy-erase.ts +1 -3
- package/src/cli/registry.ts +75 -25
- package/src/cli/resolve-dev-sql-env.test.ts +48 -0
- package/src/cli/resolve-dev-sql-env.ts +42 -0
- package/src/cli/schema.ts +3 -10
- package/src/cli/stack.ts +8 -10
- package/src/cli/start.ts +4 -15
- package/src/cli/upgrade.ts +1 -4
- package/src/cli/vault-cmd.ts +63 -0
- package/src/client/budget-entry.ts +1 -6
- package/src/client/create.test.ts +6 -12
- package/src/client/create.ts +2 -8
- package/src/client/errors.ts +1 -4
- package/src/client/index.ts +1 -6
- package/src/client/notes-contract.test.ts +4 -13
- package/src/client/transport.ts +9 -30
- package/src/client/types.ts +15 -30
- package/src/compiler/aot.test.ts +2 -9
- package/src/compiler/aot.ts +1 -4
- package/src/compiler/differential.test.ts +3 -11
- package/src/compiler/dynamic.ts +1 -4
- package/src/compiler/effects-infer.ts +8 -34
- package/src/compiler/emit.ts +1 -3
- package/src/compiler/extract.test.ts +136 -30
- package/src/compiler/extract.ts +485 -157
- package/src/compiler/fixtures/skyport/oke.config.ts +3 -3
- package/src/compiler/fixtures/skyport/src/flows/bookings/index.ts +7 -3
- package/src/compiler/fixtures/skyport/src/flows/payments/index.ts +1 -3
- package/src/compiler/fixtures/skyport/src/flows/support/index.ts +4 -1
- package/src/compiler/fixtures/skyport.expected.json +24 -83
- package/src/compiler/fixtures/triggers/five-triggers.ts +1 -2
- package/src/compiler/http-parse.ts +2 -9
- package/src/compiler/index.ts +1 -5
- package/src/compiler/response.ts +16 -7
- package/src/compiler/sucrose.ts +11 -31
- package/src/config/define-config.test.ts +55 -34
- package/src/config/index.ts +177 -46
- package/src/config/resolve-driver.test.ts +28 -17
- package/src/console/budget.test.ts +1 -4
- package/src/console/index.ts +1 -4
- package/src/console/server/access.test.ts +15 -43
- package/src/console/server/access.ts +19 -49
- package/src/console/server/ai.test.ts +3 -11
- package/src/console/server/ai.ts +23 -46
- package/src/console/server/app.ts +16 -45
- package/src/console/server/auth-rate.test.ts +4 -12
- package/src/console/server/bind.ts +1 -5
- package/src/console/server/channels.test.ts +2 -6
- package/src/console/server/channels.ts +10 -35
- package/src/console/server/claim.ts +2 -8
- package/src/console/server/clock.test.ts +2 -6
- package/src/console/server/clock.ts +8 -26
- package/src/console/server/console.test.ts +1 -3
- package/src/console/server/diff.test.ts +5 -17
- package/src/console/server/diff.ts +10 -31
- package/src/console/server/dry-run.audit.test.ts +2 -8
- package/src/console/server/flows.ts +64 -233
- package/src/console/server/gates.test.ts +14 -50
- package/src/console/server/gates.ts +13 -48
- package/src/console/server/index.ts +2 -9
- package/src/console/server/live.ts +3 -12
- package/src/console/server/operator-db.test.ts +4 -15
- package/src/console/server/operator-db.ts +13 -32
- package/src/console/server/plugin.ts +50 -53
- package/src/console/server/plugins.test.ts +2 -6
- package/src/console/server/plugins.ts +17 -56
- package/src/console/server/runs-pii.ts +2 -7
- package/src/console/server/security.gate.test.ts +18 -40
- package/src/console/server/serve.ts +10 -25
- package/src/console/server/signals.test.ts +1 -3
- package/src/console/server/signals.ts +17 -40
- package/src/console/server/state.ts +21 -59
- package/src/console/server/store.test.ts +20 -22
- package/src/console/server/store.ts +31 -76
- package/src/console/server/vault.test.ts +12 -29
- package/src/console/server/vault.ts +44 -66
- package/src/console/ui/access/AccessA11yView.tsx +6 -21
- package/src/console/ui/access/a11y.test.tsx +3 -12
- package/src/console/ui/access/acknowledgement.test.ts +1 -4
- package/src/console/ui/access/acknowledgement.ts +1 -3
- package/src/console/ui/access/blast-radius.ts +1 -3
- package/src/console/ui/access/confirmation.test.ts +1 -5
- package/src/console/ui/access/confirmation.ts +1 -4
- package/src/console/ui/access/fixture.ts +1 -5
- package/src/console/ui/access/grantable.test.ts +1 -3
- package/src/console/ui/access/grantable.ts +2 -7
- package/src/console/ui/access/index.ts +2 -9
- package/src/console/ui/access/provenance.test.ts +1 -3
- package/src/console/ui/access/provenance.ts +2 -6
- package/src/console/ui/access/search.test.ts +1 -5
- package/src/console/ui/access/search.ts +2 -6
- package/src/console/ui/ai/AiA11yView.tsx +6 -17
- package/src/console/ui/ai/a11y.test.tsx +2 -5
- package/src/console/ui/ai/fixture.ts +2 -7
- package/src/console/ui/ai/format.ts +1 -3
- package/src/console/ui/ai/group.test.ts +1 -3
- package/src/console/ui/ai/group.ts +4 -12
- package/src/console/ui/ai/index.ts +2 -9
- package/src/console/ui/ai/promotion.test.ts +2 -7
- package/src/console/ui/ai/promotion.ts +4 -13
- package/src/console/ui/ai/search.test.ts +2 -11
- package/src/console/ui/ai/search.ts +3 -13
- package/src/console/ui/ai/types.ts +1 -8
- package/src/console/ui/architecture/ArchitectureA11yView.tsx +8 -29
- package/src/console/ui/architecture/a11y.test.tsx +1 -2
- package/src/console/ui/architecture/declared.ts +1 -5
- package/src/console/ui/architecture/index.ts +7 -35
- package/src/console/ui/architecture/layout.ts +1 -3
- package/src/console/ui/architecture/pathologies.ts +10 -19
- package/src/console/ui/architecture/search.ts +6 -15
- package/src/console/ui/architecture/traffic.ts +4 -14
- package/src/console/ui/architecture/types.ts +2 -10
- package/src/console/ui/architecture/view.test.ts +7 -19
- package/src/console/ui/architecture/view.ts +9 -36
- package/src/console/ui/channels/ChannelsA11yView.tsx +4 -13
- package/src/console/ui/channels/a11y.test.tsx +1 -2
- package/src/console/ui/channels/confirmation.test.ts +1 -4
- package/src/console/ui/channels/confirmation.ts +1 -4
- package/src/console/ui/channels/findings.ts +1 -5
- package/src/console/ui/channels/index.ts +2 -8
- package/src/console/ui/channels/locale.test.ts +1 -3
- package/src/console/ui/channels/locale.ts +2 -8
- package/src/console/ui/channels/search.ts +4 -13
- package/src/console/ui/channels/taxonomy.ts +1 -3
- package/src/console/ui/clock/ClockA11yView.tsx +9 -26
- package/src/console/ui/clock/a11y.test.tsx +2 -5
- package/src/console/ui/clock/confirmation.test.ts +1 -3
- package/src/console/ui/clock/confirmation.ts +1 -4
- package/src/console/ui/clock/findings.ts +1 -4
- package/src/console/ui/clock/health.ts +2 -7
- package/src/console/ui/clock/index.ts +2 -10
- package/src/console/ui/clock/search.test.ts +1 -3
- package/src/console/ui/clock/search.ts +2 -6
- package/src/console/ui/clock/timeline.test.ts +1 -3
- package/src/console/ui/clock/waiting-on.test.ts +1 -5
- package/src/console/ui/clock/waiting-on.ts +2 -7
- package/src/console/ui/diff/DiffA11yView.tsx +8 -17
- package/src/console/ui/diff/a11y.test.tsx +2 -5
- package/src/console/ui/diff/group.test.ts +3 -13
- package/src/console/ui/diff/group.ts +2 -8
- package/src/console/ui/diff/index.ts +2 -8
- package/src/console/ui/diff/search.test.ts +1 -5
- package/src/console/ui/diff/search.ts +4 -16
- package/src/console/ui/diff/summary.ts +1 -2
- package/src/console/ui/dist/assets/{index-Dy4jht9P.js → index-BWo8R7NR.js} +2 -2
- package/src/console/ui/dist/assets/{panel-access-Dd37LU2c.js → panel-access-C0J2D-a2.js} +1 -1
- package/src/console/ui/dist/assets/{panel-ai-CC7LR6-J.js → panel-ai-D_m6WQI8.js} +1 -1
- package/src/console/ui/dist/assets/{panel-architecture-B5b3iKCz.js → panel-architecture-CKnXFyUx.js} +1 -1
- package/src/console/ui/dist/assets/{panel-channels-CeNjTKXp.js → panel-channels-BOmQ-onL.js} +1 -1
- package/src/console/ui/dist/assets/{panel-clock-DgFTLoHV.js → panel-clock-giAq0Ccv.js} +1 -1
- package/src/console/ui/dist/assets/{panel-diff-DxehccqB.js → panel-diff-cdonmH8c.js} +1 -1
- package/src/console/ui/dist/assets/{panel-flows-BtrVn-Eg.js → panel-flows-DlCU5zjA.js} +2 -2
- package/src/console/ui/dist/assets/{panel-gates-Z9MKRGdH.js → panel-gates-XclZxWD5.js} +1 -1
- package/src/console/ui/dist/assets/{panel-overview-Dt_AeXgd.js → panel-overview-BznEOTnb.js} +1 -1
- package/src/console/ui/dist/assets/{panel-plugins-DWd0TowH.js → panel-plugins-CcGM1g64.js} +1 -1
- package/src/console/ui/dist/assets/{panel-runs-DGstFHeq.js → panel-runs-CGWNHLR4.js} +1 -1
- package/src/console/ui/dist/assets/{panel-signals-DzEa2Fnt.js → panel-signals-CNywkdak.js} +1 -1
- package/src/console/ui/dist/assets/{panel-store-BJkbNgxx.js → panel-store-KmTbFHMH.js} +1 -1
- package/src/console/ui/dist/assets/{panel-traces-BaRVO3gM.js → panel-traces-DBLx2ilD.js} +1 -1
- package/src/console/ui/dist/assets/panel-vault-CEnFc0dk.js +1 -0
- package/src/console/ui/dist/index.html +1 -1
- package/src/console/ui/flows/FlowsA11yView.tsx +7 -22
- package/src/console/ui/flows/a11y.test.tsx +2 -8
- package/src/console/ui/flows/buffer.test.ts +3 -11
- package/src/console/ui/flows/buffer.ts +4 -11
- package/src/console/ui/flows/confirmation.ts +1 -3
- package/src/console/ui/flows/contract.test.ts +3 -7
- package/src/console/ui/flows/contract.ts +12 -36
- package/src/console/ui/flows/graph.test.ts +3 -11
- package/src/console/ui/flows/graph.ts +5 -15
- package/src/console/ui/flows/index.ts +1 -6
- package/src/console/ui/flows/save-as-test.ts +1 -3
- package/src/console/ui/flows/search.ts +8 -25
- package/src/console/ui/flows/tiers.ts +2 -9
- package/src/console/ui/gates/GatesA11yView.tsx +4 -13
- package/src/console/ui/gates/a11y.test.tsx +2 -5
- package/src/console/ui/gates/audit.ts +1 -3
- package/src/console/ui/gates/denial.test.ts +1 -3
- package/src/console/ui/gates/denial.ts +4 -12
- package/src/console/ui/gates/findings.ts +1 -3
- package/src/console/ui/gates/group.test.ts +3 -3
- package/src/console/ui/gates/group.ts +3 -11
- package/src/console/ui/gates/index.ts +2 -10
- package/src/console/ui/gates/search.ts +3 -10
- package/src/console/ui/overview/OverviewA11yView.tsx +9 -27
- package/src/console/ui/overview/a11y.test.tsx +1 -2
- package/src/console/ui/overview/busiest.ts +1 -3
- package/src/console/ui/overview/compose.ts +1 -13
- package/src/console/ui/overview/cost.ts +34 -38
- package/src/console/ui/overview/fixture.ts +21 -26
- package/src/console/ui/overview/golden.ts +4 -14
- package/src/console/ui/overview/index.ts +2 -9
- package/src/console/ui/overview/rank.test.ts +3 -10
- package/src/console/ui/overview/rank.ts +2 -7
- package/src/console/ui/overview/slo.test.ts +5 -9
- package/src/console/ui/overview/slo.ts +6 -23
- package/src/console/ui/overview/verdict.ts +3 -10
- package/src/console/ui/plugins/PluginsA11yView.tsx +8 -18
- package/src/console/ui/plugins/a11y.test.tsx +1 -2
- package/src/console/ui/plugins/fixture.ts +2 -4
- package/src/console/ui/plugins/group.test.ts +1 -3
- package/src/console/ui/plugins/group.ts +1 -6
- package/src/console/ui/plugins/index.ts +3 -13
- package/src/console/ui/plugins/search.ts +7 -19
- package/src/console/ui/runs/RunsA11yView.tsx +5 -20
- package/src/console/ui/runs/a11y.test.tsx +2 -5
- package/src/console/ui/runs/explain.ts +2 -6
- package/src/console/ui/runs/group.ts +3 -12
- package/src/console/ui/runs/histogram.test.ts +2 -11
- package/src/console/ui/runs/histogram.ts +1 -4
- package/src/console/ui/runs/index.ts +4 -18
- package/src/console/ui/runs/project.ts +2 -6
- package/src/console/ui/runs/query.test.ts +1 -3
- package/src/console/ui/runs/query.ts +12 -35
- package/src/console/ui/runs/search.ts +5 -19
- package/src/console/ui/runs/trace-link.test.ts +2 -6
- package/src/console/ui/runs/trace-link.ts +4 -16
- package/src/console/ui/runs/types.ts +1 -3
- package/src/console/ui/shell/App.tsx +2 -10
- package/src/console/ui/shell/client.ts +22 -115
- package/src/console/ui/shell/components/ui.tsx +1 -4
- package/src/console/ui/shell/layout/Shell.tsx +2 -4
- package/src/console/ui/shell/main.tsx +31 -96
- package/src/console/ui/shell/panels/access/AccessPanel.tsx +34 -98
- package/src/console/ui/shell/panels/ai/AiPanel.tsx +35 -106
- package/src/console/ui/shell/panels/architecture/ArchitecturePanel.tsx +18 -66
- package/src/console/ui/shell/panels/channels/ChannelsPanel.tsx +20 -57
- package/src/console/ui/shell/panels/clock/ClockPanel.tsx +22 -54
- package/src/console/ui/shell/panels/diff/DiffPanel.tsx +20 -61
- package/src/console/ui/shell/panels/flows/ContractEditor.tsx +6 -23
- package/src/console/ui/shell/panels/flows/FlowDrawer.tsx +13 -28
- package/src/console/ui/shell/panels/flows/FlowsPanel.tsx +9 -29
- package/src/console/ui/shell/panels/gates/GatesPanel.tsx +24 -80
- package/src/console/ui/shell/panels/overview/OverviewPanel.tsx +20 -58
- package/src/console/ui/shell/panels/plugins/PluginsPanel.tsx +16 -41
- package/src/console/ui/shell/panels/runs/RunsPanel.tsx +31 -99
- package/src/console/ui/shell/panels/signals/SignalsPanel.tsx +38 -101
- package/src/console/ui/shell/panels/store/StorePanel.tsx +27 -66
- package/src/console/ui/shell/panels/traces/TracesPanel.tsx +28 -89
- package/src/console/ui/shell/panels/vault/VaultPanel.tsx +22 -53
- package/src/console/ui/shell/setup/Wizard.tsx +3 -5
- package/src/console/ui/shell/styles.css +1 -2
- package/src/console/ui/signals/SignalsA11yView.tsx +9 -33
- package/src/console/ui/signals/a11y.test.tsx +2 -5
- package/src/console/ui/signals/confirmation.test.ts +1 -5
- package/src/console/ui/signals/confirmation.ts +2 -6
- package/src/console/ui/signals/dry-run.ts +1 -3
- package/src/console/ui/signals/durable.ts +1 -3
- package/src/console/ui/signals/findings.ts +1 -3
- package/src/console/ui/signals/group.test.ts +2 -8
- package/src/console/ui/signals/group.ts +2 -10
- package/src/console/ui/signals/index.ts +1 -4
- package/src/console/ui/signals/monitor.ts +2 -7
- package/src/console/ui/signals/schema-form.test.ts +3 -14
- package/src/console/ui/signals/schema-form.ts +1 -4
- package/src/console/ui/signals/search.ts +4 -13
- package/src/console/ui/store/StoreA11yView.tsx +3 -9
- package/src/console/ui/store/a11y.test.tsx +2 -5
- package/src/console/ui/store/confirmation.test.ts +1 -3
- package/src/console/ui/store/confirmation.ts +1 -4
- package/src/console/ui/store/dry-run.ts +2 -5
- package/src/console/ui/store/fixture.ts +1 -2
- package/src/console/ui/store/group.test.ts +1 -6
- package/src/console/ui/store/group.ts +1 -4
- package/src/console/ui/store/index.ts +1 -5
- package/src/console/ui/store/search.ts +2 -6
- package/src/console/ui/store/will-not-fire.ts +1 -2
- package/src/console/ui/traces/TracesA11yView.tsx +10 -29
- package/src/console/ui/traces/a11y.test.tsx +1 -2
- package/src/console/ui/traces/chain.test.ts +5 -19
- package/src/console/ui/traces/chain.ts +1 -3
- package/src/console/ui/traces/critical-path.test.ts +1 -3
- package/src/console/ui/traces/critical-path.ts +2 -6
- package/src/console/ui/traces/filter.test.ts +2 -6
- package/src/console/ui/traces/filter.ts +5 -13
- package/src/console/ui/traces/fold.test.ts +4 -12
- package/src/console/ui/traces/fold.ts +1 -3
- package/src/console/ui/traces/mini.ts +1 -3
- package/src/console/ui/traces/replay.test.ts +1 -3
- package/src/console/ui/traces/replay.ts +1 -3
- package/src/console/ui/traces/sampling.ts +1 -4
- package/src/console/ui/traces/search.ts +4 -17
- package/src/console/ui/traces/tier.ts +1 -3
- package/src/console/ui/vault/VaultA11yView.tsx +5 -17
- package/src/console/ui/vault/a11y.test.tsx +1 -2
- package/src/console/ui/vault/blast-radius.ts +1 -3
- package/src/console/ui/vault/confirmation.test.ts +1 -5
- package/src/console/ui/vault/confirmation.ts +1 -4
- package/src/console/ui/vault/dormant.test.ts +1 -4
- package/src/console/ui/vault/export-safe.test.ts +1 -5
- package/src/console/ui/vault/export-safe.ts +1 -4
- package/src/console/ui/vault/fixture.ts +3 -3
- package/src/console/ui/vault/group.ts +1 -2
- package/src/console/ui/vault/index.ts +2 -10
- package/src/console/ui/vault/search.ts +2 -6
- package/src/console/ui/vault/types.ts +1 -1
- package/src/console/xss.gate.test.ts +1 -3
- package/src/docker/compose.ts +215 -27
- package/src/docker/derive.ts +6 -14
- package/src/docker/docker.test.ts +118 -15
- package/src/docker/dockerfile.integration.test.ts +12 -21
- package/src/docker/helpers.ts +5 -4
- package/src/docker/index.ts +9 -6
- package/src/docker/pin.ts +1 -9
- package/src/docker/recipes/index.ts +6 -6
- package/src/docker/recipes/mailpit.ts +22 -0
- package/src/docker/recipes/openbao.ts +47 -0
- package/src/docker/recipes/postgres.ts +17 -6
- package/src/docker/recipes/redis.ts +11 -2
- package/src/docker/recipes/rustfs.ts +32 -0
- package/src/docker/stack-id.test.ts +73 -5
- package/src/docker/stack-id.ts +124 -33
- package/src/docker/stack.integration.test.ts +6 -21
- package/src/docker/stack.ts +36 -4
- package/src/docker/types.ts +16 -4
- package/src/docs-origin.ts +4 -4
- package/src/drivers/ai-anthropic.ts +5 -14
- package/src/drivers/ai-mock.ts +2 -5
- package/src/drivers/ai-openai-compatible.ts +4 -10
- package/src/drivers/ai-providers.test.ts +6 -13
- package/src/drivers/bun-native-completeness.test.ts +6 -15
- package/src/drivers/channel-console.ts +6 -7
- package/src/drivers/channel-fcm.ts +20 -30
- package/src/drivers/channel-resend.ts +1 -3
- package/src/drivers/channel-smtp.ts +2 -6
- package/src/drivers/channel-types.ts +2 -12
- package/src/drivers/channel-unifonic.ts +2 -6
- package/src/drivers/channel-wa-cloud.ts +2 -6
- package/src/drivers/channel-webpush.ts +21 -60
- package/src/drivers/conformance.test.ts +2 -10
- package/src/drivers/conformance.ts +8 -21
- package/src/drivers/drizzle-dialect.test.ts +20 -0
- package/src/drivers/drizzle-dialect.ts +37 -0
- package/src/drivers/fs.ts +2 -8
- package/src/drivers/index.ts +12 -57
- package/src/drivers/memory.ts +287 -75
- package/src/drivers/pgvector.ts +7 -11
- package/src/drivers/postgres.ts +7 -13
- package/src/drivers/redis.ts +13 -37
- package/src/drivers/s3.ts +15 -18
- package/src/drivers/signal-engine.ts +12 -49
- package/src/drivers/signal-memory.ts +2 -8
- package/src/drivers/signal-nats.ts +4 -9
- package/src/drivers/signal-postgres.ts +62 -129
- package/src/drivers/signal-redis.ts +7 -21
- package/src/drivers/signal-types.ts +1 -4
- package/src/drivers/sqlite.ts +3 -12
- package/src/drivers/types.ts +4 -23
- package/src/drivers/vault-driver-removal.test.ts +55 -0
- package/src/drivers/vault-env.ts +2 -6
- package/src/drivers/vault-infisical.ts +1 -5
- package/src/drivers/vault-managed.ts +1 -5
- package/src/drivers/vault-memory.ts +1 -5
- package/src/drivers/vault-openbao.test.ts +97 -0
- package/src/drivers/vault-openbao.ts +103 -40
- package/src/drivers/vault-types.ts +3 -16
- package/src/elements/ai/declare.ts +4 -14
- package/src/elements/ai/eval.ts +2 -6
- package/src/elements/ai/pii.ts +1 -3
- package/src/elements/ai/runtime.ts +12 -50
- package/src/elements/ai/schema.ts +4 -15
- package/src/elements/ai.test.ts +13 -24
- package/src/elements/ai.ts +1 -5
- package/src/elements/channel/consent.ts +3 -12
- package/src/elements/channel/costs.ts +4 -15
- package/src/elements/channel/declare.ts +1 -4
- package/src/elements/channel/email-auth.ts +1 -4
- package/src/elements/channel/locale.ts +2 -10
- package/src/elements/channel/mask.ts +1 -3
- package/src/elements/channel/mime.ts +2 -12
- package/src/elements/channel/outcomes.test.ts +1 -5
- package/src/elements/channel/outcomes.ts +5 -15
- package/src/elements/channel/receipts.ts +2 -7
- package/src/elements/channel/runtime.ts +28 -74
- package/src/elements/channel/suppression.ts +8 -14
- package/src/elements/channel.test.ts +8 -31
- package/src/elements/channel.ts +3 -14
- package/src/elements/clock/actions.ts +6 -18
- package/src/elements/clock/declare.ts +1 -3
- package/src/elements/clock/dst.ts +1 -5
- package/src/elements/clock/durable.ts +4 -16
- package/src/elements/clock/health.ts +2 -7
- package/src/elements/clock/leader.ts +2 -9
- package/src/elements/clock/reconcile.ts +4 -15
- package/src/elements/clock/runtime.ts +2 -5
- package/src/elements/clock/schedule.ts +4 -20
- package/src/elements/clock.test.ts +2 -7
- package/src/elements/clock.ts +5 -23
- package/src/elements/gate/permissions.ts +1 -4
- package/src/elements/gate/runtime.ts +7 -28
- package/src/elements/gate.ts +1 -5
- package/src/elements/index.ts +9 -7
- package/src/elements/signal/declare.ts +2 -7
- package/src/elements/signal/reconcile.test.ts +1 -4
- package/src/elements/signal/runtime.ts +1 -3
- package/src/elements/signal.test.ts +3 -15
- package/src/elements/signal.ts +2 -8
- package/src/elements/store/cache.test.ts +46 -0
- package/src/elements/store/cache.ts +3 -11
- package/src/elements/store/classify.ts +5 -22
- package/src/elements/store/declare.ts +11 -17
- package/src/elements/store/domain-ddl.test.ts +86 -0
- package/src/elements/store/emit-drizzle.ts +363 -0
- package/src/elements/store/files-policy.test.ts +1 -5
- package/src/elements/store/files-policy.ts +4 -12
- package/src/elements/store/load-plugin-tables.ts +103 -0
- package/src/elements/store/missing-relation.test.ts +83 -0
- package/src/elements/store/missing-relation.ts +38 -0
- package/src/elements/store/replica.ts +1 -4
- package/src/elements/store/resource-list-docs.fixture.ts +56 -0
- package/src/elements/store/resource-list-docs.test.ts +79 -0
- package/src/elements/store/resource.test.ts +253 -0
- package/src/elements/store/resource.ts +786 -0
- package/src/elements/store/runtime.ts +25 -28
- package/src/elements/store/schema-decl.test.ts +227 -0
- package/src/elements/store/schema-decl.ts +516 -0
- package/src/elements/store/sql-condition.test.ts +132 -0
- package/src/elements/store/sql-condition.ts +293 -65
- package/src/elements/store/sql-session.test.ts +135 -0
- package/src/elements/store/sql-session.ts +241 -84
- package/src/elements/store/table.ts +69 -23
- package/src/elements/store.test.ts +17 -39
- package/src/elements/store.ts +53 -31
- package/src/elements/vault/chain.ts +34 -0
- package/src/elements/vault/declare.ts +22 -32
- package/src/elements/vault/fingerprint.ts +2 -7
- package/src/elements/vault/redact.ts +2 -6
- package/src/elements/vault/runtime.ts +19 -33
- package/src/elements/vault.test.ts +12 -55
- package/src/elements/vault.ts +9 -13
- package/src/index.ts +5 -2
- package/src/kernel/adopt-routes.ts +15 -29
- package/src/kernel/app.ts +92 -118
- package/src/kernel/auth-resolve.ts +2 -9
- package/src/kernel/boot-bind/ai.ts +1 -4
- package/src/kernel/boot-bind/channel.test.ts +60 -0
- package/src/kernel/boot-bind/channel.ts +61 -5
- package/src/kernel/boot-bind/clock.ts +2 -6
- package/src/kernel/boot-bind/gate.ts +2 -8
- package/src/kernel/boot-bind/runs.ts +1 -3
- package/src/kernel/boot-bind/signal.ts +3 -10
- package/src/kernel/boot-bind/store.test.ts +27 -18
- package/src/kernel/boot-bind/store.ts +93 -52
- package/src/kernel/boot-bind/vault.ts +2 -8
- package/src/kernel/boot.test.ts +4 -10
- package/src/kernel/boot.ts +30 -77
- package/src/kernel/budget.test.ts +1 -3
- package/src/kernel/capability.ts +3 -10
- package/src/kernel/dry-run.test.ts +1 -4
- package/src/kernel/dry-run.ts +3 -11
- package/src/kernel/edge.test.ts +68 -0
- package/src/kernel/effects.test.ts +1 -5
- package/src/kernel/effects.ts +4 -11
- package/src/kernel/errors.registry.test.ts +2 -8
- package/src/kernel/errors.ts +23 -32
- package/src/kernel/flow.test.ts +12 -25
- package/src/kernel/flow.ts +13 -25
- package/src/kernel/fx.test.ts +31 -40
- package/src/kernel/fx.ts +135 -90
- package/src/kernel/hook-timing.test.ts +3 -6
- package/src/kernel/hook-timing.ts +5 -14
- package/src/kernel/hooks.test.ts +43 -10
- package/src/kernel/hooks.ts +25 -12
- package/src/kernel/index.ts +11 -17
- package/src/kernel/journal.ts +7 -31
- package/src/kernel/on.ts +45 -9
- package/src/kernel/pipeline.test.ts +10 -19
- package/src/kernel/pipeline.ts +5 -17
- package/src/kernel/plug.ts +4 -11
- package/src/kernel/plugin/conflicts.test.ts +13 -25
- package/src/kernel/plugin/decorate.test.ts +8 -13
- package/src/kernel/plugin/scoping.test.ts +4 -11
- package/src/kernel/plugin.ts +81 -27
- package/src/kernel/registry-isolation.test.ts +74 -0
- package/src/kernel/registry.ts +102 -30
- package/src/kernel/router.test.ts +15 -13
- package/src/kernel/router.ts +9 -29
- package/src/kernel/routing-budget.test.ts +1 -3
- package/src/kernel/run-telemetry.ts +1 -3
- package/src/kernel/triggers.ts +63 -21
- package/src/manifest/diff.test.ts +26 -91
- package/src/manifest/diff.ts +95 -225
- package/src/manifest/fixtures/skyport.excerpt.json +1 -1
- package/src/manifest/fixtures/skyport.manifest.json +1 -1
- package/src/manifest/index.ts +3 -10
- package/src/manifest/types.ts +30 -6
- package/src/manifest/undeclared.test.ts +4 -12
- package/src/manifest/undeclared.ts +1 -2
- package/src/manifest/validate.test.ts +2 -6
- package/src/manifest/validate.ts +5 -15
- package/src/mcp/authorization.ts +8 -27
- package/src/mcp/confirmation.ts +3 -10
- package/src/mcp/data.ts +2 -6
- package/src/mcp/docs-index.ts +4 -7
- package/src/mcp/docs-mcp.test.ts +3 -12
- package/src/mcp/docs-server.ts +7 -27
- package/src/mcp/docs-tools.ts +2 -6
- package/src/mcp/index.ts +1 -6
- package/src/mcp/injection.gate.test.ts +4 -18
- package/src/mcp/mcp.test.ts +18 -49
- package/src/mcp/protocol.ts +3 -10
- package/src/mcp/server.ts +11 -52
- package/src/mcp/session.ts +4 -14
- package/src/mcp/tools.ts +14 -50
- package/src/plugins/catalogue.test.ts +3 -7
- package/src/plugins/catalogue.ts +1 -3
- package/src/plugins/compression.test.ts +127 -0
- package/src/plugins/compression.ts +94 -0
- package/src/plugins/config-source.test.ts +204 -0
- package/src/plugins/config-source.ts +209 -0
- package/src/plugins/cors.test.ts +138 -0
- package/src/plugins/cors.ts +129 -0
- package/src/plugins/csrf.test.ts +102 -0
- package/src/plugins/csrf.ts +86 -0
- package/src/plugins/headers.ts +54 -0
- package/src/plugins/index.ts +26 -0
- package/src/plugins/ip-allowlist.test.ts +105 -0
- package/src/plugins/ip-allowlist.ts +76 -0
- package/src/plugins/maintenance-mode.test.ts +91 -0
- package/src/plugins/maintenance-mode.ts +85 -0
- package/src/plugins/node-import-scan.ts +2 -5
- package/src/plugins/security-headers.test.ts +243 -0
- package/src/plugins/security-headers.ts +255 -0
- package/src/plugins/supply-chain.ts +5 -17
- package/src/release/exports.ts +3 -8
- package/src/release/measure.exports.test.ts +1 -3
- package/src/release/measure.ts +16 -45
- package/src/runs/bench.test.ts +1 -3
- package/src/runs/collect.ts +8 -25
- package/src/runs/drivers/clickhouse.ts +2 -9
- package/src/runs/drivers/files.ts +9 -31
- package/src/runs/drivers/memory.ts +5 -22
- package/src/runs/drivers/postgres.ts +8 -20
- package/src/runs/duckdb.ts +2 -8
- package/src/runs/index.ts +3 -14
- package/src/runs/outlier.ts +3 -10
- package/src/runs/parquet.ts +8 -26
- package/src/runs/privacy.ts +2 -8
- package/src/runs/runs.test.ts +3 -9
- package/src/runs/runtime.ts +7 -32
- package/src/runs/shred.ts +10 -29
- package/src/runs/types.ts +1 -4
- package/src/runtime/bun.ts +4 -15
- package/src/runtime/cold-start.bench.ts +1 -3
- package/src/runtime/dev-request-log.test.ts +1 -4
- package/src/runtime/dev-request-log.ts +1 -4
- package/src/runtime/index.ts +1 -6
- package/src/runtime/primitives.ts +5 -4
- package/src/runtime/security.ts +3 -13
- package/src/runtime/serve.test.ts +4 -7
- package/src/runtime/types.ts +1 -4
- package/src/runtime/web-standard.ts +3 -15
- package/src/term.test.ts +4 -6
- package/src/term.ts +49 -98
- package/src/test/create-test-app.test.ts +4 -14
- package/src/test/create-test-app.ts +27 -33
- package/src/test/provisions.integration.test.ts +3 -11
- package/src/upgrade/codemods.test.ts +25 -6
- package/src/upgrade/codemods.ts +116 -3
- package/src/validation/standard-schema.test.ts +2 -5
- package/src/validation/standard-schema.ts +13 -33
- package/docs/spec/console.md +0 -739
- package/docs/spec/example.md +0 -1196
- package/docs/spec/four-applications.md +0 -1195
- package/docs/spec/unified-theory.md +0 -489
- package/src/cli/doc-drift.test.ts +0 -146
- package/src/cli/doc-drift.ts +0 -430
- package/src/cli/doctor-diff-examples.ts +0 -92
- package/src/console/ui/dist/assets/panel-vault-BbfWdox0.js +0 -1
- package/src/drivers/vault-sops.ts +0 -271
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Vault"
|
|
3
|
+
description: "Secrets, API keys, and config — declared once as typed contracts, resolved from a real vault in production, never leaked into logs."
|
|
4
|
+
icon: "KeyRound"
|
|
5
|
+
source: "docs/spec/unified-theory.md"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Vault is where your app's **protected knowledge** lives: API keys, database URLs, tokens — plus non-secret config like a public app URL. This page shows how to declare a secret, give it a value, and read it in a Flow, then how OKE keeps it safe in production.
|
|
9
|
+
|
|
10
|
+
<Callout title="The one rule">
|
|
11
|
+
You declare **contracts**, never values, in code. Values come from the environment at boot — a
|
|
12
|
+
secret that has no value anywhere fails the boot loudly, with every gap listed at once.
|
|
13
|
+
</Callout>
|
|
14
|
+
|
|
15
|
+
## Quick start
|
|
16
|
+
|
|
17
|
+
<Steps>
|
|
18
|
+
|
|
19
|
+
<Step>
|
|
20
|
+
### Declare the contract
|
|
21
|
+
|
|
22
|
+
In `src/vault.ts`, declare what your app needs. This says "a secret named `STRIPE_KEY` exists" — it does **not** contain the key itself:
|
|
23
|
+
|
|
24
|
+
```typescript title="src/vault.ts"
|
|
25
|
+
import { vault } from "okengine";
|
|
26
|
+
import { z } from "zod";
|
|
27
|
+
|
|
28
|
+
export const stripeKey = vault.secret("STRIPE_KEY", {
|
|
29
|
+
description: "Payments gateway key",
|
|
30
|
+
rotate: "90d",
|
|
31
|
+
schema: z.string().startsWith("sk_"),
|
|
32
|
+
dev: "sk_test_local", // used only by `oke dev` (local) when nothing else provides a value
|
|
33
|
+
});
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
</Step>
|
|
37
|
+
|
|
38
|
+
<Step>
|
|
39
|
+
### Give it a value
|
|
40
|
+
|
|
41
|
+
For local development, put the real value in `.env.local` (gitignored):
|
|
42
|
+
|
|
43
|
+
```bash title=".env.local"
|
|
44
|
+
STRIPE_KEY=sk_test_your_key_here
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Or set it from the CLI — it writes to the right place for the active mode:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
oke vault set STRIPE_KEY sk_test_your_key_here
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
</Step>
|
|
54
|
+
|
|
55
|
+
<Step>
|
|
56
|
+
### Read it in a Flow
|
|
57
|
+
|
|
58
|
+
Flows read secrets through `fx.vault` — never through `process.env`:
|
|
59
|
+
|
|
60
|
+
```typescript title="src/flows/billing/charge.ts"
|
|
61
|
+
export const charge = on(
|
|
62
|
+
http.post("/charge"),
|
|
63
|
+
flow({
|
|
64
|
+
in: ChargeInput,
|
|
65
|
+
out: z.object({ id: z.string() }),
|
|
66
|
+
do: async (input, fx) => {
|
|
67
|
+
const key = fx.vault(stripeKey); // cleartext, inside this flow only
|
|
68
|
+
const intent = await stripe(key).create(input);
|
|
69
|
+
return { id: intent.id };
|
|
70
|
+
},
|
|
71
|
+
}),
|
|
72
|
+
);
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
</Step>
|
|
76
|
+
|
|
77
|
+
</Steps>
|
|
78
|
+
|
|
79
|
+
That's the whole loop: declare → set → read. Everything below is what OKE guarantees on top of it.
|
|
80
|
+
|
|
81
|
+
## Two kinds of contracts
|
|
82
|
+
|
|
83
|
+
| Declaration | Sensitive? | Console shows | Use for |
|
|
84
|
+
| ----------------------------------- | ---------- | ---------------- | --------------------------- |
|
|
85
|
+
| `vault.secret("STRIPE_KEY", …)` | yes | fingerprint only | API keys, tokens, passwords |
|
|
86
|
+
| `vault.config("PUBLIC_APP_URL", …)` | no | cleartext value | Public URLs, feature flags |
|
|
87
|
+
|
|
88
|
+
`vault(name, …)` is shorthand for `vault.secret(name, …)`.
|
|
89
|
+
|
|
90
|
+
### Contract options
|
|
91
|
+
|
|
92
|
+
| Option | Type | Meaning |
|
|
93
|
+
| ------------- | --------------------- | ------------------------------------------------------------------------ |
|
|
94
|
+
| `description` | string | Shown in boot-gap listings and the Console |
|
|
95
|
+
| `rotate` | string | Rotation hint (`"90d"`) — drives the rotation-due signal in the Console |
|
|
96
|
+
| `schema` | zod / Standard Schema | Validated at boot; a bad value fails boot like a missing one |
|
|
97
|
+
| `dev` | string | Local-only fallback when no source provides a value (never used in prod) |
|
|
98
|
+
| `sensitive` | boolean | Override the default (`true` for secrets, `false` for config) |
|
|
99
|
+
|
|
100
|
+
### Zero-setup local fallback
|
|
101
|
+
|
|
102
|
+
`dev: vault.fromDocker("store.sql")` resolves the connection URL that `oke dev --docker` generated for that role — no manual copying of Postgres URLs:
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
export const dbUrl = vault.secret("DATABASE_URL", {
|
|
106
|
+
dev: vault.fromDocker("store.sql"),
|
|
107
|
+
});
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Where values come from
|
|
111
|
+
|
|
112
|
+
At boot, each contract is resolved through this chain — **first hit wins**:
|
|
113
|
+
|
|
114
|
+
| # | Source | Typical content |
|
|
115
|
+
| --- | -------------------- | ------------------------------------------------- |
|
|
116
|
+
| 1 | `process.env` | Real environment (CI, hosting platform) |
|
|
117
|
+
| 2 | `.env.local` | Your machine's local overrides (gitignored) |
|
|
118
|
+
| 3 | `docker/.env.docker` | Generated compose stack credentials |
|
|
119
|
+
| 4 | vault driver | OpenBao in docker/prod mode |
|
|
120
|
+
| 5 | `dev` fallback | The `dev:` option on the contract (never in prod) |
|
|
121
|
+
|
|
122
|
+
If every layer misses a contract, boot **fails** before any request is served:
|
|
123
|
+
|
|
124
|
+
```text
|
|
125
|
+
VaultBootError: 1 secret(s) missing:
|
|
126
|
+
STRIPE_KEY — Payments gateway key
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
<Callout title="Good to know">
|
|
130
|
+
This is the fail-loud contract: an app with a missing secret **never** boots halfway and fails
|
|
131
|
+
later at request time. All gaps are listed in one error, not one at a time.
|
|
132
|
+
</Callout>
|
|
133
|
+
|
|
134
|
+
## Setting and rotating values
|
|
135
|
+
|
|
136
|
+
| Command | What it does |
|
|
137
|
+
| -------------------------- | ---------------------------------------------------------------- |
|
|
138
|
+
| `oke vault set NAME value` | Write a value (OpenBao API in docker mode, `.env.local` locally) |
|
|
139
|
+
| `oke vault list` | List names present in the active store |
|
|
140
|
+
| `oke vault import <file>` | Bulk-import names from a dotenv file |
|
|
141
|
+
|
|
142
|
+
In docker mode, `oke vault set` writes straight to the running OpenBao — no git commit, no rebuild, no restart of the vault.
|
|
143
|
+
|
|
144
|
+
The **Console** (`:6533`) can also set and rotate values, but it is **write-only**: it shows a salted fingerprint (`sha256:…`) per secret, never the cleartext. When you rotate a key there, the panel shows the **blast radius** — which in-flight durable runs will wake up with the new value.
|
|
145
|
+
|
|
146
|
+
<Callout title="Secrets never reach logs">
|
|
147
|
+
Every loaded secret is registered with the redactor at boot. Even if you accidentally pass one to
|
|
148
|
+
`fx.log`, the log line shows `***` — the value, never. Traces and the Console get fingerprints.
|
|
149
|
+
</Callout>
|
|
150
|
+
|
|
151
|
+
## Per-environment drivers
|
|
152
|
+
|
|
153
|
+
Which backend holds your values depends on the mode — configured once in `oke.config.ts`:
|
|
154
|
+
|
|
155
|
+
```typescript title="oke.config.ts"
|
|
156
|
+
vault: {
|
|
157
|
+
local: "dotenv", // .env.local — zero ceremony
|
|
158
|
+
docker: "openbao", // real vault in the compose stack
|
|
159
|
+
test: "memory", // seeded map — deterministic tests
|
|
160
|
+
prod: "openbao", // real vault in production
|
|
161
|
+
},
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
| Driver | Backend | Best for |
|
|
165
|
+
| --------- | --------------- | ------------------------------------------ |
|
|
166
|
+
| `dotenv` | `.env.local` | Local loop — no infra at all |
|
|
167
|
+
| `openbao` | OpenBao (KV v2) | Docker + prod — durable, access-controlled |
|
|
168
|
+
| `memory` | in-process map | Tests |
|
|
169
|
+
|
|
170
|
+
Other drivers (`infisical`, `managed`) implement the same `VaultDriver` interface — adding one is a driver exercise, not an architecture change.
|
|
171
|
+
|
|
172
|
+
## OpenBao in docker and prod
|
|
173
|
+
|
|
174
|
+
When you run `oke dev --docker` (or bring up a `--prod` stack), OKE runs a real OpenBao container with durable Raft storage — not an in-memory dev server.
|
|
175
|
+
|
|
176
|
+
<Steps>
|
|
177
|
+
|
|
178
|
+
<Step>
|
|
179
|
+
### First boot is automatic
|
|
180
|
+
|
|
181
|
+
OKE initializes OpenBao (Shamir 1-of-1), unseals it, writes a least-privilege policy that covers **only your declared secrets**, and mints an app token bound to that policy. You never run raw `bao` commands.
|
|
182
|
+
|
|
183
|
+
</Step>
|
|
184
|
+
|
|
185
|
+
<Step>
|
|
186
|
+
### Keys stay on the host
|
|
187
|
+
|
|
188
|
+
The unseal key and root token are written to `.oke/openbao/` (mode `0600`, gitignored) — never into `docker/.env.docker`, never into YAML. Only the least-privilege app token lands in `.env.docker` as `OKE_VAULT_TOKEN`.
|
|
189
|
+
|
|
190
|
+
</Step>
|
|
191
|
+
|
|
192
|
+
<Step>
|
|
193
|
+
### Restarts just work
|
|
194
|
+
|
|
195
|
+
On every later start OKE detects the sealed vault and unseals it with the host key. Secrets set before a container restart are still there after it — proven by an integration test, not assumed.
|
|
196
|
+
|
|
197
|
+
</Step>
|
|
198
|
+
|
|
199
|
+
</Steps>
|
|
200
|
+
|
|
201
|
+
| File | Holds | Used by |
|
|
202
|
+
| ------------------------- | ------------------------- | -------------------------------- |
|
|
203
|
+
| `.oke/openbao/unseal.key` | The single unseal share | `oke` (every start) |
|
|
204
|
+
| `.oke/openbao/root.token` | Root token | `oke` (policy sync / token mint) |
|
|
205
|
+
| `.oke/openbao/app.token` | Least-privilege app token | the app + Console |
|
|
206
|
+
|
|
207
|
+
<Callout title="Single point of failure — read this once" type="warn">
|
|
208
|
+
Back up `.oke/openbao/unseal.key` to a separate safe location. Losing it means losing every secret
|
|
209
|
+
permanently, with no recovery.
|
|
210
|
+
</Callout>
|
|
211
|
+
|
|
212
|
+
This is by design: self-hosted single-node, Shamir 1-of-1, no cloud KMS. If OpenBao is initialized but the key is gone, boot fails with an explicit permanent-loss error — it never silently starts empty.
|
|
213
|
+
|
|
214
|
+
## Troubleshooting
|
|
215
|
+
|
|
216
|
+
<Accordions>
|
|
217
|
+
<Accordion title="Boot fails with VaultBootError listing missing secrets">
|
|
218
|
+
|
|
219
|
+
A contract has no value in any layer of the chain. Fix by providing it in exactly one place:
|
|
220
|
+
|
|
221
|
+
- locally: add `NAME=value` to `.env.local` (or run `oke vault set NAME value`)
|
|
222
|
+
- docker mode: `oke vault set NAME value` writes to OpenBao directly
|
|
223
|
+
- CI / hosting: set a real environment variable
|
|
224
|
+
|
|
225
|
+
</Accordion>
|
|
226
|
+
<Accordion title="OpenBao is sealed or unreachable in docker mode">
|
|
227
|
+
|
|
228
|
+
Re-run `oke dev --docker` — the bootstrap unseals with the host key on every start. If it reports the vault is initialized but `.oke/openbao/unseal.key` is missing, restore the key from your backup; the error is explicit because starting empty would look like "no secrets" instead of data loss.
|
|
229
|
+
|
|
230
|
+
</Accordion>
|
|
231
|
+
<Accordion title="Where is the root token?">
|
|
232
|
+
|
|
233
|
+
`.oke/openbao/root.token`, mode `0600`, gitignored. It exists only for `oke` to sync policies and mint app tokens — the running app never sees it.
|
|
234
|
+
|
|
235
|
+
</Accordion>
|
|
236
|
+
<Accordion title="How do I rotate a key safely?">
|
|
237
|
+
|
|
238
|
+
Set the new value (`oke vault set` or the Console). The Console's rotation view shows the blast radius — in-flight durable runs that will resume with the new value — before you commit. The `rotate: "90d"` hint on the contract drives the rotation-due signal.
|
|
239
|
+
|
|
240
|
+
</Accordion>
|
|
241
|
+
</Accordions>
|
|
242
|
+
|
|
243
|
+
## Learn more
|
|
244
|
+
|
|
245
|
+
- [Console · Vault](/docs/console/vault) — fingerprints, resolution chain, rotation blast radius
|
|
246
|
+
- [Flow](/docs/elements/flow) — how `fx.vault` reads secrets inside `do`
|
|
247
|
+
- [CLI Reference](/docs/reference/cli) — `oke vault set` · `list` · `import`
|
|
248
|
+
|
|
249
|
+
## Next
|
|
250
|
+
|
|
251
|
+
<Cards>
|
|
252
|
+
<Card title="Channel" description="Continue to Channel." href="/docs/elements/channel" />
|
|
253
|
+
<Card
|
|
254
|
+
title="Introduction"
|
|
255
|
+
description="Eight elements overview."
|
|
256
|
+
href="/docs/get-started/introduction"
|
|
257
|
+
/>
|
|
258
|
+
<Card
|
|
259
|
+
title="Console"
|
|
260
|
+
description="Panels derived from the Manifest."
|
|
261
|
+
href="/docs/console/overview"
|
|
262
|
+
/>
|
|
263
|
+
</Cards>
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Basic Usage
|
|
3
|
+
description: Scaffold the standard starter, write a Flow, and inspect it in the Console.
|
|
4
|
+
source: packages/create-oke/template
|
|
5
|
+
icon: SquareTerminal
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Scaffold an app
|
|
9
|
+
|
|
10
|
+
```bash title="Terminal"
|
|
11
|
+
bunx create-oke@latest my-app
|
|
12
|
+
cd my-app
|
|
13
|
+
oke dev
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
The app runs on `:6530`, the Console on `:6533`, and MCP on `:6535`.
|
|
17
|
+
|
|
18
|
+
## Mental model
|
|
19
|
+
|
|
20
|
+
Every backend behavior has one shape:
|
|
21
|
+
|
|
22
|
+
```text
|
|
23
|
+
on(Trigger) → Effects
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
1. **Trigger** — how work starts (`http.post`, `every("10m")`, a signal, …)
|
|
27
|
+
2. **Contracts** — `in`, `out`, and typed `errors`
|
|
28
|
+
3. **`do`** — the body; world access goes only through `fx`
|
|
29
|
+
4. **Effects** — inferred from the `fx` calls
|
|
30
|
+
|
|
31
|
+
## Your first Flow
|
|
32
|
+
|
|
33
|
+
The standard starter includes a health Flow:
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
import { on, flow, http } from "okengine";
|
|
37
|
+
import { z } from "zod";
|
|
38
|
+
|
|
39
|
+
export const health = on(
|
|
40
|
+
http.get("/health"),
|
|
41
|
+
flow({
|
|
42
|
+
out: z.object({ ok: z.literal(true) }),
|
|
43
|
+
do: () => ({ ok: true as const }),
|
|
44
|
+
}),
|
|
45
|
+
);
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Open `src/flows/main/index.ts`, change the route or output, and save. The app and
|
|
49
|
+
Console update together from the same Manifest.
|
|
50
|
+
|
|
51
|
+
<Callout title="The invariant">
|
|
52
|
+
All reads, writes, emits, sends, and external calls belong behind `fx`. This is what makes effects
|
|
53
|
+
inspectable and tests deterministic.
|
|
54
|
+
</Callout>
|
|
55
|
+
|
|
56
|
+
## Wire the app
|
|
57
|
+
|
|
58
|
+
The starter adopts the module in `src/app.ts`:
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
import { oke } from "okengine";
|
|
62
|
+
import * as main from "./flows/main";
|
|
63
|
+
|
|
64
|
+
export const app = oke({ name: "my-app" }).adopt({ main });
|
|
65
|
+
export type App = typeof app;
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
The namespace becomes the typed-client namespace and each exported Flow becomes
|
|
69
|
+
a method.
|
|
70
|
+
|
|
71
|
+
## Typed client
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
import { createClient } from "okengine/client";
|
|
75
|
+
import type { App } from "../src/app";
|
|
76
|
+
|
|
77
|
+
const api = createClient<App>("http://localhost:6530");
|
|
78
|
+
const { data, error } = await api.main.health({});
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
`data` and `error` are inferred from the Flow contracts; no separate client
|
|
82
|
+
schema or code-generation project is required.
|
|
83
|
+
|
|
84
|
+
## Test
|
|
85
|
+
|
|
86
|
+
Use `createTestApp` to boot the same app with test drivers:
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
import { expect, test } from "bun:test";
|
|
90
|
+
import { createTestApp } from "okengine/test";
|
|
91
|
+
import { app } from "../src/app";
|
|
92
|
+
|
|
93
|
+
test("health", async () => {
|
|
94
|
+
const t = await createTestApp(app);
|
|
95
|
+
const { data, error } = await t.api.main.health({});
|
|
96
|
+
expect(error).toBeNull();
|
|
97
|
+
expect(data).toEqual({ ok: true });
|
|
98
|
+
await app.stop();
|
|
99
|
+
});
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
```bash title="Terminal"
|
|
103
|
+
bun test
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Next
|
|
107
|
+
|
|
108
|
+
<Cards>
|
|
109
|
+
<Card
|
|
110
|
+
title="Flow"
|
|
111
|
+
description="Triggers, contracts, effects, and composition."
|
|
112
|
+
href="/docs/elements/flow"
|
|
113
|
+
/>
|
|
114
|
+
<Card
|
|
115
|
+
title="Store"
|
|
116
|
+
description="SQL, KV, files, index, and declarative resources."
|
|
117
|
+
href="/docs/elements/store"
|
|
118
|
+
/>
|
|
119
|
+
<Card
|
|
120
|
+
title="Console"
|
|
121
|
+
description="Manifest-derived flows, effects, traces, and architecture."
|
|
122
|
+
href="/docs/console/overview"
|
|
123
|
+
/>
|
|
124
|
+
</Cards>
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Comparison
|
|
3
|
+
description: How OKE compares to Hono, Elysia, Encore.ts, and iii — and when to pick it.
|
|
4
|
+
source: docs/spec/unified-theory.md
|
|
5
|
+
icon: Scale
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
> **OKE is the batteries-included TypeScript backend for the Bun era:** contract-first APIs with end-to-end type safety, declarative infrastructure primitives, an OpenTelemetry-native Console, secure-by-default auth and ABAC — pure TypeScript, Web-Standards portable, MIT-licensed, self-hostable with zero cloud lock-in.
|
|
9
|
+
|
|
10
|
+
_"Encore's batteries and dashboard, Elysia's speed and DX, Hono's portability — without the Rust lock-in, the cloud gravity, or the source-available license."_
|
|
11
|
+
|
|
12
|
+
## When to pick OKE
|
|
13
|
+
|
|
14
|
+
Choose OKE if you want:
|
|
15
|
+
|
|
16
|
+
- **One mental model** for HTTP, jobs, consumers, and durable work (`on(Trigger) → Effects`)
|
|
17
|
+
- **Batteries included** — store, signals, clock, gates, vault, channels, and AI as first-class elements
|
|
18
|
+
- **A local Console** derived from your code (not a separate SaaS product you must adopt)
|
|
19
|
+
- **MIT + self-host** with drivers named after protocols (`postgres`, `redis`, `s3`), not vendors
|
|
20
|
+
- Effects that power cache invalidation, live queries, and least privilege **without hand annotations**
|
|
21
|
+
|
|
22
|
+
Prefer a thinner router (Hono / Elysia alone) if you only need HTTP and will assemble queues, cron, and auth yourself.
|
|
23
|
+
|
|
24
|
+
## Matrix
|
|
25
|
+
|
|
26
|
+
| | Hono | Elysia | Encore.ts | iii | **OKE** |
|
|
27
|
+
| ----------------------------------------------- | --------------- | ----------- | ------------------- | --------------------- | --------------------------------- |
|
|
28
|
+
| Primary runtime | Multi (Web Std) | Bun-first | Node + Rust core | Rust engine, polyglot | **Bun-first, Web-Std portable** |
|
|
29
|
+
| License | MIT | MIT | MPL-2.0 | ELv2 engine | **MIT** |
|
|
30
|
+
| Typed client | hc RPC | Eden Treaty | generated | SDK | **contract-first + live queries** |
|
|
31
|
+
| DB · queue · cron · storage | ❌ | ❌ | ✅ | ✅ | **✅ (7 elements)** |
|
|
32
|
+
| Durable workflows | ❌ | ❌ | ❌ | partial | **✅ (a flag)** |
|
|
33
|
+
| Local Console | ❌ | ❌ | ✅ | ✅ | **✅ (dev + prod)** |
|
|
34
|
+
| Auto cache invalidation | ❌ | ❌ | ❌ | ❌ | **✅ (from effects)** |
|
|
35
|
+
| Least-privilege by compiler | ❌ | ❌ | ❌ | ❌ | **✅** |
|
|
36
|
+
| Human channels (email/SMS/WA) | ❌ | ❌ | ❌ | ❌ | **✅ (7th element)** |
|
|
37
|
+
| AI in the application (models, prompts, agents) | ❌ | ❌ | ❌ | ❌ | **✅ (8th element)** |
|
|
38
|
+
| Self-host, no lock-in | ✅ | ✅ | ✅ (Cloud optional) | ⚠️ | **✅ first-class** |
|
|
39
|
+
|
|
40
|
+
## vs Collections of libraries
|
|
41
|
+
|
|
42
|
+
Frameworks that ship a router plus a queue library plus a cron library plus websockets share one flaw: the concepts do not derive from one another. Documentation sprawls; each new fashion adds a concept that never gets removed.
|
|
43
|
+
|
|
44
|
+
OKE starts from one law so docs, traces, hooks, and agent surfaces stay **one shape**.
|
|
45
|
+
|
|
46
|
+
## vs Cloud-gravity platforms
|
|
47
|
+
|
|
48
|
+
OKE is MIT, self-hostable, and names drivers after **protocols** — not vendors. Vendor choice lives in images keyed by role. There is no separate “deploy to our cloud” product you must adopt to get the Console.
|
|
49
|
+
|
|
50
|
+
## vs Rolling your own effect system
|
|
51
|
+
|
|
52
|
+
Effects are inferred from what a Flow touches through `fx`. Cache invalidation, live queries, least privilege, deterministic tests, and Manifest Diff fall out of that one decision — without hand-written annotations for each capability.
|
|
53
|
+
|
|
54
|
+
<Cards>
|
|
55
|
+
<Card
|
|
56
|
+
title="Installation"
|
|
57
|
+
description="Install and scaffold in minutes."
|
|
58
|
+
href="/docs/get-started/installation"
|
|
59
|
+
/>
|
|
60
|
+
<Card
|
|
61
|
+
title="Introduction"
|
|
62
|
+
description="The one law, eight elements, ten exports."
|
|
63
|
+
href="/docs/get-started/introduction"
|
|
64
|
+
/>
|
|
65
|
+
</Cards>
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Installation
|
|
3
|
+
description: Install okengine, scaffold an app with create-oke, and open the Console.
|
|
4
|
+
source: README.md
|
|
5
|
+
icon: Download
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
This page gets you from zero to a running app. Prefer Bun throughout — the engine targets **Bun ≥ 1.3**.
|
|
9
|
+
|
|
10
|
+
<Steps>
|
|
11
|
+
|
|
12
|
+
### Prerequisites
|
|
13
|
+
|
|
14
|
+
- [Bun](https://bun.sh) ≥ 1.3 (`bun --version`)
|
|
15
|
+
- A terminal and a code editor
|
|
16
|
+
|
|
17
|
+
### Install the package
|
|
18
|
+
|
|
19
|
+
Add the framework (ships the `oke` CLI):
|
|
20
|
+
|
|
21
|
+
```bash title="Terminal"
|
|
22
|
+
bun add okengine
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
<Callout title="JSR">
|
|
26
|
+
Library API only: `bunx jsr add @omqkhafi/okengine`. Prefer npm / `bun add` when you want the
|
|
27
|
+
`oke` CLI on your PATH via the package.
|
|
28
|
+
</Callout>
|
|
29
|
+
|
|
30
|
+
### Scaffold with create-oke
|
|
31
|
+
|
|
32
|
+
Create the standard recommended project layout:
|
|
33
|
+
|
|
34
|
+
```bash title="Terminal"
|
|
35
|
+
bunx create-oke@latest my-app
|
|
36
|
+
bunx create-oke@latest my-app --template standard
|
|
37
|
+
bunx create-oke@latest my-app --sql postgres
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
The standard template is the only starter. `--sql postgres` opts into a
|
|
41
|
+
`pgTable` schema and pins local, Docker, and production to Postgres; the default
|
|
42
|
+
keeps local SQLite with Docker and production on Postgres.
|
|
43
|
+
|
|
44
|
+
### Run the app
|
|
45
|
+
|
|
46
|
+
```bash title="Terminal"
|
|
47
|
+
cd my-app
|
|
48
|
+
oke dev
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Local mode watches domain schema paths (`schema.ts` / `schema.decl.ts` / `app.ts`)
|
|
52
|
+
and auto-runs `oke db push` (drizzle-kit) so the database stays in sync. Opt out
|
|
53
|
+
with `oke dev --no-db-push` or `db: { autoPush: false }` in `oke.config.ts`. For
|
|
54
|
+
production, generate and apply migrations deliberately:
|
|
55
|
+
|
|
56
|
+
```bash title="Terminal"
|
|
57
|
+
oke db generate # write drizzle/*.sql
|
|
58
|
+
oke db migrate # apply — never automatic on boot
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Three ports come up together (mnemonic: **O·K·E = 6·5·3**):
|
|
62
|
+
|
|
63
|
+
| Port | Surface |
|
|
64
|
+
| ------- | -------- |
|
|
65
|
+
| `:6530` | Your app |
|
|
66
|
+
| `:6533` | Console |
|
|
67
|
+
| `:6535` | MCP |
|
|
68
|
+
|
|
69
|
+
Open the Console — flows, contracts, effects, and an architecture diagram are already there. **Derived, not configured.**
|
|
70
|
+
|
|
71
|
+
Want Postgres/Redis like production while the app stays on host Bun?
|
|
72
|
+
|
|
73
|
+
```bash title="Terminal"
|
|
74
|
+
oke dev --docker # or: oke dev -d
|
|
75
|
+
# or set the saved default: oke mode docker
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
That uses the `docker` driver profile in `oke.config.ts` (filled from `prod` when omitted). Compose files and credentials land under `docker/` (`.env.docker` beside compose). Host ports — including Mailpit UI / RustFS console extras — are unique per project so multiple apps can run at once. Bare `oke dev` prompts once on a TTY (saved in `.oke/mode`); non-TTY defaults to `local`.
|
|
79
|
+
|
|
80
|
+
The generated env follows each protocol instead of forcing one generic credential shape:
|
|
81
|
+
|
|
82
|
+
- Postgres: `DATABASE_URL` plus `OKE_STORE_SQL_*`
|
|
83
|
+
- Redis: `REDIS_URL` plus `OKE_STORE_KV_PASSWORD`
|
|
84
|
+
- S3-compatible files: `S3_ENDPOINT`, `S3_ACCESS_KEY_ID`, `S3_SECRET_ACCESS_KEY`, `S3_BUCKET`, `S3_URL`, `S3_REGION`, and `S3_CONSOLE_URL`
|
|
85
|
+
- SMTP email: `SMTP_URL`, `SMTP_HOST`, `SMTP_PORT`, and `MAILPIT_UI_URL` with optional `SMTP_USER` / `SMTP_PASSWORD`
|
|
86
|
+
|
|
87
|
+
Each section also includes commented controls (for example Redis memory policy,
|
|
88
|
+
Postgres init options, Bun S3 session tokens, and Mailpit limits). Uncommented
|
|
89
|
+
supported controls are preserved when `oke dev --docker` regenerates the file.
|
|
90
|
+
|
|
91
|
+
### Verify the install
|
|
92
|
+
|
|
93
|
+
Hit the app (path depends on the template) or open `http://localhost:6533`. If the Console lists your flows, the install worked.
|
|
94
|
+
|
|
95
|
+
</Steps>
|
|
96
|
+
|
|
97
|
+
## Next steps
|
|
98
|
+
|
|
99
|
+
Continue to [Basic Usage](/docs/get-started/basic-usage) for your first Flow,
|
|
100
|
+
typed client, and test.
|
|
101
|
+
|
|
102
|
+
<Cards>
|
|
103
|
+
<Card
|
|
104
|
+
title="Basic Usage"
|
|
105
|
+
description="First flows, client, and tests."
|
|
106
|
+
href="/docs/get-started/basic-usage"
|
|
107
|
+
/>
|
|
108
|
+
<Card
|
|
109
|
+
title="CLI Reference"
|
|
110
|
+
description="oke and create-oke commands."
|
|
111
|
+
href="/docs/reference/cli"
|
|
112
|
+
/>
|
|
113
|
+
</Cards>
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Introduction
|
|
3
|
+
description: Learn the one idea behind okengine — then the eight elements and ten exports.
|
|
4
|
+
source: docs/spec/unified-theory.md
|
|
5
|
+
icon: BookOpen
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
OKE is a Bun-first TypeScript backend. You do not learn a pile of unrelated tools (router + queue + cron + websockets). You learn **one sentence**, and everything else follows from it.
|
|
9
|
+
|
|
10
|
+
## The one law
|
|
11
|
+
|
|
12
|
+
> **Every backend behavior is a Flow:** `on(Trigger) → Effects`
|
|
13
|
+
|
|
14
|
+
There are no separate species called endpoints, handlers, consumers, jobs, subscribers, or workflows. There is one species — the **Flow** — and triggers are typed values:
|
|
15
|
+
|
|
16
|
+
```ts title="flows"
|
|
17
|
+
on(http.post("/bookings"), createBooking); // "an API endpoint"
|
|
18
|
+
on(every("10m"), expireStale); // "a cron job"
|
|
19
|
+
on(orderPlaced, sendReceipt); // "a queue consumer"
|
|
20
|
+
on(db.table(users).changed("email"), reverify); // "a CDC trigger"
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Same shape every time: a trigger, a flow body, and effects inferred from what that body touches through `fx`.
|
|
24
|
+
|
|
25
|
+
<Callout title="Why this lowers the learning curve">
|
|
26
|
+
One law → one mental model → one documentation path → one trace shape → one thing for an AI agent to learn.
|
|
27
|
+
|
|
28
|
+
**Learning OKE is learning one sentence.**
|
|
29
|
+
|
|
30
|
+
</Callout>
|
|
31
|
+
|
|
32
|
+
## What you get
|
|
33
|
+
|
|
34
|
+
You write TypeScript. At build time OKE extracts a **Manifest** — a machine-readable description of your system. From that Manifest the rest is **derived**, not configured by hand:
|
|
35
|
+
|
|
36
|
+
- Typed client (no separate codegen step to maintain)
|
|
37
|
+
- OpenAPI / docs surfaces
|
|
38
|
+
- Architecture diagram that _is_ the effect graph
|
|
39
|
+
- Console panels, traces, and explorers
|
|
40
|
+
- MCP surface for agents (`:6535`)
|
|
41
|
+
- Least-privilege capability matrix and cache invalidation keys
|
|
42
|
+
|
|
43
|
+
## Ten exports
|
|
44
|
+
|
|
45
|
+
The entire public vocabulary fits in one import:
|
|
46
|
+
|
|
47
|
+
```ts title="okengine"
|
|
48
|
+
import { on, flow, signal, store, clock, gate, vault, channel, ai, plugin } from "okengine";
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
| Export | Role |
|
|
52
|
+
| --------- | ----------------------------------------------- |
|
|
53
|
+
| `on` | Bind a trigger to a flow |
|
|
54
|
+
| `flow` | Define behavior + contracts |
|
|
55
|
+
| `signal` | Data in motion (queue / pub-sub / live) |
|
|
56
|
+
| `store` | Data at rest (`sql` · `kv` · `files` · `index`) |
|
|
57
|
+
| `clock` | Time (cron, delay, sleep, TTL) |
|
|
58
|
+
| `gate` | Permission to act (auth, ABAC, limits) |
|
|
59
|
+
| `vault` | Secrets and config |
|
|
60
|
+
| `channel` | Reach humans (email, SMS, …) |
|
|
61
|
+
| `ai` | Reach models / agents |
|
|
62
|
+
| `plugin` | Extend the runtime without a ninth element |
|
|
63
|
+
|
|
64
|
+
Everything else in the docs is derived from these ten names.
|
|
65
|
+
|
|
66
|
+
## The eight elements
|
|
67
|
+
|
|
68
|
+
Everything a backend has ever needed reduces to eight typed elements. An element earns its place only if it has **irreducible physics**. New infrastructure becomes a new **driver** for an existing element — never a ninth element.
|
|
69
|
+
|
|
70
|
+
<Features />
|
|
71
|
+
|
|
72
|
+
<details>
|
|
73
|
+
<summary>What each element replaces</summary>
|
|
74
|
+
|
|
75
|
+
| Element | Replaces the zoo of |
|
|
76
|
+
| ----------- | --------------------------------------------------------- |
|
|
77
|
+
| **Flow** | endpoint · handler · consumer · job · workflow · webhook |
|
|
78
|
+
| **Signal** | queue · pub/sub · stream · websocket · SSE · event bus |
|
|
79
|
+
| **Store** | database · cache · KV · file storage · search index |
|
|
80
|
+
| **Clock** | cron · delay · timeout · durable sleep · TTL |
|
|
81
|
+
| **Gate** | auth · session · ABAC · rate limit · quota · feature flag |
|
|
82
|
+
| **Vault** | secrets · config · environment |
|
|
83
|
+
| **Channel** | email · SMS · WhatsApp · push |
|
|
84
|
+
| **AI** | model calls · prompts · embeddings · agents · RAG |
|
|
85
|
+
|
|
86
|
+
</details>
|
|
87
|
+
|
|
88
|
+
## The `fx` rule
|
|
89
|
+
|
|
90
|
+
**All world access goes through `fx`.** A Flow that imports `node:fs` (or any other side-channel I/O) is a defect.
|
|
91
|
+
|
|
92
|
+
That single rule is why cache invalidation, live queries, least privilege, deterministic tests, and Manifest Diff can be **inferred** instead of annotated by hand. You will see `fx` in every example from here on.
|
|
93
|
+
|
|
94
|
+
## Where to go next
|
|
95
|
+
|
|
96
|
+
Read in this order if you are new:
|
|
97
|
+
|
|
98
|
+
1. [Comparison](/docs/get-started/comparison) — when OKE fits (and when it doesn't)
|
|
99
|
+
2. [Installation](/docs/get-started/installation) — scaffold an app in minutes
|
|
100
|
+
3. [Basic Usage](/docs/get-started/basic-usage) — first flows, client, and tests
|
|
101
|
+
4. [Flow](/docs/elements/flow) — triggers, contracts, effects, and composition
|
|
102
|
+
|
|
103
|
+
<Cards>
|
|
104
|
+
<Card
|
|
105
|
+
title="Comparison"
|
|
106
|
+
description="Positioning matrix against Hono, Elysia, Encore.ts, and iii."
|
|
107
|
+
href="/docs/get-started/comparison"
|
|
108
|
+
/>
|
|
109
|
+
<Card
|
|
110
|
+
title="Installation"
|
|
111
|
+
description="Install okengine and scaffold with create-oke."
|
|
112
|
+
href="/docs/get-started/installation"
|
|
113
|
+
/>
|
|
114
|
+
<Card
|
|
115
|
+
title="Basic Usage"
|
|
116
|
+
description="Flows, typed client, and tests from the Notes example."
|
|
117
|
+
href="/docs/get-started/basic-usage"
|
|
118
|
+
/>
|
|
119
|
+
</Cards>
|
|
120
|
+
|
|
121
|
+
## AI resources
|
|
122
|
+
|
|
123
|
+
`AGENTS.md` and MCP (`:6535`) expose the Manifest, schemas, effects, traces, and the Console's safe runtime actions. See [MCP](/docs/ai/mcp) for the runtime server, [Skills](/docs/ai/skills) for the agent contract, and [llms.txt](/docs/ai/llms-txt) for the machine-readable docs (`/llms.txt`, `/llms-full.txt`).
|