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
|
@@ -14,23 +14,11 @@ export type {
|
|
|
14
14
|
PathologyKind,
|
|
15
15
|
} from "./types.ts";
|
|
16
16
|
|
|
17
|
-
export {
|
|
18
|
-
DEFAULT_LAYERS,
|
|
19
|
-
ELEMENT_LAYERS,
|
|
20
|
-
LAYER_LABEL,
|
|
21
|
-
} from "./types.ts";
|
|
17
|
+
export { DEFAULT_LAYERS, ELEMENT_LAYERS, LAYER_LABEL } from "./types.ts";
|
|
22
18
|
|
|
23
|
-
export {
|
|
24
|
-
isBoundaryExternal,
|
|
25
|
-
labelOfRef,
|
|
26
|
-
layerOfCause,
|
|
27
|
-
layerOfEffectRef,
|
|
28
|
-
} from "./layers.ts";
|
|
19
|
+
export { isBoundaryExternal, labelOfRef, layerOfCause, layerOfEffectRef } from "./layers.ts";
|
|
29
20
|
|
|
30
|
-
export {
|
|
31
|
-
boundaryCrossingCount,
|
|
32
|
-
boundaryCrossingRefs,
|
|
33
|
-
} from "./boundary.ts";
|
|
21
|
+
export { boundaryCrossingCount, boundaryCrossingRefs } from "./boundary.ts";
|
|
34
22
|
|
|
35
23
|
export {
|
|
36
24
|
normalizeTrafficRef,
|
|
@@ -40,11 +28,7 @@ export {
|
|
|
40
28
|
traversalsOf,
|
|
41
29
|
} from "./traffic.ts";
|
|
42
30
|
|
|
43
|
-
export {
|
|
44
|
-
declaredEdgesOf,
|
|
45
|
-
ownerUnitOf,
|
|
46
|
-
unitOfFlowId,
|
|
47
|
-
} from "./declared.ts";
|
|
31
|
+
export { declaredEdgesOf, ownerUnitOf, unitOfFlowId } from "./declared.ts";
|
|
48
32
|
|
|
49
33
|
export {
|
|
50
34
|
computePathologies,
|
|
@@ -54,11 +38,7 @@ export {
|
|
|
54
38
|
findSinglePointsOfFailure,
|
|
55
39
|
} from "./pathologies.ts";
|
|
56
40
|
|
|
57
|
-
export {
|
|
58
|
-
buildArchitectureView,
|
|
59
|
-
setLayer,
|
|
60
|
-
type ArchitectureViewOptions,
|
|
61
|
-
} from "./view.ts";
|
|
41
|
+
export { buildArchitectureView, setLayer, type ArchitectureViewOptions } from "./view.ts";
|
|
62
42
|
|
|
63
43
|
export {
|
|
64
44
|
clearFocus,
|
|
@@ -71,14 +51,6 @@ export {
|
|
|
71
51
|
type ArchitectureSearch,
|
|
72
52
|
} from "./search.ts";
|
|
73
53
|
|
|
74
|
-
export {
|
|
75
|
-
ARCHITECTURE_RUNS_FIXTURE,
|
|
76
|
-
ARCHITECTURE_TEST_MANIFEST,
|
|
77
|
-
} from "./fixture.ts";
|
|
54
|
+
export { ARCHITECTURE_RUNS_FIXTURE, ARCHITECTURE_TEST_MANIFEST } from "./fixture.ts";
|
|
78
55
|
|
|
79
|
-
export {
|
|
80
|
-
layoutNodes,
|
|
81
|
-
SYSTEM_BOUNDARY,
|
|
82
|
-
type BoundaryRect,
|
|
83
|
-
type NodePosition,
|
|
84
|
-
} from "./layout.ts";
|
|
56
|
+
export { layoutNodes, SYSTEM_BOUNDARY, type BoundaryRect, type NodePosition } from "./layout.ts";
|
|
@@ -34,9 +34,7 @@ export const SYSTEM_BOUNDARY: BoundaryRect = {
|
|
|
34
34
|
*
|
|
35
35
|
* @param nodes - Visible nodes
|
|
36
36
|
*/
|
|
37
|
-
export function layoutNodes(
|
|
38
|
-
nodes: readonly ArchitectureNode[],
|
|
39
|
-
): ReadonlyMap<string, NodePosition> {
|
|
37
|
+
export function layoutNodes(nodes: readonly ArchitectureNode[]): ReadonlyMap<string, NodePosition> {
|
|
40
38
|
const inside = nodes.filter((n) => n.insideBoundary);
|
|
41
39
|
const outside = nodes.filter((n) => !n.insideBoundary);
|
|
42
40
|
const map = new Map<string, NodePosition>();
|
|
@@ -14,9 +14,7 @@ import type { ArchitectureFinding } from "./types.ts";
|
|
|
14
14
|
*
|
|
15
15
|
* @param graph - Flows causality graph
|
|
16
16
|
*/
|
|
17
|
-
export function computePathologies(
|
|
18
|
-
graph: CausalityGraph,
|
|
19
|
-
): ArchitectureFinding[] {
|
|
17
|
+
export function computePathologies(graph: CausalityGraph): ArchitectureFinding[] {
|
|
20
18
|
const findings: ArchitectureFinding[] = [];
|
|
21
19
|
findings.push(...findCycles(graph));
|
|
22
20
|
findings.push(...findGodNodes(graph));
|
|
@@ -106,15 +104,16 @@ export function findGodNodes(graph: CausalityGraph): ArchitectureFinding[] {
|
|
|
106
104
|
if (graph.effects.length === 0) return [];
|
|
107
105
|
const ranked = [...graph.effects]
|
|
108
106
|
.filter((e) => e.touchCount > 0)
|
|
109
|
-
.sort(
|
|
110
|
-
(a, b) => b.touchCount - a.touchCount || a.ref.localeCompare(b.ref),
|
|
111
|
-
);
|
|
107
|
+
.sort((a, b) => b.touchCount - a.touchCount || a.ref.localeCompare(b.ref));
|
|
112
108
|
const top = ranked[0];
|
|
113
109
|
if (!top || top.touchCount < 2) return [];
|
|
114
110
|
|
|
115
111
|
// Only flag when clearly dominant (strictly more than the runner-up, or sole)
|
|
116
112
|
const second = ranked[1]?.touchCount ?? 0;
|
|
117
|
-
if (
|
|
113
|
+
if (
|
|
114
|
+
top.touchCount === second &&
|
|
115
|
+
ranked.filter((e) => e.touchCount === top.touchCount).length > 1
|
|
116
|
+
) {
|
|
118
117
|
// Tie for first — report all tied gods
|
|
119
118
|
return ranked
|
|
120
119
|
.filter((e) => e.touchCount === top.touchCount)
|
|
@@ -143,9 +142,7 @@ export function findGodNodes(graph: CausalityGraph): ArchitectureFinding[] {
|
|
|
143
142
|
*
|
|
144
143
|
* @param graph - Causality graph
|
|
145
144
|
*/
|
|
146
|
-
export function findOrphanSignals(
|
|
147
|
-
graph: CausalityGraph,
|
|
148
|
-
): ArchitectureFinding[] {
|
|
145
|
+
export function findOrphanSignals(graph: CausalityGraph): ArchitectureFinding[] {
|
|
149
146
|
const findings: ArchitectureFinding[] = [];
|
|
150
147
|
const signalNames = new Set<string>();
|
|
151
148
|
|
|
@@ -162,12 +159,8 @@ export function findOrphanSignals(
|
|
|
162
159
|
|
|
163
160
|
for (const name of [...signalNames].sort()) {
|
|
164
161
|
const ref = `signal:${name}`;
|
|
165
|
-
const emitters = graph.flows.filter((f) =>
|
|
166
|
-
|
|
167
|
-
);
|
|
168
|
-
const consumers = graph.flows.filter(
|
|
169
|
-
(f) => f.raw.trigger?.signal === name,
|
|
170
|
-
);
|
|
162
|
+
const emitters = graph.flows.filter((f) => (f.raw.effects?.emits ?? []).includes(name));
|
|
163
|
+
const consumers = graph.flows.filter((f) => f.raw.trigger?.signal === name);
|
|
171
164
|
|
|
172
165
|
if (emitters.length === 0 && consumers.length === 0) {
|
|
173
166
|
findings.push({
|
|
@@ -208,9 +201,7 @@ export function findOrphanSignals(
|
|
|
208
201
|
*
|
|
209
202
|
* @param graph - Causality graph
|
|
210
203
|
*/
|
|
211
|
-
export function findSinglePointsOfFailure(
|
|
212
|
-
graph: CausalityGraph,
|
|
213
|
-
): ArchitectureFinding[] {
|
|
204
|
+
export function findSinglePointsOfFailure(graph: CausalityGraph): ArchitectureFinding[] {
|
|
214
205
|
const findings: ArchitectureFinding[] = [];
|
|
215
206
|
|
|
216
207
|
for (const effect of graph.effects) {
|
|
@@ -23,7 +23,8 @@ export const ArchitectureSearchSchema = z.object({
|
|
|
23
23
|
/** Focus node id (`unit:bookings`, `flow:bookings.create`, `sql:bookings`). */
|
|
24
24
|
focus: z.string().optional(),
|
|
25
25
|
/** Neighbourhood depth when focused. */
|
|
26
|
-
depth: z
|
|
26
|
+
depth: z
|
|
27
|
+
.union([z.literal(1), z.literal(2), z.literal("1"), z.literal("2")])
|
|
27
28
|
.transform((v) => (Number(v) === 2 ? 2 : 1) as FocusDepth)
|
|
28
29
|
.default(1),
|
|
29
30
|
/** Data (Store) layer. */
|
|
@@ -51,9 +52,7 @@ export type ArchitectureSearch = {
|
|
|
51
52
|
*
|
|
52
53
|
* @param search - Raw router search
|
|
53
54
|
*/
|
|
54
|
-
export function parseArchitectureSearch(
|
|
55
|
-
search: Record<string, unknown>,
|
|
56
|
-
): ArchitectureSearch {
|
|
55
|
+
export function parseArchitectureSearch(search: Record<string, unknown>): ArchitectureSearch {
|
|
57
56
|
const parsed = ArchitectureSearchSchema.safeParse(search);
|
|
58
57
|
if (!parsed.success) {
|
|
59
58
|
return { depth: 1 };
|
|
@@ -66,9 +65,7 @@ export function parseArchitectureSearch(
|
|
|
66
65
|
*
|
|
67
66
|
* @param search - Search state
|
|
68
67
|
*/
|
|
69
|
-
export function serializeArchitectureSearch(
|
|
70
|
-
search: ArchitectureSearch,
|
|
71
|
-
): Record<string, string> {
|
|
68
|
+
export function serializeArchitectureSearch(search: ArchitectureSearch): Record<string, string> {
|
|
72
69
|
const out: Record<string, string> = {};
|
|
73
70
|
if (search.focus) out.focus = search.focus;
|
|
74
71
|
if (search.depth === 2) out.depth = "2";
|
|
@@ -99,10 +96,7 @@ export function layersOf(search: ArchitectureSearch): LayerFlags {
|
|
|
99
96
|
* @param search - Current search
|
|
100
97
|
* @param focus - Node id
|
|
101
98
|
*/
|
|
102
|
-
export function focusNode(
|
|
103
|
-
search: ArchitectureSearch,
|
|
104
|
-
focus: string,
|
|
105
|
-
): ArchitectureSearch {
|
|
99
|
+
export function focusNode(search: ArchitectureSearch, focus: string): ArchitectureSearch {
|
|
106
100
|
return { ...search, focus };
|
|
107
101
|
}
|
|
108
102
|
|
|
@@ -122,10 +116,7 @@ export function clearFocus(search: ArchitectureSearch): ArchitectureSearch {
|
|
|
122
116
|
* @param search - Current search
|
|
123
117
|
* @param depth - 1 or 2
|
|
124
118
|
*/
|
|
125
|
-
export function setDepth(
|
|
126
|
-
search: ArchitectureSearch,
|
|
127
|
-
depth: FocusDepth,
|
|
128
|
-
): ArchitectureSearch {
|
|
119
|
+
export function setDepth(search: ArchitectureSearch, depth: FocusDepth): ArchitectureSearch {
|
|
129
120
|
return { ...search, depth };
|
|
130
121
|
}
|
|
131
122
|
|
|
@@ -14,17 +14,12 @@ import type { RunRecord } from "../runs/types.ts";
|
|
|
14
14
|
* @param kind - Effect kind from the run ledger
|
|
15
15
|
* @param resource - Raw resource string on the run
|
|
16
16
|
*/
|
|
17
|
-
export function normalizeTrafficRef(
|
|
18
|
-
kind: EffectKind,
|
|
19
|
-
resource: string,
|
|
20
|
-
): string {
|
|
17
|
+
export function normalizeTrafficRef(kind: EffectKind, resource: string): string {
|
|
21
18
|
switch (kind) {
|
|
22
19
|
case "emit":
|
|
23
20
|
return resource.startsWith("signal:") ? resource : `signal:${resource}`;
|
|
24
21
|
case "send":
|
|
25
|
-
return resource.startsWith("channel:")
|
|
26
|
-
? resource
|
|
27
|
-
: `channel:${resource}`;
|
|
22
|
+
return resource.startsWith("channel:") ? resource : `channel:${resource}`;
|
|
28
23
|
case "ask":
|
|
29
24
|
return resource.startsWith("ai:") ? resource : `ai:${resource}`;
|
|
30
25
|
case "secret":
|
|
@@ -51,9 +46,7 @@ export function trafficEdgeKey(flowId: string, ref: string): string {
|
|
|
51
46
|
*
|
|
52
47
|
* @param runs - Wide-event population
|
|
53
48
|
*/
|
|
54
|
-
export function observeTraffic(
|
|
55
|
-
runs: readonly RunRecord[],
|
|
56
|
-
): ReadonlyMap<string, number> {
|
|
49
|
+
export function observeTraffic(runs: readonly RunRecord[]): ReadonlyMap<string, number> {
|
|
57
50
|
const counts = new Map<string, number>();
|
|
58
51
|
for (const run of runs) {
|
|
59
52
|
for (const effect of run.effects) {
|
|
@@ -91,10 +84,7 @@ export function traversalsOf(
|
|
|
91
84
|
* @param traversals - Observed count
|
|
92
85
|
* @param maxTraversals - Max among visible edges (for relative scale)
|
|
93
86
|
*/
|
|
94
|
-
export function thicknessOf(
|
|
95
|
-
traversals: number,
|
|
96
|
-
maxTraversals: number,
|
|
97
|
-
): number {
|
|
87
|
+
export function thicknessOf(traversals: number, maxTraversals: number): number {
|
|
98
88
|
if (traversals <= 0) return 1;
|
|
99
89
|
if (maxTraversals <= 1) return 2;
|
|
100
90
|
const ratio = traversals / maxTraversals;
|
|
@@ -24,11 +24,7 @@ export const LAYER_LABEL: Readonly<Record<ElementLayer, string>> = {
|
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
/** Node kinds on the architecture diagram. */
|
|
27
|
-
export type ArchitectureNodeKind =
|
|
28
|
-
| "unit"
|
|
29
|
-
| "flow"
|
|
30
|
-
| "resource"
|
|
31
|
-
| "external";
|
|
27
|
+
export type ArchitectureNodeKind = "unit" | "flow" | "resource" | "external";
|
|
32
28
|
|
|
33
29
|
/**
|
|
34
30
|
* One node on the architecture diagram.
|
|
@@ -86,11 +82,7 @@ export interface ArchitectureEdge {
|
|
|
86
82
|
}
|
|
87
83
|
|
|
88
84
|
/** Computed pathology kinds (findings list, not decoration). */
|
|
89
|
-
export type PathologyKind =
|
|
90
|
-
| "cycle"
|
|
91
|
-
| "god-node"
|
|
92
|
-
| "orphan-signal"
|
|
93
|
-
| "spof";
|
|
85
|
+
export type PathologyKind = "cycle" | "god-node" | "orphan-signal" | "spof";
|
|
94
86
|
|
|
95
87
|
/** One diagnostic finding from the graph-as-data. */
|
|
96
88
|
export interface ArchitectureFinding {
|
|
@@ -5,16 +5,9 @@
|
|
|
5
5
|
import { describe, expect, test } from "bun:test";
|
|
6
6
|
import { buildCausalityGraph } from "../flows/graph.ts";
|
|
7
7
|
import { boundaryCrossingCount } from "./boundary.ts";
|
|
8
|
-
import {
|
|
9
|
-
ARCHITECTURE_RUNS_FIXTURE,
|
|
10
|
-
ARCHITECTURE_TEST_MANIFEST,
|
|
11
|
-
} from "./fixture.ts";
|
|
8
|
+
import { ARCHITECTURE_RUNS_FIXTURE, ARCHITECTURE_TEST_MANIFEST } from "./fixture.ts";
|
|
12
9
|
import { computePathologies } from "./pathologies.ts";
|
|
13
|
-
import {
|
|
14
|
-
layersOf,
|
|
15
|
-
parseArchitectureSearch,
|
|
16
|
-
serializeArchitectureSearch,
|
|
17
|
-
} from "./search.ts";
|
|
10
|
+
import { layersOf, parseArchitectureSearch, serializeArchitectureSearch } from "./search.ts";
|
|
18
11
|
import { observeTraffic, thicknessOf } from "./traffic.ts";
|
|
19
12
|
import { buildArchitectureView } from "./view.ts";
|
|
20
13
|
|
|
@@ -92,13 +85,10 @@ describe("architecture view", () => {
|
|
|
92
85
|
expect(count).toBe(1); // channel:booking-confirmed
|
|
93
86
|
const view = buildArchitectureView(graph);
|
|
94
87
|
expect(view.boundaryCrossingCount).toBe(count);
|
|
95
|
-
expect(
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
view.nodes.find((n) => n.id === "channel:booking-confirmed")
|
|
100
|
-
?.insideBoundary,
|
|
101
|
-
).toBe(false);
|
|
88
|
+
expect(view.nodes.some((n) => n.id === "channel:booking-confirmed")).toBe(true);
|
|
89
|
+
expect(view.nodes.find((n) => n.id === "channel:booking-confirmed")?.insideBoundary).toBe(
|
|
90
|
+
false,
|
|
91
|
+
);
|
|
102
92
|
});
|
|
103
93
|
|
|
104
94
|
test("edge thickness follows Runs traffic; zero traversals are dashed", () => {
|
|
@@ -122,9 +112,7 @@ describe("architecture view", () => {
|
|
|
122
112
|
expect(kinds.has("god-node")).toBe(true);
|
|
123
113
|
expect(kinds.has("orphan-signal")).toBe(true);
|
|
124
114
|
expect(kinds.has("spof")).toBe(true);
|
|
125
|
-
expect(
|
|
126
|
-
findings.some((f) => f.detail.includes("legacy-unused")),
|
|
127
|
-
).toBe(true);
|
|
115
|
+
expect(findings.some((f) => f.detail.includes("legacy-unused"))).toBe(true);
|
|
128
116
|
});
|
|
129
117
|
});
|
|
130
118
|
|
|
@@ -10,18 +10,10 @@
|
|
|
10
10
|
import type { CausalityGraph } from "../flows/graph.ts";
|
|
11
11
|
import type { RunRecord } from "../runs/types.ts";
|
|
12
12
|
import { boundaryCrossingCount, boundaryCrossingRefs } from "./boundary.ts";
|
|
13
|
-
import {
|
|
14
|
-
declaredEdgesOf,
|
|
15
|
-
type DeclaredEdge,
|
|
16
|
-
unitOfFlowId,
|
|
17
|
-
} from "./declared.ts";
|
|
13
|
+
import { declaredEdgesOf, type DeclaredEdge, unitOfFlowId } from "./declared.ts";
|
|
18
14
|
import { isBoundaryExternal, labelOfRef } from "./layers.ts";
|
|
19
15
|
import { computePathologies } from "./pathologies.ts";
|
|
20
|
-
import {
|
|
21
|
-
observeTraffic,
|
|
22
|
-
thicknessOf,
|
|
23
|
-
traversalsOf,
|
|
24
|
-
} from "./traffic.ts";
|
|
16
|
+
import { observeTraffic, thicknessOf, traversalsOf } from "./traffic.ts";
|
|
25
17
|
import type {
|
|
26
18
|
ArchitectureEdge,
|
|
27
19
|
ArchitectureNode,
|
|
@@ -147,9 +139,7 @@ function buildClusteredView(input: {
|
|
|
147
139
|
if (fromId === toId) continue;
|
|
148
140
|
|
|
149
141
|
const key = `${fromId}\0${toId}\0${edge.layer}`;
|
|
150
|
-
const trav = edge.ref
|
|
151
|
-
? traversalsOf(traffic, edge.flowId, edge.ref)
|
|
152
|
-
: 0;
|
|
142
|
+
const trav = edge.ref ? traversalsOf(traffic, edge.flowId, edge.ref) : 0;
|
|
153
143
|
const existing = agg.get(key);
|
|
154
144
|
if (existing) {
|
|
155
145
|
existing.traversals += trav;
|
|
@@ -186,8 +176,7 @@ function buildFocusedView(input: {
|
|
|
186
176
|
readonly findings: ArchitectureView["findings"];
|
|
187
177
|
readonly crossings: number;
|
|
188
178
|
}): ArchitectureView {
|
|
189
|
-
const { graph, declared, traffic, focus, depth, layers, findings, crossings } =
|
|
190
|
-
input;
|
|
179
|
+
const { graph, declared, traffic, focus, depth, layers, findings, crossings } = input;
|
|
191
180
|
|
|
192
181
|
const neighbourhood = neighbourhoodIds(graph, declared, focus, depth);
|
|
193
182
|
const nodes: ArchitectureNode[] = [];
|
|
@@ -247,11 +236,7 @@ function buildFocusedView(input: {
|
|
|
247
236
|
id,
|
|
248
237
|
kind: isBoundaryExternal(id) ? "external" : "resource",
|
|
249
238
|
label: labelOfRef(id),
|
|
250
|
-
layer: isBoundaryExternal(id)
|
|
251
|
-
? "external"
|
|
252
|
-
: id.startsWith("signal:")
|
|
253
|
-
? "messaging"
|
|
254
|
-
: "data",
|
|
239
|
+
layer: isBoundaryExternal(id) ? "external" : id.startsWith("signal:") ? "messaging" : "data",
|
|
255
240
|
insideBoundary: !isBoundaryExternal(id),
|
|
256
241
|
focused: id === focus,
|
|
257
242
|
depth: hop,
|
|
@@ -283,9 +268,7 @@ function buildFocusedView(input: {
|
|
|
283
268
|
if (!visible.has(from) || !visible.has(to)) continue;
|
|
284
269
|
|
|
285
270
|
const key = `${from}\0${to}\0${edge.layer}`;
|
|
286
|
-
const trav = edge.ref
|
|
287
|
-
? traversalsOf(traffic, edge.flowId, edge.ref)
|
|
288
|
-
: 0;
|
|
271
|
+
const trav = edge.ref ? traversalsOf(traffic, edge.flowId, edge.ref) : 0;
|
|
289
272
|
const existing = edgeAgg.get(key);
|
|
290
273
|
if (existing) {
|
|
291
274
|
existing.traversals += trav;
|
|
@@ -311,10 +294,7 @@ function buildFocusedView(input: {
|
|
|
311
294
|
};
|
|
312
295
|
}
|
|
313
296
|
|
|
314
|
-
function materializeFocusNode(
|
|
315
|
-
graph: CausalityGraph,
|
|
316
|
-
focus: string,
|
|
317
|
-
): ArchitectureNode[] {
|
|
297
|
+
function materializeFocusNode(graph: CausalityGraph, focus: string): ArchitectureNode[] {
|
|
318
298
|
if (focus.startsWith("unit:")) {
|
|
319
299
|
const unit = focus.slice("unit:".length);
|
|
320
300
|
return [
|
|
@@ -455,10 +435,7 @@ function distanceFromFocus(
|
|
|
455
435
|
return maxDepth;
|
|
456
436
|
}
|
|
457
437
|
|
|
458
|
-
function layerVisible(
|
|
459
|
-
layer: ElementLayer | "call",
|
|
460
|
-
layers: LayerFlags,
|
|
461
|
-
): boolean {
|
|
438
|
+
function layerVisible(layer: ElementLayer | "call", layers: LayerFlags): boolean {
|
|
462
439
|
if (layer === "call") return true;
|
|
463
440
|
return layers[layer];
|
|
464
441
|
}
|
|
@@ -507,10 +484,6 @@ function dedupeNodes(nodes: readonly ArchitectureNode[]): ArchitectureNode[] {
|
|
|
507
484
|
* @param layer - Layer to flip
|
|
508
485
|
* @param on - Desired state
|
|
509
486
|
*/
|
|
510
|
-
export function setLayer(
|
|
511
|
-
layers: LayerFlags,
|
|
512
|
-
layer: ElementLayer,
|
|
513
|
-
on: boolean,
|
|
514
|
-
): LayerFlags {
|
|
487
|
+
export function setLayer(layers: LayerFlags, layer: ElementLayer, on: boolean): LayerFlags {
|
|
515
488
|
return { ...layers, [layer]: on };
|
|
516
489
|
}
|
|
@@ -81,9 +81,7 @@ export function ChannelsA11yView(props: ChannelsA11yViewProps) {
|
|
|
81
81
|
{outcomes.map((row) => (
|
|
82
82
|
<tr
|
|
83
83
|
key={row.state}
|
|
84
|
-
data-emphasized={
|
|
85
|
-
isConsequenceEmphasized(row) ? "true" : undefined
|
|
86
|
-
}
|
|
84
|
+
data-emphasized={isConsequenceEmphasized(row) ? "true" : undefined}
|
|
87
85
|
>
|
|
88
86
|
<th scope="row">{STATE_LABEL[row.state]}</th>
|
|
89
87
|
<td>{row.count}</td>
|
|
@@ -103,8 +101,7 @@ export function ChannelsA11yView(props: ChannelsA11yViewProps) {
|
|
|
103
101
|
<section aria-label="Template detail" aria-live="polite">
|
|
104
102
|
<h2>{open.name}</h2>
|
|
105
103
|
<p>
|
|
106
|
-
From {open.from ?? "unset"} · Locales{" "}
|
|
107
|
-
{open.locales.join(", ") || "none"}
|
|
104
|
+
From {open.from ?? "unset"} · Locales {open.locales.join(", ") || "none"}
|
|
108
105
|
</p>
|
|
109
106
|
<section aria-label="Email authentication">
|
|
110
107
|
<h3>SPF / DKIM / DMARC</h3>
|
|
@@ -118,11 +115,7 @@ export function ChannelsA11yView(props: ChannelsA11yViewProps) {
|
|
|
118
115
|
<h3>Preview</h3>
|
|
119
116
|
<p>
|
|
120
117
|
Locale chain:{" "}
|
|
121
|
-
{formatLocaleChainDisplay([
|
|
122
|
-
"profile:ar",
|
|
123
|
-
"accept-language:ar",
|
|
124
|
-
"default:en",
|
|
125
|
-
])}
|
|
118
|
+
{formatLocaleChainDisplay(["profile:ar", "accept-language:ar", "default:en"])}
|
|
126
119
|
</p>
|
|
127
120
|
<div dir={dir} lang={previewLocale}>
|
|
128
121
|
<p>رمز 1234</p>
|
|
@@ -130,9 +123,7 @@ export function ChannelsA11yView(props: ChannelsA11yViewProps) {
|
|
|
130
123
|
</section>
|
|
131
124
|
<section aria-label="Send test">
|
|
132
125
|
<h3>Send test</h3>
|
|
133
|
-
<p role="status">
|
|
134
|
-
Real send to a designated recipient — not a dry run
|
|
135
|
-
</p>
|
|
126
|
+
<p role="status">Real send to a designated recipient — not a dry run</p>
|
|
136
127
|
<label>
|
|
137
128
|
Recipient
|
|
138
129
|
<input aria-label="Test recipient" defaultValue="" />
|
|
@@ -16,8 +16,7 @@ describe("Channels panel accessibility", () => {
|
|
|
16
16
|
let container: HTMLElement;
|
|
17
17
|
|
|
18
18
|
beforeEach(() => {
|
|
19
|
-
(globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT =
|
|
20
|
-
true;
|
|
19
|
+
(globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true;
|
|
21
20
|
window = new Window({ url: "http://console.test/channels" });
|
|
22
21
|
Object.defineProperty(globalThis, "window", {
|
|
23
22
|
value: window,
|
|
@@ -3,10 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { describe, expect, test } from "bun:test";
|
|
6
|
-
import {
|
|
7
|
-
sendTestConfirmation,
|
|
8
|
-
validateTypedConfirm,
|
|
9
|
-
} from "./confirmation.ts";
|
|
6
|
+
import { sendTestConfirmation, validateTypedConfirm } from "./confirmation.ts";
|
|
10
7
|
|
|
11
8
|
describe("sendTestConfirmation", () => {
|
|
12
9
|
test("production requires typed SEND + reason", () => {
|
|
@@ -4,10 +4,7 @@
|
|
|
4
4
|
* Send test is a real external send — typed confirm in production, never stubbed.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import {
|
|
8
|
-
UNDO_WINDOW_MS,
|
|
9
|
-
type ConfirmationPattern,
|
|
10
|
-
} from "../flows/confirmation.ts";
|
|
7
|
+
import { UNDO_WINDOW_MS, type ConfirmationPattern } from "../flows/confirmation.ts";
|
|
11
8
|
|
|
12
9
|
export { UNDO_WINDOW_MS, validateTypedConfirm } from "../flows/confirmation.ts";
|
|
13
10
|
export type { ConfirmationPattern } from "../flows/confirmation.ts";
|
|
@@ -24,11 +24,7 @@ export function spamComplaintFindings(
|
|
|
24
24
|
outcomes: readonly OutcomeRow[],
|
|
25
25
|
): readonly SpamComplaintFinding[] {
|
|
26
26
|
return outcomes
|
|
27
|
-
.filter(
|
|
28
|
-
(r) =>
|
|
29
|
-
r.state === "delivered-then-complained" &&
|
|
30
|
-
isConsequenceEmphasized(r),
|
|
31
|
-
)
|
|
27
|
+
.filter((r) => r.state === "delivered-then-complained" && isConsequenceEmphasized(r))
|
|
32
28
|
.map((r) => ({
|
|
33
29
|
state: "delivered-then-complained" as const,
|
|
34
30
|
count: r.count,
|
|
@@ -24,10 +24,7 @@ export {
|
|
|
24
24
|
VERDICT_LABEL,
|
|
25
25
|
} from "./taxonomy.ts";
|
|
26
26
|
|
|
27
|
-
export {
|
|
28
|
-
spamComplaintFindings,
|
|
29
|
-
type SpamComplaintFinding,
|
|
30
|
-
} from "./findings.ts";
|
|
27
|
+
export { spamComplaintFindings, type SpamComplaintFinding } from "./findings.ts";
|
|
31
28
|
|
|
32
29
|
export { formatFallbackLine } from "./fallback.ts";
|
|
33
30
|
|
|
@@ -51,7 +48,4 @@ export {
|
|
|
51
48
|
|
|
52
49
|
export { filterTemplates } from "./group.ts";
|
|
53
50
|
|
|
54
|
-
export {
|
|
55
|
-
CHANNELS_INBOX_FIXTURE,
|
|
56
|
-
CHANNELS_LIST_FIXTURE,
|
|
57
|
-
} from "./fixture.ts";
|
|
51
|
+
export { CHANNELS_INBOX_FIXTURE, CHANNELS_LIST_FIXTURE } from "./fixture.ts";
|
|
@@ -7,9 +7,7 @@ import { dirForLocale, formatLocaleChainDisplay } from "./locale.ts";
|
|
|
7
7
|
|
|
8
8
|
describe("locale display", () => {
|
|
9
9
|
test("formats chain and detects RTL", () => {
|
|
10
|
-
expect(
|
|
11
|
-
formatLocaleChainDisplay(["profile:ar", "default:en"]),
|
|
12
|
-
).toBe("profile:ar → default:en");
|
|
10
|
+
expect(formatLocaleChainDisplay(["profile:ar", "default:en"])).toBe("profile:ar → default:en");
|
|
13
11
|
expect(dirForLocale("ar")).toBe("rtl");
|
|
14
12
|
expect(dirForLocale("ar-SA")).toBe("rtl");
|
|
15
13
|
expect(dirForLocale("en")).toBe("ltr");
|
|
@@ -7,9 +7,7 @@
|
|
|
7
7
|
*
|
|
8
8
|
* @param chain - Resolution steps
|
|
9
9
|
*/
|
|
10
|
-
export function formatLocaleChainDisplay(
|
|
11
|
-
chain: readonly string[],
|
|
12
|
-
): string {
|
|
10
|
+
export function formatLocaleChainDisplay(chain: readonly string[]): string {
|
|
13
11
|
if (chain.length === 0) return "default";
|
|
14
12
|
return chain.join(" → ");
|
|
15
13
|
}
|
|
@@ -21,11 +19,7 @@ export function formatLocaleChainDisplay(
|
|
|
21
19
|
*/
|
|
22
20
|
export function dirForLocale(locale: string): "ltr" | "rtl" {
|
|
23
21
|
const base = locale.toLowerCase().split("-")[0] ?? locale;
|
|
24
|
-
return base === "ar" ||
|
|
25
|
-
base === "he" ||
|
|
26
|
-
base === "fa" ||
|
|
27
|
-
base === "ur" ||
|
|
28
|
-
base === "yi"
|
|
22
|
+
return base === "ar" || base === "he" || base === "fa" || base === "ur" || base === "yi"
|
|
29
23
|
? "rtl"
|
|
30
24
|
: "ltr";
|
|
31
25
|
}
|
|
@@ -8,9 +8,7 @@ const ChannelsSearchSchema = z.object({
|
|
|
8
8
|
q: z.string().optional(),
|
|
9
9
|
template: z.string().optional(),
|
|
10
10
|
locale: z.string().optional(),
|
|
11
|
-
view: z
|
|
12
|
-
.enum(["inbox", "outcomes", "receipts", "suppression", "preview"])
|
|
13
|
-
.optional(),
|
|
11
|
+
view: z.enum(["inbox", "outcomes", "receipts", "suppression", "preview"]).optional(),
|
|
14
12
|
});
|
|
15
13
|
|
|
16
14
|
/** Parsed Channels URL search. */
|
|
@@ -21,9 +19,7 @@ export type ChannelsSearch = z.infer<typeof ChannelsSearchSchema>;
|
|
|
21
19
|
*
|
|
22
20
|
* @param search - Raw router search
|
|
23
21
|
*/
|
|
24
|
-
export function parseChannelsSearch(
|
|
25
|
-
search: Record<string, unknown>,
|
|
26
|
-
): ChannelsSearch {
|
|
22
|
+
export function parseChannelsSearch(search: Record<string, unknown>): ChannelsSearch {
|
|
27
23
|
const parsed = ChannelsSearchSchema.safeParse(search);
|
|
28
24
|
return parsed.success ? parsed.data : {};
|
|
29
25
|
}
|
|
@@ -33,9 +29,7 @@ export function parseChannelsSearch(
|
|
|
33
29
|
*
|
|
34
30
|
* @param search - Search state
|
|
35
31
|
*/
|
|
36
|
-
export function serializeChannelsSearch(
|
|
37
|
-
search: ChannelsSearch,
|
|
38
|
-
): Record<string, string> {
|
|
32
|
+
export function serializeChannelsSearch(search: ChannelsSearch): Record<string, string> {
|
|
39
33
|
const out: Record<string, string> = {};
|
|
40
34
|
if (search.q) out.q = search.q;
|
|
41
35
|
if (search.template) out.template = search.template;
|
|
@@ -50,9 +44,6 @@ export function serializeChannelsSearch(
|
|
|
50
44
|
* @param search - Current search
|
|
51
45
|
* @param template - Template name
|
|
52
46
|
*/
|
|
53
|
-
export function openTemplate(
|
|
54
|
-
search: ChannelsSearch,
|
|
55
|
-
template: string,
|
|
56
|
-
): ChannelsSearch {
|
|
47
|
+
export function openTemplate(search: ChannelsSearch, template: string): ChannelsSearch {
|
|
57
48
|
return { ...search, template };
|
|
58
49
|
}
|
|
@@ -30,9 +30,7 @@ export const VERDICT_LABEL: Readonly<Record<DeliveryVerdict, string>> = {
|
|
|
30
30
|
*
|
|
31
31
|
* @param rows - Outcome rows
|
|
32
32
|
*/
|
|
33
|
-
export function sortByConsequence(
|
|
34
|
-
rows: readonly OutcomeRow[],
|
|
35
|
-
): readonly OutcomeRow[] {
|
|
33
|
+
export function sortByConsequence(rows: readonly OutcomeRow[]): readonly OutcomeRow[] {
|
|
36
34
|
return [...rows].sort((a, b) => {
|
|
37
35
|
if (b.weight !== a.weight) return b.weight - a.weight;
|
|
38
36
|
return b.count - a.count;
|