@treeseed/sdk 0.11.0 → 0.12.5
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/README.md +9 -4
- package/dist/agent-capacity.d.ts +916 -0
- package/dist/agent-capacity.js +1600 -0
- package/dist/agent-tools.d.ts +37 -0
- package/dist/agent-tools.js +301 -0
- package/dist/api/app.d.ts +1 -1
- package/dist/api/auth/d1-database.d.ts +2 -2
- package/dist/api/auth/d1-provider.d.ts +4 -4
- package/dist/api/auth/d1-store.d.ts +2 -2
- package/dist/api/auth/memory-provider.d.ts +1 -1
- package/dist/api/auth/tokens.d.ts +1 -1
- package/dist/api/config.d.ts +3 -1
- package/dist/api/config.js +34 -10
- package/dist/api/http.d.ts +2 -2
- package/dist/api/index.d.ts +10 -10
- package/dist/api/index.js +4 -2
- package/dist/api/operations-routes.d.ts +3 -3
- package/dist/api/operations.d.ts +1 -1
- package/dist/api/providers.d.ts +1 -1
- package/dist/api/providers.js +21 -4
- package/dist/api/railway.d.ts +3 -2
- package/dist/api/sdk-dispatch.d.ts +4 -4
- package/dist/api/sdk-routes.d.ts +2 -2
- package/dist/api/templates.d.ts +2 -2
- package/dist/api/types.d.ts +3 -2
- package/dist/capacity-provider.d.ts +117 -60
- package/dist/capacity-provider.js +215 -43
- package/dist/capacity.d.ts +2 -2
- package/dist/cli-tools.d.ts +1 -1
- package/dist/content-operations.d.ts +97 -0
- package/dist/content-operations.js +250 -0
- package/dist/content-store.d.ts +4 -4
- package/dist/control-plane-client.d.ts +13 -18
- package/dist/control-plane-client.js +8 -86
- package/dist/control-plane.d.ts +2 -2
- package/dist/copilot.d.ts +3 -0
- package/dist/copilot.js +16 -1
- package/dist/d1-http.d.ts +1 -1
- package/dist/d1-store.d.ts +32 -57
- package/dist/d1-store.js +115 -318
- package/dist/db/d1.d.ts +1 -232
- package/dist/db/index.d.ts +3 -3
- package/dist/db/market-schema.d.ts +49037 -11843
- package/dist/db/market-schema.js +1788 -50
- package/dist/db/node-sqlite.d.ts +1 -232
- package/dist/db/schema.d.ts +0 -462
- package/dist/db/schema.js +2 -22
- package/dist/dispatch.d.ts +1 -1
- package/dist/dispatch.js +0 -11
- package/dist/fixture-support.js +52 -4
- package/dist/governance.d.ts +133 -0
- package/dist/governance.js +285 -0
- package/dist/graph/build.d.ts +2 -2
- package/dist/graph/context-query-contracts.d.ts +1 -1
- package/dist/graph/dsl.d.ts +1 -1
- package/dist/graph/query.d.ts +4 -4
- package/dist/graph/ranking.d.ts +1 -1
- package/dist/graph/schema.d.ts +1 -1
- package/dist/graph.d.ts +11 -11
- package/dist/guarantees/index.d.ts +425 -0
- package/dist/guarantees/index.js +1146 -0
- package/dist/hosting/apps.d.ts +1 -1
- package/dist/hosting/builtins.d.ts +1 -1
- package/dist/hosting/builtins.js +9 -198
- package/dist/hosting/contracts.d.ts +3 -2
- package/dist/hosting/graph.d.ts +24 -21
- package/dist/hosting/graph.js +280 -294
- package/dist/hosting/index.d.ts +4 -4
- package/dist/index.d.ts +88 -74
- package/dist/index.js +81 -10
- package/dist/local-dev/managed-dev.d.ts +85 -0
- package/dist/local-dev/managed-dev.js +368 -0
- package/dist/managed-dependencies.d.ts +9 -0
- package/dist/managed-dependencies.js +10 -8
- package/dist/market-client.d.ts +265 -7
- package/dist/market-client.js +381 -9
- package/dist/model-registry.d.ts +1 -1
- package/dist/model-registry.js +19 -19
- package/dist/operations/agent-tools.d.ts +2 -11
- package/dist/operations/agent-tools.js +2 -14
- package/dist/operations/providers/default.d.ts +1 -1
- package/dist/operations/providers/default.js +20 -37
- package/dist/operations/repository-operations.d.ts +26 -2
- package/dist/operations/repository-operations.js +159 -1
- package/dist/operations/runtime.d.ts +3 -3
- package/dist/operations/services/bootstrap-runner.d.ts +1 -1
- package/dist/operations/services/build-warning-policy.d.ts +34 -0
- package/dist/operations/services/build-warning-policy.js +81 -82
- package/dist/operations/services/commit-message-provider.js +4 -4
- package/dist/operations/services/config-runtime.d.ts +73 -19
- package/dist/operations/services/config-runtime.js +276 -100
- package/dist/operations/services/deploy.d.ts +41 -622
- package/dist/operations/services/deploy.js +181 -213
- package/dist/operations/services/deployment-readiness.d.ts +1 -1
- package/dist/operations/services/deployment-readiness.js +38 -7
- package/dist/operations/services/git-remote-policy.js +12 -4
- package/dist/operations/services/git-runner.d.ts +66 -0
- package/dist/operations/services/git-runner.js +479 -0
- package/dist/operations/services/git-workflow.d.ts +43 -5
- package/dist/operations/services/git-workflow.js +242 -20
- package/dist/operations/services/github-actions-verification.d.ts +3 -1
- package/dist/operations/services/github-actions-verification.js +11 -3
- package/dist/operations/services/github-api.js +21 -5
- package/dist/operations/services/github-automation.d.ts +3 -3
- package/dist/operations/services/github-automation.js +15 -18
- package/dist/operations/services/github-credentials.js +2 -1
- package/dist/operations/services/hosted-service-checks.d.ts +19 -1
- package/dist/operations/services/hosted-service-checks.js +162 -11
- package/dist/operations/services/hosting-audit.d.ts +2 -2
- package/dist/operations/services/hosting-audit.js +7 -7
- package/dist/operations/services/hub-launch.d.ts +1 -1
- package/dist/operations/services/hub-provider-launch.d.ts +5 -5
- package/dist/operations/services/hub-provider-launch.js +19 -14
- package/dist/operations/services/live-hosted-service-checks.d.ts +2 -1
- package/dist/operations/services/live-hosted-service-checks.js +193 -80
- package/dist/operations/services/local-dev.js +0 -1
- package/dist/operations/services/managed-host-security.d.ts +1 -1
- package/dist/operations/services/managed-repositories.d.ts +37 -0
- package/dist/operations/services/managed-repositories.js +177 -0
- package/dist/operations/services/operations-runner-smoke.d.ts +3 -2
- package/dist/operations/services/operations-runner-smoke.js +22 -4
- package/dist/operations/services/package-adapters.d.ts +77 -2
- package/dist/operations/services/package-adapters.js +629 -56
- package/dist/operations/services/package-reference-policy.d.ts +12 -88
- package/dist/operations/services/package-reference-policy.js +81 -213
- package/dist/operations/services/project-host-operations.d.ts +4 -4
- package/dist/operations/services/project-platform.d.ts +19 -193
- package/dist/operations/services/project-platform.js +31 -103
- package/dist/operations/services/project-web-monitor.d.ts +2 -2
- package/dist/operations/services/project-web-monitor.js +97 -2
- package/dist/operations/services/railway-api.d.ts +36 -7
- package/dist/operations/services/railway-api.js +331 -100
- package/dist/operations/services/railway-deploy.d.ts +7 -95
- package/dist/operations/services/railway-deploy.js +334 -742
- package/dist/operations/services/release-history.js +3 -4
- package/dist/operations/services/release-proof-ledger.d.ts +13 -0
- package/dist/operations/services/release-proof-ledger.js +81 -0
- package/dist/operations/services/release-proof-planner.d.ts +48 -0
- package/dist/operations/services/release-proof-planner.js +195 -0
- package/dist/operations/services/release-proof-runner.d.ts +16 -0
- package/dist/operations/services/release-proof-runner.js +169 -0
- package/dist/operations/services/release-proof.d.ts +81 -0
- package/dist/operations/services/release-proof.js +79 -0
- package/dist/operations/services/repository-save-orchestrator.d.ts +6 -7
- package/dist/operations/services/repository-save-orchestrator.js +353 -174
- package/dist/operations/services/runtime-paths.d.ts +1 -3
- package/dist/operations/services/runtime-paths.js +0 -4
- package/dist/operations/services/runtime-tools.d.ts +1 -192
- package/dist/operations/services/runtime-tools.js +4 -444
- package/dist/operations/services/save-deploy-preflight.js +9 -1
- package/dist/operations/services/template-host-bindings.d.ts +2 -2
- package/dist/operations/services/template-host-bindings.js +3 -2
- package/dist/operations/services/template-registry.d.ts +6 -6
- package/dist/operations/services/template-registry.js +33 -14
- package/dist/operations/services/template-secret-sync.d.ts +3 -3
- package/dist/operations/services/workflow-timing.d.ts +25 -0
- package/dist/operations/services/workflow-timing.js +79 -0
- package/dist/operations/services/workspace-dependency-mode.js +41 -4
- package/dist/operations/services/workspace-preflight.js +8 -8
- package/dist/operations/services/workspace-save-script.d.ts +4 -4
- package/dist/operations/services/workspace-save.d.ts +1 -0
- package/dist/operations/services/workspace-save.js +41 -18
- package/dist/operations/services/workspace-tools.js +40 -6
- package/dist/operations-registry.d.ts +1 -1
- package/dist/operations-registry.js +5 -6
- package/dist/operations-types.d.ts +1 -1
- package/dist/operations.d.ts +17 -11
- package/dist/operations.js +57 -3
- package/dist/platform/book-export.js +2 -0
- package/dist/platform/books-data.d.ts +1 -1
- package/dist/platform/config.d.ts +27 -0
- package/dist/platform/config.js +100 -0
- package/dist/platform/content-runtime-source.d.ts +54 -0
- package/dist/platform/content-runtime-source.js +169 -0
- package/dist/platform/contracts.d.ts +6 -1
- package/dist/platform/deploy-config.d.ts +1 -1
- package/dist/platform/deploy-config.js +7 -1
- package/dist/platform/deploy-runtime.d.ts +1 -1
- package/dist/platform/desired-state.d.ts +66 -0
- package/dist/platform/desired-state.js +1052 -0
- package/dist/platform/env.yaml +414 -19
- package/dist/platform/environment.d.ts +2 -2
- package/dist/platform/environment.js +54 -22
- package/dist/platform/local-content-materialization.d.ts +9 -0
- package/dist/platform/local-content-materialization.js +212 -0
- package/dist/platform/plugin.d.ts +5 -5
- package/dist/platform/plugins/runtime.d.ts +3 -3
- package/dist/platform/plugins/runtime.js +62 -1
- package/dist/platform/plugins.d.ts +6 -6
- package/dist/platform/published-content-pipeline.d.ts +3 -3
- package/dist/platform/published-content-pipeline.js +5 -1
- package/dist/platform/published-content.d.ts +4 -3
- package/dist/platform/site-config-schema.d.ts +1 -0
- package/dist/platform/site-config-schema.js +4 -1
- package/dist/platform/tenant/runtime-config.d.ts +152 -2
- package/dist/platform/tenant-config.d.ts +1 -1
- package/dist/platform/utils/site-config-schema.d.ts +154 -0
- package/dist/platform/utils/site-config-schema.js +400 -461
- package/dist/platform-operation-store.d.ts +1 -1
- package/dist/plugin-default.d.ts +1 -1
- package/dist/plugin-default.js +27 -12
- package/dist/project-import.d.ts +91 -0
- package/dist/project-import.js +257 -0
- package/dist/project-workflow.d.ts +1 -1
- package/dist/reconcile/bootstrap-systems.d.ts +2 -2
- package/dist/reconcile/bootstrap-systems.js +3 -3
- package/dist/reconcile/builtin-adapters.d.ts +7 -1
- package/dist/reconcile/builtin-adapters.js +2924 -346
- package/dist/reconcile/contracts.d.ts +15 -2
- package/dist/reconcile/desired-state.d.ts +2 -193
- package/dist/reconcile/desired-state.js +24 -33
- package/dist/reconcile/engine.d.ts +60 -397
- package/dist/reconcile/engine.js +182 -18
- package/dist/reconcile/index.d.ts +10 -10
- package/dist/reconcile/live-acceptance.d.ts +22 -1
- package/dist/reconcile/live-acceptance.js +456 -44
- package/dist/reconcile/providers/docker-private.d.ts +54 -0
- package/dist/reconcile/providers/docker-private.js +101 -0
- package/dist/reconcile/providers/github-private.d.ts +65 -0
- package/dist/reconcile/providers/github-private.js +119 -0
- package/dist/reconcile/providers/local-private.d.ts +28 -0
- package/dist/reconcile/providers/local-private.js +75 -0
- package/dist/reconcile/providers/railway-iac.d.ts +66 -0
- package/dist/reconcile/providers/railway-iac.js +275 -0
- package/dist/reconcile/providers/release-private.d.ts +92 -0
- package/dist/reconcile/providers/release-private.js +152 -0
- package/dist/reconcile/registry.d.ts +2 -2
- package/dist/reconcile/registry.js +16 -1
- package/dist/reconcile/state.d.ts +1 -1
- package/dist/reconcile/state.js +3 -40
- package/dist/reconcile/units.d.ts +1 -1
- package/dist/reconcile/units.js +7 -1
- package/dist/remote.d.ts +6 -6
- package/dist/scenes/artifacts.d.ts +16 -0
- package/dist/scenes/artifacts.js +61 -0
- package/dist/scenes/auth.d.ts +2 -0
- package/dist/scenes/auth.js +28 -0
- package/dist/scenes/base-url.d.ts +12 -0
- package/dist/scenes/base-url.js +123 -0
- package/dist/scenes/builtin-plugins.d.ts +2 -0
- package/dist/scenes/builtin-plugins.js +447 -0
- package/dist/scenes/checkpoints.d.ts +14 -0
- package/dist/scenes/checkpoints.js +33 -0
- package/dist/scenes/device-matrix.d.ts +2 -0
- package/dist/scenes/device-matrix.js +97 -0
- package/dist/scenes/devices.d.ts +11 -0
- package/dist/scenes/devices.js +22 -0
- package/dist/scenes/diagnostics.d.ts +5 -0
- package/dist/scenes/diagnostics.js +22 -0
- package/dist/scenes/diagram-providers.d.ts +2 -0
- package/dist/scenes/diagram-providers.js +181 -0
- package/dist/scenes/diagram-validation.d.ts +22 -0
- package/dist/scenes/diagram-validation.js +74 -0
- package/dist/scenes/environment.d.ts +2 -0
- package/dist/scenes/environment.js +65 -0
- package/dist/scenes/evidence-bundle.d.ts +5 -0
- package/dist/scenes/evidence-bundle.js +42 -0
- package/dist/scenes/evidence-report.d.ts +10 -0
- package/dist/scenes/evidence-report.js +73 -0
- package/dist/scenes/evidence.d.ts +16 -0
- package/dist/scenes/evidence.js +277 -0
- package/dist/scenes/index.d.ts +48 -0
- package/dist/scenes/index.js +312 -0
- package/dist/scenes/inspect.d.ts +9 -0
- package/dist/scenes/inspect.js +64 -0
- package/dist/scenes/loader.d.ts +3 -0
- package/dist/scenes/loader.js +38 -0
- package/dist/scenes/logs.d.ts +2 -0
- package/dist/scenes/logs.js +47 -0
- package/dist/scenes/operations.d.ts +3 -0
- package/dist/scenes/operations.js +128 -0
- package/dist/scenes/phase0.d.ts +9 -0
- package/dist/scenes/phase0.js +637 -0
- package/dist/scenes/planner.d.ts +12 -0
- package/dist/scenes/planner.js +166 -0
- package/dist/scenes/playwright-adapter.d.ts +2 -0
- package/dist/scenes/playwright-adapter.js +63 -0
- package/dist/scenes/plugins.d.ts +5 -0
- package/dist/scenes/plugins.js +115 -0
- package/dist/scenes/progress.d.ts +17 -0
- package/dist/scenes/progress.js +24 -0
- package/dist/scenes/publish-destinations.d.ts +12 -0
- package/dist/scenes/publish-destinations.js +99 -0
- package/dist/scenes/publish-plan-report.d.ts +10 -0
- package/dist/scenes/publish-plan-report.js +70 -0
- package/dist/scenes/publish-plan.d.ts +15 -0
- package/dist/scenes/publish-plan.js +248 -0
- package/dist/scenes/publish-redaction.d.ts +16 -0
- package/dist/scenes/publish-redaction.js +148 -0
- package/dist/scenes/publish-release-record.d.ts +13 -0
- package/dist/scenes/publish-release-record.js +34 -0
- package/dist/scenes/publish-report.d.ts +10 -0
- package/dist/scenes/publish-report.js +67 -0
- package/dist/scenes/publish.d.ts +16 -0
- package/dist/scenes/publish.js +298 -0
- package/dist/scenes/registry.d.ts +12 -0
- package/dist/scenes/registry.js +65 -0
- package/dist/scenes/remotion-adapter.d.ts +3 -0
- package/dist/scenes/remotion-adapter.js +94 -0
- package/dist/scenes/remotion-composition-registry.d.ts +2 -0
- package/dist/scenes/remotion-composition-registry.js +12 -0
- package/dist/scenes/remotion-compositions.d.ts +15 -0
- package/dist/scenes/remotion-compositions.js +464 -0
- package/dist/scenes/remotion-diagrams.d.ts +9 -0
- package/dist/scenes/remotion-diagrams.js +188 -0
- package/dist/scenes/remotion-input.d.ts +13 -0
- package/dist/scenes/remotion-input.js +291 -0
- package/dist/scenes/remotion-visuals.d.ts +29 -0
- package/dist/scenes/remotion-visuals.js +198 -0
- package/dist/scenes/render-media-assets.d.ts +9 -0
- package/dist/scenes/render-media-assets.js +117 -0
- package/dist/scenes/render-report.d.ts +10 -0
- package/dist/scenes/render-report.js +27 -0
- package/dist/scenes/render.d.ts +2 -0
- package/dist/scenes/render.js +218 -0
- package/dist/scenes/reporter.d.ts +3 -0
- package/dist/scenes/reporter.js +101 -0
- package/dist/scenes/resume.d.ts +2 -0
- package/dist/scenes/resume.js +79 -0
- package/dist/scenes/runner.d.ts +2 -0
- package/dist/scenes/runner.js +674 -0
- package/dist/scenes/schema.d.ts +6 -0
- package/dist/scenes/schema.js +994 -0
- package/dist/scenes/seed.d.ts +2 -0
- package/dist/scenes/seed.js +83 -0
- package/dist/scenes/segments.d.ts +15 -0
- package/dist/scenes/segments.js +79 -0
- package/dist/scenes/selectors.d.ts +3 -0
- package/dist/scenes/selectors.js +21 -0
- package/dist/scenes/timeline.d.ts +11 -0
- package/dist/scenes/timeline.js +26 -0
- package/dist/scenes/timeouts.d.ts +6 -0
- package/dist/scenes/timeouts.js +17 -0
- package/dist/scenes/training-captions.d.ts +14 -0
- package/dist/scenes/training-captions.js +98 -0
- package/dist/scenes/training-report.d.ts +10 -0
- package/dist/scenes/training-report.js +78 -0
- package/dist/scenes/training-transcript.d.ts +24 -0
- package/dist/scenes/training-transcript.js +204 -0
- package/dist/scenes/training.d.ts +10 -0
- package/dist/scenes/training.js +134 -0
- package/dist/scenes/types.d.ts +1872 -0
- package/dist/scenes/types.js +8 -0
- package/dist/scenes/visual-audit-contact-sheets.d.ts +6 -0
- package/dist/scenes/visual-audit-contact-sheets.js +119 -0
- package/dist/scenes/visual-audit-fixtures.d.ts +25 -0
- package/dist/scenes/visual-audit-fixtures.js +210 -0
- package/dist/scenes/visual-audit-report.d.ts +11 -0
- package/dist/scenes/visual-audit-report.js +85 -0
- package/dist/scenes/visual-audit-review.d.ts +23 -0
- package/dist/scenes/visual-audit-review.js +829 -0
- package/dist/scenes/visual-audit-routes.d.ts +13 -0
- package/dist/scenes/visual-audit-routes.js +308 -0
- package/dist/scenes/visual-audit.d.ts +3 -0
- package/dist/scenes/visual-audit.js +596 -0
- package/dist/scripts/build-dist.js +154 -40
- package/dist/scripts/check-build-warnings.js +42 -53
- package/dist/scripts/cleanup-markdown.js +1 -1
- package/dist/scripts/cli-test-fixtures.js +24 -28
- package/dist/scripts/migrate-journey-csv-to-guarantees.js +140 -0
- package/dist/scripts/package-tools.js +12 -1
- package/dist/scripts/prepare.js +3 -7
- package/dist/scripts/release-verify.js +2 -5
- package/dist/scripts/run-fixture-astro-command.js +1 -1
- package/dist/scripts/template-catalog.test.js +68 -82
- package/dist/scripts/tenant-dev.js +0 -10
- package/dist/scripts/test-cloudflare-local.js +1 -1
- package/dist/scripts/test-scaffold.js +0 -1
- package/dist/scripts/test-smoke.js +3 -3
- package/dist/scripts/treeseed-build-dist.js +4 -7
- package/dist/scripts/treeseed-release-verify.js +1 -1
- package/dist/scripts/verify-driver.js +30 -21
- package/dist/scripts/workflow-commands.test.js +18 -27
- package/dist/scripts/workspace-command-e2e.js +1 -1
- package/dist/scripts/workspace-lint.js +6 -0
- package/dist/scripts/workspace-release-test.js +90 -1
- package/dist/scripts/workspace-test.js +6 -0
- package/dist/sdk-dispatch.d.ts +1 -1
- package/dist/sdk-dispatch.js +0 -16
- package/dist/sdk-fields.d.ts +1 -1
- package/dist/sdk-filters.d.ts +1 -1
- package/dist/sdk-types.d.ts +1184 -113
- package/dist/sdk-types.js +393 -0
- package/dist/sdk.d.ts +74 -79
- package/dist/sdk.js +27 -36
- package/dist/secrets-capability.d.ts +421 -0
- package/dist/secrets-capability.js +530 -0
- package/dist/seeds/normalize.js +1 -0
- package/dist/seeds/planner.js +38 -0
- package/dist/seeds/schema.js +293 -4
- package/dist/seeds/types.d.ts +60 -0
- package/dist/seeds/types.js +9 -1
- package/dist/service-credentials.d.ts +54 -0
- package/dist/service-credentials.js +112 -0
- package/dist/stores/cursor-store.d.ts +2 -2
- package/dist/stores/envelopes.d.ts +1 -1
- package/dist/stores/helpers.d.ts +1 -1
- package/dist/stores/lease-store.d.ts +2 -2
- package/dist/stores/message-store.d.ts +2 -2
- package/dist/stores/operational-store.d.ts +3 -26
- package/dist/stores/operational-store.js +0 -225
- package/dist/stores/project-workflow-store.d.ts +2 -2
- package/dist/stores/run-store.d.ts +2 -3
- package/dist/stores/run-store.js +0 -98
- package/dist/stores/subscription-store.d.ts +2 -3
- package/dist/stores/subscription-store.js +0 -100
- package/dist/template-catalog.d.ts +1 -1
- package/dist/template-launch-requirements.d.ts +2 -2
- package/dist/template-launch-ui.d.ts +2 -2
- package/dist/treedx/adapters.d.ts +6 -6
- package/dist/treedx/client.d.ts +1 -1
- package/dist/treedx/errors.d.ts +1 -1
- package/dist/treedx/federated-client.d.ts +3 -3
- package/dist/treedx/graph-adapter.d.ts +2 -2
- package/dist/treedx/index.d.ts +14 -14
- package/dist/treedx/market-integration.d.ts +1 -1
- package/dist/treedx/ports.d.ts +30 -30
- package/dist/treedx/query-adapter.d.ts +3 -3
- package/dist/treedx/registry-client.d.ts +2 -2
- package/dist/treedx/repository-adapter.d.ts +4 -4
- package/dist/treedx/repository-adapter.js +14 -3
- package/dist/treedx/sdk-integration.d.ts +3 -3
- package/dist/treedx/types.d.ts +2 -2
- package/dist/treedx/workspace-adapter.d.ts +2 -2
- package/dist/treedx-backends.d.ts +13 -11
- package/dist/treedx-backends.js +52 -50
- package/dist/treedx-client.d.ts +3 -0
- package/dist/treedx-client.js +10 -1
- package/dist/treeseed/services/compose.yml +2 -3
- package/dist/treeseed/template-catalog/catalog.fixture.json +4 -4
- package/dist/types/agents.d.ts +256 -0
- package/dist/types/agents.js +42 -1
- package/dist/verification.d.ts +1 -0
- package/dist/verification.js +143 -14
- package/dist/workflow/operations.d.ts +510 -559
- package/dist/workflow/operations.js +1891 -1342
- package/dist/workflow/policy.js +19 -7
- package/dist/workflow/runs.d.ts +9 -3
- package/dist/workflow/runs.js +66 -26
- package/dist/workflow/session.d.ts +4 -1
- package/dist/workflow/session.js +50 -10
- package/dist/workflow/worktrees.d.ts +6 -2
- package/dist/workflow/worktrees.js +98 -15
- package/dist/workflow-state.d.ts +5 -5
- package/dist/workflow-state.js +27 -17
- package/dist/workflow-support.d.ts +26 -25
- package/dist/workflow-support.js +27 -31
- package/dist/workflow.d.ts +46 -16
- package/dist/workflow.js +19 -7
- package/drizzle/d1/0000_treeseed_d1.sql +0 -18
- package/drizzle/market/0000_market_control_plane.sql +1793 -1499
- package/drizzle/market/0005_agent_capacity_coordination.sql +145 -0
- package/drizzle/market/0006_provider_assignment_lifecycle.sql +9 -0
- package/drizzle/market/0007_agent_architecture_gap_closure.sql +157 -0
- package/drizzle/market/0008_agent_capacity_operational_closure.sql +27 -0
- package/drizzle/market/0009_agent_capacity_runtime_hardening.sql +29 -0
- package/drizzle/market/0010_secrets_capability_persistence.sql +130 -0
- package/drizzle/market/0011_github_app_adapter.sql +47 -0
- package/drizzle/market/0012_workday_test_runs.sql +44 -0
- package/drizzle/market/0013_runtime_task_lifecycle.sql +39 -0
- package/drizzle/market/0014_governance_pipeline.sql +189 -0
- package/package.json +75 -18
- package/scripts/{verify-driver.mjs → verify-driver.ts} +19 -4
- package/templates/github/deploy-web.workflow.yml +12 -8
- package/dist/operations/services/mailpit-runtime.d.ts +0 -20
- package/dist/operations/services/mailpit-runtime.js +0 -67
- package/dist/operations/services/release-candidate.d.ts +0 -60
- package/dist/operations/services/release-candidate.js +0 -953
- package/dist/scripts/ensure-mailpit.js +0 -48
- package/dist/scripts/logs-mailpit.js +0 -2
- package/dist/scripts/run-ts.js +0 -45
- package/dist/scripts/stop-mailpit.js +0 -5
- package/dist/scripts/treeseed-run-ts.js +0 -45
package/dist/hosting/graph.js
CHANGED
|
@@ -1,29 +1,11 @@
|
|
|
1
1
|
import { loadTreeseedDeployConfig } from "../platform/deploy-config.js";
|
|
2
2
|
import { loadTreeseedPlugins } from "../platform/plugins/runtime.js";
|
|
3
|
-
import {
|
|
3
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
4
4
|
import { resolve } from "node:path";
|
|
5
|
+
import { parse as parseYaml } from "yaml";
|
|
5
6
|
import { createPersistentDeployTarget } from "../operations/services/deploy.js";
|
|
6
|
-
import { collectTreeseedConfigSeedValues } from "../operations/services/config-runtime.js";
|
|
7
|
-
import {
|
|
8
|
-
configuredRailwayServices,
|
|
9
|
-
deployRailwayService
|
|
10
|
-
} from "../operations/services/railway-deploy.js";
|
|
11
|
-
import {
|
|
12
|
-
deployRailwayServiceInstance,
|
|
13
|
-
deleteRailwayService,
|
|
14
|
-
ensureRailwayEnvironment,
|
|
15
|
-
ensureRailwayGeneratedServiceDomain,
|
|
16
|
-
ensureRailwayProject,
|
|
17
|
-
ensureRailwayService,
|
|
18
|
-
ensureRailwayServiceInstanceConfiguration,
|
|
19
|
-
ensureRailwayServiceVolume,
|
|
20
|
-
listRailwayVariables,
|
|
21
|
-
listRailwayServices,
|
|
22
|
-
normalizeRailwayEnvironmentName,
|
|
23
|
-
resolveRailwayWorkspaceContext,
|
|
24
|
-
updateRailwayServiceName,
|
|
25
|
-
upsertRailwayVariables
|
|
26
|
-
} from "../operations/services/railway-api.js";
|
|
7
|
+
import { collectTreeseedConfigSeedValues, resolveTreeseedMachineEnvironmentValues } from "../operations/services/config-runtime.js";
|
|
8
|
+
import { classifyTreeseedGitMode, runTreeseedGitText } from "../operations/services/git-runner.js";
|
|
27
9
|
import { createTreeseedCanonicalReconcileReport } from "../reconcile/index.js";
|
|
28
10
|
import { reconcileTreeseedTarget } from "../reconcile/index.js";
|
|
29
11
|
import { discoverTreeseedApplications, findTreeseedApplication } from "./apps.js";
|
|
@@ -70,8 +52,41 @@ function publicTreeDxNodePool(config) {
|
|
|
70
52
|
const maxNodes = Math.max(bootstrapCount, Number.parseInt(String(nodePool.maxNodes ?? 4), 10) || 4);
|
|
71
53
|
return { bootstrapCount, maxNodes };
|
|
72
54
|
}
|
|
73
|
-
function
|
|
74
|
-
|
|
55
|
+
function resolvePublicTreeDxRoot(input) {
|
|
56
|
+
const candidates = [
|
|
57
|
+
resolve(input.tenantRoot, "packages", "treedx"),
|
|
58
|
+
resolve(input.tenantRoot, "..", "treedx"),
|
|
59
|
+
input.configRoot ? resolve(input.configRoot, "packages", "treedx") : null
|
|
60
|
+
].filter((candidate) => Boolean(candidate));
|
|
61
|
+
return candidates.find((candidate) => existsSync(resolve(candidate, "treeseed.package.yaml")) || existsSync(resolve(candidate, ".git"))) ?? candidates[0];
|
|
62
|
+
}
|
|
63
|
+
function publicTreeDxSourcePolicy(input, config) {
|
|
64
|
+
const railway = config.publicTreeDxFederation?.railway ?? {};
|
|
65
|
+
const configuredSource = railway.source && typeof railway.source === "object" && !Array.isArray(railway.source) ? railway.source : {};
|
|
66
|
+
const configuredMode = typeof railway.sourceMode === "string" ? railway.sourceMode : null;
|
|
67
|
+
const treeDxRoot = resolvePublicTreeDxRoot(input);
|
|
68
|
+
const repository = typeof railway.sourceRepo === "string" ? railway.sourceRepo : typeof configuredSource.repository === "string" ? configuredSource.repository : typeof configuredSource.repo === "string" ? configuredSource.repo : readPackageRepository(treeDxRoot) ?? "treeseed-ai/treedx";
|
|
69
|
+
const sourceMode = configuredMode === "git" || configuredMode === "image" ? configuredMode : input.environment === "staging" ? "git" : "image";
|
|
70
|
+
if (sourceMode !== "git") {
|
|
71
|
+
return {
|
|
72
|
+
sourceMode: "image",
|
|
73
|
+
sourceRepo: null,
|
|
74
|
+
sourceBranch: null,
|
|
75
|
+
sourceCommit: null,
|
|
76
|
+
sourceRootDirectory: null,
|
|
77
|
+
image: "treeseed/treedx",
|
|
78
|
+
imageTagRef: "TREESEED_PUBLIC_TREEDX_IMAGE_REF"
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
sourceMode: "git",
|
|
83
|
+
sourceRepo: repository,
|
|
84
|
+
sourceBranch: typeof railway.sourceBranch === "string" ? railway.sourceBranch : typeof configuredSource.branch === "string" ? configuredSource.branch : "staging",
|
|
85
|
+
sourceCommit: typeof railway.sourceCommit === "string" ? railway.sourceCommit : typeof configuredSource.commit === "string" ? configuredSource.commit : headCommitSafe(treeDxRoot) ?? headCommitSafe(input.tenantRoot),
|
|
86
|
+
sourceRootDirectory: typeof railway.sourceRootDirectory === "string" ? railway.sourceRootDirectory : typeof configuredSource.rootDirectory === "string" ? configuredSource.rootDirectory : ".",
|
|
87
|
+
image: null,
|
|
88
|
+
imageTagRef: null
|
|
89
|
+
};
|
|
75
90
|
}
|
|
76
91
|
function serviceKeyPlacement(serviceKey) {
|
|
77
92
|
if (serviceKey === "api") return "api";
|
|
@@ -84,11 +99,87 @@ function serviceKeyPlacement(serviceKey) {
|
|
|
84
99
|
}
|
|
85
100
|
function serviceKeyType(serviceKey, service) {
|
|
86
101
|
if (serviceKey === "treeseedDatabase" || service.railway?.resourceType === "postgres") return "relational-database";
|
|
102
|
+
if (String(serviceKey).startsWith("capacityProvider")) return "capacity-provider";
|
|
87
103
|
if (serviceKey === "operationsRunner" || /runner/iu.test(serviceKey)) return "runner-pool";
|
|
88
104
|
if (Array.isArray(service.railway?.schedule) || typeof service.railway?.schedule === "string") return "scheduled-job";
|
|
89
105
|
if (serviceKey === "api") return "container-api";
|
|
90
106
|
return service.railway?.volumeMountPath ? "stateful-container" : "container-api";
|
|
91
107
|
}
|
|
108
|
+
function railwayImageRefEnvForService(serviceKey) {
|
|
109
|
+
if (serviceKey === "api") return "TREESEED_API_IMAGE_REF";
|
|
110
|
+
if (serviceKey === "operationsRunner") return "TREESEED_OPERATIONS_RUNNER_IMAGE_REF";
|
|
111
|
+
if (serviceKey === "capacityProviderManager") return "TREESEED_AGENT_MANAGER_IMAGE_REF";
|
|
112
|
+
if (serviceKey === "capacityProviderRunner") return "TREESEED_AGENT_RUNNER_IMAGE_REF";
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
function defaultRailwayImageRefForService(serviceKey, environment) {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
function readPackageRepository(root) {
|
|
119
|
+
const manifestPath = resolve(root, "treeseed.package.yaml");
|
|
120
|
+
if (!existsSync(manifestPath)) return null;
|
|
121
|
+
try {
|
|
122
|
+
const parsed = parseYaml(readFileSync(manifestPath, "utf8"));
|
|
123
|
+
const repository = parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed.repository : null;
|
|
124
|
+
return typeof repository === "string" && /^[^/\s]+\/[^/\s]+$/u.test(repository.trim()) ? repository.trim() : null;
|
|
125
|
+
} catch {
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
function headCommitSafe(root) {
|
|
130
|
+
try {
|
|
131
|
+
return runTreeseedGitText(["rev-parse", "HEAD"], {
|
|
132
|
+
cwd: root,
|
|
133
|
+
mode: classifyTreeseedGitMode(["rev-parse", "HEAD"])
|
|
134
|
+
}).trim();
|
|
135
|
+
} catch {
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
function resolveRailwayServiceSourceRoot(input, serviceKey, service) {
|
|
140
|
+
if (String(serviceKey).startsWith("capacityProvider")) {
|
|
141
|
+
if (service.railway?.rootDir) {
|
|
142
|
+
return resolve(input.tenantRoot, service.railway.rootDir);
|
|
143
|
+
}
|
|
144
|
+
const workspaceRoot = input.configRoot ?? input.tenantRoot;
|
|
145
|
+
const candidates = [
|
|
146
|
+
resolve(input.tenantRoot, "..", "agent"),
|
|
147
|
+
resolve(workspaceRoot, "packages", "agent"),
|
|
148
|
+
resolve(input.tenantRoot, "..", "..", "packages", "agent")
|
|
149
|
+
];
|
|
150
|
+
const found = candidates.find(
|
|
151
|
+
(candidate) => existsSync(resolve(candidate, "treeseed.package.yaml")) || existsSync(resolve(candidate, "package.json"))
|
|
152
|
+
);
|
|
153
|
+
return found ?? resolve(workspaceRoot, "packages", "agent");
|
|
154
|
+
}
|
|
155
|
+
const rootDir = service.railway?.rootDir ?? service.rootDir ?? ".";
|
|
156
|
+
return resolve(input.tenantRoot, rootDir);
|
|
157
|
+
}
|
|
158
|
+
function railwaySourcePolicy(input, serviceKey, service, imageRef) {
|
|
159
|
+
const configuredSource = service.railway?.source && typeof service.railway.source === "object" && !Array.isArray(service.railway.source) ? service.railway.source : {};
|
|
160
|
+
const configuredMode = typeof service.railway?.sourceMode === "string" ? service.railway.sourceMode : null;
|
|
161
|
+
const repository = typeof service.railway?.sourceRepo === "string" ? service.railway.sourceRepo : typeof configuredSource.repository === "string" ? configuredSource.repository : typeof configuredSource.repo === "string" ? configuredSource.repo : readPackageRepository(resolveRailwayServiceSourceRoot(input, serviceKey, service)) ?? readPackageRepository(input.tenantRoot);
|
|
162
|
+
const sourceEligible = ["api", "operationsRunner", "capacityProviderManager", "capacityProviderRunner"].includes(serviceKey);
|
|
163
|
+
const mode = input.environment === "prod" ? "image" : configuredMode === "git" || configuredMode === "image" ? configuredMode : imageRef ? "image" : input.environment === "staging" && sourceEligible && repository ? "git" : "git";
|
|
164
|
+
if (mode !== "git") {
|
|
165
|
+
return {
|
|
166
|
+
sourceMode: "image",
|
|
167
|
+
sourceRepo: null,
|
|
168
|
+
sourceBranch: null,
|
|
169
|
+
sourceCommit: null,
|
|
170
|
+
sourceRootDirectory: null,
|
|
171
|
+
imageRef
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
return {
|
|
175
|
+
sourceMode: "git",
|
|
176
|
+
sourceRepo: repository,
|
|
177
|
+
sourceBranch: typeof service.railway?.sourceBranch === "string" ? service.railway.sourceBranch : typeof configuredSource.branch === "string" ? configuredSource.branch : input.environment === "staging" ? "staging" : null,
|
|
178
|
+
sourceCommit: headCommitSafe(resolveRailwayServiceSourceRoot(input, serviceKey, service)) ?? headCommitSafe(input.tenantRoot),
|
|
179
|
+
sourceRootDirectory: typeof service.railway?.sourceRootDirectory === "string" ? service.railway.sourceRootDirectory : typeof configuredSource.rootDirectory === "string" ? configuredSource.rootDirectory : ".",
|
|
180
|
+
imageRef: null
|
|
181
|
+
};
|
|
182
|
+
}
|
|
92
183
|
function collectPluginHostingContributions(input) {
|
|
93
184
|
const plugins = loadTreeseedPlugins(input.deployConfig);
|
|
94
185
|
const context = {
|
|
@@ -117,7 +208,8 @@ function collectPluginHostingContributions(input) {
|
|
|
117
208
|
};
|
|
118
209
|
}
|
|
119
210
|
function marketProjectGroup(environment, config) {
|
|
120
|
-
const
|
|
211
|
+
const apiService = config.services?.api && typeof config.services.api === "object" ? config.services.api : null;
|
|
212
|
+
const railwayProjectName = typeof apiService?.railway?.projectName === "string" && apiService.railway.projectName.trim() ? apiService.railway.projectName.trim() : void 0;
|
|
121
213
|
const projectName = railwayProjectName ?? config.slug ?? "treeseed-api";
|
|
122
214
|
return {
|
|
123
215
|
id: "treeseed-control-plane",
|
|
@@ -131,6 +223,38 @@ function marketProjectGroup(environment, config) {
|
|
|
131
223
|
metadata: { stableProjectName: projectName }
|
|
132
224
|
};
|
|
133
225
|
}
|
|
226
|
+
function railwayProjectGroupIdForProjectName(prefix, projectName) {
|
|
227
|
+
const slug = projectName.toLowerCase().replace(/[^a-z0-9-]+/gu, "-").replace(/^-+|-+$/gu, "") || "railway-project";
|
|
228
|
+
return `${prefix}:${slug}`;
|
|
229
|
+
}
|
|
230
|
+
function capacityProviderProjectGroupId(projectName) {
|
|
231
|
+
return railwayProjectGroupIdForProjectName("capacity-provider", projectName);
|
|
232
|
+
}
|
|
233
|
+
function capacityProviderProjectGroups(environment, config) {
|
|
234
|
+
const projectNames = /* @__PURE__ */ new Set();
|
|
235
|
+
for (const [serviceKey, service] of Object.entries(config.services ?? {})) {
|
|
236
|
+
if (!String(serviceKey).startsWith("capacityProvider")) continue;
|
|
237
|
+
if (!service || typeof service !== "object") continue;
|
|
238
|
+
const projectName = service.railway?.projectName;
|
|
239
|
+
if (typeof projectName === "string" && projectName.trim()) {
|
|
240
|
+
projectNames.add(projectName.trim());
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
return [...projectNames].map((projectName) => ({
|
|
244
|
+
id: capacityProviderProjectGroupId(projectName),
|
|
245
|
+
label: "Capacity provider",
|
|
246
|
+
hostId: environment === "local" ? "local-docker" : "railway",
|
|
247
|
+
environments: {
|
|
248
|
+
local: { projectName: `${projectName}-local`, environmentName: "local" },
|
|
249
|
+
staging: { projectName, environmentName: "staging" },
|
|
250
|
+
prod: { projectName, environmentName: "production" }
|
|
251
|
+
},
|
|
252
|
+
metadata: {
|
|
253
|
+
stableProjectName: projectName,
|
|
254
|
+
isolation: "capacity-provider"
|
|
255
|
+
}
|
|
256
|
+
}));
|
|
257
|
+
}
|
|
134
258
|
function publicTreeDxProjectGroup(environment, config) {
|
|
135
259
|
const apiProjectName = marketProjectGroup(environment, config).environments.staging?.projectName ?? config.slug ?? "treeseed-api";
|
|
136
260
|
return {
|
|
@@ -167,9 +291,17 @@ function buildProfileFromDeployConfig(input) {
|
|
|
167
291
|
const services = [];
|
|
168
292
|
const projectGroups = [
|
|
169
293
|
marketProjectGroup(environment, config),
|
|
294
|
+
...capacityProviderProjectGroups(environment, config),
|
|
170
295
|
publicTreeDxProjectGroup(environment, config),
|
|
171
296
|
privateTreeDxProjectGroup()
|
|
172
297
|
];
|
|
298
|
+
const railwayImageRefEnvKeys = [...new Set(Object.keys(config.services ?? {}).map((serviceKey) => railwayImageRefEnvForService(serviceKey)).filter((value) => Boolean(value)))];
|
|
299
|
+
let railwayImageRefEnv = {};
|
|
300
|
+
try {
|
|
301
|
+
railwayImageRefEnv = resolveTreeseedMachineEnvironmentValues(input.configRoot ?? input.tenantRoot, environment, railwayImageRefEnvKeys);
|
|
302
|
+
} catch {
|
|
303
|
+
railwayImageRefEnv = {};
|
|
304
|
+
}
|
|
173
305
|
if (config.surfaces?.web && config.surfaces.web.enabled !== false) {
|
|
174
306
|
services.push({
|
|
175
307
|
id: "web",
|
|
@@ -199,7 +331,11 @@ function buildProfileFromDeployConfig(input) {
|
|
|
199
331
|
if (!service || service.enabled === false) continue;
|
|
200
332
|
const serviceType = serviceKeyType(serviceKey, service);
|
|
201
333
|
const placement = serviceKeyPlacement(serviceKey);
|
|
202
|
-
const
|
|
334
|
+
const configuredRailwayProjectName = typeof service.railway?.projectName === "string" && service.railway.projectName.trim() ? service.railway.projectName.trim() : null;
|
|
335
|
+
const defaultProjectGroup = service.provider === "railway" || service.railway ? String(serviceKey).startsWith("capacityProvider") && configuredRailwayProjectName ? capacityProviderProjectGroupId(configuredRailwayProjectName) : "treeseed-control-plane" : void 0;
|
|
336
|
+
const imageRefEnv = railwayImageRefEnvForService(serviceKey);
|
|
337
|
+
const imageRef = service.railway?.imageRef ?? (imageRefEnv ? railwayImageRefEnv[imageRefEnv] ?? process.env[imageRefEnv] : null) ?? defaultRailwayImageRefForService(serviceKey, input.environment) ?? null;
|
|
338
|
+
const sourcePolicy = railwaySourcePolicy(input, serviceKey, service, imageRef);
|
|
203
339
|
services.push({
|
|
204
340
|
id: serviceKey,
|
|
205
341
|
label: placement === "runner-capacity" ? "Runner Capacity" : serviceKey === "api" ? "API Runtime" : serviceKey,
|
|
@@ -208,8 +344,16 @@ function buildProfileFromDeployConfig(input) {
|
|
|
208
344
|
projectGroupId: defaultProjectGroup,
|
|
209
345
|
config: {
|
|
210
346
|
rootDir: service.railway?.rootDir ?? service.rootDir ?? ".",
|
|
211
|
-
|
|
212
|
-
|
|
347
|
+
imageRef: sourcePolicy.imageRef,
|
|
348
|
+
imageRefEnv: sourcePolicy.sourceMode === "image" ? imageRefEnv : null,
|
|
349
|
+
sourceMode: sourcePolicy.sourceMode,
|
|
350
|
+
sourceRepo: sourcePolicy.sourceRepo,
|
|
351
|
+
sourceBranch: sourcePolicy.sourceBranch,
|
|
352
|
+
sourceCommit: sourcePolicy.sourceCommit,
|
|
353
|
+
sourceRootDirectory: sourcePolicy.sourceRootDirectory,
|
|
354
|
+
dockerfilePath: sourcePolicy.sourceMode === "git" ? service.railway?.dockerfilePath ?? null : null,
|
|
355
|
+
buildCommand: sourcePolicy.imageRef ? null : service.railway?.buildCommand ?? null,
|
|
356
|
+
startCommand: sourcePolicy.imageRef ? null : service.railway?.startCommand ?? null,
|
|
213
357
|
healthcheckPath: service.railway?.healthcheckPath ?? null,
|
|
214
358
|
runtimeMode: service.railway?.runtimeMode ?? null,
|
|
215
359
|
volumeMountPath: service.railway?.volumeMountPath ?? null,
|
|
@@ -220,6 +364,7 @@ function buildProfileFromDeployConfig(input) {
|
|
|
220
364
|
},
|
|
221
365
|
secretRefs: serviceKey === "treeseedDatabase" ? ["TREESEED_DATABASE_URL"] : [],
|
|
222
366
|
variableRefs: serviceKey === "operationsRunner" ? ["TREESEED_PLATFORM_RUNNER_ID", "TREESEED_PLATFORM_RUNNER_DATA_DIR", "TREESEED_PLATFORM_RUNNER_ENVIRONMENT"] : [],
|
|
367
|
+
metadata: String(serviceKey).startsWith("capacityProvider") ? { capacityProvider: true, deployByDefault: false } : {},
|
|
223
368
|
environments: {
|
|
224
369
|
local: {
|
|
225
370
|
hostId: serviceType === "relational-database" || serviceType === "runner-pool" || service.railway?.volumeMountPath ? "local-docker" : "local-process",
|
|
@@ -273,6 +418,7 @@ function buildProfileFromDeployConfig(input) {
|
|
|
273
418
|
}
|
|
274
419
|
if (config.hosting?.kind === "treeseed_control_plane") {
|
|
275
420
|
const treeDxNodePool = publicTreeDxNodePool(config);
|
|
421
|
+
const treeDxSourcePolicy = publicTreeDxSourcePolicy(input, config);
|
|
276
422
|
const treeDxNodeUnits = Array.from({ length: treeDxNodePool.bootstrapCount }, (_, offset) => {
|
|
277
423
|
const nodeIndex = offset + 1;
|
|
278
424
|
const serviceName = indexedName("public-treedx-node", nodeIndex);
|
|
@@ -283,14 +429,18 @@ function buildProfileFromDeployConfig(input) {
|
|
|
283
429
|
placement: "knowledge-library",
|
|
284
430
|
projectGroupId: "public-treedx-federation",
|
|
285
431
|
config: {
|
|
286
|
-
image:
|
|
287
|
-
imageTagRef:
|
|
432
|
+
...treeDxSourcePolicy.image ? { image: treeDxSourcePolicy.image } : {},
|
|
433
|
+
...treeDxSourcePolicy.imageTagRef ? { imageTagRef: treeDxSourcePolicy.imageTagRef } : {},
|
|
434
|
+
sourceMode: treeDxSourcePolicy.sourceMode,
|
|
435
|
+
...treeDxSourcePolicy.sourceRepo ? { sourceRepo: treeDxSourcePolicy.sourceRepo } : {},
|
|
436
|
+
...treeDxSourcePolicy.sourceBranch ? { sourceBranch: treeDxSourcePolicy.sourceBranch } : {},
|
|
437
|
+
...treeDxSourcePolicy.sourceCommit ? { sourceCommit: treeDxSourcePolicy.sourceCommit } : {},
|
|
438
|
+
...treeDxSourcePolicy.sourceRootDirectory ? { sourceRootDirectory: treeDxSourcePolicy.sourceRootDirectory } : {},
|
|
288
439
|
serviceName,
|
|
289
440
|
volumeName: `${serviceName}-volume`,
|
|
290
441
|
volumeMountPath: "/data",
|
|
291
442
|
runtimeMode: "replicated",
|
|
292
443
|
environmentVariables: {
|
|
293
|
-
PHX_SERVER: "true",
|
|
294
444
|
PORT: "4000",
|
|
295
445
|
TREEDX_DATA_DIR: "/data",
|
|
296
446
|
TREEDX_AUTH_MODE: "connected",
|
|
@@ -300,13 +450,15 @@ function buildProfileFromDeployConfig(input) {
|
|
|
300
450
|
TREEDX_FEDERATION_MODE: "connected_library",
|
|
301
451
|
TREEDX_JWT_AUDIENCE: "treedx-public-federation",
|
|
302
452
|
TREEDX_JWT_ISSUER: "https://api.treeseed.local/treedx",
|
|
303
|
-
|
|
453
|
+
TREEDX_BOOTSTRAP_TRUST_ACTOR_ID: "treeseed-api",
|
|
454
|
+
TREEDX_BOOTSTRAP_TRUST_TENANT_ID: "treeseed-control-plane",
|
|
455
|
+
TREEDX_BOOTSTRAP_TRUST_REPO_IDS: "*",
|
|
456
|
+
TREEDX_BOOTSTRAP_TRUST_REFS: "*",
|
|
457
|
+
TREEDX_BOOTSTRAP_TRUST_PATHS: "**",
|
|
458
|
+
TREEDX_SCOPE: "public_federation"
|
|
304
459
|
}
|
|
305
460
|
},
|
|
306
461
|
variableRefs: [
|
|
307
|
-
"TREESEED_PUBLIC_TREEDX_IMAGE_REF",
|
|
308
|
-
"PHX_HOST",
|
|
309
|
-
"PHX_SERVER",
|
|
310
462
|
"PORT",
|
|
311
463
|
"TREEDX_DATA_DIR",
|
|
312
464
|
"TREEDX_AUTH_MODE",
|
|
@@ -316,9 +468,14 @@ function buildProfileFromDeployConfig(input) {
|
|
|
316
468
|
"TREEDX_FEDERATION_MODE",
|
|
317
469
|
"TREEDX_JWT_AUDIENCE",
|
|
318
470
|
"TREEDX_JWT_ISSUER",
|
|
319
|
-
"
|
|
471
|
+
"TREEDX_BOOTSTRAP_TRUST_ACTOR_ID",
|
|
472
|
+
"TREEDX_BOOTSTRAP_TRUST_TENANT_ID",
|
|
473
|
+
"TREEDX_BOOTSTRAP_TRUST_REPO_IDS",
|
|
474
|
+
"TREEDX_BOOTSTRAP_TRUST_REFS",
|
|
475
|
+
"TREEDX_BOOTSTRAP_TRUST_PATHS",
|
|
476
|
+
"TREEDX_SCOPE"
|
|
320
477
|
],
|
|
321
|
-
secretRefs: ["
|
|
478
|
+
secretRefs: ["TREEDX_SECRET_KEY_BASE", "TREEDX_ADMIN_TOKEN", "TREEDX_JWT_HS256_SECRET"],
|
|
322
479
|
environments: {
|
|
323
480
|
local: { hostId: "local-docker", projectGroupId: "public-treedx-federation" },
|
|
324
481
|
staging: { hostId: "railway", projectGroupId: "public-treedx-federation" },
|
|
@@ -451,12 +608,14 @@ function filterHostingUnits(units, filter) {
|
|
|
451
608
|
const serviceIds = normalizeFilterValues(filter?.serviceIds);
|
|
452
609
|
const placements = normalizeFilterValues(filter?.placements);
|
|
453
610
|
const hosts = normalizeFilterValues(filter?.hosts);
|
|
454
|
-
if (serviceIds.size === 0 && placements.size === 0 && hosts.size === 0) return units;
|
|
455
611
|
const allServiceIds = new Set(units.map((unit) => unit.id));
|
|
456
612
|
const missingServices = [...serviceIds].filter((serviceId) => !allServiceIds.has(serviceId));
|
|
457
613
|
if (missingServices.length > 0) {
|
|
458
614
|
throw new Error(`Unknown hosting service id${missingServices.length === 1 ? "" : "s"}: ${missingServices.join(", ")}.`);
|
|
459
615
|
}
|
|
616
|
+
if (serviceIds.size === 0 && placements.size === 0 && hosts.size === 0) {
|
|
617
|
+
return units.filter((unit) => unit.metadata.deployByDefault !== false);
|
|
618
|
+
}
|
|
460
619
|
return units.filter((unit) => (serviceIds.size === 0 || serviceIds.has(unit.id)) && (placements.size === 0 || placements.has(unit.placement)) && (hosts.size === 0 || hosts.has(unit.host.id)));
|
|
461
620
|
}
|
|
462
621
|
function compileSingleTreeseedHostingGraph(input, application) {
|
|
@@ -503,6 +662,7 @@ function mergeTreeseedHostingGraphs(input, applications) {
|
|
|
503
662
|
const graphs = applications.map((application) => compileSingleTreeseedHostingGraph({
|
|
504
663
|
...input,
|
|
505
664
|
tenantRoot: application.root,
|
|
665
|
+
configRoot: resolve(input.tenantRoot),
|
|
506
666
|
deployConfig: application.config,
|
|
507
667
|
filter: void 0
|
|
508
668
|
}, application));
|
|
@@ -539,6 +699,7 @@ function compileTreeseedHostingGraph(input) {
|
|
|
539
699
|
return compileSingleTreeseedHostingGraph({
|
|
540
700
|
...input,
|
|
541
701
|
tenantRoot: application.root,
|
|
702
|
+
configRoot: tenantRoot,
|
|
542
703
|
deployConfig: application.config
|
|
543
704
|
}, application);
|
|
544
705
|
}
|
|
@@ -569,10 +730,14 @@ function railwayReconcileSystemsForUnits(units) {
|
|
|
569
730
|
const systems = /* @__PURE__ */ new Set();
|
|
570
731
|
for (const unit of units) {
|
|
571
732
|
if (unit.host.id !== "railway") continue;
|
|
572
|
-
if (unit.
|
|
733
|
+
if (unit.id === "operationsRunner") {
|
|
734
|
+
systems.add("api");
|
|
735
|
+
continue;
|
|
736
|
+
}
|
|
737
|
+
if (unit.placement === "api" || unit.placement === "knowledge-library" || unit.id === "api" || unit.serviceType.id === "container-api" || unit.serviceType.id === "treedx-node") {
|
|
573
738
|
systems.add("api");
|
|
574
739
|
}
|
|
575
|
-
if (unit.placement === "runner-capacity" || unit.
|
|
740
|
+
if (unit.placement === "runner-capacity" || unit.serviceType.id === "runner-pool") {
|
|
576
741
|
systems.add("agents");
|
|
577
742
|
}
|
|
578
743
|
if (unit.placement === "database" && units.some((candidate) => candidate.id === "api" || candidate.placement === "api")) {
|
|
@@ -581,18 +746,8 @@ function railwayReconcileSystemsForUnits(units) {
|
|
|
581
746
|
}
|
|
582
747
|
return [...systems];
|
|
583
748
|
}
|
|
584
|
-
function
|
|
585
|
-
|
|
586
|
-
for (const unit of units) {
|
|
587
|
-
if (unit.host.id !== "railway") continue;
|
|
588
|
-
if (unit.id === "api" || unit.placement === "api" || unit.serviceType.id === "container-api") {
|
|
589
|
-
keys.add("api");
|
|
590
|
-
}
|
|
591
|
-
if (unit.id === "operationsRunner" || unit.placement === "runner-capacity" || unit.serviceType.id === "runner-pool") {
|
|
592
|
-
keys.add("operationsRunner");
|
|
593
|
-
}
|
|
594
|
-
}
|
|
595
|
-
return keys;
|
|
749
|
+
function isInfrastructureHostedUnit(unit) {
|
|
750
|
+
return ["railway", "cloudflare", "cloudflare-dns", "local-docker"].includes(unit.host.id);
|
|
596
751
|
}
|
|
597
752
|
function railwayEnvForHostingApply(input, graph) {
|
|
598
753
|
const seedValues = collectTreeseedConfigSeedValues(input.tenantRoot, graph.environment);
|
|
@@ -601,254 +756,85 @@ function railwayEnvForHostingApply(input, graph) {
|
|
|
601
756
|
...seedValues
|
|
602
757
|
};
|
|
603
758
|
}
|
|
604
|
-
async function deploySelectedRailwayServices(input, graph) {
|
|
605
|
-
const selectedKeys = railwayDeployServiceKeysForUnits(graph.units);
|
|
606
|
-
if (selectedKeys.size === 0 || graph.environment === "local") {
|
|
607
|
-
return [];
|
|
608
|
-
}
|
|
609
|
-
const env = railwayEnvForHostingApply(input, graph);
|
|
610
|
-
const services = configuredRailwayServices(graph.tenantRoot, graph.environment).filter((service) => selectedKeys.has(service.key));
|
|
611
|
-
const results = [];
|
|
612
|
-
for (const service of services) {
|
|
613
|
-
results.push(await deployRailwayService(graph.tenantRoot, service, {
|
|
614
|
-
env,
|
|
615
|
-
prefix: {
|
|
616
|
-
scope: graph.environment,
|
|
617
|
-
system: service.key === "api" ? "api" : "agents",
|
|
618
|
-
task: `${service.key}-railway-deploy`,
|
|
619
|
-
stage: "deploy"
|
|
620
|
-
}
|
|
621
|
-
}));
|
|
622
|
-
}
|
|
623
|
-
return results;
|
|
624
|
-
}
|
|
625
|
-
function valueFromUnitConfig(unit, key) {
|
|
626
|
-
const config = unit.config && typeof unit.config === "object" ? unit.config : {};
|
|
627
|
-
const value = config[key];
|
|
628
|
-
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
629
|
-
}
|
|
630
|
-
function traceHostingRailway(env, stage, message) {
|
|
631
|
-
if (env.TREESEED_RECONCILE_TRACE === "1" || process.env.TREESEED_RECONCILE_TRACE === "1") {
|
|
632
|
-
console.error(`[trsd][hosting][railway][${stage}] ${message}`);
|
|
633
|
-
}
|
|
634
|
-
}
|
|
635
|
-
async function treeDxStage(env, stage, task) {
|
|
636
|
-
traceHostingRailway(env, `treedx:${stage}:start`, stage);
|
|
637
|
-
try {
|
|
638
|
-
const result = await task();
|
|
639
|
-
traceHostingRailway(env, `treedx:${stage}:done`, stage);
|
|
640
|
-
return result;
|
|
641
|
-
} catch (error) {
|
|
642
|
-
const message = error instanceof Error ? error.message : String(error ?? "");
|
|
643
|
-
throw new Error(`Public TreeDX Railway reconcile failed during ${stage}: ${message}`);
|
|
644
|
-
}
|
|
645
|
-
}
|
|
646
|
-
async function reconcilePublicTreeDxUnits(input, graph) {
|
|
647
|
-
if (graph.environment === "local") {
|
|
648
|
-
return [];
|
|
649
|
-
}
|
|
650
|
-
const nodeUnits = graph.units.filter((unit) => unit.id.startsWith("public-treedx-node-") && unit.host.id === "railway");
|
|
651
|
-
if (nodeUnits.length === 0) {
|
|
652
|
-
return [];
|
|
653
|
-
}
|
|
654
|
-
const env = railwayEnvForHostingApply(input, graph);
|
|
655
|
-
const workspace = await resolveRailwayWorkspaceContext({ env });
|
|
656
|
-
const results = [];
|
|
657
|
-
for (const unit of nodeUnits) {
|
|
658
|
-
const projectName2 = unit.projectGroup?.environments?.[graph.environment]?.projectName || String(env.TREESEED_PUBLIC_TREEDX_RAILWAY_PROJECT_NAME ?? "").trim() || "treeseed-api";
|
|
659
|
-
const environmentName2 = normalizeRailwayEnvironmentName(unit.projectGroup?.environments?.[graph.environment]?.environmentName) || ENVIRONMENT_NAMES[graph.environment];
|
|
660
|
-
const configuredImage = valueFromUnitConfig(unit, "image") ?? "treeseed/treedx";
|
|
661
|
-
const imageRef = String(env.TREESEED_PUBLIC_TREEDX_IMAGE_REF ?? "").trim() || (configuredImage.includes(":") ? configuredImage : `${configuredImage}:latest`);
|
|
662
|
-
const serviceName = valueFromUnitConfig(unit, "serviceName") ?? unit.id;
|
|
663
|
-
const volumeName = valueFromUnitConfig(unit, "volumeName") ?? `${serviceName}-volume`;
|
|
664
|
-
const mountPath = valueFromUnitConfig(unit, "volumeMountPath") ?? "/data";
|
|
665
|
-
const deploymentRegion = String(env.TREESEED_PUBLIC_TREEDX_RAILWAY_REGION ?? env.TREESEED_RAILWAY_STATEFUL_REGION ?? "us-west2").trim();
|
|
666
|
-
const ensuredProject2 = await treeDxStage(env, "project", () => ensureRailwayProject({
|
|
667
|
-
projectName: projectName2,
|
|
668
|
-
defaultEnvironmentName: environmentName2,
|
|
669
|
-
workspace: workspace.name,
|
|
670
|
-
env
|
|
671
|
-
}));
|
|
672
|
-
const ensuredEnvironment = await treeDxStage(env, "environment", () => ensureRailwayEnvironment({
|
|
673
|
-
projectId: ensuredProject2.project.id,
|
|
674
|
-
environmentName: environmentName2,
|
|
675
|
-
env
|
|
676
|
-
}));
|
|
677
|
-
const ensuredService = await treeDxStage(env, "service", async () => {
|
|
678
|
-
const services2 = await listRailwayServices({ projectId: ensuredProject2.project.id, env });
|
|
679
|
-
const existing = services2.find((service) => service.name === serviceName) ?? null;
|
|
680
|
-
const legacy = unit.metadata.nodeIndex === 1 ? services2.find((service) => service.name === "public-treedx-node") ?? null : null;
|
|
681
|
-
if (!existing && legacy) {
|
|
682
|
-
const renamed = await updateRailwayServiceName({ serviceId: legacy.id, name: serviceName, env });
|
|
683
|
-
return { service: renamed, created: false, adopted: true };
|
|
684
|
-
}
|
|
685
|
-
return ensureRailwayService({
|
|
686
|
-
projectId: ensuredProject2.project.id,
|
|
687
|
-
environmentId: ensuredEnvironment.environment.id,
|
|
688
|
-
serviceName,
|
|
689
|
-
imageRef,
|
|
690
|
-
env
|
|
691
|
-
});
|
|
692
|
-
});
|
|
693
|
-
const instance = await treeDxStage(env, "instance", () => ensureRailwayServiceInstanceConfiguration({
|
|
694
|
-
serviceId: ensuredService.service.id,
|
|
695
|
-
environmentId: ensuredEnvironment.environment.id,
|
|
696
|
-
healthcheckPath: "/api/v1/health",
|
|
697
|
-
healthcheckTimeoutSeconds: 120,
|
|
698
|
-
runtimeMode: "replicated",
|
|
699
|
-
deploymentRegion,
|
|
700
|
-
env
|
|
701
|
-
}));
|
|
702
|
-
const currentVariables = await treeDxStage(env, "variables:observe", () => listRailwayVariables({
|
|
703
|
-
projectId: ensuredProject2.project.id,
|
|
704
|
-
environmentId: ensuredEnvironment.environment.id,
|
|
705
|
-
serviceId: ensuredService.service.id,
|
|
706
|
-
env
|
|
707
|
-
}).catch(() => ({})));
|
|
708
|
-
await treeDxStage(env, "variables", () => upsertRailwayVariables({
|
|
709
|
-
projectId: ensuredProject2.project.id,
|
|
710
|
-
environmentId: ensuredEnvironment.environment.id,
|
|
711
|
-
serviceId: ensuredService.service.id,
|
|
712
|
-
variables: {
|
|
713
|
-
TREESEED_PUBLIC_TREEDX_IMAGE_REF: imageRef,
|
|
714
|
-
PHX_HOST: `${serviceName}.railway.app`,
|
|
715
|
-
PHX_SERVER: "true",
|
|
716
|
-
PORT: "4000",
|
|
717
|
-
TREEDX_DATA_DIR: mountPath,
|
|
718
|
-
TREEDX_AUTH_MODE: "connected",
|
|
719
|
-
TREEDX_AUTH_VERIFIER: "hs256_dev",
|
|
720
|
-
TREEDX_ALLOW_DEV_VERIFIER_IN_PROD: "true",
|
|
721
|
-
TREEDX_EXEC_BACKEND: "container_sandbox",
|
|
722
|
-
TREEDX_FEDERATION_MODE: "connected_library",
|
|
723
|
-
TREEDX_JWT_AUDIENCE: "treedx-public-federation",
|
|
724
|
-
TREEDX_JWT_ISSUER: `https://${serviceName}.railway.app/treedx`,
|
|
725
|
-
TREESEED_TREEDX_SCOPE: "public_federation",
|
|
726
|
-
...typeof currentVariables.SECRET_KEY_BASE === "string" && currentVariables.SECRET_KEY_BASE.trim() ? {} : { SECRET_KEY_BASE: treeDxSecretBase() },
|
|
727
|
-
...typeof currentVariables.TREEDX_JWT_HS256_SECRET === "string" && currentVariables.TREEDX_JWT_HS256_SECRET.trim() ? {} : { TREEDX_JWT_HS256_SECRET: treeDxSecretBase() },
|
|
728
|
-
...typeof env.TREESEED_TREEDX_ADMIN_TOKEN === "string" && env.TREESEED_TREEDX_ADMIN_TOKEN.trim() ? { TREESEED_TREEDX_ADMIN_TOKEN: env.TREESEED_TREEDX_ADMIN_TOKEN } : {}
|
|
729
|
-
},
|
|
730
|
-
env
|
|
731
|
-
}));
|
|
732
|
-
const volume = await treeDxStage(env, "volume", () => ensureRailwayServiceVolume({
|
|
733
|
-
projectId: ensuredProject2.project.id,
|
|
734
|
-
environmentId: ensuredEnvironment.environment.id,
|
|
735
|
-
serviceId: ensuredService.service.id,
|
|
736
|
-
name: volumeName,
|
|
737
|
-
mountPath,
|
|
738
|
-
env
|
|
739
|
-
}));
|
|
740
|
-
const domain = await treeDxStage(env, "domain", () => ensureRailwayGeneratedServiceDomain({
|
|
741
|
-
projectId: ensuredProject2.project.id,
|
|
742
|
-
environmentId: ensuredEnvironment.environment.id,
|
|
743
|
-
serviceId: ensuredService.service.id,
|
|
744
|
-
env
|
|
745
|
-
}));
|
|
746
|
-
await treeDxStage(env, "variables:domain", () => upsertRailwayVariables({
|
|
747
|
-
projectId: ensuredProject2.project.id,
|
|
748
|
-
environmentId: ensuredEnvironment.environment.id,
|
|
749
|
-
serviceId: ensuredService.service.id,
|
|
750
|
-
variables: {
|
|
751
|
-
PHX_HOST: domain.domain.domain,
|
|
752
|
-
TREEDX_JWT_ISSUER: `https://${domain.domain.domain}/treedx`
|
|
753
|
-
},
|
|
754
|
-
env
|
|
755
|
-
}));
|
|
756
|
-
const deployment = await treeDxStage(env, "deploy", () => deployRailwayServiceInstance({
|
|
757
|
-
serviceId: ensuredService.service.id,
|
|
758
|
-
environmentId: ensuredEnvironment.environment.id,
|
|
759
|
-
env
|
|
760
|
-
}));
|
|
761
|
-
results.push({
|
|
762
|
-
status: "ready",
|
|
763
|
-
locators: {
|
|
764
|
-
hostId: "railway",
|
|
765
|
-
projectGroupId: unit.projectGroup?.id ?? null,
|
|
766
|
-
projectName: projectName2,
|
|
767
|
-
serviceName,
|
|
768
|
-
domain: domain.domain.domain
|
|
769
|
-
},
|
|
770
|
-
state: {
|
|
771
|
-
unitId: unit.id,
|
|
772
|
-
serviceType: unit.serviceType.id,
|
|
773
|
-
placement: unit.placement,
|
|
774
|
-
projectId: ensuredProject2.project.id,
|
|
775
|
-
environmentId: ensuredEnvironment.environment.id,
|
|
776
|
-
serviceId: ensuredService.service.id,
|
|
777
|
-
imageRef,
|
|
778
|
-
volumeMountPath: volume.instance?.mountPath ?? mountPath,
|
|
779
|
-
healthcheckPath: instance.instance.healthcheckPath,
|
|
780
|
-
deploymentId: deployment.deploymentId
|
|
781
|
-
},
|
|
782
|
-
warnings: []
|
|
783
|
-
});
|
|
784
|
-
}
|
|
785
|
-
const firstUnit = nodeUnits[0];
|
|
786
|
-
const desiredIndexes = new Set(nodeUnits.map((unit) => Number(unit.metadata.nodeIndex ?? 1)).filter((index) => Number.isFinite(index) && index > 0));
|
|
787
|
-
const projectName = firstUnit.projectGroup?.environments?.[graph.environment]?.projectName || String(env.TREESEED_PUBLIC_TREEDX_RAILWAY_PROJECT_NAME ?? "").trim() || "treeseed-api";
|
|
788
|
-
const environmentName = normalizeRailwayEnvironmentName(firstUnit.projectGroup?.environments?.[graph.environment]?.environmentName) || ENVIRONMENT_NAMES[graph.environment];
|
|
789
|
-
const ensuredProject = await treeDxStage(env, "scale-down-project", () => ensureRailwayProject({
|
|
790
|
-
projectName,
|
|
791
|
-
defaultEnvironmentName: environmentName,
|
|
792
|
-
workspace: workspace.name,
|
|
793
|
-
env
|
|
794
|
-
}));
|
|
795
|
-
await treeDxStage(env, "scale-down-environment", () => ensureRailwayEnvironment({
|
|
796
|
-
projectId: ensuredProject.project.id,
|
|
797
|
-
environmentName,
|
|
798
|
-
env
|
|
799
|
-
}));
|
|
800
|
-
const services = await treeDxStage(env, "scale-down-services", () => listRailwayServices({ projectId: ensuredProject.project.id, env }));
|
|
801
|
-
for (const service of services) {
|
|
802
|
-
const match = /^public-treedx-node-(\d{2,})$/u.exec(service.name);
|
|
803
|
-
const index = match ? Number.parseInt(match[1], 10) : null;
|
|
804
|
-
const staleSingleton = service.name === "public-treedx-node" && desiredIndexes.has(1);
|
|
805
|
-
if (index !== null && !desiredIndexes.has(index) || staleSingleton) {
|
|
806
|
-
await treeDxStage(env, `scale-down-service:${service.name}`, () => deleteRailwayService({ serviceId: service.id, env }));
|
|
807
|
-
results.push({
|
|
808
|
-
status: "ready",
|
|
809
|
-
locators: {
|
|
810
|
-
hostId: "railway",
|
|
811
|
-
projectGroupId: firstUnit.projectGroup?.id ?? null,
|
|
812
|
-
projectName,
|
|
813
|
-
serviceName: service.name
|
|
814
|
-
},
|
|
815
|
-
state: {
|
|
816
|
-
unitId: service.name,
|
|
817
|
-
action: "delete",
|
|
818
|
-
retainedResources: [{
|
|
819
|
-
kind: "volume",
|
|
820
|
-
name: `${service.name}-volume`,
|
|
821
|
-
reason: "Stateful TreeDX volumes are retained across scale-down for later reclaim."
|
|
822
|
-
}]
|
|
823
|
-
},
|
|
824
|
-
warnings: [`Destroyed scaled-down TreeDX service ${service.name}; retained ${service.name}-volume.`]
|
|
825
|
-
});
|
|
826
|
-
}
|
|
827
|
-
}
|
|
828
|
-
return results;
|
|
829
|
-
}
|
|
830
759
|
async function applyTreeseedHostingGraph(input) {
|
|
831
760
|
const plan = await planTreeseedHostingGraph(input);
|
|
832
761
|
const graph = compileTreeseedHostingGraph(input);
|
|
833
762
|
const selectedSystems = railwayReconcileSystemsForUnits(graph.units);
|
|
834
|
-
const
|
|
835
|
-
if (
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
763
|
+
const infrastructureUnits = graph.units.filter(isInfrastructureHostedUnit);
|
|
764
|
+
if (plan.dryRun) {
|
|
765
|
+
return {
|
|
766
|
+
environment: plan.environment,
|
|
767
|
+
dryRun: true,
|
|
768
|
+
selectedApps: [...new Set(graph.units.map((unit) => unit.application?.id).filter((value) => Boolean(value)))],
|
|
769
|
+
selectedSystems,
|
|
770
|
+
skippedSystems: ["web", "data", "github"].filter((system) => !selectedSystems.includes(system)).map((system) => ({ system, reason: selectedSystems.length > 0 ? "Not selected by hosting app filter." : "No Railway reconciliation selected." })),
|
|
771
|
+
results: plan.units.map((entry) => ({
|
|
772
|
+
unit: entry.unit,
|
|
773
|
+
plan: entry.plan,
|
|
774
|
+
result: entry.observed,
|
|
775
|
+
verification: entry.verification
|
|
776
|
+
})),
|
|
777
|
+
placements: plan.placements,
|
|
778
|
+
warnings: plan.warnings
|
|
779
|
+
};
|
|
844
780
|
}
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
const unit = graph.units.find((candidate) => candidate.id === entry.unit.id) ?? entry.unit;
|
|
848
|
-
const result = await unit.host.apply({ environment: graph.environment, unit, graph, plan: entry.plan, dryRun: plan.dryRun });
|
|
849
|
-
const verification = await unit.host.verify({ environment: graph.environment, unit, graph, observed: result, dryRun: plan.dryRun });
|
|
850
|
-
results.push({ unit, plan: entry.plan, result, verification });
|
|
781
|
+
if (infrastructureUnits.length > 0 && selectedSystems.length === 0) {
|
|
782
|
+
throw new Error(`Hosting apply selected infrastructure resources but no provider reconciliation system was selected: ${infrastructureUnits.map((unit) => `${unit.id} (${unit.host.id})`).join(", ")}.`);
|
|
851
783
|
}
|
|
784
|
+
const reconcile = await reconcileTreeseedTarget({
|
|
785
|
+
tenantRoot: graph.tenantRoot,
|
|
786
|
+
target: createPersistentDeployTarget(graph.environment),
|
|
787
|
+
systems: selectedSystems.length > 0 ? selectedSystems : void 0,
|
|
788
|
+
env: railwayEnvForHostingApply(input, graph),
|
|
789
|
+
dryRun: plan.dryRun
|
|
790
|
+
});
|
|
791
|
+
const resultByUnit = /* @__PURE__ */ new Map();
|
|
792
|
+
for (const entry of reconcile.results) {
|
|
793
|
+
resultByUnit.set(entry.unit.unitId, entry);
|
|
794
|
+
resultByUnit.set(entry.unit.logicalName, entry);
|
|
795
|
+
}
|
|
796
|
+
const results = plan.units.map((entry) => {
|
|
797
|
+
const unit = graph.units.find((candidate) => candidate.id === entry.unit.id) ?? entry.unit;
|
|
798
|
+
const reconcileResult = resultByUnit.get(entry.unit.id) ?? resultByUnit.get(unit.id) ?? resultByUnit.get(unit.logicalName) ?? null;
|
|
799
|
+
return {
|
|
800
|
+
unit,
|
|
801
|
+
plan: entry.plan,
|
|
802
|
+
result: {
|
|
803
|
+
status: reconcileResult?.verification?.ready || plan.dryRun ? "ready" : "blocked",
|
|
804
|
+
locators: reconcileResult?.resourceLocators ?? {},
|
|
805
|
+
state: reconcileResult?.state ?? {
|
|
806
|
+
unitId: unit.id,
|
|
807
|
+
action: plan.dryRun ? "plan" : "unmatched"
|
|
808
|
+
},
|
|
809
|
+
warnings: reconcileResult?.warnings ?? []
|
|
810
|
+
},
|
|
811
|
+
verification: reconcileResult?.verification ? {
|
|
812
|
+
unitId: unit.id,
|
|
813
|
+
status: reconcileResult.verification.verified ? "ready" : "blocked",
|
|
814
|
+
verified: reconcileResult.verification.verified,
|
|
815
|
+
checks: reconcileResult.verification.checks.map((check) => ({
|
|
816
|
+
key: check.key,
|
|
817
|
+
label: check.description,
|
|
818
|
+
ok: check.verified,
|
|
819
|
+
expected: check.expected,
|
|
820
|
+
observed: check.observed,
|
|
821
|
+
issues: check.issues
|
|
822
|
+
})),
|
|
823
|
+
warnings: reconcileResult.verification.warnings
|
|
824
|
+
} : {
|
|
825
|
+
unitId: unit.id,
|
|
826
|
+
status: plan.dryRun ? "ready" : "blocked",
|
|
827
|
+
verified: plan.dryRun,
|
|
828
|
+
checks: plan.dryRun ? [] : [{
|
|
829
|
+
key: "reconcile-result",
|
|
830
|
+
label: "Hosting unit matched a reconcile result",
|
|
831
|
+
ok: false,
|
|
832
|
+
issues: [`No reconcile result matched hosting unit ${unit.id}.`]
|
|
833
|
+
}],
|
|
834
|
+
warnings: []
|
|
835
|
+
}
|
|
836
|
+
};
|
|
837
|
+
});
|
|
852
838
|
return {
|
|
853
839
|
environment: plan.environment,
|
|
854
840
|
dryRun: plan.dryRun,
|