@flisk-sh/flisk 0.0.0-stage → 1.3.189
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-QWYXYAX6.js +510 -0
- package/cli/dist-bundle/cli.js +2017 -0
- package/cli/dist-bundle/cold-preflight-MM46GFQA.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,363 @@
|
|
|
1
|
+
// Copyright (c) 2026 Flisk contributors
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
/**
|
|
4
|
+
* Wake gateway: fronts every `sablier.deferStart` resource's Traefik static
|
|
5
|
+
* route (see openspec/changes/prioritized-cold-start). On the first request
|
|
6
|
+
* for a resource with no running container, it triggers the resource (and
|
|
7
|
+
* its cold dependencies) via `tilt trigger`, and/or Sablier's own start for
|
|
8
|
+
* an already-created container, then holds the request until the resource
|
|
9
|
+
* answers its healthcheck or the configured timeout elapses.
|
|
10
|
+
*
|
|
11
|
+
* Config for each request comes from headers a Traefik `headers` middleware
|
|
12
|
+
* injects (set by the file-provider entry generated in
|
|
13
|
+
* traefik_static_routes.star) rather than the path, so the original request
|
|
14
|
+
* path/query reach the real backend unchanged once it's ready:
|
|
15
|
+
* X-Wake-Resource Tilt/Compose resource name (for `tilt trigger` and
|
|
16
|
+
* `docker compose up <service>`).
|
|
17
|
+
* X-Wake-Container The actual Docker container name (for `docker
|
|
18
|
+
* inspect` state/health and the proxy target -- NOT the same string as
|
|
19
|
+
* the resource name; Compose derives it as
|
|
20
|
+
* <project>-<service>-<replica>, confirmed empirically
|
|
21
|
+
* against a live Flisk container, e.g.
|
|
22
|
+
* "tdk-erp-system-analytics-autogenerated-data-governance-api-1"
|
|
23
|
+
* for the "data-governance-api" resource).
|
|
24
|
+
* X-Wake-Deps Comma-separated "resourceName=containerName" pairs
|
|
25
|
+
* for required dependencies (task 1.5: Tilt never
|
|
26
|
+
* cascades a trigger to these on its own).
|
|
27
|
+
* X-Wake-Compose-Project The resource's Compose project (e.g. "tdk-erp-system-analytics-autogenerated").
|
|
28
|
+
* X-Wake-Compose-Files Comma-separated absolute compose file paths, the
|
|
29
|
+
* same ones Tilt's `<resource>-run-only` resource
|
|
30
|
+
* passes. The project root is mounted into this
|
|
31
|
+
* container at the same absolute path, so relative
|
|
32
|
+
* paths inside those files resolve exactly as for Tilt.
|
|
33
|
+
* X-Wake-Env-File Absolute path of the project's .env (optional).
|
|
34
|
+
* X-Wake-Image The image the compose service declares
|
|
35
|
+
* (<project>_<stack>_<resource>:dev).
|
|
36
|
+
* X-Wake-Timeout-Ms, X-Wake-Proxy-Port, X-Wake-Session-Duration
|
|
37
|
+
* X-Wake-Respond-Within-Ms How long to hold the request before answering
|
|
38
|
+
* 503 + Retry-After while the start continues in the
|
|
39
|
+
* background (default decide.ts EARLY_RESPONSE_MS).
|
|
40
|
+
*/
|
|
41
|
+
import {
|
|
42
|
+
RETRY_AFTER_SECONDS,
|
|
43
|
+
decideWakeAction,
|
|
44
|
+
earlyResponseMs,
|
|
45
|
+
evaluateReadiness,
|
|
46
|
+
isGatewayLivenessProbe,
|
|
47
|
+
wakeTimeoutMs,
|
|
48
|
+
type ContainerState,
|
|
49
|
+
} from "./decide";
|
|
50
|
+
|
|
51
|
+
const TILT_HOST = process.env.TILT_HOST || "host.docker.internal";
|
|
52
|
+
const TILT_PORT = process.env.TILT_PORT || "10350";
|
|
53
|
+
const SABLIER_URL = process.env.SABLIER_URL || "http://sablier:10000";
|
|
54
|
+
const POLL_INTERVAL_MS = 1000;
|
|
55
|
+
|
|
56
|
+
async function run(cmd: string[]): Promise<{ code: number; stdout: string; stderr: string }> {
|
|
57
|
+
const proc = Bun.spawn(cmd, { stdout: "pipe", stderr: "pipe" });
|
|
58
|
+
const [stdout, stderr, code] = await Promise.all([
|
|
59
|
+
new Response(proc.stdout).text(),
|
|
60
|
+
new Response(proc.stderr).text(),
|
|
61
|
+
proc.exited,
|
|
62
|
+
]);
|
|
63
|
+
return { code, stdout, stderr };
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async function containerState(name: string): Promise<ContainerState> {
|
|
67
|
+
const { code, stdout } = await run([
|
|
68
|
+
"docker", "inspect", "--format", "{{.State.Status}}", name,
|
|
69
|
+
]);
|
|
70
|
+
if (code !== 0) return "absent";
|
|
71
|
+
const status = stdout.trim();
|
|
72
|
+
if (status === "running") return "running";
|
|
73
|
+
if (status === "created") return "created";
|
|
74
|
+
return "exited";
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
async function isHealthy(name: string): Promise<boolean> {
|
|
78
|
+
const { code, stdout } = await run([
|
|
79
|
+
"docker", "inspect",
|
|
80
|
+
"--format", "{{if .State.Health}}{{.State.Health.Status}}{{else}}{{.State.Status}}{{end}}",
|
|
81
|
+
name,
|
|
82
|
+
]);
|
|
83
|
+
if (code !== 0) return false;
|
|
84
|
+
const status = stdout.trim();
|
|
85
|
+
return status === "healthy" || status === "running";
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
async function tiltTrigger(name: string): Promise<void> {
|
|
89
|
+
const { code, stderr } = await run(["tilt", "trigger", name, "--host", TILT_HOST, "--port", TILT_PORT]);
|
|
90
|
+
console.log(`tilt trigger ${name}: ${code === 0 ? "queued" : `failed (${stderr.trim()})`}`);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
interface ComposeInvocation {
|
|
94
|
+
project: string;
|
|
95
|
+
files: string[];
|
|
96
|
+
envFile: string;
|
|
97
|
+
image: string;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Make sure the compose service's declared image exists locally. Tilt tags its
|
|
102
|
+
* own builds `<repo>:tilt-<hash>` and injects that tag when it runs compose, so
|
|
103
|
+
* the declared `<repo>:dev` tag may be missing even though the resource was
|
|
104
|
+
* built; retag Tilt's newest build in that case. False when nothing was ever
|
|
105
|
+
* built -- only `tilt trigger` (which builds) can wake the resource then.
|
|
106
|
+
*/
|
|
107
|
+
async function ensureImage(image: string): Promise<boolean> {
|
|
108
|
+
if ((await run(["docker", "image", "inspect", "--format", "{{.Id}}", image])).code === 0) return true;
|
|
109
|
+
const repo = image.split(":")[0];
|
|
110
|
+
// `docker images` lists newest first.
|
|
111
|
+
const { code, stdout } = await run(["docker", "images", repo, "--format", "{{.Tag}}"]);
|
|
112
|
+
if (code !== 0) return false;
|
|
113
|
+
const tiltTag = stdout.split("\n").map((t) => t.trim()).find((t) => t.startsWith("tilt-"));
|
|
114
|
+
if (!tiltTag) return false;
|
|
115
|
+
return (await run(["docker", "tag", `${repo}:${tiltTag}`, image])).code === 0;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Create and start the resource's container directly, with the same
|
|
120
|
+
* `docker compose ... up -d --no-build` its Tilt `-run-only` resource runs,
|
|
121
|
+
* bypassing Tilt's build queue (see decide.ts useComposeStart).
|
|
122
|
+
*/
|
|
123
|
+
async function composeStart(compose: ComposeInvocation, service: string): Promise<boolean> {
|
|
124
|
+
if (!(await ensureImage(compose.image))) {
|
|
125
|
+
console.log(`compose start ${service}: no local image for ${compose.image}, falling back to tilt trigger`);
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
const args = ["docker", "compose", "-p", compose.project];
|
|
129
|
+
for (const file of compose.files) args.push("-f", file);
|
|
130
|
+
if (compose.envFile) args.push("--env-file", compose.envFile);
|
|
131
|
+
args.push("up", "-d", "--no-build", "--no-deps", service);
|
|
132
|
+
const { code, stderr } = await run(args);
|
|
133
|
+
console.log(`compose start ${service}: ${code === 0 ? "started" : `failed (${stderr.trim()})`}`);
|
|
134
|
+
return code === 0;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Sablier's real blocking-strategy endpoint (GET /api/strategies/blocking,
|
|
139
|
+
* per https://sablierapp.dev/openapi.json): starts the named instance and
|
|
140
|
+
* holds until it's ready or `timeoutMs` elapses, returning that outcome via
|
|
141
|
+
* the X-Sablier-Session-Status header. Only valid for an instance Sablier
|
|
142
|
+
* already knows about (a container that exists with sablier.enable=true) --
|
|
143
|
+
* see decide.ts's useSablierStart.
|
|
144
|
+
*/
|
|
145
|
+
async function sablierBlockingWait(resource: string, sessionDuration: string, timeoutMs: number): Promise<boolean> {
|
|
146
|
+
const params = new URLSearchParams({
|
|
147
|
+
names: resource,
|
|
148
|
+
session_duration: sessionDuration,
|
|
149
|
+
timeout: `${Math.max(1, Math.round(timeoutMs / 1000))}s`,
|
|
150
|
+
});
|
|
151
|
+
try {
|
|
152
|
+
const res = await fetch(`${SABLIER_URL}/api/strategies/blocking?${params}`);
|
|
153
|
+
return res.headers.get("X-Sablier-Session-Status") === "ready";
|
|
154
|
+
} catch {
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
interface NamedDep {
|
|
160
|
+
resourceName: string;
|
|
161
|
+
containerName: string;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function parseDeps(raw: string): NamedDep[] {
|
|
165
|
+
return raw
|
|
166
|
+
.split(",")
|
|
167
|
+
.filter(Boolean)
|
|
168
|
+
.map((pair) => {
|
|
169
|
+
const [resourceName, containerName] = pair.split("=");
|
|
170
|
+
return { resourceName, containerName: containerName || resourceName };
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function parseRequest(req: Request) {
|
|
175
|
+
const resource = req.headers.get("X-Wake-Resource") || "";
|
|
176
|
+
const container = req.headers.get("X-Wake-Container") || resource;
|
|
177
|
+
const deps = parseDeps(req.headers.get("X-Wake-Deps") || "");
|
|
178
|
+
const timeoutOverrideMs = Number(req.headers.get("X-Wake-Timeout-Ms")) || undefined;
|
|
179
|
+
const respondWithinOverrideMs = Number(req.headers.get("X-Wake-Respond-Within-Ms")) || undefined;
|
|
180
|
+
const proxyPort = req.headers.get("X-Wake-Proxy-Port") || "80";
|
|
181
|
+
const sessionDuration = req.headers.get("X-Wake-Session-Duration") || "10m";
|
|
182
|
+
const composeFiles = (req.headers.get("X-Wake-Compose-Files") || "").split(",").filter(Boolean);
|
|
183
|
+
const compose: ComposeInvocation = {
|
|
184
|
+
project: req.headers.get("X-Wake-Compose-Project") || "",
|
|
185
|
+
files: composeFiles,
|
|
186
|
+
envFile: req.headers.get("X-Wake-Env-File") || "",
|
|
187
|
+
image: req.headers.get("X-Wake-Image") || "",
|
|
188
|
+
};
|
|
189
|
+
const hasCompose = Boolean(compose.project && compose.files.length && compose.image);
|
|
190
|
+
return {
|
|
191
|
+
resource,
|
|
192
|
+
container,
|
|
193
|
+
deps,
|
|
194
|
+
timeoutOverrideMs,
|
|
195
|
+
respondWithinOverrideMs,
|
|
196
|
+
proxyPort,
|
|
197
|
+
sessionDuration,
|
|
198
|
+
compose,
|
|
199
|
+
hasCompose,
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
type WakeParams = ReturnType<typeof parseRequest>;
|
|
204
|
+
type WakeOutcome = { ready: true } | { ready: false; timeoutMs: number };
|
|
205
|
+
|
|
206
|
+
// One wake per resource at a time: a caller that got an early 503 and retries,
|
|
207
|
+
// or a second caller arriving meanwhile, joins the wake already in progress
|
|
208
|
+
// instead of starting the container again.
|
|
209
|
+
const inflight = new Map<string, Promise<WakeOutcome>>();
|
|
210
|
+
|
|
211
|
+
function wakeOnce(params: WakeParams): Promise<WakeOutcome> {
|
|
212
|
+
let wake = inflight.get(params.resource);
|
|
213
|
+
if (!wake) {
|
|
214
|
+
wake = runWake(params).finally(() => inflight.delete(params.resource));
|
|
215
|
+
inflight.set(params.resource, wake);
|
|
216
|
+
}
|
|
217
|
+
return wake;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
async function handleWake(req: Request): Promise<Response> {
|
|
221
|
+
const params = parseRequest(req);
|
|
222
|
+
if (!params.resource) {
|
|
223
|
+
return new Response("wake gateway: missing X-Wake-Resource header (set by the generated Traefik static route)", { status: 400 });
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const holdMs = earlyResponseMs(params.respondWithinOverrideMs);
|
|
227
|
+
const outcome = await Promise.race([wakeOnce(params), Bun.sleep(holdMs).then(() => null)]);
|
|
228
|
+
if (outcome === null) {
|
|
229
|
+
console.log(`wake ${params.resource}: still starting after ${holdMs}ms, answering 503`);
|
|
230
|
+
return new Response(
|
|
231
|
+
`wake gateway: ${params.resource} is starting; retry in ${RETRY_AFTER_SECONDS}s`,
|
|
232
|
+
{ status: 503, headers: { "Retry-After": String(RETRY_AFTER_SECONDS) } },
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
if (outcome.ready) {
|
|
236
|
+
return proxyThrough(req, params.container, params.proxyPort);
|
|
237
|
+
}
|
|
238
|
+
return new Response(
|
|
239
|
+
`wake gateway: timed out after ${outcome.timeoutMs}ms waiting for ${params.resource} and its dependencies to become healthy`,
|
|
240
|
+
{ status: 504 },
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
async function runWake(params: WakeParams): Promise<WakeOutcome> {
|
|
245
|
+
const { resource, container, deps, timeoutOverrideMs, sessionDuration, compose, hasCompose } = params;
|
|
246
|
+
const resourceState = await containerState(container);
|
|
247
|
+
const dependencies = await Promise.all(
|
|
248
|
+
deps.map(async (dep) => ({ name: dep.resourceName, state: await containerState(dep.containerName) })),
|
|
249
|
+
);
|
|
250
|
+
|
|
251
|
+
const action = decideWakeAction({
|
|
252
|
+
resourceContainerName: resource,
|
|
253
|
+
resourceState,
|
|
254
|
+
dependencies,
|
|
255
|
+
hasComposeInvocation: hasCompose,
|
|
256
|
+
});
|
|
257
|
+
console.log(
|
|
258
|
+
`wake ${resource}: state=${resourceState} compose=${action.useComposeStart} ` +
|
|
259
|
+
`trigger=[${action.tiltTriggerNames.join(",")}] sablier=${action.useSablierStart}`,
|
|
260
|
+
);
|
|
261
|
+
|
|
262
|
+
// Dependencies (and the resource itself when it can't be started directly)
|
|
263
|
+
// go through tilt trigger (task 1.5: Tilt never cascades this on its own).
|
|
264
|
+
const tiltNames = [...action.tiltTriggerNames];
|
|
265
|
+
let startedViaCompose = false;
|
|
266
|
+
if (action.useComposeStart) {
|
|
267
|
+
startedViaCompose = await composeStart(compose, resource);
|
|
268
|
+
if (!startedViaCompose) tiltNames.unshift(resource);
|
|
269
|
+
}
|
|
270
|
+
const timeoutMs = wakeTimeoutMs(startedViaCompose, timeoutOverrideMs);
|
|
271
|
+
const deadline = Date.now() + timeoutMs;
|
|
272
|
+
|
|
273
|
+
// Sablier's blocking call, when applicable, both starts AND waits for the
|
|
274
|
+
// resource itself in one round trip.
|
|
275
|
+
const [, resourceReadyViaSablier] = await Promise.all([
|
|
276
|
+
Promise.all(tiltNames.map(tiltTrigger)),
|
|
277
|
+
action.useSablierStart
|
|
278
|
+
? sablierBlockingWait(resource, sessionDuration, timeoutMs)
|
|
279
|
+
: Promise.resolve(false),
|
|
280
|
+
]);
|
|
281
|
+
|
|
282
|
+
const requiredNames = [resource, ...deps.map((d) => d.resourceName)];
|
|
283
|
+
|
|
284
|
+
while (Date.now() < deadline) {
|
|
285
|
+
const healthy: Record<string, boolean> = {};
|
|
286
|
+
// Sablier's blocking call already confirmed the resource itself; re-check
|
|
287
|
+
// it too (cheap) so a false result from Sablier still gets a fair retry.
|
|
288
|
+
healthy[resource] = resourceReadyViaSablier || (await isHealthy(container));
|
|
289
|
+
for (const dep of deps) {
|
|
290
|
+
healthy[dep.resourceName] = await isHealthy(dep.containerName);
|
|
291
|
+
}
|
|
292
|
+
if (evaluateReadiness(requiredNames, healthy).ready) {
|
|
293
|
+
return { ready: true };
|
|
294
|
+
}
|
|
295
|
+
await Bun.sleep(POLL_INTERVAL_MS);
|
|
296
|
+
}
|
|
297
|
+
return { ready: false, timeoutMs };
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// Headers that must not be forwarded verbatim to the upstream fetch: Host
|
|
301
|
+
// would otherwise carry the gateway's own address, and the X-Wake-* control
|
|
302
|
+
// headers are gateway-internal, not part of the real app request.
|
|
303
|
+
const STRIPPED_REQUEST_HEADERS = new Set([
|
|
304
|
+
"host",
|
|
305
|
+
"x-wake-resource",
|
|
306
|
+
"x-wake-container",
|
|
307
|
+
"x-wake-deps",
|
|
308
|
+
"x-wake-timeout-ms",
|
|
309
|
+
"x-wake-respond-within-ms",
|
|
310
|
+
"x-wake-proxy-port",
|
|
311
|
+
"x-wake-session-duration",
|
|
312
|
+
"x-wake-compose-project",
|
|
313
|
+
"x-wake-compose-files",
|
|
314
|
+
"x-wake-env-file",
|
|
315
|
+
"x-wake-image",
|
|
316
|
+
]);
|
|
317
|
+
|
|
318
|
+
// Proxies to the container name rather than the Compose service name: every
|
|
319
|
+
// Flisk project's resources share the traefik-public network, where a bare
|
|
320
|
+
// service name is only an alias and could collide across projects.
|
|
321
|
+
async function proxyThrough(req: Request, container: string, port: string): Promise<Response> {
|
|
322
|
+
// The original path/query reach the gateway untouched (config travels via
|
|
323
|
+
// X-Wake-* headers, not the path), so they're forwarded as-is.
|
|
324
|
+
const target = new URL(req.url);
|
|
325
|
+
target.protocol = "http:";
|
|
326
|
+
// Set hostname/port separately, not via `.host` -- confirmed empirically
|
|
327
|
+
// that `target.host = "name:port"` silently keeps the URL's original port
|
|
328
|
+
// when one is already present instead of replacing it.
|
|
329
|
+
target.hostname = container;
|
|
330
|
+
target.port = port;
|
|
331
|
+
|
|
332
|
+
const headers = new Headers();
|
|
333
|
+
for (const [key, value] of req.headers) {
|
|
334
|
+
if (!STRIPPED_REQUEST_HEADERS.has(key.toLowerCase())) headers.set(key, value);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
const upstream = await fetch(target.toString(), {
|
|
338
|
+
method: req.method,
|
|
339
|
+
headers,
|
|
340
|
+
body: req.method === "GET" || req.method === "HEAD" ? undefined : await req.arrayBuffer(),
|
|
341
|
+
});
|
|
342
|
+
return new Response(upstream.body, { status: upstream.status, headers: upstream.headers });
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
Bun.serve({
|
|
346
|
+
port: Number(process.env.PORT) || 9999,
|
|
347
|
+
// Bun's default idleTimeout (10s) is shorter than a real wake can take
|
|
348
|
+
// (tilt trigger + healthcheck polling) -- confirmed empirically: a request
|
|
349
|
+
// was killed mid-wait with "request timed out after 10 seconds" before this
|
|
350
|
+
// was raised. 255s is Bun's own max for this setting.
|
|
351
|
+
idleTimeout: 255,
|
|
352
|
+
fetch(req) {
|
|
353
|
+
if (isGatewayLivenessProbe(req.method, new URL(req.url).pathname, req.headers)) {
|
|
354
|
+
return new Response("ok");
|
|
355
|
+
}
|
|
356
|
+
return handleWake(req).catch((err) => {
|
|
357
|
+
console.error("wake gateway error:", err);
|
|
358
|
+
return new Response(`wake gateway error: ${String(err)}`, { status: 500 });
|
|
359
|
+
});
|
|
360
|
+
},
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
console.log(`wake gateway listening on :${Number(process.env.PORT) || 9999}`);
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Copyright (c) 2026 Flisk Landscape contributors
|
|
3
|
+
# SPDX-License-Identifier: MIT
|
|
4
|
+
set -euo pipefail
|
|
5
|
+
|
|
6
|
+
# Delete images for completed DB migrator containers to free disk space.
|
|
7
|
+
# Safe guards:
|
|
8
|
+
# - only containers with names ending in -db-migrator are considered
|
|
9
|
+
# - only exited containers with exit code 0 are processed
|
|
10
|
+
# - image deletion is best-effort (skips if still in use)
|
|
11
|
+
|
|
12
|
+
mapfile -t migrator_containers < <(
|
|
13
|
+
docker ps -a --format '{{.Names}}' | grep -E -- '-db-migrator($|-)' 2>/dev/null || true
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
if [ "${#migrator_containers[@]}" -eq 0 ]; then
|
|
17
|
+
exit 0
|
|
18
|
+
fi
|
|
19
|
+
|
|
20
|
+
for name in "${migrator_containers[@]}"; do
|
|
21
|
+
state="$(docker inspect -f '{{.State.Status}}' "$name" 2>/dev/null || true)"
|
|
22
|
+
exit_code="$(docker inspect -f '{{.State.ExitCode}}' "$name" 2>/dev/null || true)"
|
|
23
|
+
|
|
24
|
+
if [ "$state" != "exited" ] || [ "$exit_code" != "0" ]; then
|
|
25
|
+
continue
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
image_ref="$(docker inspect -f '{{.Config.Image}}' "$name" 2>/dev/null || true)"
|
|
29
|
+
if [ -z "$image_ref" ]; then
|
|
30
|
+
continue
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
# Remove the stopped migrator container so image can be deleted if unused.
|
|
34
|
+
docker rm "$name" >/dev/null 2>&1 || true
|
|
35
|
+
|
|
36
|
+
if docker image rm "$image_ref" >/dev/null 2>&1; then
|
|
37
|
+
echo "$(date +%H:%M:%S) pruned migrator image: $image_ref"
|
|
38
|
+
fi
|
|
39
|
+
done
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Copyright (c) 2026 Flisk Landscape contributors
|
|
3
|
+
# SPDX-License-Identifier: MIT
|
|
4
|
+
|
|
5
|
+
set -euo pipefail
|
|
6
|
+
|
|
7
|
+
# Keep the newest N Tilt-tagged images per repository.
|
|
8
|
+
# Defaults to a safe dry-run unless --force is provided.
|
|
9
|
+
|
|
10
|
+
KEEP_COUNT=0
|
|
11
|
+
FORCE=0
|
|
12
|
+
|
|
13
|
+
usage() {
|
|
14
|
+
cat <<USAGE
|
|
15
|
+
Usage: $0 [--keep N] [--force]
|
|
16
|
+
|
|
17
|
+
Options:
|
|
18
|
+
--keep N Number of newest tilt-* images to keep per repository (default: 0)
|
|
19
|
+
--force Actually remove images. Without this, runs in dry-run mode.
|
|
20
|
+
USAGE
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
while [[ $# -gt 0 ]]; do
|
|
24
|
+
case "$1" in
|
|
25
|
+
--keep)
|
|
26
|
+
KEEP_COUNT="${2:-}"
|
|
27
|
+
shift 2
|
|
28
|
+
;;
|
|
29
|
+
--force)
|
|
30
|
+
FORCE=1
|
|
31
|
+
shift
|
|
32
|
+
;;
|
|
33
|
+
-h|--help)
|
|
34
|
+
usage
|
|
35
|
+
exit 0
|
|
36
|
+
;;
|
|
37
|
+
*)
|
|
38
|
+
echo "Unknown option: $1"
|
|
39
|
+
usage
|
|
40
|
+
exit 1
|
|
41
|
+
;;
|
|
42
|
+
esac
|
|
43
|
+
done
|
|
44
|
+
|
|
45
|
+
if ! [[ "$KEEP_COUNT" =~ ^[0-9]+$ ]] || [[ "$KEEP_COUNT" -lt 0 ]]; then
|
|
46
|
+
echo "--keep must be an integer >= 0"
|
|
47
|
+
exit 1
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
echo "Scanning Tilt images (tag starts with tilt-) ..."
|
|
51
|
+
|
|
52
|
+
# Format: REPO TAG IMAGE_ID CREATED_AT
|
|
53
|
+
# Sort newest-first by creation time so first N are retained.
|
|
54
|
+
IMAGES_RAW="$(
|
|
55
|
+
docker image ls --format '{{.Repository}} {{.Tag}} {{.ID}} {{.CreatedAt}}' \
|
|
56
|
+
| awk '$2 ~ /^tilt-/' \
|
|
57
|
+
| sort -rk4,5
|
|
58
|
+
)"
|
|
59
|
+
|
|
60
|
+
if [[ -z "${IMAGES_RAW}" ]]; then
|
|
61
|
+
echo "No tilt-* images found."
|
|
62
|
+
exit 0
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
TO_DELETE=()
|
|
66
|
+
|
|
67
|
+
echo "Retention policy: keep newest $KEEP_COUNT tilt-* images per repository"
|
|
68
|
+
|
|
69
|
+
REPOS="$(printf '%s\n' "$IMAGES_RAW" | awk '{print $1}' | sort -u)"
|
|
70
|
+
for repo in $REPOS; do
|
|
71
|
+
repo_blob="$(printf '%s\n' "$IMAGES_RAW" | awk -v r="$repo" '$1==r')"
|
|
72
|
+
total=$(printf '%s\n' "$repo_blob" | awk 'NF{c++} END{print c+0}')
|
|
73
|
+
echo "- $repo: $total tilt image(s)"
|
|
74
|
+
|
|
75
|
+
if (( total <= KEEP_COUNT )); then
|
|
76
|
+
continue
|
|
77
|
+
fi
|
|
78
|
+
|
|
79
|
+
# Delete rows after KEEP_COUNT newest.
|
|
80
|
+
i=0
|
|
81
|
+
while IFS= read -r row; do
|
|
82
|
+
[[ -z "$row" ]] && continue
|
|
83
|
+
if (( i < KEEP_COUNT )); then
|
|
84
|
+
((++i))
|
|
85
|
+
continue
|
|
86
|
+
fi
|
|
87
|
+
image_id="$(awk '{print $3}' <<< "$row")"
|
|
88
|
+
tag="$(awk '{print $2}' <<< "$row")"
|
|
89
|
+
TO_DELETE+=("$image_id|$repo:$tag")
|
|
90
|
+
((++i))
|
|
91
|
+
done <<< "$repo_blob"
|
|
92
|
+
done
|
|
93
|
+
|
|
94
|
+
if [[ ${#TO_DELETE[@]} -eq 0 ]]; then
|
|
95
|
+
echo "Nothing to remove."
|
|
96
|
+
exit 0
|
|
97
|
+
fi
|
|
98
|
+
|
|
99
|
+
echo
|
|
100
|
+
echo "Images selected for cleanup: ${#TO_DELETE[@]}"
|
|
101
|
+
for item in "${TO_DELETE[@]}"; do
|
|
102
|
+
IFS='|' read -r image_id ref <<< "$item"
|
|
103
|
+
echo " $ref ($image_id)"
|
|
104
|
+
done
|
|
105
|
+
|
|
106
|
+
echo
|
|
107
|
+
if [[ "$FORCE" -ne 1 ]]; then
|
|
108
|
+
echo "Dry-run only. Re-run with --force to remove these images."
|
|
109
|
+
exit 0
|
|
110
|
+
fi
|
|
111
|
+
|
|
112
|
+
echo "Removing old tilt images..."
|
|
113
|
+
for item in "${TO_DELETE[@]}"; do
|
|
114
|
+
IFS='|' read -r image_id ref <<< "$item"
|
|
115
|
+
if docker rmi "$image_id" >/dev/null 2>&1; then
|
|
116
|
+
echo " removed $ref ($image_id)"
|
|
117
|
+
else
|
|
118
|
+
echo " skipped $ref ($image_id) - likely in use"
|
|
119
|
+
fi
|
|
120
|
+
done
|
|
121
|
+
|
|
122
|
+
echo "Cleanup complete."
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Copyright (c) 2026 Flisk contributors
|
|
3
|
+
# SPDX-License-Identifier: MIT
|
|
4
|
+
|
|
5
|
+
# Flisk Mac M1 Resource Monitor
|
|
6
|
+
# Monitors Docker container resource usage and provides optimization recommendations
|
|
7
|
+
|
|
8
|
+
set -e
|
|
9
|
+
|
|
10
|
+
# Colors for output
|
|
11
|
+
RED='\033[0;31m'
|
|
12
|
+
GREEN='\033[0;32m'
|
|
13
|
+
YELLOW='\033[1;33m'
|
|
14
|
+
BLUE='\033[0;34m'
|
|
15
|
+
NC='\033[0m' # No Color
|
|
16
|
+
|
|
17
|
+
echo -e "${BLUE}🍎 Flisk Mac M1 Resource Monitor${NC}"
|
|
18
|
+
echo "=================================================="
|
|
19
|
+
|
|
20
|
+
# Check if Docker is running
|
|
21
|
+
if ! docker info >/dev/null 2>&1; then
|
|
22
|
+
echo -e "${RED}❌ Docker is not running${NC}"
|
|
23
|
+
exit 1
|
|
24
|
+
fi
|
|
25
|
+
|
|
26
|
+
# Get Docker Desktop memory limit
|
|
27
|
+
DOCKER_MEMORY=$(docker system info 2>/dev/null | grep -i "total memory" | awk '{print $3 $4}' || echo "Unknown")
|
|
28
|
+
echo -e "${BLUE}🐳 Docker Memory Limit:${NC} $DOCKER_MEMORY"
|
|
29
|
+
|
|
30
|
+
# Get system memory info (macOS)
|
|
31
|
+
SYSTEM_MEMORY=$(system_profiler SPHardwareDataType | grep "Memory:" | awk '{print $2 $3}' || echo "Unknown")
|
|
32
|
+
echo -e "${BLUE}💻 System Memory:${NC} $SYSTEM_MEMORY"
|
|
33
|
+
|
|
34
|
+
echo ""
|
|
35
|
+
|
|
36
|
+
# Check running Flisk containers
|
|
37
|
+
PROJECT_CONTAINERS=$(docker ps --format "{{.Names}}" | grep -E "(postgres|redis|nats|kafka|traefik|clickhouse|elasticsearch|verdaccio|infisical)" | sort)
|
|
38
|
+
|
|
39
|
+
if [ -z "$PROJECT_CONTAINERS" ]; then
|
|
40
|
+
echo -e "${YELLOW}⚠️ No Flisk containers are currently running${NC}"
|
|
41
|
+
echo "Run 'tilt up' to start services"
|
|
42
|
+
exit 0
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
echo -e "${GREEN}📊 Running Flisk Containers:${NC}"
|
|
46
|
+
echo "=================================================="
|
|
47
|
+
|
|
48
|
+
# Get detailed stats for Flisk containers
|
|
49
|
+
TOTAL_MEMORY_MB=0
|
|
50
|
+
HIGH_CPU_COUNT=0
|
|
51
|
+
HIGH_MEMORY_COUNT=0
|
|
52
|
+
|
|
53
|
+
echo -e "${BLUE}Container Name${NC}\t\t${BLUE}CPU%${NC}\t${BLUE}Memory${NC}\t${BLUE}Status${NC}"
|
|
54
|
+
echo "------------------------------------------------------------------------"
|
|
55
|
+
|
|
56
|
+
while IFS= read -r container; do
|
|
57
|
+
if [ -n "$container" ]; then
|
|
58
|
+
# Get container stats
|
|
59
|
+
STATS=$(docker stats --no-stream --format "{{.CPUPerc}}\t{{.MemUsage}}" "$container" 2>/dev/null || echo "N/A\tN/A")
|
|
60
|
+
CPU_PERCENT=$(echo "$STATS" | cut -f1 | sed 's/%//')
|
|
61
|
+
MEMORY_USAGE=$(echo "$STATS" | cut -f2)
|
|
62
|
+
|
|
63
|
+
# Extract memory in MB for calculation
|
|
64
|
+
MEMORY_MB=$(echo "$MEMORY_USAGE" | grep -o '[0-9.]*MiB' | sed 's/MiB//' || echo "0")
|
|
65
|
+
if [ -z "$MEMORY_MB" ]; then
|
|
66
|
+
MEMORY_MB=0
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
# Status indicators
|
|
70
|
+
STATUS=""
|
|
71
|
+
if (( $(echo "$CPU_PERCENT > 50" | bc -l 2>/dev/null || echo 0) )); then
|
|
72
|
+
STATUS="${RED}🔥 HIGH CPU${NC}"
|
|
73
|
+
HIGH_CPU_COUNT=$((HIGH_CPU_COUNT + 1))
|
|
74
|
+
elif (( $(echo "$MEMORY_MB > 200" | bc -l 2>/dev/null || echo 0) )); then
|
|
75
|
+
STATUS="${YELLOW}⚠️ HIGH MEM${NC}"
|
|
76
|
+
HIGH_MEMORY_COUNT=$((HIGH_MEMORY_COUNT + 1))
|
|
77
|
+
else
|
|
78
|
+
STATUS="${GREEN}✅ OK${NC}"
|
|
79
|
+
fi
|
|
80
|
+
|
|
81
|
+
# Add to total memory
|
|
82
|
+
TOTAL_MEMORY_MB=$(echo "$TOTAL_MEMORY_MB + $MEMORY_MB" | bc -l 2>/dev/null || echo "$TOTAL_MEMORY_MB")
|
|
83
|
+
|
|
84
|
+
# Format container name for display
|
|
85
|
+
CONTAINER_DISPLAY=$(echo "$container" | sed 's/TDK_//' | cut -c1-20)
|
|
86
|
+
|
|
87
|
+
printf "%-20s\t%s%%\t%s\t%s\n" "$CONTAINER_DISPLAY" "$CPU_PERCENT" "$MEMORY_USAGE" "$STATUS"
|
|
88
|
+
fi
|
|
89
|
+
done <<< "$PROJECT_CONTAINERS"
|
|
90
|
+
|
|
91
|
+
echo ""
|
|
92
|
+
echo -e "${BLUE}📈 Resource Summary:${NC}"
|
|
93
|
+
echo "=================================================="
|
|
94
|
+
echo -e "Total Memory Usage: ${YELLOW}~${TOTAL_MEMORY_MB}MB${NC}"
|
|
95
|
+
echo -e "High CPU Containers: ${RED}$HIGH_CPU_COUNT${NC}"
|
|
96
|
+
echo -e "High Memory Containers: ${YELLOW}$HIGH_MEMORY_COUNT${NC}"
|
|
97
|
+
|
|
98
|
+
# Recommendations
|
|
99
|
+
echo ""
|
|
100
|
+
echo -e "${BLUE}🔧 Mac M1 Optimization Recommendations:${NC}"
|
|
101
|
+
echo "=================================================="
|
|
102
|
+
|
|
103
|
+
if (( $(echo "$TOTAL_MEMORY_MB > 3000" | bc -l 2>/dev/null || echo 0) )); then
|
|
104
|
+
echo -e "${RED}⚠️ HIGH MEMORY USAGE DETECTED!${NC}"
|
|
105
|
+
echo "• Consider stopping unnecessary services with 'tilt down'"
|
|
106
|
+
echo "• Avoid running monitoring + elk + all apps simultaneously"
|
|
107
|
+
echo "• Use selective service loading: 'tilt up --focus <domain>' instead of all services"
|
|
108
|
+
elif (( $(echo "$TOTAL_MEMORY_MB > 2000" | bc -l 2>/dev/null || echo 0) )); then
|
|
109
|
+
echo -e "${YELLOW}⚡ MODERATE MEMORY USAGE${NC}"
|
|
110
|
+
echo "• Memory usage is acceptable for Mac M1"
|
|
111
|
+
echo "• Monitor for performance issues"
|
|
112
|
+
else
|
|
113
|
+
echo -e "${GREEN}✅ OPTIMAL MEMORY USAGE${NC}"
|
|
114
|
+
echo "• Memory usage is well optimized for Mac M1"
|
|
115
|
+
fi
|
|
116
|
+
|
|
117
|
+
echo ""
|
|
118
|
+
echo "• Increase Docker Desktop memory limit to 6-8GB if experiencing issues"
|
|
119
|
+
echo "• Use 'tilt trigger resource-monitor' for regular monitoring"
|
|
120
|
+
echo "• Use 'tilt trigger memory-optimizer' for additional suggestions"
|
|
121
|
+
|
|
122
|
+
echo ""
|
|
123
|
+
echo -e "${BLUE}🔄 To refresh this report: ./.tilt/assets/scripts/mac-m1-resource-monitor.sh${NC}"
|