@flisk-sh/flisk 0.0.0-stage → 1.3.190
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/CHANGELOG.md +492 -0
- package/LICENSE +21 -0
- package/README.md +479 -2
- package/Tiltfile +151 -0
- package/cli/bin/flisk.js +42 -0
- package/cli/dist/agent-runtimes/custom.js +335 -0
- package/cli/dist/agent-runtimes/registry.js +34 -0
- package/cli/dist/backend-frameworks/elysia.js +38 -0
- package/cli/dist/backend-frameworks/express.js +49 -0
- package/cli/dist/backend-frameworks/fastify.js +43 -0
- package/cli/dist/backend-frameworks/h3.js +37 -0
- package/cli/dist/backend-frameworks/koa.js +47 -0
- package/cli/dist/backend-frameworks/mcp.js +86 -0
- package/cli/dist/backend-frameworks/nestjs.js +55 -0
- package/cli/dist/backend-frameworks/registry.js +134 -0
- package/cli/dist/backend-frameworks/types.js +1 -0
- package/cli/dist/backend-languages/bun.js +76 -0
- package/cli/dist/backend-languages/go.js +125 -0
- package/cli/dist/backend-languages/node.js +122 -0
- package/cli/dist/backend-languages/python.js +94 -0
- package/cli/dist/backend-languages/registry.js +37 -0
- package/cli/dist/backend-languages/rust.js +82 -0
- package/cli/dist/backend-languages/types.js +1 -0
- package/cli/dist/cli.js +29 -0
- package/cli/dist/commands/__tests__/project-e2e-helpers.js +49 -0
- package/cli/dist/commands/__tests__/ui-loading-screen.test.js +16 -0
- package/cli/dist/commands/agent.js +182 -0
- package/cli/dist/commands/completion-candidates.js +116 -0
- package/cli/dist/commands/completion.js +843 -0
- package/cli/dist/commands/config.js +362 -0
- package/cli/dist/commands/doctor.js +1504 -0
- package/cli/dist/commands/down.js +114 -0
- package/cli/dist/commands/eject.js +108 -0
- package/cli/dist/commands/help.js +152 -0
- package/cli/dist/commands/import.js +164 -0
- package/cli/dist/commands/logs.js +119 -0
- package/cli/dist/commands/maintainers.js +102 -0
- package/cli/dist/commands/mcp.js +28 -0
- package/cli/dist/commands/networks.js +306 -0
- package/cli/dist/commands/project.js +447 -0
- package/cli/dist/commands/projects.js +103 -0
- package/cli/dist/commands/registry.js +53 -0
- package/cli/dist/commands/resource.js +992 -0
- package/cli/dist/commands/resources.js +127 -0
- package/cli/dist/commands/restart.js +89 -0
- package/cli/dist/commands/runtime.js +75 -0
- package/cli/dist/commands/stack.js +171 -0
- package/cli/dist/commands/stacks.js +71 -0
- package/cli/dist/commands/status.js +211 -0
- package/cli/dist/commands/ui.js +725 -0
- package/cli/dist/commands/up.js +609 -0
- package/cli/dist/commands/upgrade.js +840 -0
- package/cli/dist/commands/version.js +10 -0
- package/cli/dist/components/Accessible.js +11 -0
- package/cli/dist/components/BaseTooltip.js +30 -0
- package/cli/dist/components/DetailPanel.js +33 -0
- package/cli/dist/components/FileTree.js +51 -0
- package/cli/dist/components/ResourceSelectInput.js +42 -0
- package/cli/dist/components/ResourceTable.js +35 -0
- package/cli/dist/components/ServiceIssues.js +13 -0
- package/cli/dist/components/TUIHeader.js +27 -0
- package/cli/dist/components/TabBar.js +27 -0
- package/cli/dist/components/Tooltip.js +13 -0
- package/cli/dist/components/index.js +11 -0
- package/cli/dist/components/ui-theme.js +120 -0
- package/cli/dist/config/platform-standards.js +182 -0
- package/cli/dist/frontend-frameworks/lit.js +64 -0
- package/cli/dist/frontend-frameworks/preact.js +62 -0
- package/cli/dist/frontend-frameworks/qwik.js +61 -0
- package/cli/dist/frontend-frameworks/react.js +69 -0
- package/cli/dist/frontend-frameworks/registry.js +83 -0
- package/cli/dist/frontend-frameworks/solid.js +62 -0
- package/cli/dist/frontend-frameworks/svelte.js +67 -0
- package/cli/dist/frontend-frameworks/tanstack-router.js +101 -0
- package/cli/dist/frontend-frameworks/types.js +1 -0
- package/cli/dist/frontend-frameworks/vanilla.js +59 -0
- package/cli/dist/frontend-frameworks/vue.js +72 -0
- package/cli/dist/generator/__tests__/golden-helpers.js +43 -0
- package/cli/dist/generator/extension-fetch.js +291 -0
- package/cli/dist/generator/resource-templates.js +133 -0
- package/cli/dist/generator/template-engine.js +801 -0
- package/cli/dist/index.js +10 -0
- package/cli/dist/mcp/server.js +101 -0
- package/cli/dist/mcp/tools.js +351 -0
- package/cli/dist/program.js +37 -0
- package/cli/dist/types/index.js +38 -0
- package/cli/dist/utils/agent-host.js +36 -0
- package/cli/dist/utils/atomic-write.js +36 -0
- package/cli/dist/utils/bun-floor.js +9 -0
- package/cli/dist/utils/bun-requirement.js +10 -0
- package/cli/dist/utils/cache.js +63 -0
- package/cli/dist/utils/cold-preflight.js +257 -0
- package/cli/dist/utils/command-helpers.js +57 -0
- package/cli/dist/utils/constants.js +160 -0
- package/cli/dist/utils/discovery-context.js +71 -0
- package/cli/dist/utils/discovery-paths.js +93 -0
- package/cli/dist/utils/docker.js +34 -0
- package/cli/dist/utils/doctor-crashloop.js +161 -0
- package/cli/dist/utils/doctor-fix.js +391 -0
- package/cli/dist/utils/doctor-host.js +66 -0
- package/cli/dist/utils/doctor-report.js +78 -0
- package/cli/dist/utils/doctor-runtime.js +880 -0
- package/cli/dist/utils/doctor-starlark.js +132 -0
- package/cli/dist/utils/doctor-wiring.js +698 -0
- package/cli/dist/utils/down-cleanup.js +125 -0
- package/cli/dist/utils/env-validator.js +266 -0
- package/cli/dist/utils/errors.js +175 -0
- package/cli/dist/utils/exec-async.js +31 -0
- package/cli/dist/utils/file-helpers.js +104 -0
- package/cli/dist/utils/formatting.js +165 -0
- package/cli/dist/utils/generated-paths.js +51 -0
- package/cli/dist/utils/help-command.js +11 -0
- package/cli/dist/utils/host-port-config.js +140 -0
- package/cli/dist/utils/host-port-plan.js +100 -0
- package/cli/dist/utils/json-output.js +29 -0
- package/cli/dist/utils/machine-output.js +33 -0
- package/cli/dist/utils/paths.js +43 -0
- package/cli/dist/utils/platform.js +58 -0
- package/cli/dist/utils/port-assignment.js +75 -0
- package/cli/dist/utils/port-conflict-fix.js +25 -0
- package/cli/dist/utils/port-fallback-notice.js +17 -0
- package/cli/dist/utils/port-listener-probe.js +20 -0
- package/cli/dist/utils/project-config-defaults.js +17 -0
- package/cli/dist/utils/project-features.js +91 -0
- package/cli/dist/utils/project-templates.js +32 -0
- package/cli/dist/utils/prompt.js +97 -0
- package/cli/dist/utils/resource-features.js +184 -0
- package/cli/dist/utils/resource-kind.js +9 -0
- package/cli/dist/utils/schema-version-gate.js +45 -0
- package/cli/dist/utils/search-status.js +12 -0
- package/cli/dist/utils/secret-redaction.js +73 -0
- package/cli/dist/utils/service-config-checks.js +189 -0
- package/cli/dist/utils/service-manifest.js +254 -0
- package/cli/dist/utils/service-runtime-state.js +66 -0
- package/cli/dist/utils/service-urls.js +112 -0
- package/cli/dist/utils/services.js +360 -0
- package/cli/dist/utils/shared-infra.js +45 -0
- package/cli/dist/utils/shared-platform-postgres.js +232 -0
- package/cli/dist/utils/single-flight.js +21 -0
- package/cli/dist/utils/smoke.js +401 -0
- package/cli/dist/utils/spinner.js +40 -0
- package/cli/dist/utils/stack-features.js +15 -0
- package/cli/dist/utils/stack-status.js +14 -0
- package/cli/dist/utils/startup-report.js +78 -0
- package/cli/dist/utils/status-message.js +21 -0
- package/cli/dist/utils/status-ports.js +33 -0
- package/cli/dist/utils/suggestions.js +63 -0
- package/cli/dist/utils/tar.js +46 -0
- package/cli/dist/utils/tdk-version.js +51 -0
- package/cli/dist/utils/terminal-layout.js +19 -0
- package/cli/dist/utils/tilt-events.js +194 -0
- package/cli/dist/utils/tilt-logs.js +61 -0
- package/cli/dist/utils/tilt-port-owner.js +63 -0
- package/cli/dist/utils/tilt-process.js +54 -0
- package/cli/dist/utils/tilt-resource-state.js +32 -0
- package/cli/dist/utils/tilt-startup.js +49 -0
- package/cli/dist/utils/tilt-unreachable-message.js +9 -0
- package/cli/dist/utils/tilt.js +104 -0
- package/cli/dist/utils/ui-keymap.js +129 -0
- package/cli/dist/utils/ui-service-state.js +34 -0
- package/cli/dist/utils/up-only.js +28 -0
- package/cli/dist/utils/up-readiness.js +118 -0
- package/cli/dist/utils/url-actions.js +103 -0
- package/cli/dist/utils/validation.js +62 -0
- package/cli/dist/utils/which.js +56 -0
- package/cli/dist/utils/windows-doctor.js +176 -0
- package/cli/dist-bundle/chunk-6EA4DGCY.js +2 -0
- package/cli/dist-bundle/chunk-BZ4H7MM4.js +3 -0
- package/cli/dist-bundle/chunk-CLCUIDBH.js +510 -0
- package/cli/dist-bundle/cli.js +2017 -0
- package/cli/dist-bundle/cold-preflight-SY26O2IG.js +2 -0
- package/cli/dist-bundle/devtools-ZUHXW33W.js +5 -0
- package/cli/dist-bundle/extension-fetch-J4FFH7TJ.js +2 -0
- package/cli/package.json +83 -0
- package/cli/shared-platform-engineering/docker-templates/bun-hoisted-symlink-fix.sh +25 -0
- package/cli/shared-platform-engineering/docker-templates/infisical-entrypoint.sh +466 -0
- package/cli/shared-platform-engineering/docker-templates/install-deps.sh +154 -0
- package/cli/shared-platform-engineering/docker-templates/prisma-bun-client-link-fix.sh +14 -0
- package/cli/shared-platform-engineering/docker-templates/prisma-normalize-client.sh +58 -0
- package/cli/templates/.tiltignore.hbs +72 -0
- package/cli/templates/TILT_RESOURCE_DEFAULTS.star.hbs +220 -0
- package/cli/templates/TILT_TECH_STACK.star.hbs +149 -0
- package/cli/templates/Tiltfile.hbs +381 -0
- package/cli/templates/spec.master.hbs +192 -0
- package/discovery/AGENTS.md +362 -0
- package/discovery/TILT_DISCOVERY.star +429 -0
- package/discovery/Tiltfile +58 -0
- package/discovery/config.star +265 -0
- package/discovery/constants.star +167 -0
- package/discovery/deterministic.star +213 -0
- package/discovery/discovery_daemon.star +193 -0
- package/discovery/discovery_orchestrator.star +492 -0
- package/discovery/filtering.star +7 -0
- package/discovery/identity-management-backend/service.yaml +26 -0
- package/discovery/identity-management-frontend/service.yaml +29 -0
- package/discovery/identity-sdk/service.yaml +9 -0
- package/discovery/incremental_discovery.star +215 -0
- package/discovery/indexing.star +9 -0
- package/discovery/json_manifest_scanner.star +57 -0
- package/discovery/libraries.star +48 -0
- package/discovery/loading.star +25 -0
- package/discovery/manifest/constants.star +106 -0
- package/discovery/manifest/loading.star +418 -0
- package/discovery/manifest/normalize.star +289 -0
- package/discovery/manifest/validation.star +110 -0
- package/discovery/normalization.star +13 -0
- package/discovery/registry.star +562 -0
- package/discovery/resource_snapshot.py +384 -0
- package/discovery/resource_snapshot.star +145 -0
- package/discovery/schemas.star +3 -0
- package/discovery/services/platform/cdc/debezium/nats-connector/service.yaml +9 -0
- package/discovery/services/platform/cdc/nats-http-bridge/service.yaml +9 -0
- package/discovery/services/platform/orchestrator/orchestrator-glue-backend/service.yaml +26 -0
- package/discovery/services/platform/synthetic-monitor/service.yaml +9 -0
- package/discovery/test_resource_snapshot.py +253 -0
- package/discovery/validation.star +80 -0
- package/discovery/versioning.star +3 -0
- package/engine/AGENTS.md +706 -0
- package/engine/README.md +31 -0
- package/engine/REFACTORING_MANIFEST_SYSTEM.md +974 -0
- package/engine/Tiltfile +86 -0
- package/engine/assets/docker/golden-layers.Dockerfile +204 -0
- package/engine/assets/docker/wake-gateway/Dockerfile +28 -0
- package/engine/assets/docker/wake-gateway/decide.test.ts +177 -0
- package/engine/assets/docker/wake-gateway/decide.ts +135 -0
- package/engine/assets/docker/wake-gateway/server.ts +363 -0
- package/engine/assets/scripts/cleanup-completed-migrator-images.sh +39 -0
- package/engine/assets/scripts/cleanup-tilt-images.sh +122 -0
- package/engine/assets/scripts/mac-m1-resource-monitor.sh +123 -0
- package/engine/config.star +5 -0
- package/engine/entrypoint.star +101 -0
- package/engine/lifecycle/orchestrator.star +263 -0
- package/engine/paths.star +719 -0
- package/engine/schemas/project-schema.json +147 -0
- package/engine/schemas/service-schema.json +537 -0
- package/engine/scripts/README.md +89 -0
- package/engine/scripts/build-and-publish-lib.sh +207 -0
- package/engine/scripts/check-lib-publish.sh +87 -0
- package/engine/scripts/debug-container.sh +265 -0
- package/engine/scripts/generate-manifest.sh +200 -0
- package/engine/spec.master +702 -0
- package/engine/spec.master.example +341 -0
- package/engine/topologies/README.md +33 -0
- package/engine/topologies/platform/docker/AGENTS.md +59 -0
- package/engine/topologies/platform/docker/auth/auth.star +207 -0
- package/engine/topologies/platform/docker/build/frontend_build_plan.star +65 -0
- package/engine/topologies/platform/docker/build/golden_image.star +37 -0
- package/engine/topologies/platform/docker/build/golden_image_build.star +144 -0
- package/engine/topologies/platform/docker/build/golden_image_constants.star +100 -0
- package/engine/topologies/platform/docker/build/golden_image_dockerfile.star +263 -0
- package/engine/topologies/platform/docker/compose/compose.star +637 -0
- package/engine/topologies/platform/docker/compose/compose_helpers.star +54 -0
- package/engine/topologies/platform/docker/compose/traefik_standalone.star +171 -0
- package/engine/topologies/platform/docker/config/bunignore.star +144 -0
- package/engine/topologies/platform/docker/config/dockerignore.star +152 -0
- package/engine/topologies/platform/docker/config/healthcheck.star +58 -0
- package/engine/topologies/platform/docker/constants.star +211 -0
- package/engine/topologies/platform/docker/dockerfile/dockerfile.star +56 -0
- package/engine/topologies/platform/docker/dockerfile/language_dockerfile.star +264 -0
- package/engine/topologies/platform/docker/generators/golden_docker_generator_v2.star +76 -0
- package/engine/topologies/platform/docker/index.star +40 -0
- package/engine/topologies/platform/docker/layers/bun_helpers.star +25 -0
- package/engine/topologies/platform/docker/layers/infisical/index.star +42 -0
- package/engine/topologies/platform/docker/layers/infisical/infisical_docker.star +264 -0
- package/engine/topologies/platform/docker/layers/l1_base_layers.star +89 -0
- package/engine/topologies/platform/docker/layers/l2_dependency_layers.star +147 -0
- package/engine/topologies/platform/docker/layers/l3_builder_layers.star +229 -0
- package/engine/topologies/platform/docker/layers/l4_runtime_layers.star +282 -0
- package/engine/topologies/platform/docker/layers/prisma/constants.star +138 -0
- package/engine/topologies/platform/docker/layers/prisma/db_readiness.star +98 -0
- package/engine/topologies/platform/docker/layers/prisma/filesystem_setup.star +131 -0
- package/engine/topologies/platform/docker/layers/prisma/migrate_script.star +100 -0
- package/engine/topologies/platform/docker/layers/prisma/prisma_build.star +128 -0
- package/engine/topologies/platform/docker/layers/prisma/prisma_runtime.star +205 -0
- package/engine/topologies/platform/docker/layers/prisma/secret_resolution.star +121 -0
- package/engine/topologies/platform/docker/networking/api_path_constants.star +206 -0
- package/engine/topologies/platform/docker/networking/sablier_container_cycle.star +31 -0
- package/engine/topologies/platform/docker/networking/traefik.star +266 -0
- package/engine/topologies/platform/docker/networking/traefik_constants.star +148 -0
- package/engine/topologies/platform/docker/networking/traefik_helpers.star +162 -0
- package/engine/topologies/platform/docker/networking/traefik_static_routes.star +165 -0
- package/engine/topologies/platform/docker/secrets/env_secrets.star +74 -0
- package/engine/topologies/platform/docker/secrets/infisical.star +109 -0
- package/engine/topologies/platform/net/AGENTS.md +64 -0
- package/engine/topologies/platform/net/proxy.star +6 -0
- package/engine/topologies/platform/registries/local.star +6 -0
- package/engine/topologies/platform/registries/verdaccio_loader.star +20 -0
- package/engine/topologies/platform/security/AGENTS.md +49 -0
- package/engine/topologies/platform/security/secrets.star +241 -0
- package/engine/topologies/platform/state/AGENTS.md +64 -0
- package/engine/topologies/platform/state/relational.star +6 -0
- package/engine/topologies/tilt/common/AGENTS.md +59 -0
- package/engine/topologies/tilt/common/utils.star +409 -0
- package/engine/topologies/tilt/common/utils_debug.star +71 -0
- package/engine/topologies/tilt/common/utils_deterministic.star +170 -0
- package/engine/topologies/tilt/common/utils_docker_networks.star +54 -0
- package/engine/topologies/tilt/common/utils_env.star +92 -0
- package/engine/topologies/tilt/common/utils_output.star +99 -0
- package/engine/topologies/tilt/config/AGENTS.md +68 -0
- package/engine/topologies/tilt/config/defaults.star +5 -0
- package/engine/topologies/tilt/config/feature_flags.star +12 -0
- package/engine/topologies/tilt/config/global.star +57 -0
- package/engine/topologies/tilt/config/profiles.star +398 -0
- package/engine/topologies/tilt/generators/agents_md.star +64 -0
- package/engine/topologies/tilt/generators/api_gateway.star +147 -0
- package/engine/topologies/tilt/generators/index.star +126 -0
- package/engine/topologies/tilt/generators/infisical/README.md +424 -0
- package/engine/topologies/tilt/generators/infisical/examples.star +314 -0
- package/engine/topologies/tilt/generators/infisical/index.star +59 -0
- package/engine/topologies/tilt/generators/infisical/machine_identity.star +422 -0
- package/engine/topologies/tilt/generators/infisical/organization.star +536 -0
- package/engine/topologies/tilt/generators/infisical/path_manager.star +478 -0
- package/engine/topologies/tilt/generators/infisical/secrets_generator.star +422 -0
- package/engine/topologies/tilt/generators/nginx_conf.star +145 -0
- package/engine/topologies/tilt/generators/npmrc.star +132 -0
- package/engine/topologies/tilt/generators/tsconfig.star +25 -0
- package/engine/topologies/tilt/generators/typescript/backend_library_tsconfig.star +73 -0
- package/engine/topologies/tilt/generators/typescript/backend_tsconfig.star +137 -0
- package/engine/topologies/tilt/generators/typescript/common.star +9 -0
- package/engine/topologies/tilt/generators/typescript/frontend_library_tsconfig.star +78 -0
- package/engine/topologies/tilt/generators/typescript/frontend_tsconfig.star +140 -0
- package/engine/topologies/tilt/generators/typescript/include.star +25 -0
- package/engine/topologies/tilt/generators/typescript/playwright_config.star +42 -0
- package/engine/topologies/tilt/generators/typescript/prisma_config.star +51 -0
- package/engine/topologies/tilt/generators/validators.star +868 -0
- package/engine/topologies/tilt/generators/vite/backend.star +80 -0
- package/engine/topologies/tilt/generators/vite/frameworks/lit.star +92 -0
- package/engine/topologies/tilt/generators/vite/frameworks/preact.star +94 -0
- package/engine/topologies/tilt/generators/vite/frameworks/qwik.star +94 -0
- package/engine/topologies/tilt/generators/vite/frameworks/react.star +128 -0
- package/engine/topologies/tilt/generators/vite/frameworks/solid.star +94 -0
- package/engine/topologies/tilt/generators/vite/frameworks/svelte.star +94 -0
- package/engine/topologies/tilt/generators/vite/frameworks/vanilla.star +92 -0
- package/engine/topologies/tilt/generators/vite/frameworks/vue.star +94 -0
- package/engine/topologies/tilt/generators/vite/frontend.star +153 -0
- package/engine/topologies/tilt/generators/vite/generators.star +45 -0
- package/engine/topologies/tilt/generators/vite/helpers.star +256 -0
- package/engine/topologies/tilt/generators/vite/library.star +67 -0
- package/engine/topologies/tilt/generators/vite/sdk.star +75 -0
- package/engine/topologies/tilt/generators/vite/templates.star +460 -0
- package/engine/topologies/tilt/generators/vite_config.star +24 -0
- package/engine/topologies/tilt/manifest/AGENTS.md +61 -0
- package/engine/topologies/tilt/manifest/README.md +679 -0
- package/engine/topologies/tilt/manifest/__init__.star +220 -0
- package/engine/topologies/tilt/manifest/constants.star +262 -0
- package/engine/topologies/tilt/manifest/errors.star +268 -0
- package/engine/topologies/tilt/manifest/integration.star +348 -0
- package/engine/topologies/tilt/manifest/json_to_yaml.py +61 -0
- package/engine/topologies/tilt/manifest/loader.star +239 -0
- package/engine/topologies/tilt/manifest/mapper.star +229 -0
- package/engine/topologies/tilt/manifest/parser.star +490 -0
- package/engine/topologies/tilt/manifest/schema.star +502 -0
- package/engine/topologies/tilt/manifest/tests/test_integration.star +278 -0
- package/engine/topologies/tilt/manifest/tests/test_loader_parser.star +475 -0
- package/engine/topologies/tilt/manifest/tests/test_manifest.star +319 -0
- package/engine/topologies/tilt/manifest/tests/test_validator.star +472 -0
- package/engine/topologies/tilt/manifest/validator.star +744 -0
- package/engine/topologies/tilt/manifest/yaml_to_json.py +20 -0
- package/engine/topologies/tilt/resources/AGENTS.md +71 -0
- package/engine/topologies/tilt/resources/build_concurrency.star +56 -0
- package/engine/topologies/tilt/resources/conditions.star +5 -0
- package/engine/topologies/tilt/resources/databases.star +246 -0
- package/engine/topologies/tilt/resources/declaration.star +5 -0
- package/engine/topologies/tilt/resources/deps.star +5 -0
- package/engine/topologies/tilt/resources/infra-loader.star +504 -0
- package/engine/topologies/tilt/resources/libs.star +32 -0
- package/engine/topologies/tilt/resources/libs_discovery.star +104 -0
- package/engine/topologies/tilt/resources/libs_paths.star +81 -0
- package/engine/topologies/tilt/resources/libs_resource_definition.star +153 -0
- package/engine/topologies/tilt/resources/libs_setup.star +166 -0
- package/engine/topologies/tilt/resources/libs_tsconfig.star +39 -0
- package/engine/topologies/tilt/resources/orchestrator/apply.star +79 -0
- package/engine/topologies/tilt/resources/orchestrator/apply_compose_resource_registration.star +864 -0
- package/engine/topologies/tilt/resources/orchestrator/apply_manifest_orchestration.star +90 -0
- package/engine/topologies/tilt/resources/orchestrator/apply_migrator_orchestration.star +150 -0
- package/engine/topologies/tilt/resources/orchestrator/apply_resource_validation.star +38 -0
- package/engine/topologies/tilt/resources/orchestrator/apply_runtime_flags.star +46 -0
- package/engine/topologies/tilt/resources/orchestrator/builders/typescript.star +193 -0
- package/engine/topologies/tilt/resources/orchestrator/generators/dependencies/AGENTS.md +75 -0
- package/engine/topologies/tilt/resources/orchestrator/generators/dependencies/index.star +23 -0
- package/engine/topologies/tilt/resources/orchestrator/generators/dependencies/resolver.star +136 -0
- package/engine/topologies/tilt/resources/orchestrator/generators/env.star +219 -0
- package/engine/topologies/tilt/resources/orchestrator/generators/frontend.star +172 -0
- package/engine/topologies/tilt/resources/orchestrator/generators/manifest_resource.star +577 -0
- package/engine/topologies/tilt/resources/orchestrator/helpers.star +35 -0
- package/engine/topologies/tilt/resources/orchestrator.star +56 -0
- package/engine/topologies/tilt/resources/ordering.star +5 -0
- package/engine/topologies/tilt/resources/shared-platform-postgres.star +30 -0
- package/engine/topologies/tilt/resources/triggers.star +5 -0
- package/engine/topologies/tilt/resources/watchers.star +304 -0
- package/engine/where-things-live.star +719 -0
- package/examples/tdk-example/LICENSE +21 -0
- package/examples/tdk-example/README.md +23 -0
- package/examples/tdk-example/TILT_SERVICE_DEFAULTS.star +42 -0
- package/examples/tdk-example/TILT_TECH_STACK.star +67 -0
- package/examples/tdk-example/Tiltfile +25 -0
- package/examples/tdk-example/services/platform/messaging/docker-compose.yml +26 -0
- package/examples/tdk-example/services/shop/orders-api/package.json +20 -0
- package/examples/tdk-example/services/shop/orders-api/service.json +14 -0
- package/examples/tdk-example/services/shop/orders-api/src/index.ts +81 -0
- package/examples/tdk-example/services/shop/orders-app/index.html +12 -0
- package/examples/tdk-example/services/shop/orders-app/package.json +23 -0
- package/examples/tdk-example/services/shop/orders-app/public/.gitkeep +0 -0
- package/examples/tdk-example/services/shop/orders-app/service.json +9 -0
- package/examples/tdk-example/services/shop/orders-app/src/main.tsx +9 -0
- package/examples/tdk-example/services/shop/orders-app/src/orders.tsx +67 -0
- package/examples/tdk-example/services/shop/orders-app/src/style.css +15 -0
- package/examples/tdk-example/services/shop/orders-worker/package.json +18 -0
- package/examples/tdk-example/services/shop/orders-worker/service.json +13 -0
- package/examples/tdk-example/services/shop/orders-worker/src/index.ts +33 -0
- package/ext/Tiltfile +66 -0
- package/ext/ide-components/README.md +221 -0
- package/ext/ide-components/code_viewer/server.py +208 -0
- package/ext/ide-components/config_inspector/server.py +1052 -0
- package/ext/ide-components/file_browser/server.py +287 -0
- package/ext/ide-components/shared/config_service.py +471 -0
- package/ext/ide-components/shared/file_utils.py +300 -0
- package/ext/ide-components/shared/http_utils.py +234 -0
- package/ext/ide-components/shared/static/styles.css +1334 -0
- package/ext/ide-components/shared/syntax_highlighter.py +142 -0
- package/ext/ide-components/shared/template_engine.py +125 -0
- package/ext/ide-components/shared/templates/base.html +121 -0
- package/ext/ide-components/shared/test_config_service.py +328 -0
- package/ext/ide-components/shared/tilt_integration.py +160 -0
- package/ext/ui-enhancements/cron-status-server.sh +51 -0
- package/ext/ui-enhancements/cron-status-tracker.sh +148 -0
- package/ext/ui-enhancements/extension.yaml +36 -0
- package/ext/ui-enhancements/tiltfile.py +101 -0
- package/ext/ui-enhancements/ui/cron-jobs-tab.css +396 -0
- package/ext/ui-enhancements/ui/help-panel.css +279 -0
- package/ext/ui-enhancements/ui/icons.css +125 -0
- package/ext/ui-enhancements/ui/tooltips.css +114 -0
- package/package.json +94 -4
- package/shared-platform-engineering/docker-templates/bun-hoisted-symlink-fix.sh +25 -0
- package/shared-platform-engineering/docker-templates/infisical-entrypoint.sh +466 -0
- package/shared-platform-engineering/docker-templates/install-deps.sh +154 -0
- package/shared-platform-engineering/docker-templates/prisma-bun-client-link-fix.sh +14 -0
- package/shared-platform-engineering/docker-templates/prisma-normalize-client.sh +58 -0
- package/specs/specs/TILT_SERVICE_DEFAULTS.star +207 -0
- package/specs/specs/TILT_TECH_STACK.star +161 -0
|
@@ -0,0 +1,637 @@
|
|
|
1
|
+
# Copyright (c) 2026 Flisk contributors
|
|
2
|
+
# SPDX-License-Identifier: MIT
|
|
3
|
+
# =============================================================================
|
|
4
|
+
# 🐳 TILT SDK - DOCKER COMPOSE GENERATORS (modular)
|
|
5
|
+
# =============================================================================
|
|
6
|
+
# Path: .tilt/topologies/platform/docker/compose.star
|
|
7
|
+
# Purpose: docker-compose generation helpers extracted from .tilt/providers/docker.star
|
|
8
|
+
# =============================================================================
|
|
9
|
+
|
|
10
|
+
# === INLINED CONSTANTS for pure extension loading ===
|
|
11
|
+
BASE_PORT_FRONTEND = 3000
|
|
12
|
+
BASE_PORT_BACKEND = 4000
|
|
13
|
+
# The nginx frontend runtime layer always serves on 80: L4_generate_frontend_runtime
|
|
14
|
+
# emits a fixed `EXPOSE 80` and the generated nginx.conf has a fixed `listen 80`.
|
|
15
|
+
NGINX_CONTAINER_PORT = 80
|
|
16
|
+
HEALTH_CHECK_PATH = "/health"
|
|
17
|
+
NO_HTTP_HEALTHCHECK = " healthcheck:\n disable: true\n"
|
|
18
|
+
OUTPUT = struct(AUTOGENERATED_FOLDER = ".autogenerated")
|
|
19
|
+
# === END INLINED CONSTANTS ===
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
load("./compose_helpers.star", "compose_build_config")
|
|
23
|
+
load("../networking/traefik.star", "get_frontend_traefik_labels", "get_backend_traefik_labels")
|
|
24
|
+
load("../networking/api_path_constants.star", "get_api_path_for_domain", "get_frontend_base_path")
|
|
25
|
+
load("../secrets/infisical.star", "get_infisical_environment_vars")
|
|
26
|
+
load("../secrets/env_secrets.star", "get_secret_environment_lines")
|
|
27
|
+
load("../auth/auth.star", "AuthConfig")
|
|
28
|
+
|
|
29
|
+
load("../constants.star", "PlatformDockerConstants")
|
|
30
|
+
load("../config/healthcheck.star", "DOCKER_HEALTHCHECK", "compose_healthcheck_timing")
|
|
31
|
+
|
|
32
|
+
# Load project name for dynamic host naming
|
|
33
|
+
# Use TDK_PROJECT_ROOT env var set by Tilt, fallback to current directory
|
|
34
|
+
def _load_project_name():
|
|
35
|
+
project_root = os.environ.get('TDK_PROJECT_ROOT', '')
|
|
36
|
+
project_json_path = '.tdk/project.json'
|
|
37
|
+
if project_root:
|
|
38
|
+
project_json_path = project_root + '/' + project_json_path
|
|
39
|
+
|
|
40
|
+
if os.path.exists(project_json_path):
|
|
41
|
+
_project_json = read_json(project_json_path)
|
|
42
|
+
return _project_json.get('project', {}).get('name', 'tdk-project')
|
|
43
|
+
return 'tdk-project'
|
|
44
|
+
|
|
45
|
+
_PROJECT_NAME = _load_project_name()
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _compute_env_file_rel_path(resource_path, full_resource_path, env_filename):
|
|
49
|
+
"""
|
|
50
|
+
Compute the relative path from compose file location to env file.
|
|
51
|
+
|
|
52
|
+
The compose file is at: resource_path + '/' + OUTPUT.AUTOGENERATED_FOLDER/docker-compose.app.autogenerated.yml'
|
|
53
|
+
The env file is at: full_resource_path + '/' + OUTPUT.AUTOGENERATED_FOLDER + '/' + env_filename
|
|
54
|
+
|
|
55
|
+
Args:
|
|
56
|
+
resource_path: The domain/service group path (e.g., 'services/product/users' or 'services/platform')
|
|
57
|
+
full_resource_path: The actual service path (e.g., 'services/product/users/user-management-backend' or 'shared-platform-engineering/my-lib/infra')
|
|
58
|
+
env_filename: The env file name (e.g., '.env.frontend.autogenerated' or '.env.backend.autogenerated')
|
|
59
|
+
|
|
60
|
+
Returns:
|
|
61
|
+
Relative path from compose file to env file
|
|
62
|
+
"""
|
|
63
|
+
# Count how many levels deep the compose file is
|
|
64
|
+
# resource_path like 'services/product/users' has 3 parts
|
|
65
|
+
# compose file is at resource_path + '/' + OUTPUT.AUTOGENERATED_FOLDER + '/', so we need len(parts) + 1 levels of ../
|
|
66
|
+
resource_path_parts = resource_path.split('/')
|
|
67
|
+
num_dotdots = len(resource_path_parts) + 1 # +1 for the autogenerated directory
|
|
68
|
+
|
|
69
|
+
# Build the dotdot prefix
|
|
70
|
+
dotdot_prefix = '/'.join(['..'] * num_dotdots)
|
|
71
|
+
|
|
72
|
+
# The env file is at full_resource_path + '/' + OUTPUT.AUTOGENERATED_FOLDER + '/' + env_filename
|
|
73
|
+
return dotdot_prefix + '/' + full_resource_path + '/' + OUTPUT.AUTOGENERATED_FOLDER + '/' + env_filename
|
|
74
|
+
|
|
75
|
+
# =============================================================================
|
|
76
|
+
# 🚦 FRONTEND / BACKEND ENTRIES
|
|
77
|
+
# =============================================================================
|
|
78
|
+
|
|
79
|
+
def generate_frontend_compose(resource_path, resource_name, res, manifest=None):
|
|
80
|
+
"""Generate frontend docker-compose entry with Traefik routing."""
|
|
81
|
+
res_name = res['name']
|
|
82
|
+
image_name = PlatformDockerConstants.app_image_name(resource_name, res_name)
|
|
83
|
+
stack = manifest.get('stack', resource_name) if manifest else resource_name
|
|
84
|
+
|
|
85
|
+
target_path = res.get('target_path', manifest.get('target_path', '/usr/share/nginx/html'))
|
|
86
|
+
use_nginx = 'nginx' in target_path or target_path == '/usr/share/nginx/html'
|
|
87
|
+
# The manifest `port` is the Vite dev-server port. These compose entries always
|
|
88
|
+
# build the `production` target, so for an nginx runtime the port inside the
|
|
89
|
+
# container is 80, not the dev port. Using the dev port here made the container
|
|
90
|
+
# healthcheck probe a port nothing listens on, which left the container marked
|
|
91
|
+
# unhealthy -- and Traefik's Docker provider skips unhealthy containers, so the
|
|
92
|
+
# router was never registered and every request 404'd.
|
|
93
|
+
port = NGINX_CONTAINER_PORT if use_nginx else manifest.get('port', BASE_PORT_FRONTEND)
|
|
94
|
+
|
|
95
|
+
# Base path for routing on {project}.localhost. Shared with the Vite config and
|
|
96
|
+
# PUBLIC_URL generators -- see get_frontend_base_path for why they must agree.
|
|
97
|
+
base_path = get_frontend_base_path(manifest, res_name)
|
|
98
|
+
|
|
99
|
+
traefik_cfg = manifest.get('traefik', {}) if manifest else {}
|
|
100
|
+
traefik_host = traefik_cfg.get('host')
|
|
101
|
+
# Use custom dockerfile from manifest if specified, otherwise use autogenerated default
|
|
102
|
+
dockerfile_path = res.get('dockerfile', OUTPUT.AUTOGENERATED_FOLDER + '/Dockerfile.app.autogenerated')
|
|
103
|
+
# Handle flat service structure (e.g., services/product/identity-management-frontend) vs nested (services/product/domain/service)
|
|
104
|
+
# Detect flat structure: services/product/{service} (3 path parts after root)
|
|
105
|
+
# vs nested: services/product/{domain}/{service} (4+ path parts)
|
|
106
|
+
full_resource_path = res.get('_resource_path', resource_path + '/' + res_name)
|
|
107
|
+
path_parts = full_resource_path.split('/')
|
|
108
|
+
# If path is like services/product/xxx (3 parts), it's flat - use path directly
|
|
109
|
+
# If path is like services/product/domain/xxx (4 parts), it's nested - use standard construction
|
|
110
|
+
if len(path_parts) <= 3:
|
|
111
|
+
# Flat structure: resource_path already includes res_name
|
|
112
|
+
build_config = compose_build_config(full_resource_path, '', dockerfile_path, 'production')
|
|
113
|
+
else:
|
|
114
|
+
# Nested structure: use resource_path and res_name separately
|
|
115
|
+
build_config = compose_build_config(resource_path, res_name, dockerfile_path, 'production')
|
|
116
|
+
|
|
117
|
+
# Calculate correct relative path to env_file from compose file location
|
|
118
|
+
# The compose file is at: resource_path + '/' + OUTPUT.AUTOGENERATED_FOLDER/docker-compose.app.autogenerated.yml'
|
|
119
|
+
# The env file is at: full_resource_path + '/' + OUTPUT.AUTOGENERATED_FOLDER/.env.frontend.autogenerated'
|
|
120
|
+
env_file_rel_path = _compute_env_file_rel_path(resource_path, full_resource_path, '.env.frontend.autogenerated')
|
|
121
|
+
|
|
122
|
+
traefik_labels = get_frontend_traefik_labels(
|
|
123
|
+
res_name,
|
|
124
|
+
stack,
|
|
125
|
+
base_path,
|
|
126
|
+
port,
|
|
127
|
+
traefik_host=traefik_host,
|
|
128
|
+
manifest=manifest,
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
return """ {res_name}:
|
|
132
|
+
image: {image_name}
|
|
133
|
+
init: true
|
|
134
|
+
{build_config}
|
|
135
|
+
<<: *frontend-memory-limit
|
|
136
|
+
env_file:
|
|
137
|
+
- {env_file_rel_path}
|
|
138
|
+
environment:
|
|
139
|
+
- VITE_APP_ENV=development
|
|
140
|
+
labels:
|
|
141
|
+
{traefik_labels}
|
|
142
|
+
networks:
|
|
143
|
+
- {network_traefik_public}
|
|
144
|
+
- {network_backend}
|
|
145
|
+
healthcheck:
|
|
146
|
+
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://127.0.0.1:{port}"]
|
|
147
|
+
{healthcheck_timing}""".format(
|
|
148
|
+
res_name=res_name,
|
|
149
|
+
image_name=image_name,
|
|
150
|
+
build_config=build_config,
|
|
151
|
+
env_file_rel_path=env_file_rel_path,
|
|
152
|
+
traefik_labels=traefik_labels,
|
|
153
|
+
port=port,
|
|
154
|
+
network_traefik_public=PlatformDockerConstants.NETWORK_TRAEFIK_PUBLIC,
|
|
155
|
+
network_backend=PlatformDockerConstants.NETWORK_BACKEND,
|
|
156
|
+
healthcheck_timing=compose_healthcheck_timing(DOCKER_HEALTHCHECK["frontend_start_period_seconds"]),
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def _generate_single_backend_entry(resource_path, resource_name, res, manifest, instance_id=None):
|
|
161
|
+
"""
|
|
162
|
+
Generate a single backend docker-compose entry.
|
|
163
|
+
"""
|
|
164
|
+
res_name = res['name']
|
|
165
|
+
stack = manifest.get('stack', resource_name) if manifest else resource_name
|
|
166
|
+
|
|
167
|
+
# Get full service path from resource (for cross-root service support)
|
|
168
|
+
full_resource_path = res.get('_resource_path', resource_path + '/' + res_name)
|
|
169
|
+
|
|
170
|
+
# Calculate correct relative path to env_file from compose file location
|
|
171
|
+
env_file_rel_path = _compute_env_file_rel_path(resource_path, full_resource_path, '.env.backend.autogenerated')
|
|
172
|
+
|
|
173
|
+
internal_port = manifest.get('port', BASE_PORT_BACKEND) if manifest else BASE_PORT_BACKEND
|
|
174
|
+
dev_port = internal_port
|
|
175
|
+
# Use PROJECT_NAME from PlatformDockerConstants for portable database naming
|
|
176
|
+
_db_prefix = PlatformDockerConstants.PROJECT_NAME + "_"
|
|
177
|
+
db_name = manifest.get('databaseName', _db_prefix + stack) if manifest else _db_prefix + stack
|
|
178
|
+
|
|
179
|
+
# Compute database URLs using centralized constants
|
|
180
|
+
db_url_for_tilt = PlatformDockerConstants.get_database_url_for_env(db_name)
|
|
181
|
+
db_url_with_fallback = PlatformDockerConstants.get_compose_env_database_url(db_name)
|
|
182
|
+
|
|
183
|
+
health_path = manifest.get('healthCheckPath', HEALTH_CHECK_PATH) if manifest else HEALTH_CHECK_PATH
|
|
184
|
+
# A bring-your-own service without healthCheckPath may not serve HTTP. None means no HTTP probe: no Traefik health check labels.
|
|
185
|
+
if manifest and manifest.get('appType') == 'bring-your-own' and not manifest.get('healthCheckPath'):
|
|
186
|
+
health_path = None
|
|
187
|
+
|
|
188
|
+
traefik_cfg = manifest.get('traefik', {}) if manifest else {}
|
|
189
|
+
traefik_host = traefik_cfg.get('host', stack + '.backend.' + _PROJECT_NAME + '.local')
|
|
190
|
+
# ALPHA: Use proper API v1 path with -management suffix via api_path_constants
|
|
191
|
+
# Old default: '/api/' + stack
|
|
192
|
+
# New default: get_api_path_for_domain → /api/v1/{stack}-management
|
|
193
|
+
traefik_path = traefik_cfg.get('pathPrefix', get_api_path_for_domain(stack, manifest))
|
|
194
|
+
|
|
195
|
+
nats_cfg = manifest.get('nats', {}) if manifest else {}
|
|
196
|
+
nats_queue = nats_cfg.get('queueGroup', stack + '_backend_svc')
|
|
197
|
+
nats_url = PlatformDockerConstants.NATS_URL
|
|
198
|
+
|
|
199
|
+
# Auth configuration: one shared builder keeps this identical to the generated env file (see AuthConfig.from_manifest).
|
|
200
|
+
auth_config = AuthConfig.from_manifest(manifest)
|
|
201
|
+
|
|
202
|
+
auth_env = AuthConfig.generate_docker_compose_auth_env(auth_config)
|
|
203
|
+
# secrets.required / secrets.optional, read from the project .env by Compose (empty with TDK_SECRET_PROVIDER=infisical)
|
|
204
|
+
secrets_env = get_secret_environment_lines(manifest, res_name)
|
|
205
|
+
|
|
206
|
+
# Use .autogenerated/Dockerfile.app.autogenerated by default for build config (primary only)
|
|
207
|
+
if manifest and manifest.get('appType') == 'bring-your-own':
|
|
208
|
+
if manifest.get('image'):
|
|
209
|
+
build_config = ""
|
|
210
|
+
else:
|
|
211
|
+
# A BYO Dockerfile copies paths relative to the service directory
|
|
212
|
+
# (for example, `COPY app.py .`). Build with that directory as the
|
|
213
|
+
# context instead of the project root used by generated Flisk apps.
|
|
214
|
+
context_prefix = '/'.join(['..'] * (len(resource_path.split('/')) + 1))
|
|
215
|
+
build_context = context_prefix + '/' + full_resource_path
|
|
216
|
+
# `buildContext` (relative to the service directory) moves the context
|
|
217
|
+
# to the source tree an imported Dockerfile lives in; `dockerfile` is then
|
|
218
|
+
# relative to that context, as in Compose.
|
|
219
|
+
custom_context = manifest.get('buildContext')
|
|
220
|
+
if custom_context and custom_context != '.':
|
|
221
|
+
build_context = build_context + '/' + custom_context
|
|
222
|
+
dockerfile = manifest.get('dockerfile', 'Dockerfile')
|
|
223
|
+
if dockerfile.startswith('./'):
|
|
224
|
+
dockerfile = dockerfile[2:]
|
|
225
|
+
build_config = """ build:
|
|
226
|
+
context: {build_context}
|
|
227
|
+
dockerfile: {dockerfile}""".format(
|
|
228
|
+
build_context=build_context,
|
|
229
|
+
dockerfile=dockerfile,
|
|
230
|
+
)
|
|
231
|
+
else:
|
|
232
|
+
build_config = compose_build_config(resource_path, res_name)
|
|
233
|
+
|
|
234
|
+
# REMOVED: External port exposure - all services accessed via Traefik only
|
|
235
|
+
# Services are available at {project}.localhost/api/v1/{service}
|
|
236
|
+
# Inside the Docker network a service listens on its own port (manifest.port, passed to it as PORT), for service-to-service calls
|
|
237
|
+
ports_section = "" # No external ports - Traefik-only access
|
|
238
|
+
|
|
239
|
+
# Determine service name based on instance
|
|
240
|
+
if instance_id:
|
|
241
|
+
# Replica instance: add instance suffix
|
|
242
|
+
resource_entry_name = res_name + '-' + str(instance_id)
|
|
243
|
+
instance_label = str(instance_id)
|
|
244
|
+
# Replicas should reuse the already-built image; avoid per-replica builds
|
|
245
|
+
build_config = ""
|
|
246
|
+
else:
|
|
247
|
+
# Primary instance
|
|
248
|
+
resource_entry_name = res_name
|
|
249
|
+
instance_label = '0'
|
|
250
|
+
|
|
251
|
+
# All instances share the same Traefik service for load balancing
|
|
252
|
+
traefik_resource_name = res_name # LB service name (shared)
|
|
253
|
+
|
|
254
|
+
# Workers have no HTTP server: they consume from NATS and exit-on-crash. Giving
|
|
255
|
+
# them a Traefik route advertises an endpoint that can never answer, and giving
|
|
256
|
+
# them an HTTP healthcheck marks a perfectly healthy worker as unhealthy forever.
|
|
257
|
+
is_worker = manifest.get('appType') == 'worker' if manifest else False
|
|
258
|
+
is_byo = manifest.get('appType') == 'bring-your-own' if manifest else False
|
|
259
|
+
is_proxy_disabled_byo = (
|
|
260
|
+
is_byo and not manifest.get('exposeViaProxy', True)
|
|
261
|
+
) if manifest else False
|
|
262
|
+
|
|
263
|
+
# One-shot jobs (migrations, seeders) must not be restarted after they exit 0, so a
|
|
264
|
+
# bring-your-own resource can choose its Compose restart policy. Default is unchanged.
|
|
265
|
+
restart_policy = 'unless-stopped'
|
|
266
|
+
if is_byo and manifest.get('restart') in ['no', 'on-failure', 'unless-stopped', 'always']:
|
|
267
|
+
restart_policy = manifest.get('restart')
|
|
268
|
+
restart_policy = '"no"' if restart_policy == 'no' else restart_policy
|
|
269
|
+
|
|
270
|
+
# No HTTP server means no HTTP probe. Disable explicitly: the image HEALTHCHECK would otherwise probe a port nothing listens on.
|
|
271
|
+
no_http_healthcheck_section = NO_HTTP_HEALTHCHECK if (is_worker or health_path == None) else ""
|
|
272
|
+
# Backends with a health path get it in the env, so the shared golden image's HEALTHCHECK can probe it.
|
|
273
|
+
health_env = " - TDK_HEALTH_PATH={}\n".format(health_path) if health_path else ""
|
|
274
|
+
# An agent with files durability keeps its session checkpoints in a named volume. The volume is declared at the top of the
|
|
275
|
+
# generated file (generate_app_compose_from_entries reads the marker line below), so flisk down keeps it.
|
|
276
|
+
agent_env = ""
|
|
277
|
+
agent_volume_section = ""
|
|
278
|
+
if manifest and type(manifest.get('agent')) == 'dict':
|
|
279
|
+
agent_durability = manifest['agent'].get('durability', 'files')
|
|
280
|
+
agent_env = " - AGENT_DURABILITY={}\n".format(agent_durability)
|
|
281
|
+
if agent_durability == 'files':
|
|
282
|
+
agent_volume = res_name + '-agent-state'
|
|
283
|
+
agent_env += " - AGENT_STATE_DIR=/var/lib/tdk-agent\n"
|
|
284
|
+
agent_volume_section = " # tdk-agent-volume: {vol}\n volumes:\n - {vol}:/var/lib/tdk-agent\n".format(vol=agent_volume)
|
|
285
|
+
|
|
286
|
+
if is_worker or is_proxy_disabled_byo:
|
|
287
|
+
traefik_labels = ' - "traefik.enable=false"'
|
|
288
|
+
healthcheck_section = no_http_healthcheck_section
|
|
289
|
+
else:
|
|
290
|
+
# Traefik's load-balancer check can be overridden separately in service.json
|
|
291
|
+
# (`traefik.healthCheck`); it defaults to the container check's path.
|
|
292
|
+
traefik_health_path = traefik_cfg.get('healthCheck') or health_path
|
|
293
|
+
traefik_labels = get_backend_traefik_labels(
|
|
294
|
+
resource_entry_name=resource_entry_name,
|
|
295
|
+
traefik_host=traefik_host,
|
|
296
|
+
traefik_path=traefik_path,
|
|
297
|
+
traefik_resource_name=traefik_resource_name,
|
|
298
|
+
internal_port=internal_port,
|
|
299
|
+
health_path=traefik_health_path,
|
|
300
|
+
manifest=manifest,
|
|
301
|
+
)
|
|
302
|
+
# BYO images may not contain curl. Traefik uses its own HTTP health
|
|
303
|
+
# check labels above, so don't mark an otherwise healthy container
|
|
304
|
+
# unhealthy because the image lacks a command Flisk cannot require.
|
|
305
|
+
healthcheck_section = no_http_healthcheck_section if no_http_healthcheck_section else "" if is_byo else """ healthcheck:
|
|
306
|
+
test: ["CMD", "curl", "-f", "--max-time", "5", "http://localhost:{internal_port}{health_path}"]
|
|
307
|
+
""".format(internal_port=internal_port, health_path=health_path) + compose_healthcheck_timing()
|
|
308
|
+
infisical_env = get_infisical_environment_vars(as_array=True, resource_name=res_name)
|
|
309
|
+
|
|
310
|
+
# Build auth environment variables section using centralized auth utilities
|
|
311
|
+
|
|
312
|
+
return """
|
|
313
|
+
{resource_entry_name}:
|
|
314
|
+
image: {image_name}
|
|
315
|
+
init: true
|
|
316
|
+
restart: {restart_policy}
|
|
317
|
+
{build_config}
|
|
318
|
+
{ports_section}
|
|
319
|
+
env_file:
|
|
320
|
+
- {env_file_rel_path}
|
|
321
|
+
environment:
|
|
322
|
+
{infisical_env}
|
|
323
|
+
- RESOURCE_NAME={stack}
|
|
324
|
+
- PORT={port_anchor}
|
|
325
|
+
{health_env}{agent_env} - INSTANCE_ID={instance_label}
|
|
326
|
+
- NATS_QUEUE_GROUP={nats_queue}
|
|
327
|
+
- TILT_DATABASE_URL={db_url_for_tilt}
|
|
328
|
+
- TILT_NATS_URL={nats_url}
|
|
329
|
+
- NODE_ENV=development
|
|
330
|
+
- DATABASE_URL={db_url_for_tilt}
|
|
331
|
+
# Per-project escape hatch: set AUTO_MIGRATE=false in the project root .env
|
|
332
|
+
# to skip Prisma auto-migration at container boot (e.g. while diagnosing a
|
|
333
|
+
# migration/CLI issue) without touching the generator or any service code.
|
|
334
|
+
- AUTO_MIGRATE=${{AUTO_MIGRATE:-true}}
|
|
335
|
+
{auth_env}{secrets_env}
|
|
336
|
+
{agent_volume_section} labels:
|
|
337
|
+
{traefik_labels}
|
|
338
|
+
networks:
|
|
339
|
+
- {network_traefik_public}
|
|
340
|
+
- {network_backend}
|
|
341
|
+
- {network_database}
|
|
342
|
+
- {network_infisical}
|
|
343
|
+
{healthcheck_section} # Note: depends_on removed - Tilt manages service startup order
|
|
344
|
+
deploy:
|
|
345
|
+
resources:
|
|
346
|
+
limits:
|
|
347
|
+
cpus: '0.5'
|
|
348
|
+
memory: 512M
|
|
349
|
+
reservations:
|
|
350
|
+
cpus: '0.2'
|
|
351
|
+
memory: 256M
|
|
352
|
+
""".format(
|
|
353
|
+
resource_entry_name=resource_entry_name,
|
|
354
|
+
res_name=res_name,
|
|
355
|
+
resource_name=resource_name,
|
|
356
|
+
image_name=(
|
|
357
|
+
manifest.get('image')
|
|
358
|
+
if manifest and manifest.get('appType') == 'bring-your-own' and manifest.get('image')
|
|
359
|
+
else PlatformDockerConstants.app_image_name(resource_name, res_name)
|
|
360
|
+
),
|
|
361
|
+
build_config=build_config,
|
|
362
|
+
ports_section=ports_section,
|
|
363
|
+
env_file_rel_path=env_file_rel_path,
|
|
364
|
+
stack=stack,
|
|
365
|
+
internal_port=internal_port,
|
|
366
|
+
port_anchor=internal_port,
|
|
367
|
+
restart_policy=restart_policy,
|
|
368
|
+
dev_port=dev_port,
|
|
369
|
+
db_name=db_name,
|
|
370
|
+
db_url_for_tilt=db_url_for_tilt,
|
|
371
|
+
db_url_with_fallback=db_url_with_fallback,
|
|
372
|
+
instance_label=instance_label,
|
|
373
|
+
health_path=health_path,
|
|
374
|
+
traefik_host=traefik_host,
|
|
375
|
+
traefik_path=traefik_path,
|
|
376
|
+
traefik_resource_name=traefik_resource_name,
|
|
377
|
+
nats_queue=nats_queue,
|
|
378
|
+
nats_url=nats_url,
|
|
379
|
+
traefik_labels=traefik_labels,
|
|
380
|
+
healthcheck_section=healthcheck_section,
|
|
381
|
+
health_env=health_env,
|
|
382
|
+
agent_env=agent_env,
|
|
383
|
+
agent_volume_section=agent_volume_section,
|
|
384
|
+
infisical_env=infisical_env,
|
|
385
|
+
auth_env=auth_env,
|
|
386
|
+
secrets_env=secrets_env,
|
|
387
|
+
network_traefik_public=PlatformDockerConstants.NETWORK_TRAEFIK_PUBLIC,
|
|
388
|
+
network_backend=PlatformDockerConstants.NETWORK_BACKEND,
|
|
389
|
+
network_database=PlatformDockerConstants.NETWORK_DATABASE,
|
|
390
|
+
network_infisical=PlatformDockerConstants.NETWORK_INFISICAL,
|
|
391
|
+
)
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
def generate_backend_compose_entry(resource_path, resource_name, res, manifest=None):
|
|
395
|
+
"""
|
|
396
|
+
Generate backend docker-compose entries with TRUE multi-replica support.
|
|
397
|
+
"""
|
|
398
|
+
replicas = manifest.get('replicas', 1) if manifest else 1
|
|
399
|
+
|
|
400
|
+
if replicas <= 1:
|
|
401
|
+
# Single instance - simple case
|
|
402
|
+
return _generate_single_backend_entry(resource_path, resource_name, res, manifest, instance_id=None)
|
|
403
|
+
|
|
404
|
+
# Multi-replica: generate separate service entries
|
|
405
|
+
entries = []
|
|
406
|
+
|
|
407
|
+
# Primary instance (gets the port mapping)
|
|
408
|
+
entries.append(_generate_single_backend_entry(resource_path, resource_name, res, manifest, instance_id=None))
|
|
409
|
+
|
|
410
|
+
# Additional replicas (numbered, expose only)
|
|
411
|
+
for i in range(1, replicas):
|
|
412
|
+
entries.append(_generate_single_backend_entry(resource_path, resource_name, res, manifest, instance_id=i))
|
|
413
|
+
|
|
414
|
+
return ''.join(entries)
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
def _generate_port_anchors(resource_entries):
|
|
418
|
+
"""Extract unique ports and generate YAML anchors for them."""
|
|
419
|
+
backend_port = None
|
|
420
|
+
frontend_port = None
|
|
421
|
+
sdk_port = None
|
|
422
|
+
has_backend = False
|
|
423
|
+
has_sdk = False
|
|
424
|
+
has_frontend = False
|
|
425
|
+
|
|
426
|
+
for entry in resource_entries:
|
|
427
|
+
# Check if this is an SDK (ends with -sdk)
|
|
428
|
+
if "-sdk:" in entry or entry.strip().startswith("identity-sdk:"):
|
|
429
|
+
has_sdk = True
|
|
430
|
+
# Extract SDK port from entry
|
|
431
|
+
if "loadbalancer.server.port=" in entry:
|
|
432
|
+
for line in entry.split("\n"):
|
|
433
|
+
if "loadbalancer.server.port=" in line:
|
|
434
|
+
# Safe parsing without try/except
|
|
435
|
+
port_str = line.split("loadbalancer.server.port=")[-1].split('"')[0]
|
|
436
|
+
if port_str.isdigit():
|
|
437
|
+
sdk_port = int(port_str)
|
|
438
|
+
break
|
|
439
|
+
# Check if this is a frontend (has frontend-memory-limit but not SDK)
|
|
440
|
+
elif "<<: *frontend-memory-limit" in entry and not ("-sdk:" in entry or entry.strip().startswith("identity-sdk:")):
|
|
441
|
+
has_frontend = True
|
|
442
|
+
# Extract frontend port from entry
|
|
443
|
+
if "loadbalancer.server.port=" in entry:
|
|
444
|
+
for line in entry.split("\n"):
|
|
445
|
+
if "loadbalancer.server.port=" in line:
|
|
446
|
+
# Safe parsing without try/except
|
|
447
|
+
port_str = line.split("loadbalancer.server.port=")[-1].split('"')[0]
|
|
448
|
+
if port_str.isdigit():
|
|
449
|
+
frontend_port = int(port_str)
|
|
450
|
+
break
|
|
451
|
+
# Check if this is a backend (has a port, not frontend, not SDK)
|
|
452
|
+
# Backend entries have "healthcheck:" section with backend port
|
|
453
|
+
elif "healthcheck:" in entry and "<<: *frontend-memory-limit" not in entry and not ("-sdk:" in entry or entry.strip().startswith("identity-sdk:")):
|
|
454
|
+
has_backend = True
|
|
455
|
+
# Extract backend port from entry
|
|
456
|
+
if "loadbalancer.server.port=" in entry:
|
|
457
|
+
for line in entry.split("\n"):
|
|
458
|
+
if "loadbalancer.server.port=" in line:
|
|
459
|
+
# Safe parsing without try/except
|
|
460
|
+
port_str = line.split("loadbalancer.server.port=")[-1].split('"')[0]
|
|
461
|
+
if port_str.isdigit():
|
|
462
|
+
backend_port = int(port_str)
|
|
463
|
+
break
|
|
464
|
+
|
|
465
|
+
# Build anchors - use extracted port or fall back to default
|
|
466
|
+
anchors = []
|
|
467
|
+
anchors.append("x-backend-port: &backend-port {}".format(backend_port if backend_port else BASE_PORT_BACKEND))
|
|
468
|
+
if has_frontend and frontend_port:
|
|
469
|
+
anchors.append("x-frontend-port: &frontend-port {}".format(frontend_port))
|
|
470
|
+
if has_sdk and sdk_port:
|
|
471
|
+
anchors.append("x-sdk-port: &sdk-port {}".format(sdk_port))
|
|
472
|
+
|
|
473
|
+
return "\n".join(anchors)
|
|
474
|
+
|
|
475
|
+
|
|
476
|
+
def generate_app_compose_from_entries(resource_path, resource_entries, write_fn=None):
|
|
477
|
+
"""Generate docker-compose.app.autogenerated.yml from service entries with port anchors.
|
|
478
|
+
|
|
479
|
+
Args:
|
|
480
|
+
resource_path: Path to the resource directory
|
|
481
|
+
resource_entries: List of docker-compose entries for services
|
|
482
|
+
write_fn: Optional write function for file output
|
|
483
|
+
|
|
484
|
+
Returns:
|
|
485
|
+
str: Generated docker-compose YAML content
|
|
486
|
+
"""
|
|
487
|
+
|
|
488
|
+
# Generate port anchors
|
|
489
|
+
port_anchors = _generate_port_anchors(resource_entries)
|
|
490
|
+
|
|
491
|
+
header = """###############################################################################
|
|
492
|
+
# 🛑 CRITICAL: SYSTEM-GENERATED FILE - DO NOT MODIFY DIRECTLY
|
|
493
|
+
#
|
|
494
|
+
# ANY MANUAL CHANGES MADE TO THIS FILE WILL BE WIPED ON THE NEXT 'tilt up'.
|
|
495
|
+
# Generation Source: .tilt/topologies/platform/docker/index.star
|
|
496
|
+
###############################################################################
|
|
497
|
+
|
|
498
|
+
# =============================================================================
|
|
499
|
+
# PORT DEFINITIONS - Change these to change ports everywhere
|
|
500
|
+
# =============================================================================
|
|
501
|
+
{port_anchors}
|
|
502
|
+
|
|
503
|
+
# =============================================================================
|
|
504
|
+
# MEMORY LIMITS
|
|
505
|
+
# =============================================================================
|
|
506
|
+
x-nix-any-m1-arm64-memory-limit: &nix-any-m1-arm64-memory-limit
|
|
507
|
+
deploy:
|
|
508
|
+
resources:
|
|
509
|
+
limits:
|
|
510
|
+
memory: 192M
|
|
511
|
+
reservations:
|
|
512
|
+
memory: 64M
|
|
513
|
+
|
|
514
|
+
x-frontend-memory-limit: &frontend-memory-limit
|
|
515
|
+
deploy:
|
|
516
|
+
resources:
|
|
517
|
+
limits:
|
|
518
|
+
memory: 64M
|
|
519
|
+
cpus: '0.15'
|
|
520
|
+
reservations:
|
|
521
|
+
memory: 32M
|
|
522
|
+
|
|
523
|
+
services:
|
|
524
|
+
""".format(port_anchors=port_anchors)
|
|
525
|
+
|
|
526
|
+
# Named volumes used by services (agent session state) must be declared at the top level. Services mark them with a
|
|
527
|
+
# "# tdk-agent-volume: <name>" line, so the declaration follows the services without a separate registry.
|
|
528
|
+
volume_names = []
|
|
529
|
+
for entry in resource_entries:
|
|
530
|
+
for line in entry.split("\n"):
|
|
531
|
+
if line.strip().startswith("# tdk-agent-volume: "):
|
|
532
|
+
name = line.strip()[len("# tdk-agent-volume: "):]
|
|
533
|
+
# Replicas of one agent repeat the marker; Compose rejects a duplicate key under volumes:.
|
|
534
|
+
if name not in volume_names:
|
|
535
|
+
volume_names.append(name)
|
|
536
|
+
volumes_section = ""
|
|
537
|
+
if volume_names:
|
|
538
|
+
volumes_section = "\nvolumes:\n" + "".join([" {}:\n".format(name) for name in volume_names])
|
|
539
|
+
|
|
540
|
+
footer = """
|
|
541
|
+
networks:
|
|
542
|
+
{network_traefik_public}:
|
|
543
|
+
external: true
|
|
544
|
+
{network_backend}:
|
|
545
|
+
external: true
|
|
546
|
+
{network_database}:
|
|
547
|
+
external: true
|
|
548
|
+
{network_infisical}:
|
|
549
|
+
external: true
|
|
550
|
+
{volumes_section}""".format(
|
|
551
|
+
network_traefik_public=PlatformDockerConstants.NETWORK_TRAEFIK_PUBLIC,
|
|
552
|
+
network_backend=PlatformDockerConstants.NETWORK_BACKEND,
|
|
553
|
+
network_database=PlatformDockerConstants.NETWORK_DATABASE,
|
|
554
|
+
network_infisical=PlatformDockerConstants.NETWORK_INFISICAL,
|
|
555
|
+
volumes_section=volumes_section,
|
|
556
|
+
)
|
|
557
|
+
|
|
558
|
+
content = header + "\n".join(resource_entries) + footer
|
|
559
|
+
|
|
560
|
+
if write_fn:
|
|
561
|
+
compose_path = resource_path + '/' + OUTPUT.AUTOGENERATED_FOLDER + '/docker-compose.app.autogenerated.yml'
|
|
562
|
+
write_fn(compose_path, content)
|
|
563
|
+
|
|
564
|
+
return content
|
|
565
|
+
|
|
566
|
+
|
|
567
|
+
def generate_migrator_compose(resource_path, resource_name, dockerfile_path=None, write_fn=None):
|
|
568
|
+
"""Generate docker-compose for database migrators.
|
|
569
|
+
|
|
570
|
+
Args:
|
|
571
|
+
resource_path: Path to the resource directory
|
|
572
|
+
resource_name: Name of the resource
|
|
573
|
+
dockerfile_path: Optional path to Dockerfile
|
|
574
|
+
write_fn: Optional write function for file output
|
|
575
|
+
|
|
576
|
+
Returns:
|
|
577
|
+
str: Generated docker-compose YAML content
|
|
578
|
+
"""
|
|
579
|
+
migrator_name = resource_name + '-db-migrator'
|
|
580
|
+
image_name = PlatformDockerConstants.migrator_image_name(resource_name)
|
|
581
|
+
|
|
582
|
+
# Use PROJECT_NAME from PlatformDockerConstants for portable database naming
|
|
583
|
+
db_name = PlatformDockerConstants.PROJECT_NAME + '_' + resource_name
|
|
584
|
+
default_db_url = PlatformDockerConstants.get_database_url_for_env(db_name)
|
|
585
|
+
|
|
586
|
+
dockerfile_ref = dockerfile_path if dockerfile_path else resource_path + "/" + OUTPUT.AUTOGENERATED_FOLDER + "/Dockerfile.migrator.autogenerated"
|
|
587
|
+
infisical_env = get_infisical_environment_vars(as_array=False)
|
|
588
|
+
|
|
589
|
+
content = """###############################################################################
|
|
590
|
+
# 🛑 CRITICAL: SYSTEM-GENERATED FILE - DO NOT MODIFY DIRECTLY
|
|
591
|
+
# Generation Source: .tilt/topologies/platform/docker/index.star
|
|
592
|
+
###############################################################################
|
|
593
|
+
# 🔐 Infisical Zero-Code Integration Enabled
|
|
594
|
+
# 🗃️ Database Virtualization: Connects to shared PostgreSQL instance
|
|
595
|
+
services:
|
|
596
|
+
{migrator_name}:
|
|
597
|
+
image: {image_name}
|
|
598
|
+
build:
|
|
599
|
+
context: ../../../.
|
|
600
|
+
dockerfile: {dockerfile_ref}
|
|
601
|
+
target: migrator
|
|
602
|
+
environment:
|
|
603
|
+
{infisical_env}
|
|
604
|
+
RESOURCE_NAME: {resource_name}
|
|
605
|
+
TILT_DATABASE_URL: "{default_db_url}"
|
|
606
|
+
DATABASE_URL: ${{DATABASE_URL:-{default_db_url}}}
|
|
607
|
+
networks:
|
|
608
|
+
- {network_database}
|
|
609
|
+
- {network_backend}
|
|
610
|
+
- {network_infisical}
|
|
611
|
+
restart: "no"
|
|
612
|
+
|
|
613
|
+
networks:
|
|
614
|
+
{network_database}:
|
|
615
|
+
external: true
|
|
616
|
+
{network_backend}:
|
|
617
|
+
external: true
|
|
618
|
+
{network_infisical}:
|
|
619
|
+
external: true
|
|
620
|
+
""".format(
|
|
621
|
+
migrator_name=migrator_name,
|
|
622
|
+
image_name=image_name,
|
|
623
|
+
resource_path=resource_path,
|
|
624
|
+
dockerfile_ref=dockerfile_ref,
|
|
625
|
+
resource_name=resource_name,
|
|
626
|
+
db_name=db_name,
|
|
627
|
+
default_db_url=default_db_url,
|
|
628
|
+
infisical_env=infisical_env,
|
|
629
|
+
network_database=PlatformDockerConstants.NETWORK_DATABASE,
|
|
630
|
+
network_backend=PlatformDockerConstants.NETWORK_BACKEND,
|
|
631
|
+
network_infisical=PlatformDockerConstants.NETWORK_INFISICAL,
|
|
632
|
+
)
|
|
633
|
+
|
|
634
|
+
if write_fn:
|
|
635
|
+
write_fn(resource_path + '/' + OUTPUT.AUTOGENERATED_FOLDER + '/docker-compose.migrator.autogenerated.yml', content)
|
|
636
|
+
|
|
637
|
+
return content
|