okengine 0.2.5 → 0.2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +24 -23
- package/README.md +52 -346
- package/docs/spec/console.md +165 -142
- package/docs/spec/example.md +490 -312
- package/docs/spec/four-applications.md +495 -314
- package/docs/spec/unified-theory.md +184 -175
- package/package.json +46 -38
- package/spec/manifest.v1.schema.json +40 -9
- package/src/auth/api-keys.ts +2 -5
- package/src/auth/attenuation.ts +2 -6
- package/src/auth/auth.test.ts +53 -31
- package/src/auth/invoke-as.ts +1 -3
- package/src/auth/operator.ts +8 -26
- package/src/auth/planes.ts +2 -7
- package/src/auth/plugin.ts +4 -7
- package/src/auth/roles.ts +1 -5
- package/src/auth/sessions.ts +10 -39
- package/src/cli/args.ts +1 -5
- package/src/cli/ask-dev-mode.ts +40 -0
- package/src/cli/build.ts +1 -2
- package/src/cli/client-add.test.ts +8 -15
- package/src/cli/client-add.ts +5 -14
- package/src/cli/completion.test.ts +1 -5
- package/src/cli/completion.ts +4 -17
- package/src/cli/db-auto-push.test.ts +64 -0
- package/src/cli/db-auto-push.ts +72 -0
- package/src/cli/db.test.ts +189 -0
- package/src/cli/db.ts +386 -0
- package/src/cli/dev-app-runner.ts +2 -8
- package/src/cli/dev-db-push.test.ts +163 -0
- package/src/cli/dev-mode.test.ts +45 -0
- package/src/cli/dev-mode.ts +78 -0
- package/src/cli/dev.test.ts +148 -21
- package/src/cli/dev.ts +208 -134
- package/src/cli/doc-drift.test.ts +3 -2
- package/src/cli/doc-drift.ts +21 -50
- package/src/cli/doc-staleness.test.ts +69 -0
- package/src/cli/docker-cli.test.ts +7 -8
- package/src/cli/docker.ts +1 -3
- package/src/cli/doctor-diff-examples.ts +1 -3
- package/src/cli/doctor-diff.test.ts +1 -5
- package/src/cli/doctor-diff.ts +17 -46
- package/src/cli/doctor-pii.ts +2 -7
- package/src/cli/doctor.test.ts +26 -4
- package/src/cli/doctor.ts +35 -11
- package/src/cli/eval.ts +4 -14
- package/src/cli/gates-list.ts +1 -4
- package/src/cli/hero-meta.test.ts +17 -19
- package/src/cli/hero-meta.ts +20 -30
- package/src/cli/images.ts +3 -8
- package/src/cli/index.ts +11 -2
- package/src/cli/load-config.images.test.ts +14 -14
- package/src/cli/load-config.ts +41 -47
- package/src/cli/mcp-from-console.ts +1 -4
- package/src/cli/mode.ts +45 -0
- package/src/cli/ports.test.ts +4 -13
- package/src/cli/ports.ts +1 -3
- package/src/cli/privacy-erase.ts +1 -3
- package/src/cli/registry.ts +75 -25
- package/src/cli/schema.ts +3 -10
- package/src/cli/stack.ts +2 -7
- package/src/cli/start.ts +4 -15
- package/src/cli/upgrade.ts +1 -4
- package/src/client/budget-entry.ts +1 -6
- package/src/client/create.test.ts +6 -12
- package/src/client/create.ts +2 -8
- package/src/client/errors.ts +1 -4
- package/src/client/index.ts +1 -6
- package/src/client/notes-contract.test.ts +4 -13
- package/src/client/transport.ts +9 -30
- package/src/client/types.ts +8 -29
- package/src/compiler/aot.test.ts +2 -9
- package/src/compiler/aot.ts +1 -4
- package/src/compiler/differential.test.ts +3 -11
- package/src/compiler/dynamic.ts +1 -4
- package/src/compiler/effects-infer.ts +8 -34
- package/src/compiler/emit.ts +1 -3
- package/src/compiler/extract.test.ts +96 -30
- package/src/compiler/extract.ts +362 -156
- package/src/compiler/fixtures/skyport/oke.config.ts +1 -1
- package/src/compiler/fixtures/skyport/src/flows/bookings/index.ts +7 -3
- package/src/compiler/fixtures/skyport/src/flows/payments/index.ts +1 -3
- package/src/compiler/fixtures/skyport/src/flows/support/index.ts +4 -1
- package/src/compiler/fixtures/skyport.expected.json +24 -83
- package/src/compiler/fixtures/triggers/five-triggers.ts +1 -2
- package/src/compiler/http-parse.ts +2 -9
- package/src/compiler/index.ts +1 -5
- package/src/compiler/response.ts +4 -7
- package/src/compiler/sucrose.ts +11 -31
- package/src/config/define-config.test.ts +57 -34
- package/src/config/index.ts +181 -37
- package/src/config/resolve-driver.test.ts +28 -17
- package/src/console/budget.test.ts +1 -4
- package/src/console/index.ts +1 -4
- package/src/console/server/access.test.ts +15 -43
- package/src/console/server/access.ts +19 -49
- package/src/console/server/ai.test.ts +3 -11
- package/src/console/server/ai.ts +23 -46
- package/src/console/server/app.ts +14 -45
- package/src/console/server/auth-rate.test.ts +4 -12
- package/src/console/server/bind.ts +1 -5
- package/src/console/server/channels.test.ts +2 -6
- package/src/console/server/channels.ts +10 -35
- package/src/console/server/claim.ts +2 -8
- package/src/console/server/clock.test.ts +2 -6
- package/src/console/server/clock.ts +8 -26
- package/src/console/server/console.test.ts +1 -3
- package/src/console/server/diff.test.ts +5 -17
- package/src/console/server/diff.ts +10 -31
- package/src/console/server/dry-run.audit.test.ts +2 -8
- package/src/console/server/flows.ts +64 -233
- package/src/console/server/gates.test.ts +14 -50
- package/src/console/server/gates.ts +13 -48
- package/src/console/server/index.ts +2 -9
- package/src/console/server/live.ts +3 -12
- package/src/console/server/operator-db.test.ts +4 -15
- package/src/console/server/operator-db.ts +13 -32
- package/src/console/server/plugin.ts +50 -53
- package/src/console/server/plugins.test.ts +2 -6
- package/src/console/server/plugins.ts +17 -56
- package/src/console/server/runs-pii.ts +2 -7
- package/src/console/server/security.gate.test.ts +18 -40
- package/src/console/server/serve.ts +10 -25
- package/src/console/server/signals.test.ts +1 -3
- package/src/console/server/signals.ts +17 -40
- package/src/console/server/state.ts +21 -59
- package/src/console/server/store.test.ts +20 -22
- package/src/console/server/store.ts +31 -76
- package/src/console/server/vault.test.ts +12 -29
- package/src/console/server/vault.ts +23 -60
- package/src/console/ui/access/AccessA11yView.tsx +6 -21
- package/src/console/ui/access/a11y.test.tsx +3 -12
- package/src/console/ui/access/acknowledgement.test.ts +1 -4
- package/src/console/ui/access/acknowledgement.ts +1 -3
- package/src/console/ui/access/blast-radius.ts +1 -3
- package/src/console/ui/access/confirmation.test.ts +1 -5
- package/src/console/ui/access/confirmation.ts +1 -4
- package/src/console/ui/access/fixture.ts +1 -5
- package/src/console/ui/access/grantable.test.ts +1 -3
- package/src/console/ui/access/grantable.ts +2 -7
- package/src/console/ui/access/index.ts +2 -9
- package/src/console/ui/access/provenance.test.ts +1 -3
- package/src/console/ui/access/provenance.ts +2 -6
- package/src/console/ui/access/search.test.ts +1 -5
- package/src/console/ui/access/search.ts +2 -6
- package/src/console/ui/ai/AiA11yView.tsx +6 -17
- package/src/console/ui/ai/a11y.test.tsx +2 -5
- package/src/console/ui/ai/fixture.ts +2 -7
- package/src/console/ui/ai/format.ts +1 -3
- package/src/console/ui/ai/group.test.ts +1 -3
- package/src/console/ui/ai/group.ts +4 -12
- package/src/console/ui/ai/index.ts +2 -9
- package/src/console/ui/ai/promotion.test.ts +2 -7
- package/src/console/ui/ai/promotion.ts +4 -13
- package/src/console/ui/ai/search.test.ts +2 -11
- package/src/console/ui/ai/search.ts +3 -13
- package/src/console/ui/ai/types.ts +1 -8
- package/src/console/ui/architecture/ArchitectureA11yView.tsx +8 -29
- package/src/console/ui/architecture/a11y.test.tsx +1 -2
- package/src/console/ui/architecture/declared.ts +1 -5
- package/src/console/ui/architecture/index.ts +7 -35
- package/src/console/ui/architecture/layout.ts +1 -3
- package/src/console/ui/architecture/pathologies.ts +10 -19
- package/src/console/ui/architecture/search.ts +6 -15
- package/src/console/ui/architecture/traffic.ts +4 -14
- package/src/console/ui/architecture/types.ts +2 -10
- package/src/console/ui/architecture/view.test.ts +7 -19
- package/src/console/ui/architecture/view.ts +9 -36
- package/src/console/ui/channels/ChannelsA11yView.tsx +4 -13
- package/src/console/ui/channels/a11y.test.tsx +1 -2
- package/src/console/ui/channels/confirmation.test.ts +1 -4
- package/src/console/ui/channels/confirmation.ts +1 -4
- package/src/console/ui/channels/findings.ts +1 -5
- package/src/console/ui/channels/index.ts +2 -8
- package/src/console/ui/channels/locale.test.ts +1 -3
- package/src/console/ui/channels/locale.ts +2 -8
- package/src/console/ui/channels/search.ts +4 -13
- package/src/console/ui/channels/taxonomy.ts +1 -3
- package/src/console/ui/clock/ClockA11yView.tsx +9 -26
- package/src/console/ui/clock/a11y.test.tsx +2 -5
- package/src/console/ui/clock/confirmation.test.ts +1 -3
- package/src/console/ui/clock/confirmation.ts +1 -4
- package/src/console/ui/clock/findings.ts +1 -4
- package/src/console/ui/clock/health.ts +2 -7
- package/src/console/ui/clock/index.ts +2 -10
- package/src/console/ui/clock/search.test.ts +1 -3
- package/src/console/ui/clock/search.ts +2 -6
- package/src/console/ui/clock/timeline.test.ts +1 -3
- package/src/console/ui/clock/waiting-on.test.ts +1 -5
- package/src/console/ui/clock/waiting-on.ts +2 -7
- package/src/console/ui/diff/DiffA11yView.tsx +8 -17
- package/src/console/ui/diff/a11y.test.tsx +2 -5
- package/src/console/ui/diff/group.test.ts +3 -13
- package/src/console/ui/diff/group.ts +2 -8
- package/src/console/ui/diff/index.ts +2 -8
- package/src/console/ui/diff/search.test.ts +1 -5
- package/src/console/ui/diff/search.ts +4 -16
- package/src/console/ui/diff/summary.ts +1 -2
- package/src/console/ui/dist/assets/{index-Dy4jht9P.js → index-BWo8R7NR.js} +2 -2
- package/src/console/ui/dist/assets/{panel-access-Dd37LU2c.js → panel-access-C0J2D-a2.js} +1 -1
- package/src/console/ui/dist/assets/{panel-ai-CC7LR6-J.js → panel-ai-D_m6WQI8.js} +1 -1
- package/src/console/ui/dist/assets/{panel-architecture-B5b3iKCz.js → panel-architecture-CKnXFyUx.js} +1 -1
- package/src/console/ui/dist/assets/{panel-channels-CeNjTKXp.js → panel-channels-BOmQ-onL.js} +1 -1
- package/src/console/ui/dist/assets/{panel-clock-DgFTLoHV.js → panel-clock-giAq0Ccv.js} +1 -1
- package/src/console/ui/dist/assets/{panel-diff-DxehccqB.js → panel-diff-cdonmH8c.js} +1 -1
- package/src/console/ui/dist/assets/{panel-flows-BtrVn-Eg.js → panel-flows-DlCU5zjA.js} +2 -2
- package/src/console/ui/dist/assets/{panel-gates-Z9MKRGdH.js → panel-gates-XclZxWD5.js} +1 -1
- package/src/console/ui/dist/assets/{panel-overview-Dt_AeXgd.js → panel-overview-BznEOTnb.js} +1 -1
- package/src/console/ui/dist/assets/{panel-plugins-DWd0TowH.js → panel-plugins-CcGM1g64.js} +1 -1
- package/src/console/ui/dist/assets/{panel-runs-DGstFHeq.js → panel-runs-CGWNHLR4.js} +1 -1
- package/src/console/ui/dist/assets/{panel-signals-DzEa2Fnt.js → panel-signals-CNywkdak.js} +1 -1
- package/src/console/ui/dist/assets/{panel-store-BJkbNgxx.js → panel-store-KmTbFHMH.js} +1 -1
- package/src/console/ui/dist/assets/{panel-traces-BaRVO3gM.js → panel-traces-DBLx2ilD.js} +1 -1
- package/src/console/ui/dist/assets/panel-vault-CEnFc0dk.js +1 -0
- package/src/console/ui/dist/index.html +1 -1
- package/src/console/ui/flows/FlowsA11yView.tsx +7 -22
- package/src/console/ui/flows/a11y.test.tsx +2 -8
- package/src/console/ui/flows/buffer.test.ts +3 -11
- package/src/console/ui/flows/buffer.ts +4 -11
- package/src/console/ui/flows/confirmation.ts +1 -3
- package/src/console/ui/flows/contract.test.ts +3 -7
- package/src/console/ui/flows/contract.ts +12 -36
- package/src/console/ui/flows/graph.test.ts +3 -11
- package/src/console/ui/flows/graph.ts +5 -15
- package/src/console/ui/flows/index.ts +1 -6
- package/src/console/ui/flows/save-as-test.ts +1 -3
- package/src/console/ui/flows/search.ts +8 -25
- package/src/console/ui/flows/tiers.ts +2 -9
- package/src/console/ui/gates/GatesA11yView.tsx +4 -13
- package/src/console/ui/gates/a11y.test.tsx +2 -5
- package/src/console/ui/gates/audit.ts +1 -3
- package/src/console/ui/gates/denial.test.ts +1 -3
- package/src/console/ui/gates/denial.ts +4 -12
- package/src/console/ui/gates/findings.ts +1 -3
- package/src/console/ui/gates/group.test.ts +3 -3
- package/src/console/ui/gates/group.ts +3 -11
- package/src/console/ui/gates/index.ts +2 -10
- package/src/console/ui/gates/search.ts +3 -10
- package/src/console/ui/overview/OverviewA11yView.tsx +9 -27
- package/src/console/ui/overview/a11y.test.tsx +1 -2
- package/src/console/ui/overview/busiest.ts +1 -3
- package/src/console/ui/overview/compose.ts +1 -13
- package/src/console/ui/overview/cost.ts +34 -38
- package/src/console/ui/overview/fixture.ts +21 -26
- package/src/console/ui/overview/golden.ts +4 -14
- package/src/console/ui/overview/index.ts +2 -9
- package/src/console/ui/overview/rank.test.ts +3 -10
- package/src/console/ui/overview/rank.ts +2 -7
- package/src/console/ui/overview/slo.test.ts +5 -9
- package/src/console/ui/overview/slo.ts +6 -23
- package/src/console/ui/overview/verdict.ts +3 -10
- package/src/console/ui/plugins/PluginsA11yView.tsx +8 -18
- package/src/console/ui/plugins/a11y.test.tsx +1 -2
- package/src/console/ui/plugins/fixture.ts +2 -4
- package/src/console/ui/plugins/group.test.ts +1 -3
- package/src/console/ui/plugins/group.ts +1 -6
- package/src/console/ui/plugins/index.ts +3 -13
- package/src/console/ui/plugins/search.ts +7 -19
- package/src/console/ui/runs/RunsA11yView.tsx +5 -20
- package/src/console/ui/runs/a11y.test.tsx +2 -5
- package/src/console/ui/runs/explain.ts +2 -6
- package/src/console/ui/runs/group.ts +3 -12
- package/src/console/ui/runs/histogram.test.ts +2 -11
- package/src/console/ui/runs/histogram.ts +1 -4
- package/src/console/ui/runs/index.ts +4 -18
- package/src/console/ui/runs/project.ts +2 -6
- package/src/console/ui/runs/query.test.ts +1 -3
- package/src/console/ui/runs/query.ts +12 -35
- package/src/console/ui/runs/search.ts +5 -19
- package/src/console/ui/runs/trace-link.test.ts +2 -6
- package/src/console/ui/runs/trace-link.ts +4 -16
- package/src/console/ui/runs/types.ts +1 -3
- package/src/console/ui/shell/App.tsx +2 -10
- package/src/console/ui/shell/client.ts +22 -115
- package/src/console/ui/shell/components/ui.tsx +1 -4
- package/src/console/ui/shell/layout/Shell.tsx +2 -4
- package/src/console/ui/shell/main.tsx +31 -96
- package/src/console/ui/shell/panels/access/AccessPanel.tsx +34 -98
- package/src/console/ui/shell/panels/ai/AiPanel.tsx +35 -106
- package/src/console/ui/shell/panels/architecture/ArchitecturePanel.tsx +18 -66
- package/src/console/ui/shell/panels/channels/ChannelsPanel.tsx +20 -57
- package/src/console/ui/shell/panels/clock/ClockPanel.tsx +22 -54
- package/src/console/ui/shell/panels/diff/DiffPanel.tsx +20 -61
- package/src/console/ui/shell/panels/flows/ContractEditor.tsx +6 -23
- package/src/console/ui/shell/panels/flows/FlowDrawer.tsx +13 -28
- package/src/console/ui/shell/panels/flows/FlowsPanel.tsx +9 -29
- package/src/console/ui/shell/panels/gates/GatesPanel.tsx +24 -80
- package/src/console/ui/shell/panels/overview/OverviewPanel.tsx +20 -58
- package/src/console/ui/shell/panels/plugins/PluginsPanel.tsx +16 -41
- package/src/console/ui/shell/panels/runs/RunsPanel.tsx +31 -99
- package/src/console/ui/shell/panels/signals/SignalsPanel.tsx +38 -101
- package/src/console/ui/shell/panels/store/StorePanel.tsx +27 -66
- package/src/console/ui/shell/panels/traces/TracesPanel.tsx +28 -89
- package/src/console/ui/shell/panels/vault/VaultPanel.tsx +22 -53
- package/src/console/ui/shell/setup/Wizard.tsx +3 -5
- package/src/console/ui/shell/styles.css +1 -2
- package/src/console/ui/signals/SignalsA11yView.tsx +9 -33
- package/src/console/ui/signals/a11y.test.tsx +2 -5
- package/src/console/ui/signals/confirmation.test.ts +1 -5
- package/src/console/ui/signals/confirmation.ts +2 -6
- package/src/console/ui/signals/dry-run.ts +1 -3
- package/src/console/ui/signals/durable.ts +1 -3
- package/src/console/ui/signals/findings.ts +1 -3
- package/src/console/ui/signals/group.test.ts +2 -8
- package/src/console/ui/signals/group.ts +2 -10
- package/src/console/ui/signals/index.ts +1 -4
- package/src/console/ui/signals/monitor.ts +2 -7
- package/src/console/ui/signals/schema-form.test.ts +3 -14
- package/src/console/ui/signals/schema-form.ts +1 -4
- package/src/console/ui/signals/search.ts +4 -13
- package/src/console/ui/store/StoreA11yView.tsx +3 -9
- package/src/console/ui/store/a11y.test.tsx +2 -5
- package/src/console/ui/store/confirmation.test.ts +1 -3
- package/src/console/ui/store/confirmation.ts +1 -4
- package/src/console/ui/store/dry-run.ts +2 -5
- package/src/console/ui/store/fixture.ts +1 -2
- package/src/console/ui/store/group.test.ts +1 -6
- package/src/console/ui/store/group.ts +1 -4
- package/src/console/ui/store/index.ts +1 -5
- package/src/console/ui/store/search.ts +2 -6
- package/src/console/ui/store/will-not-fire.ts +1 -2
- package/src/console/ui/traces/TracesA11yView.tsx +10 -29
- package/src/console/ui/traces/a11y.test.tsx +1 -2
- package/src/console/ui/traces/chain.test.ts +5 -19
- package/src/console/ui/traces/chain.ts +1 -3
- package/src/console/ui/traces/critical-path.test.ts +1 -3
- package/src/console/ui/traces/critical-path.ts +2 -6
- package/src/console/ui/traces/filter.test.ts +2 -6
- package/src/console/ui/traces/filter.ts +5 -13
- package/src/console/ui/traces/fold.test.ts +4 -12
- package/src/console/ui/traces/fold.ts +1 -3
- package/src/console/ui/traces/mini.ts +1 -3
- package/src/console/ui/traces/replay.test.ts +1 -3
- package/src/console/ui/traces/replay.ts +1 -3
- package/src/console/ui/traces/sampling.ts +1 -4
- package/src/console/ui/traces/search.ts +4 -17
- package/src/console/ui/traces/tier.ts +1 -3
- package/src/console/ui/vault/VaultA11yView.tsx +5 -17
- package/src/console/ui/vault/a11y.test.tsx +1 -2
- package/src/console/ui/vault/blast-radius.ts +1 -3
- package/src/console/ui/vault/confirmation.test.ts +1 -5
- package/src/console/ui/vault/confirmation.ts +1 -4
- package/src/console/ui/vault/dormant.test.ts +1 -4
- package/src/console/ui/vault/export-safe.test.ts +1 -5
- package/src/console/ui/vault/export-safe.ts +1 -4
- package/src/console/ui/vault/fixture.ts +3 -3
- package/src/console/ui/vault/group.ts +1 -2
- package/src/console/ui/vault/index.ts +2 -10
- package/src/console/ui/vault/search.ts +2 -6
- package/src/console/ui/vault/types.ts +1 -1
- package/src/console/xss.gate.test.ts +1 -3
- package/src/docker/compose.ts +112 -20
- package/src/docker/derive.ts +5 -19
- package/src/docker/docker.test.ts +15 -15
- package/src/docker/dockerfile.integration.test.ts +12 -21
- package/src/docker/helpers.ts +5 -4
- package/src/docker/index.ts +4 -11
- package/src/docker/pin.ts +1 -9
- package/src/docker/recipes/index.ts +5 -6
- package/src/docker/recipes/mailpit.ts +22 -0
- package/src/docker/recipes/postgres.ts +17 -6
- package/src/docker/recipes/redis.ts +6 -1
- package/src/docker/recipes/rustfs.ts +33 -0
- package/src/docker/stack-id.test.ts +33 -0
- package/src/docker/stack-id.ts +25 -13
- package/src/docker/stack.integration.test.ts +6 -21
- package/src/docker/types.ts +13 -4
- package/src/drivers/ai-anthropic.ts +5 -14
- package/src/drivers/ai-mock.ts +2 -5
- package/src/drivers/ai-openai-compatible.ts +4 -10
- package/src/drivers/ai-providers.test.ts +6 -13
- package/src/drivers/bun-native-completeness.test.ts +6 -15
- package/src/drivers/channel-console.ts +6 -7
- package/src/drivers/channel-fcm.ts +20 -30
- package/src/drivers/channel-resend.ts +1 -3
- package/src/drivers/channel-smtp.ts +2 -6
- package/src/drivers/channel-types.ts +2 -12
- package/src/drivers/channel-unifonic.ts +2 -6
- package/src/drivers/channel-wa-cloud.ts +2 -6
- package/src/drivers/channel-webpush.ts +21 -60
- package/src/drivers/conformance.test.ts +2 -10
- package/src/drivers/conformance.ts +8 -21
- package/src/drivers/fs.ts +2 -8
- package/src/drivers/index.ts +12 -56
- package/src/drivers/memory.ts +14 -41
- package/src/drivers/pgvector.ts +7 -11
- package/src/drivers/postgres.ts +7 -13
- package/src/drivers/redis.ts +13 -37
- package/src/drivers/s3.ts +5 -17
- package/src/drivers/signal-engine.ts +12 -49
- package/src/drivers/signal-memory.ts +2 -8
- package/src/drivers/signal-nats.ts +4 -9
- package/src/drivers/signal-postgres.ts +62 -129
- package/src/drivers/signal-redis.ts +7 -21
- package/src/drivers/signal-types.ts +1 -4
- package/src/drivers/sqlite.ts +3 -12
- package/src/drivers/types.ts +4 -23
- package/src/drivers/vault-env.ts +2 -6
- package/src/drivers/vault-infisical.ts +1 -5
- package/src/drivers/vault-managed.ts +1 -5
- package/src/drivers/vault-memory.ts +1 -5
- package/src/drivers/vault-openbao.ts +1 -5
- package/src/drivers/vault-sops.ts +10 -35
- package/src/drivers/vault-types.ts +1 -7
- package/src/elements/ai/declare.ts +4 -14
- package/src/elements/ai/eval.ts +2 -6
- package/src/elements/ai/pii.ts +1 -3
- package/src/elements/ai/runtime.ts +12 -50
- package/src/elements/ai/schema.ts +4 -15
- package/src/elements/ai.test.ts +13 -24
- package/src/elements/ai.ts +1 -5
- package/src/elements/channel/consent.ts +3 -12
- package/src/elements/channel/costs.ts +4 -15
- package/src/elements/channel/declare.ts +1 -4
- package/src/elements/channel/email-auth.ts +1 -4
- package/src/elements/channel/locale.ts +2 -10
- package/src/elements/channel/mask.ts +1 -3
- package/src/elements/channel/mime.ts +2 -12
- package/src/elements/channel/outcomes.test.ts +1 -5
- package/src/elements/channel/outcomes.ts +5 -15
- package/src/elements/channel/receipts.ts +2 -7
- package/src/elements/channel/runtime.ts +28 -74
- package/src/elements/channel/suppression.ts +8 -14
- package/src/elements/channel.test.ts +8 -31
- package/src/elements/channel.ts +3 -14
- package/src/elements/clock/actions.ts +6 -18
- package/src/elements/clock/declare.ts +1 -3
- package/src/elements/clock/dst.ts +1 -5
- package/src/elements/clock/durable.ts +4 -16
- package/src/elements/clock/health.ts +2 -7
- package/src/elements/clock/leader.ts +2 -9
- package/src/elements/clock/reconcile.ts +4 -15
- package/src/elements/clock/runtime.ts +2 -5
- package/src/elements/clock/schedule.ts +4 -20
- package/src/elements/clock.test.ts +2 -7
- package/src/elements/clock.ts +5 -23
- package/src/elements/gate/permissions.ts +1 -4
- package/src/elements/gate/runtime.ts +7 -28
- package/src/elements/gate.ts +1 -5
- package/src/elements/index.ts +9 -7
- package/src/elements/signal/declare.ts +2 -7
- package/src/elements/signal/reconcile.test.ts +1 -4
- package/src/elements/signal/runtime.ts +1 -3
- package/src/elements/signal.test.ts +3 -15
- package/src/elements/signal.ts +2 -8
- package/src/elements/store/cache.test.ts +46 -0
- package/src/elements/store/cache.ts +3 -11
- package/src/elements/store/classify.ts +5 -22
- package/src/elements/store/declare.ts +8 -17
- package/src/elements/store/domain-ddl.test.ts +86 -0
- package/src/elements/store/emit-drizzle.ts +363 -0
- package/src/elements/store/files-policy.test.ts +1 -5
- package/src/elements/store/files-policy.ts +4 -12
- package/src/elements/store/load-plugin-tables.ts +103 -0
- package/src/elements/store/missing-relation.test.ts +83 -0
- package/src/elements/store/missing-relation.ts +38 -0
- package/src/elements/store/replica.ts +1 -4
- package/src/elements/store/runtime.ts +25 -28
- package/src/elements/store/schema-decl.test.ts +227 -0
- package/src/elements/store/schema-decl.ts +516 -0
- package/src/elements/store/sql-condition.ts +11 -21
- package/src/elements/store/sql-session.test.ts +50 -0
- package/src/elements/store/sql-session.ts +60 -63
- package/src/elements/store/table.ts +35 -19
- package/src/elements/store.test.ts +17 -39
- package/src/elements/store.ts +37 -31
- package/src/elements/vault/chain.ts +34 -0
- package/src/elements/vault/declare.ts +22 -32
- package/src/elements/vault/fingerprint.ts +2 -7
- package/src/elements/vault/redact.ts +2 -6
- package/src/elements/vault/runtime.ts +18 -32
- package/src/elements/vault.test.ts +12 -28
- package/src/elements/vault.ts +8 -12
- package/src/index.ts +5 -2
- package/src/kernel/adopt-routes.ts +15 -29
- package/src/kernel/app.ts +34 -94
- package/src/kernel/auth-resolve.ts +2 -9
- package/src/kernel/boot-bind/ai.ts +1 -4
- package/src/kernel/boot-bind/channel.ts +2 -8
- package/src/kernel/boot-bind/clock.ts +2 -6
- package/src/kernel/boot-bind/gate.ts +2 -8
- package/src/kernel/boot-bind/runs.ts +1 -3
- package/src/kernel/boot-bind/signal.ts +3 -10
- package/src/kernel/boot-bind/store.test.ts +17 -17
- package/src/kernel/boot-bind/store.ts +44 -50
- package/src/kernel/boot-bind/vault.ts +2 -8
- package/src/kernel/boot.test.ts +4 -9
- package/src/kernel/boot.ts +29 -76
- package/src/kernel/budget.test.ts +1 -3
- package/src/kernel/capability.ts +3 -10
- package/src/kernel/dry-run.test.ts +1 -4
- package/src/kernel/dry-run.ts +3 -11
- package/src/kernel/effects.test.ts +1 -5
- package/src/kernel/effects.ts +4 -11
- package/src/kernel/errors.registry.test.ts +2 -8
- package/src/kernel/errors.ts +23 -32
- package/src/kernel/flow.test.ts +12 -25
- package/src/kernel/flow.ts +5 -25
- package/src/kernel/fx.test.ts +15 -44
- package/src/kernel/fx.ts +27 -79
- package/src/kernel/hook-timing.test.ts +3 -6
- package/src/kernel/hook-timing.ts +5 -14
- package/src/kernel/hooks.test.ts +10 -10
- package/src/kernel/hooks.ts +3 -12
- package/src/kernel/index.ts +4 -17
- package/src/kernel/journal.ts +7 -31
- package/src/kernel/on.ts +1 -6
- package/src/kernel/pipeline.test.ts +10 -19
- package/src/kernel/pipeline.ts +5 -17
- package/src/kernel/plug.ts +4 -11
- package/src/kernel/plugin/conflicts.test.ts +13 -25
- package/src/kernel/plugin/decorate.test.ts +8 -13
- package/src/kernel/plugin/scoping.test.ts +4 -11
- package/src/kernel/plugin.ts +48 -24
- package/src/kernel/registry.ts +80 -29
- package/src/kernel/router.test.ts +15 -13
- package/src/kernel/router.ts +9 -29
- package/src/kernel/routing-budget.test.ts +1 -3
- package/src/kernel/run-telemetry.ts +1 -3
- package/src/kernel/triggers.ts +4 -21
- package/src/manifest/diff.test.ts +26 -91
- package/src/manifest/diff.ts +95 -225
- package/src/manifest/index.ts +2 -9
- package/src/manifest/types.ts +29 -5
- package/src/manifest/undeclared.test.ts +4 -12
- package/src/manifest/undeclared.ts +1 -2
- package/src/manifest/validate.test.ts +2 -6
- package/src/manifest/validate.ts +4 -14
- package/src/mcp/authorization.ts +8 -27
- package/src/mcp/confirmation.ts +3 -10
- package/src/mcp/data.ts +2 -6
- package/src/mcp/docs-index.ts +4 -7
- package/src/mcp/docs-mcp.test.ts +3 -12
- package/src/mcp/docs-server.ts +7 -27
- package/src/mcp/docs-tools.ts +2 -6
- package/src/mcp/index.ts +1 -6
- package/src/mcp/injection.gate.test.ts +4 -18
- package/src/mcp/mcp.test.ts +18 -49
- package/src/mcp/protocol.ts +3 -10
- package/src/mcp/server.ts +11 -52
- package/src/mcp/session.ts +4 -14
- package/src/mcp/tools.ts +14 -50
- package/src/plugins/catalogue.test.ts +3 -7
- package/src/plugins/catalogue.ts +1 -3
- package/src/plugins/node-import-scan.ts +2 -5
- package/src/plugins/supply-chain.ts +5 -17
- package/src/release/exports.ts +3 -8
- package/src/release/measure.exports.test.ts +1 -3
- package/src/release/measure.ts +15 -43
- package/src/runs/bench.test.ts +1 -3
- package/src/runs/collect.ts +8 -25
- package/src/runs/drivers/clickhouse.ts +2 -9
- package/src/runs/drivers/files.ts +9 -31
- package/src/runs/drivers/memory.ts +5 -22
- package/src/runs/drivers/postgres.ts +8 -20
- package/src/runs/duckdb.ts +2 -8
- package/src/runs/index.ts +3 -14
- package/src/runs/outlier.ts +3 -10
- package/src/runs/parquet.ts +8 -26
- package/src/runs/privacy.ts +2 -8
- package/src/runs/runs.test.ts +3 -9
- package/src/runs/runtime.ts +7 -32
- package/src/runs/shred.ts +10 -29
- package/src/runs/types.ts +1 -4
- package/src/runtime/bun.ts +4 -15
- package/src/runtime/cold-start.bench.ts +1 -3
- package/src/runtime/dev-request-log.test.ts +1 -4
- package/src/runtime/dev-request-log.ts +1 -4
- package/src/runtime/index.ts +1 -6
- package/src/runtime/primitives.ts +5 -4
- package/src/runtime/security.ts +3 -13
- package/src/runtime/serve.test.ts +4 -7
- package/src/runtime/types.ts +1 -4
- package/src/runtime/web-standard.ts +3 -15
- package/src/term.test.ts +4 -6
- package/src/term.ts +49 -98
- package/src/test/create-test-app.test.ts +4 -14
- package/src/test/create-test-app.ts +13 -31
- package/src/test/provisions.integration.test.ts +3 -11
- package/src/upgrade/codemods.test.ts +25 -6
- package/src/upgrade/codemods.ts +116 -3
- package/src/validation/standard-schema.test.ts +2 -5
- package/src/validation/standard-schema.ts +13 -33
- package/src/console/ui/dist/assets/panel-vault-BbfWdox0.js +0 -1
package/src/cli/dev.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `oke dev` — watch · hot reload · Console :6533 · MCP :6535 · client types on save.
|
|
3
|
-
* `
|
|
3
|
+
* Mode: `local` (in-memory) or `docker` (compose infra + host Bun).
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { watch } from "node:fs";
|
|
@@ -13,7 +13,6 @@ import type { ConsoleState } from "../console/server/state.ts";
|
|
|
13
13
|
import {
|
|
14
14
|
DEFAULT_DOCKER_DIR,
|
|
15
15
|
deriveInfrastructure,
|
|
16
|
-
formatStackEnv,
|
|
17
16
|
loadExistingStackCredentials,
|
|
18
17
|
stackAppSlug,
|
|
19
18
|
stackInstanceId,
|
|
@@ -22,11 +21,7 @@ import {
|
|
|
22
21
|
} from "../docker/index.ts";
|
|
23
22
|
import type { Manifest } from "../manifest/types.ts";
|
|
24
23
|
import type { McpContext } from "../mcp/tools.ts";
|
|
25
|
-
import {
|
|
26
|
-
APP_PORT,
|
|
27
|
-
CONSOLE_PORT,
|
|
28
|
-
MCP_PORT,
|
|
29
|
-
} from "../runtime/types.ts";
|
|
24
|
+
import { APP_PORT, CONSOLE_PORT, MCP_PORT } from "../runtime/types.ts";
|
|
30
25
|
import {
|
|
31
26
|
formatDevBanner,
|
|
32
27
|
formatDevLogSeparator,
|
|
@@ -36,15 +31,16 @@ import {
|
|
|
36
31
|
} from "../term.ts";
|
|
37
32
|
import { clientAdd } from "./client-add.ts";
|
|
38
33
|
import { resolveDriverId } from "../config/index.ts";
|
|
34
|
+
import { askDevMode, type AskDevModeFn } from "./ask-dev-mode.ts";
|
|
39
35
|
import {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
} from "./load-config.ts";
|
|
36
|
+
createDebouncedRunner,
|
|
37
|
+
isDomainSchemaWatchPath,
|
|
38
|
+
resolveDevAutoPush,
|
|
39
|
+
} from "./db-auto-push.ts";
|
|
40
|
+
import { resolveDrizzleConfigPath, runPush } from "./db.ts";
|
|
41
|
+
import { readDevMode, shouldAskDevMode, writeDevMode, type DevMode } from "./dev-mode.ts";
|
|
42
|
+
import { buildDevHeroSnapshot, encodeHeroSnapshot } from "./hero-meta.ts";
|
|
43
|
+
import { loadManifest, loadOkeConfig, resolveImages } from "./load-config.ts";
|
|
48
44
|
import { mcpContextFromConsole } from "./mcp-from-console.ts";
|
|
49
45
|
import { resolveDevPorts } from "./ports.ts";
|
|
50
46
|
|
|
@@ -114,7 +110,30 @@ export interface DevSession {
|
|
|
114
110
|
export interface DevOptions {
|
|
115
111
|
readonly cwd?: string;
|
|
116
112
|
readonly entry?: string;
|
|
117
|
-
|
|
113
|
+
/**
|
|
114
|
+
* Session-only mode override. `true` / role list → docker; `false` → local.
|
|
115
|
+
* When unset, resolve from `.oke/mode` / TTY ask / non-TTY default `local`.
|
|
116
|
+
*/
|
|
117
|
+
readonly docker?: boolean | readonly string[];
|
|
118
|
+
/** Force local for this session only (never writes `.oke/mode`). */
|
|
119
|
+
readonly local?: boolean;
|
|
120
|
+
/**
|
|
121
|
+
* Opt out of auto `oke db push` on schema change for this session.
|
|
122
|
+
* Also set via `--no-db-push`.
|
|
123
|
+
*/
|
|
124
|
+
readonly noDbPush?: boolean;
|
|
125
|
+
/**
|
|
126
|
+
* Injectable domain-schema push (tests). Default: {@link runPush}.
|
|
127
|
+
*
|
|
128
|
+
* @param cwd - Project root
|
|
129
|
+
*/
|
|
130
|
+
readonly dbPush?: (cwd: string) => Promise<number>;
|
|
131
|
+
/**
|
|
132
|
+
* Called when a schema watch path triggers auto-push (tests).
|
|
133
|
+
*
|
|
134
|
+
* @param filename - Relative path from the watcher
|
|
135
|
+
*/
|
|
136
|
+
readonly onDbAutoPush?: (filename: string) => void;
|
|
118
137
|
readonly images?: Readonly<Record<string, string>>;
|
|
119
138
|
readonly credentials?: DeriveOptions["credentials"];
|
|
120
139
|
readonly write?: (text: string) => void;
|
|
@@ -138,15 +157,12 @@ export interface DevOptions {
|
|
|
138
157
|
readonly consolePort?: number;
|
|
139
158
|
readonly mcpPort?: number;
|
|
140
159
|
/**
|
|
141
|
-
* Boot compose
|
|
160
|
+
* Boot compose (injectable).
|
|
142
161
|
*
|
|
143
162
|
* @param composeFiles - `-f` list excluding override if missing
|
|
144
|
-
* @param cwd -
|
|
163
|
+
* @param cwd - Compose directory (`docker/`)
|
|
145
164
|
*/
|
|
146
|
-
readonly composeUp?: (
|
|
147
|
-
composeFiles: readonly string[],
|
|
148
|
-
cwd: string,
|
|
149
|
-
) => Promise<void>;
|
|
165
|
+
readonly composeUp?: (composeFiles: readonly string[], cwd: string) => Promise<void>;
|
|
150
166
|
/**
|
|
151
167
|
* Regenerate client types (injectable).
|
|
152
168
|
*
|
|
@@ -166,10 +182,15 @@ export interface DevOptions {
|
|
|
166
182
|
* (import → `app.boot()` → `createBunRuntime().serve`) so Bun soft-reloads
|
|
167
183
|
* app code while preserving the listen socket.
|
|
168
184
|
*/
|
|
169
|
-
readonly startApp?: (
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
185
|
+
readonly startApp?: (entry: string, env: Record<string, string>) => Promise<DevAppHandle>;
|
|
186
|
+
/**
|
|
187
|
+
* Injectable mode prompt (tests). Default: {@link askDevMode}.
|
|
188
|
+
*/
|
|
189
|
+
readonly ask?: AskDevModeFn;
|
|
190
|
+
/**
|
|
191
|
+
* Override stdin TTY detection (tests). Default: `process.stdin.isTTY`.
|
|
192
|
+
*/
|
|
193
|
+
readonly stdinIsTTY?: boolean;
|
|
173
194
|
}
|
|
174
195
|
|
|
175
196
|
/** Result of a dry-run / prepared / live-but-detached dev session. */
|
|
@@ -236,20 +257,55 @@ export async function runDev(options: DevOptions = {}): Promise<DevResult> {
|
|
|
236
257
|
return { code: 1 };
|
|
237
258
|
}
|
|
238
259
|
|
|
260
|
+
const explicitLocal = options.local === true;
|
|
261
|
+
const explicitDocker = options.docker === true || Array.isArray(options.docker);
|
|
262
|
+
if (explicitLocal && explicitDocker) {
|
|
263
|
+
console.error("oke dev: use either --local or --docker, not both");
|
|
264
|
+
return { code: 1 };
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
const savedMode = await readDevMode(cwd);
|
|
268
|
+
const explicit = explicitLocal || explicitDocker;
|
|
269
|
+
let mode: DevMode;
|
|
270
|
+
if (explicitLocal) {
|
|
271
|
+
mode = "local";
|
|
272
|
+
} else if (explicitDocker) {
|
|
273
|
+
mode = "docker";
|
|
274
|
+
} else if (savedMode !== null) {
|
|
275
|
+
mode = savedMode;
|
|
276
|
+
} else if (
|
|
277
|
+
shouldAskDevMode({
|
|
278
|
+
saved: savedMode,
|
|
279
|
+
explicit,
|
|
280
|
+
stdinIsTTY: options.stdinIsTTY ?? process.stdin.isTTY,
|
|
281
|
+
})
|
|
282
|
+
) {
|
|
283
|
+
const ask = options.ask ?? askDevMode;
|
|
284
|
+
const chosen = await ask();
|
|
285
|
+
if (chosen === null) {
|
|
286
|
+
console.error("oke dev: cancelled");
|
|
287
|
+
return { code: 1 };
|
|
288
|
+
}
|
|
289
|
+
mode = chosen;
|
|
290
|
+
await writeDevMode(cwd, mode);
|
|
291
|
+
} else {
|
|
292
|
+
// Non-TTY + unset: deterministic local — zero ask, zero docker, no save.
|
|
293
|
+
mode = "local";
|
|
294
|
+
}
|
|
295
|
+
|
|
239
296
|
let stackRoles: string[] | null = null;
|
|
240
297
|
let composeFiles: string[] | null = null;
|
|
241
298
|
let stackEnv: Record<string, string> | null = null;
|
|
242
299
|
let stackSqlDriver = "postgres";
|
|
243
300
|
let stackKvDriver = "redis";
|
|
244
|
-
let loadedConfig: Awaited<ReturnType<typeof loadOkeConfig>>["config"] | null =
|
|
245
|
-
null;
|
|
301
|
+
let loadedConfig: Awaited<ReturnType<typeof loadOkeConfig>>["config"] | null = null;
|
|
246
302
|
try {
|
|
247
303
|
loadedConfig = (await loadOkeConfig(cwd)).config;
|
|
248
304
|
} catch {
|
|
249
305
|
loadedConfig = null;
|
|
250
306
|
}
|
|
251
307
|
|
|
252
|
-
if (
|
|
308
|
+
if (mode === "docker") {
|
|
253
309
|
let images = options.images;
|
|
254
310
|
if (!images) {
|
|
255
311
|
if (!loadedConfig) {
|
|
@@ -271,28 +327,23 @@ export async function runDev(options: DevOptions = {}): Promise<DevResult> {
|
|
|
271
327
|
loadedConfig = null;
|
|
272
328
|
}
|
|
273
329
|
}
|
|
274
|
-
if (Array.isArray(options.
|
|
275
|
-
const allow = new Set(options.
|
|
276
|
-
images = Object.fromEntries(
|
|
277
|
-
Object.entries(images).filter(([role]) => allow.has(role)),
|
|
278
|
-
);
|
|
330
|
+
if (Array.isArray(options.docker)) {
|
|
331
|
+
const allow = new Set(options.docker);
|
|
332
|
+
images = Object.fromEntries(Object.entries(images).filter(([role]) => allow.has(role)));
|
|
279
333
|
stackRoles = [...allow];
|
|
280
334
|
} else {
|
|
281
335
|
stackRoles = Object.keys(images);
|
|
282
336
|
}
|
|
283
337
|
|
|
284
|
-
stackSqlDriver =
|
|
285
|
-
|
|
286
|
-
stackKvDriver =
|
|
287
|
-
resolveDriverId(loadedConfig?.drivers?.store?.kv, "prod") ?? "redis";
|
|
338
|
+
stackSqlDriver = resolveDriverId(loadedConfig?.drivers?.store?.sql, "prod") ?? "postgres";
|
|
339
|
+
stackKvDriver = resolveDriverId(loadedConfig?.drivers?.store?.kv, "prod") ?? "redis";
|
|
288
340
|
|
|
289
341
|
const composeDir = DEFAULT_DOCKER_DIR;
|
|
290
342
|
const dockerOut = resolve(cwd, composeDir);
|
|
291
343
|
const instanceId = stackInstanceId(cwd);
|
|
292
344
|
const appSlug = stackAppSlug(cwd);
|
|
293
345
|
const reusedCreds =
|
|
294
|
-
options.credentials ??
|
|
295
|
-
(await loadExistingStackCredentials(cwd, stackRoles));
|
|
346
|
+
options.credentials ?? (await loadExistingStackCredentials(cwd, stackRoles));
|
|
296
347
|
const derived = deriveInfrastructure({
|
|
297
348
|
images,
|
|
298
349
|
app: appSlug,
|
|
@@ -304,38 +355,40 @@ export async function runDev(options: DevOptions = {}): Promise<DevResult> {
|
|
|
304
355
|
host: "127.0.0.1",
|
|
305
356
|
});
|
|
306
357
|
// Layer 4 is user-owned — include only if the file already exists.
|
|
307
|
-
const existingOverride = await Bun.file(
|
|
308
|
-
resolve(dockerOut, "compose.override.yml"),
|
|
309
|
-
).exists();
|
|
358
|
+
const existingOverride = await Bun.file(resolve(dockerOut, "compose.override.yml")).exists();
|
|
310
359
|
composeFiles = derived.composeFiles.filter(
|
|
311
360
|
(f) => f !== "compose.override.yml" || existingOverride,
|
|
312
361
|
);
|
|
313
362
|
stackEnv = { ...derived.stackEnv };
|
|
314
363
|
|
|
315
364
|
if (!options.dryRun) {
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
});
|
|
320
|
-
// Ensure .env.stack is at project root for the host Bun app / vault.
|
|
321
|
-
await Bun.write(resolve(cwd, ".env.stack"), formatStackEnv(stackEnv));
|
|
322
|
-
const up =
|
|
323
|
-
options.composeUp ??
|
|
324
|
-
(async (files, dir) => {
|
|
325
|
-
const args = ["compose", ...files.flatMap((f) => ["-f", f]), "up", "-d"];
|
|
326
|
-
const proc = Bun.spawn(["docker", ...args], {
|
|
327
|
-
cwd: dir,
|
|
328
|
-
stdout: "inherit",
|
|
329
|
-
stderr: "inherit",
|
|
330
|
-
env: { ...process.env, ...stackEnv! },
|
|
331
|
-
});
|
|
332
|
-
const code = await proc.exited;
|
|
333
|
-
if (code !== 0) {
|
|
334
|
-
throw new Error(`oke dev --stack: docker compose exited ${code}`);
|
|
335
|
-
}
|
|
365
|
+
try {
|
|
366
|
+
await writeDerivedFiles(derived, dockerOut, {
|
|
367
|
+
writeStackEnv: true,
|
|
336
368
|
});
|
|
337
|
-
|
|
338
|
-
|
|
369
|
+
const up =
|
|
370
|
+
options.composeUp ??
|
|
371
|
+
(async (files, dir) => {
|
|
372
|
+
const args = ["compose", ...files.flatMap((f) => ["-f", f]), "up", "-d"];
|
|
373
|
+
const proc = Bun.spawn(["docker", ...args], {
|
|
374
|
+
cwd: dir,
|
|
375
|
+
stdout: "inherit",
|
|
376
|
+
stderr: "inherit",
|
|
377
|
+
env: { ...process.env, ...stackEnv! },
|
|
378
|
+
});
|
|
379
|
+
const code = await proc.exited;
|
|
380
|
+
if (code !== 0) {
|
|
381
|
+
throw new Error(`oke dev --docker: docker compose exited ${code}`);
|
|
382
|
+
}
|
|
383
|
+
});
|
|
384
|
+
// Compose files live under docker/; cwd for compose is that directory.
|
|
385
|
+
await up(composeFiles, dockerOut);
|
|
386
|
+
} catch (err) {
|
|
387
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
388
|
+
console.error(msg);
|
|
389
|
+
console.error("oke dev: docker mode failed — fix compose, or run `oke mode local`");
|
|
390
|
+
return { code: 1 };
|
|
391
|
+
}
|
|
339
392
|
const roleLabel = (role: string): string => {
|
|
340
393
|
if (role === "store.sql") return "postgres";
|
|
341
394
|
if (role === "store.kv") return "redis";
|
|
@@ -370,9 +423,9 @@ export async function runDev(options: DevOptions = {}): Promise<DevResult> {
|
|
|
370
423
|
|
|
371
424
|
let okeVersion = "0.0.0";
|
|
372
425
|
try {
|
|
373
|
-
const pkg = (await Bun.file(
|
|
374
|
-
|
|
375
|
-
|
|
426
|
+
const pkg = (await Bun.file(resolve(import.meta.dir, "../../package.json")).json()) as {
|
|
427
|
+
version?: string;
|
|
428
|
+
};
|
|
376
429
|
if (typeof pkg.version === "string") okeVersion = pkg.version;
|
|
377
430
|
} catch {
|
|
378
431
|
// shipped binary may not sit next to package.json
|
|
@@ -380,9 +433,9 @@ export async function runDev(options: DevOptions = {}): Promise<DevResult> {
|
|
|
380
433
|
|
|
381
434
|
const heroSnapshot = buildDevHeroSnapshot({
|
|
382
435
|
config: loadedConfig,
|
|
383
|
-
|
|
384
|
-
sqlDriver:
|
|
385
|
-
kvDriver:
|
|
436
|
+
docker: mode === "docker",
|
|
437
|
+
sqlDriver: mode === "docker" ? stackSqlDriver : undefined,
|
|
438
|
+
kvDriver: mode === "docker" ? stackKvDriver : undefined,
|
|
386
439
|
version: okeVersion,
|
|
387
440
|
nodeEnv: "development",
|
|
388
441
|
});
|
|
@@ -399,6 +452,12 @@ export async function runDev(options: DevOptions = {}): Promise<DevResult> {
|
|
|
399
452
|
|
|
400
453
|
if (options.dryRun) return { code: 0, plan };
|
|
401
454
|
|
|
455
|
+
const autoPushEnabled = resolveDevAutoPush({
|
|
456
|
+
noDbPush: options.noDbPush,
|
|
457
|
+
docker: Boolean(stackEnv),
|
|
458
|
+
configAutoPush: loadedConfig?.db?.autoPush,
|
|
459
|
+
});
|
|
460
|
+
|
|
402
461
|
const env: Record<string, string> = {
|
|
403
462
|
...(process.env as Record<string, string>),
|
|
404
463
|
NODE_ENV: "development",
|
|
@@ -408,10 +467,12 @@ export async function runDev(options: DevOptions = {}): Promise<DevResult> {
|
|
|
408
467
|
OKE_DEV_HERO_CONSOLE: `http://127.0.0.1:${consolePort}`,
|
|
409
468
|
OKE_DEV_HERO_MCP: `http://127.0.0.1:${mcpPort}`,
|
|
410
469
|
OKE_DEV_HERO_META: encodeHeroSnapshot(heroSnapshot),
|
|
470
|
+
// Propagate opt-out so the app disables ensureFromMeta when auto-push owns DDL.
|
|
471
|
+
...(autoPushEnabled ? { OKE_DB_AUTO_PUSH: "1" } : { OKE_DB_AUTO_PUSH: "0" }),
|
|
411
472
|
...(stackEnv ?? {}),
|
|
412
473
|
...(stackEnv
|
|
413
474
|
? {
|
|
414
|
-
|
|
475
|
+
OKE_DOCKER: "1",
|
|
415
476
|
OKE_SQL_DRIVER: stackSqlDriver,
|
|
416
477
|
OKE_KV_DRIVER: stackKvDriver,
|
|
417
478
|
}
|
|
@@ -419,18 +480,12 @@ export async function runDev(options: DevOptions = {}): Promise<DevResult> {
|
|
|
419
480
|
};
|
|
420
481
|
process.env.OKE_DEV_REQUEST_LOG = "1";
|
|
421
482
|
|
|
422
|
-
const startApp =
|
|
423
|
-
options.startApp ??
|
|
424
|
-
((entryPath, appEnv) => startAppHot(cwd, entryPath, appEnv));
|
|
483
|
+
const startApp = options.startApp ?? ((entryPath, appEnv) => startAppHot(cwd, entryPath, appEnv));
|
|
425
484
|
|
|
426
485
|
const seedManifest =
|
|
427
|
-
options.manifest !== undefined
|
|
428
|
-
? options.manifest
|
|
429
|
-
: await tryLoadProjectManifest(cwd);
|
|
486
|
+
options.manifest !== undefined ? options.manifest : await tryLoadProjectManifest(cwd);
|
|
430
487
|
|
|
431
|
-
async function refreshManifestInto(
|
|
432
|
-
state: ConsoleState | null,
|
|
433
|
-
): Promise<void> {
|
|
488
|
+
async function refreshManifestInto(state: ConsoleState | null): Promise<void> {
|
|
434
489
|
if (!state) return;
|
|
435
490
|
try {
|
|
436
491
|
const { extractManifest } = await import("../compiler/extract.ts");
|
|
@@ -445,9 +500,7 @@ export async function runDev(options: DevOptions = {}): Promise<DevResult> {
|
|
|
445
500
|
const serveConsole =
|
|
446
501
|
options.serveConsole ??
|
|
447
502
|
(async (port) => {
|
|
448
|
-
const { serveConsole: serveConsoleKernel } = await import(
|
|
449
|
-
"../console/server/serve.ts"
|
|
450
|
-
);
|
|
503
|
+
const { serveConsole: serveConsoleKernel } = await import("../console/server/serve.ts");
|
|
451
504
|
const server = await serveConsoleKernel({
|
|
452
505
|
port,
|
|
453
506
|
hostname: "127.0.0.1",
|
|
@@ -455,16 +508,9 @@ export async function runDev(options: DevOptions = {}): Promise<DevResult> {
|
|
|
455
508
|
env: "dev",
|
|
456
509
|
silentClaim: options.silentClaim ?? false,
|
|
457
510
|
...(options.secret !== undefined ? { secret: options.secret } : {}),
|
|
458
|
-
...(seedManifest !== undefined && seedManifest !== null
|
|
459
|
-
? { manifest: seedManifest }
|
|
460
|
-
: {}),
|
|
511
|
+
...(seedManifest !== undefined && seedManifest !== null ? { manifest: seedManifest } : {}),
|
|
461
512
|
});
|
|
462
|
-
write(
|
|
463
|
-
formatServiceLine(
|
|
464
|
-
"Console",
|
|
465
|
-
`http://127.0.0.1:${server.port}`,
|
|
466
|
-
),
|
|
467
|
-
);
|
|
513
|
+
write(formatServiceLine("Console", `http://127.0.0.1:${server.port}`));
|
|
468
514
|
return {
|
|
469
515
|
console: server.console,
|
|
470
516
|
port: server.port,
|
|
@@ -538,27 +584,53 @@ export async function runDev(options: DevOptions = {}): Promise<DevResult> {
|
|
|
538
584
|
const boundMcpPort = mcpServer?.port ?? mcpPort;
|
|
539
585
|
const mcpUrl = mcpServer?.url ?? null;
|
|
540
586
|
|
|
541
|
-
const appUrl =
|
|
542
|
-
app.url?.origin ?? `http://127.0.0.1:${boundAppPort}`;
|
|
587
|
+
const appUrl = app.url?.origin ?? `http://127.0.0.1:${boundAppPort}`;
|
|
543
588
|
await regen(appUrl);
|
|
589
|
+
|
|
590
|
+
const dbPush =
|
|
591
|
+
options.dbPush ??
|
|
592
|
+
(async (projectCwd: string) => {
|
|
593
|
+
const configPath = await resolveDrizzleConfigPath(projectCwd);
|
|
594
|
+
return runPush(configPath, (t) => write(t));
|
|
595
|
+
});
|
|
596
|
+
|
|
597
|
+
let lastSchemaFilename = "";
|
|
598
|
+
const autoPushRunner = createDebouncedRunner(async () => {
|
|
599
|
+
if (!autoPushEnabled) return;
|
|
600
|
+
options.onDbAutoPush?.(lastSchemaFilename);
|
|
601
|
+
write(formatStatusLine("oke db push (schema change)"));
|
|
602
|
+
try {
|
|
603
|
+
await dbPush(cwd);
|
|
604
|
+
} catch {
|
|
605
|
+
// Mid-edit / kit unavailable — next save retries.
|
|
606
|
+
}
|
|
607
|
+
});
|
|
608
|
+
|
|
609
|
+
// Initial sync so local DB matches schema.ts without a prior manual push.
|
|
610
|
+
if (autoPushEnabled) {
|
|
611
|
+
lastSchemaFilename = "src/schema.ts";
|
|
612
|
+
autoPushRunner.trigger();
|
|
613
|
+
}
|
|
614
|
+
|
|
544
615
|
write(formatDevLogSeparator());
|
|
545
616
|
|
|
546
|
-
const watcher = watch(
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
()
|
|
550
|
-
void
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
}
|
|
556
|
-
);
|
|
617
|
+
const watcher = watch(resolve(cwd, "src"), { recursive: true }, (_event, filename) => {
|
|
618
|
+
void regen(appUrl);
|
|
619
|
+
// Only live-extract when the host did not pin a Manifest (tests).
|
|
620
|
+
if (options.manifest === undefined) {
|
|
621
|
+
void refreshManifestInto(consoleState);
|
|
622
|
+
}
|
|
623
|
+
if (autoPushEnabled && isDomainSchemaWatchPath(filename?.toString())) {
|
|
624
|
+
lastSchemaFilename = filename?.toString() ?? "schema.ts";
|
|
625
|
+
autoPushRunner.trigger();
|
|
626
|
+
}
|
|
627
|
+
});
|
|
557
628
|
|
|
558
629
|
let stopped = false;
|
|
559
630
|
const stop = () => {
|
|
560
631
|
if (stopped) return;
|
|
561
632
|
stopped = true;
|
|
633
|
+
autoPushRunner.cancel();
|
|
562
634
|
watcher.close();
|
|
563
635
|
app.stop();
|
|
564
636
|
consoleServer.stop();
|
|
@@ -619,9 +691,7 @@ function isSparseManifest(manifest: Manifest): boolean {
|
|
|
619
691
|
*
|
|
620
692
|
* @param cwd - Project root
|
|
621
693
|
*/
|
|
622
|
-
async function tryLoadProjectManifest(
|
|
623
|
-
cwd: string,
|
|
624
|
-
): Promise<Manifest | null | undefined> {
|
|
694
|
+
async function tryLoadProjectManifest(cwd: string): Promise<Manifest | null | undefined> {
|
|
625
695
|
let extracted: Manifest | undefined;
|
|
626
696
|
try {
|
|
627
697
|
const { extractManifest } = await import("../compiler/extract.ts");
|
|
@@ -658,10 +728,7 @@ async function startAppHot(
|
|
|
658
728
|
): Promise<DevAppHandle> {
|
|
659
729
|
const absoluteEntry = resolve(cwd, entryPath);
|
|
660
730
|
const runner = resolve(import.meta.dir, "dev-app-runner.ts");
|
|
661
|
-
const readyPath = join(
|
|
662
|
-
tmpdir(),
|
|
663
|
-
`oke-dev-ready-${crypto.randomUUID()}.txt`,
|
|
664
|
-
);
|
|
731
|
+
const readyPath = join(tmpdir(), `oke-dev-ready-${crypto.randomUUID()}.txt`);
|
|
665
732
|
const hostname = "127.0.0.1";
|
|
666
733
|
const env: Record<string, string> = {
|
|
667
734
|
...appEnv,
|
|
@@ -696,11 +763,7 @@ async function startAppHot(
|
|
|
696
763
|
};
|
|
697
764
|
|
|
698
765
|
try {
|
|
699
|
-
const boundPort = await waitForAppReady(
|
|
700
|
-
readyPath,
|
|
701
|
-
proc,
|
|
702
|
-
APP_READY_TIMEOUT_MS,
|
|
703
|
-
);
|
|
766
|
+
const boundPort = await waitForAppReady(readyPath, proc, APP_READY_TIMEOUT_MS);
|
|
704
767
|
// Child prints the App ready line (again on each soft reload).
|
|
705
768
|
const url = new URL(`http://${hostname}:${boundPort}/`);
|
|
706
769
|
return { stop, port: boundPort, url };
|
|
@@ -726,9 +789,7 @@ async function waitForAppReady(
|
|
|
726
789
|
while (Date.now() - started < timeoutMs) {
|
|
727
790
|
const exitCode = proc.exitCode;
|
|
728
791
|
if (exitCode !== null) {
|
|
729
|
-
throw new Error(
|
|
730
|
-
`oke dev: app process exited before ready (code ${exitCode})`,
|
|
731
|
-
);
|
|
792
|
+
throw new Error(`oke dev: app process exited before ready (code ${exitCode})`);
|
|
732
793
|
}
|
|
733
794
|
if (await Bun.file(readyPath).exists()) {
|
|
734
795
|
const text = (await Bun.file(readyPath).text()).trim();
|
|
@@ -740,44 +801,57 @@ async function waitForAppReady(
|
|
|
740
801
|
}
|
|
741
802
|
await Bun.sleep(25);
|
|
742
803
|
}
|
|
743
|
-
throw new Error(
|
|
744
|
-
`oke dev: app did not become ready within ${timeoutMs}ms`,
|
|
745
|
-
);
|
|
804
|
+
throw new Error(`oke dev: app did not become ready within ${timeoutMs}ms`);
|
|
746
805
|
}
|
|
747
806
|
|
|
748
807
|
/**
|
|
749
|
-
* CLI entry for `oke dev [--
|
|
808
|
+
* CLI entry for `oke dev [--local|-l] [--docker|-d [roles]]`.
|
|
750
809
|
*
|
|
751
810
|
* @param args - Args after `dev`
|
|
752
811
|
*/
|
|
753
812
|
export async function devCli(args: readonly string[]): Promise<number> {
|
|
754
|
-
let
|
|
813
|
+
let docker: boolean | string[] | undefined;
|
|
814
|
+
let local = false;
|
|
815
|
+
let noDbPush = false;
|
|
755
816
|
let entry: string | undefined;
|
|
756
817
|
for (let i = 0; i < args.length; i++) {
|
|
757
818
|
const a = args[i]!;
|
|
758
|
-
if (a === "--
|
|
819
|
+
if (a === "--local" || a === "-l") {
|
|
820
|
+
local = true;
|
|
821
|
+
} else if (a === "--docker" || a === "-d") {
|
|
759
822
|
const next = args[i + 1];
|
|
760
823
|
if (next && !next.startsWith("-") && /^[\w.,]+$/.test(next)) {
|
|
761
|
-
|
|
824
|
+
docker = next
|
|
825
|
+
.split(",")
|
|
826
|
+
.map((s) => s.trim())
|
|
827
|
+
.filter(Boolean);
|
|
762
828
|
i++;
|
|
763
829
|
} else {
|
|
764
|
-
|
|
830
|
+
docker = true;
|
|
765
831
|
}
|
|
832
|
+
} else if (a === "--no-db-push") {
|
|
833
|
+
noDbPush = true;
|
|
766
834
|
} else if (a === "--entry" || a === "-e") entry = args[++i];
|
|
767
835
|
else if (a === "--help" || a === "-h") {
|
|
768
|
-
console.log(`oke dev [--
|
|
836
|
+
console.log(`oke dev [--local|-l] [--docker|-d [roles]] [--no-db-push] [--entry|-e src/app.ts]
|
|
769
837
|
|
|
770
838
|
Watch · hot reload · Console :6533 · app :6530 · MCP :6535
|
|
771
839
|
Regenerates client types on every save.
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
840
|
+
Local mode auto-runs \`oke db push\` when schema.ts changes (opt out: --no-db-push).
|
|
841
|
+
|
|
842
|
+
Bare \`oke dev\` uses .oke/mode (one-time prompt on a TTY; non-TTY → local).
|
|
843
|
+
--local / --docker override for this session only (never write .oke/mode).
|
|
844
|
+
--docker boots infra under docker/ and runs the app on host Bun with prod
|
|
845
|
+
store drivers (Postgres/Redis). Partial roles: -d store.sql,store.kv.
|
|
846
|
+
Change the saved default with \`oke mode local|docker\`.
|
|
775
847
|
`);
|
|
776
848
|
return 0;
|
|
777
849
|
}
|
|
778
850
|
}
|
|
779
851
|
const { code } = await runDev({
|
|
780
|
-
|
|
852
|
+
...(local ? { local: true } : {}),
|
|
853
|
+
...(docker === undefined ? {} : { docker }),
|
|
854
|
+
...(noDbPush ? { noDbPush: true } : {}),
|
|
781
855
|
entry,
|
|
782
856
|
});
|
|
783
857
|
return code;
|
|
@@ -12,8 +12,9 @@ import {
|
|
|
12
12
|
} from "./doc-drift.ts";
|
|
13
13
|
|
|
14
14
|
describe("doc-drift", () => {
|
|
15
|
-
test("normalizeTs
|
|
16
|
-
expect(normalizeTs("a \n b\t\n")).toBe("a
|
|
15
|
+
test("normalizeTs collapses whitespace (indent-insensitive)", () => {
|
|
16
|
+
expect(normalizeTs("a \n b\t\n")).toBe("a b");
|
|
17
|
+
expect(normalizeTs(" const t = 1;\n const u = 2;")).toBe("const t = 1; const u = 2;");
|
|
17
18
|
});
|
|
18
19
|
|
|
19
20
|
test("parseClaimedFences picks headed typescript only", () => {
|