okengine 0.2.5 → 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 +46 -38
- 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
|
@@ -63,51 +63,32 @@ export function RunsPanel() {
|
|
|
63
63
|
|
|
64
64
|
const allRuns = runsQuery.data ?? [];
|
|
65
65
|
const query = dimensionQueryOf(search);
|
|
66
|
-
const filtered = useMemo(
|
|
67
|
-
() => filterRuns(allRuns, query),
|
|
68
|
-
[allRuns, query],
|
|
69
|
-
);
|
|
66
|
+
const filtered = useMemo(() => filterRuns(allRuns, query), [allRuns, query]);
|
|
70
67
|
const range = durationRangeOf(search);
|
|
71
|
-
const buckets = useMemo(
|
|
72
|
-
() => durationHistogram(filtered),
|
|
73
|
-
[filtered],
|
|
74
|
-
);
|
|
68
|
+
const buckets = useMemo(() => durationHistogram(filtered), [filtered]);
|
|
75
69
|
const maxBucket = Math.max(1, ...buckets.map((b) => b.count));
|
|
76
70
|
const groups = useMemo(
|
|
77
|
-
() =>
|
|
78
|
-
search.group ? groupByDimension(filtered, search.group) : [],
|
|
71
|
+
() => (search.group ? groupByDimension(filtered, search.group) : []),
|
|
79
72
|
[filtered, search.group],
|
|
80
73
|
);
|
|
81
74
|
const findings = useMemo(
|
|
82
75
|
() => (range ? explainDurationOutliers(filtered, range) : []),
|
|
83
76
|
[filtered, range],
|
|
84
77
|
);
|
|
85
|
-
const dimensions = useMemo(
|
|
86
|
-
() => discoverDimensions(allRuns),
|
|
87
|
-
[allRuns],
|
|
88
|
-
);
|
|
78
|
+
const dimensions = useMemo(() => discoverDimensions(allRuns), [allRuns]);
|
|
89
79
|
const open = allRuns.find((r) => r.id === search.run);
|
|
90
80
|
|
|
91
81
|
return (
|
|
92
82
|
<div className="flex h-full min-h-0 flex-col">
|
|
93
83
|
<header className="flex shrink-0 flex-wrap items-end gap-4 border-b border-[var(--oke-line)] px-6 py-4">
|
|
94
84
|
<div className="flex flex-col gap-1">
|
|
95
|
-
<p className="text-xs uppercase tracking-[0.2em] text-[var(--oke-muted)]">
|
|
96
|
-
|
|
97
|
-
</p>
|
|
98
|
-
<h1 className="text-xl font-semibold tracking-tight">
|
|
99
|
-
Population analysis
|
|
100
|
-
</h1>
|
|
85
|
+
<p className="text-xs uppercase tracking-[0.2em] text-[var(--oke-muted)]">Runs</p>
|
|
86
|
+
<h1 className="text-xl font-semibold tracking-tight">Population analysis</h1>
|
|
101
87
|
<p className="text-xs text-[var(--oke-muted)]">
|
|
102
|
-
{filtered.length} of {allRuns.length} runs · wide events, not log
|
|
103
|
-
lines
|
|
88
|
+
{filtered.length} of {allRuns.length} runs · wide events, not log lines
|
|
104
89
|
</p>
|
|
105
90
|
</div>
|
|
106
|
-
<QueryBuilder
|
|
107
|
-
search={search}
|
|
108
|
-
dimensions={dimensions}
|
|
109
|
-
onChange={setSearch}
|
|
110
|
-
/>
|
|
91
|
+
<QueryBuilder search={search} dimensions={dimensions} onChange={setSearch} />
|
|
111
92
|
<label className="flex flex-col gap-1 text-sm">
|
|
112
93
|
<span className="text-[var(--oke-muted)]">Group by</span>
|
|
113
94
|
<select
|
|
@@ -132,18 +113,14 @@ export function RunsPanel() {
|
|
|
132
113
|
<div className="grid min-h-0 flex-1 grid-cols-1 lg:grid-cols-[minmax(0,1.2fr)_minmax(0,1fr)]">
|
|
133
114
|
<div className="min-h-0 overflow-auto border-r border-[var(--oke-line)] px-6 py-6">
|
|
134
115
|
<section aria-label="Duration distribution" className="mb-8">
|
|
135
|
-
<h2 className="mb-2 text-sm font-medium">
|
|
136
|
-
Duration distribution
|
|
137
|
-
</h2>
|
|
116
|
+
<h2 className="mb-2 text-sm font-medium">Duration distribution</h2>
|
|
138
117
|
<p className="mb-3 text-xs text-[var(--oke-muted)]">
|
|
139
118
|
Range-select a region to explain outliers against the rest.
|
|
140
119
|
</p>
|
|
141
120
|
{runsQuery.isLoading ? (
|
|
142
121
|
<p className="text-sm text-[var(--oke-muted)]">Loading runs…</p>
|
|
143
122
|
) : buckets.length === 0 ? (
|
|
144
|
-
<p className="text-sm text-[var(--oke-muted)]">
|
|
145
|
-
No runs match the current query.
|
|
146
|
-
</p>
|
|
123
|
+
<p className="text-sm text-[var(--oke-muted)]">No runs match the current query.</p>
|
|
147
124
|
) : (
|
|
148
125
|
<DurationChart
|
|
149
126
|
buckets={buckets}
|
|
@@ -155,8 +132,7 @@ export function RunsPanel() {
|
|
|
155
132
|
{range ? (
|
|
156
133
|
<div className="mt-3 flex flex-wrap items-center gap-2">
|
|
157
134
|
<p className="text-xs text-[var(--oke-muted)]">
|
|
158
|
-
Selected {formatDurationMs(range.minMs)} –{
|
|
159
|
-
{formatDurationMs(range.maxMs)}
|
|
135
|
+
Selected {formatDurationMs(range.minMs)} – {formatDurationMs(range.maxMs)}
|
|
160
136
|
</p>
|
|
161
137
|
<Button
|
|
162
138
|
type="button"
|
|
@@ -171,9 +147,7 @@ export function RunsPanel() {
|
|
|
171
147
|
|
|
172
148
|
{range ? (
|
|
173
149
|
<section aria-label="Outlier explanation" className="mb-8">
|
|
174
|
-
<h2 className="mb-2 text-sm font-medium">
|
|
175
|
-
Outlier explanation
|
|
176
|
-
</h2>
|
|
150
|
+
<h2 className="mb-2 text-sm font-medium">Outlier explanation</h2>
|
|
177
151
|
{findings.length === 0 ? (
|
|
178
152
|
<p className="text-sm text-[var(--oke-muted)]">
|
|
179
153
|
No dimension separates this region strongly enough.
|
|
@@ -181,9 +155,7 @@ export function RunsPanel() {
|
|
|
181
155
|
) : (
|
|
182
156
|
<ol className="flex list-decimal flex-col gap-1 pl-5 text-sm">
|
|
183
157
|
{findings.map((f) => (
|
|
184
|
-
<li key={`${f.dimension}:${f.value}`}>
|
|
185
|
-
{f.explanation}
|
|
186
|
-
</li>
|
|
158
|
+
<li key={`${f.dimension}:${f.value}`}>{f.explanation}</li>
|
|
187
159
|
))}
|
|
188
160
|
</ol>
|
|
189
161
|
)}
|
|
@@ -192,9 +164,7 @@ export function RunsPanel() {
|
|
|
192
164
|
|
|
193
165
|
{search.group ? (
|
|
194
166
|
<section aria-label="Group aggregates" className="mb-8">
|
|
195
|
-
<h2 className="mb-2 text-sm font-medium">
|
|
196
|
-
Group by {search.group}
|
|
197
|
-
</h2>
|
|
167
|
+
<h2 className="mb-2 text-sm font-medium">Group by {search.group}</h2>
|
|
198
168
|
<table className="w-full border-collapse text-left text-sm">
|
|
199
169
|
<thead>
|
|
200
170
|
<tr className="border-b border-[var(--oke-line)] text-[var(--oke-muted)]">
|
|
@@ -223,18 +193,10 @@ export function RunsPanel() {
|
|
|
223
193
|
<tr key={g.key}>
|
|
224
194
|
<td className="py-2 pr-3 font-mono text-xs">{g.key}</td>
|
|
225
195
|
<td className="py-2 pr-3">{g.count}</td>
|
|
226
|
-
<td className="py-2 pr-3">
|
|
227
|
-
|
|
228
|
-
</td>
|
|
229
|
-
<td className="py-2
|
|
230
|
-
{formatDurationMs(g.p50DurationMs)}
|
|
231
|
-
</td>
|
|
232
|
-
<td className="py-2 pr-3">
|
|
233
|
-
{formatDurationMs(g.p99DurationMs)}
|
|
234
|
-
</td>
|
|
235
|
-
<td className="py-2">
|
|
236
|
-
{g.sumCost > 0 ? `$${g.sumCost.toFixed(3)}` : "—"}
|
|
237
|
-
</td>
|
|
196
|
+
<td className="py-2 pr-3">{formatDurationMs(g.avgDurationMs)}</td>
|
|
197
|
+
<td className="py-2 pr-3">{formatDurationMs(g.p50DurationMs)}</td>
|
|
198
|
+
<td className="py-2 pr-3">{formatDurationMs(g.p99DurationMs)}</td>
|
|
199
|
+
<td className="py-2">{g.sumCost > 0 ? `$${g.sumCost.toFixed(3)}` : "—"}</td>
|
|
238
200
|
</tr>
|
|
239
201
|
))}
|
|
240
202
|
</tbody>
|
|
@@ -269,10 +231,7 @@ export function RunsPanel() {
|
|
|
269
231
|
<span className="flex items-center gap-3 font-mono text-xs text-[var(--oke-muted)]">
|
|
270
232
|
<span>{run.cache}</span>
|
|
271
233
|
{run.error ? (
|
|
272
|
-
<span
|
|
273
|
-
role="status"
|
|
274
|
-
className="text-[var(--oke-danger)]"
|
|
275
|
-
>
|
|
234
|
+
<span role="status" className="text-[var(--oke-danger)]">
|
|
276
235
|
{run.error}
|
|
277
236
|
</span>
|
|
278
237
|
) : (
|
|
@@ -298,11 +257,7 @@ export function RunsPanel() {
|
|
|
298
257
|
Select a run to see its flat dimension record.
|
|
299
258
|
</p>
|
|
300
259
|
) : (
|
|
301
|
-
<RunDetail
|
|
302
|
-
run={open}
|
|
303
|
-
allRuns={allRuns}
|
|
304
|
-
onClose={() => setSearch(closeRun(search))}
|
|
305
|
-
/>
|
|
260
|
+
<RunDetail run={open} allRuns={allRuns} onClose={() => setSearch(closeRun(search))} />
|
|
306
261
|
)}
|
|
307
262
|
</section>
|
|
308
263
|
</div>
|
|
@@ -320,9 +275,7 @@ function QueryBuilder({
|
|
|
320
275
|
readonly onChange: (next: RunsSearch) => void;
|
|
321
276
|
}) {
|
|
322
277
|
const query = dimensionQueryOf(search);
|
|
323
|
-
const dimOptions = [
|
|
324
|
-
...new Set([...BUILDER_DIMENSIONS, ...dimensions]),
|
|
325
|
-
].sort();
|
|
278
|
+
const dimOptions = [...new Set([...BUILDER_DIMENSIONS, ...dimensions])].sort();
|
|
326
279
|
const [dim, setDim] = useState<string>("cache");
|
|
327
280
|
const [op, setOp] = useState<QueryOp>("=");
|
|
328
281
|
const [value, setValue] = useState("miss");
|
|
@@ -378,9 +331,7 @@ function QueryBuilder({
|
|
|
378
331
|
type="button"
|
|
379
332
|
variant="ghost"
|
|
380
333
|
onClick={() => {
|
|
381
|
-
const parsed = parseDimensionQuery(
|
|
382
|
-
`${dim} ${op} ${value}`,
|
|
383
|
-
);
|
|
334
|
+
const parsed = parseDimensionQuery(`${dim} ${op} ${value}`);
|
|
384
335
|
const clause = parsed.clauses[0];
|
|
385
336
|
if (!clause) return;
|
|
386
337
|
const next = setWhere(search, upsertClause(query, clause));
|
|
@@ -393,20 +344,14 @@ function QueryBuilder({
|
|
|
393
344
|
</div>
|
|
394
345
|
|
|
395
346
|
{query.clauses.length > 0 ? (
|
|
396
|
-
<ul
|
|
397
|
-
aria-label="Active query clauses"
|
|
398
|
-
className="flex flex-wrap gap-2"
|
|
399
|
-
>
|
|
347
|
+
<ul aria-label="Active query clauses" className="flex flex-wrap gap-2">
|
|
400
348
|
{query.clauses.map((c) => (
|
|
401
349
|
<li key={c.dimension}>
|
|
402
350
|
<button
|
|
403
351
|
type="button"
|
|
404
352
|
className="min-h-8 border border-[var(--oke-line)] px-2 font-mono text-xs"
|
|
405
353
|
onClick={() => {
|
|
406
|
-
const next = setWhere(
|
|
407
|
-
search,
|
|
408
|
-
removeClause(query, c.dimension),
|
|
409
|
-
);
|
|
354
|
+
const next = setWhere(search, removeClause(query, c.dimension));
|
|
410
355
|
setExprDraft(next.where ?? "");
|
|
411
356
|
onChange(next);
|
|
412
357
|
}}
|
|
@@ -419,9 +364,7 @@ function QueryBuilder({
|
|
|
419
364
|
) : null}
|
|
420
365
|
|
|
421
366
|
<label className="flex flex-col gap-1 text-sm">
|
|
422
|
-
<span className="text-[var(--oke-muted)]">
|
|
423
|
-
Dimension query expression
|
|
424
|
-
</span>
|
|
367
|
+
<span className="text-[var(--oke-muted)]">Dimension query expression</span>
|
|
425
368
|
<input
|
|
426
369
|
aria-label="Dimension query expression"
|
|
427
370
|
className="min-h-8 border border-[var(--oke-line)] bg-transparent px-2 font-mono text-sm"
|
|
@@ -465,10 +408,7 @@ function DurationChart({
|
|
|
465
408
|
onMouseLeave={() => setAnchor(null)}
|
|
466
409
|
>
|
|
467
410
|
{buckets.map((b, i) => {
|
|
468
|
-
const selected =
|
|
469
|
-
range !== null &&
|
|
470
|
-
b.minMs <= range.maxMs &&
|
|
471
|
-
b.maxMs >= range.minMs;
|
|
411
|
+
const selected = range !== null && b.minMs <= range.maxMs && b.maxMs >= range.minMs;
|
|
472
412
|
const height = Math.max(4, (b.count / maxBucket) * 100);
|
|
473
413
|
return (
|
|
474
414
|
<button
|
|
@@ -533,9 +473,7 @@ function RunDetail({
|
|
|
533
473
|
label: "replica",
|
|
534
474
|
value:
|
|
535
475
|
run.replica != null
|
|
536
|
-
? `${run.replica}${
|
|
537
|
-
run.replicaLagMs != null ? ` · lag ${run.replicaLagMs}ms` : ""
|
|
538
|
-
}`
|
|
476
|
+
? `${run.replica}${run.replicaLagMs != null ? ` · lag ${run.replicaLagMs}ms` : ""}`
|
|
539
477
|
: "—",
|
|
540
478
|
},
|
|
541
479
|
{
|
|
@@ -587,9 +525,7 @@ function RunDetail({
|
|
|
587
525
|
<dd
|
|
588
526
|
className={clsx(
|
|
589
527
|
"font-mono text-xs",
|
|
590
|
-
f.label === "error" && run.error
|
|
591
|
-
? "text-[var(--oke-danger)]"
|
|
592
|
-
: "",
|
|
528
|
+
f.label === "error" && run.error ? "text-[var(--oke-danger)]" : "",
|
|
593
529
|
)}
|
|
594
530
|
>
|
|
595
531
|
{f.value}
|
|
@@ -610,8 +546,7 @@ function RunDetail({
|
|
|
610
546
|
className="flex min-h-8 items-center justify-between gap-3 py-1"
|
|
611
547
|
>
|
|
612
548
|
<span>
|
|
613
|
-
{e.kind}
|
|
614
|
-
<span className="font-mono text-xs">{e.resource}</span>
|
|
549
|
+
{e.kind} <span className="font-mono text-xs">{e.resource}</span>
|
|
615
550
|
</span>
|
|
616
551
|
<span className="font-mono text-xs text-[var(--oke-muted)]">
|
|
617
552
|
{e.duration}ms · {e.reversibility}
|
|
@@ -623,17 +558,14 @@ function RunDetail({
|
|
|
623
558
|
</div>
|
|
624
559
|
|
|
625
560
|
<details className="group">
|
|
626
|
-
<summary className="cursor-pointer text-sm font-medium">
|
|
627
|
-
fx.log ({run.logs.length})
|
|
628
|
-
</summary>
|
|
561
|
+
<summary className="cursor-pointer text-sm font-medium">fx.log ({run.logs.length})</summary>
|
|
629
562
|
{run.logs.length === 0 ? (
|
|
630
563
|
<p className="mt-2 text-sm text-[var(--oke-muted)]">No log lines</p>
|
|
631
564
|
) : (
|
|
632
565
|
<ul className="mt-2 divide-y divide-[var(--oke-line)] font-mono text-xs">
|
|
633
566
|
{run.logs.map((line, i) => (
|
|
634
567
|
<li key={i} className="py-2">
|
|
635
|
-
<span className="text-[var(--oke-muted)]">[{line.level}]</span>{
|
|
636
|
-
{line.message}
|
|
568
|
+
<span className="text-[var(--oke-muted)]">[{line.level}]</span> {line.message}
|
|
637
569
|
{line.data ? (
|
|
638
570
|
<pre className="mt-1 whitespace-pre-wrap text-[var(--oke-muted)]">
|
|
639
571
|
{JSON.stringify(line.data, null, 2)}
|
|
@@ -43,9 +43,7 @@ export function SignalsPanel() {
|
|
|
43
43
|
const [typed, setTyped] = useState("");
|
|
44
44
|
const [reason, setReason] = useState("");
|
|
45
45
|
const [dryRunSummary, setDryRunSummary] = useState<string | null>(null);
|
|
46
|
-
const [monitor, setMonitor] = useState<LiveMonitorState>(() =>
|
|
47
|
-
createLiveMonitor(),
|
|
48
|
-
);
|
|
46
|
+
const [monitor, setMonitor] = useState<LiveMonitorState>(() => createLiveMonitor());
|
|
49
47
|
const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set());
|
|
50
48
|
|
|
51
49
|
const setSearch = (next: SignalsSearch) => {
|
|
@@ -68,20 +66,13 @@ export function SignalsPanel() {
|
|
|
68
66
|
});
|
|
69
67
|
|
|
70
68
|
const signals = signalsQuery.data ?? [];
|
|
71
|
-
const groups = useMemo(
|
|
72
|
-
() => groupByPhysics(signals, search.q ?? ""),
|
|
73
|
-
[signals, search.q],
|
|
74
|
-
);
|
|
69
|
+
const groups = useMemo(() => groupByPhysics(signals, search.q ?? ""), [signals, search.q]);
|
|
75
70
|
const open = signals.find((s) => s.name === search.signal);
|
|
76
71
|
const line = open ? durableLine(open.consumersDurable) : null;
|
|
77
72
|
const dlq = open?.deadLetters.find((d) => d.id === search.dlq);
|
|
78
73
|
const fields = open ? fieldsFromSchema(open.schema) : [];
|
|
79
|
-
const replayConfirm = open
|
|
80
|
-
|
|
81
|
-
: null;
|
|
82
|
-
const discardConfirm = open
|
|
83
|
-
? discardConfirmation(open, { production: true })
|
|
84
|
-
: null;
|
|
74
|
+
const replayConfirm = open ? replayConfirmation(open, { production: true }) : null;
|
|
75
|
+
const discardConfirm = open ? discardConfirmation(open, { production: true }) : null;
|
|
85
76
|
const dryOffer = open ? dryRunOffer(open) : null;
|
|
86
77
|
|
|
87
78
|
useEffect(() => {
|
|
@@ -99,8 +90,7 @@ export function SignalsPanel() {
|
|
|
99
90
|
}
|
|
100
91
|
setMonitor((m) => ({
|
|
101
92
|
...setPaused(m, false),
|
|
102
|
-
payloads:
|
|
103
|
-
m.payloads.length === 0 ? [...open.recentLive] : m.payloads,
|
|
93
|
+
payloads: m.payloads.length === 0 ? [...open.recentLive] : m.payloads,
|
|
104
94
|
}));
|
|
105
95
|
}, [open?.name, open?.recentLive, open?.delivery, search.paused]);
|
|
106
96
|
|
|
@@ -110,10 +100,7 @@ export function SignalsPanel() {
|
|
|
110
100
|
if (dryOffer && !dryOffer.ok) {
|
|
111
101
|
throw new Error(dryOffer.reason);
|
|
112
102
|
}
|
|
113
|
-
const ids =
|
|
114
|
-
selectedIds.size > 0
|
|
115
|
-
? [...selectedIds]
|
|
116
|
-
: open.deadLetters.map((d) => d.id);
|
|
103
|
+
const ids = selectedIds.size > 0 ? [...selectedIds] : open.deadLetters.map((d) => d.id);
|
|
117
104
|
const res = await consoleCalls.signalsDryRunReplay({
|
|
118
105
|
signal: open.name,
|
|
119
106
|
messageIds: ids,
|
|
@@ -129,14 +116,10 @@ export function SignalsPanel() {
|
|
|
129
116
|
data.wouldHaveFired?.length > 0
|
|
130
117
|
? ` · ${data.wouldHaveFired.length} external effect(s) stubbed`
|
|
131
118
|
: "";
|
|
132
|
-
setDryRunSummary(
|
|
133
|
-
`${data.succeeded} would succeed, ${data.failed} would still fail${stubs}`,
|
|
134
|
-
);
|
|
119
|
+
setDryRunSummary(`${data.succeeded} would succeed, ${data.failed} would still fail${stubs}`);
|
|
135
120
|
},
|
|
136
121
|
onError: (err) => {
|
|
137
|
-
setDryRunSummary(
|
|
138
|
-
err instanceof Error ? err.message : "Dry-run refused",
|
|
139
|
-
);
|
|
122
|
+
setDryRunSummary(err instanceof Error ? err.message : "Dry-run refused");
|
|
140
123
|
},
|
|
141
124
|
});
|
|
142
125
|
|
|
@@ -158,9 +141,7 @@ export function SignalsPanel() {
|
|
|
158
141
|
? [dlq.id]
|
|
159
142
|
: open.deadLetters.map((d) => d.id);
|
|
160
143
|
const payloads =
|
|
161
|
-
dlq && fields
|
|
162
|
-
? { [dlq.id]: formValuesToPayload(formValues, fields) }
|
|
163
|
-
: undefined;
|
|
144
|
+
dlq && fields ? { [dlq.id]: formValuesToPayload(formValues, fields) } : undefined;
|
|
164
145
|
const res = await consoleCalls.signalsReplay({
|
|
165
146
|
signal: open.name,
|
|
166
147
|
messageIds: ids,
|
|
@@ -168,8 +149,7 @@ export function SignalsPanel() {
|
|
|
168
149
|
ratePerSec: rate,
|
|
169
150
|
dryRun: false,
|
|
170
151
|
payloads,
|
|
171
|
-
confirmation:
|
|
172
|
-
replayConfirm.kind === "typed" ? typed : undefined,
|
|
152
|
+
confirmation: replayConfirm.kind === "typed" ? typed : undefined,
|
|
173
153
|
reason: replayConfirm.kind === "typed" ? reason : undefined,
|
|
174
154
|
});
|
|
175
155
|
if (res.error) throw new Error(res.error.code);
|
|
@@ -202,8 +182,7 @@ export function SignalsPanel() {
|
|
|
202
182
|
const res = await consoleCalls.signalsDiscard({
|
|
203
183
|
signal: open.name,
|
|
204
184
|
messageIds: ids,
|
|
205
|
-
confirmation:
|
|
206
|
-
discardConfirm.kind === "typed" ? typed : undefined,
|
|
185
|
+
confirmation: discardConfirm.kind === "typed" ? typed : undefined,
|
|
207
186
|
reason: discardConfirm.kind === "typed" ? reason : undefined,
|
|
208
187
|
});
|
|
209
188
|
if (res.error) throw new Error(res.error.code);
|
|
@@ -220,15 +199,9 @@ export function SignalsPanel() {
|
|
|
220
199
|
<div className="flex h-full min-h-0 flex-col">
|
|
221
200
|
<header className="flex shrink-0 flex-wrap items-end gap-4 border-b border-[var(--oke-line)] px-6 py-4">
|
|
222
201
|
<div className="flex flex-col gap-1">
|
|
223
|
-
<p className="text-xs uppercase tracking-[0.2em] text-[var(--oke-muted)]">
|
|
224
|
-
|
|
225
|
-
</p>
|
|
226
|
-
<h1 className="text-xl font-semibold tracking-tight">
|
|
227
|
-
Delivery physics
|
|
228
|
-
</h1>
|
|
229
|
-
<p className="text-xs text-[var(--oke-muted)]">
|
|
230
|
-
One list — once · broadcast · live
|
|
231
|
-
</p>
|
|
202
|
+
<p className="text-xs uppercase tracking-[0.2em] text-[var(--oke-muted)]">Signals</p>
|
|
203
|
+
<h1 className="text-xl font-semibold tracking-tight">Delivery physics</h1>
|
|
204
|
+
<p className="text-xs text-[var(--oke-muted)]">One list — once · broadcast · live</p>
|
|
232
205
|
</div>
|
|
233
206
|
<label className="flex flex-col gap-1 text-sm">
|
|
234
207
|
<span className="text-[var(--oke-muted)]">Filter</span>
|
|
@@ -236,9 +209,7 @@ export function SignalsPanel() {
|
|
|
236
209
|
aria-label="Filter signals"
|
|
237
210
|
className="min-h-8 border border-[var(--oke-line)] bg-transparent px-2 text-sm"
|
|
238
211
|
value={search.q ?? ""}
|
|
239
|
-
onChange={(e) =>
|
|
240
|
-
setSearch({ ...search, q: e.target.value || undefined })
|
|
241
|
-
}
|
|
212
|
+
onChange={(e) => setSearch({ ...search, q: e.target.value || undefined })}
|
|
242
213
|
/>
|
|
243
214
|
</label>
|
|
244
215
|
</header>
|
|
@@ -249,13 +220,9 @@ export function SignalsPanel() {
|
|
|
249
220
|
className="min-h-0 overflow-auto border-r border-[var(--oke-line)]"
|
|
250
221
|
>
|
|
251
222
|
{signalsQuery.isLoading ? (
|
|
252
|
-
<p className="px-6 py-8 text-sm text-[var(--oke-muted)]">
|
|
253
|
-
Loading signals…
|
|
254
|
-
</p>
|
|
223
|
+
<p className="px-6 py-8 text-sm text-[var(--oke-muted)]">Loading signals…</p>
|
|
255
224
|
) : groups.length === 0 ? (
|
|
256
|
-
<p className="px-6 py-8 text-sm text-[var(--oke-muted)]">
|
|
257
|
-
No signals declared.
|
|
258
|
-
</p>
|
|
225
|
+
<p className="px-6 py-8 text-sm text-[var(--oke-muted)]">No signals declared.</p>
|
|
259
226
|
) : (
|
|
260
227
|
groups.map((group) => (
|
|
261
228
|
<section
|
|
@@ -283,10 +250,7 @@ export function SignalsPanel() {
|
|
|
283
250
|
<span className="font-medium">
|
|
284
251
|
{s.name}
|
|
285
252
|
{s.orphaned ? (
|
|
286
|
-
<span
|
|
287
|
-
role="status"
|
|
288
|
-
className="ml-2 text-xs text-[var(--oke-muted)]"
|
|
289
|
-
>
|
|
253
|
+
<span role="status" className="ml-2 text-xs text-[var(--oke-muted)]">
|
|
290
254
|
orphaned
|
|
291
255
|
</span>
|
|
292
256
|
) : null}
|
|
@@ -294,8 +258,7 @@ export function SignalsPanel() {
|
|
|
294
258
|
<span className="text-xs text-[var(--oke-muted)]">
|
|
295
259
|
{s.delivery === "once" && (
|
|
296
260
|
<>
|
|
297
|
-
pending {s.pending} · in-flight {s.inflight} ·
|
|
298
|
-
DLQ {s.dead}
|
|
261
|
+
pending {s.pending} · in-flight {s.inflight} · DLQ {s.dead}
|
|
299
262
|
{s.outboxLagMs != null && s.outboxLagMs > 0
|
|
300
263
|
? ` · outbox ${s.outboxLagMs}ms`
|
|
301
264
|
: ""}
|
|
@@ -388,9 +351,7 @@ export function SignalsPanel() {
|
|
|
388
351
|
<div className="flex flex-col gap-2">
|
|
389
352
|
<h3 className="text-sm font-medium">Subscribers</h3>
|
|
390
353
|
<table className="w-full text-left text-sm">
|
|
391
|
-
<caption className="sr-only">
|
|
392
|
-
Per-subscriber lag and errors
|
|
393
|
-
</caption>
|
|
354
|
+
<caption className="sr-only">Per-subscriber lag and errors</caption>
|
|
394
355
|
<thead>
|
|
395
356
|
<tr className="text-[var(--oke-muted)]">
|
|
396
357
|
<th scope="col" className="py-1 font-normal">
|
|
@@ -421,10 +382,7 @@ export function SignalsPanel() {
|
|
|
421
382
|
onClick={() =>
|
|
422
383
|
setSearch({
|
|
423
384
|
...search,
|
|
424
|
-
sub:
|
|
425
|
-
search.sub === sub.id
|
|
426
|
-
? undefined
|
|
427
|
-
: sub.id,
|
|
385
|
+
sub: search.sub === sub.id ? undefined : sub.id,
|
|
428
386
|
})
|
|
429
387
|
}
|
|
430
388
|
>
|
|
@@ -439,10 +397,7 @@ export function SignalsPanel() {
|
|
|
439
397
|
) : null}
|
|
440
398
|
|
|
441
399
|
{open.delivery === "live" ? (
|
|
442
|
-
<section
|
|
443
|
-
aria-label="Payload monitor"
|
|
444
|
-
className="flex flex-col gap-2"
|
|
445
|
-
>
|
|
400
|
+
<section aria-label="Payload monitor" className="flex flex-col gap-2">
|
|
446
401
|
<div className="flex flex-wrap items-center gap-3">
|
|
447
402
|
<h3 className="text-sm font-medium">Payload monitor</h3>
|
|
448
403
|
<span className="text-xs text-[var(--oke-muted)]">
|
|
@@ -466,10 +421,9 @@ export function SignalsPanel() {
|
|
|
466
421
|
type="button"
|
|
467
422
|
variant="ghost"
|
|
468
423
|
onClick={() => {
|
|
469
|
-
const blob = new Blob(
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
);
|
|
424
|
+
const blob = new Blob([exportLivePayloads(monitor.payloads)], {
|
|
425
|
+
type: "application/json",
|
|
426
|
+
});
|
|
473
427
|
const url = URL.createObjectURL(blob);
|
|
474
428
|
const a = document.createElement("a");
|
|
475
429
|
a.href = url;
|
|
@@ -498,10 +452,7 @@ export function SignalsPanel() {
|
|
|
498
452
|
});
|
|
499
453
|
}}
|
|
500
454
|
>
|
|
501
|
-
{(monitor.payloads.length
|
|
502
|
-
? monitor.payloads
|
|
503
|
-
: open.recentLive
|
|
504
|
-
).map((p, i) => (
|
|
455
|
+
{(monitor.payloads.length ? monitor.payloads : open.recentLive).map((p, i) => (
|
|
505
456
|
<li key={i} className="border-b border-[var(--oke-line)]/50 py-1">
|
|
506
457
|
{JSON.stringify(p)}
|
|
507
458
|
</li>
|
|
@@ -569,18 +520,14 @@ export function SignalsPanel() {
|
|
|
569
520
|
|
|
570
521
|
{open.dead > 0 ? (
|
|
571
522
|
<section aria-label="Dead letters" className="flex flex-col gap-3">
|
|
572
|
-
<h3 className="text-sm font-medium">
|
|
573
|
-
Dead letters ({open.dead})
|
|
574
|
-
</h3>
|
|
523
|
+
<h3 className="text-sm font-medium">Dead letters ({open.dead})</h3>
|
|
575
524
|
<p className="text-xs text-[var(--oke-muted)]">
|
|
576
|
-
Bulk repair: dry run first, then replay at a controlled rate
|
|
577
|
-
|
|
525
|
+
Bulk repair: dry run first, then replay at a controlled rate — never an
|
|
526
|
+
unthrottled flood.
|
|
578
527
|
</p>
|
|
579
528
|
<div className="flex flex-wrap items-end gap-3">
|
|
580
529
|
<label className="flex flex-col gap-1 text-sm">
|
|
581
|
-
<span className="text-[var(--oke-muted)]">
|
|
582
|
-
Rate (per second)
|
|
583
|
-
</span>
|
|
530
|
+
<span className="text-[var(--oke-muted)]">Rate (per second)</span>
|
|
584
531
|
<input
|
|
585
532
|
aria-label="Replay rate (per second)"
|
|
586
533
|
type="number"
|
|
@@ -600,9 +547,7 @@ export function SignalsPanel() {
|
|
|
600
547
|
type="button"
|
|
601
548
|
onClick={() => dryRun.mutate()}
|
|
602
549
|
disabled={dryRun.isPending || (dryOffer !== null && !dryOffer.ok)}
|
|
603
|
-
title={
|
|
604
|
-
dryOffer && !dryOffer.ok ? dryOffer.reason : undefined
|
|
605
|
-
}
|
|
550
|
+
title={dryOffer && !dryOffer.ok ? dryOffer.reason : undefined}
|
|
606
551
|
>
|
|
607
552
|
Dry run
|
|
608
553
|
</Button>
|
|
@@ -632,12 +577,11 @@ export function SignalsPanel() {
|
|
|
632
577
|
{dryRunSummary}
|
|
633
578
|
</p>
|
|
634
579
|
) : null}
|
|
635
|
-
{(replayConfirm?.kind === "typed" ||
|
|
636
|
-
discardConfirm?.kind === "typed") && (
|
|
580
|
+
{(replayConfirm?.kind === "typed" || discardConfirm?.kind === "typed") && (
|
|
637
581
|
<div className="flex flex-col gap-2 border border-[var(--oke-line)] p-3">
|
|
638
582
|
<p className="text-xs text-[var(--oke-muted)]">
|
|
639
|
-
This action re-triggers external effects or permanently
|
|
640
|
-
|
|
583
|
+
This action re-triggers external effects or permanently discards messages.
|
|
584
|
+
Type the phrase and a reason.
|
|
641
585
|
</p>
|
|
642
586
|
<label className="flex flex-col gap-1 text-sm">
|
|
643
587
|
Confirmation
|
|
@@ -688,9 +632,7 @@ export function SignalsPanel() {
|
|
|
688
632
|
type="button"
|
|
689
633
|
aria-pressed={d.id === search.dlq}
|
|
690
634
|
className="min-h-8 flex-1 text-left text-sm"
|
|
691
|
-
onClick={() =>
|
|
692
|
-
setSearch(openDeadLetter(search, d.id))
|
|
693
|
-
}
|
|
635
|
+
onClick={() => setSearch(openDeadLetter(search, d.id))}
|
|
694
636
|
>
|
|
695
637
|
<span className="font-mono text-xs">{d.id}</span>
|
|
696
638
|
{last ? (
|
|
@@ -712,9 +654,7 @@ export function SignalsPanel() {
|
|
|
712
654
|
className="flex flex-col gap-3 border-t border-[var(--oke-line)] pt-4"
|
|
713
655
|
>
|
|
714
656
|
<div className="flex items-center justify-between">
|
|
715
|
-
<h3 className="text-sm font-medium">
|
|
716
|
-
Dead letter {dlq.id}
|
|
717
|
-
</h3>
|
|
657
|
+
<h3 className="text-sm font-medium">Dead letter {dlq.id}</h3>
|
|
718
658
|
<Button
|
|
719
659
|
type="button"
|
|
720
660
|
variant="ghost"
|
|
@@ -775,9 +715,7 @@ export function SignalsPanel() {
|
|
|
775
715
|
aria-label="Payload JSON"
|
|
776
716
|
className="min-h-24 border border-[var(--oke-line)] bg-transparent px-2 font-mono text-xs"
|
|
777
717
|
value={formValues._raw ?? ""}
|
|
778
|
-
onChange={(e) =>
|
|
779
|
-
setFormValues({ _raw: e.target.value })
|
|
780
|
-
}
|
|
718
|
+
onChange={(e) => setFormValues({ _raw: e.target.value })}
|
|
781
719
|
rows={4}
|
|
782
720
|
/>
|
|
783
721
|
</label>
|
|
@@ -790,8 +728,7 @@ export function SignalsPanel() {
|
|
|
790
728
|
<ol className="list-decimal space-y-1 pl-5 text-sm">
|
|
791
729
|
{dlq.failures.map((f) => (
|
|
792
730
|
<li key={`${f.attempt}-${f.code}-${f.at}`}>
|
|
793
|
-
Attempt {f.attempt}: <strong>{f.code}</strong> —{
|
|
794
|
-
{f.message}
|
|
731
|
+
Attempt {f.attempt}: <strong>{f.code}</strong> — {f.message}
|
|
795
732
|
</li>
|
|
796
733
|
))}
|
|
797
734
|
</ol>
|