okengine 0.1.4
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 +91 -0
- package/README.md +327 -0
- package/docs/spec/complete-example.md +1188 -0
- package/docs/spec/console.md +739 -0
- package/docs/spec/four-applications.md +1188 -0
- package/docs/spec/unified-theory.md +489 -0
- package/package.json +152 -0
- package/spec/manifest.v1.schema.json +624 -0
- package/src/auth/api-keys.ts +168 -0
- package/src/auth/attenuation.ts +116 -0
- package/src/auth/auth.test.ts +273 -0
- package/src/auth/cross-plane.ts +98 -0
- package/src/auth/index.ts +112 -0
- package/src/auth/invites.ts +66 -0
- package/src/auth/invoke-as.ts +49 -0
- package/src/auth/operator.ts +178 -0
- package/src/auth/planes.ts +102 -0
- package/src/auth/plugin.ts +44 -0
- package/src/auth/roles.ts +84 -0
- package/src/auth/sessions.ts +418 -0
- package/src/auth/tables.ts +131 -0
- package/src/cli/args.ts +50 -0
- package/src/cli/branch.ts +75 -0
- package/src/cli/build.ts +86 -0
- package/src/cli/client-add.test.ts +140 -0
- package/src/cli/client-add.ts +164 -0
- package/src/cli/completion.test.ts +58 -0
- package/src/cli/completion.ts +296 -0
- package/src/cli/dev-app-runner.ts +77 -0
- package/src/cli/dev.test.ts +435 -0
- package/src/cli/dev.ts +594 -0
- package/src/cli/doc-drift.test.ts +146 -0
- package/src/cli/doc-drift.ts +397 -0
- package/src/cli/docker-cli.test.ts +221 -0
- package/src/cli/docker.ts +127 -0
- package/src/cli/doctor-diff-examples.ts +92 -0
- package/src/cli/doctor-diff.test.ts +91 -0
- package/src/cli/doctor-diff.ts +274 -0
- package/src/cli/doctor-pii.test.ts +98 -0
- package/src/cli/doctor-pii.ts +151 -0
- package/src/cli/doctor.test.ts +150 -0
- package/src/cli/doctor.ts +223 -0
- package/src/cli/eval.ts +122 -0
- package/src/cli/exit.ts +19 -0
- package/src/cli/gates-list.test.ts +47 -0
- package/src/cli/gates-list.ts +84 -0
- package/src/cli/images.ts +277 -0
- package/src/cli/index.ts +99 -0
- package/src/cli/json-out.test.ts +129 -0
- package/src/cli/load-config.ts +71 -0
- package/src/cli/mcp-from-console.ts +50 -0
- package/src/cli/privacy-erase.ts +73 -0
- package/src/cli/registry.ts +455 -0
- package/src/cli/safe-defaults.test.ts +92 -0
- package/src/cli/schema.ts +196 -0
- package/src/cli/stack.ts +82 -0
- package/src/cli/start.ts +106 -0
- package/src/cli/upgrade.ts +105 -0
- package/src/cli/vault-cmd.ts +140 -0
- package/src/client/budget-entry.ts +34 -0
- package/src/client/budget.test.ts +17 -0
- package/src/client/create.test.ts +159 -0
- package/src/client/create.ts +152 -0
- package/src/client/errors.ts +60 -0
- package/src/client/index.ts +35 -0
- package/src/client/notes-contract.test.ts +289 -0
- package/src/client/transport.test.ts +123 -0
- package/src/client/transport.ts +254 -0
- package/src/client/types.ts +282 -0
- package/src/compiler/aot.test.ts +248 -0
- package/src/compiler/aot.ts +182 -0
- package/src/compiler/differential.test.ts +241 -0
- package/src/compiler/dynamic.ts +54 -0
- package/src/compiler/effects-infer.ts +541 -0
- package/src/compiler/emit.ts +40 -0
- package/src/compiler/extract.test.ts +177 -0
- package/src/compiler/extract.ts +1368 -0
- package/src/compiler/fixtures/raw/raw-unannotated.ts +28 -0
- package/src/compiler/fixtures/skyport/oke.config.ts +24 -0
- package/src/compiler/fixtures/skyport/src/ai.ts +15 -0
- package/src/compiler/fixtures/skyport/src/app.ts +10 -0
- package/src/compiler/fixtures/skyport/src/channels.ts +6 -0
- package/src/compiler/fixtures/skyport/src/core.ts +3 -0
- package/src/compiler/fixtures/skyport/src/flows/bookings/index.ts +57 -0
- package/src/compiler/fixtures/skyport/src/flows/bookings/signals.ts +11 -0
- package/src/compiler/fixtures/skyport/src/flows/payments/index.ts +14 -0
- package/src/compiler/fixtures/skyport/src/flows/support/index.ts +20 -0
- package/src/compiler/fixtures/skyport/src/gates.ts +14 -0
- package/src/compiler/fixtures/skyport/src/journeys.ts +9 -0
- package/src/compiler/fixtures/skyport/src/schema.ts +3 -0
- package/src/compiler/fixtures/skyport/src/vault.ts +6 -0
- package/src/compiler/fixtures/skyport.expected.json +241 -0
- package/src/compiler/fixtures/triggers/five-triggers.ts +69 -0
- package/src/compiler/http-parse.ts +214 -0
- package/src/compiler/index.ts +67 -0
- package/src/compiler/response.ts +89 -0
- package/src/compiler/sucrose.ts +238 -0
- package/src/config/index.ts +167 -0
- package/src/console/budget.test.ts +73 -0
- package/src/console/index.ts +30 -0
- package/src/console/server/access.test.ts +370 -0
- package/src/console/server/access.ts +777 -0
- package/src/console/server/ai.test.ts +172 -0
- package/src/console/server/ai.ts +632 -0
- package/src/console/server/app.ts +294 -0
- package/src/console/server/auth-rate.test.ts +81 -0
- package/src/console/server/auth-rate.ts +72 -0
- package/src/console/server/bind.ts +25 -0
- package/src/console/server/channels.test.ts +179 -0
- package/src/console/server/channels.ts +469 -0
- package/src/console/server/claim.test.ts +66 -0
- package/src/console/server/claim.ts +134 -0
- package/src/console/server/clock.test.ts +239 -0
- package/src/console/server/clock.ts +390 -0
- package/src/console/server/console.test.ts +338 -0
- package/src/console/server/diff.test.ts +299 -0
- package/src/console/server/diff.ts +352 -0
- package/src/console/server/dry-run.audit.test.ts +118 -0
- package/src/console/server/flows-invoke.test.ts +148 -0
- package/src/console/server/flows.ts +3633 -0
- package/src/console/server/gates.test.ts +360 -0
- package/src/console/server/gates.ts +869 -0
- package/src/console/server/index.ts +141 -0
- package/src/console/server/live.test.ts +30 -0
- package/src/console/server/live.ts +109 -0
- package/src/console/server/plugin.ts +50 -0
- package/src/console/server/plugins.test.ts +131 -0
- package/src/console/server/plugins.ts +429 -0
- package/src/console/server/runs-pii.ts +98 -0
- package/src/console/server/security-headers.ts +97 -0
- package/src/console/server/security.gate.test.ts +286 -0
- package/src/console/server/serve.ts +319 -0
- package/src/console/server/signals.test.ts +88 -0
- package/src/console/server/signals.ts +282 -0
- package/src/console/server/state.ts +982 -0
- package/src/console/server/store.test.ts +233 -0
- package/src/console/server/store.ts +861 -0
- package/src/console/server/structural.ts +95 -0
- package/src/console/server/vault.test.ts +251 -0
- package/src/console/server/vault.ts +430 -0
- package/src/console/ui/access/AccessA11yView.tsx +237 -0
- package/src/console/ui/access/a11y.test.tsx +122 -0
- package/src/console/ui/access/acknowledgement.test.ts +13 -0
- package/src/console/ui/access/acknowledgement.ts +35 -0
- package/src/console/ui/access/blast-radius.test.ts +26 -0
- package/src/console/ui/access/blast-radius.ts +40 -0
- package/src/console/ui/access/confirmation.test.ts +38 -0
- package/src/console/ui/access/confirmation.ts +36 -0
- package/src/console/ui/access/fixture.ts +203 -0
- package/src/console/ui/access/grantable.test.ts +17 -0
- package/src/console/ui/access/grantable.ts +36 -0
- package/src/console/ui/access/hygiene.test.ts +12 -0
- package/src/console/ui/access/hygiene.ts +39 -0
- package/src/console/ui/access/index.ts +54 -0
- package/src/console/ui/access/provenance.test.ts +12 -0
- package/src/console/ui/access/provenance.ts +29 -0
- package/src/console/ui/access/search.test.ts +17 -0
- package/src/console/ui/access/search.ts +72 -0
- package/src/console/ui/access/types.ts +111 -0
- package/src/console/ui/ai/AiA11yView.tsx +265 -0
- package/src/console/ui/ai/a11y.test.tsx +99 -0
- package/src/console/ui/ai/findings.ts +41 -0
- package/src/console/ui/ai/fixture.ts +182 -0
- package/src/console/ui/ai/format.ts +90 -0
- package/src/console/ui/ai/group.test.ts +37 -0
- package/src/console/ui/ai/group.ts +88 -0
- package/src/console/ui/ai/index.ts +66 -0
- package/src/console/ui/ai/promotion.test.ts +77 -0
- package/src/console/ui/ai/promotion.ts +150 -0
- package/src/console/ui/ai/search.test.ts +40 -0
- package/src/console/ui/ai/search.ts +89 -0
- package/src/console/ui/ai/types.ts +139 -0
- package/src/console/ui/architecture/ArchitectureA11yView.tsx +163 -0
- package/src/console/ui/architecture/a11y.test.tsx +97 -0
- package/src/console/ui/architecture/boundary.ts +42 -0
- package/src/console/ui/architecture/declared.ts +165 -0
- package/src/console/ui/architecture/fixture.ts +74 -0
- package/src/console/ui/architecture/index.ts +84 -0
- package/src/console/ui/architecture/layers.ts +64 -0
- package/src/console/ui/architecture/layout.ts +68 -0
- package/src/console/ui/architecture/pathologies.ts +260 -0
- package/src/console/ui/architecture/search.ts +145 -0
- package/src/console/ui/architecture/traffic.ts +102 -0
- package/src/console/ui/architecture/types.ts +144 -0
- package/src/console/ui/architecture/view.test.ts +165 -0
- package/src/console/ui/architecture/view.ts +516 -0
- package/src/console/ui/channels/ChannelsA11yView.tsx +180 -0
- package/src/console/ui/channels/a11y.test.tsx +96 -0
- package/src/console/ui/channels/confirmation.test.ts +37 -0
- package/src/console/ui/channels/confirmation.ts +27 -0
- package/src/console/ui/channels/fallback.test.ts +15 -0
- package/src/console/ui/channels/fallback.ts +20 -0
- package/src/console/ui/channels/findings.ts +38 -0
- package/src/console/ui/channels/fixture.ts +134 -0
- package/src/console/ui/channels/group.ts +25 -0
- package/src/console/ui/channels/index.ts +57 -0
- package/src/console/ui/channels/locale.test.ts +17 -0
- package/src/console/ui/channels/locale.ts +31 -0
- package/src/console/ui/channels/mask.test.ts +14 -0
- package/src/console/ui/channels/mask.ts +12 -0
- package/src/console/ui/channels/search.ts +58 -0
- package/src/console/ui/channels/taxonomy.test.ts +17 -0
- package/src/console/ui/channels/taxonomy.ts +49 -0
- package/src/console/ui/channels/types.ts +117 -0
- package/src/console/ui/clock/ClockA11yView.tsx +182 -0
- package/src/console/ui/clock/a11y.test.tsx +99 -0
- package/src/console/ui/clock/confirmation.test.ts +32 -0
- package/src/console/ui/clock/confirmation.ts +34 -0
- package/src/console/ui/clock/findings.ts +40 -0
- package/src/console/ui/clock/fixture.ts +111 -0
- package/src/console/ui/clock/health.test.ts +25 -0
- package/src/console/ui/clock/health.ts +61 -0
- package/src/console/ui/clock/index.ts +49 -0
- package/src/console/ui/clock/search.test.ts +39 -0
- package/src/console/ui/clock/search.ts +76 -0
- package/src/console/ui/clock/timeline.test.ts +44 -0
- package/src/console/ui/clock/timeline.ts +41 -0
- package/src/console/ui/clock/types.ts +78 -0
- package/src/console/ui/clock/waiting-on.test.ts +34 -0
- package/src/console/ui/clock/waiting-on.ts +83 -0
- package/src/console/ui/confirmation.unify.test.ts +92 -0
- package/src/console/ui/diff/DiffA11yView.tsx +85 -0
- package/src/console/ui/diff/a11y.test.tsx +99 -0
- package/src/console/ui/diff/fixture.ts +85 -0
- package/src/console/ui/diff/group.test.ts +58 -0
- package/src/console/ui/diff/group.ts +97 -0
- package/src/console/ui/diff/index.ts +38 -0
- package/src/console/ui/diff/search.test.ts +32 -0
- package/src/console/ui/diff/search.ts +75 -0
- package/src/console/ui/diff/summary.ts +74 -0
- package/src/console/ui/diff/types.ts +48 -0
- package/src/console/ui/dist/assets/index-B71Yl_SS.js +10 -0
- package/src/console/ui/dist/assets/panel-access-Dd37LU2c.js +64 -0
- package/src/console/ui/dist/assets/panel-ai-CC7LR6-J.js +1 -0
- package/src/console/ui/dist/assets/panel-architecture-B5b3iKCz.js +1 -0
- package/src/console/ui/dist/assets/panel-channels-CeNjTKXp.js +1 -0
- package/src/console/ui/dist/assets/panel-clock-DgFTLoHV.js +1 -0
- package/src/console/ui/dist/assets/panel-diff-DxehccqB.js +1 -0
- package/src/console/ui/dist/assets/panel-flows-BtrVn-Eg.js +45 -0
- package/src/console/ui/dist/assets/panel-gates-Z9MKRGdH.js +1 -0
- package/src/console/ui/dist/assets/panel-overview-Bd48d9km.js +1 -0
- package/src/console/ui/dist/assets/panel-plugins-DWd0TowH.js +1 -0
- package/src/console/ui/dist/assets/panel-runs-BwsWqKeB.js +1 -0
- package/src/console/ui/dist/assets/panel-signals-9najbZY2.js +1 -0
- package/src/console/ui/dist/assets/panel-store-OHkP2pDp.js +1 -0
- package/src/console/ui/dist/assets/panel-traces-tn2JoY8U.js +1 -0
- package/src/console/ui/dist/assets/panel-vault-BbfWdox0.js +1 -0
- package/src/console/ui/dist/assets/rolldown-runtime-CNC7AqOf.js +1 -0
- package/src/console/ui/dist/assets/style-Cnl7WLya.css +3 -0
- package/src/console/ui/dist/index.html +14 -0
- package/src/console/ui/flows/FlowsA11yView.tsx +155 -0
- package/src/console/ui/flows/a11y.test.tsx +105 -0
- package/src/console/ui/flows/buffer.test.ts +91 -0
- package/src/console/ui/flows/buffer.ts +118 -0
- package/src/console/ui/flows/confirmation.ts +131 -0
- package/src/console/ui/flows/contract.test.ts +89 -0
- package/src/console/ui/flows/contract.ts +353 -0
- package/src/console/ui/flows/fixture.ts +81 -0
- package/src/console/ui/flows/graph.test.ts +101 -0
- package/src/console/ui/flows/graph.ts +549 -0
- package/src/console/ui/flows/index.ts +87 -0
- package/src/console/ui/flows/save-as-test.test.ts +47 -0
- package/src/console/ui/flows/save-as-test.ts +99 -0
- package/src/console/ui/flows/search.ts +255 -0
- package/src/console/ui/flows/tiers.ts +140 -0
- package/src/console/ui/gates/GatesA11yView.tsx +192 -0
- package/src/console/ui/gates/a11y.test.tsx +116 -0
- package/src/console/ui/gates/audit.test.ts +40 -0
- package/src/console/ui/gates/audit.ts +63 -0
- package/src/console/ui/gates/denial.test.ts +36 -0
- package/src/console/ui/gates/denial.ts +51 -0
- package/src/console/ui/gates/findings.ts +19 -0
- package/src/console/ui/gates/fixture.ts +189 -0
- package/src/console/ui/gates/group.test.ts +30 -0
- package/src/console/ui/gates/group.ts +102 -0
- package/src/console/ui/gates/index.ts +47 -0
- package/src/console/ui/gates/search.test.ts +49 -0
- package/src/console/ui/gates/search.ts +115 -0
- package/src/console/ui/gates/types.ts +121 -0
- package/src/console/ui/overview/OverviewA11yView.tsx +152 -0
- package/src/console/ui/overview/a11y.test.tsx +113 -0
- package/src/console/ui/overview/busiest.ts +26 -0
- package/src/console/ui/overview/compose.ts +133 -0
- package/src/console/ui/overview/cost.test.ts +39 -0
- package/src/console/ui/overview/cost.ts +138 -0
- package/src/console/ui/overview/fixture.ts +161 -0
- package/src/console/ui/overview/golden.ts +57 -0
- package/src/console/ui/overview/index.ts +59 -0
- package/src/console/ui/overview/rank.test.ts +136 -0
- package/src/console/ui/overview/rank.ts +210 -0
- package/src/console/ui/overview/slo.test.ts +73 -0
- package/src/console/ui/overview/slo.ts +229 -0
- package/src/console/ui/overview/types.ts +121 -0
- package/src/console/ui/overview/verdict.ts +131 -0
- package/src/console/ui/plugins/PluginsA11yView.tsx +227 -0
- package/src/console/ui/plugins/a11y.test.tsx +97 -0
- package/src/console/ui/plugins/command.test.ts +22 -0
- package/src/console/ui/plugins/command.ts +27 -0
- package/src/console/ui/plugins/findings.ts +39 -0
- package/src/console/ui/plugins/fixture.ts +233 -0
- package/src/console/ui/plugins/group.test.ts +38 -0
- package/src/console/ui/plugins/group.ts +67 -0
- package/src/console/ui/plugins/index.ts +40 -0
- package/src/console/ui/plugins/search.ts +67 -0
- package/src/console/ui/plugins/types.ts +115 -0
- package/src/console/ui/runs/RunsA11yView.tsx +267 -0
- package/src/console/ui/runs/a11y.test.tsx +99 -0
- package/src/console/ui/runs/explain.test.ts +23 -0
- package/src/console/ui/runs/explain.ts +32 -0
- package/src/console/ui/runs/fixture.ts +189 -0
- package/src/console/ui/runs/group.test.ts +24 -0
- package/src/console/ui/runs/group.ts +85 -0
- package/src/console/ui/runs/histogram.test.ts +31 -0
- package/src/console/ui/runs/histogram.ts +85 -0
- package/src/console/ui/runs/index.ts +75 -0
- package/src/console/ui/runs/project.ts +122 -0
- package/src/console/ui/runs/query.test.ts +50 -0
- package/src/console/ui/runs/query.ts +283 -0
- package/src/console/ui/runs/search.test.ts +45 -0
- package/src/console/ui/runs/search.ts +141 -0
- package/src/console/ui/runs/trace-link.test.ts +30 -0
- package/src/console/ui/runs/trace-link.ts +99 -0
- package/src/console/ui/runs/types.ts +137 -0
- package/src/console/ui/shell/App.tsx +56 -0
- package/src/console/ui/shell/client.ts +1715 -0
- package/src/console/ui/shell/components/ui.tsx +110 -0
- package/src/console/ui/shell/index.html +12 -0
- package/src/console/ui/shell/layout/Shell.tsx +95 -0
- package/src/console/ui/shell/main.tsx +281 -0
- package/src/console/ui/shell/panels/Access.tsx +5 -0
- package/src/console/ui/shell/panels/Ai.tsx +5 -0
- package/src/console/ui/shell/panels/Architecture.tsx +5 -0
- package/src/console/ui/shell/panels/Channels.tsx +5 -0
- package/src/console/ui/shell/panels/Clock.tsx +5 -0
- package/src/console/ui/shell/panels/Diff.tsx +5 -0
- package/src/console/ui/shell/panels/Flows.tsx +5 -0
- package/src/console/ui/shell/panels/Gates.tsx +5 -0
- package/src/console/ui/shell/panels/Overview.tsx +6 -0
- package/src/console/ui/shell/panels/Plugins.tsx +5 -0
- package/src/console/ui/shell/panels/Runs.tsx +5 -0
- package/src/console/ui/shell/panels/Signals.tsx +5 -0
- package/src/console/ui/shell/panels/Store.tsx +5 -0
- package/src/console/ui/shell/panels/Traces.tsx +5 -0
- package/src/console/ui/shell/panels/Vault.tsx +5 -0
- package/src/console/ui/shell/panels/access/AccessPanel.tsx +813 -0
- package/src/console/ui/shell/panels/ai/AiPanel.tsx +563 -0
- package/src/console/ui/shell/panels/architecture/ArchitecturePanel.tsx +377 -0
- package/src/console/ui/shell/panels/channels/ChannelsPanel.tsx +454 -0
- package/src/console/ui/shell/panels/clock/ClockPanel.tsx +479 -0
- package/src/console/ui/shell/panels/diff/DiffPanel.tsx +275 -0
- package/src/console/ui/shell/panels/flows/ContractEditor.tsx +301 -0
- package/src/console/ui/shell/panels/flows/FlowDrawer.tsx +350 -0
- package/src/console/ui/shell/panels/flows/FlowsPanel.tsx +502 -0
- package/src/console/ui/shell/panels/gates/GatesPanel.tsx +482 -0
- package/src/console/ui/shell/panels/overview/OverviewPanel.tsx +428 -0
- package/src/console/ui/shell/panels/plugins/PluginsPanel.tsx +413 -0
- package/src/console/ui/shell/panels/runs/RunsPanel.tsx +649 -0
- package/src/console/ui/shell/panels/signals/SignalsPanel.tsx +840 -0
- package/src/console/ui/shell/panels/store/StorePanel.tsx +787 -0
- package/src/console/ui/shell/panels/traces/TracesPanel.tsx +539 -0
- package/src/console/ui/shell/panels/vault/VaultPanel.tsx +449 -0
- package/src/console/ui/shell/plugin/Sandbox.tsx +29 -0
- package/src/console/ui/shell/setup/Wizard.tsx +189 -0
- package/src/console/ui/shell/styles.css +75 -0
- package/src/console/ui/signals/SignalsA11yView.tsx +276 -0
- package/src/console/ui/signals/a11y.test.tsx +99 -0
- package/src/console/ui/signals/confirmation.test.ts +39 -0
- package/src/console/ui/signals/confirmation.ts +63 -0
- package/src/console/ui/signals/dry-run.test.ts +18 -0
- package/src/console/ui/signals/dry-run.ts +36 -0
- package/src/console/ui/signals/durable.test.ts +22 -0
- package/src/console/ui/signals/durable.ts +41 -0
- package/src/console/ui/signals/findings.ts +33 -0
- package/src/console/ui/signals/fixture.ts +242 -0
- package/src/console/ui/signals/group.test.ts +32 -0
- package/src/console/ui/signals/group.ts +49 -0
- package/src/console/ui/signals/index.ts +52 -0
- package/src/console/ui/signals/monitor.test.ts +30 -0
- package/src/console/ui/signals/monitor.ts +79 -0
- package/src/console/ui/signals/schema-form.test.ts +34 -0
- package/src/console/ui/signals/schema-form.ts +112 -0
- package/src/console/ui/signals/search.ts +102 -0
- package/src/console/ui/signals/types.ts +71 -0
- package/src/console/ui/store/StoreA11yView.tsx +199 -0
- package/src/console/ui/store/a11y.test.tsx +99 -0
- package/src/console/ui/store/cache-view.test.ts +13 -0
- package/src/console/ui/store/cache-view.ts +36 -0
- package/src/console/ui/store/confirmation.test.ts +38 -0
- package/src/console/ui/store/confirmation.ts +55 -0
- package/src/console/ui/store/dry-run.test.ts +15 -0
- package/src/console/ui/store/dry-run.ts +29 -0
- package/src/console/ui/store/fixture.ts +163 -0
- package/src/console/ui/store/group.test.ts +21 -0
- package/src/console/ui/store/group.ts +41 -0
- package/src/console/ui/store/index.ts +40 -0
- package/src/console/ui/store/search.ts +78 -0
- package/src/console/ui/store/types.ts +65 -0
- package/src/console/ui/store/will-not-fire.test.ts +19 -0
- package/src/console/ui/store/will-not-fire.ts +40 -0
- package/src/console/ui/traces/TracesA11yView.tsx +200 -0
- package/src/console/ui/traces/a11y.test.tsx +97 -0
- package/src/console/ui/traces/chain.test.ts +61 -0
- package/src/console/ui/traces/chain.ts +144 -0
- package/src/console/ui/traces/critical-path.test.ts +24 -0
- package/src/console/ui/traces/critical-path.ts +59 -0
- package/src/console/ui/traces/filter.test.ts +78 -0
- package/src/console/ui/traces/filter.ts +112 -0
- package/src/console/ui/traces/fixture.ts +126 -0
- package/src/console/ui/traces/fold.test.ts +67 -0
- package/src/console/ui/traces/fold.ts +170 -0
- package/src/console/ui/traces/index.ts +64 -0
- package/src/console/ui/traces/mini.ts +65 -0
- package/src/console/ui/traces/replay.test.ts +24 -0
- package/src/console/ui/traces/replay.ts +35 -0
- package/src/console/ui/traces/sampling.test.ts +26 -0
- package/src/console/ui/traces/sampling.ts +66 -0
- package/src/console/ui/traces/search.ts +148 -0
- package/src/console/ui/traces/tier.ts +72 -0
- package/src/console/ui/traces/types.ts +125 -0
- package/src/console/ui/tsconfig.json +20 -0
- package/src/console/ui/vault/VaultA11yView.tsx +177 -0
- package/src/console/ui/vault/a11y.test.tsx +97 -0
- package/src/console/ui/vault/blast-radius.test.ts +35 -0
- package/src/console/ui/vault/blast-radius.ts +55 -0
- package/src/console/ui/vault/confirmation.test.ts +41 -0
- package/src/console/ui/vault/confirmation.ts +39 -0
- package/src/console/ui/vault/dormant.test.ts +37 -0
- package/src/console/ui/vault/dormant.ts +28 -0
- package/src/console/ui/vault/export-safe.test.ts +30 -0
- package/src/console/ui/vault/export-safe.ts +65 -0
- package/src/console/ui/vault/fixture.ts +75 -0
- package/src/console/ui/vault/group.test.ts +25 -0
- package/src/console/ui/vault/group.ts +50 -0
- package/src/console/ui/vault/index.ts +45 -0
- package/src/console/ui/vault/search.ts +62 -0
- package/src/console/ui/vault/types.ts +57 -0
- package/src/console/ui/vite.config.ts +84 -0
- package/src/console/xss.gate.test.ts +118 -0
- package/src/docker/compose.ts +226 -0
- package/src/docker/credentials.ts +25 -0
- package/src/docker/derive.ts +83 -0
- package/src/docker/docker.test.ts +185 -0
- package/src/docker/dockerfile.integration.test.ts +170 -0
- package/src/docker/dockerfile.ts +39 -0
- package/src/docker/helpers.ts +103 -0
- package/src/docker/index.ts +52 -0
- package/src/docker/pin.ts +90 -0
- package/src/docker/recipes/index.ts +33 -0
- package/src/docker/recipes/postgres.ts +18 -0
- package/src/docker/recipes/redis.ts +18 -0
- package/src/docker/stack.integration.test.ts +140 -0
- package/src/docker/stack.ts +62 -0
- package/src/docker/types.ts +134 -0
- package/src/drivers/ai-anthropic.ts +128 -0
- package/src/drivers/ai-mock.ts +82 -0
- package/src/drivers/ai-openai-compatible.ts +139 -0
- package/src/drivers/ai-providers.test.ts +163 -0
- package/src/drivers/ai-types.ts +83 -0
- package/src/drivers/bun-native-completeness.test.ts +155 -0
- package/src/drivers/channel-console.ts +118 -0
- package/src/drivers/channel-fcm.ts +96 -0
- package/src/drivers/channel-resend.ts +27 -0
- package/src/drivers/channel-smtp.ts +33 -0
- package/src/drivers/channel-types.ts +160 -0
- package/src/drivers/channel-unifonic.ts +79 -0
- package/src/drivers/channel-wa-cloud.ts +84 -0
- package/src/drivers/channel-webpush.ts +317 -0
- package/src/drivers/conformance.test.ts +89 -0
- package/src/drivers/conformance.ts +162 -0
- package/src/drivers/fs.ts +73 -0
- package/src/drivers/index.ts +194 -0
- package/src/drivers/kv-lua.ts +222 -0
- package/src/drivers/memory.ts +472 -0
- package/src/drivers/pgvector.ts +130 -0
- package/src/drivers/postgres.ts +221 -0
- package/src/drivers/redis.ts +254 -0
- package/src/drivers/s3.ts +129 -0
- package/src/drivers/signal-engine.ts +690 -0
- package/src/drivers/signal-memory.ts +27 -0
- package/src/drivers/signal-nats.ts +131 -0
- package/src/drivers/signal-postgres.ts +1089 -0
- package/src/drivers/signal-redis.ts +275 -0
- package/src/drivers/signal-types.ts +328 -0
- package/src/drivers/sqlite.ts +53 -0
- package/src/drivers/types.ts +334 -0
- package/src/drivers/vault-dotenv-parse.ts +56 -0
- package/src/drivers/vault-env.ts +101 -0
- package/src/drivers/vault-infisical.ts +61 -0
- package/src/drivers/vault-managed.ts +42 -0
- package/src/drivers/vault-memory.ts +38 -0
- package/src/drivers/vault-openbao.ts +80 -0
- package/src/drivers/vault-sops.ts +252 -0
- package/src/drivers/vault-types.ts +84 -0
- package/src/elements/ai/declare.ts +206 -0
- package/src/elements/ai/eval.ts +113 -0
- package/src/elements/ai/pii.ts +108 -0
- package/src/elements/ai/runtime.ts +540 -0
- package/src/elements/ai/schema.ts +194 -0
- package/src/elements/ai.test.ts +393 -0
- package/src/elements/ai.ts +56 -0
- package/src/elements/channel/consent.ts +81 -0
- package/src/elements/channel/costs.test.ts +62 -0
- package/src/elements/channel/costs.ts +130 -0
- package/src/elements/channel/declare.ts +141 -0
- package/src/elements/channel/email-auth.test.ts +47 -0
- package/src/elements/channel/email-auth.ts +109 -0
- package/src/elements/channel/locale.ts +97 -0
- package/src/elements/channel/mask.test.ts +19 -0
- package/src/elements/channel/mask.ts +60 -0
- package/src/elements/channel/mime.ts +23 -0
- package/src/elements/channel/outcomes.test.ts +40 -0
- package/src/elements/channel/outcomes.ts +126 -0
- package/src/elements/channel/receipts.ts +121 -0
- package/src/elements/channel/runtime.ts +500 -0
- package/src/elements/channel/suppression.ts +136 -0
- package/src/elements/channel.test.ts +232 -0
- package/src/elements/channel.ts +109 -0
- package/src/elements/clock/actions.ts +170 -0
- package/src/elements/clock/declare.ts +58 -0
- package/src/elements/clock/dst.ts +197 -0
- package/src/elements/clock/durable.ts +140 -0
- package/src/elements/clock/duration.ts +29 -0
- package/src/elements/clock/health.test.ts +103 -0
- package/src/elements/clock/health.ts +112 -0
- package/src/elements/clock/leader.ts +127 -0
- package/src/elements/clock/reconcile.ts +241 -0
- package/src/elements/clock/runtime.ts +243 -0
- package/src/elements/clock/schedule.ts +262 -0
- package/src/elements/clock/time-travel.ts +53 -0
- package/src/elements/clock.test.ts +365 -0
- package/src/elements/clock.ts +80 -0
- package/src/elements/gate/declare.ts +134 -0
- package/src/elements/gate/permissions.ts +104 -0
- package/src/elements/gate/runtime.ts +177 -0
- package/src/elements/gate/strategies.ts +388 -0
- package/src/elements/gate.test.ts +145 -0
- package/src/elements/gate.ts +41 -0
- package/src/elements/index.ts +169 -0
- package/src/elements/signal/chaos-child.ts +47 -0
- package/src/elements/signal/declare.ts +77 -0
- package/src/elements/signal/dry-run-replay.test.ts +95 -0
- package/src/elements/signal/dry-run-write-isolation.test.ts +94 -0
- package/src/elements/signal/reconcile.test.ts +23 -0
- package/src/elements/signal/reconcile.ts +122 -0
- package/src/elements/signal/runtime.ts +94 -0
- package/src/elements/signal.test.ts +457 -0
- package/src/elements/signal.ts +26 -0
- package/src/elements/store/cache.ts +197 -0
- package/src/elements/store/classify.ts +125 -0
- package/src/elements/store/declare.ts +200 -0
- package/src/elements/store/files-policy.test.ts +31 -0
- package/src/elements/store/files-policy.ts +70 -0
- package/src/elements/store/replica.ts +68 -0
- package/src/elements/store/runtime.ts +393 -0
- package/src/elements/store/sql-condition.ts +205 -0
- package/src/elements/store/sql-session.ts +579 -0
- package/src/elements/store/table.ts +282 -0
- package/src/elements/store.test.ts +370 -0
- package/src/elements/store.ts +99 -0
- package/src/elements/vault/declare.ts +143 -0
- package/src/elements/vault/fingerprint.ts +30 -0
- package/src/elements/vault/redact.ts +52 -0
- package/src/elements/vault/runtime.ts +461 -0
- package/src/elements/vault.test.ts +296 -0
- package/src/elements/vault.ts +44 -0
- package/src/index.ts +183 -0
- package/src/kernel/adopt-routes.ts +194 -0
- package/src/kernel/app.ts +1068 -0
- package/src/kernel/auth-resolve.ts +93 -0
- package/src/kernel/boot.test.ts +173 -0
- package/src/kernel/boot.ts +439 -0
- package/src/kernel/budget-entry.ts +55 -0
- package/src/kernel/budget.test.ts +19 -0
- package/src/kernel/call.test.ts +83 -0
- package/src/kernel/capability.ts +113 -0
- package/src/kernel/dry-run.test.ts +64 -0
- package/src/kernel/dry-run.ts +171 -0
- package/src/kernel/effects.test.ts +89 -0
- package/src/kernel/effects.ts +140 -0
- package/src/kernel/errors.registry.test.ts +39 -0
- package/src/kernel/errors.ts +225 -0
- package/src/kernel/flow.test.ts +154 -0
- package/src/kernel/flow.ts +290 -0
- package/src/kernel/fx.test.ts +245 -0
- package/src/kernel/fx.ts +996 -0
- package/src/kernel/hook-timing.test.ts +72 -0
- package/src/kernel/hook-timing.ts +190 -0
- package/src/kernel/hooks.test.ts +181 -0
- package/src/kernel/hooks.ts +275 -0
- package/src/kernel/index.ts +278 -0
- package/src/kernel/journal.ts +405 -0
- package/src/kernel/journey.ts +75 -0
- package/src/kernel/on.ts +74 -0
- package/src/kernel/pipeline.test.ts +349 -0
- package/src/kernel/pipeline.ts +245 -0
- package/src/kernel/plug.ts +82 -0
- package/src/kernel/plugin/capabilities.test.ts +84 -0
- package/src/kernel/plugin/conflicts.test.ts +106 -0
- package/src/kernel/plugin/decorate.test.ts +111 -0
- package/src/kernel/plugin/scoping.test.ts +138 -0
- package/src/kernel/plugin.ts +485 -0
- package/src/kernel/rate-limit.ts +25 -0
- package/src/kernel/registry.ts +398 -0
- package/src/kernel/router.test.ts +114 -0
- package/src/kernel/router.ts +556 -0
- package/src/kernel/routing-budget.test.ts +19 -0
- package/src/kernel/run-telemetry.ts +70 -0
- package/src/kernel/triggers.ts +324 -0
- package/src/kernel/unit.ts +88 -0
- package/src/manifest/diff.test.ts +866 -0
- package/src/manifest/diff.ts +1670 -0
- package/src/manifest/fixtures/base.manifest.json +112 -0
- package/src/manifest/fixtures/skyport.excerpt.json +51 -0
- package/src/manifest/fixtures/skyport.manifest.json +153 -0
- package/src/manifest/index.ts +27 -0
- package/src/manifest/types.ts +358 -0
- package/src/manifest/undeclared.test.ts +82 -0
- package/src/manifest/undeclared.ts +65 -0
- package/src/manifest/validate.test.ts +105 -0
- package/src/manifest/validate.ts +174 -0
- package/src/mcp/authorization.ts +340 -0
- package/src/mcp/confirmation.ts +174 -0
- package/src/mcp/data.ts +90 -0
- package/src/mcp/index.ts +80 -0
- package/src/mcp/injection.gate.test.ts +176 -0
- package/src/mcp/mcp.test.ts +348 -0
- package/src/mcp/protocol.ts +172 -0
- package/src/mcp/server.ts +283 -0
- package/src/mcp/session.ts +139 -0
- package/src/mcp/tools.ts +391 -0
- package/src/plugins/catalogue.test.ts +48 -0
- package/src/plugins/catalogue.ts +113 -0
- package/src/plugins/node-import-scan.test.ts +28 -0
- package/src/plugins/node-import-scan.ts +98 -0
- package/src/plugins/supply-chain.test.ts +48 -0
- package/src/plugins/supply-chain.ts +460 -0
- package/src/release/index.ts +30 -0
- package/src/release/limits.ts +20 -0
- package/src/release/measure.ts +443 -0
- package/src/release/publish.ts +56 -0
- package/src/runs/bench.test.ts +93 -0
- package/src/runs/collect.ts +144 -0
- package/src/runs/drivers/clickhouse.ts +108 -0
- package/src/runs/drivers/files.ts +201 -0
- package/src/runs/drivers/memory.ts +94 -0
- package/src/runs/drivers/postgres.ts +110 -0
- package/src/runs/duckdb.ts +99 -0
- package/src/runs/index.ts +82 -0
- package/src/runs/outlier.ts +180 -0
- package/src/runs/parquet.ts +210 -0
- package/src/runs/privacy.ts +49 -0
- package/src/runs/runs.test.ts +324 -0
- package/src/runs/runtime.ts +229 -0
- package/src/runs/shred.ts +243 -0
- package/src/runs/telemetry.ts +10 -0
- package/src/runs/types.ts +179 -0
- package/src/runtime/bun.ts +140 -0
- package/src/runtime/cold-start.bench.ts +20 -0
- package/src/runtime/index.ts +46 -0
- package/src/runtime/primitives.ts +242 -0
- package/src/runtime/security.test.ts +170 -0
- package/src/runtime/security.ts +168 -0
- package/src/runtime/serve.test.ts +223 -0
- package/src/runtime/types.ts +217 -0
- package/src/runtime/web-standard.ts +77 -0
- package/src/test/create-test-app.test.ts +161 -0
- package/src/test/create-test-app.ts +533 -0
- package/src/test/index.ts +21 -0
- package/src/test/provisions.integration.test.ts +174 -0
- package/src/upgrade/codemods.test.ts +58 -0
- package/src/upgrade/codemods.ts +83 -0
- package/src/validation/index.ts +23 -0
- package/src/validation/standard-schema.test.ts +96 -0
- package/src/validation/standard-schema.ts +316 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bearer → principal resolution via the builtin hybrid session path.
|
|
3
|
+
*
|
|
4
|
+
* Production HTTP requests must call {@link verifyAccess} (HMAC signature,
|
|
5
|
+
* expiry, session not revoked). Test-harness principal injection is gated
|
|
6
|
+
* separately in the pipeline (`allowTestPrincipals`).
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import {
|
|
10
|
+
createSessionStore,
|
|
11
|
+
verifyAccess,
|
|
12
|
+
type AccessClaims,
|
|
13
|
+
type SessionStore,
|
|
14
|
+
} from "../auth/sessions.ts";
|
|
15
|
+
import type { ResolvedPrincipal } from "./pipeline.ts";
|
|
16
|
+
|
|
17
|
+
/** Auth binding for the request pipeline. */
|
|
18
|
+
export interface AppAuthBinding {
|
|
19
|
+
/** HMAC secret for access tokens. */
|
|
20
|
+
readonly secret: string;
|
|
21
|
+
/** Session store (revocation checks). Created when omitted. */
|
|
22
|
+
readonly sessions: SessionStore;
|
|
23
|
+
/** Injectable clock (tests / frozen harness). */
|
|
24
|
+
readonly now: () => number;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Options for {@link createAppAuthBinding}. */
|
|
28
|
+
export interface CreateAppAuthBindingOptions {
|
|
29
|
+
readonly secret: string;
|
|
30
|
+
readonly sessions?: SessionStore;
|
|
31
|
+
readonly now?: () => number;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Create an auth binding that verifies Bearer tokens cryptographically.
|
|
36
|
+
*
|
|
37
|
+
* @param options - Secret + optional session store / clock
|
|
38
|
+
*/
|
|
39
|
+
export function createAppAuthBinding(
|
|
40
|
+
options: CreateAppAuthBindingOptions,
|
|
41
|
+
): AppAuthBinding {
|
|
42
|
+
return {
|
|
43
|
+
secret: options.secret,
|
|
44
|
+
sessions: options.sessions ?? createSessionStore(),
|
|
45
|
+
now: options.now ?? (() => Date.now()),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Verify a Bearer access token and map claims to a {@link ResolvedPrincipal}.
|
|
51
|
+
* Throws {@link import("../auth/sessions.ts").SessionError} on forge / expiry / revoke.
|
|
52
|
+
*
|
|
53
|
+
* @param auth - App auth binding
|
|
54
|
+
* @param token - Raw Bearer token (no `Bearer ` prefix)
|
|
55
|
+
*/
|
|
56
|
+
export async function verifyBearerToken(
|
|
57
|
+
auth: AppAuthBinding,
|
|
58
|
+
token: string,
|
|
59
|
+
): Promise<ResolvedPrincipal> {
|
|
60
|
+
const claims = await verifyAccess(
|
|
61
|
+
auth.sessions,
|
|
62
|
+
auth.secret,
|
|
63
|
+
token,
|
|
64
|
+
auth.now,
|
|
65
|
+
);
|
|
66
|
+
return claimsToPrincipal(claims);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Map access-token claims to the pipeline principal shape.
|
|
71
|
+
*
|
|
72
|
+
* A cryptographically valid access token implies an authenticated principal;
|
|
73
|
+
* `verified` is set so policy gates like `member` accept the session.
|
|
74
|
+
*
|
|
75
|
+
* @param claims - Verified claims
|
|
76
|
+
*/
|
|
77
|
+
export function claimsToPrincipal(claims: AccessClaims): ResolvedPrincipal {
|
|
78
|
+
if (claims.plane === "operator") {
|
|
79
|
+
return {
|
|
80
|
+
plane: "operator",
|
|
81
|
+
operatorId: claims.sub,
|
|
82
|
+
userId: null,
|
|
83
|
+
scopes: claims.scopes,
|
|
84
|
+
verified: true,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
plane: "user",
|
|
89
|
+
userId: claims.sub,
|
|
90
|
+
scopes: claims.scopes,
|
|
91
|
+
verified: true,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Boot sequence acceptance:
|
|
3
|
+
* - missing secrets fail naming every gap at once
|
|
4
|
+
* - capability tokens minted from flow effects (Manifest)
|
|
5
|
+
* - declared cron fires on a running app without manual dispatch
|
|
6
|
+
* - real timer loop starts by default outside test env (fake wall-clock)
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { afterEach, describe, expect, jest, test } from "bun:test";
|
|
10
|
+
import { memoryVaultDriver } from "../drivers/index.ts";
|
|
11
|
+
import { clock } from "../elements/clock.ts";
|
|
12
|
+
import { vault, VaultBootError } from "../elements/vault.ts";
|
|
13
|
+
import { bootApplication } from "./boot.ts";
|
|
14
|
+
import { flow, resetFlowSeq } from "./flow.ts";
|
|
15
|
+
import { every, http } from "./triggers.ts";
|
|
16
|
+
import { oke } from "./app.ts";
|
|
17
|
+
import { on, resetBindings } from "./on.ts";
|
|
18
|
+
|
|
19
|
+
describe("boot — vault gaps", () => {
|
|
20
|
+
test("two missing secrets fail naming both at once", async () => {
|
|
21
|
+
try {
|
|
22
|
+
await bootApplication({
|
|
23
|
+
env: "prod",
|
|
24
|
+
secrets: [
|
|
25
|
+
vault("STRIPE_KEY", { description: "Payments gateway key" }),
|
|
26
|
+
vault("DATABASE_URL", { description: "Primary SQL URL" }),
|
|
27
|
+
],
|
|
28
|
+
vault: {
|
|
29
|
+
allowDevFallbacks: false,
|
|
30
|
+
chain: [{ driver: memoryVaultDriver, options: { secrets: {} } }],
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
expect.unreachable("boot should fail");
|
|
34
|
+
} catch (err) {
|
|
35
|
+
expect(err).toBeInstanceOf(VaultBootError);
|
|
36
|
+
const boot = err as VaultBootError;
|
|
37
|
+
expect(boot.gaps.map((g) => g.name).sort()).toEqual([
|
|
38
|
+
"DATABASE_URL",
|
|
39
|
+
"STRIPE_KEY",
|
|
40
|
+
]);
|
|
41
|
+
expect(boot.message).toContain("STRIPE_KEY");
|
|
42
|
+
expect(boot.message).toContain("DATABASE_URL");
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
describe("boot — capabilities from Manifest effects", () => {
|
|
48
|
+
test("tokens cover declared effects only", async () => {
|
|
49
|
+
const charge = flow({
|
|
50
|
+
name: "payments.charge",
|
|
51
|
+
effects: { secrets: ["STRIPE_KEY"], writes: ["sql:orders"] },
|
|
52
|
+
do: () => ({ ok: true }),
|
|
53
|
+
});
|
|
54
|
+
const result = await bootApplication({
|
|
55
|
+
env: "test",
|
|
56
|
+
secrets: [vault("STRIPE_KEY", { dev: "sk_test" })],
|
|
57
|
+
vault: { allowDevFallbacks: true, chain: [] },
|
|
58
|
+
flows: [charge],
|
|
59
|
+
});
|
|
60
|
+
const cap = result.capabilities.get("payments.charge");
|
|
61
|
+
expect(cap).toBeDefined();
|
|
62
|
+
expect(cap!.allows("secret", "STRIPE_KEY")).toBe(true);
|
|
63
|
+
expect(cap!.allows("write", "sql:orders")).toBe(true);
|
|
64
|
+
expect(cap!.allows("secret", "OTHER")).toBe(false);
|
|
65
|
+
await result.close();
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
describe("boot — cron fires without manual dispatch", () => {
|
|
70
|
+
test("scheduler tick runs a due every-binding", async () => {
|
|
71
|
+
resetBindings();
|
|
72
|
+
resetFlowSeq();
|
|
73
|
+
|
|
74
|
+
let ran = 0;
|
|
75
|
+
on(
|
|
76
|
+
every("1h"),
|
|
77
|
+
flow({
|
|
78
|
+
name: "cleanup.expire",
|
|
79
|
+
do: () => {
|
|
80
|
+
ran += 1;
|
|
81
|
+
},
|
|
82
|
+
}),
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
const app = oke({
|
|
86
|
+
name: "cron-boot",
|
|
87
|
+
clocks: [clock("expire-stale", { every: "1h" })],
|
|
88
|
+
env: "test",
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
await app.boot({
|
|
92
|
+
env: "test",
|
|
93
|
+
startScheduler: false,
|
|
94
|
+
clocks: [clock("expire-stale", { every: "1h" })],
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
const rt = app.bootResult!.clock!;
|
|
98
|
+
// First tick — due (never ran).
|
|
99
|
+
const { ran: names } = await rt.tick();
|
|
100
|
+
expect(names.length).toBeGreaterThan(0);
|
|
101
|
+
expect(ran).toBeGreaterThanOrEqual(1);
|
|
102
|
+
|
|
103
|
+
// Advance past the effective every; tick again without dispatchEvery.
|
|
104
|
+
rt.advance("1h");
|
|
105
|
+
const before = ran;
|
|
106
|
+
await rt.tick();
|
|
107
|
+
expect(ran).toBeGreaterThan(before);
|
|
108
|
+
|
|
109
|
+
await app.bootResult?.close();
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
describe("boot — HTTP gate wiring lives behind boot", () => {
|
|
114
|
+
test("unbooted app still serves without gates (legacy)", async () => {
|
|
115
|
+
resetBindings();
|
|
116
|
+
resetFlowSeq();
|
|
117
|
+
on(
|
|
118
|
+
http.get("/ping"),
|
|
119
|
+
flow({
|
|
120
|
+
name: "ping",
|
|
121
|
+
do: () => ({ ok: true }),
|
|
122
|
+
}),
|
|
123
|
+
);
|
|
124
|
+
const app = oke({ name: "legacy" });
|
|
125
|
+
const res = await app.fetch(
|
|
126
|
+
new Request("http://localhost/ping", { method: "GET" }),
|
|
127
|
+
);
|
|
128
|
+
expect(res.status).toBe(200);
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
describe("boot — cron autostart via real timer loop", () => {
|
|
133
|
+
afterEach(() => {
|
|
134
|
+
jest.useRealTimers();
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
test("booted app (non-test) fires every() with no manual tick/runNow", async () => {
|
|
138
|
+
resetBindings();
|
|
139
|
+
resetFlowSeq();
|
|
140
|
+
jest.useFakeTimers({ now: 1_000_000 });
|
|
141
|
+
|
|
142
|
+
let ran = 0;
|
|
143
|
+
on(
|
|
144
|
+
every("10m"),
|
|
145
|
+
flow({
|
|
146
|
+
name: "cleanup.autostart",
|
|
147
|
+
do: () => {
|
|
148
|
+
ran += 1;
|
|
149
|
+
},
|
|
150
|
+
}),
|
|
151
|
+
);
|
|
152
|
+
|
|
153
|
+
// env: "dev" → startScheduler defaults ON. No createTestApp / advance.
|
|
154
|
+
const app = oke({
|
|
155
|
+
name: "cron-autostart",
|
|
156
|
+
env: "dev",
|
|
157
|
+
schedulerIntervalMs: 1000,
|
|
158
|
+
});
|
|
159
|
+
await app.boot();
|
|
160
|
+
|
|
161
|
+
expect(ran).toBe(0);
|
|
162
|
+
|
|
163
|
+
// Drive the wall-clock interval that boot installed — not clock.advance /
|
|
164
|
+
// runNow / dispatchEvery (those prove the harness, not autostart).
|
|
165
|
+
jest.advanceTimersByTime(1000);
|
|
166
|
+
// Interval callback does `void clock.tick()`; drain the async store walk.
|
|
167
|
+
for (let i = 0; i < 50; i++) await Promise.resolve();
|
|
168
|
+
|
|
169
|
+
expect(ran).toBeGreaterThanOrEqual(1);
|
|
170
|
+
|
|
171
|
+
await app.stop();
|
|
172
|
+
});
|
|
173
|
+
});
|
|
@@ -0,0 +1,439 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ordered application boot — fail fast before a single request is served.
|
|
3
|
+
*
|
|
4
|
+
* ```
|
|
5
|
+
* 1. Vault — resolve every declared secret (list all gaps at once)
|
|
6
|
+
* 2. Store — bind drivers per environment; open connections
|
|
7
|
+
* 3. Signals — register declarations; start consumers
|
|
8
|
+
* 4. Clocks — reconcile into the Store; start scheduler (leader election)
|
|
9
|
+
* 5. Channel — bind channel runtime
|
|
10
|
+
* 6. AI — bind AI runtime
|
|
11
|
+
* 7. Runs — open the runs store
|
|
12
|
+
* 8. Caps — mint per-flow capability tokens from the Manifest / effects
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* The scheduler reads the effective state from the Store after reconciliation,
|
|
16
|
+
* never the code directly (console §5).
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import {
|
|
20
|
+
createAiRuntime,
|
|
21
|
+
type AiRuntime,
|
|
22
|
+
type CreateAiRuntimeOptions,
|
|
23
|
+
} from "../elements/ai.ts";
|
|
24
|
+
import {
|
|
25
|
+
createChannelRuntime,
|
|
26
|
+
type ChannelRuntime,
|
|
27
|
+
type CreateChannelRuntimeOptions,
|
|
28
|
+
} from "../elements/channel.ts";
|
|
29
|
+
import {
|
|
30
|
+
clock as declareClock,
|
|
31
|
+
createClockRuntime,
|
|
32
|
+
createTestClockRuntime,
|
|
33
|
+
type ClockDecl,
|
|
34
|
+
type ClockRuntime,
|
|
35
|
+
} from "../elements/clock.ts";
|
|
36
|
+
import {
|
|
37
|
+
createGateRuntime,
|
|
38
|
+
type GateDecl,
|
|
39
|
+
type GateRuntime,
|
|
40
|
+
} from "../elements/gate.ts";
|
|
41
|
+
import {
|
|
42
|
+
createSignalRuntime,
|
|
43
|
+
type SignalDecl,
|
|
44
|
+
type SignalRuntime,
|
|
45
|
+
} from "../elements/signal.ts";
|
|
46
|
+
import {
|
|
47
|
+
createStoreRuntime,
|
|
48
|
+
type StoreDecl,
|
|
49
|
+
type StoreRuntime,
|
|
50
|
+
} from "../elements/store.ts";
|
|
51
|
+
import {
|
|
52
|
+
createVaultRuntime,
|
|
53
|
+
type CreateVaultRuntimeOptions,
|
|
54
|
+
type VaultRuntime,
|
|
55
|
+
type VaultSecretDecl,
|
|
56
|
+
} from "../elements/vault.ts";
|
|
57
|
+
import {
|
|
58
|
+
memoryDrivers,
|
|
59
|
+
memorySignalDriver,
|
|
60
|
+
memoryVaultDriver,
|
|
61
|
+
openConsoleChannel,
|
|
62
|
+
mockAiDriver,
|
|
63
|
+
} from "../drivers/index.ts";
|
|
64
|
+
import {
|
|
65
|
+
resolveDriverId,
|
|
66
|
+
type ConfigEnv,
|
|
67
|
+
type OkeConfig,
|
|
68
|
+
} from "../config/index.ts";
|
|
69
|
+
import {
|
|
70
|
+
createRunsRuntime,
|
|
71
|
+
memoryRunsDriver,
|
|
72
|
+
type CreateRunsRuntimeOptions,
|
|
73
|
+
type RunsRuntime,
|
|
74
|
+
} from "../runs/index.ts";
|
|
75
|
+
import {
|
|
76
|
+
createCapabilityToken,
|
|
77
|
+
type CapabilityToken,
|
|
78
|
+
} from "./capability.ts";
|
|
79
|
+
import type { AnyFlowDef } from "./flow.ts";
|
|
80
|
+
import type { Binding } from "./on.ts";
|
|
81
|
+
|
|
82
|
+
/** Pre-built or partially-built element runtimes. */
|
|
83
|
+
export interface ElementRuntimes {
|
|
84
|
+
readonly vault?: VaultRuntime;
|
|
85
|
+
readonly store?: StoreRuntime;
|
|
86
|
+
readonly signal?: SignalRuntime;
|
|
87
|
+
readonly clock?: ClockRuntime;
|
|
88
|
+
readonly gate?: GateRuntime;
|
|
89
|
+
readonly channel?: ChannelRuntime;
|
|
90
|
+
readonly ai?: AiRuntime;
|
|
91
|
+
readonly runs?: RunsRuntime;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/** Declarations + options consumed by {@link bootApplication}. */
|
|
95
|
+
export interface BootOptions {
|
|
96
|
+
/** Active environment (defaults to `dev`). */
|
|
97
|
+
readonly env?: ConfigEnv;
|
|
98
|
+
/** Optional `oke.config.ts` document. */
|
|
99
|
+
readonly config?: OkeConfig;
|
|
100
|
+
/** Pre-built runtimes (skip construction when present). */
|
|
101
|
+
readonly elements?: ElementRuntimes;
|
|
102
|
+
/** Vault secret contracts. */
|
|
103
|
+
readonly secrets?: readonly VaultSecretDecl[];
|
|
104
|
+
/** Vault create options (chain / allowDevFallbacks). */
|
|
105
|
+
readonly vault?: Omit<CreateVaultRuntimeOptions, "secrets"> & {
|
|
106
|
+
readonly secrets?: readonly VaultSecretDecl[];
|
|
107
|
+
};
|
|
108
|
+
/** Gate declarations for the runtime. */
|
|
109
|
+
readonly gates?: readonly GateDecl[];
|
|
110
|
+
/** Signal declarations. */
|
|
111
|
+
readonly signals?: readonly SignalDecl[];
|
|
112
|
+
/** Named clock declarations. */
|
|
113
|
+
readonly clocks?: readonly ClockDecl[];
|
|
114
|
+
/** Store facet declarations to register. */
|
|
115
|
+
readonly stores?: readonly StoreDecl[];
|
|
116
|
+
/** Channel runtime options. */
|
|
117
|
+
readonly channel?: CreateChannelRuntimeOptions;
|
|
118
|
+
/** AI runtime options. */
|
|
119
|
+
readonly ai?: CreateAiRuntimeOptions;
|
|
120
|
+
/** Runs runtime or create options. */
|
|
121
|
+
readonly runs?: RunsRuntime | CreateRunsRuntimeOptions;
|
|
122
|
+
/** Adopted bindings (for every→cron + signal consumers). */
|
|
123
|
+
readonly bindings?: readonly Binding[];
|
|
124
|
+
/** Flows known to the app (for capability minting). */
|
|
125
|
+
readonly flows?: readonly AnyFlowDef[];
|
|
126
|
+
/**
|
|
127
|
+
* Dispatch a cron / every interval when the scheduler fires.
|
|
128
|
+
*
|
|
129
|
+
* @param name - Cron name or every-interval
|
|
130
|
+
*/
|
|
131
|
+
readonly onCronFire?: (name: string) => void | Promise<void>;
|
|
132
|
+
/**
|
|
133
|
+
* Dispatch a signal message to bound flows.
|
|
134
|
+
*
|
|
135
|
+
* @param signal - Signal name
|
|
136
|
+
* @param payload - Payload
|
|
137
|
+
*/
|
|
138
|
+
readonly onSignal?: (
|
|
139
|
+
signal: string,
|
|
140
|
+
payload: unknown,
|
|
141
|
+
) => void | Promise<void>;
|
|
142
|
+
/** Injectable clock for test / frozen harnesses. */
|
|
143
|
+
readonly now?: () => number;
|
|
144
|
+
/** Instance id for leader election. */
|
|
145
|
+
readonly instanceId?: string;
|
|
146
|
+
/**
|
|
147
|
+
* Start a background scheduler tick loop.
|
|
148
|
+
* Default: `true` when `env !== "test"`; `false` in test (opt in explicitly).
|
|
149
|
+
* Opt out in production with `startScheduler: false`.
|
|
150
|
+
*/
|
|
151
|
+
readonly startScheduler?: boolean;
|
|
152
|
+
/** Scheduler tick period ms (default 1000). */
|
|
153
|
+
readonly schedulerIntervalMs?: number;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/** Result of a successful boot. */
|
|
157
|
+
export interface BootResult {
|
|
158
|
+
readonly vault?: VaultRuntime;
|
|
159
|
+
readonly store?: StoreRuntime;
|
|
160
|
+
readonly signal?: SignalRuntime;
|
|
161
|
+
readonly clock?: ClockRuntime;
|
|
162
|
+
readonly gate?: GateRuntime;
|
|
163
|
+
readonly channel?: ChannelRuntime;
|
|
164
|
+
readonly ai?: AiRuntime;
|
|
165
|
+
readonly runs?: RunsRuntime;
|
|
166
|
+
/** Per-flow capability tokens minted from declared effects. */
|
|
167
|
+
readonly capabilities: ReadonlyMap<string, CapabilityToken>;
|
|
168
|
+
/** Stop the background scheduler (if started). */
|
|
169
|
+
stopScheduler(): void;
|
|
170
|
+
/** Close element runtimes. */
|
|
171
|
+
close(): Promise<void>;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Run the ordered boot sequence. Fails fast — a missing secret throws
|
|
176
|
+
* before store/signal/… open, so no request can be served.
|
|
177
|
+
*
|
|
178
|
+
* @param options - Declarations, config, pre-built runtimes
|
|
179
|
+
*/
|
|
180
|
+
export async function bootApplication(
|
|
181
|
+
options: BootOptions = {},
|
|
182
|
+
): Promise<BootResult> {
|
|
183
|
+
const env: ConfigEnv = options.env ?? "dev";
|
|
184
|
+
const pre = options.elements ?? {};
|
|
185
|
+
const now = options.now ?? (() => Date.now());
|
|
186
|
+
|
|
187
|
+
// 1. Vault boot — resolve every declared secret; list all gaps at once.
|
|
188
|
+
const vaultSecrets =
|
|
189
|
+
options.vault?.secrets ?? options.secrets ?? [];
|
|
190
|
+
let vault = pre.vault;
|
|
191
|
+
if (!vault && vaultSecrets.length > 0) {
|
|
192
|
+
vault = createVaultRuntime({
|
|
193
|
+
secrets: vaultSecrets,
|
|
194
|
+
chain: options.vault?.chain ?? [
|
|
195
|
+
{
|
|
196
|
+
driver: memoryVaultDriver,
|
|
197
|
+
options: { secrets: {} },
|
|
198
|
+
},
|
|
199
|
+
],
|
|
200
|
+
allowDevFallbacks:
|
|
201
|
+
options.vault?.allowDevFallbacks ?? env !== "prod",
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
if (vault && !vault.booted) {
|
|
205
|
+
await vault.boot();
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// 2. Bind store drivers per environment; open connections.
|
|
209
|
+
let store = pre.store;
|
|
210
|
+
if (!store) {
|
|
211
|
+
const sqlId =
|
|
212
|
+
resolveDriverId(options.config?.drivers?.store?.sql, env) ?? "memory";
|
|
213
|
+
const kvId =
|
|
214
|
+
resolveDriverId(options.config?.drivers?.store?.kv, env) ?? "memory";
|
|
215
|
+
// Protocol ids → memory bundle for test/dev when not otherwise injected.
|
|
216
|
+
void sqlId;
|
|
217
|
+
void kvId;
|
|
218
|
+
store = createStoreRuntime({
|
|
219
|
+
drivers: {
|
|
220
|
+
sql: memoryDrivers.sql,
|
|
221
|
+
kv: memoryDrivers.kv,
|
|
222
|
+
files: memoryDrivers.files,
|
|
223
|
+
index: memoryDrivers.index,
|
|
224
|
+
},
|
|
225
|
+
now,
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
for (const decl of options.stores ?? []) {
|
|
229
|
+
store.register?.(decl);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// 3. Register signals; start consumers.
|
|
233
|
+
let signal = pre.signal;
|
|
234
|
+
if (!signal) {
|
|
235
|
+
const signalId =
|
|
236
|
+
resolveDriverId(options.config?.drivers?.signal, env) ?? "memory";
|
|
237
|
+
void signalId;
|
|
238
|
+
signal = createSignalRuntime({
|
|
239
|
+
driver: memorySignalDriver,
|
|
240
|
+
now,
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
for (const decl of options.signals ?? []) {
|
|
244
|
+
signal.register(decl);
|
|
245
|
+
}
|
|
246
|
+
// Also register signal-as-trigger names from bindings.
|
|
247
|
+
for (const b of options.bindings ?? []) {
|
|
248
|
+
if (b.trigger.kind === "signal") {
|
|
249
|
+
if (!signal.declarations.has(b.trigger.name)) {
|
|
250
|
+
// Minimal decl so the bus knows the name; optional to avoid orphan fail.
|
|
251
|
+
signal.register({
|
|
252
|
+
name: b.trigger.name,
|
|
253
|
+
delivery: "once",
|
|
254
|
+
retries: 3,
|
|
255
|
+
deadLetter: true,
|
|
256
|
+
optional: true,
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
const bus = await signal.start();
|
|
262
|
+
|
|
263
|
+
if (options.onSignal) {
|
|
264
|
+
const handler = options.onSignal;
|
|
265
|
+
const seen = new Set<string>();
|
|
266
|
+
for (const b of options.bindings ?? []) {
|
|
267
|
+
if (b.trigger.kind !== "signal") continue;
|
|
268
|
+
const name = b.trigger.name;
|
|
269
|
+
if (seen.has(name)) continue;
|
|
270
|
+
seen.add(name);
|
|
271
|
+
await bus.subscribe(name, `oke:${name}`, async (msg) => {
|
|
272
|
+
await handler(name, msg.payload);
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// 4. Reconcile clocks into the store; start scheduler with leader election.
|
|
278
|
+
const clockDriver =
|
|
279
|
+
resolveDriverId(options.config?.drivers?.clock, env) ??
|
|
280
|
+
(env === "test" ? "frozen" : "memory");
|
|
281
|
+
let clock = pre.clock;
|
|
282
|
+
if (!clock) {
|
|
283
|
+
clock =
|
|
284
|
+
clockDriver === "frozen" || env === "test"
|
|
285
|
+
? createTestClockRuntime(now(), { instanceId: options.instanceId })
|
|
286
|
+
: createClockRuntime({ instanceId: options.instanceId, now });
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
const clockDecls = new Map<string, ClockDecl>();
|
|
290
|
+
for (const c of options.clocks ?? []) {
|
|
291
|
+
clockDecls.set(c.name, c);
|
|
292
|
+
}
|
|
293
|
+
// every("1h") bindings → named clocks the scheduler can fire.
|
|
294
|
+
for (const b of options.bindings ?? []) {
|
|
295
|
+
if (b.trigger.kind === "every" && !clockDecls.has(b.trigger.interval)) {
|
|
296
|
+
clockDecls.set(
|
|
297
|
+
b.trigger.interval,
|
|
298
|
+
declareClock(b.trigger.interval, { every: b.trigger.interval }),
|
|
299
|
+
);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
for (const decl of clockDecls.values()) {
|
|
303
|
+
clock.register(decl);
|
|
304
|
+
}
|
|
305
|
+
await clock.reconcile();
|
|
306
|
+
|
|
307
|
+
if (options.onCronFire) {
|
|
308
|
+
const fire = options.onCronFire;
|
|
309
|
+
for (const name of clockDecls.keys()) {
|
|
310
|
+
clock.onCron(name, async () => {
|
|
311
|
+
await fire(name);
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// Default ON outside test — a declared every()/cron must fire with zero
|
|
317
|
+
// further application calls (Clock element's core promise).
|
|
318
|
+
const startScheduler =
|
|
319
|
+
options.startScheduler ?? (env !== "test");
|
|
320
|
+
let schedulerTimer: ReturnType<typeof setInterval> | undefined;
|
|
321
|
+
if (startScheduler) {
|
|
322
|
+
const period = options.schedulerIntervalMs ?? 1000;
|
|
323
|
+
schedulerTimer = setInterval(() => {
|
|
324
|
+
void clock!.tick();
|
|
325
|
+
}, period);
|
|
326
|
+
// Don't keep the process alive solely for the scheduler in tests.
|
|
327
|
+
schedulerTimer.unref?.();
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// Gate runtime (needs kv from store drivers) — used by the request
|
|
331
|
+
// pipeline and AI agents. Constructed before channel/AI bind.
|
|
332
|
+
let gate = pre.gate;
|
|
333
|
+
if (!gate) {
|
|
334
|
+
const kvNs = await memoryDrivers.kv.open({ name: "oke:gates" });
|
|
335
|
+
gate = createGateRuntime({
|
|
336
|
+
gates: options.gates ?? [],
|
|
337
|
+
kv: kvNs,
|
|
338
|
+
now,
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// 5. Bind channel runtime.
|
|
343
|
+
let channel = pre.channel;
|
|
344
|
+
if (!channel) {
|
|
345
|
+
channel = createChannelRuntime({
|
|
346
|
+
...(options.channel ?? {}),
|
|
347
|
+
drivers: options.channel?.drivers ?? [openConsoleChannel()],
|
|
348
|
+
now,
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// 6. Bind AI runtime (shares the gate runtime for agent tool checks).
|
|
353
|
+
let ai = pre.ai;
|
|
354
|
+
if (!ai) {
|
|
355
|
+
ai = createAiRuntime({
|
|
356
|
+
...(options.ai ?? {}),
|
|
357
|
+
defaultDriver: options.ai?.defaultDriver ?? mockAiDriver,
|
|
358
|
+
gates: options.ai?.gates ?? gate,
|
|
359
|
+
now,
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// 7. Open the runs store.
|
|
364
|
+
let runs = pre.runs;
|
|
365
|
+
if (!runs) {
|
|
366
|
+
if (options.runs && isRunsRuntime(options.runs)) {
|
|
367
|
+
runs = options.runs;
|
|
368
|
+
} else {
|
|
369
|
+
const runsOpts =
|
|
370
|
+
options.runs && !isRunsRuntime(options.runs)
|
|
371
|
+
? options.runs
|
|
372
|
+
: undefined;
|
|
373
|
+
runs = createRunsRuntime({
|
|
374
|
+
driver: runsOpts?.driver ?? memoryRunsDriver,
|
|
375
|
+
...(runsOpts ?? {}),
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
if (runs && !runs.store) {
|
|
380
|
+
await runs.open();
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
// 8. Mint per-flow capability tokens from declared effects (Manifest).
|
|
384
|
+
const capabilities = mintCapabilities(options.flows ?? []);
|
|
385
|
+
|
|
386
|
+
return {
|
|
387
|
+
vault,
|
|
388
|
+
store,
|
|
389
|
+
signal,
|
|
390
|
+
clock,
|
|
391
|
+
gate,
|
|
392
|
+
channel,
|
|
393
|
+
ai,
|
|
394
|
+
runs,
|
|
395
|
+
capabilities,
|
|
396
|
+
stopScheduler() {
|
|
397
|
+
if (schedulerTimer !== undefined) {
|
|
398
|
+
clearInterval(schedulerTimer);
|
|
399
|
+
schedulerTimer = undefined;
|
|
400
|
+
}
|
|
401
|
+
},
|
|
402
|
+
async close() {
|
|
403
|
+
if (schedulerTimer !== undefined) {
|
|
404
|
+
clearInterval(schedulerTimer);
|
|
405
|
+
schedulerTimer = undefined;
|
|
406
|
+
}
|
|
407
|
+
await signal?.close();
|
|
408
|
+
await vault?.close();
|
|
409
|
+
await runs?.flush();
|
|
410
|
+
},
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
/**
|
|
415
|
+
* Mint capability tokens from each flow's declared effects.
|
|
416
|
+
* Tokens come from the Manifest / flow contract — never hand-passed sets.
|
|
417
|
+
*
|
|
418
|
+
* @param flows - Adopted flows
|
|
419
|
+
*/
|
|
420
|
+
export function mintCapabilities(
|
|
421
|
+
flows: readonly AnyFlowDef[],
|
|
422
|
+
): Map<string, CapabilityToken> {
|
|
423
|
+
const map = new Map<string, CapabilityToken>();
|
|
424
|
+
for (const f of flows) {
|
|
425
|
+
map.set(f.name, createCapabilityToken(f.name, f.effects));
|
|
426
|
+
}
|
|
427
|
+
return map;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
function isRunsRuntime(
|
|
431
|
+
value: RunsRuntime | CreateRunsRuntimeOptions,
|
|
432
|
+
): value is RunsRuntime {
|
|
433
|
+
return (
|
|
434
|
+
typeof value === "object" &&
|
|
435
|
+
value !== null &&
|
|
436
|
+
"record" in value &&
|
|
437
|
+
typeof (value as RunsRuntime).record === "function"
|
|
438
|
+
);
|
|
439
|
+
}
|