@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,121 @@
|
|
|
1
|
+
# Copyright (c) 2026 Flisk Landscape contributors
|
|
2
|
+
# SPDX-License-Identifier: MIT
|
|
3
|
+
"""
|
|
4
|
+
Secret Resolution Shell Fragment
|
|
5
|
+
|
|
6
|
+
Generates the shell script block responsible for resolving DATABASE_URL at
|
|
7
|
+
runtime. Priority order:
|
|
8
|
+
1. Infisical API (when INFISICAL_TOKEN + INFISICAL_PROJECT_ID are present)
|
|
9
|
+
2. Individual DB_* env vars assembled into a connection string
|
|
10
|
+
3. Pre-injected DATABASE_URL (docker-compose / Tilt direct injection)
|
|
11
|
+
|
|
12
|
+
Returns a plain string that is embedded verbatim inside migrate.sh.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
load('../../../../tilt/common/utils_debug.star', 'DEBUG_MODE')
|
|
16
|
+
load(
|
|
17
|
+
'./constants.star',
|
|
18
|
+
'DATABASE_URL_UNSET_CONDITION',
|
|
19
|
+
'DB_URL_COMPONENT_ENV_KEYS',
|
|
20
|
+
'DB_URL_FROM_COMPONENTS',
|
|
21
|
+
'DEFAULT_INFISICAL_URL',
|
|
22
|
+
'INFISICAL_SECRET_ENV_KEYS',
|
|
23
|
+
)
|
|
24
|
+
load('../../../../tilt/generators/infisical/path_manager.star', 'PathManager')
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _export_secret_line(secret_key):
|
|
28
|
+
return (
|
|
29
|
+
" export " + secret_key + "=$(echo \"$RESPONSE\" | jq -r --arg k \"" + secret_key + "\" "
|
|
30
|
+
+ "'.secrets[] | select(.secretKey==$k) | .secretValue' || true)\n"
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _infisical_export_block():
|
|
35
|
+
lines = []
|
|
36
|
+
for secret_key in INFISICAL_SECRET_ENV_KEYS:
|
|
37
|
+
lines.append(_export_secret_line(secret_key))
|
|
38
|
+
return "".join(lines)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def _all_env_present_condition(env_keys):
|
|
42
|
+
checks = []
|
|
43
|
+
for env_key in env_keys:
|
|
44
|
+
checks.append("[ -n \"$" + env_key + "\" ]")
|
|
45
|
+
return " && ".join(checks)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _infisical_fetch_block(log_fetch, log_fetch_ok, log_fetch_fail):
|
|
49
|
+
"""Build the Infisical curl block using Starlark path manager."""
|
|
50
|
+
else_block = (" else\n" + log_fetch_fail + " fi\n") if log_fetch_fail else " fi\n"
|
|
51
|
+
# Use default database subpath from PathManager constants
|
|
52
|
+
default_secret_path = PathManager.RESOURCE_SUBPATHS[0] if PathManager.RESOURCE_SUBPATHS else ""
|
|
53
|
+
# Note: In shell, we use env var with fallback. The actual path resolution
|
|
54
|
+
# happens at runtime, but we document the Starlark-managed path convention here.
|
|
55
|
+
return (
|
|
56
|
+
"if [ -n \"$INFISICAL_TOKEN\" ] && [ -n \"$INFISICAL_PROJECT_ID\" ]; then\n"
|
|
57
|
+
+ log_fetch
|
|
58
|
+
+ " INFISICAL_URL=\"${INFISICAL_API_URL:-${INFISICAL_URL:-" + DEFAULT_INFISICAL_URL + "}}\"\n"
|
|
59
|
+
+ " INFISICAL_ENV=\"${INFISICAL_ENVIRONMENT:-dev}\"\n"
|
|
60
|
+
+ " # Using Starlark-managed path: /services/$RESOURCE_NAME" + default_secret_path + "\n"
|
|
61
|
+
+ " SECRET_PATH=\"${INFISICAL_SECRET_PATH:-/services/$RESOURCE_NAME/database}\"\n"
|
|
62
|
+
+ " RESPONSE=$(curl -s -f -H \"Authorization: Bearer $INFISICAL_TOKEN\" "
|
|
63
|
+
+ "\"${INFISICAL_URL}/api/v3/secrets/raw?environment=${INFISICAL_ENV}"
|
|
64
|
+
+ "&workspaceId=${INFISICAL_PROJECT_ID}&secretPath=${SECRET_PATH}\") || true\n"
|
|
65
|
+
+ " if [ -n \"$RESPONSE\" ]; then\n"
|
|
66
|
+
+ log_fetch_ok
|
|
67
|
+
+ _infisical_export_block()
|
|
68
|
+
+ else_block
|
|
69
|
+
+ "fi\n"
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def _component_url_build_block(log_built):
|
|
74
|
+
"""Build DATABASE_URL from individual DB_* parts when it is absent."""
|
|
75
|
+
components_ready = _all_env_present_condition(DB_URL_COMPONENT_ENV_KEYS)
|
|
76
|
+
return (
|
|
77
|
+
"# Build DATABASE_URL from components if not present\n"
|
|
78
|
+
+ "if " + DATABASE_URL_UNSET_CONDITION + "; then\n"
|
|
79
|
+
+ " if " + components_ready + "; then\n"
|
|
80
|
+
+ " export DATABASE_URL=\"" + DB_URL_FROM_COMPONENTS + "\"\n"
|
|
81
|
+
+ log_built
|
|
82
|
+
+ " fi\n"
|
|
83
|
+
+ "fi\n"
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def _validate_url_block():
|
|
88
|
+
"""Hard-fail when DATABASE_URL is still missing after all attempts."""
|
|
89
|
+
return (
|
|
90
|
+
"if " + DATABASE_URL_UNSET_CONDITION + "; then\n"
|
|
91
|
+
+ " echo \"\\u274c ERROR: DATABASE_URL is not set."
|
|
92
|
+
+ " Set it via Infisical or environment variables.\"\n"
|
|
93
|
+
+ " exit 1\n"
|
|
94
|
+
+ "fi\n"
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def secret_resolution_script():
|
|
99
|
+
"""
|
|
100
|
+
Return the complete shell fragment that resolves DATABASE_URL.
|
|
101
|
+
|
|
102
|
+
Uses DEBUG_MODE to include/suppress verbose log lines.
|
|
103
|
+
"""
|
|
104
|
+
if DEBUG_MODE:
|
|
105
|
+
log_fetch = " echo \"\\U0001f510 Fetching secrets from Infisical...\"\n"
|
|
106
|
+
log_fetch_ok = " echo \"\\u2705 Successfully fetched secrets from Infisical\"\n"
|
|
107
|
+
log_fetch_fail = " echo \"\\u26a0\\ufe0f Infisical did not return secrets (or not reachable)\"\n"
|
|
108
|
+
log_built = " echo \"\\U0001f511 Built DATABASE_URL from components\"\n"
|
|
109
|
+
else:
|
|
110
|
+
log_fetch = ""
|
|
111
|
+
log_fetch_ok = ""
|
|
112
|
+
log_fetch_fail = ""
|
|
113
|
+
log_built = ""
|
|
114
|
+
|
|
115
|
+
return (
|
|
116
|
+
_infisical_fetch_block(log_fetch, log_fetch_ok, log_fetch_fail)
|
|
117
|
+
+ _component_url_build_block(log_built)
|
|
118
|
+
+ _validate_url_block()
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
DEBUG = {}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# Copyright (c) 2026 Flisk contributors
|
|
2
|
+
# SPDX-License-Identifier: MIT
|
|
3
|
+
# =============================================================================
|
|
4
|
+
# 🌐 - API PATH CONSTANTS (Dynamic)
|
|
5
|
+
# =============================================================================
|
|
6
|
+
# API paths are generated dynamically from manifest stack and appName fields
|
|
7
|
+
# No hardcoded resource names - all from service.json
|
|
8
|
+
# =============================================================================
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
# =============================================================================
|
|
13
|
+
# API VERSION AND BASE PATH
|
|
14
|
+
# =============================================================================
|
|
15
|
+
|
|
16
|
+
# === INLINED CONSTANTS for pure extension loading ===
|
|
17
|
+
HEALTH_CHECK_PATH = "/health"
|
|
18
|
+
# === END INLINED CONSTANTS ===
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
API_VERSION_V1 = "v1"
|
|
22
|
+
API_BASE_PATH = "/api"
|
|
23
|
+
|
|
24
|
+
# =============================================================================
|
|
25
|
+
# DYNAMIC API PATH GENERATION
|
|
26
|
+
# =============================================================================
|
|
27
|
+
|
|
28
|
+
def generate_api_path(stack, app_name):
|
|
29
|
+
"""Generate API path from manifest stack and appName.
|
|
30
|
+
|
|
31
|
+
URL Restructuring: Changed from /api/v1/{app-name} to /api/{stack}-management
|
|
32
|
+
This provides clean separation between frontend and backend while removing version from path.
|
|
33
|
+
"""
|
|
34
|
+
# NEW: Use /api/{stack}-management pattern
|
|
35
|
+
# Examples: /api/user-management, /api/order-management
|
|
36
|
+
return "/api/" + stack + "-management"
|
|
37
|
+
|
|
38
|
+
# =============================================================================
|
|
39
|
+
# HELPER FUNCTIONS
|
|
40
|
+
# =============================================================================
|
|
41
|
+
|
|
42
|
+
def _pluralize_stack(stack):
|
|
43
|
+
"""Convert stack to proper plural form.
|
|
44
|
+
|
|
45
|
+
Handles irregular plurals and special cases for platform stacks.
|
|
46
|
+
|
|
47
|
+
Args:
|
|
48
|
+
stack: Singular stack name (e.g., "user", "order", "product")
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
str: Pluralized stack name (e.g., "users", "orders", "products")
|
|
52
|
+
"""
|
|
53
|
+
# Already plural
|
|
54
|
+
if stack.endswith("s"):
|
|
55
|
+
return stack
|
|
56
|
+
|
|
57
|
+
# Special cases - irregular plurals (common English patterns)
|
|
58
|
+
irregulars = {
|
|
59
|
+
"category": "categories",
|
|
60
|
+
"city": "cities",
|
|
61
|
+
"company": "companies",
|
|
62
|
+
"story": "stories",
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if stack in irregulars:
|
|
66
|
+
return irregulars[stack]
|
|
67
|
+
|
|
68
|
+
# Words ending in 'y' (not preceded by a vowel) -> 'ies'
|
|
69
|
+
if stack.endswith("y") and len(stack) > 1 and stack[-2] not in "aeiou":
|
|
70
|
+
return stack[:-1] + "ies"
|
|
71
|
+
|
|
72
|
+
# Words ending in 'ch', 'sh', 'ss', 'x', 'z', 'o' -> add 'es'
|
|
73
|
+
if stack.endswith(("ch", "sh", "ss", "x", "z", "o")):
|
|
74
|
+
return stack + "es"
|
|
75
|
+
|
|
76
|
+
# Default: add 's'
|
|
77
|
+
return stack + "s"
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def get_api_path_for_stack(stack, manifest=None):
|
|
81
|
+
"""Returns the full API path for a service stack.
|
|
82
|
+
|
|
83
|
+
URL Restructuring: Changed from /api/v1/{stack}s to /api/{stack}-management
|
|
84
|
+
This aligns API paths with resource naming conventions.
|
|
85
|
+
|
|
86
|
+
Args:
|
|
87
|
+
stack: Service stack name from manifest.json
|
|
88
|
+
manifest: Optional manifest dict that may contain 'apiPath' override
|
|
89
|
+
|
|
90
|
+
Returns:
|
|
91
|
+
Full API path string (e.g., "/api/user-management")
|
|
92
|
+
Falls back to "/api/{stack}-management" if not found
|
|
93
|
+
Returns apiPath from manifest if explicitly specified
|
|
94
|
+
"""
|
|
95
|
+
# Check for explicit apiPath override in manifest
|
|
96
|
+
if manifest and manifest.get("apiPath"):
|
|
97
|
+
return manifest.get("apiPath")
|
|
98
|
+
|
|
99
|
+
# NEW: Use /api/{stack}-management pattern instead of /api/v1/{pluralized}
|
|
100
|
+
return "/api/" + stack + "-management"
|
|
101
|
+
|
|
102
|
+
# Backwards compatibility alias
|
|
103
|
+
get_api_path_for_domain = get_api_path_for_stack
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def get_frontend_base_path(manifest, res_name=None):
|
|
107
|
+
"""Returns the public route a frontend is served under, e.g. "/floor-app".
|
|
108
|
+
|
|
109
|
+
Single source of truth. Three separate generators need this value and they
|
|
110
|
+
MUST agree, because they are three halves of one route:
|
|
111
|
+
|
|
112
|
+
- compose.star -> the Traefik router rule and its stripprefix middleware
|
|
113
|
+
- vite/frontend -> `base`, which prefixes every asset URL in index.html
|
|
114
|
+
- env.star -> PUBLIC_URL
|
|
115
|
+
|
|
116
|
+
If they disagree the app still "starts" but serves a white page: Traefik
|
|
117
|
+
routes /a, index.html asks for /b/assets/*, and nothing answers. They used
|
|
118
|
+
to default to `stack + 's'`, `'/' + stack + 's'` and `'/' + stack`
|
|
119
|
+
respectively -- three different answers, one of which ("operations" + "s")
|
|
120
|
+
produced the nonsense route /operationss.
|
|
121
|
+
|
|
122
|
+
Defaults to the service name: it is unique per service (a stack with two
|
|
123
|
+
frontends would otherwise collide on one route) and it matches the URL
|
|
124
|
+
`flisk up` prints, so what the CLI advertises is what Traefik serves.
|
|
125
|
+
"""
|
|
126
|
+
base_path = manifest.get('basePath') if manifest else None
|
|
127
|
+
if not base_path:
|
|
128
|
+
base_path = res_name or (manifest.get('appName') if manifest else None) or ''
|
|
129
|
+
if not base_path:
|
|
130
|
+
return ''
|
|
131
|
+
if not base_path.startswith('/'):
|
|
132
|
+
base_path = '/' + base_path
|
|
133
|
+
return base_path
|
|
134
|
+
|
|
135
|
+
def get_api_path_for_resource(resource_name):
|
|
136
|
+
"""Returns the full API path for a resource name.
|
|
137
|
+
|
|
138
|
+
Args:
|
|
139
|
+
resource_name: Resource appName from manifest
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
Full API path string
|
|
143
|
+
"""
|
|
144
|
+
# Extract stack from resource name using pattern matching
|
|
145
|
+
# No hardcoded resource names - all patterns derived from naming conventions
|
|
146
|
+
if "-management-backend" in resource_name:
|
|
147
|
+
stack = resource_name.replace("-management-backend", "")
|
|
148
|
+
elif "-management-frontend" in resource_name:
|
|
149
|
+
stack = resource_name.replace("-management-frontend", "")
|
|
150
|
+
elif "-planner-backend" in resource_name:
|
|
151
|
+
stack = resource_name.replace("-planner-backend", "")
|
|
152
|
+
elif "-planner-frontend" in resource_name:
|
|
153
|
+
stack = resource_name.replace("-planner-frontend", "")
|
|
154
|
+
elif "-backend" in resource_name:
|
|
155
|
+
stack = resource_name.replace("-backend", "")
|
|
156
|
+
elif "-frontend" in resource_name:
|
|
157
|
+
stack = resource_name.replace("-frontend", "")
|
|
158
|
+
else:
|
|
159
|
+
stack = resource_name
|
|
160
|
+
|
|
161
|
+
return get_api_path_for_stack(stack)
|
|
162
|
+
|
|
163
|
+
# Backwards compatibility alias
|
|
164
|
+
get_api_path_for_service = get_api_path_for_resource
|
|
165
|
+
|
|
166
|
+
# Load project name for dynamic localhost domain
|
|
167
|
+
# Use TDK_PROJECT_ROOT env var set by Tilt, fallback to current directory
|
|
168
|
+
def _load_project_localhost():
|
|
169
|
+
project_root = os.environ.get('TDK_PROJECT_ROOT', '')
|
|
170
|
+
project_json_path = '.tdk/project.json'
|
|
171
|
+
if project_root:
|
|
172
|
+
project_json_path = project_root + '/' + project_json_path
|
|
173
|
+
|
|
174
|
+
if os.path.exists(project_json_path):
|
|
175
|
+
_project_json = read_json(project_json_path)
|
|
176
|
+
return _project_json.get('project', {}).get('name', 'tdk-project') + ".localhost"
|
|
177
|
+
return "tdk-project.localhost"
|
|
178
|
+
|
|
179
|
+
_PROJECT_LOCALHOST = _load_project_localhost()
|
|
180
|
+
|
|
181
|
+
def build_traefik_url(api_path, host=None, scheme="http"):
|
|
182
|
+
"""Builds full Traefik gateway URL from API path.
|
|
183
|
+
|
|
184
|
+
Args:
|
|
185
|
+
api_path: API path
|
|
186
|
+
host: Gateway host (default: {project}.localhost from project.json)
|
|
187
|
+
scheme: URL scheme (default: http)
|
|
188
|
+
|
|
189
|
+
Returns:
|
|
190
|
+
Full URL string
|
|
191
|
+
"""
|
|
192
|
+
if host == None:
|
|
193
|
+
host = _PROJECT_LOCALHOST
|
|
194
|
+
return scheme + "://" + host + api_path
|
|
195
|
+
|
|
196
|
+
def build_health_endpoint(api_path, health_path="/health"):
|
|
197
|
+
"""Builds health check endpoint path from API path.
|
|
198
|
+
|
|
199
|
+
Args:
|
|
200
|
+
api_path: API path
|
|
201
|
+
health_path: Health endpoint suffix (default: /health)
|
|
202
|
+
|
|
203
|
+
Returns:
|
|
204
|
+
Full health endpoint path
|
|
205
|
+
"""
|
|
206
|
+
return api_path + health_path
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Copyright (c) 2026 Flisk Landscape contributors
|
|
2
|
+
# SPDX-License-Identifier: MIT
|
|
3
|
+
# =============================================================================
|
|
4
|
+
# On-demand scaling: Sablier + Traefik (free-tier stub)
|
|
5
|
+
# =============================================================================
|
|
6
|
+
# Path: engine/topologies/platform/docker/networking/sablier_container_cycle.star
|
|
7
|
+
# =============================================================================
|
|
8
|
+
# The real generator (Sablier + Traefik label wiring that stops idle
|
|
9
|
+
# containers and wakes them on the next request) is part of a paid Flisk
|
|
10
|
+
# license. When a valid license grants the "sablier" resource,
|
|
11
|
+
# cli/src/generator/template-engine.ts (vendorTdkExtension) overwrites this
|
|
12
|
+
# file with the licensed version fetched via extension-fetch.ts before Tilt
|
|
13
|
+
# loads it. Same function signatures either way, so nothing else in the
|
|
14
|
+
# generator pipeline changes -- every call site just gets "disabled" back
|
|
15
|
+
# for a manifest's `sablier` block until then.
|
|
16
|
+
# =============================================================================
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _sablier_config(_manifest):
|
|
20
|
+
"""Free-tier stub - see module header. Always disabled."""
|
|
21
|
+
return False, "", ""
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def sablier_middleware_suffix(_manifest, _res_name):
|
|
25
|
+
"""Free-tier stub - see module header. Always disabled."""
|
|
26
|
+
return "", False
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def sablier_container_labels(_manifest, _res_name, _indent):
|
|
30
|
+
"""Free-tier stub - see module header. No labels to add."""
|
|
31
|
+
return ""
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
# Copyright (c) 2026 Flisk Landscape contributors
|
|
2
|
+
# SPDX-License-Identifier: MIT
|
|
3
|
+
# =============================================================================
|
|
4
|
+
# 🐳 TILT SDK - TRAEFIK LABELS GENERATOR
|
|
5
|
+
# =============================================================================
|
|
6
|
+
|
|
7
|
+
load(
|
|
8
|
+
"./traefik_constants.star",
|
|
9
|
+
"TRAEFIK_BACKEND_ENABLE_HTTP",
|
|
10
|
+
"TRAEFIK_BACKEND_ENABLE_HTTPS",
|
|
11
|
+
"TRAEFIK_PROJECT_HOST",
|
|
12
|
+
"TRAEFIK_PROJECT_API_HOST",
|
|
13
|
+
"TRAEFIK_DOCKER_NETWORK",
|
|
14
|
+
"TRAEFIK_ENABLE_LABEL",
|
|
15
|
+
"TRAEFIK_FRONTEND_ENABLE_HTTP",
|
|
16
|
+
"TRAEFIK_FRONTEND_ENABLE_HTTPS",
|
|
17
|
+
"TRAEFIK_FRONTEND_PRIORITY_BASE",
|
|
18
|
+
"TRAEFIK_MIDDLEWARE_SUFFIX",
|
|
19
|
+
"TRAEFIK_WEB_ENTRYPOINT",
|
|
20
|
+
"TRAEFIK_WEBSECURE_ENTRYPOINT",
|
|
21
|
+
"TRAEFIK_API_VERSION",
|
|
22
|
+
"TRAEFIK_HEALTHCHECK_INTERVAL",
|
|
23
|
+
"TRAEFIK_HEALTHCHECK_TIMEOUT",
|
|
24
|
+
"TRAEFIK_HEALTHCHECK_RETRIES",
|
|
25
|
+
"TRAEFIK_STARTUP_GRACE_PERIOD",
|
|
26
|
+
"TRAEFIK_API_BASE_PATH",
|
|
27
|
+
)
|
|
28
|
+
load("./traefik_helpers.star",
|
|
29
|
+
"backend_rule",
|
|
30
|
+
"build_entrypoints",
|
|
31
|
+
"cli_api_path",
|
|
32
|
+
"frontend_rule",
|
|
33
|
+
"get_api_path",
|
|
34
|
+
"project_backend_rule",
|
|
35
|
+
)
|
|
36
|
+
load("./sablier_container_cycle.star",
|
|
37
|
+
"sablier_middleware_suffix",
|
|
38
|
+
"sablier_container_labels",
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def get_frontend_traefik_labels(res_name, domain, base_path, port, traefik_host=None, manifest=None):
|
|
43
|
+
"""Generate Traefik labels for frontend services."""
|
|
44
|
+
# Priority based on path length ensures more specific paths win over broader ones
|
|
45
|
+
router_priority = TRAEFIK_FRONTEND_PRIORITY_BASE + len(base_path or "")
|
|
46
|
+
frontend_route_rule = frontend_rule(res_name, base_path, traefik_host)
|
|
47
|
+
frontend_entrypoints = build_entrypoints(
|
|
48
|
+
TRAEFIK_FRONTEND_ENABLE_HTTP,
|
|
49
|
+
TRAEFIK_FRONTEND_ENABLE_HTTPS,
|
|
50
|
+
)
|
|
51
|
+
middleware_name = res_name + TRAEFIK_MIDDLEWARE_SUFFIX
|
|
52
|
+
|
|
53
|
+
# Check if maintenance feature is enabled
|
|
54
|
+
features = manifest.get('featuresEnabled', []) if manifest else []
|
|
55
|
+
maintenance_middleware = ""
|
|
56
|
+
if 'maintenance' in features:
|
|
57
|
+
maintenance_middleware = ",maintenance@file"
|
|
58
|
+
|
|
59
|
+
# On-demand scaling: attach the Sablier middleware when opted in via the manifest
|
|
60
|
+
sablier_middleware, sablier_enabled = sablier_middleware_suffix(manifest, res_name)
|
|
61
|
+
|
|
62
|
+
labels = """ - "{traefik_enable_label}"
|
|
63
|
+
- 'traefik.http.routers.{res_name}.rule={frontend_route_rule}'
|
|
64
|
+
- "traefik.http.routers.{res_name}.entrypoints={frontend_entrypoints}"
|
|
65
|
+
- "traefik.http.routers.{res_name}.priority={router_priority}"
|
|
66
|
+
- "traefik.http.routers.{res_name}.middlewares={middleware_name}{maintenance_middleware}{sablier_middleware}"
|
|
67
|
+
- "traefik.http.middlewares.{middleware_name}.stripprefix.prefixes={base_path}"
|
|
68
|
+
- "traefik.http.services.{res_name}.loadbalancer.server.port={port}"
|
|
69
|
+
- "traefik.docker.network={traefik_network}\"""".format(
|
|
70
|
+
res_name=res_name,
|
|
71
|
+
traefik_enable_label=TRAEFIK_ENABLE_LABEL,
|
|
72
|
+
frontend_route_rule=frontend_route_rule,
|
|
73
|
+
frontend_entrypoints=frontend_entrypoints,
|
|
74
|
+
middleware_name=middleware_name,
|
|
75
|
+
base_path=base_path,
|
|
76
|
+
port=port,
|
|
77
|
+
router_priority=router_priority,
|
|
78
|
+
traefik_network=TRAEFIK_DOCKER_NETWORK,
|
|
79
|
+
maintenance_middleware=maintenance_middleware,
|
|
80
|
+
sablier_middleware=sablier_middleware,
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
if sablier_enabled:
|
|
84
|
+
labels += sablier_container_labels(manifest, res_name, " ")
|
|
85
|
+
|
|
86
|
+
return labels
|
|
87
|
+
|
|
88
|
+
def _stack_is_shared(manifest):
|
|
89
|
+
"""True when this backend shares its stack with another routable backend (`_stackBackendCount`, set by register_compose_resources).
|
|
90
|
+
|
|
91
|
+
The stack-scoped routers (the host/`pathPrefix` router and `<name>-management`) carry one rule per stack. With two backends in
|
|
92
|
+
one stack they would carry the same rule, so Traefik would pick between them arbitrarily. Each backend keeps its own
|
|
93
|
+
`<name>-project` router (`/api/<name>`).
|
|
94
|
+
"""
|
|
95
|
+
return bool(manifest) and manifest.get('_stackBackendCount', 1) > 1
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def _explicit_backend_route(manifest):
|
|
99
|
+
"""The `traefik.host` / `traefik.pathPrefix` a manifest set on purpose, as (host, path); either may be empty."""
|
|
100
|
+
traefik_cfg = (manifest.get('traefik') or {}) if manifest else {}
|
|
101
|
+
return traefik_cfg.get('host') or '', traefik_cfg.get('pathPrefix') or ''
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def get_backend_traefik_labels(
|
|
105
|
+
resource_entry_name,
|
|
106
|
+
traefik_host,
|
|
107
|
+
traefik_path,
|
|
108
|
+
traefik_resource_name,
|
|
109
|
+
internal_port,
|
|
110
|
+
health_path,
|
|
111
|
+
manifest=None,
|
|
112
|
+
):
|
|
113
|
+
"""Generate Traefik labels for backend services with enhanced health checks."""
|
|
114
|
+
backend_route_rule = backend_rule(traefik_host, traefik_path)
|
|
115
|
+
backend_entrypoints = build_entrypoints(
|
|
116
|
+
TRAEFIK_BACKEND_ENABLE_HTTP,
|
|
117
|
+
TRAEFIK_BACKEND_ENABLE_HTTPS,
|
|
118
|
+
)
|
|
119
|
+
middleware_name = resource_entry_name + TRAEFIK_MIDDLEWARE_SUFFIX
|
|
120
|
+
|
|
121
|
+
# Check if maintenance feature is enabled
|
|
122
|
+
features = manifest.get('featuresEnabled', []) if manifest else []
|
|
123
|
+
maintenance_middleware = ""
|
|
124
|
+
if 'maintenance' in features:
|
|
125
|
+
maintenance_middleware = ",maintenance@file"
|
|
126
|
+
|
|
127
|
+
# On-demand scaling: attach the Sablier middleware when opted in via the manifest
|
|
128
|
+
sablier_middleware, sablier_enabled = sablier_middleware_suffix(manifest, resource_entry_name)
|
|
129
|
+
|
|
130
|
+
# Build middleware config only if traefik_path is not empty
|
|
131
|
+
if traefik_path:
|
|
132
|
+
middleware_config_lines = [
|
|
133
|
+
' - "traefik.http.routers.' + resource_entry_name + '.middlewares=' + middleware_name + maintenance_middleware + sablier_middleware + '"',
|
|
134
|
+
' - "traefik.http.middlewares.' + middleware_name + '.stripprefix.prefixes=' + traefik_path + '"',
|
|
135
|
+
]
|
|
136
|
+
middleware_config = "\n".join(middleware_config_lines)
|
|
137
|
+
elif sablier_middleware:
|
|
138
|
+
# No strip-prefix path, but still front the router with the Sablier middleware
|
|
139
|
+
middleware_config = ' - "traefik.http.routers.' + resource_entry_name + '.middlewares=' + sablier_middleware.lstrip(",") + '"'
|
|
140
|
+
else:
|
|
141
|
+
# No middleware if path is empty - router has no middlewares
|
|
142
|
+
middleware_config = ""
|
|
143
|
+
|
|
144
|
+
stack_shared = _stack_is_shared(manifest)
|
|
145
|
+
explicit_host, explicit_path = _explicit_backend_route(manifest)
|
|
146
|
+
if stack_shared:
|
|
147
|
+
# Another backend in this stack would match the same stack rule, so it is not emitted. The service labels stay (the
|
|
148
|
+
# -project router points at the service). A manifest that set its own host or pathPrefix keeps a router, but one whose
|
|
149
|
+
# rule is only what it set, never the shared stack host or path.
|
|
150
|
+
backend_route_rule = backend_rule(explicit_host, explicit_path)
|
|
151
|
+
|
|
152
|
+
if stack_shared and not backend_route_rule:
|
|
153
|
+
backend_router_labels = ""
|
|
154
|
+
else:
|
|
155
|
+
backend_router_labels = """ - "traefik.http.routers.{resource_entry_name}.rule={backend_route_rule}"
|
|
156
|
+
- "traefik.http.routers.{resource_entry_name}.entrypoints={backend_entrypoints}"
|
|
157
|
+
- "traefik.http.routers.{resource_entry_name}.service={traefik_resource_name}"
|
|
158
|
+
{middleware_config}
|
|
159
|
+
""".format(
|
|
160
|
+
resource_entry_name=resource_entry_name,
|
|
161
|
+
backend_route_rule=backend_route_rule,
|
|
162
|
+
backend_entrypoints=backend_entrypoints,
|
|
163
|
+
traefik_resource_name=traefik_resource_name,
|
|
164
|
+
middleware_config=middleware_config,
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
# No health path (a bring-your-own service that does not speak HTTP): Traefik balances without an active HTTP probe rather than
|
|
168
|
+
# probing a path the service never serves.
|
|
169
|
+
traefik_healthcheck_labels = ""
|
|
170
|
+
if health_path:
|
|
171
|
+
traefik_healthcheck_labels = """ - "traefik.http.services.{traefik_resource_name}.loadbalancer.healthcheck.path={health_path}"
|
|
172
|
+
- "traefik.http.services.{traefik_resource_name}.loadbalancer.healthcheck.interval={health_interval}"
|
|
173
|
+
- "traefik.http.services.{traefik_resource_name}.loadbalancer.healthcheck.timeout={health_timeout}"
|
|
174
|
+
- "traefik.http.services.{traefik_resource_name}.loadbalancer.healthcheck.followredirects=false"
|
|
175
|
+
""".format(
|
|
176
|
+
traefik_resource_name=traefik_resource_name,
|
|
177
|
+
health_path=health_path,
|
|
178
|
+
health_interval=TRAEFIK_HEALTHCHECK_INTERVAL,
|
|
179
|
+
health_timeout=TRAEFIK_HEALTHCHECK_TIMEOUT,
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
labels = """ - "{traefik_enable_label}"
|
|
183
|
+
{backend_router_labels} - "traefik.http.services.{traefik_resource_name}.loadbalancer.server.port={internal_port}"
|
|
184
|
+
{traefik_healthcheck_labels} - "traefik.docker.network={traefik_network}"
|
|
185
|
+
""".format(
|
|
186
|
+
resource_entry_name=resource_entry_name,
|
|
187
|
+
traefik_enable_label=TRAEFIK_ENABLE_LABEL,
|
|
188
|
+
backend_router_labels=backend_router_labels,
|
|
189
|
+
traefik_resource_name=traefik_resource_name,
|
|
190
|
+
internal_port=internal_port,
|
|
191
|
+
traefik_healthcheck_labels=traefik_healthcheck_labels,
|
|
192
|
+
traefik_network=TRAEFIK_DOCKER_NETWORK,
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
# Emit Sablier discovery labels so the Sablier container can wake/stop this workload
|
|
196
|
+
if sablier_enabled:
|
|
197
|
+
labels += sablier_container_labels(manifest, resource_entry_name, " ")
|
|
198
|
+
|
|
199
|
+
# Generate project localhost routing to match `flisk up` URLs:
|
|
200
|
+
# http://api.{project}.localhost/api/{resource-name}
|
|
201
|
+
if manifest:
|
|
202
|
+
stack = manifest.get("stack", "")
|
|
203
|
+
api_path = cli_api_path(resource_entry_name, manifest)
|
|
204
|
+
project_rule = project_backend_rule(manifest, resource_entry_name)
|
|
205
|
+
project_entrypoints = build_entrypoints(
|
|
206
|
+
TRAEFIK_BACKEND_ENABLE_HTTP,
|
|
207
|
+
TRAEFIK_BACKEND_ENABLE_HTTPS,
|
|
208
|
+
)
|
|
209
|
+
# Calculate priority based on path length (more specific = higher priority)
|
|
210
|
+
router_priority = TRAEFIK_FRONTEND_PRIORITY_BASE + len(api_path)
|
|
211
|
+
|
|
212
|
+
# Generate old path pattern for redirect (e.g., /{stack}-management/api/v1/)
|
|
213
|
+
old_path_pattern = "/{stack}-management/api/v1".format(stack=stack) if stack else ""
|
|
214
|
+
management_path = get_api_path(stack, manifest) if stack else ""
|
|
215
|
+
|
|
216
|
+
labels += """
|
|
217
|
+
- "traefik.http.routers.{resource_entry_name}-project.rule={project_rule}"
|
|
218
|
+
- "traefik.http.routers.{resource_entry_name}-project.entrypoints={project_entrypoints}"
|
|
219
|
+
- "traefik.http.routers.{resource_entry_name}-project.service={traefik_resource_name}"
|
|
220
|
+
- "traefik.http.routers.{resource_entry_name}-project.middlewares={middleware_name}-project{maintenance_middleware}{sablier_middleware}"
|
|
221
|
+
- "traefik.http.middlewares.{middleware_name}-project.stripprefix.prefixes={api_path}"
|
|
222
|
+
- "traefik.http.routers.{resource_entry_name}-project.priority={router_priority}"
|
|
223
|
+
""".format(
|
|
224
|
+
resource_entry_name=resource_entry_name,
|
|
225
|
+
traefik_resource_name=traefik_resource_name,
|
|
226
|
+
project_rule=project_rule,
|
|
227
|
+
project_entrypoints=project_entrypoints,
|
|
228
|
+
middleware_name=middleware_name,
|
|
229
|
+
maintenance_middleware=maintenance_middleware,
|
|
230
|
+
sablier_middleware=sablier_middleware,
|
|
231
|
+
api_path=api_path,
|
|
232
|
+
router_priority=router_priority,
|
|
233
|
+
)
|
|
234
|
+
|
|
235
|
+
if management_path and management_path != api_path and not stack_shared:
|
|
236
|
+
labels += """
|
|
237
|
+
- "traefik.http.routers.{resource_entry_name}-management.rule=Host(`{api_host}`) && PathPrefix(`{management_path}`)"
|
|
238
|
+
- "traefik.http.routers.{resource_entry_name}-management.entrypoints={project_entrypoints}"
|
|
239
|
+
- "traefik.http.routers.{resource_entry_name}-management.service={traefik_resource_name}"
|
|
240
|
+
- "traefik.http.routers.{resource_entry_name}-management.middlewares={middleware_name}-management{sablier_middleware}"
|
|
241
|
+
- "traefik.http.middlewares.{middleware_name}-management.stripprefix.prefixes={management_path}"
|
|
242
|
+
- "traefik.http.routers.{resource_entry_name}-management.priority={mgmt_priority}"
|
|
243
|
+
""".format(
|
|
244
|
+
resource_entry_name=resource_entry_name,
|
|
245
|
+
traefik_resource_name=traefik_resource_name,
|
|
246
|
+
api_host=TRAEFIK_PROJECT_API_HOST,
|
|
247
|
+
management_path=management_path,
|
|
248
|
+
project_entrypoints=project_entrypoints,
|
|
249
|
+
middleware_name=middleware_name,
|
|
250
|
+
sablier_middleware=sablier_middleware,
|
|
251
|
+
mgmt_priority=TRAEFIK_FRONTEND_PRIORITY_BASE + len(management_path),
|
|
252
|
+
)
|
|
253
|
+
|
|
254
|
+
if old_path_pattern:
|
|
255
|
+
labels += """
|
|
256
|
+
# Redirect middleware for URL restructuring: old path -> new path
|
|
257
|
+
- "traefik.http.middlewares.{resource_entry_name}-redirect.redirectregex.regex=^`{old_path_pattern}/(.*)`"
|
|
258
|
+
- "traefik.http.middlewares.{resource_entry_name}-redirect.redirectregex.replacement=`{api_path}/$$1`"
|
|
259
|
+
- "traefik.http.middlewares.{resource_entry_name}-redirect.redirectregex.permanent=true"
|
|
260
|
+
""".format(
|
|
261
|
+
resource_entry_name=resource_entry_name,
|
|
262
|
+
old_path_pattern=old_path_pattern,
|
|
263
|
+
api_path=api_path,
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
return labels
|