okengine 0.2.6 → 0.2.8
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 +24 -23
- package/README.md +52 -346
- package/docs/spec/console.md +165 -142
- package/docs/spec/example.md +490 -312
- package/docs/spec/four-applications.md +495 -314
- package/docs/spec/unified-theory.md +184 -175
- package/package.json +45 -37
- package/spec/manifest.v1.schema.json +40 -9
- package/src/auth/api-keys.ts +2 -5
- package/src/auth/attenuation.ts +2 -6
- package/src/auth/auth.test.ts +53 -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 +386 -0
- package/src/cli/dev-app-runner.ts +2 -8
- package/src/cli/dev-db-push.test.ts +163 -0
- package/src/cli/dev-mode.test.ts +45 -0
- package/src/cli/dev-mode.ts +78 -0
- package/src/cli/dev.test.ts +148 -21
- package/src/cli/dev.ts +208 -134
- package/src/cli/doc-drift.test.ts +3 -2
- package/src/cli/doc-drift.ts +21 -50
- package/src/cli/doc-staleness.test.ts +69 -0
- package/src/cli/docker-cli.test.ts +7 -8
- package/src/cli/docker.ts +1 -3
- package/src/cli/doctor-diff-examples.ts +1 -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/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 +41 -47
- package/src/cli/mcp-from-console.ts +1 -4
- package/src/cli/mode.ts +45 -0
- package/src/cli/ports.test.ts +4 -13
- package/src/cli/ports.ts +1 -3
- package/src/cli/privacy-erase.ts +1 -3
- package/src/cli/registry.ts +75 -25
- package/src/cli/schema.ts +3 -10
- package/src/cli/stack.ts +2 -7
- package/src/cli/start.ts +4 -15
- package/src/cli/upgrade.ts +1 -4
- 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 +8 -29
- 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 +96 -30
- package/src/compiler/extract.ts +362 -156
- package/src/compiler/fixtures/skyport/oke.config.ts +1 -1
- 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 +4 -7
- package/src/compiler/sucrose.ts +11 -31
- package/src/config/define-config.test.ts +57 -34
- package/src/config/index.ts +181 -37
- 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 +14 -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 +23 -60
- 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 +112 -20
- package/src/docker/derive.ts +5 -19
- package/src/docker/docker.test.ts +15 -15
- package/src/docker/dockerfile.integration.test.ts +12 -21
- package/src/docker/helpers.ts +5 -4
- package/src/docker/index.ts +4 -11
- package/src/docker/pin.ts +1 -9
- package/src/docker/recipes/index.ts +5 -6
- package/src/docker/recipes/mailpit.ts +22 -0
- package/src/docker/recipes/postgres.ts +17 -6
- package/src/docker/recipes/redis.ts +6 -1
- package/src/docker/recipes/rustfs.ts +33 -0
- package/src/docker/stack-id.test.ts +33 -0
- package/src/docker/stack-id.ts +25 -13
- package/src/docker/stack.integration.test.ts +6 -21
- package/src/docker/types.ts +13 -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/fs.ts +2 -8
- package/src/drivers/index.ts +12 -56
- package/src/drivers/memory.ts +14 -41
- 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 +5 -17
- 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-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.ts +1 -5
- package/src/drivers/vault-sops.ts +10 -35
- package/src/drivers/vault-types.ts +1 -7
- 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 +8 -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/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.ts +11 -21
- package/src/elements/store/sql-session.test.ts +50 -0
- package/src/elements/store/sql-session.ts +60 -63
- package/src/elements/store/table.ts +35 -19
- package/src/elements/store.test.ts +17 -39
- package/src/elements/store.ts +37 -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 +18 -32
- package/src/elements/vault.test.ts +12 -28
- package/src/elements/vault.ts +8 -12
- package/src/index.ts +5 -2
- package/src/kernel/adopt-routes.ts +15 -29
- package/src/kernel/app.ts +34 -94
- package/src/kernel/auth-resolve.ts +2 -9
- package/src/kernel/boot-bind/ai.ts +1 -4
- package/src/kernel/boot-bind/channel.ts +2 -8
- 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 +17 -17
- package/src/kernel/boot-bind/store.ts +44 -50
- package/src/kernel/boot-bind/vault.ts +2 -8
- package/src/kernel/boot.test.ts +4 -9
- package/src/kernel/boot.ts +29 -76
- 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/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 +5 -25
- package/src/kernel/fx.test.ts +15 -44
- package/src/kernel/fx.ts +27 -79
- package/src/kernel/hook-timing.test.ts +3 -6
- package/src/kernel/hook-timing.ts +5 -14
- package/src/kernel/hooks.test.ts +10 -10
- package/src/kernel/hooks.ts +3 -12
- package/src/kernel/index.ts +4 -17
- package/src/kernel/journal.ts +7 -31
- package/src/kernel/on.ts +1 -6
- 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 +48 -24
- package/src/kernel/registry.ts +80 -29
- 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 +4 -21
- package/src/manifest/diff.test.ts +26 -91
- package/src/manifest/diff.ts +95 -225
- package/src/manifest/index.ts +2 -9
- package/src/manifest/types.ts +29 -5
- 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 +4 -14
- 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/node-import-scan.ts +2 -5
- 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 +15 -43
- 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 +13 -31
- 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/src/console/ui/dist/assets/panel-vault-BbfWdox0.js +0 -1
package/src/config/index.ts
CHANGED
|
@@ -8,12 +8,15 @@
|
|
|
8
8
|
/**
|
|
9
9
|
* Environment role keys used in driver maps.
|
|
10
10
|
*
|
|
11
|
-
* - `
|
|
12
|
-
* - `
|
|
11
|
+
* - `local` — laptop defaults (`oke dev` / `oke dev -l`)
|
|
12
|
+
* - `docker` — compose infra + host Bun (`oke dev -d`)
|
|
13
13
|
* - `test` — automated tests
|
|
14
14
|
* - `prod` — production deploy
|
|
15
15
|
*/
|
|
16
|
-
export type ConfigEnv = "
|
|
16
|
+
export type ConfigEnv = "local" | "docker" | "test" | "prod";
|
|
17
|
+
|
|
18
|
+
/** Legacy driver-map keys accepted during soft-compat migration. */
|
|
19
|
+
type LegacyConfigEnv = "dev" | "stack";
|
|
17
20
|
|
|
18
21
|
/** Pool options for SQL drivers. */
|
|
19
22
|
export interface DriverPoolOptions {
|
|
@@ -38,6 +41,12 @@ export type DriverRef =
|
|
|
38
41
|
/** Map of env → driver ref. */
|
|
39
42
|
export type EnvDriverMap = Partial<Record<ConfigEnv, DriverRef>>;
|
|
40
43
|
|
|
44
|
+
/**
|
|
45
|
+
* Raw map that may still use deprecated `dev` / `stack` keys.
|
|
46
|
+
* Normalized by {@link normalizeEnvDriverMap}.
|
|
47
|
+
*/
|
|
48
|
+
export type RawEnvDriverMap = Partial<Record<ConfigEnv | LegacyConfigEnv, DriverRef>>;
|
|
49
|
+
|
|
41
50
|
/** Store facet driver maps. */
|
|
42
51
|
export interface StoreDriversConfig {
|
|
43
52
|
readonly sql?: EnvDriverMap;
|
|
@@ -92,9 +101,7 @@ export interface TenancyResolveContext {
|
|
|
92
101
|
export interface TenancyConfig {
|
|
93
102
|
readonly isolation?: "row" | "schema" | "database";
|
|
94
103
|
/** Tenant resolver — opaque string id or function (Skyport). */
|
|
95
|
-
readonly resolve?:
|
|
96
|
-
| string
|
|
97
|
-
| ((ctx: TenancyResolveContext) => string | null | undefined);
|
|
104
|
+
readonly resolve?: string | ((ctx: TenancyResolveContext) => string | null | undefined);
|
|
98
105
|
}
|
|
99
106
|
|
|
100
107
|
/** Port overrides (defaults: app 6530 · console 6533 · mcp 6535). */
|
|
@@ -126,6 +133,42 @@ export interface RunsConfig {
|
|
|
126
133
|
*/
|
|
127
134
|
export type PrivacyConfig = Readonly<Record<string, unknown>>;
|
|
128
135
|
|
|
136
|
+
/**
|
|
137
|
+
* Domain schema sync via drizzle-kit (`oke db push|generate|migrate`).
|
|
138
|
+
*
|
|
139
|
+
* Distinct from `oke schema generate` (core/plugin stub tables).
|
|
140
|
+
*/
|
|
141
|
+
export interface DbConfig {
|
|
142
|
+
/**
|
|
143
|
+
* Auto-run `oke db push` when domain schema files change under `oke dev`
|
|
144
|
+
* (local mode only). Default `true`. Set `false` to opt out explicitly.
|
|
145
|
+
* Forced off for `docker` / `prod`.
|
|
146
|
+
*/
|
|
147
|
+
readonly autoPush?: boolean;
|
|
148
|
+
/**
|
|
149
|
+
* Path to `drizzle.config.ts` (relative to project root).
|
|
150
|
+
* Default `"drizzle.config.ts"`.
|
|
151
|
+
*/
|
|
152
|
+
readonly config?: string;
|
|
153
|
+
/**
|
|
154
|
+
* Abstract schema declare module (`store.schema.table` exports).
|
|
155
|
+
* When present, `oke db` emits Drizzle into {@link generated} before sync.
|
|
156
|
+
* Default `"src/schema.decl.ts"` (emit skipped if the file is absent).
|
|
157
|
+
*/
|
|
158
|
+
readonly declare?: string;
|
|
159
|
+
/**
|
|
160
|
+
* Generated Drizzle schema path written from abstract decls.
|
|
161
|
+
* Default `"src/schema.generated.ts"`. Point `drizzle.config.ts` `schema`
|
|
162
|
+
* at this file when using the abstract path.
|
|
163
|
+
*/
|
|
164
|
+
readonly generated?: string;
|
|
165
|
+
/**
|
|
166
|
+
* App entry used to collect live `.plug()` table contributions for emit.
|
|
167
|
+
* Default: `package.json` `okengine.entry` / `src/app.ts` (same as `oke start`).
|
|
168
|
+
*/
|
|
169
|
+
readonly entry?: string;
|
|
170
|
+
}
|
|
171
|
+
|
|
129
172
|
/**
|
|
130
173
|
* Application config returned by {@link defineConfig}.
|
|
131
174
|
*/
|
|
@@ -144,108 +187,209 @@ export interface OkeConfig {
|
|
|
144
187
|
* Not the same key as `drivers.runs`.
|
|
145
188
|
*/
|
|
146
189
|
readonly runs?: RunsConfig;
|
|
190
|
+
/**
|
|
191
|
+
* Domain Drizzle schema sync (`oke db …`). Not related to `oke schema`.
|
|
192
|
+
*/
|
|
193
|
+
readonly db?: DbConfig;
|
|
147
194
|
readonly topology?: "monolith" | "services";
|
|
148
195
|
readonly ports?: PortsConfig;
|
|
149
196
|
readonly console?: ConsoleConfig;
|
|
150
197
|
}
|
|
151
198
|
|
|
152
199
|
/**
|
|
153
|
-
*
|
|
200
|
+
* Whether domain auto-DDL (`ensureFromMeta`) should run for this env.
|
|
201
|
+
*
|
|
202
|
+
* - `ensure` — `CREATE TABLE IF NOT EXISTS` on first touch (test / local opt-out)
|
|
203
|
+
* - `off` — migrations / `oke db push` own DDL (docker, prod, local+autoPush)
|
|
204
|
+
*/
|
|
205
|
+
export type DomainDdlMode = "ensure" | "off";
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Resolve domain DDL policy from env + `db.autoPush`.
|
|
209
|
+
*
|
|
210
|
+
* @param env - Active config env
|
|
211
|
+
* @param autoPush - Effective auto-push flag (default true)
|
|
212
|
+
*/
|
|
213
|
+
export function resolveDomainDdlMode(env: ConfigEnv, autoPush = true): DomainDdlMode {
|
|
214
|
+
if (env === "test") return "ensure";
|
|
215
|
+
if (env === "docker" || env === "prod") return "off";
|
|
216
|
+
return autoPush ? "off" : "ensure";
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/** Whether a legacy-key deprecation warning was already emitted this process. */
|
|
220
|
+
let legacyKeyWarned = false;
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Normalize deprecated `dev`/`stack` driver-map keys to `local`/`docker`.
|
|
224
|
+
*
|
|
225
|
+
* Emits a one-time stderr warning when legacy keys are present.
|
|
226
|
+
*
|
|
227
|
+
* @param raw - Env → driver map (possibly legacy keys)
|
|
228
|
+
*/
|
|
229
|
+
export function normalizeEnvDriverMap(
|
|
230
|
+
raw: RawEnvDriverMap | EnvDriverMap | undefined,
|
|
231
|
+
): EnvDriverMap | undefined {
|
|
232
|
+
if (!raw) return undefined;
|
|
233
|
+
const hasLegacy =
|
|
234
|
+
(raw as RawEnvDriverMap).dev !== undefined || (raw as RawEnvDriverMap).stack !== undefined;
|
|
235
|
+
if (hasLegacy && !legacyKeyWarned) {
|
|
236
|
+
legacyKeyWarned = true;
|
|
237
|
+
console.warn(
|
|
238
|
+
"oke: driver map keys `dev`/`stack` are deprecated — use `local`/`docker` (run `oke upgrade`)",
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
const out: EnvDriverMap = { ...(raw as EnvDriverMap) };
|
|
242
|
+
const legacy = raw as RawEnvDriverMap;
|
|
243
|
+
if (legacy.local === undefined && legacy.dev !== undefined) {
|
|
244
|
+
out.local = legacy.dev;
|
|
245
|
+
}
|
|
246
|
+
if (legacy.docker === undefined && legacy.stack !== undefined) {
|
|
247
|
+
out.docker = legacy.stack;
|
|
248
|
+
}
|
|
249
|
+
delete (out as RawEnvDriverMap).dev;
|
|
250
|
+
delete (out as RawEnvDriverMap).stack;
|
|
251
|
+
return out;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Normalize every env map under a drivers block.
|
|
154
256
|
*
|
|
155
|
-
*
|
|
156
|
-
|
|
257
|
+
* @param drivers - Drivers block
|
|
258
|
+
*/
|
|
259
|
+
export function normalizeDriversConfig(
|
|
260
|
+
drivers: DriversConfig | undefined,
|
|
261
|
+
): DriversConfig | undefined {
|
|
262
|
+
if (!drivers) return undefined;
|
|
263
|
+
const store = drivers.store
|
|
264
|
+
? {
|
|
265
|
+
...drivers.store,
|
|
266
|
+
sql: normalizeEnvDriverMap(drivers.store.sql as RawEnvDriverMap),
|
|
267
|
+
kv: normalizeEnvDriverMap(drivers.store.kv as RawEnvDriverMap),
|
|
268
|
+
files: normalizeEnvDriverMap(drivers.store.files as RawEnvDriverMap),
|
|
269
|
+
index: normalizeEnvDriverMap(drivers.store.index as RawEnvDriverMap),
|
|
270
|
+
}
|
|
271
|
+
: undefined;
|
|
272
|
+
const channel = drivers.channel
|
|
273
|
+
? {
|
|
274
|
+
...drivers.channel,
|
|
275
|
+
email: normalizeEnvDriverMap(drivers.channel.email as RawEnvDriverMap),
|
|
276
|
+
sms: normalizeEnvDriverMap(drivers.channel.sms as RawEnvDriverMap),
|
|
277
|
+
whatsapp: normalizeEnvDriverMap(drivers.channel.whatsapp as RawEnvDriverMap),
|
|
278
|
+
push: normalizeEnvDriverMap(drivers.channel.push as RawEnvDriverMap),
|
|
279
|
+
}
|
|
280
|
+
: undefined;
|
|
281
|
+
return {
|
|
282
|
+
...drivers,
|
|
283
|
+
...(store !== undefined ? { store } : {}),
|
|
284
|
+
signal: normalizeEnvDriverMap(drivers.signal as RawEnvDriverMap),
|
|
285
|
+
clock: normalizeEnvDriverMap(drivers.clock as RawEnvDriverMap),
|
|
286
|
+
vault: normalizeEnvDriverMap(drivers.vault as RawEnvDriverMap),
|
|
287
|
+
...(channel !== undefined ? { channel } : {}),
|
|
288
|
+
ai: normalizeEnvDriverMap(drivers.ai as RawEnvDriverMap),
|
|
289
|
+
runs: normalizeEnvDriverMap(drivers.runs as RawEnvDriverMap),
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Fill missing `docker` pins from `prod` (compose infra ≈ production protocols).
|
|
295
|
+
*
|
|
296
|
+
* Vault is the exception: `prod: "sops"` becomes `docker: "dotenv"` so
|
|
297
|
+
* `oke dev -d` can read `docker/.env.docker` without age keys.
|
|
157
298
|
*
|
|
158
299
|
* @param map - Env → driver map
|
|
159
300
|
* @param options - Element-specific defaults
|
|
160
301
|
*/
|
|
161
|
-
export function
|
|
302
|
+
export function fillDockerFromProd(
|
|
162
303
|
map: EnvDriverMap | undefined,
|
|
163
304
|
options: { readonly vault?: boolean } = {},
|
|
164
305
|
): EnvDriverMap | undefined {
|
|
165
306
|
if (!map) return undefined;
|
|
166
|
-
if (map.
|
|
307
|
+
if (map.docker !== undefined || map.prod === undefined) return map;
|
|
167
308
|
if (options.vault) {
|
|
168
309
|
const prodId = typeof map.prod === "string" ? map.prod : map.prod.driver;
|
|
169
310
|
if (prodId === "sops") {
|
|
170
|
-
return { ...map,
|
|
311
|
+
return { ...map, docker: "dotenv" };
|
|
171
312
|
}
|
|
172
313
|
}
|
|
173
|
-
return { ...map,
|
|
314
|
+
return { ...map, docker: map.prod };
|
|
174
315
|
}
|
|
175
316
|
|
|
176
317
|
/**
|
|
177
|
-
* Copy production driver pins onto `
|
|
318
|
+
* Copy production driver pins onto `docker` wherever `docker` is omitted.
|
|
178
319
|
*
|
|
179
320
|
* @param drivers - Drivers block
|
|
180
321
|
*/
|
|
181
|
-
export function
|
|
322
|
+
export function fillDriversDockerFromProd(
|
|
182
323
|
drivers: DriversConfig | undefined,
|
|
183
324
|
): DriversConfig | undefined {
|
|
184
325
|
if (!drivers) return undefined;
|
|
185
326
|
const store = drivers.store
|
|
186
327
|
? {
|
|
187
328
|
...drivers.store,
|
|
188
|
-
sql:
|
|
189
|
-
kv:
|
|
190
|
-
files:
|
|
191
|
-
index:
|
|
329
|
+
sql: fillDockerFromProd(drivers.store.sql),
|
|
330
|
+
kv: fillDockerFromProd(drivers.store.kv),
|
|
331
|
+
files: fillDockerFromProd(drivers.store.files),
|
|
332
|
+
index: fillDockerFromProd(drivers.store.index),
|
|
192
333
|
}
|
|
193
334
|
: undefined;
|
|
194
335
|
const channel = drivers.channel
|
|
195
336
|
? {
|
|
196
337
|
...drivers.channel,
|
|
197
|
-
email:
|
|
198
|
-
sms:
|
|
199
|
-
whatsapp:
|
|
200
|
-
push:
|
|
338
|
+
email: fillDockerFromProd(drivers.channel.email),
|
|
339
|
+
sms: fillDockerFromProd(drivers.channel.sms),
|
|
340
|
+
whatsapp: fillDockerFromProd(drivers.channel.whatsapp),
|
|
341
|
+
push: fillDockerFromProd(drivers.channel.push),
|
|
201
342
|
}
|
|
202
343
|
: undefined;
|
|
203
344
|
return {
|
|
204
345
|
...drivers,
|
|
205
346
|
...(store !== undefined ? { store } : {}),
|
|
206
|
-
signal:
|
|
207
|
-
clock:
|
|
208
|
-
vault:
|
|
347
|
+
signal: fillDockerFromProd(drivers.signal),
|
|
348
|
+
clock: fillDockerFromProd(drivers.clock),
|
|
349
|
+
vault: fillDockerFromProd(drivers.vault, { vault: true }),
|
|
209
350
|
...(channel !== undefined ? { channel } : {}),
|
|
210
|
-
ai:
|
|
211
|
-
runs:
|
|
351
|
+
ai: fillDockerFromProd(drivers.ai),
|
|
352
|
+
runs: fillDockerFromProd(drivers.runs),
|
|
212
353
|
};
|
|
213
354
|
}
|
|
214
355
|
|
|
215
356
|
/**
|
|
216
357
|
* Define an `oke.config.ts` document.
|
|
217
358
|
*
|
|
218
|
-
* Missing `
|
|
219
|
-
* same server protocols as production (vault → dotenv for
|
|
359
|
+
* Missing `docker` driver pins are filled from `prod` so `oke dev -d` uses the
|
|
360
|
+
* same server protocols as production (vault → dotenv for `docker/.env.docker`).
|
|
361
|
+
* Legacy `dev`/`stack` keys are normalized to `local`/`docker`.
|
|
220
362
|
*
|
|
221
363
|
* @param config - Driver / tenancy / i18n / topology
|
|
222
364
|
*/
|
|
223
365
|
export function defineConfig(config: OkeConfig): OkeConfig {
|
|
224
366
|
if (!config.drivers) return config;
|
|
367
|
+
const normalized = normalizeDriversConfig(config.drivers);
|
|
225
368
|
return {
|
|
226
369
|
...config,
|
|
227
|
-
drivers:
|
|
370
|
+
drivers: fillDriversDockerFromProd(normalized),
|
|
228
371
|
};
|
|
229
372
|
}
|
|
230
373
|
|
|
231
374
|
/**
|
|
232
375
|
* Resolve a driver id for an env from an {@link EnvDriverMap}.
|
|
233
376
|
*
|
|
234
|
-
* `
|
|
235
|
-
* until an explicit `
|
|
377
|
+
* `docker` falls back to `prod` then `local` so existing configs keep working
|
|
378
|
+
* until an explicit `docker:` pin is added. Legacy keys are normalized first.
|
|
236
379
|
*
|
|
237
380
|
* @param map - Env → driver map
|
|
238
381
|
* @param env - Active environment
|
|
239
382
|
*/
|
|
240
383
|
export function resolveDriverId(
|
|
241
|
-
map: EnvDriverMap | undefined,
|
|
384
|
+
map: EnvDriverMap | RawEnvDriverMap | undefined,
|
|
242
385
|
env: ConfigEnv,
|
|
243
386
|
): string | undefined {
|
|
244
387
|
if (!map) return undefined;
|
|
388
|
+
const normalized = normalizeEnvDriverMap(map as RawEnvDriverMap) ?? map;
|
|
245
389
|
const ref =
|
|
246
|
-
env === "
|
|
247
|
-
? (
|
|
248
|
-
: (
|
|
390
|
+
env === "docker"
|
|
391
|
+
? (normalized.docker ?? normalized.prod ?? normalized.local ?? normalized.test)
|
|
392
|
+
: (normalized[env] ?? normalized.local ?? normalized.test);
|
|
249
393
|
if (ref === undefined) return undefined;
|
|
250
394
|
return typeof ref === "string" ? ref : ref.driver;
|
|
251
395
|
}
|
|
@@ -1,30 +1,41 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Driver map resolution — including `
|
|
2
|
+
* Driver map resolution — including `docker` → prod fallback.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { describe, expect, test } from "bun:test";
|
|
6
|
-
import { resolveDriverId } from "./index.ts";
|
|
6
|
+
import { resolveDomainDdlMode, resolveDriverId } from "./index.ts";
|
|
7
|
+
|
|
8
|
+
describe("resolveDomainDdlMode", () => {
|
|
9
|
+
test("test keeps ensure; docker/prod always off", () => {
|
|
10
|
+
expect(resolveDomainDdlMode("test", true)).toBe("ensure");
|
|
11
|
+
expect(resolveDomainDdlMode("docker", true)).toBe("off");
|
|
12
|
+
expect(resolveDomainDdlMode("prod", true)).toBe("off");
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
test("local follows autoPush", () => {
|
|
16
|
+
expect(resolveDomainDdlMode("local", true)).toBe("off");
|
|
17
|
+
expect(resolveDomainDdlMode("local", false)).toBe("ensure");
|
|
18
|
+
});
|
|
19
|
+
});
|
|
7
20
|
|
|
8
21
|
describe("resolveDriverId", () => {
|
|
9
22
|
test("reads the named env key", () => {
|
|
10
|
-
expect(
|
|
11
|
-
|
|
12
|
-
).toBe("sqlite");
|
|
13
|
-
expect(
|
|
14
|
-
resolveDriverId({ dev: "sqlite", prod: "postgres" }, "prod"),
|
|
15
|
-
).toBe("postgres");
|
|
23
|
+
expect(resolveDriverId({ local: "sqlite", prod: "postgres" }, "local")).toBe("sqlite");
|
|
24
|
+
expect(resolveDriverId({ local: "sqlite", prod: "postgres" }, "prod")).toBe("postgres");
|
|
16
25
|
});
|
|
17
26
|
|
|
18
|
-
test("
|
|
19
|
-
expect(
|
|
20
|
-
resolveDriverId(
|
|
21
|
-
{ dev: "sqlite", stack: "postgres", prod: "postgres" },
|
|
22
|
-
"stack",
|
|
23
|
-
),
|
|
24
|
-
).toBe("postgres");
|
|
27
|
+
test("docker prefers docker, then prod, then local", () => {
|
|
25
28
|
expect(
|
|
26
|
-
resolveDriverId({
|
|
29
|
+
resolveDriverId({ local: "sqlite", docker: "postgres", prod: "postgres" }, "docker"),
|
|
27
30
|
).toBe("postgres");
|
|
28
|
-
expect(resolveDriverId({
|
|
31
|
+
expect(resolveDriverId({ local: "sqlite", prod: "postgres" }, "docker")).toBe("postgres");
|
|
32
|
+
expect(resolveDriverId({ local: "sqlite" }, "docker")).toBe("sqlite");
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
test("legacy keys resolve after normalize", () => {
|
|
36
|
+
expect(resolveDriverId({ dev: "sqlite", stack: "postgres" } as never, "local")).toBe("sqlite");
|
|
37
|
+
expect(resolveDriverId({ dev: "sqlite", stack: "postgres" } as never, "docker")).toBe(
|
|
38
|
+
"postgres",
|
|
39
|
+
);
|
|
29
40
|
});
|
|
30
41
|
});
|
|
@@ -32,10 +32,7 @@ describe("console bundle budget", () => {
|
|
|
32
32
|
console.log(
|
|
33
33
|
"other (not initial, not panel-*):\n" +
|
|
34
34
|
breakdown.other
|
|
35
|
-
.map(
|
|
36
|
-
(a) =>
|
|
37
|
-
` ${a.name}: ${a.gzip} (${(a.gzip / 1024).toFixed(2)} kB)`,
|
|
38
|
-
)
|
|
35
|
+
.map((a) => ` ${a.name}: ${a.gzip} (${(a.gzip / 1024).toFixed(2)} kB)`)
|
|
39
36
|
.join("\n"),
|
|
40
37
|
);
|
|
41
38
|
}
|
package/src/console/index.ts
CHANGED
|
@@ -37,7 +37,4 @@ export {
|
|
|
37
37
|
type ConsoleServerHandle,
|
|
38
38
|
type ServeConsoleOptions,
|
|
39
39
|
} from "./server/serve.ts";
|
|
40
|
-
export {
|
|
41
|
-
createConsoleState,
|
|
42
|
-
type ConsoleState,
|
|
43
|
-
} from "./server/state.ts";
|
|
40
|
+
export { createConsoleState, type ConsoleState } from "./server/state.ts";
|
|
@@ -126,26 +126,14 @@ describe("projectAccessPanel", () => {
|
|
|
126
126
|
expect(projection.userPlane.operators).toBeUndefined();
|
|
127
127
|
|
|
128
128
|
// Cross-plane scopes absent from grantable lists.
|
|
129
|
-
expect(
|
|
130
|
-
projection.operatorPlane.grantableScopes.every((s) =>
|
|
131
|
-
s.startsWith("console:"),
|
|
132
|
-
),
|
|
133
|
-
).toBe(true);
|
|
134
|
-
expect(
|
|
135
|
-
projection.userPlane.grantableScopes.every(
|
|
136
|
-
(s) => !s.startsWith("console:"),
|
|
137
|
-
),
|
|
138
|
-
).toBe(true);
|
|
139
|
-
|
|
140
|
-
expect(projection.hygiene.unusedKeys.some((k) => k.id === "key_stale")).toBe(
|
|
129
|
+
expect(projection.operatorPlane.grantableScopes.every((s) => s.startsWith("console:"))).toBe(
|
|
141
130
|
true,
|
|
142
131
|
);
|
|
143
|
-
expect(
|
|
144
|
-
|
|
145
|
-
).toBe(true);
|
|
146
|
-
expect(
|
|
147
|
-
|
|
148
|
-
).toBe(true);
|
|
132
|
+
expect(projection.userPlane.grantableScopes.every((s) => !s.startsWith("console:"))).toBe(true);
|
|
133
|
+
|
|
134
|
+
expect(projection.hygiene.unusedKeys.some((k) => k.id === "key_stale")).toBe(true);
|
|
135
|
+
expect(projection.hygiene.neverSignedInOperators.some((o) => o.id === "op_never")).toBe(true);
|
|
136
|
+
expect(projection.hygiene.expiredInvitations.some((i) => i.id === "inv1")).toBe(true);
|
|
149
137
|
});
|
|
150
138
|
|
|
151
139
|
test("scope not held is not grantable (absence, not refusal)", () => {
|
|
@@ -163,12 +151,8 @@ describe("projectAccessPanel", () => {
|
|
|
163
151
|
now: () => 0,
|
|
164
152
|
});
|
|
165
153
|
expect(projection.userPlane.grantableScopes).not.toContain("booking:create");
|
|
166
|
-
expect(projection.operatorPlane.grantableScopes).toContain(
|
|
167
|
-
|
|
168
|
-
);
|
|
169
|
-
expect(projection.operatorPlane.grantableScopes).not.toContain(
|
|
170
|
-
"console:store.sql:write",
|
|
171
|
-
);
|
|
154
|
+
expect(projection.operatorPlane.grantableScopes).toContain("console:store.sql:read");
|
|
155
|
+
expect(projection.operatorPlane.grantableScopes).not.toContain("console:store.sql:write");
|
|
172
156
|
});
|
|
173
157
|
});
|
|
174
158
|
|
|
@@ -266,9 +250,7 @@ describe("keyBlastRadius", () => {
|
|
|
266
250
|
expect(blast.lastUsedAt).toBe(200);
|
|
267
251
|
expect(blast.sourceAddresses).toEqual(["198.51.100.7", "203.0.113.10"]);
|
|
268
252
|
expect(blast.accessTtlMs).toBe(ttl);
|
|
269
|
-
expect(blast.residualAccessNote).toBe(
|
|
270
|
-
residualAccessNote(ttl),
|
|
271
|
-
);
|
|
253
|
+
expect(blast.residualAccessNote).toBe(residualAccessNote(ttl));
|
|
272
254
|
expect(blast.residualAccessNote).toContain("7 minute");
|
|
273
255
|
});
|
|
274
256
|
});
|
|
@@ -331,22 +313,16 @@ describe("accessCreateKey / revoke", () => {
|
|
|
331
313
|
|
|
332
314
|
describe("helpers", () => {
|
|
333
315
|
test("expandAccessCeiling adds application scopes for console:*", () => {
|
|
334
|
-
const held = expandAccessCeiling(["console:*"], [
|
|
335
|
-
"console:store.sql:read",
|
|
336
|
-
"booking:create",
|
|
337
|
-
]);
|
|
316
|
+
const held = expandAccessCeiling(["console:*"], ["console:store.sql:read", "booking:create"]);
|
|
338
317
|
expect(held.has("console:store.sql:read")).toBe(true);
|
|
339
318
|
expect(held.has("booking:create")).toBe(true);
|
|
340
319
|
});
|
|
341
320
|
|
|
342
321
|
test("isKeyUnused90d", () => {
|
|
343
322
|
const now = () => 1_000_000 + KEY_UNUSED_MS;
|
|
344
|
-
expect(
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
now,
|
|
348
|
-
),
|
|
349
|
-
).toBe(true);
|
|
323
|
+
expect(isKeyUnused90d({ createdAt: 1_000_000, lastUsedAt: null, revokedAt: null }, now)).toBe(
|
|
324
|
+
true,
|
|
325
|
+
);
|
|
350
326
|
expect(
|
|
351
327
|
isKeyUnused90d(
|
|
352
328
|
{
|
|
@@ -360,11 +336,7 @@ describe("helpers", () => {
|
|
|
360
336
|
});
|
|
361
337
|
|
|
362
338
|
test("residualAccessNote uses config TTL, not a hardcoded 14", () => {
|
|
363
|
-
expect(residualAccessNote(60_000)).toBe(
|
|
364
|
-
|
|
365
|
-
);
|
|
366
|
-
expect(residualAccessNote(90_000)).toBe(
|
|
367
|
-
"Existing access may continue up to 2 minutes",
|
|
368
|
-
);
|
|
339
|
+
expect(residualAccessNote(60_000)).toBe("Existing access may continue up to 1 minute");
|
|
340
|
+
expect(residualAccessNote(90_000)).toBe("Existing access may continue up to 2 minutes");
|
|
369
341
|
});
|
|
370
342
|
});
|
|
@@ -180,9 +180,7 @@ export interface ProjectAccessOptions {
|
|
|
180
180
|
*
|
|
181
181
|
* @param options - Auth stores + actor ceiling
|
|
182
182
|
*/
|
|
183
|
-
export function projectAccessPanel(
|
|
184
|
-
options: ProjectAccessOptions,
|
|
185
|
-
): AccessPanelProjection {
|
|
183
|
+
export function projectAccessPanel(options: ProjectAccessOptions): AccessPanelProjection {
|
|
186
184
|
const now = options.now ?? (() => Date.now());
|
|
187
185
|
const accessTtlMs = options.accessTtlMs ?? ACCESS_TTL_MS;
|
|
188
186
|
const catalog = options.manifest
|
|
@@ -269,9 +267,7 @@ export function effectivePermissions(options: {
|
|
|
269
267
|
.sort((a, b) => a.localeCompare(b))
|
|
270
268
|
.map((scope) => ({
|
|
271
269
|
scope,
|
|
272
|
-
sources: [
|
|
273
|
-
{ kind: "direct" as const, id: key.id, name: key.name },
|
|
274
|
-
],
|
|
270
|
+
sources: [{ kind: "direct" as const, id: key.id, name: key.name }],
|
|
275
271
|
})),
|
|
276
272
|
};
|
|
277
273
|
}
|
|
@@ -288,9 +284,7 @@ export function effectivePermissions(options: {
|
|
|
288
284
|
plane: role.plane,
|
|
289
285
|
scopes: scopes.map((scope) => ({
|
|
290
286
|
scope,
|
|
291
|
-
sources: [
|
|
292
|
-
{ kind: "role" as const, id: role.id, name: role.name },
|
|
293
|
-
],
|
|
287
|
+
sources: [{ kind: "role" as const, id: role.id, name: role.name }],
|
|
294
288
|
})),
|
|
295
289
|
};
|
|
296
290
|
}
|
|
@@ -318,9 +312,7 @@ export function effectivePermissions(options: {
|
|
|
318
312
|
if (covered.has(scope)) continue;
|
|
319
313
|
scopes.push({
|
|
320
314
|
scope,
|
|
321
|
-
sources: [
|
|
322
|
-
{ kind: "direct" as const, id: identity.id, name: identity.name },
|
|
323
|
-
],
|
|
315
|
+
sources: [{ kind: "direct" as const, id: identity.id, name: identity.name }],
|
|
324
316
|
});
|
|
325
317
|
}
|
|
326
318
|
scopes.sort((a, b) => a.scope.localeCompare(b.scope));
|
|
@@ -412,9 +404,7 @@ export async function accessCreateKey(
|
|
|
412
404
|
for (const scope of input.scopes) {
|
|
413
405
|
if (!allowed.has(scope)) {
|
|
414
406
|
assertAttenuated(held, [scope], "api key");
|
|
415
|
-
throw new AccessGrantError(
|
|
416
|
-
`scope ${scope} is not grantable on the ${input.plane} plane`,
|
|
417
|
-
);
|
|
407
|
+
throw new AccessGrantError(`scope ${scope} is not grantable on the ${input.plane} plane`);
|
|
418
408
|
}
|
|
419
409
|
}
|
|
420
410
|
const created = await createApiKey(store, {
|
|
@@ -461,9 +451,7 @@ export function accessSetRoleGrants(options: {
|
|
|
461
451
|
);
|
|
462
452
|
for (const scope of options.scopes) {
|
|
463
453
|
if (!allowed.has(scope)) {
|
|
464
|
-
throw new AccessGrantError(
|
|
465
|
-
`scope ${scope} is not grantable on the ${role.plane} plane`,
|
|
466
|
-
);
|
|
454
|
+
throw new AccessGrantError(`scope ${scope} is not grantable on the ${role.plane} plane`);
|
|
467
455
|
}
|
|
468
456
|
}
|
|
469
457
|
setRoleGrants(options.roles, options.roleId, options.scopes);
|
|
@@ -565,15 +553,13 @@ export function expandAccessCeiling(
|
|
|
565
553
|
return out;
|
|
566
554
|
}
|
|
567
555
|
|
|
568
|
-
function projectOperators(
|
|
569
|
-
options: ProjectAccessOptions,
|
|
570
|
-
): AccessOperatorRow[] {
|
|
556
|
+
function projectOperators(options: ProjectAccessOptions): AccessOperatorRow[] {
|
|
571
557
|
const rows: AccessOperatorRow[] = [];
|
|
572
558
|
for (const op of options.operators.operators.values()) {
|
|
573
559
|
const roleIds = options.operators.roles.get(op.id) ?? [];
|
|
574
|
-
const scopes = [
|
|
575
|
-
|
|
576
|
-
|
|
560
|
+
const scopes = [...scopesForRoles(options.roles, roleIds, "operator")].sort((a, b) =>
|
|
561
|
+
a.localeCompare(b),
|
|
562
|
+
);
|
|
577
563
|
rows.push({
|
|
578
564
|
id: op.id,
|
|
579
565
|
email: op.email,
|
|
@@ -592,12 +578,10 @@ function projectUsers(options: ProjectAccessOptions): AccessUserRow[] {
|
|
|
592
578
|
return options.identities
|
|
593
579
|
.map((identity) => {
|
|
594
580
|
const roleIds = roleIdsForMember(options.roleMembers, identity.id);
|
|
595
|
-
const fromRoles = [
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
...new Set([...fromRoles, ...identity.scopes]),
|
|
600
|
-
].sort((a, b) => a.localeCompare(b));
|
|
581
|
+
const fromRoles = [...scopesForRoles(options.roles, roleIds, "user")];
|
|
582
|
+
const scopes = [...new Set([...fromRoles, ...identity.scopes])].sort((a, b) =>
|
|
583
|
+
a.localeCompare(b),
|
|
584
|
+
);
|
|
601
585
|
return {
|
|
602
586
|
id: identity.id,
|
|
603
587
|
email: identity.email,
|
|
@@ -618,19 +602,14 @@ function projectRoles(options: ProjectAccessOptions): AccessRoleRow[] {
|
|
|
618
602
|
name: role.name,
|
|
619
603
|
plane: role.plane,
|
|
620
604
|
description: role.description,
|
|
621
|
-
scopes: [...(options.roles.grants.get(role.id) ?? [])].sort((a, b) =>
|
|
622
|
-
a.localeCompare(b),
|
|
623
|
-
),
|
|
605
|
+
scopes: [...(options.roles.grants.get(role.id) ?? [])].sort((a, b) => a.localeCompare(b)),
|
|
624
606
|
memberCount: options.roleMembers.get(role.id)?.length ?? 0,
|
|
625
607
|
});
|
|
626
608
|
}
|
|
627
609
|
return rows.sort((a, b) => a.name.localeCompare(b.name));
|
|
628
610
|
}
|
|
629
611
|
|
|
630
|
-
function projectKeys(
|
|
631
|
-
options: ProjectAccessOptions,
|
|
632
|
-
now: () => number,
|
|
633
|
-
): AccessKeyRow[] {
|
|
612
|
+
function projectKeys(options: ProjectAccessOptions, now: () => number): AccessKeyRow[] {
|
|
634
613
|
const rows: AccessKeyRow[] = [];
|
|
635
614
|
for (const key of options.apiKeys.keys.values()) {
|
|
636
615
|
rows.push(toKeyRow(key, now));
|
|
@@ -638,10 +617,7 @@ function projectKeys(
|
|
|
638
617
|
return rows.sort((a, b) => a.name.localeCompare(b.name));
|
|
639
618
|
}
|
|
640
619
|
|
|
641
|
-
function projectInvites(
|
|
642
|
-
options: ProjectAccessOptions,
|
|
643
|
-
now: () => number,
|
|
644
|
-
): AccessInviteRow[] {
|
|
620
|
+
function projectInvites(options: ProjectAccessOptions, now: () => number): AccessInviteRow[] {
|
|
645
621
|
const rows: AccessInviteRow[] = [];
|
|
646
622
|
for (const invite of options.invites.invites.values()) {
|
|
647
623
|
rows.push({
|
|
@@ -714,10 +690,7 @@ function provenanceForRoles(
|
|
|
714
690
|
roleIds: readonly string[],
|
|
715
691
|
plane: "user" | "operator",
|
|
716
692
|
): AccessScopeProvenance[] {
|
|
717
|
-
const byScope = new Map<
|
|
718
|
-
string,
|
|
719
|
-
{ kind: "role"; id: string; name: string }[]
|
|
720
|
-
>();
|
|
693
|
+
const byScope = new Map<string, { kind: "role"; id: string; name: string }[]>();
|
|
721
694
|
for (const roleId of roleIds) {
|
|
722
695
|
const role = roles.roles.get(roleId);
|
|
723
696
|
if (!role || role.plane !== plane) continue;
|
|
@@ -762,10 +735,7 @@ function sourceAddressOf(run: WideEvent): string | null {
|
|
|
762
735
|
return null;
|
|
763
736
|
}
|
|
764
737
|
|
|
765
|
-
function collectCatalogFromStores(
|
|
766
|
-
roles: RoleStore,
|
|
767
|
-
apiKeys: ApiKeyStore,
|
|
768
|
-
): string[] {
|
|
738
|
+
function collectCatalogFromStores(roles: RoleStore, apiKeys: ApiKeyStore): string[] {
|
|
769
739
|
const set = new Set<string>();
|
|
770
740
|
for (const grants of roles.grants.values()) {
|
|
771
741
|
for (const g of grants) set.add(g);
|