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/kernel/hooks.ts
CHANGED
|
@@ -40,9 +40,7 @@ export const BEFORE_HANDLER_STAGES: readonly HookStage[] = [
|
|
|
40
40
|
] as const;
|
|
41
41
|
|
|
42
42
|
/** Stages that run after a successful handler (before onResponse). */
|
|
43
|
-
export const AFTER_HANDLER_STAGES: readonly HookStage[] = [
|
|
44
|
-
"afterHandle",
|
|
45
|
-
] as const;
|
|
43
|
+
export const AFTER_HANDLER_STAGES: readonly HookStage[] = ["afterHandle"] as const;
|
|
46
44
|
|
|
47
45
|
/** All user-registrable stages in pipeline order. */
|
|
48
46
|
export const HOOK_STAGES: readonly HookStage[] = [
|
|
@@ -97,11 +95,7 @@ export type HookFn = (
|
|
|
97
95
|
ctx: InvocationContext,
|
|
98
96
|
fxOrErr: Fx | unknown,
|
|
99
97
|
fx?: Fx,
|
|
100
|
-
) =>
|
|
101
|
-
| void
|
|
102
|
-
| Response
|
|
103
|
-
| FlowFailure
|
|
104
|
-
| Promise<void | Response | FlowFailure>;
|
|
98
|
+
) => void | Response | FlowFailure | Promise<void | Response | FlowFailure>;
|
|
105
99
|
|
|
106
100
|
/** Hook bag keyed by stage. */
|
|
107
101
|
export type HookMap = Partial<Record<HookStage, HookFn[]>>;
|
|
@@ -247,10 +241,7 @@ async function runStage(
|
|
|
247
241
|
const started = pluginId !== undefined ? performance.now() : 0;
|
|
248
242
|
try {
|
|
249
243
|
// Spec apps use `.hook("onError", (ctx, err, fx) => …)`.
|
|
250
|
-
returned =
|
|
251
|
-
stage === "onError"
|
|
252
|
-
? await fn(ctx, ctx.error, fx)
|
|
253
|
-
: await fn(ctx, fx);
|
|
244
|
+
returned = stage === "onError" ? await fn(ctx, ctx.error, fx) : await fn(ctx, fx);
|
|
254
245
|
} catch (err) {
|
|
255
246
|
if (pluginId !== undefined) {
|
|
256
247
|
recordHookCost(pluginId, stage, performance.now() - started);
|
package/src/kernel/index.ts
CHANGED
|
@@ -50,11 +50,7 @@ export type {
|
|
|
50
50
|
RoutesFromAdoptArgs,
|
|
51
51
|
} from "./adopt-routes.ts";
|
|
52
52
|
|
|
53
|
-
export {
|
|
54
|
-
createCapabilityToken,
|
|
55
|
-
effectsFieldOf,
|
|
56
|
-
type CapabilityToken,
|
|
57
|
-
} from "./capability.ts";
|
|
53
|
+
export { createCapabilityToken, effectsFieldOf, type CapabilityToken } from "./capability.ts";
|
|
58
54
|
|
|
59
55
|
export {
|
|
60
56
|
createEffectLedger,
|
|
@@ -181,12 +177,7 @@ export {
|
|
|
181
177
|
type HookCostSummary,
|
|
182
178
|
} from "./hook-timing.ts";
|
|
183
179
|
|
|
184
|
-
export {
|
|
185
|
-
listBindings,
|
|
186
|
-
on,
|
|
187
|
-
resetBindings,
|
|
188
|
-
type Binding,
|
|
189
|
-
} from "./on.ts";
|
|
180
|
+
export { listBindings, on, resetBindings, type Binding } from "./on.ts";
|
|
190
181
|
|
|
191
182
|
export {
|
|
192
183
|
isPlugin,
|
|
@@ -205,6 +196,7 @@ export {
|
|
|
205
196
|
type PluginOptions,
|
|
206
197
|
type PluginRegistration,
|
|
207
198
|
type TableContribution,
|
|
199
|
+
type PluginTableOptions,
|
|
208
200
|
} from "./plugin.ts";
|
|
209
201
|
|
|
210
202
|
export {
|
|
@@ -270,11 +262,6 @@ export {
|
|
|
270
262
|
type JourneySlo,
|
|
271
263
|
} from "./journey.ts";
|
|
272
264
|
|
|
273
|
-
export {
|
|
274
|
-
unit,
|
|
275
|
-
consumeUnitPlugins,
|
|
276
|
-
resetUnitPlugins,
|
|
277
|
-
type UnitBag,
|
|
278
|
-
} from "./unit.ts";
|
|
265
|
+
export { unit, consumeUnitPlugins, resetUnitPlugins, type UnitBag } from "./unit.ts";
|
|
279
266
|
|
|
280
267
|
export { rateLimit, type RateLimitPluginOptions } from "./rate-limit.ts";
|
package/src/kernel/journal.ts
CHANGED
|
@@ -11,11 +11,7 @@ import { mkdir } from "node:fs/promises";
|
|
|
11
11
|
import { dirname } from "node:path";
|
|
12
12
|
|
|
13
13
|
/** Status of a durable run. */
|
|
14
|
-
export type JournalRunStatus =
|
|
15
|
-
| "running"
|
|
16
|
-
| "sleeping"
|
|
17
|
-
| "completed"
|
|
18
|
-
| "failed";
|
|
14
|
+
export type JournalRunStatus = "running" | "sleeping" | "completed" | "failed";
|
|
19
15
|
|
|
20
16
|
/** A completed named step. */
|
|
21
17
|
export interface JournalStepEntry {
|
|
@@ -44,10 +40,7 @@ export interface JournalEffectEntry {
|
|
|
44
40
|
}
|
|
45
41
|
|
|
46
42
|
/** One journaled event in call order. */
|
|
47
|
-
export type JournalEntry =
|
|
48
|
-
| JournalStepEntry
|
|
49
|
-
| JournalSleepEntry
|
|
50
|
-
| JournalEffectEntry;
|
|
43
|
+
export type JournalEntry = JournalStepEntry | JournalSleepEntry | JournalEffectEntry;
|
|
51
44
|
|
|
52
45
|
/** Persisted durable run. */
|
|
53
46
|
export interface JournalRun {
|
|
@@ -103,9 +96,7 @@ export interface JournalStore {
|
|
|
103
96
|
}
|
|
104
97
|
|
|
105
98
|
/** In-memory journal store. */
|
|
106
|
-
export function createMemoryJournalStore(
|
|
107
|
-
seed?: readonly JournalRun[],
|
|
108
|
-
): JournalStore {
|
|
99
|
+
export function createMemoryJournalStore(seed?: readonly JournalRun[]): JournalStore {
|
|
109
100
|
const runs = new Map<string, JournalRun>();
|
|
110
101
|
for (const r of seed ?? []) {
|
|
111
102
|
runs.set(r.id, cloneRun(r));
|
|
@@ -147,10 +138,7 @@ export function createFileJournalStore(path: string): JournalStore {
|
|
|
147
138
|
|
|
148
139
|
async function flush(map: Map<string, JournalRun>): Promise<void> {
|
|
149
140
|
await mkdir(dirname(path), { recursive: true });
|
|
150
|
-
await Bun.write(
|
|
151
|
-
path,
|
|
152
|
-
JSON.stringify({ runs: [...map.values()] }, null, 2),
|
|
153
|
-
);
|
|
141
|
+
await Bun.write(path, JSON.stringify({ runs: [...map.values()] }, null, 2));
|
|
154
142
|
}
|
|
155
143
|
|
|
156
144
|
return {
|
|
@@ -204,11 +192,7 @@ export interface JournalSession {
|
|
|
204
192
|
* @param duration - Duration string (`7d`, `2m`, …)
|
|
205
193
|
* @param parseMs - Duration → milliseconds
|
|
206
194
|
*/
|
|
207
|
-
sleep(
|
|
208
|
-
label: string,
|
|
209
|
-
duration: string,
|
|
210
|
-
parseMs: (duration: string) => number,
|
|
211
|
-
): Promise<void>;
|
|
195
|
+
sleep(label: string, duration: string, parseMs: (duration: string) => number): Promise<void>;
|
|
212
196
|
/**
|
|
213
197
|
* Journal an arbitrary fx effect (replay returns recorded value).
|
|
214
198
|
*
|
|
@@ -216,11 +200,7 @@ export interface JournalSession {
|
|
|
216
200
|
* @param resource - Resource ref
|
|
217
201
|
* @param execute - Side-effecting body
|
|
218
202
|
*/
|
|
219
|
-
effect<T>(
|
|
220
|
-
effectKind: string,
|
|
221
|
-
resource: string,
|
|
222
|
-
execute: () => T | Promise<T>,
|
|
223
|
-
): Promise<T>;
|
|
203
|
+
effect<T>(effectKind: string, resource: string, execute: () => T | Promise<T>): Promise<T>;
|
|
224
204
|
/** Persist current run status / output. */
|
|
225
205
|
commit(
|
|
226
206
|
status: JournalRunStatus,
|
|
@@ -327,11 +307,7 @@ export function createJournal(options: CreateJournalOptions): Journal {
|
|
|
327
307
|
): Promise<T> {
|
|
328
308
|
for (let i = cursor; i < run.entries.length; i++) {
|
|
329
309
|
const e = run.entries[i]!;
|
|
330
|
-
if (
|
|
331
|
-
e.kind === "effect" &&
|
|
332
|
-
e.effectKind === effectKind &&
|
|
333
|
-
e.resource === resource
|
|
334
|
-
) {
|
|
310
|
+
if (e.kind === "effect" && e.effectKind === effectKind && e.resource === resource) {
|
|
335
311
|
cursor = i + 1;
|
|
336
312
|
return e.value as T;
|
|
337
313
|
}
|
package/src/kernel/on.ts
CHANGED
|
@@ -6,12 +6,7 @@
|
|
|
6
6
|
* The return type carries the bound trigger so `typeof app` can derive REST.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import {
|
|
10
|
-
isFlow,
|
|
11
|
-
type AnyFlowDef,
|
|
12
|
-
type FlowDef,
|
|
13
|
-
type FlowErrorMap,
|
|
14
|
-
} from "./flow.ts";
|
|
9
|
+
import { isFlow, type AnyFlowDef, type FlowDef, type FlowErrorMap } from "./flow.ts";
|
|
15
10
|
import {
|
|
16
11
|
normalizeTrigger,
|
|
17
12
|
type BoundTriggerOf,
|
|
@@ -9,10 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
import { describe, expect, test } from "bun:test";
|
|
11
11
|
import { z } from "zod";
|
|
12
|
-
import {
|
|
13
|
-
createSessionStore,
|
|
14
|
-
issueSessionWithScopes,
|
|
15
|
-
} from "../auth/sessions.ts";
|
|
12
|
+
import { createSessionStore, issueSessionWithScopes } from "../auth/sessions.ts";
|
|
16
13
|
import { createClockRuntime } from "../elements/clock.ts";
|
|
17
14
|
import { gate } from "../elements/gate.ts";
|
|
18
15
|
import { createRunsRuntime, memoryRunsDriver } from "../runs/index.ts";
|
|
@@ -20,16 +17,11 @@ import { oke } from "./app.ts";
|
|
|
20
17
|
import { flow, resetFlowSeq } from "./flow.ts";
|
|
21
18
|
import { on, resetBindings } from "./on.ts";
|
|
22
19
|
import { http } from "./triggers.ts";
|
|
23
|
-
import {
|
|
24
|
-
gateDenialFailure,
|
|
25
|
-
recordGateEvaluations,
|
|
26
|
-
} from "./pipeline.ts";
|
|
20
|
+
import { gateDenialFailure, recordGateEvaluations } from "./pipeline.ts";
|
|
27
21
|
import { createRunTelemetry } from "./run-telemetry.ts";
|
|
28
22
|
|
|
29
23
|
const member = gate.policy("member", ({ auth }) => !!auth.verified);
|
|
30
|
-
const canOrder = gate.policy("order:create", ({ auth }) =>
|
|
31
|
-
auth.scopes.has("order:create"),
|
|
32
|
-
);
|
|
24
|
+
const canOrder = gate.policy("order:create", ({ auth }) => auth.scopes.has("order:create"));
|
|
33
25
|
|
|
34
26
|
describe("gateDenialFailure", () => {
|
|
35
27
|
test("anonymous → Unauthorized; authed → Forbidden; rate → RateLimited", () => {
|
|
@@ -217,18 +209,17 @@ describe("pipeline — Bearer cryptographic verification", () => {
|
|
|
217
209
|
const app = oke({
|
|
218
210
|
name: "auth-forge",
|
|
219
211
|
gates: [member],
|
|
220
|
-
env: "
|
|
212
|
+
env: "local",
|
|
221
213
|
auth: { secret: "hmac-secret-for-tests", sessions },
|
|
222
214
|
startScheduler: false,
|
|
223
215
|
});
|
|
224
|
-
await app.boot({ env: "
|
|
216
|
+
await app.boot({ env: "local", gates: [member], startScheduler: false });
|
|
225
217
|
|
|
226
218
|
const res = await app.fetch(
|
|
227
219
|
new Request("http://localhost/secure", {
|
|
228
220
|
method: "GET",
|
|
229
221
|
headers: {
|
|
230
|
-
authorization:
|
|
231
|
-
"Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJoYWNrZXIifQ.forgedsignature",
|
|
222
|
+
authorization: "Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJoYWNrZXIifQ.forgedsignature",
|
|
232
223
|
},
|
|
233
224
|
}),
|
|
234
225
|
);
|
|
@@ -272,13 +263,13 @@ describe("pipeline — Bearer cryptographic verification", () => {
|
|
|
272
263
|
const app = oke({
|
|
273
264
|
name: "auth-expired",
|
|
274
265
|
gates: [member],
|
|
275
|
-
env: "
|
|
266
|
+
env: "local",
|
|
276
267
|
auth: { secret, sessions, now: () => nowMs },
|
|
277
268
|
elements: { clock: clockRt },
|
|
278
269
|
startScheduler: false,
|
|
279
270
|
});
|
|
280
271
|
await app.boot({
|
|
281
|
-
env: "
|
|
272
|
+
env: "local",
|
|
282
273
|
gates: [member],
|
|
283
274
|
startScheduler: false,
|
|
284
275
|
elements: { clock: clockRt },
|
|
@@ -324,10 +315,10 @@ describe("pipeline — Bearer cryptographic verification", () => {
|
|
|
324
315
|
const app = oke({
|
|
325
316
|
name: "no-inject",
|
|
326
317
|
gates: [member],
|
|
327
|
-
env: "
|
|
318
|
+
env: "local",
|
|
328
319
|
startScheduler: false,
|
|
329
320
|
});
|
|
330
|
-
await app.boot({ env: "
|
|
321
|
+
await app.boot({ env: "local", gates: [member], startScheduler: false });
|
|
331
322
|
|
|
332
323
|
const result = await app.execute(
|
|
333
324
|
app.flow("orders.inject")!,
|
package/src/kernel/pipeline.ts
CHANGED
|
@@ -74,18 +74,14 @@ export type GateDenialCode = "Unauthorized" | "Forbidden" | "RateLimited";
|
|
|
74
74
|
* @param evaluation - First denying evaluation
|
|
75
75
|
* @param ctx - Policy context at denial time
|
|
76
76
|
*/
|
|
77
|
-
export function gateDenialFailure(
|
|
78
|
-
evaluation: GateEvaluation,
|
|
79
|
-
ctx: GatePolicyContext,
|
|
80
|
-
): FlowFailure {
|
|
77
|
+
export function gateDenialFailure(evaluation: GateEvaluation, ctx: GatePolicyContext): FlowFailure {
|
|
81
78
|
if (evaluation.kind === "rate" || evaluation.reason === "rate limited") {
|
|
82
79
|
return fail("RateLimited", {
|
|
83
80
|
retryAfterMs: evaluation.retryAfterMs ?? 0,
|
|
84
81
|
});
|
|
85
82
|
}
|
|
86
83
|
|
|
87
|
-
const authenticated =
|
|
88
|
-
ctx.auth.userId !== null && ctx.auth.userId !== undefined;
|
|
84
|
+
const authenticated = ctx.auth.userId !== null && ctx.auth.userId !== undefined;
|
|
89
85
|
if (!authenticated) {
|
|
90
86
|
return fail("Unauthorized", {});
|
|
91
87
|
}
|
|
@@ -102,9 +98,7 @@ export function gateDenialFailure(
|
|
|
102
98
|
*/
|
|
103
99
|
export function gateNamesOf(trigger: Trigger): string[] {
|
|
104
100
|
if (trigger.kind !== "http") return [];
|
|
105
|
-
return (trigger as HttpTrigger).gates.map((g) =>
|
|
106
|
-
typeof g === "string" ? g : g.name,
|
|
107
|
-
);
|
|
101
|
+
return (trigger as HttpTrigger).gates.map((g) => (typeof g === "string" ? g : g.name));
|
|
108
102
|
}
|
|
109
103
|
|
|
110
104
|
/**
|
|
@@ -129,10 +123,7 @@ export function recordGateEvaluations(
|
|
|
129
123
|
* @param bag - Mutable principal bag
|
|
130
124
|
* @param resolved - Identity
|
|
131
125
|
*/
|
|
132
|
-
export function applyPrincipal(
|
|
133
|
-
bag: PrincipalBag,
|
|
134
|
-
resolved: ResolvedPrincipal | undefined,
|
|
135
|
-
): void {
|
|
126
|
+
export function applyPrincipal(bag: PrincipalBag, resolved: ResolvedPrincipal | undefined): void {
|
|
136
127
|
if (!resolved) return;
|
|
137
128
|
if (resolved.plane === "operator" || resolved.operatorId !== undefined) {
|
|
138
129
|
bag.operator.id = resolved.operatorId ?? null;
|
|
@@ -217,10 +208,7 @@ export function createElementPipelineHooks(deps: PipelineDeps): {
|
|
|
217
208
|
* @param fx - Fx door
|
|
218
209
|
* @param ctx - Invocation context (for IP / meta)
|
|
219
210
|
*/
|
|
220
|
-
export function policyContextOf(
|
|
221
|
-
fx: Fx,
|
|
222
|
-
ctx: InvocationContext,
|
|
223
|
-
): GatePolicyContext {
|
|
211
|
+
export function policyContextOf(fx: Fx, ctx: InvocationContext): GatePolicyContext {
|
|
224
212
|
const auth = fx.auth as FxAuth;
|
|
225
213
|
const operator = fx.operator as FxOperator;
|
|
226
214
|
const ip =
|
package/src/kernel/plug.ts
CHANGED
|
@@ -14,10 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
import type { AnyFlowDef } from "./flow.ts";
|
|
16
16
|
import { isPlugin, type DecorationsOf, type PluginDef } from "./plugin.ts";
|
|
17
|
-
import {
|
|
18
|
-
type PluginRegistry,
|
|
19
|
-
type PluginScope,
|
|
20
|
-
} from "./registry.ts";
|
|
17
|
+
import { type PluginRegistry, type PluginScope } from "./registry.ts";
|
|
21
18
|
|
|
22
19
|
/**
|
|
23
20
|
* Apply a plugin to a registry at the given scope.
|
|
@@ -43,10 +40,8 @@ export function applyPlugin(
|
|
|
43
40
|
* @typeParam Base - Existing decorations
|
|
44
41
|
* @typeParam P - Plugin being plugged
|
|
45
42
|
*/
|
|
46
|
-
export type AccumulateDecorations<
|
|
47
|
-
|
|
48
|
-
P,
|
|
49
|
-
> = Base & DecorationsOf<P>;
|
|
43
|
+
export type AccumulateDecorations<Base extends Record<string, unknown>, P> = Base &
|
|
44
|
+
DecorationsOf<P>;
|
|
50
45
|
|
|
51
46
|
/** Something that can receive `.plug()` with type accumulation. */
|
|
52
47
|
export interface Pluggable<D extends Record<string, unknown> = {}> {
|
|
@@ -55,9 +50,7 @@ export interface Pluggable<D extends Record<string, unknown> = {}> {
|
|
|
55
50
|
*
|
|
56
51
|
* @param pluginDef - Plugin from {@link plugin}
|
|
57
52
|
*/
|
|
58
|
-
plug<P extends PluginDef>(
|
|
59
|
-
pluginDef: P,
|
|
60
|
-
): Pluggable<AccumulateDecorations<D, P>>;
|
|
53
|
+
plug<P extends PluginDef>(pluginDef: P): Pluggable<AccumulateDecorations<D, P>>;
|
|
61
54
|
}
|
|
62
55
|
|
|
63
56
|
/**
|
|
@@ -10,19 +10,11 @@ describe("plugin conflict detection", () => {
|
|
|
10
10
|
test("table-name collision fails the boot with both plugin names", () => {
|
|
11
11
|
const registry = createPluginRegistry();
|
|
12
12
|
|
|
13
|
-
registry.plug(
|
|
14
|
-
plugin("audit", { version: "1.0.0" }).table("events"),
|
|
15
|
-
{ kind: "app" },
|
|
16
|
-
);
|
|
13
|
+
registry.plug(plugin("audit", { version: "1.0.0" }).table("events"), { kind: "app" });
|
|
17
14
|
|
|
18
15
|
expect(() =>
|
|
19
|
-
registry.plug(
|
|
20
|
-
|
|
21
|
-
{ kind: "app" },
|
|
22
|
-
),
|
|
23
|
-
).toThrow(
|
|
24
|
-
'Plugin conflict: table "events" claimed by "audit" and "billing"',
|
|
25
|
-
);
|
|
16
|
+
registry.plug(plugin("billing", { version: "1.0.0" }).table("events"), { kind: "app" }),
|
|
17
|
+
).toThrow('Plugin conflict: table "events" claimed by "audit" and "billing"');
|
|
26
18
|
});
|
|
27
19
|
|
|
28
20
|
test("panel-id collision names both sides", () => {
|
|
@@ -79,28 +71,24 @@ describe("plugin conflict detection", () => {
|
|
|
79
71
|
config: { max: 30 },
|
|
80
72
|
}).hook("onRequest", () => {});
|
|
81
73
|
|
|
82
|
-
expect(
|
|
83
|
-
|
|
84
|
-
).toBeDefined();
|
|
85
|
-
expect(
|
|
86
|
-
registry.plug(p, { kind: "unit", name: "payments" }),
|
|
87
|
-
).toBeDefined();
|
|
74
|
+
expect(registry.plug(p, { kind: "unit", name: "orders" })).toBeDefined();
|
|
75
|
+
expect(registry.plug(p, { kind: "unit", name: "payments" })).toBeDefined();
|
|
88
76
|
expect(registry.installed).toHaveLength(2);
|
|
89
77
|
});
|
|
90
78
|
|
|
91
79
|
test("same plugin twice with conflicting config is a boot error", () => {
|
|
92
80
|
const registry = createPluginRegistry();
|
|
93
81
|
|
|
94
|
-
registry.plug(
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
);
|
|
82
|
+
registry.plug(plugin("rate-limit", { version: "1.0.0", config: { max: 30 } }), {
|
|
83
|
+
kind: "unit",
|
|
84
|
+
name: "orders",
|
|
85
|
+
});
|
|
98
86
|
|
|
99
87
|
expect(() =>
|
|
100
|
-
registry.plug(
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
),
|
|
88
|
+
registry.plug(plugin("rate-limit", { version: "1.0.0", config: { max: 60 } }), {
|
|
89
|
+
kind: "unit",
|
|
90
|
+
name: "payments",
|
|
91
|
+
}),
|
|
104
92
|
).toThrow(/conflicting config/);
|
|
105
93
|
});
|
|
106
94
|
});
|
|
@@ -15,8 +15,7 @@ beforeEach(() => {
|
|
|
15
15
|
});
|
|
16
16
|
|
|
17
17
|
/** Compile-time assert: `Actual` extends `Expected`. */
|
|
18
|
-
type ExpectExtends<Actual, Expected> =
|
|
19
|
-
Actual extends Expected ? true : false;
|
|
18
|
+
type ExpectExtends<Actual, Expected> = Actual extends Expected ? true : false;
|
|
20
19
|
|
|
21
20
|
describe("plugin decorate — types and runtime", () => {
|
|
22
21
|
test("decoration is visible in downstream handlers", async () => {
|
|
@@ -45,14 +44,12 @@ describe("plugin decorate — types and runtime", () => {
|
|
|
45
44
|
});
|
|
46
45
|
|
|
47
46
|
test("types accumulate through .plug()", () => {
|
|
48
|
-
const withAudit = plugin("audit", { version: "1.0.0" }).decorate(
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
)
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
{ currency: "SAR" as const },
|
|
55
|
-
);
|
|
47
|
+
const withAudit = plugin("audit", { version: "1.0.0" }).decorate("audit", {
|
|
48
|
+
enabled: true as const,
|
|
49
|
+
});
|
|
50
|
+
const withBilling = plugin("billing", { version: "1.0.0" }).decorate("billing", {
|
|
51
|
+
currency: "SAR" as const,
|
|
52
|
+
});
|
|
56
53
|
|
|
57
54
|
const app = oke({ name: "types" }).plug(withAudit).plug(withBilling);
|
|
58
55
|
|
|
@@ -98,9 +95,7 @@ describe("plugin decorate — types and runtime", () => {
|
|
|
98
95
|
);
|
|
99
96
|
|
|
100
97
|
const app = oke({ name: "deco-scope" });
|
|
101
|
-
app.unit("orders").plug(
|
|
102
|
-
plugin("flag", { version: "1.0.0" }).decorate("flag", "orders-only"),
|
|
103
|
-
);
|
|
98
|
+
app.unit("orders").plug(plugin("flag", { version: "1.0.0" }).decorate("flag", "orders-only"));
|
|
104
99
|
|
|
105
100
|
await app.fetch(new Request("http://localhost/orders"));
|
|
106
101
|
await app.fetch(new Request("http://localhost/payments"));
|
|
@@ -54,11 +54,7 @@ describe("plugin scoping — attachment point is the scope", () => {
|
|
|
54
54
|
await app.fetch(new Request("http://localhost/orders"));
|
|
55
55
|
await app.fetch(new Request("http://localhost/payments"));
|
|
56
56
|
|
|
57
|
-
expect(fired).toEqual([
|
|
58
|
-
"rate-limit",
|
|
59
|
-
"orders:handler",
|
|
60
|
-
"payments:handler",
|
|
61
|
-
]);
|
|
57
|
+
expect(fired).toEqual(["rate-limit", "orders:handler", "payments:handler"]);
|
|
62
58
|
});
|
|
63
59
|
|
|
64
60
|
test("app-scoped plugin hook fires for every unit", async () => {
|
|
@@ -87,12 +83,9 @@ describe("plugin scoping — attachment point is the scope", () => {
|
|
|
87
83
|
}),
|
|
88
84
|
);
|
|
89
85
|
|
|
90
|
-
const audit = plugin("audit", { version: "1.0.0" }).hook(
|
|
91
|
-
"
|
|
92
|
-
|
|
93
|
-
fired.push("audit");
|
|
94
|
-
},
|
|
95
|
-
);
|
|
86
|
+
const audit = plugin("audit", { version: "1.0.0" }).hook("afterHandle", () => {
|
|
87
|
+
fired.push("audit");
|
|
88
|
+
});
|
|
96
89
|
|
|
97
90
|
const app = oke({ name: "app-scope" }).plug(audit);
|
|
98
91
|
|
package/src/kernel/plugin.ts
CHANGED
|
@@ -91,10 +91,30 @@ export interface ImageRecipeContribution {
|
|
|
91
91
|
export interface TableContribution {
|
|
92
92
|
/** Table name — conflict namespace shared across plugins. */
|
|
93
93
|
readonly name: string;
|
|
94
|
-
/**
|
|
94
|
+
/**
|
|
95
|
+
* Abstract column map from `field.*` builders (merged into domain schema emit).
|
|
96
|
+
* Omit when the plugin only claims a name (DDL stays hand-written).
|
|
97
|
+
*/
|
|
98
|
+
readonly columns?: Readonly<Record<string, unknown>>;
|
|
99
|
+
/**
|
|
100
|
+
* Non-column metadata (e.g. data plane). Prefer this over stuffing `plane`
|
|
101
|
+
* into the column map.
|
|
102
|
+
*/
|
|
103
|
+
readonly options?: {
|
|
104
|
+
readonly plane?: "operator" | "user" | "shared" | string;
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* Opaque schema descriptor (legacy). Prefer {@link columns} + {@link options}.
|
|
108
|
+
* Still set for plane-only contributions so older readers keep working.
|
|
109
|
+
*/
|
|
95
110
|
readonly schema?: unknown;
|
|
96
111
|
}
|
|
97
112
|
|
|
113
|
+
/** Options for {@link PluginApi.table} / {@link PluginDef.table}. */
|
|
114
|
+
export interface PluginTableOptions {
|
|
115
|
+
readonly plane?: "operator" | "user" | "shared" | string;
|
|
116
|
+
}
|
|
117
|
+
|
|
98
118
|
/** Driver contribution. */
|
|
99
119
|
export interface DriverContribution {
|
|
100
120
|
/** Driver id (protocol-named) — conflict namespace shared across plugins. */
|
|
@@ -152,10 +172,7 @@ export interface PluginApi {
|
|
|
152
172
|
* @param name - Command name
|
|
153
173
|
* @param handler - Command handler
|
|
154
174
|
*/
|
|
155
|
-
cli(
|
|
156
|
-
name: string,
|
|
157
|
-
handler: CliContribution["handler"],
|
|
158
|
-
): PluginApi;
|
|
175
|
+
cli(name: string, handler: CliContribution["handler"]): PluginApi;
|
|
159
176
|
/**
|
|
160
177
|
* Contribute a driver.
|
|
161
178
|
*
|
|
@@ -173,10 +190,19 @@ export interface PluginApi {
|
|
|
173
190
|
/**
|
|
174
191
|
* Contribute a DB table / schema fragment.
|
|
175
192
|
*
|
|
193
|
+
* Plugins may declare **whole tables** (with optional `field.*` columns)
|
|
194
|
+
* merged into the generated domain schema. Extending an existing app-owned
|
|
195
|
+
* table with plugin columns is not supported — contribute a separate table.
|
|
196
|
+
*
|
|
176
197
|
* @param name - Table name
|
|
177
|
-
* @param
|
|
198
|
+
* @param columns - Abstract column map, or legacy `{ plane }` options
|
|
199
|
+
* @param options - Plane / metadata (preferred over embedding `plane` in columns)
|
|
178
200
|
*/
|
|
179
|
-
table(
|
|
201
|
+
table(
|
|
202
|
+
name: string,
|
|
203
|
+
columns?: Readonly<Record<string, unknown>>,
|
|
204
|
+
options?: PluginTableOptions,
|
|
205
|
+
): PluginApi;
|
|
180
206
|
/**
|
|
181
207
|
* Contribute a flow.
|
|
182
208
|
*
|
|
@@ -265,10 +291,7 @@ export interface PluginDef<D extends Record<string, unknown> = {}> {
|
|
|
265
291
|
* @param key - Decoration key
|
|
266
292
|
* @param value - Value
|
|
267
293
|
*/
|
|
268
|
-
decorate<K extends string, V>(
|
|
269
|
-
key: K,
|
|
270
|
-
value: V,
|
|
271
|
-
): PluginDef<D & { [P in K]: V }>;
|
|
294
|
+
decorate<K extends string, V>(key: K, value: V): PluginDef<D & { [P in K]: V }>;
|
|
272
295
|
/**
|
|
273
296
|
* Queue an element contribution.
|
|
274
297
|
*
|
|
@@ -317,10 +340,17 @@ export interface PluginDef<D extends Record<string, unknown> = {}> {
|
|
|
317
340
|
/**
|
|
318
341
|
* Queue a table / schema contribution.
|
|
319
342
|
*
|
|
343
|
+
* Whole tables only — no column injection into app-owned tables (v1).
|
|
344
|
+
*
|
|
320
345
|
* @param name - Table name
|
|
321
|
-
* @param
|
|
346
|
+
* @param columns - Abstract column map, or legacy `{ plane }` options
|
|
347
|
+
* @param options - Plane / metadata
|
|
322
348
|
*/
|
|
323
|
-
table(
|
|
349
|
+
table(
|
|
350
|
+
name: string,
|
|
351
|
+
columns?: Readonly<Record<string, unknown>>,
|
|
352
|
+
options?: PluginTableOptions,
|
|
353
|
+
): PluginDef<D>;
|
|
324
354
|
/**
|
|
325
355
|
* Queue a flow contribution.
|
|
326
356
|
*
|
|
@@ -343,8 +373,7 @@ export interface PluginDef<D extends Record<string, unknown> = {}> {
|
|
|
343
373
|
}
|
|
344
374
|
|
|
345
375
|
/** Extract accumulated decoration types from a {@link PluginDef}. */
|
|
346
|
-
export type DecorationsOf<P> =
|
|
347
|
-
P extends PluginDef<infer D> ? D : Record<string, never>;
|
|
376
|
+
export type DecorationsOf<P> = P extends PluginDef<infer D> ? D : Record<string, never>;
|
|
348
377
|
|
|
349
378
|
/**
|
|
350
379
|
* Define a plugin. Fluent methods queue a registration plan; the registry
|
|
@@ -353,10 +382,7 @@ export type DecorationsOf<P> =
|
|
|
353
382
|
* @param name - Stable plugin id
|
|
354
383
|
* @param options - Version and optional config snapshot
|
|
355
384
|
*/
|
|
356
|
-
export function plugin(
|
|
357
|
-
name: string,
|
|
358
|
-
options: PluginOptions,
|
|
359
|
-
): PluginDef {
|
|
385
|
+
export function plugin(name: string, options: PluginOptions): PluginDef {
|
|
360
386
|
const steps: Array<(api: PluginApi) => void> = [];
|
|
361
387
|
|
|
362
388
|
const def: PluginDef = {
|
|
@@ -390,9 +416,7 @@ export function plugin(
|
|
|
390
416
|
api.element(el);
|
|
391
417
|
} else if (typeof el.facet === "string" && typeof el.name === "string") {
|
|
392
418
|
api.element({
|
|
393
|
-
kind: el.facet.startsWith("store.")
|
|
394
|
-
? el.facet
|
|
395
|
-
: `store.${el.facet}`,
|
|
419
|
+
kind: el.facet.startsWith("store.") ? el.facet : `store.${el.facet}`,
|
|
396
420
|
name: el.name,
|
|
397
421
|
});
|
|
398
422
|
} else {
|
|
@@ -437,9 +461,9 @@ export function plugin(
|
|
|
437
461
|
});
|
|
438
462
|
return def;
|
|
439
463
|
},
|
|
440
|
-
table(tableName,
|
|
464
|
+
table(tableName, columns, options) {
|
|
441
465
|
steps.push((api) => {
|
|
442
|
-
api.table(tableName,
|
|
466
|
+
api.table(tableName, columns, options);
|
|
443
467
|
});
|
|
444
468
|
return def;
|
|
445
469
|
},
|