@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.
Files changed (440) hide show
  1. package/CHANGELOG.md +492 -0
  2. package/LICENSE +21 -0
  3. package/README.md +479 -2
  4. package/Tiltfile +151 -0
  5. package/cli/bin/flisk.js +42 -0
  6. package/cli/dist/agent-runtimes/custom.js +335 -0
  7. package/cli/dist/agent-runtimes/registry.js +34 -0
  8. package/cli/dist/backend-frameworks/elysia.js +38 -0
  9. package/cli/dist/backend-frameworks/express.js +49 -0
  10. package/cli/dist/backend-frameworks/fastify.js +43 -0
  11. package/cli/dist/backend-frameworks/h3.js +37 -0
  12. package/cli/dist/backend-frameworks/koa.js +47 -0
  13. package/cli/dist/backend-frameworks/mcp.js +86 -0
  14. package/cli/dist/backend-frameworks/nestjs.js +55 -0
  15. package/cli/dist/backend-frameworks/registry.js +134 -0
  16. package/cli/dist/backend-frameworks/types.js +1 -0
  17. package/cli/dist/backend-languages/bun.js +76 -0
  18. package/cli/dist/backend-languages/go.js +125 -0
  19. package/cli/dist/backend-languages/node.js +122 -0
  20. package/cli/dist/backend-languages/python.js +94 -0
  21. package/cli/dist/backend-languages/registry.js +37 -0
  22. package/cli/dist/backend-languages/rust.js +82 -0
  23. package/cli/dist/backend-languages/types.js +1 -0
  24. package/cli/dist/cli.js +29 -0
  25. package/cli/dist/commands/__tests__/project-e2e-helpers.js +49 -0
  26. package/cli/dist/commands/__tests__/ui-loading-screen.test.js +16 -0
  27. package/cli/dist/commands/agent.js +182 -0
  28. package/cli/dist/commands/completion-candidates.js +116 -0
  29. package/cli/dist/commands/completion.js +843 -0
  30. package/cli/dist/commands/config.js +362 -0
  31. package/cli/dist/commands/doctor.js +1504 -0
  32. package/cli/dist/commands/down.js +114 -0
  33. package/cli/dist/commands/eject.js +108 -0
  34. package/cli/dist/commands/help.js +152 -0
  35. package/cli/dist/commands/import.js +164 -0
  36. package/cli/dist/commands/logs.js +119 -0
  37. package/cli/dist/commands/maintainers.js +102 -0
  38. package/cli/dist/commands/mcp.js +28 -0
  39. package/cli/dist/commands/networks.js +306 -0
  40. package/cli/dist/commands/project.js +447 -0
  41. package/cli/dist/commands/projects.js +103 -0
  42. package/cli/dist/commands/registry.js +53 -0
  43. package/cli/dist/commands/resource.js +992 -0
  44. package/cli/dist/commands/resources.js +127 -0
  45. package/cli/dist/commands/restart.js +89 -0
  46. package/cli/dist/commands/runtime.js +75 -0
  47. package/cli/dist/commands/stack.js +171 -0
  48. package/cli/dist/commands/stacks.js +71 -0
  49. package/cli/dist/commands/status.js +211 -0
  50. package/cli/dist/commands/ui.js +725 -0
  51. package/cli/dist/commands/up.js +609 -0
  52. package/cli/dist/commands/upgrade.js +840 -0
  53. package/cli/dist/commands/version.js +10 -0
  54. package/cli/dist/components/Accessible.js +11 -0
  55. package/cli/dist/components/BaseTooltip.js +30 -0
  56. package/cli/dist/components/DetailPanel.js +33 -0
  57. package/cli/dist/components/FileTree.js +51 -0
  58. package/cli/dist/components/ResourceSelectInput.js +42 -0
  59. package/cli/dist/components/ResourceTable.js +35 -0
  60. package/cli/dist/components/ServiceIssues.js +13 -0
  61. package/cli/dist/components/TUIHeader.js +27 -0
  62. package/cli/dist/components/TabBar.js +27 -0
  63. package/cli/dist/components/Tooltip.js +13 -0
  64. package/cli/dist/components/index.js +11 -0
  65. package/cli/dist/components/ui-theme.js +120 -0
  66. package/cli/dist/config/platform-standards.js +182 -0
  67. package/cli/dist/frontend-frameworks/lit.js +64 -0
  68. package/cli/dist/frontend-frameworks/preact.js +62 -0
  69. package/cli/dist/frontend-frameworks/qwik.js +61 -0
  70. package/cli/dist/frontend-frameworks/react.js +69 -0
  71. package/cli/dist/frontend-frameworks/registry.js +83 -0
  72. package/cli/dist/frontend-frameworks/solid.js +62 -0
  73. package/cli/dist/frontend-frameworks/svelte.js +67 -0
  74. package/cli/dist/frontend-frameworks/tanstack-router.js +101 -0
  75. package/cli/dist/frontend-frameworks/types.js +1 -0
  76. package/cli/dist/frontend-frameworks/vanilla.js +59 -0
  77. package/cli/dist/frontend-frameworks/vue.js +72 -0
  78. package/cli/dist/generator/__tests__/golden-helpers.js +43 -0
  79. package/cli/dist/generator/extension-fetch.js +291 -0
  80. package/cli/dist/generator/resource-templates.js +133 -0
  81. package/cli/dist/generator/template-engine.js +801 -0
  82. package/cli/dist/index.js +10 -0
  83. package/cli/dist/mcp/server.js +101 -0
  84. package/cli/dist/mcp/tools.js +351 -0
  85. package/cli/dist/program.js +37 -0
  86. package/cli/dist/types/index.js +38 -0
  87. package/cli/dist/utils/agent-host.js +36 -0
  88. package/cli/dist/utils/atomic-write.js +36 -0
  89. package/cli/dist/utils/bun-floor.js +9 -0
  90. package/cli/dist/utils/bun-requirement.js +10 -0
  91. package/cli/dist/utils/cache.js +63 -0
  92. package/cli/dist/utils/cold-preflight.js +257 -0
  93. package/cli/dist/utils/command-helpers.js +57 -0
  94. package/cli/dist/utils/constants.js +160 -0
  95. package/cli/dist/utils/discovery-context.js +71 -0
  96. package/cli/dist/utils/discovery-paths.js +93 -0
  97. package/cli/dist/utils/docker.js +34 -0
  98. package/cli/dist/utils/doctor-crashloop.js +161 -0
  99. package/cli/dist/utils/doctor-fix.js +391 -0
  100. package/cli/dist/utils/doctor-host.js +66 -0
  101. package/cli/dist/utils/doctor-report.js +78 -0
  102. package/cli/dist/utils/doctor-runtime.js +880 -0
  103. package/cli/dist/utils/doctor-starlark.js +132 -0
  104. package/cli/dist/utils/doctor-wiring.js +698 -0
  105. package/cli/dist/utils/down-cleanup.js +125 -0
  106. package/cli/dist/utils/env-validator.js +266 -0
  107. package/cli/dist/utils/errors.js +175 -0
  108. package/cli/dist/utils/exec-async.js +31 -0
  109. package/cli/dist/utils/file-helpers.js +104 -0
  110. package/cli/dist/utils/formatting.js +165 -0
  111. package/cli/dist/utils/generated-paths.js +51 -0
  112. package/cli/dist/utils/help-command.js +11 -0
  113. package/cli/dist/utils/host-port-config.js +140 -0
  114. package/cli/dist/utils/host-port-plan.js +100 -0
  115. package/cli/dist/utils/json-output.js +29 -0
  116. package/cli/dist/utils/machine-output.js +33 -0
  117. package/cli/dist/utils/paths.js +43 -0
  118. package/cli/dist/utils/platform.js +58 -0
  119. package/cli/dist/utils/port-assignment.js +75 -0
  120. package/cli/dist/utils/port-conflict-fix.js +25 -0
  121. package/cli/dist/utils/port-fallback-notice.js +17 -0
  122. package/cli/dist/utils/port-listener-probe.js +20 -0
  123. package/cli/dist/utils/project-config-defaults.js +17 -0
  124. package/cli/dist/utils/project-features.js +91 -0
  125. package/cli/dist/utils/project-templates.js +32 -0
  126. package/cli/dist/utils/prompt.js +97 -0
  127. package/cli/dist/utils/resource-features.js +184 -0
  128. package/cli/dist/utils/resource-kind.js +9 -0
  129. package/cli/dist/utils/schema-version-gate.js +45 -0
  130. package/cli/dist/utils/search-status.js +12 -0
  131. package/cli/dist/utils/secret-redaction.js +73 -0
  132. package/cli/dist/utils/service-config-checks.js +189 -0
  133. package/cli/dist/utils/service-manifest.js +254 -0
  134. package/cli/dist/utils/service-runtime-state.js +66 -0
  135. package/cli/dist/utils/service-urls.js +112 -0
  136. package/cli/dist/utils/services.js +360 -0
  137. package/cli/dist/utils/shared-infra.js +45 -0
  138. package/cli/dist/utils/shared-platform-postgres.js +232 -0
  139. package/cli/dist/utils/single-flight.js +21 -0
  140. package/cli/dist/utils/smoke.js +401 -0
  141. package/cli/dist/utils/spinner.js +40 -0
  142. package/cli/dist/utils/stack-features.js +15 -0
  143. package/cli/dist/utils/stack-status.js +14 -0
  144. package/cli/dist/utils/startup-report.js +78 -0
  145. package/cli/dist/utils/status-message.js +21 -0
  146. package/cli/dist/utils/status-ports.js +33 -0
  147. package/cli/dist/utils/suggestions.js +63 -0
  148. package/cli/dist/utils/tar.js +46 -0
  149. package/cli/dist/utils/tdk-version.js +51 -0
  150. package/cli/dist/utils/terminal-layout.js +19 -0
  151. package/cli/dist/utils/tilt-events.js +194 -0
  152. package/cli/dist/utils/tilt-logs.js +61 -0
  153. package/cli/dist/utils/tilt-port-owner.js +63 -0
  154. package/cli/dist/utils/tilt-process.js +54 -0
  155. package/cli/dist/utils/tilt-resource-state.js +32 -0
  156. package/cli/dist/utils/tilt-startup.js +49 -0
  157. package/cli/dist/utils/tilt-unreachable-message.js +9 -0
  158. package/cli/dist/utils/tilt.js +104 -0
  159. package/cli/dist/utils/ui-keymap.js +129 -0
  160. package/cli/dist/utils/ui-service-state.js +34 -0
  161. package/cli/dist/utils/up-only.js +28 -0
  162. package/cli/dist/utils/up-readiness.js +118 -0
  163. package/cli/dist/utils/url-actions.js +103 -0
  164. package/cli/dist/utils/validation.js +62 -0
  165. package/cli/dist/utils/which.js +56 -0
  166. package/cli/dist/utils/windows-doctor.js +176 -0
  167. package/cli/dist-bundle/chunk-6EA4DGCY.js +2 -0
  168. package/cli/dist-bundle/chunk-BZ4H7MM4.js +3 -0
  169. package/cli/dist-bundle/chunk-CLCUIDBH.js +510 -0
  170. package/cli/dist-bundle/cli.js +2017 -0
  171. package/cli/dist-bundle/cold-preflight-SY26O2IG.js +2 -0
  172. package/cli/dist-bundle/devtools-ZUHXW33W.js +5 -0
  173. package/cli/dist-bundle/extension-fetch-J4FFH7TJ.js +2 -0
  174. package/cli/package.json +83 -0
  175. package/cli/shared-platform-engineering/docker-templates/bun-hoisted-symlink-fix.sh +25 -0
  176. package/cli/shared-platform-engineering/docker-templates/infisical-entrypoint.sh +466 -0
  177. package/cli/shared-platform-engineering/docker-templates/install-deps.sh +154 -0
  178. package/cli/shared-platform-engineering/docker-templates/prisma-bun-client-link-fix.sh +14 -0
  179. package/cli/shared-platform-engineering/docker-templates/prisma-normalize-client.sh +58 -0
  180. package/cli/templates/.tiltignore.hbs +72 -0
  181. package/cli/templates/TILT_RESOURCE_DEFAULTS.star.hbs +220 -0
  182. package/cli/templates/TILT_TECH_STACK.star.hbs +149 -0
  183. package/cli/templates/Tiltfile.hbs +381 -0
  184. package/cli/templates/spec.master.hbs +192 -0
  185. package/discovery/AGENTS.md +362 -0
  186. package/discovery/TILT_DISCOVERY.star +429 -0
  187. package/discovery/Tiltfile +58 -0
  188. package/discovery/config.star +265 -0
  189. package/discovery/constants.star +167 -0
  190. package/discovery/deterministic.star +213 -0
  191. package/discovery/discovery_daemon.star +193 -0
  192. package/discovery/discovery_orchestrator.star +492 -0
  193. package/discovery/filtering.star +7 -0
  194. package/discovery/identity-management-backend/service.yaml +26 -0
  195. package/discovery/identity-management-frontend/service.yaml +29 -0
  196. package/discovery/identity-sdk/service.yaml +9 -0
  197. package/discovery/incremental_discovery.star +215 -0
  198. package/discovery/indexing.star +9 -0
  199. package/discovery/json_manifest_scanner.star +57 -0
  200. package/discovery/libraries.star +48 -0
  201. package/discovery/loading.star +25 -0
  202. package/discovery/manifest/constants.star +106 -0
  203. package/discovery/manifest/loading.star +418 -0
  204. package/discovery/manifest/normalize.star +289 -0
  205. package/discovery/manifest/validation.star +110 -0
  206. package/discovery/normalization.star +13 -0
  207. package/discovery/registry.star +562 -0
  208. package/discovery/resource_snapshot.py +384 -0
  209. package/discovery/resource_snapshot.star +145 -0
  210. package/discovery/schemas.star +3 -0
  211. package/discovery/services/platform/cdc/debezium/nats-connector/service.yaml +9 -0
  212. package/discovery/services/platform/cdc/nats-http-bridge/service.yaml +9 -0
  213. package/discovery/services/platform/orchestrator/orchestrator-glue-backend/service.yaml +26 -0
  214. package/discovery/services/platform/synthetic-monitor/service.yaml +9 -0
  215. package/discovery/test_resource_snapshot.py +253 -0
  216. package/discovery/validation.star +80 -0
  217. package/discovery/versioning.star +3 -0
  218. package/engine/AGENTS.md +706 -0
  219. package/engine/README.md +31 -0
  220. package/engine/REFACTORING_MANIFEST_SYSTEM.md +974 -0
  221. package/engine/Tiltfile +86 -0
  222. package/engine/assets/docker/golden-layers.Dockerfile +204 -0
  223. package/engine/assets/docker/wake-gateway/Dockerfile +28 -0
  224. package/engine/assets/docker/wake-gateway/decide.test.ts +177 -0
  225. package/engine/assets/docker/wake-gateway/decide.ts +135 -0
  226. package/engine/assets/docker/wake-gateway/server.ts +363 -0
  227. package/engine/assets/scripts/cleanup-completed-migrator-images.sh +39 -0
  228. package/engine/assets/scripts/cleanup-tilt-images.sh +122 -0
  229. package/engine/assets/scripts/mac-m1-resource-monitor.sh +123 -0
  230. package/engine/config.star +5 -0
  231. package/engine/entrypoint.star +101 -0
  232. package/engine/lifecycle/orchestrator.star +263 -0
  233. package/engine/paths.star +719 -0
  234. package/engine/schemas/project-schema.json +147 -0
  235. package/engine/schemas/service-schema.json +537 -0
  236. package/engine/scripts/README.md +89 -0
  237. package/engine/scripts/build-and-publish-lib.sh +207 -0
  238. package/engine/scripts/check-lib-publish.sh +87 -0
  239. package/engine/scripts/debug-container.sh +265 -0
  240. package/engine/scripts/generate-manifest.sh +200 -0
  241. package/engine/spec.master +702 -0
  242. package/engine/spec.master.example +341 -0
  243. package/engine/topologies/README.md +33 -0
  244. package/engine/topologies/platform/docker/AGENTS.md +59 -0
  245. package/engine/topologies/platform/docker/auth/auth.star +207 -0
  246. package/engine/topologies/platform/docker/build/frontend_build_plan.star +65 -0
  247. package/engine/topologies/platform/docker/build/golden_image.star +37 -0
  248. package/engine/topologies/platform/docker/build/golden_image_build.star +144 -0
  249. package/engine/topologies/platform/docker/build/golden_image_constants.star +100 -0
  250. package/engine/topologies/platform/docker/build/golden_image_dockerfile.star +263 -0
  251. package/engine/topologies/platform/docker/compose/compose.star +637 -0
  252. package/engine/topologies/platform/docker/compose/compose_helpers.star +54 -0
  253. package/engine/topologies/platform/docker/compose/traefik_standalone.star +171 -0
  254. package/engine/topologies/platform/docker/config/bunignore.star +144 -0
  255. package/engine/topologies/platform/docker/config/dockerignore.star +152 -0
  256. package/engine/topologies/platform/docker/config/healthcheck.star +58 -0
  257. package/engine/topologies/platform/docker/constants.star +211 -0
  258. package/engine/topologies/platform/docker/dockerfile/dockerfile.star +56 -0
  259. package/engine/topologies/platform/docker/dockerfile/language_dockerfile.star +264 -0
  260. package/engine/topologies/platform/docker/generators/golden_docker_generator_v2.star +76 -0
  261. package/engine/topologies/platform/docker/index.star +40 -0
  262. package/engine/topologies/platform/docker/layers/bun_helpers.star +25 -0
  263. package/engine/topologies/platform/docker/layers/infisical/index.star +42 -0
  264. package/engine/topologies/platform/docker/layers/infisical/infisical_docker.star +264 -0
  265. package/engine/topologies/platform/docker/layers/l1_base_layers.star +89 -0
  266. package/engine/topologies/platform/docker/layers/l2_dependency_layers.star +147 -0
  267. package/engine/topologies/platform/docker/layers/l3_builder_layers.star +229 -0
  268. package/engine/topologies/platform/docker/layers/l4_runtime_layers.star +282 -0
  269. package/engine/topologies/platform/docker/layers/prisma/constants.star +138 -0
  270. package/engine/topologies/platform/docker/layers/prisma/db_readiness.star +98 -0
  271. package/engine/topologies/platform/docker/layers/prisma/filesystem_setup.star +131 -0
  272. package/engine/topologies/platform/docker/layers/prisma/migrate_script.star +100 -0
  273. package/engine/topologies/platform/docker/layers/prisma/prisma_build.star +128 -0
  274. package/engine/topologies/platform/docker/layers/prisma/prisma_runtime.star +205 -0
  275. package/engine/topologies/platform/docker/layers/prisma/secret_resolution.star +121 -0
  276. package/engine/topologies/platform/docker/networking/api_path_constants.star +206 -0
  277. package/engine/topologies/platform/docker/networking/sablier_container_cycle.star +31 -0
  278. package/engine/topologies/platform/docker/networking/traefik.star +266 -0
  279. package/engine/topologies/platform/docker/networking/traefik_constants.star +148 -0
  280. package/engine/topologies/platform/docker/networking/traefik_helpers.star +162 -0
  281. package/engine/topologies/platform/docker/networking/traefik_static_routes.star +165 -0
  282. package/engine/topologies/platform/docker/secrets/env_secrets.star +74 -0
  283. package/engine/topologies/platform/docker/secrets/infisical.star +109 -0
  284. package/engine/topologies/platform/net/AGENTS.md +64 -0
  285. package/engine/topologies/platform/net/proxy.star +6 -0
  286. package/engine/topologies/platform/registries/local.star +6 -0
  287. package/engine/topologies/platform/registries/verdaccio_loader.star +20 -0
  288. package/engine/topologies/platform/security/AGENTS.md +49 -0
  289. package/engine/topologies/platform/security/secrets.star +241 -0
  290. package/engine/topologies/platform/state/AGENTS.md +64 -0
  291. package/engine/topologies/platform/state/relational.star +6 -0
  292. package/engine/topologies/tilt/common/AGENTS.md +59 -0
  293. package/engine/topologies/tilt/common/utils.star +409 -0
  294. package/engine/topologies/tilt/common/utils_debug.star +71 -0
  295. package/engine/topologies/tilt/common/utils_deterministic.star +170 -0
  296. package/engine/topologies/tilt/common/utils_docker_networks.star +54 -0
  297. package/engine/topologies/tilt/common/utils_env.star +92 -0
  298. package/engine/topologies/tilt/common/utils_output.star +99 -0
  299. package/engine/topologies/tilt/config/AGENTS.md +68 -0
  300. package/engine/topologies/tilt/config/defaults.star +5 -0
  301. package/engine/topologies/tilt/config/feature_flags.star +12 -0
  302. package/engine/topologies/tilt/config/global.star +57 -0
  303. package/engine/topologies/tilt/config/profiles.star +398 -0
  304. package/engine/topologies/tilt/generators/agents_md.star +64 -0
  305. package/engine/topologies/tilt/generators/api_gateway.star +147 -0
  306. package/engine/topologies/tilt/generators/index.star +126 -0
  307. package/engine/topologies/tilt/generators/infisical/README.md +424 -0
  308. package/engine/topologies/tilt/generators/infisical/examples.star +314 -0
  309. package/engine/topologies/tilt/generators/infisical/index.star +59 -0
  310. package/engine/topologies/tilt/generators/infisical/machine_identity.star +422 -0
  311. package/engine/topologies/tilt/generators/infisical/organization.star +536 -0
  312. package/engine/topologies/tilt/generators/infisical/path_manager.star +478 -0
  313. package/engine/topologies/tilt/generators/infisical/secrets_generator.star +422 -0
  314. package/engine/topologies/tilt/generators/nginx_conf.star +145 -0
  315. package/engine/topologies/tilt/generators/npmrc.star +132 -0
  316. package/engine/topologies/tilt/generators/tsconfig.star +25 -0
  317. package/engine/topologies/tilt/generators/typescript/backend_library_tsconfig.star +73 -0
  318. package/engine/topologies/tilt/generators/typescript/backend_tsconfig.star +137 -0
  319. package/engine/topologies/tilt/generators/typescript/common.star +9 -0
  320. package/engine/topologies/tilt/generators/typescript/frontend_library_tsconfig.star +78 -0
  321. package/engine/topologies/tilt/generators/typescript/frontend_tsconfig.star +140 -0
  322. package/engine/topologies/tilt/generators/typescript/include.star +25 -0
  323. package/engine/topologies/tilt/generators/typescript/playwright_config.star +42 -0
  324. package/engine/topologies/tilt/generators/typescript/prisma_config.star +51 -0
  325. package/engine/topologies/tilt/generators/validators.star +868 -0
  326. package/engine/topologies/tilt/generators/vite/backend.star +80 -0
  327. package/engine/topologies/tilt/generators/vite/frameworks/lit.star +92 -0
  328. package/engine/topologies/tilt/generators/vite/frameworks/preact.star +94 -0
  329. package/engine/topologies/tilt/generators/vite/frameworks/qwik.star +94 -0
  330. package/engine/topologies/tilt/generators/vite/frameworks/react.star +128 -0
  331. package/engine/topologies/tilt/generators/vite/frameworks/solid.star +94 -0
  332. package/engine/topologies/tilt/generators/vite/frameworks/svelte.star +94 -0
  333. package/engine/topologies/tilt/generators/vite/frameworks/vanilla.star +92 -0
  334. package/engine/topologies/tilt/generators/vite/frameworks/vue.star +94 -0
  335. package/engine/topologies/tilt/generators/vite/frontend.star +153 -0
  336. package/engine/topologies/tilt/generators/vite/generators.star +45 -0
  337. package/engine/topologies/tilt/generators/vite/helpers.star +256 -0
  338. package/engine/topologies/tilt/generators/vite/library.star +67 -0
  339. package/engine/topologies/tilt/generators/vite/sdk.star +75 -0
  340. package/engine/topologies/tilt/generators/vite/templates.star +460 -0
  341. package/engine/topologies/tilt/generators/vite_config.star +24 -0
  342. package/engine/topologies/tilt/manifest/AGENTS.md +61 -0
  343. package/engine/topologies/tilt/manifest/README.md +679 -0
  344. package/engine/topologies/tilt/manifest/__init__.star +220 -0
  345. package/engine/topologies/tilt/manifest/constants.star +262 -0
  346. package/engine/topologies/tilt/manifest/errors.star +268 -0
  347. package/engine/topologies/tilt/manifest/integration.star +348 -0
  348. package/engine/topologies/tilt/manifest/json_to_yaml.py +61 -0
  349. package/engine/topologies/tilt/manifest/loader.star +239 -0
  350. package/engine/topologies/tilt/manifest/mapper.star +229 -0
  351. package/engine/topologies/tilt/manifest/parser.star +490 -0
  352. package/engine/topologies/tilt/manifest/schema.star +502 -0
  353. package/engine/topologies/tilt/manifest/tests/test_integration.star +278 -0
  354. package/engine/topologies/tilt/manifest/tests/test_loader_parser.star +475 -0
  355. package/engine/topologies/tilt/manifest/tests/test_manifest.star +319 -0
  356. package/engine/topologies/tilt/manifest/tests/test_validator.star +472 -0
  357. package/engine/topologies/tilt/manifest/validator.star +744 -0
  358. package/engine/topologies/tilt/manifest/yaml_to_json.py +20 -0
  359. package/engine/topologies/tilt/resources/AGENTS.md +71 -0
  360. package/engine/topologies/tilt/resources/build_concurrency.star +56 -0
  361. package/engine/topologies/tilt/resources/conditions.star +5 -0
  362. package/engine/topologies/tilt/resources/databases.star +246 -0
  363. package/engine/topologies/tilt/resources/declaration.star +5 -0
  364. package/engine/topologies/tilt/resources/deps.star +5 -0
  365. package/engine/topologies/tilt/resources/infra-loader.star +504 -0
  366. package/engine/topologies/tilt/resources/libs.star +32 -0
  367. package/engine/topologies/tilt/resources/libs_discovery.star +104 -0
  368. package/engine/topologies/tilt/resources/libs_paths.star +81 -0
  369. package/engine/topologies/tilt/resources/libs_resource_definition.star +153 -0
  370. package/engine/topologies/tilt/resources/libs_setup.star +166 -0
  371. package/engine/topologies/tilt/resources/libs_tsconfig.star +39 -0
  372. package/engine/topologies/tilt/resources/orchestrator/apply.star +79 -0
  373. package/engine/topologies/tilt/resources/orchestrator/apply_compose_resource_registration.star +864 -0
  374. package/engine/topologies/tilt/resources/orchestrator/apply_manifest_orchestration.star +90 -0
  375. package/engine/topologies/tilt/resources/orchestrator/apply_migrator_orchestration.star +150 -0
  376. package/engine/topologies/tilt/resources/orchestrator/apply_resource_validation.star +38 -0
  377. package/engine/topologies/tilt/resources/orchestrator/apply_runtime_flags.star +46 -0
  378. package/engine/topologies/tilt/resources/orchestrator/builders/typescript.star +193 -0
  379. package/engine/topologies/tilt/resources/orchestrator/generators/dependencies/AGENTS.md +75 -0
  380. package/engine/topologies/tilt/resources/orchestrator/generators/dependencies/index.star +23 -0
  381. package/engine/topologies/tilt/resources/orchestrator/generators/dependencies/resolver.star +136 -0
  382. package/engine/topologies/tilt/resources/orchestrator/generators/env.star +219 -0
  383. package/engine/topologies/tilt/resources/orchestrator/generators/frontend.star +172 -0
  384. package/engine/topologies/tilt/resources/orchestrator/generators/manifest_resource.star +577 -0
  385. package/engine/topologies/tilt/resources/orchestrator/helpers.star +35 -0
  386. package/engine/topologies/tilt/resources/orchestrator.star +56 -0
  387. package/engine/topologies/tilt/resources/ordering.star +5 -0
  388. package/engine/topologies/tilt/resources/shared-platform-postgres.star +30 -0
  389. package/engine/topologies/tilt/resources/triggers.star +5 -0
  390. package/engine/topologies/tilt/resources/watchers.star +304 -0
  391. package/engine/where-things-live.star +719 -0
  392. package/examples/tdk-example/LICENSE +21 -0
  393. package/examples/tdk-example/README.md +23 -0
  394. package/examples/tdk-example/TILT_SERVICE_DEFAULTS.star +42 -0
  395. package/examples/tdk-example/TILT_TECH_STACK.star +67 -0
  396. package/examples/tdk-example/Tiltfile +25 -0
  397. package/examples/tdk-example/services/platform/messaging/docker-compose.yml +26 -0
  398. package/examples/tdk-example/services/shop/orders-api/package.json +20 -0
  399. package/examples/tdk-example/services/shop/orders-api/service.json +14 -0
  400. package/examples/tdk-example/services/shop/orders-api/src/index.ts +81 -0
  401. package/examples/tdk-example/services/shop/orders-app/index.html +12 -0
  402. package/examples/tdk-example/services/shop/orders-app/package.json +23 -0
  403. package/examples/tdk-example/services/shop/orders-app/public/.gitkeep +0 -0
  404. package/examples/tdk-example/services/shop/orders-app/service.json +9 -0
  405. package/examples/tdk-example/services/shop/orders-app/src/main.tsx +9 -0
  406. package/examples/tdk-example/services/shop/orders-app/src/orders.tsx +67 -0
  407. package/examples/tdk-example/services/shop/orders-app/src/style.css +15 -0
  408. package/examples/tdk-example/services/shop/orders-worker/package.json +18 -0
  409. package/examples/tdk-example/services/shop/orders-worker/service.json +13 -0
  410. package/examples/tdk-example/services/shop/orders-worker/src/index.ts +33 -0
  411. package/ext/Tiltfile +66 -0
  412. package/ext/ide-components/README.md +221 -0
  413. package/ext/ide-components/code_viewer/server.py +208 -0
  414. package/ext/ide-components/config_inspector/server.py +1052 -0
  415. package/ext/ide-components/file_browser/server.py +287 -0
  416. package/ext/ide-components/shared/config_service.py +471 -0
  417. package/ext/ide-components/shared/file_utils.py +300 -0
  418. package/ext/ide-components/shared/http_utils.py +234 -0
  419. package/ext/ide-components/shared/static/styles.css +1334 -0
  420. package/ext/ide-components/shared/syntax_highlighter.py +142 -0
  421. package/ext/ide-components/shared/template_engine.py +125 -0
  422. package/ext/ide-components/shared/templates/base.html +121 -0
  423. package/ext/ide-components/shared/test_config_service.py +328 -0
  424. package/ext/ide-components/shared/tilt_integration.py +160 -0
  425. package/ext/ui-enhancements/cron-status-server.sh +51 -0
  426. package/ext/ui-enhancements/cron-status-tracker.sh +148 -0
  427. package/ext/ui-enhancements/extension.yaml +36 -0
  428. package/ext/ui-enhancements/tiltfile.py +101 -0
  429. package/ext/ui-enhancements/ui/cron-jobs-tab.css +396 -0
  430. package/ext/ui-enhancements/ui/help-panel.css +279 -0
  431. package/ext/ui-enhancements/ui/icons.css +125 -0
  432. package/ext/ui-enhancements/ui/tooltips.css +114 -0
  433. package/package.json +94 -4
  434. package/shared-platform-engineering/docker-templates/bun-hoisted-symlink-fix.sh +25 -0
  435. package/shared-platform-engineering/docker-templates/infisical-entrypoint.sh +466 -0
  436. package/shared-platform-engineering/docker-templates/install-deps.sh +154 -0
  437. package/shared-platform-engineering/docker-templates/prisma-bun-client-link-fix.sh +14 -0
  438. package/shared-platform-engineering/docker-templates/prisma-normalize-client.sh +58 -0
  439. package/specs/specs/TILT_SERVICE_DEFAULTS.star +207 -0
  440. 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