@flisk-sh/flisk 1.3.207 → 1.4.0

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 (376) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +40 -37
  3. package/cli/dist/agent-runtimes/custom.js +3 -3
  4. package/cli/dist/agent-runtimes/registry.js +3 -3
  5. package/cli/dist/backend-frameworks/registry.js +8 -8
  6. package/cli/dist/backend-languages/python.js +4 -1
  7. package/cli/dist/backend-languages/registry.js +3 -3
  8. package/cli/dist/cli.js +4 -3
  9. package/cli/dist/commands/__tests__/project-e2e-helpers.js +6 -6
  10. package/cli/dist/commands/agent.js +8 -8
  11. package/cli/dist/commands/completion.js +26 -26
  12. package/cli/dist/commands/config.js +8 -8
  13. package/cli/dist/commands/doctor.js +18 -18
  14. package/cli/dist/commands/down.js +1 -1
  15. package/cli/dist/commands/eject.js +10 -10
  16. package/cli/dist/commands/help.js +2 -2
  17. package/cli/dist/commands/import.js +2 -2
  18. package/cli/dist/commands/logs.js +2 -2
  19. package/cli/dist/commands/mcp.js +2 -2
  20. package/cli/dist/commands/networks.js +2 -2
  21. package/cli/dist/commands/open.js +0 -1
  22. package/cli/dist/commands/project.js +19 -19
  23. package/cli/dist/commands/projects.js +1 -1
  24. package/cli/dist/commands/resource.js +21 -21
  25. package/cli/dist/commands/resources.js +2 -2
  26. package/cli/dist/commands/restart.js +7 -4
  27. package/cli/dist/commands/runtime.js +15 -3
  28. package/cli/dist/commands/stack.js +8 -8
  29. package/cli/dist/commands/up.js +23 -23
  30. package/cli/dist/commands/upgrade.js +44 -40
  31. package/cli/dist/frontend-frameworks/registry.js +3 -3
  32. package/cli/dist/generator/extension-fetch.js +12 -9
  33. package/cli/dist/generator/template-engine.js +66 -53
  34. package/cli/dist/mcp/tools.js +2 -2
  35. package/cli/dist/utils/agent-host.js +1 -1
  36. package/cli/dist/utils/cli-command.js +1 -1
  37. package/cli/dist/utils/cold-preflight.js +2 -2
  38. package/cli/dist/utils/constants.js +3 -3
  39. package/cli/dist/utils/discovery-paths.js +2 -2
  40. package/cli/dist/utils/doctor-fix.js +10 -10
  41. package/cli/dist/utils/doctor-report.js +3 -3
  42. package/cli/dist/utils/doctor-runtime.js +4 -3
  43. package/cli/dist/utils/doctor-starlark.js +3 -3
  44. package/cli/dist/utils/doctor-wiring.js +4 -4
  45. package/cli/dist/utils/down-cleanup.js +2 -2
  46. package/cli/dist/utils/env-compat-init.js +8 -0
  47. package/cli/dist/utils/env-compat.js +27 -0
  48. package/cli/dist/utils/env-selection.js +9 -9
  49. package/cli/dist/utils/errors.js +13 -13
  50. package/cli/dist/utils/file-helpers.js +5 -5
  51. package/cli/dist/utils/{tdk-version.js → flisk-version.js} +8 -8
  52. package/cli/dist/utils/generated-paths.js +6 -6
  53. package/cli/dist/utils/host-port-config.js +10 -10
  54. package/cli/dist/utils/host-port-plan.js +3 -3
  55. package/cli/dist/utils/machine-output.js +2 -2
  56. package/cli/dist/utils/native-windows.js +1 -1
  57. package/cli/dist/utils/paths.js +3 -3
  58. package/cli/dist/utils/platform.js +9 -9
  59. package/cli/dist/utils/port-conflict-fix.js +3 -3
  60. package/cli/dist/utils/port-fallback-notice.js +3 -3
  61. package/cli/dist/utils/project-config-defaults.js +1 -1
  62. package/cli/dist/utils/project-features.js +2 -2
  63. package/cli/dist/utils/resource-features.js +3 -3
  64. package/cli/dist/utils/runtime-layout.js +58 -0
  65. package/cli/dist/utils/schema-version-gate.js +3 -2
  66. package/cli/dist/utils/service-urls.js +3 -3
  67. package/cli/dist/utils/services.js +2 -2
  68. package/cli/dist/utils/shared-infra.js +2 -2
  69. package/cli/dist/utils/shared-platform-postgres.js +6 -6
  70. package/cli/dist/utils/tar.js +1 -1
  71. package/cli/dist/utils/tilt.js +1 -1
  72. package/cli/dist/utils/up-readiness.js +1 -1
  73. package/cli/dist/utils/windows-doctor.js +3 -3
  74. package/cli/dist-bundle/{chunk-D2DIEX5E.js → chunk-36SOQVAL.js} +2 -2
  75. package/cli/dist-bundle/{chunk-YZRPX76N.js → chunk-3J6XI3NX.js} +1 -1
  76. package/cli/dist-bundle/chunk-5EZ4EX6U.js +2 -0
  77. package/cli/dist-bundle/chunk-763VK575.js +54 -0
  78. package/cli/dist-bundle/{chunk-5LRMAY67.js → chunk-B6Q5VKL7.js} +13 -13
  79. package/cli/dist-bundle/{chunk-AGXA5DOQ.js → chunk-BWK6MPCB.js} +3 -3
  80. package/cli/dist-bundle/{chunk-SLKTM6ZO.js → chunk-D7N2GGJH.js} +14 -14
  81. package/cli/dist-bundle/chunk-HEMPQKD6.js +7 -0
  82. package/cli/dist-bundle/chunk-ICXF6PXA.js +35 -0
  83. package/cli/dist-bundle/chunk-K6SOCO6V.js +3 -0
  84. package/cli/dist-bundle/{chunk-6EA4DGCY.js → chunk-KJZUBHLO.js} +1 -1
  85. package/cli/dist-bundle/{chunk-GOEBYLFN.js → chunk-MINZ25AC.js} +1 -1
  86. package/cli/dist-bundle/{chunk-FAHNFTWN.js → chunk-PVBAGX5X.js} +2 -2
  87. package/cli/dist-bundle/chunk-QQEV6D74.js +2 -0
  88. package/cli/dist-bundle/chunk-VHFFSBVJ.js +10 -0
  89. package/cli/dist-bundle/chunk-VMB5673O.js +57 -0
  90. package/cli/dist-bundle/{chunk-53M5D4KE.js → chunk-XD3BBFZB.js} +1 -1
  91. package/cli/dist-bundle/{chunk-GIMHTZNR.js → chunk-YL56J2WX.js} +1 -1
  92. package/cli/dist-bundle/cli.js +254 -254
  93. package/cli/dist-bundle/cold-preflight-ABU26DYW.js +2 -0
  94. package/cli/dist-bundle/colima-GBURKN54.js +2 -0
  95. package/cli/dist-bundle/{demo-stage-ANHJKDZC.js → demo-stage-EBIUCJBX.js} +2 -2
  96. package/cli/dist-bundle/{devtools-MGITLOWZ.js → devtools-ZD6XIOLD.js} +2 -2
  97. package/cli/dist-bundle/extension-fetch-VEFSCG4B.js +2 -0
  98. package/cli/dist-bundle/native-windows-BWVEYVPO.js +2 -0
  99. package/cli/dist-bundle/{one-command-P6XVAXWV.js → one-command-VNKQAMFJ.js} +2 -2
  100. package/cli/dist-bundle/open-2KSAF6M2.js +2 -0
  101. package/cli/dist-bundle/project-YD3C4ZV3.js +2 -0
  102. package/cli/dist-bundle/project-templates-EYSQG2EO.js +2 -0
  103. package/cli/dist-bundle/{services-CBXN4SXC.js → services-V6Q55JR5.js} +2 -2
  104. package/cli/dist-bundle/{stack-progress-6GO2TCRH.js → stack-progress-NIFM5T2K.js} +2 -2
  105. package/cli/dist-bundle/tilt-port-owner-MWJ7P6NB.js +2 -0
  106. package/cli/dist-bundle/url-actions-HXJLBTX6.js +2 -0
  107. package/cli/package.json +5 -5
  108. package/cli/shared-platform-engineering/docker-templates/infisical-entrypoint.sh +2 -2
  109. package/cli/shared-platform-engineering/docker-templates/install-deps.sh +2 -2
  110. package/cli/templates/.tiltignore.hbs +2 -2
  111. package/cli/templates/TILT_RESOURCE_DEFAULTS.star.hbs +1 -1
  112. package/cli/templates/TILT_TECH_STACK.star.hbs +1 -1
  113. package/cli/templates/Tiltfile.hbs +21 -21
  114. package/cli/templates/spec.master.hbs +4 -4
  115. package/examples/tdk-example/LICENSE +1 -1
  116. package/examples/tdk-example/Tiltfile +10 -10
  117. package/examples/tdk-example/services/platform/messaging/docker-compose.yml +7 -7
  118. package/examples/tdk-example/services/shop/orders-api/service.json +1 -1
  119. package/examples/tdk-example/services/shop/orders-api/src/index.ts +1 -1
  120. package/examples/tdk-example/services/shop/orders-app/index.html +1 -1
  121. package/examples/tdk-example/services/shop/orders-worker/service.json +1 -1
  122. package/examples/tdk-example/services/shop/orders-worker/src/index.ts +1 -1
  123. package/package.json +29 -11
  124. package/{Tiltfile → runtime/Tiltfile} +9 -5
  125. package/{discovery → runtime/discovery}/AGENTS.md +1 -1
  126. package/{discovery → runtime/discovery}/TILT_DISCOVERY.star +5 -5
  127. package/{discovery → runtime/discovery}/Tiltfile +5 -5
  128. package/{discovery → runtime/discovery}/config.star +5 -5
  129. package/{discovery → runtime/discovery}/constants.star +14 -14
  130. package/{discovery → runtime/discovery}/deterministic.star +1 -1
  131. package/{discovery → runtime/discovery}/discovery_daemon.star +2 -2
  132. package/{discovery → runtime/discovery}/discovery_orchestrator.star +17 -17
  133. package/{discovery → runtime/discovery}/identity-management-backend/service.yaml +2 -2
  134. package/{discovery → runtime/discovery}/incremental_discovery.star +1 -1
  135. package/{discovery → runtime/discovery}/json_manifest_scanner.star +2 -2
  136. package/{discovery → runtime/discovery}/libraries.star +1 -1
  137. package/{discovery → runtime/discovery}/manifest/constants.star +1 -1
  138. package/{discovery → runtime/discovery}/manifest/loading.star +7 -7
  139. package/{discovery → runtime/discovery}/manifest/normalize.star +12 -15
  140. package/{discovery → runtime/discovery}/registry.star +11 -11
  141. package/{discovery → runtime/discovery}/resource_snapshot.py +2 -2
  142. package/{discovery → runtime/discovery}/resource_snapshot.star +6 -6
  143. package/{discovery → runtime/discovery}/services/platform/orchestrator/orchestrator-glue-backend/service.yaml +2 -2
  144. package/{discovery → runtime/discovery}/test_resource_snapshot.py +6 -6
  145. package/{engine → runtime/engine}/AGENTS.md +6 -6
  146. package/{engine → runtime/engine}/README.md +2 -2
  147. package/{engine → runtime/engine}/Tiltfile +5 -5
  148. package/{engine → runtime/engine}/assets/docker/golden-layers.Dockerfile +17 -17
  149. package/{engine → runtime/engine}/assets/docker/wake-gateway/Dockerfile +7 -0
  150. package/{engine → runtime/engine}/entrypoint.star +1 -1
  151. package/{engine → runtime/engine}/paths.star +5 -5
  152. package/{engine → runtime/engine}/schemas/project-schema.json +2 -2
  153. package/{engine → runtime/engine}/schemas/service-schema.json +5 -5
  154. package/{engine → runtime/engine}/scripts/debug-container.sh +3 -3
  155. package/{engine → runtime/engine}/spec.master +3 -3
  156. package/{engine → runtime/engine}/topologies/README.md +3 -3
  157. package/{engine → runtime/engine}/topologies/platform/docker/build/golden_image_build.star +5 -5
  158. package/{engine → runtime/engine}/topologies/platform/docker/build/golden_image_constants.star +7 -7
  159. package/{engine → runtime/engine}/topologies/platform/docker/build/golden_image_dockerfile.star +8 -8
  160. package/{engine → runtime/engine}/topologies/platform/docker/compose/compose.star +12 -12
  161. package/{engine → runtime/engine}/topologies/platform/docker/compose/traefik_standalone.star +21 -6
  162. package/{engine → runtime/engine}/topologies/platform/docker/config/healthcheck.star +7 -7
  163. package/{engine → runtime/engine}/topologies/platform/docker/constants.star +7 -7
  164. package/{engine → runtime/engine}/topologies/platform/docker/dockerfile/language_dockerfile.star +3 -3
  165. package/{engine → runtime/engine}/topologies/platform/docker/layers/l1_base_layers.star +5 -5
  166. package/{engine → runtime/engine}/topologies/platform/docker/layers/l2_dependency_layers.star +14 -14
  167. package/{engine → runtime/engine}/topologies/platform/docker/layers/l3_builder_layers.star +5 -5
  168. package/{engine → runtime/engine}/topologies/platform/docker/layers/l4_runtime_layers.star +8 -8
  169. package/{engine → runtime/engine}/topologies/platform/docker/layers/prisma/constants.star +5 -5
  170. package/{engine → runtime/engine}/topologies/platform/docker/networking/api_path_constants.star +5 -5
  171. package/{engine → runtime/engine}/topologies/platform/docker/networking/sablier_container_cycle.star +1 -1
  172. package/{engine → runtime/engine}/topologies/platform/docker/networking/traefik_static_routes.star +1 -1
  173. package/{engine → runtime/engine}/topologies/platform/docker/secrets/env_secrets.star +2 -2
  174. package/{engine → runtime/engine}/topologies/platform/docker/secrets/infisical.star +4 -4
  175. package/{engine → runtime/engine}/topologies/platform/registries/verdaccio_loader.star +1 -1
  176. package/{engine → runtime/engine}/topologies/platform/security/secrets.star +1 -1
  177. package/{engine → runtime/engine}/topologies/tilt/common/utils.star +9 -10
  178. package/{engine → runtime/engine}/topologies/tilt/common/utils_debug.star +1 -1
  179. package/{engine → runtime/engine}/topologies/tilt/common/utils_deterministic.star +2 -2
  180. package/{engine → runtime/engine}/topologies/tilt/common/utils_env.star +5 -5
  181. package/{engine → runtime/engine}/topologies/tilt/config/profiles.star +4 -4
  182. package/{engine → runtime/engine}/topologies/tilt/generators/agents_md.star +1 -1
  183. package/{engine → runtime/engine}/topologies/tilt/generators/infisical/README.md +1 -1
  184. package/{engine → runtime/engine}/topologies/tilt/generators/infisical/organization.star +6 -6
  185. package/{engine → runtime/engine}/topologies/tilt/generators/npmrc.star +5 -5
  186. package/{engine → runtime/engine}/topologies/tilt/generators/typescript/backend_tsconfig.star +1 -1
  187. package/{engine → runtime/engine}/topologies/tilt/generators/typescript/playwright_config.star +1 -1
  188. package/{engine → runtime/engine}/topologies/tilt/generators/vite/helpers.star +7 -7
  189. package/{engine → runtime/engine}/topologies/tilt/generators/vite/templates.star +5 -5
  190. package/{engine → runtime/engine}/topologies/tilt/manifest/json_to_yaml.py +2 -2
  191. package/{engine → runtime/engine}/topologies/tilt/manifest/loader.star +2 -2
  192. package/{engine → runtime/engine}/topologies/tilt/manifest/schema.star +1 -1
  193. package/{engine → runtime/engine}/topologies/tilt/manifest/yaml_to_json.py +1 -1
  194. package/{engine → runtime/engine}/topologies/tilt/resources/build_concurrency.star +3 -3
  195. package/{engine → runtime/engine}/topologies/tilt/resources/databases.star +7 -6
  196. package/{engine → runtime/engine}/topologies/tilt/resources/infra-loader.star +12 -12
  197. package/{engine → runtime/engine}/topologies/tilt/resources/libs_paths.star +1 -1
  198. package/{engine → runtime/engine}/topologies/tilt/resources/libs_resource_definition.star +2 -2
  199. package/{engine → runtime/engine}/topologies/tilt/resources/libs_setup.star +1 -1
  200. package/{engine → runtime/engine}/topologies/tilt/resources/orchestrator/apply_compose_resource_registration.star +36 -28
  201. package/{engine → runtime/engine}/topologies/tilt/resources/orchestrator/apply_migrator_orchestration.star +1 -1
  202. package/{engine → runtime/engine}/topologies/tilt/resources/orchestrator/generators/frontend.star +5 -5
  203. package/{engine → runtime/engine}/topologies/tilt/resources/orchestrator/generators/manifest_resource.star +4 -4
  204. package/{engine → runtime/engine}/topologies/tilt/resources/watchers.star +20 -20
  205. package/{engine → runtime/engine}/where-things-live.star +5 -5
  206. package/{ext → runtime/ext}/Tiltfile +5 -5
  207. package/{ext → runtime/ext}/ide-components/code_viewer/server.py +1 -1
  208. package/{ext → runtime/ext}/ide-components/config_inspector/server.py +2 -2
  209. package/{ext → runtime/ext}/ide-components/file_browser/server.py +1 -1
  210. package/{ext → runtime/ext}/ide-components/shared/config_service.py +2 -2
  211. package/{ext → runtime/ext}/ide-components/shared/file_utils.py +2 -2
  212. package/{ext → runtime/ext}/ide-components/shared/http_utils.py +1 -1
  213. package/{ext → runtime/ext}/ide-components/shared/syntax_highlighter.py +1 -1
  214. package/{ext → runtime/ext}/ide-components/shared/template_engine.py +1 -1
  215. package/{ext → runtime/ext}/ide-components/shared/templates/base.html +1 -1
  216. package/{ext → runtime/ext}/ide-components/shared/test_config_service.py +1 -1
  217. package/{ext → runtime/ext}/ide-components/shared/tilt_integration.py +1 -1
  218. package/{ext → runtime/ext}/ui-enhancements/tiltfile.py +1 -1
  219. package/shared-platform-engineering/docker-templates/infisical-entrypoint.sh +2 -2
  220. package/shared-platform-engineering/docker-templates/install-deps.sh +2 -2
  221. package/cli/dist-bundle/chunk-42IVF3YT.js +0 -3
  222. package/cli/dist-bundle/chunk-AT5MFZ3D.js +0 -10
  223. package/cli/dist-bundle/chunk-BHWJU6HY.js +0 -2
  224. package/cli/dist-bundle/chunk-DWR3LLHS.js +0 -2
  225. package/cli/dist-bundle/chunk-GB6DJJ5N.js +0 -57
  226. package/cli/dist-bundle/chunk-ODYL6LET.js +0 -52
  227. package/cli/dist-bundle/chunk-YTXQPTCN.js +0 -35
  228. package/cli/dist-bundle/chunk-Z2C55UFP.js +0 -7
  229. package/cli/dist-bundle/cold-preflight-7PFKXNK7.js +0 -2
  230. package/cli/dist-bundle/colima-SVZX2UML.js +0 -2
  231. package/cli/dist-bundle/extension-fetch-6XNTDF44.js +0 -2
  232. package/cli/dist-bundle/native-windows-X5XVLFJS.js +0 -2
  233. package/cli/dist-bundle/open-VJZ7W4JR.js +0 -2
  234. package/cli/dist-bundle/project-QSH7LOWI.js +0 -2
  235. package/cli/dist-bundle/project-templates-JDRE7AVL.js +0 -2
  236. package/cli/dist-bundle/tilt-port-owner-SMN5SAQJ.js +0 -2
  237. package/cli/dist-bundle/url-actions-D6ROTHZG.js +0 -2
  238. /package/cli/bin/{tdk.js → flisk.js} +0 -0
  239. /package/{discovery → runtime/discovery}/filtering.star +0 -0
  240. /package/{discovery → runtime/discovery}/identity-management-frontend/service.yaml +0 -0
  241. /package/{discovery → runtime/discovery}/identity-sdk/service.yaml +0 -0
  242. /package/{discovery → runtime/discovery}/indexing.star +0 -0
  243. /package/{discovery → runtime/discovery}/loading.star +0 -0
  244. /package/{discovery → runtime/discovery}/manifest/validation.star +0 -0
  245. /package/{discovery → runtime/discovery}/normalization.star +0 -0
  246. /package/{discovery → runtime/discovery}/schemas.star +0 -0
  247. /package/{discovery → runtime/discovery}/services/platform/cdc/debezium/nats-connector/service.yaml +0 -0
  248. /package/{discovery → runtime/discovery}/services/platform/cdc/nats-http-bridge/service.yaml +0 -0
  249. /package/{discovery → runtime/discovery}/services/platform/synthetic-monitor/service.yaml +0 -0
  250. /package/{discovery → runtime/discovery}/validation.star +0 -0
  251. /package/{discovery → runtime/discovery}/versioning.star +0 -0
  252. /package/{engine → runtime/engine}/REFACTORING_MANIFEST_SYSTEM.md +0 -0
  253. /package/{engine → runtime/engine}/assets/docker/wake-gateway/decide.test.ts +0 -0
  254. /package/{engine → runtime/engine}/assets/docker/wake-gateway/decide.ts +0 -0
  255. /package/{engine → runtime/engine}/assets/docker/wake-gateway/server.ts +0 -0
  256. /package/{engine → runtime/engine}/assets/scripts/cleanup-completed-migrator-images.sh +0 -0
  257. /package/{engine → runtime/engine}/assets/scripts/cleanup-tilt-images.sh +0 -0
  258. /package/{engine → runtime/engine}/assets/scripts/mac-m1-resource-monitor.sh +0 -0
  259. /package/{engine → runtime/engine}/config.star +0 -0
  260. /package/{engine → runtime/engine}/lifecycle/orchestrator.star +0 -0
  261. /package/{engine → runtime/engine}/scripts/README.md +0 -0
  262. /package/{engine → runtime/engine}/scripts/build-and-publish-lib.sh +0 -0
  263. /package/{engine → runtime/engine}/scripts/check-lib-publish.sh +0 -0
  264. /package/{engine → runtime/engine}/scripts/generate-manifest.sh +0 -0
  265. /package/{engine → runtime/engine}/spec.master.example +0 -0
  266. /package/{engine → runtime/engine}/topologies/platform/docker/AGENTS.md +0 -0
  267. /package/{engine → runtime/engine}/topologies/platform/docker/auth/auth.star +0 -0
  268. /package/{engine → runtime/engine}/topologies/platform/docker/build/frontend_build_plan.star +0 -0
  269. /package/{engine → runtime/engine}/topologies/platform/docker/build/golden_image.star +0 -0
  270. /package/{engine → runtime/engine}/topologies/platform/docker/compose/compose_helpers.star +0 -0
  271. /package/{engine → runtime/engine}/topologies/platform/docker/compose/unsafe_value.star +0 -0
  272. /package/{engine → runtime/engine}/topologies/platform/docker/config/bunignore.star +0 -0
  273. /package/{engine → runtime/engine}/topologies/platform/docker/config/dockerignore.star +0 -0
  274. /package/{engine → runtime/engine}/topologies/platform/docker/dockerfile/dockerfile.star +0 -0
  275. /package/{engine → runtime/engine}/topologies/platform/docker/generators/golden_docker_generator_v2.star +0 -0
  276. /package/{engine → runtime/engine}/topologies/platform/docker/index.star +0 -0
  277. /package/{engine → runtime/engine}/topologies/platform/docker/layers/bun_helpers.star +0 -0
  278. /package/{engine → runtime/engine}/topologies/platform/docker/layers/infisical/index.star +0 -0
  279. /package/{engine → runtime/engine}/topologies/platform/docker/layers/infisical/infisical_docker.star +0 -0
  280. /package/{engine → runtime/engine}/topologies/platform/docker/layers/prisma/db_readiness.star +0 -0
  281. /package/{engine → runtime/engine}/topologies/platform/docker/layers/prisma/filesystem_setup.star +0 -0
  282. /package/{engine → runtime/engine}/topologies/platform/docker/layers/prisma/migrate_script.star +0 -0
  283. /package/{engine → runtime/engine}/topologies/platform/docker/layers/prisma/prisma_build.star +0 -0
  284. /package/{engine → runtime/engine}/topologies/platform/docker/layers/prisma/prisma_runtime.star +0 -0
  285. /package/{engine → runtime/engine}/topologies/platform/docker/layers/prisma/secret_resolution.star +0 -0
  286. /package/{engine → runtime/engine}/topologies/platform/docker/networking/traefik.star +0 -0
  287. /package/{engine → runtime/engine}/topologies/platform/docker/networking/traefik_constants.star +0 -0
  288. /package/{engine → runtime/engine}/topologies/platform/docker/networking/traefik_helpers.star +0 -0
  289. /package/{engine → runtime/engine}/topologies/platform/net/AGENTS.md +0 -0
  290. /package/{engine → runtime/engine}/topologies/platform/net/proxy.star +0 -0
  291. /package/{engine → runtime/engine}/topologies/platform/registries/local.star +0 -0
  292. /package/{engine → runtime/engine}/topologies/platform/security/AGENTS.md +0 -0
  293. /package/{engine → runtime/engine}/topologies/platform/state/AGENTS.md +0 -0
  294. /package/{engine → runtime/engine}/topologies/platform/state/relational.star +0 -0
  295. /package/{engine → runtime/engine}/topologies/tilt/common/AGENTS.md +0 -0
  296. /package/{engine → runtime/engine}/topologies/tilt/common/utils_docker_networks.star +0 -0
  297. /package/{engine → runtime/engine}/topologies/tilt/common/utils_output.star +0 -0
  298. /package/{engine → runtime/engine}/topologies/tilt/config/AGENTS.md +0 -0
  299. /package/{engine → runtime/engine}/topologies/tilt/config/defaults.star +0 -0
  300. /package/{engine → runtime/engine}/topologies/tilt/config/feature_flags.star +0 -0
  301. /package/{engine → runtime/engine}/topologies/tilt/config/global.star +0 -0
  302. /package/{engine → runtime/engine}/topologies/tilt/generators/api_gateway.star +0 -0
  303. /package/{engine → runtime/engine}/topologies/tilt/generators/index.star +0 -0
  304. /package/{engine → runtime/engine}/topologies/tilt/generators/infisical/examples.star +0 -0
  305. /package/{engine → runtime/engine}/topologies/tilt/generators/infisical/index.star +0 -0
  306. /package/{engine → runtime/engine}/topologies/tilt/generators/infisical/machine_identity.star +0 -0
  307. /package/{engine → runtime/engine}/topologies/tilt/generators/infisical/path_manager.star +0 -0
  308. /package/{engine → runtime/engine}/topologies/tilt/generators/infisical/secrets_generator.star +0 -0
  309. /package/{engine → runtime/engine}/topologies/tilt/generators/nginx_conf.star +0 -0
  310. /package/{engine → runtime/engine}/topologies/tilt/generators/tsconfig.star +0 -0
  311. /package/{engine → runtime/engine}/topologies/tilt/generators/typescript/backend_library_tsconfig.star +0 -0
  312. /package/{engine → runtime/engine}/topologies/tilt/generators/typescript/common.star +0 -0
  313. /package/{engine → runtime/engine}/topologies/tilt/generators/typescript/frontend_library_tsconfig.star +0 -0
  314. /package/{engine → runtime/engine}/topologies/tilt/generators/typescript/frontend_tsconfig.star +0 -0
  315. /package/{engine → runtime/engine}/topologies/tilt/generators/typescript/include.star +0 -0
  316. /package/{engine → runtime/engine}/topologies/tilt/generators/typescript/prisma_config.star +0 -0
  317. /package/{engine → runtime/engine}/topologies/tilt/generators/validators.star +0 -0
  318. /package/{engine → runtime/engine}/topologies/tilt/generators/vite/backend.star +0 -0
  319. /package/{engine → runtime/engine}/topologies/tilt/generators/vite/frameworks/lit.star +0 -0
  320. /package/{engine → runtime/engine}/topologies/tilt/generators/vite/frameworks/preact.star +0 -0
  321. /package/{engine → runtime/engine}/topologies/tilt/generators/vite/frameworks/qwik.star +0 -0
  322. /package/{engine → runtime/engine}/topologies/tilt/generators/vite/frameworks/react.star +0 -0
  323. /package/{engine → runtime/engine}/topologies/tilt/generators/vite/frameworks/solid.star +0 -0
  324. /package/{engine → runtime/engine}/topologies/tilt/generators/vite/frameworks/svelte.star +0 -0
  325. /package/{engine → runtime/engine}/topologies/tilt/generators/vite/frameworks/vanilla.star +0 -0
  326. /package/{engine → runtime/engine}/topologies/tilt/generators/vite/frameworks/vue.star +0 -0
  327. /package/{engine → runtime/engine}/topologies/tilt/generators/vite/frontend.star +0 -0
  328. /package/{engine → runtime/engine}/topologies/tilt/generators/vite/generators.star +0 -0
  329. /package/{engine → runtime/engine}/topologies/tilt/generators/vite/library.star +0 -0
  330. /package/{engine → runtime/engine}/topologies/tilt/generators/vite/sdk.star +0 -0
  331. /package/{engine → runtime/engine}/topologies/tilt/generators/vite_config.star +0 -0
  332. /package/{engine → runtime/engine}/topologies/tilt/manifest/AGENTS.md +0 -0
  333. /package/{engine → runtime/engine}/topologies/tilt/manifest/README.md +0 -0
  334. /package/{engine → runtime/engine}/topologies/tilt/manifest/__init__.star +0 -0
  335. /package/{engine → runtime/engine}/topologies/tilt/manifest/constants.star +0 -0
  336. /package/{engine → runtime/engine}/topologies/tilt/manifest/errors.star +0 -0
  337. /package/{engine → runtime/engine}/topologies/tilt/manifest/integration.star +0 -0
  338. /package/{engine → runtime/engine}/topologies/tilt/manifest/mapper.star +0 -0
  339. /package/{engine → runtime/engine}/topologies/tilt/manifest/parser.star +0 -0
  340. /package/{engine → runtime/engine}/topologies/tilt/manifest/tests/test_integration.star +0 -0
  341. /package/{engine → runtime/engine}/topologies/tilt/manifest/tests/test_loader_parser.star +0 -0
  342. /package/{engine → runtime/engine}/topologies/tilt/manifest/tests/test_manifest.star +0 -0
  343. /package/{engine → runtime/engine}/topologies/tilt/manifest/tests/test_validator.star +0 -0
  344. /package/{engine → runtime/engine}/topologies/tilt/manifest/validator.star +0 -0
  345. /package/{engine → runtime/engine}/topologies/tilt/resources/AGENTS.md +0 -0
  346. /package/{engine → runtime/engine}/topologies/tilt/resources/conditions.star +0 -0
  347. /package/{engine → runtime/engine}/topologies/tilt/resources/declaration.star +0 -0
  348. /package/{engine → runtime/engine}/topologies/tilt/resources/deps.star +0 -0
  349. /package/{engine → runtime/engine}/topologies/tilt/resources/libs.star +0 -0
  350. /package/{engine → runtime/engine}/topologies/tilt/resources/libs_discovery.star +0 -0
  351. /package/{engine → runtime/engine}/topologies/tilt/resources/libs_tsconfig.star +0 -0
  352. /package/{engine → runtime/engine}/topologies/tilt/resources/orchestrator/apply.star +0 -0
  353. /package/{engine → runtime/engine}/topologies/tilt/resources/orchestrator/apply_manifest_orchestration.star +0 -0
  354. /package/{engine → runtime/engine}/topologies/tilt/resources/orchestrator/apply_resource_validation.star +0 -0
  355. /package/{engine → runtime/engine}/topologies/tilt/resources/orchestrator/apply_runtime_flags.star +0 -0
  356. /package/{engine → runtime/engine}/topologies/tilt/resources/orchestrator/builders/typescript.star +0 -0
  357. /package/{engine → runtime/engine}/topologies/tilt/resources/orchestrator/generators/dependencies/AGENTS.md +0 -0
  358. /package/{engine → runtime/engine}/topologies/tilt/resources/orchestrator/generators/dependencies/index.star +0 -0
  359. /package/{engine → runtime/engine}/topologies/tilt/resources/orchestrator/generators/dependencies/resolver.star +0 -0
  360. /package/{engine → runtime/engine}/topologies/tilt/resources/orchestrator/generators/env.star +0 -0
  361. /package/{engine → runtime/engine}/topologies/tilt/resources/orchestrator/helpers.star +0 -0
  362. /package/{engine → runtime/engine}/topologies/tilt/resources/orchestrator.star +0 -0
  363. /package/{engine → runtime/engine}/topologies/tilt/resources/ordering.star +0 -0
  364. /package/{engine → runtime/engine}/topologies/tilt/resources/shared-platform-postgres.star +0 -0
  365. /package/{engine → runtime/engine}/topologies/tilt/resources/triggers.star +0 -0
  366. /package/{ext → runtime/ext}/ide-components/README.md +0 -0
  367. /package/{ext → runtime/ext}/ide-components/shared/static/styles.css +0 -0
  368. /package/{ext → runtime/ext}/ui-enhancements/cron-status-server.sh +0 -0
  369. /package/{ext → runtime/ext}/ui-enhancements/cron-status-tracker.sh +0 -0
  370. /package/{ext → runtime/ext}/ui-enhancements/extension.yaml +0 -0
  371. /package/{ext → runtime/ext}/ui-enhancements/ui/cron-jobs-tab.css +0 -0
  372. /package/{ext → runtime/ext}/ui-enhancements/ui/help-panel.css +0 -0
  373. /package/{ext → runtime/ext}/ui-enhancements/ui/icons.css +0 -0
  374. /package/{ext → runtime/ext}/ui-enhancements/ui/tooltips.css +0 -0
  375. /package/{specs → runtime/specs}/specs/TILT_SERVICE_DEFAULTS.star +0 -0
  376. /package/{specs → runtime/specs}/specs/TILT_TECH_STACK.star +0 -0
@@ -1,6 +1,6 @@
1
1
  // Copyright (c) 2026 Flisk Landscape contributors
2
2
  // SPDX-License-Identifier: MIT
3
- import { relative } from "node:path";
3
+ import { relative, sep } from "node:path";
4
4
  import chalk from "chalk";
5
5
  import { formatCount } from "./formatting.js";
6
6
  import { SERVICE_MANIFEST_SCHEMA_VERSION } from "./service-manifest.js";
@@ -28,7 +28,8 @@ export function enforceSchemaVersionGate(projectRoot, options = {}, exit = proce
28
28
  const version = resource.config?.schemaVersion;
29
29
  if (version === undefined || version === SERVICE_MANIFEST_SCHEMA_VERSION)
30
30
  return [];
31
- const file = relative(projectRoot, resource.configPath) || resource.configPath;
31
+ const rel = relative(projectRoot, resource.configPath) || resource.configPath;
32
+ const file = rel.split(sep).join("/");
32
33
  return [
33
34
  `${file} schemaVersion ${JSON.stringify(version)}: this flisk supports ${SERVICE_MANIFEST_SCHEMA_VERSION}`,
34
35
  ];
@@ -12,7 +12,7 @@ export function getProjectName() {
12
12
  export function getProjectNameFor(root) {
13
13
  if (root) {
14
14
  try {
15
- const content = readFileSync(join(root, ".tdk", PROJECT_JSON), "utf-8");
15
+ const content = readFileSync(join(root, ".flisk", PROJECT_JSON), "utf-8");
16
16
  const parsed = JSON.parse(content);
17
17
  if (parsed?.project?.name) {
18
18
  return parsed.project.name;
@@ -20,11 +20,11 @@ export function getProjectNameFor(root) {
20
20
  }
21
21
  catch { }
22
22
  }
23
- return "tdk-project";
23
+ return "flisk-project";
24
24
  }
25
25
  export function resolveSubdomainBases(ingressPort, projectRoot) {
26
26
  const projectName = getProjectNameFor(projectRoot ?? findProjectRoot());
27
- const raw = process.env.TDK_SERVICE_BASE_URL ??
27
+ const raw = process.env.FLISK_SERVICE_BASE_URL ??
28
28
  `http://${projectName}.localhost${ingressPort ? `:${ingressPort}` : ""}`;
29
29
  try {
30
30
  const u = new URL(raw.includes("://") ? raw : `http://${raw}`);
@@ -168,9 +168,9 @@ export function discoverResourcesStrict(discovered) {
168
168
  }
169
169
  /**
170
170
  * Unique, sorted `stack` values across discovered service.json files under `projectRoot`.
171
- * Tilt's discovery groups services by this same field (see tdk-cli-extensions
171
+ * Tilt's discovery groups services by this same field (see flisk-cli-extensions
172
172
  * discovery_orchestrator.star), so these are the names that must appear in a
173
- * stack's `services` list in .tdk/project.json for that group to be enabled.
173
+ * stack's `services` list in .flisk/project.json for that group to be enabled.
174
174
  */
175
175
  export function discoverStackNames(projectRoot, resources) {
176
176
  const resourcesToScan = resources ?? discoverResourcesFromRoot(projectRoot);
@@ -33,10 +33,10 @@ export function groupSharedPostgres(projectName, stacks) {
33
33
  return null;
34
34
  return { name: "postgres", databases };
35
35
  }
36
- /** `project.name` from `.tdk/project.json`, or null when the project file is missing or unreadable. */
36
+ /** `project.name` from `.flisk/project.json`, or null when the project file is missing or unreadable. */
37
37
  export function readProjectName(projectRoot) {
38
38
  try {
39
- const parsed = JSON.parse(readFileSync(join(projectRoot, ".tdk", PROJECT_JSON), "utf-8"));
39
+ const parsed = JSON.parse(readFileSync(join(projectRoot, ".flisk", PROJECT_JSON), "utf-8"));
40
40
  return typeof parsed?.project?.name === "string" ? parsed.project.name : null;
41
41
  }
42
42
  catch {
@@ -26,7 +26,7 @@ export function isSharedPlatformPostgresDependency(name) {
26
26
  }
27
27
  function readProjectJson(projectRoot) {
28
28
  try {
29
- return JSON.parse(readFileSync(join(projectRoot, ".tdk", PROJECT_JSON), "utf-8"));
29
+ return JSON.parse(readFileSync(join(projectRoot, ".flisk", PROJECT_JSON), "utf-8"));
30
30
  }
31
31
  catch {
32
32
  return undefined;
@@ -67,14 +67,14 @@ function parseStarlarkStringList(source, name) {
67
67
  }
68
68
  }
69
69
  function tiltfileAlwaysEnabledInfra(projectRoot) {
70
- const path = join(projectRoot, ".tdk", ".tdk-out", "Tiltfile");
70
+ const path = join(projectRoot, ".flisk", ".flisk-out", "Tiltfile");
71
71
  const text = readTextIfExists(path);
72
72
  if (!text)
73
73
  return undefined;
74
74
  return parseStarlarkStringList(text, "ALWAYS_ENABLED_INFRA");
75
75
  }
76
76
  function specMasterHasDatabaseManagement(projectRoot) {
77
- const path = join(projectRoot, ".tdk", ".tdk-out", "spec.master");
77
+ const path = join(projectRoot, ".flisk", ".flisk-out", "spec.master");
78
78
  const text = readTextIfExists(path);
79
79
  if (text === undefined)
80
80
  return undefined;
@@ -82,11 +82,11 @@ function specMasterHasDatabaseManagement(projectRoot) {
82
82
  return /"database-management"\s*:\s*True/.test(text);
83
83
  }
84
84
  function generatedDefaultFocusEnablesDatabaseManagement(projectRoot) {
85
- const output = join(projectRoot, ".tdk", ".tdk-out");
85
+ const output = join(projectRoot, ".flisk", ".flisk-out");
86
86
  const tiltfile = readTextIfExists(join(output, "Tiltfile"));
87
87
  const spec = readTextIfExists(join(output, "spec.master"));
88
- const config = readTextIfExists(join(output, "tdk-cli-ext", "discovery", "config.star"));
89
- const profiles = readTextIfExists(join(output, "tdk-cli-ext", "engine", "topologies", "tilt", "config", "profiles.star"));
88
+ const config = readTextIfExists(join(output, "flisk-cli-ext", "discovery", "config.star"));
89
+ const profiles = readTextIfExists(join(output, "flisk-cli-ext", "engine", "topologies", "tilt", "config", "profiles.star"));
90
90
  if (!tiltfile || !spec || !config || !profiles)
91
91
  return false;
92
92
  const preAlpha = spec.match(/PRE_ALPHA_RESOURCES\s*=\s*\{([^}]*)\}/)?.[1];
@@ -10,7 +10,7 @@ import { join } from "node:path";
10
10
  * implementation - available by default on macOS and Linux.
11
11
  */
12
12
  export function extractTarball(data, destDir) {
13
- const tempDir = mkdtempSync(join(tmpdir(), "tdk-ext-"));
13
+ const tempDir = mkdtempSync(join(tmpdir(), "flisk-ext-"));
14
14
  const tmpFile = join(tempDir, "bundle.tar.gz");
15
15
  writeFileSync(tmpFile, data);
16
16
  mkdirSync(destDir, { recursive: true });
@@ -54,7 +54,7 @@ export function getTiltfilePath() {
54
54
  if (!projectRoot) {
55
55
  throw errorFactories.notInProject();
56
56
  }
57
- return join(projectRoot, ".tdk", ".tdk-out", "Tiltfile");
57
+ return join(projectRoot, ".flisk", ".flisk-out", "Tiltfile");
58
58
  }
59
59
  function addTiltfilePath(args) {
60
60
  const tiltfilePath = getTiltfilePath();
@@ -91,7 +91,7 @@ export function evaluateTiltReadiness(jsonText, deferred, expected) {
91
91
  * with an errored resource, or at the deadline. Sablier-deferred resources are excluded: they stay idle by design.
92
92
  */
93
93
  export async function waitForTiltResourcesReady(port, options = {}) {
94
- const timeoutMs = options.timeoutMs ?? Number(process.env.TDK_UP_READY_TIMEOUT_MS ?? 900_000);
94
+ const timeoutMs = options.timeoutMs ?? Number(process.env.FLISK_UP_READY_TIMEOUT_MS ?? 900_000);
95
95
  const intervalMs = options.intervalMs ?? 2_000;
96
96
  const fetchJson = options.fetchJson ?? tiltGetUiResources;
97
97
  const deferred = options.deferred ?? getDeferredResourceNames();
@@ -6,7 +6,7 @@ import { parsePublishedPortHolders, probeHostPort } from "./doctor-runtime.js";
6
6
  import { findProjectRoot } from "./paths.js";
7
7
  import { getProjectName } from "./service-urls.js";
8
8
  import { findOnPath } from "./which.js";
9
- const WINDOWS_DNS_FAILURE = "Windows did not resolve *.tdk.localhost to 127.0.0.1. Browser URLs with hostnames will fail until you fix hosts or use the 127.0.0.1 URLs printed by flisk networks.";
9
+ const WINDOWS_DNS_FAILURE = "Windows did not resolve *.flisk.localhost to 127.0.0.1. Browser URLs with hostnames will fail until you fix hosts or use the 127.0.0.1 URLs printed by flisk networks.";
10
10
  function loopbackAddresses(addresses) {
11
11
  return (addresses.length > 0 &&
12
12
  addresses.every((address) => address === "127.0.0.1" || address === "::1"));
@@ -138,7 +138,7 @@ export async function checkWindowsHostConfiguration() {
138
138
  }
139
139
  }
140
140
  let dnsOk = true;
141
- for (const host of ["tdk.localhost", "example.tdk.localhost"]) {
141
+ for (const host of ["flisk.localhost", "example.flisk.localhost"]) {
142
142
  try {
143
143
  const records = await lookup(host, { all: true, verbatim: true });
144
144
  if (!loopbackAddresses(records.map((record) => record.address)))
@@ -149,7 +149,7 @@ export async function checkWindowsHostConfiguration() {
149
149
  }
150
150
  }
151
151
  if (!dnsOk) {
152
- warnings.push(`${WINDOWS_DNS_FAILURE}\nAdd these lines to C:\\Windows\\System32\\drivers\\etc\\hosts (Administrator Notepad):\n127.0.0.1 tdk.localhost\n127.0.0.1 example.tdk.localhost`);
152
+ warnings.push(`${WINDOWS_DNS_FAILURE}\nAdd these lines to C:\\Windows\\System32\\drivers\\etc\\hosts (Administrator Notepad):\n127.0.0.1 flisk.localhost\n127.0.0.1 example.flisk.localhost`);
153
153
  }
154
154
  try {
155
155
  const autocrlf = execFileSync("git", ["config", "core.autocrlf"], {
@@ -1,2 +1,2 @@
1
- import{createRequire as __tdkRequire}from'node:module';const require=__tdkRequire(import.meta.url);
2
- import{E as C,t as $}from"./chunk-AT5MFZ3D.js";var g=class extends Error{kind;constructor(i,a){super(i),this.kind=a,this.name="TiltEventsLoadError"}};function m(n){return typeof n=="object"&&n!==null&&!Array.isArray(n)?n:null}var w="\x1B",k="\x07",I=new RegExp(`${w}(?:\\[[0-?]*[ -/]*[@-~]|\\][^${k}${w}]*(?:${k}|${w}\\\\)?|[@-Z\\\\-_])`,"g"),O=new RegExp("[\\u0000-\\u0008\\u000b-\\u001f\\u007f-\\u009f]","g");function U(n){return n.replace(I,"").replace(O,"")}function r(n){return typeof n!="string"?void 0:U(n).trim()||void 0}function _(n){return Array.isArray(n)?n.flatMap(i=>{let a=r(i);return a?[a]:[]}):[]}function L(n){let i=m(n);if(!i||!Array.isArray(i.items))throw new Error("Tilt returned an invalid UIResource list");let a=[],e=[];for(let s of i.items){let u=m(s),N=m(u?.metadata),t=r(N?.name);if(!u||!t)continue;let c=m(u.status);a.push({name:t,runtimeStatus:r(c?.runtimeStatus),updateStatus:r(c?.updateStatus),hasPendingChanges:typeof c?.hasPendingChanges=="boolean"?c.hasPendingChanges:void 0});let x=Array.isArray(c?.buildHistory)?c.buildHistory:[];for(let[d,A]of x.entries()){let o=m(A);if(!o)continue;let f=r(o.error),l=_(o.warnings),p=[f,...l].filter(S=>!!S),h=r(o.spanID);e.push({id:`${t}:build:${h??String(d)}`,resourceName:t,kind:f?"failed":l.length?"warning":"success",title:f?"Build failed":l.length?"Build completed with warnings":"Build completed",occurredAt:r(o.finishTime)??r(o.startTime),details:p.length?p.join("; "):void 0})}let T=m(c?.currentBuild);T&&e.push({id:`${t}:current-build`,resourceName:t,kind:"running",title:"Build in progress",occurredAt:r(T.startTime)});let b=r(c?.pendingBuildSince);!T&&(c?.queued===!0||b)&&e.push({id:`${t}:queued`,resourceName:t,kind:"warning",title:"Update queued",occurredAt:b});let y=r(c?.lastDeployTime),E=y?Date.parse(y):Number.NaN,R=e.some(d=>d.resourceName===t&&d.kind==="success"&&d.occurredAt!==void 0&&Date.parse(d.occurredAt)===E);y&&!R&&e.push({id:`${t}:last-deploy`,resourceName:t,kind:"success",title:"Last deployed",occurredAt:y});let B=Array.isArray(c?.conditions)?c.conditions:[];for(let[d,A]of B.entries()){let o=m(A);if(!o)continue;let f=r(o.type),l=r(o.status),p=r(o.reason),h=r(o.message);if(!f&&!p&&!h||l==="True"&&!p&&!h)continue;let S=[p,h].filter(D=>!!D).join(": ");e.push({id:`${t}:condition:${d}:${f??"status"}`,resourceName:t,kind:l==="False"?"warning":"status",title:`Condition ${f??"status"}${l?`: ${l}`:""}`,occurredAt:r(o.lastTransitionTime),details:S||void 0})}}return e.sort((s,u)=>{if(s.kind==="running"&&u.kind!=="running")return-1;if(u.kind==="running"&&s.kind!=="running")return 1;let N=s.occurredAt?Date.parse(s.occurredAt):Number.NaN,t=u.occurredAt?Date.parse(u.occurredAt):Number.NaN;return Number.isNaN(N)?Number.isNaN(t)?s.resourceName.localeCompare(u.resourceName):1:Number.isNaN(t)?-1:t-N}),{resources:a,events:e}}async function q(){let n=process.env.TILT_PORT??String($.tiltUi),i;try{i=await C("get",["uiresources","-o","json","--port",n],{inheritStdio:!1,timeoutMs:1e4})}catch(e){let s=e instanceof Error?e.message:String(e),u=/ENOENT|not found|no such file|connection refused|failed to connect|could not connect|unable to connect|Tilt is not running/i.test(s)?"unavailable":"error";throw new g(s,u)}if(i.exitCode!==0){let e=i.stderr.trim()||`tilt get exited with code ${i.exitCode}`,s=/connection refused|failed to connect|could not connect|unable to connect|Tilt is not running|no running Tilt/i.test(e)?"unavailable":"error";throw new g(e,s)}let a;try{a=JSON.parse(i.stdout)}catch{throw new g("Tilt returned invalid UIResource JSON","error")}try{return L(a)}catch(e){throw new g(e instanceof Error?e.message:"Tilt returned an invalid UIResource list","error")}}export{g as a,U as b,q as c};
1
+ import{createRequire as __fliskRequire}from'node:module';const require=__fliskRequire(import.meta.url);
2
+ import{E as C,t as $}from"./chunk-VHFFSBVJ.js";var g=class extends Error{kind;constructor(i,a){super(i),this.kind=a,this.name="TiltEventsLoadError"}};function m(n){return typeof n=="object"&&n!==null&&!Array.isArray(n)?n:null}var w="\x1B",k="\x07",I=new RegExp(`${w}(?:\\[[0-?]*[ -/]*[@-~]|\\][^${k}${w}]*(?:${k}|${w}\\\\)?|[@-Z\\\\-_])`,"g"),O=new RegExp("[\\u0000-\\u0008\\u000b-\\u001f\\u007f-\\u009f]","g");function U(n){return n.replace(I,"").replace(O,"")}function r(n){return typeof n!="string"?void 0:U(n).trim()||void 0}function _(n){return Array.isArray(n)?n.flatMap(i=>{let a=r(i);return a?[a]:[]}):[]}function L(n){let i=m(n);if(!i||!Array.isArray(i.items))throw new Error("Tilt returned an invalid UIResource list");let a=[],e=[];for(let s of i.items){let u=m(s),N=m(u?.metadata),t=r(N?.name);if(!u||!t)continue;let c=m(u.status);a.push({name:t,runtimeStatus:r(c?.runtimeStatus),updateStatus:r(c?.updateStatus),hasPendingChanges:typeof c?.hasPendingChanges=="boolean"?c.hasPendingChanges:void 0});let x=Array.isArray(c?.buildHistory)?c.buildHistory:[];for(let[d,A]of x.entries()){let o=m(A);if(!o)continue;let f=r(o.error),l=_(o.warnings),p=[f,...l].filter(S=>!!S),h=r(o.spanID);e.push({id:`${t}:build:${h??String(d)}`,resourceName:t,kind:f?"failed":l.length?"warning":"success",title:f?"Build failed":l.length?"Build completed with warnings":"Build completed",occurredAt:r(o.finishTime)??r(o.startTime),details:p.length?p.join("; "):void 0})}let T=m(c?.currentBuild);T&&e.push({id:`${t}:current-build`,resourceName:t,kind:"running",title:"Build in progress",occurredAt:r(T.startTime)});let b=r(c?.pendingBuildSince);!T&&(c?.queued===!0||b)&&e.push({id:`${t}:queued`,resourceName:t,kind:"warning",title:"Update queued",occurredAt:b});let y=r(c?.lastDeployTime),E=y?Date.parse(y):Number.NaN,R=e.some(d=>d.resourceName===t&&d.kind==="success"&&d.occurredAt!==void 0&&Date.parse(d.occurredAt)===E);y&&!R&&e.push({id:`${t}:last-deploy`,resourceName:t,kind:"success",title:"Last deployed",occurredAt:y});let B=Array.isArray(c?.conditions)?c.conditions:[];for(let[d,A]of B.entries()){let o=m(A);if(!o)continue;let f=r(o.type),l=r(o.status),p=r(o.reason),h=r(o.message);if(!f&&!p&&!h||l==="True"&&!p&&!h)continue;let S=[p,h].filter(D=>!!D).join(": ");e.push({id:`${t}:condition:${d}:${f??"status"}`,resourceName:t,kind:l==="False"?"warning":"status",title:`Condition ${f??"status"}${l?`: ${l}`:""}`,occurredAt:r(o.lastTransitionTime),details:S||void 0})}}return e.sort((s,u)=>{if(s.kind==="running"&&u.kind!=="running")return-1;if(u.kind==="running"&&s.kind!=="running")return 1;let N=s.occurredAt?Date.parse(s.occurredAt):Number.NaN,t=u.occurredAt?Date.parse(u.occurredAt):Number.NaN;return Number.isNaN(N)?Number.isNaN(t)?s.resourceName.localeCompare(u.resourceName):1:Number.isNaN(t)?-1:t-N}),{resources:a,events:e}}async function q(){let n=process.env.TILT_PORT??String($.tiltUi),i;try{i=await C("get",["uiresources","-o","json","--port",n],{inheritStdio:!1,timeoutMs:1e4})}catch(e){let s=e instanceof Error?e.message:String(e),u=/ENOENT|not found|no such file|connection refused|failed to connect|could not connect|unable to connect|Tilt is not running/i.test(s)?"unavailable":"error";throw new g(s,u)}if(i.exitCode!==0){let e=i.stderr.trim()||`tilt get exited with code ${i.exitCode}`,s=/connection refused|failed to connect|could not connect|unable to connect|Tilt is not running|no running Tilt/i.test(e)?"unavailable":"error";throw new g(e,s)}let a;try{a=JSON.parse(i.stdout)}catch{throw new g("Tilt returned invalid UIResource JSON","error")}try{return L(a)}catch(e){throw new g(e instanceof Error?e.message:"Tilt returned an invalid UIResource list","error")}}export{g as a,U as b,q as c};
@@ -1,2 +1,2 @@
1
- import{createRequire as __tdkRequire}from'node:module';const require=__tdkRequire(import.meta.url);
1
+ import{createRequire as __fliskRequire}from'node:module';const require=__fliskRequire(import.meta.url);
2
2
  import{execFileSync as a,spawnSync as c}from"node:child_process";import{existsSync as s}from"node:fs";import{join as l}from"node:path";var u=()=>({env:process.env,dockerAnswers:()=>{try{return a("docker",["info","--format","{{.ServerVersion}}"],{encoding:"utf-8",timeout:1e4,stdio:["ignore","pipe","ignore"]}),!0}catch{return!1}},run:(t,e)=>{let n=c(t,e,{encoding:"utf-8",timeout:2e4,stdio:["ignore","pipe","pipe"]});return`${n.stdout??""}${n.stderr??""}`},exists:s,home:process.env.HOME??""});function m(t=u()){let e=t.env.DOCKER_HOST??"";if(e.includes(".colima"))return!0;let n=l(t.home,".colima","default","docker.sock");return t.exists(n)&&e.includes("docker.sock")===!1&&e!==""}function p(t=u()){if(!m(t))return{isColima:!1,running:!0};let e="";try{e=t.run("colima",["status"])}catch(n){let i=String(n?.stderr??n);return/rosetta|native arch/i.test(i)?{isColima:!0,running:!1,problem:"Lima is installed as an x86_64 build, so it cannot start the Colima VM on this Mac",fix:"Install a native Lima (brew reinstall lima, or use a native limactl on PATH) and run `colima start`"}:t.dockerAnswers()?{isColima:!0,running:!0,problem:"The Colima VM is running, but the colima CLI on this PATH cannot see it",fix:"Use a native limactl (a Rosetta x86_64 limactl cannot talk to the VM): brew reinstall lima, or put a native limactl first on PATH"}:/not running/i.test(i)?{isColima:!0,running:!1,problem:"The Colima VM is not running",fix:"Run `colima start`"}:{isColima:!0,running:!1,problem:"The state of the Colima VM could not be read",fix:"Run `colima status` to see what it says"}}return/is running/i.test(e)?{isColima:!0,running:!0,arch:/arch:\s*(\S+)/.exec(e)?.[1]}:t.dockerAnswers()?{isColima:!0,running:!0,problem:"The Colima VM is running, but the colima CLI on this PATH cannot see it",fix:"Use a native limactl (a Rosetta x86_64 limactl cannot talk to the VM): brew reinstall lima, or put a native limactl first on PATH"}:{isColima:!0,running:!1,problem:"The Colima VM is not running",fix:"Run `colima start`"}}function g(t,e){if(t.isColima){if(t.problem&&/x86_64|rosetta|native arch|cannot see it/i.test(t.problem))return"native-lima";if(!t.running)return"start";if(!e)return"restart"}}function C(t=process.env){let e=t.HOME??"",n=["/opt/homebrew/bin",e?`${e}/.local/bin`:"",e?`${e}/bin`:""].filter(Boolean);for(let i of n){let r=l(i,"limactl");try{if(!s(r))continue;let o="";try{o=a("file",["-bL",r],{encoding:"utf-8",timeout:5e3,stdio:["ignore","pipe","ignore"]})}catch{return i}if(/arm64|aarch64/i.test(o))return i}catch{}}}export{m as a,p as b,g as c,C as d};
@@ -0,0 +1,2 @@
1
+ import{createRequire as __fliskRequire}from'node:module';const require=__fliskRequire(import.meta.url);
2
+ import{f as A}from"./chunk-VHFFSBVJ.js";var o=[A,"proxy"];export{o as a};
@@ -0,0 +1,54 @@
1
+ import{createRequire as __fliskRequire}from'node:module';const require=__fliskRequire(import.meta.url);
2
+ import{c as re,e as se}from"./chunk-K6SOCO6V.js";import{a as ie}from"./chunk-5EZ4EX6U.js";import{T as ee,U as te,ca as K,ga as ne,u as G}from"./chunk-BWK6MPCB.js";import{b as z,f as v,g as k,i as Q,j as I,k as C,l as U,m as Z,n as F,s as u,t as M}from"./chunk-VHFFSBVJ.js";import{a as O}from"./chunk-KJZUBHLO.js";import{appendFileSync as ke,existsSync as H,mkdirSync as ye,readFileSync as Ee,writeFileSync as oe}from"node:fs";import{dirname as Te,resolve as w}from"node:path";function yt(t,e,n){for(let[r,s]of e.entries())console.log(z.blue(`${s.emoji} ${s.description}...`)),s.type==="json"?be(t,s.filename,s.content):ve(t,s.filename,String(s.content)),n&&n(s,r,e.length)}function _e(t,e,n=2){let r=`${JSON.stringify(e,null,n)}
3
+ `;oe(t,r,"utf-8")}function be(t,e,n,r=2){let s=w(t,e);_e(s,n,r)}function q(t,e){oe(t,e,"utf-8")}function ve(t,e,n){let r=w(t,e);q(r,n)}function Et(t){H(t)||ye(t,{recursive:!0})}var we=[".env",".flisk/.flisk-out/",".flisk/.project-id",".flisk/smoke/","node_modules/"];function xe(t){let e=w(t,".gitignore"),n=H(e)?Ee(e,"utf-8"):"",r=new Set(n.split(`
4
+ `).map(d=>d.trim().replace(/\/$/,""))),s=we.filter(d=>!r.has(d.replace(/\/$/,"")));if(s.length===0)return[];let l=n&&!n.endsWith(`
5
+ `)?`
6
+ `:"";return ke(e,`${l}${n?`
7
+ # Flisk (generated files and secrets)
8
+ `:`# Flisk (generated files and secrets)
9
+ `}${s.join(`
10
+ `)}
11
+ `),s}function Ie(t){let e=w(t);for(;;){if(H(w(e,".git")))return!0;let n=Te(e);if(n===e)return!1;e=n}}function Tt(t){if(Ie(t))try{xe(t);return}catch(e){let n=e instanceof Error?e.message:String(e);return`Could not add .flisk/smoke/ to ${w(t,".gitignore")}: ${n}. Git may track the smoke response records.`}}import*as a from"node:fs";import*as i from"node:path";import{fileURLToPath as We}from"node:url";import _ from"handlebars";var Fe="1.0.0",$e={runtime:"bun",bundler:"vite",language:"typescript",framework:"hono",database:"postgresql",orm:"prisma",messaging:"nats",linting:"biome",testing:"vitest"},Re={frontend:{base:u.frontend.base,range:u.frontend.range,start:u.frontend.min,end:u.frontend.max},backend:{base:u.backend.base,range:u.backend.range,start:u.backend.min,end:u.backend.max},health:{base:u.health.base,range:u.health.range,start:u.health.min,end:u.health.max},worker:{base:u.worker.base,range:u.worker.range,start:u.worker.min,end:u.worker.max},migrator:{base:u.migrator.base,range:u.migrator.range,start:u.migrator.min,end:u.migrator.max},tiltUi:M.tiltUi,traefik:M.traefik},Ae={path:"/health",live:"/health/live",ready:"/health/ready",timeout:30,interval:5},je={frontend:"-frontend",backend:"-backend",worker:"-worker",migrator:"-migrator",library:"-lib",sdk:"-sdk",validSeparators:["-","_"],maxLength:63,minLength:3},Pe={entrypoint:"web",network:"traefik-public",defaultHost:"localhost",appHost:"app.localhost",apiHost:"api.localhost",appSubdomainPrefix:"app",apiSubdomainPrefix:"api",defaultPort:8080,tlsEnabled:!1,entrypoints:["web"],middlewares:[],tls:{enabled:!1},healthcheckPath:"/health",healthcheckInterval:"10s",healthcheckTimeout:"5s",frontendPriorityBase:100},De=["node_modules","dist","build",".git",".prisma",".turbo","coverage","tmp","temp","__tests__","test","tests"],Le={frontend:{suffix:"-frontend",portRange:"3000-3999"},backend:{suffix:"-backend",portRange:"4000-4999"},library:{suffix:"-library",portRange:null},sdk:{suffix:"-sdk",portRange:"3000-9999"},migrator:{suffix:"-migrator",portRange:"7000-7999"},worker:{suffix:"-worker",portRange:"6000-6999"}},Ne={prisma:"Database ORM with migrations",nats:"Event streaming via NATS",redis:"Caching layer",infisical:"Secrets management",vitest:"Testing framework",traefik:"HTTP routing",websocket:"Real-time connections",graphql:"GraphQL support",grpc:"gRPC support",viteNode:"Vite Node runtime",maintenance:"Maintenance mode"},Oe={services:"services/product",sharedPlatform:"shared-platform-engineering",sharedProduct:"shared-product-engineering",sharedDdd:"shared-ddd-layers"},Ce={scanIntervalSeconds:5,maxManifestsPerRoot:50,servicePatterns:["services/product/*","services/platform/*"]},Ue={dockerfile:"Dockerfile",context:"."},Me={backend:{command:"bun",args:["run","dev"],env:{NODE_ENV:"development"}},frontend:{command:"bun",args:["run","dev"],env:{NODE_ENV:"development"}}},S={version:Fe,tech:$e,ports:Re,health:Ae,naming:je,traefik:Pe,filewatchIgnores:De,serviceTypes:Le,features:Ne,paths:Oe,discovery:Ce,docker:Ue,runtime:Me};import{existsSync as Ge,lstatSync as Ke}from"node:fs";import{isAbsolute as ae,normalize as R,relative as He,sep as le}from"node:path";var Ft=[`${I}/**`,".flisk/.flisk-out/**","Tiltfile","TILT_*.star",k,`${F} (create only)`,"shared-platform-engineering/docker-templates/**","services/platform/database-management/docker-compose.yml","product_autogenerated_resource_manifests/**","product_autogenerated_services_list/**"];function qe(t){let e=R(t).split(le).join("/");return ae(t)||e===".."||e.startsWith("../")?!1:e.split("/").includes(I)||e.startsWith(".flisk/.flisk-out/")||e==="shared-platform-engineering/docker-templates"||e.startsWith("shared-platform-engineering/docker-templates/")||e.startsWith("product_autogenerated_resource_manifests/")||e.startsWith("product_autogenerated_services_list/")?!0:e==="Tiltfile"||/^TILT_[^/]+\.star$/.test(e)||e===k||e===F||e==="services/platform/database-management/docker-compose.yml"}function T(t,e){let n=ae(e)?R(e):R(`${t}/${e}`),r=He(t,n).split(le).join("/");if(!qe(r))throw new Error(`Refusing to write outside Flisk's generated-file allowlist: ${r}`);let s=t;for(let l of r.split("/"))if(s=R(`${s}/${l}`),Ge(s)&&Ke(s).isSymbolicLink())throw new Error(`Refusing to write through a symbolic link in generated path: ${r}`);return n}import{existsSync as A}from"node:fs";import{join as x}from"node:path";var V=["engine","discovery","specs","ext"],j="runtime";function ce(t,e){let n=x(t,j,e);return A(n)?n:x(t,e)}function fe(t){let e=x(t,j,"Tiltfile");return A(e)?e:x(t,"Tiltfile")}function P(t){let e=["Tiltfile",...V],n=e.filter(o=>A(x(t,j,o))),r=e.filter(o=>A(x(t,o)));if(n.length===0&&r.length===0)return{ok:!1,kind:"incomplete",missing:[...e],mixed:[]};if(n.length===e.length)return{ok:!0,kind:"nested",missing:[],mixed:[]};if(n.length===0){let o=e.filter(d=>!r.includes(d));return o.length===0?{ok:!0,kind:"flat",missing:o,mixed:[]}:{ok:!1,kind:"incomplete",missing:o,mixed:[]}}let s=e.filter(o=>!n.includes(o)),l=s.filter(o=>r.includes(o));return{ok:!1,kind:l.length>0?"mixed":"incomplete",missing:s,mixed:l}}function W(t,e=P(t)){if(e.ok)return`${t}: ${e.kind} layout`;let n=[];e.kind==="mixed"&&n.push(`mixes the nested ${j}/ layout with flat entries (${e.mixed.join(", ")} only at the root)`);let r=e.missing.filter(s=>!e.mixed.includes(s));return r.length>0&&n.push(`is missing ${r.join(", ")}`),`${t} ${n.join(" and ")}`}function D(t){return P(t).ok}var Ve={[v]:{name:v,description:"Generate and load the stack-level PostgreSQL docker-compose file",generatedFiles:["services/platform/database-management/docker-compose.yml"]}};function pe(t,e){return Ve[e]?["pre_alpha","alpha","beta"].some(n=>t[n]?.enabledStacks?.includes(e)):!1}var Je=We(new URL("../dist/generator/template-engine.js",import.meta.url).href),J=i.dirname(Je);function $(t){let e=[i.join(J,"..","..","templates"),i.join(J,"..","templates"),i.join(J,"..","..","..","templates"),i.join(process.cwd(),"node_modules","@flisk-sh","flisk","templates"),i.join(i.dirname(process.execPath),"flisk-cli","cli","templates")],n=[];for(let r of e){let s=i.join(r,t);n.push(s);try{return a.readFileSync(s,"utf-8")}catch{}}throw new Error(`Failed to load template ${t} from any of these paths: ${n.join(", ")}`)}var B=null;function Be(){return B||(B={[k]:$(".tiltignore.hbs"),[U]:$("TILT_RESOURCE_DEFAULTS.star.hbs"),[C]:$("TILT_TECH_STACK.star.hbs"),Tiltfile:$("Tiltfile.hbs"),"spec.master":$("spec.master.hbs")}),B}var Ye={proxy:"Traefik reverse proxy",verdaccio:"Private npm registry","database-management":"PostgreSQL database"},Xe={monitoring:"Signoz, SkyWalking (RAM intensive)",elk:"Elasticsearch/Logstash/Kibana",debezium:"CDC with Kafka/Zookeeper",golden_image:"Golden image rebuild (one-time)",verdaccio:"Premium local npm registry"},ue=["TILT_TECH_STACK.star","TILT_RESOURCE_DEFAULTS.star","spec.master","Tiltfile",".tiltignore"],L=class{templatesDir;constructor(e){let n=O("node:url").fileURLToPath(new URL("../dist/generator",import.meta.url))||i.dirname(new URL(new URL("../dist/generator/template-engine.js",import.meta.url).href).pathname);this.templatesDir=e||i.join(n,"..","..","templates"),this.registerHelpers()}quoteStarlarkString(e){return`"${e.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`}formatStarlarkValue(e){return e==null?"None":typeof e=="string"?this.quoteStarlarkString(e):typeof e=="boolean"?e?"True":"False":typeof e=="number"?String(e):Array.isArray(e)?`[${e.map(r=>this.formatStarlarkValue(r)).join(", ")}]`:typeof e=="object"?`{${Object.entries(e).map(([r,s])=>`${this.quoteStarlarkString(r)}: ${this.formatStarlarkValue(s)}`).join(", ")}}`:String(e)}registerHelpers(){_.registerHelper("starlark",e=>new _.SafeString(this.formatStarlarkValue(e))),_.registerHelper("starlarkArray",e=>{if(!Array.isArray(e))return new _.SafeString("[]");let n=e.map(r=>this.formatStarlarkValue(r));return new _.SafeString(`[${n.join(", ")}]`)}),_.registerHelper("json",e=>JSON.stringify(e))}buildContext(e){return{version:S.version,tech:S.tech,ports:S.ports,health:S.health,naming:S.naming,traefik:S.traefik,filewatchIgnores:[...S.filewatchIgnores],serviceTypes:S.serviceTypes,paths:S.paths,discovery:{scanIntervalSeconds:S.discovery.scanIntervalSeconds,maxManifestsPerRoot:S.discovery.maxManifestsPerRoot,paths:e.discovery.paths},docker:S.docker,runtime:S.runtime,project:e.project,phases:ze(e.phases),alwaysEnabledInfra:e.always_enabled_infra??[...ie],optionalInfra:e.optional_infra,serviceDescriptions:Ye,infraDescriptions:Xe}}loadTemplate(e){let n=i.join(this.templatesDir,`${e}.hbs`),r=a.existsSync(n)?a.readFileSync(n,"utf-8"):Be()[e];if(!r)throw new Error(`Template not found: ${n}`);return _.compile(r)}generateTechStack(e){return this.loadTemplate(C)(e)}generateServiceDefaults(e){return this.loadTemplate(U)(e)}generateSpecMaster(e){return this.loadTemplate("spec.master")(e)}generateTiltfile(e){return this.loadTemplate("Tiltfile")(e)}generateTiltIgnore(e){return this.loadTemplate(".tiltignore")(e)}generateAll(e){let n=this.buildContext(e);return{"TILT_TECH_STACK.star":this.generateTechStack(n),"TILT_RESOURCE_DEFAULTS.star":this.generateServiceDefaults(n),"spec.master":this.generateSpecMaster(n),Tiltfile:this.generateTiltfile(n),".tiltignore":this.generateTiltIgnore(n)}}};function ze(t){let e={...t};for(let n of Object.keys(e))e[n]={...e[n],enabledStacks:Array.from(new Set(e[n].enabledStacks))};return e}function Qe(t){return t.replace(/-/g,"_")}function Ze(t){let e=Qe(t.project.name||"flisk_project");return`###############################################################################
12
+ # SYSTEM-GENERATED - DO NOT EDIT
13
+ # Stack feature: database-management
14
+ # Source: .flisk/project.json phases.*.enabledStacks includes "database-management"
15
+ # Regenerate with: flisk config regenerate
16
+ ###############################################################################
17
+
18
+ services:
19
+ postgres:
20
+ image: postgres:16-alpine
21
+ container_name: ${e}_postgres
22
+ restart: unless-stopped
23
+ environment:
24
+ POSTGRES_USER: ${e}
25
+ POSTGRES_PASSWORD: \${DB_PASSWORD}
26
+ POSTGRES_DB: postgres
27
+ ports:
28
+ - "\${FLISK_BIND_ADDRESS:-127.0.0.1}:\${FLISK_POSTGRES_PORT:-15432}:5432"
29
+ volumes:
30
+ - ${e}_postgres_data:/var/lib/postgresql/data
31
+ networks:
32
+ - database
33
+ healthcheck:
34
+ test: ["CMD-SHELL", "pg_isready -U ${e} -d postgres"]
35
+ interval: 5s
36
+ timeout: 5s
37
+ retries: 20
38
+
39
+ networks:
40
+ database:
41
+ name: ${e}_database
42
+ external: true
43
+
44
+ volumes:
45
+ ${e}_postgres_data:
46
+ `}function de(t,e){if(!t||typeof t!="object")return!1;let n=t;for(let r of["pre_alpha","alpha","beta","out_of_scope"]){let s=n[r];if(!s||typeof s!="object"||!Array.isArray(s[e]))return!1}return!0}function et(t){if(!t||typeof t!="object")return null;let e=t;if(typeof e.version!="string"||!e.project||typeof e.project!="object")return null;let n=e.project;if(typeof n.name!="string"||typeof n.version!="string")return null;let r=null;if(de(e.phases,"enabledStacks"))r=e.phases;else if(de(e.stacks,"services")){let o=e.stacks;r={pre_alpha:{name:o.pre_alpha.name,description:o.pre_alpha.description,enabledStacks:o.pre_alpha.services},alpha:{name:o.alpha.name,description:o.alpha.description,enabledStacks:o.alpha.services},beta:{name:o.beta.name,description:o.beta.description,enabledStacks:o.beta.services},out_of_scope:{name:o.out_of_scope.name,description:o.out_of_scope.description,enabledStacks:o.out_of_scope.services}}}if(!r||!e.optional_infra||typeof e.optional_infra!="object")return null;let s=e.optional_infra;if(typeof s.monitoring!="boolean"||typeof s.elk!="boolean"||typeof s.debezium!="boolean"||typeof s.golden_image!="boolean"||typeof s.verdaccio!="boolean"||!e.discovery||typeof e.discovery!="object")return null;let l=e.discovery;return Array.isArray(l.paths)?{version:e.version,project:e.project,phases:r,always_enabled_infra:e.always_enabled_infra,optional_infra:e.optional_infra,discovery:e.discovery,overrides:e.overrides}:null}var Y=class extends Error{};function me(t){let e=i.join(t,".flisk",Z),n;try{n=a.readFileSync(e,"utf-8")}catch(l){if(l?.code==="ENOENT")throw new Y(`Project config not found: ${e}. Run 'flisk project --yes' first.`);let o=l instanceof Error?l.message:String(l);throw new Error(`Could not read project.json at ${e}: ${o}`)}let r;try{r=JSON.parse(n)}catch(l){let o=l instanceof Error?l.message:String(l);throw new Error(`Could not parse project.json at ${e}: ${o}`)}let s=et(r);if(!s)throw new Error("Invalid project.json: missing or invalid required fields. Expected: version (string), project (object with name/version), phases (object with pre_alpha/alpha/beta/out_of_scope enabledStacks), optional_infra (object with boolean flags), discovery (object with paths array)");return s}async function tt(t){let e=ne(t).filter(r=>r.config?.sablier?.enable===!0);e.length===0||await se(t)||console.warn(`\u26A0\uFE0F Sablier (on-demand scaling) is a Premium feature - no valid license key found. ${e.length} resource${e.length===1?" has":"s have"} a \`sablier\` block, but it will have no effect without a license. Set FLISK_LICENSE_KEY to a key that grants it, or remove the \`sablier\` block from the affected service.json file(s) to silence this warning.`)}function nt(t,e){let n=T(t,F);if(a.existsSync(n))return!1;let r={name:e.project.name||i.basename(t),version:e.project.version||"1.0.0",private:!0,type:"module",workspaces:e.discovery.paths};return q(n,`${JSON.stringify(r,null,2)}
47
+ `),!0}async function Bt(t,e={}){let n=me(t),r=K(t).flatMap(p=>ee(p,i.relative(t,p).split(i.sep).join("/")));if(r.length>0)throw new Error(`Refusing to generate config from unsafe service.json values:
48
+ ${r.map(p=>` ${p}`).join(`
49
+ `)}`);await tt(t),nt(t,n)&&!e.quiet&&console.log("\u2713 Generated: package.json (workspace root)");let s=Object.values(n.phases).some(p=>p.enabledStacks.includes("verdaccio"));(n.optional_infra.verdaccio||s)&&(await re(t)||console.warn("\u26A0\uFE0F Verdaccio is a Premium feature - no valid license key found. It's enabled in this project's config, but will have no effect without a license. Set FLISK_LICENSE_KEY to a key that grants it, or run `flisk config disable-infra verdaccio` to silence this warning."));let l=i.join(t,".flisk",".flisk-out");a.existsSync(l)||a.mkdirSync(l,{recursive:!0});let d=new L().generateAll(n);for(let p of ue){let m=d[p],b=T(t,i.join(".flisk",".flisk-out",p));G(b,m),e.quiet||console.log(`\u2713 Generated: .flisk/.flisk-out/${p}`)}if(pe(n.phases,v)){let p=T(t,i.join("services","platform",v,Q)),m=i.dirname(p);a.mkdirSync(m,{recursive:!0}),G(p,Ze(n)),e.quiet||console.log("\u2713 Generated: services/platform/database-management/docker-compose.yml")}let f=i.join(l,k),c=T(t,k);if(a.existsSync(f)){if(!a.existsSync(c))a.copyFileSync(f,c),e.quiet||console.log("\u2713 Copied: .tiltignore \u2192 project root");else if(e.discardHandEdits){let p=a.readFileSync(c,"utf-8");p.includes(Se)&&p!==a.readFileSync(f,"utf-8")&&(a.copyFileSync(f,c),e.quiet||console.log("\u2713 Restored: .tiltignore \u2192 project root (hand edits discarded)"))}}let h=ct(t);if(!e.quiet)for(let p of h)console.log(`\u2713 Copied: ${p} \u2192 project root`);await ft(t,{quiet:e.quiet}),e.quiet||(console.log(""),console.log("\u{1F4A1} To start Tilt: flisk up"))}var rt=/\.(?:test|spec)\.[cm]?[jt]sx?$/;function he(t){return rt.test(t)}function ge(t){if(a.existsSync(t))for(let e of a.readdirSync(t,{withFileTypes:!0})){let n=i.join(t,e.name);e.isDirectory()?ge(n):he(n)&&a.rmSync(n,{force:!0})}}var st=V,it=[["shared-platform-engineering","docker-templates"]],ot=["install-deps.sh","bun-hoisted-symlink-fix.sh","prisma-bun-client-link-fix.sh","prisma-normalize-client.sh"];function at(){let t=O("node:url").fileURLToPath(new URL("../dist/generator",import.meta.url))||process.cwd();for(let e=0;e<6;e++){if(D(t))return t;let n=i.dirname(t);if(n===t)break;t=n}return null}function lt(){let t=O("node:url").fileURLToPath(new URL("../dist/generator",import.meta.url))||process.cwd();for(let r=0;r<8;r++){if(a.existsSync(i.join(t,"shared-platform-engineering","docker-templates")))return t;let s=i.dirname(t);if(s===t)break;t=s}let e=i.dirname(process.execPath);return[i.join(e,"flisk-cli"),i.join(process.cwd(),"node_modules","@flisk-sh","flisk")].find(r=>a.existsSync(i.join(r,"shared-platform-engineering","docker-templates")))??null}function ct(t){let e=lt(),n=[];if(!e)return console.warn("\u26A0\uFE0F Flisk runtime assets not found - generated Dockerfiles may fail. Reinstall or upgrade Flisk, then re-run `flisk project`."),n;for(let r of it){let s=i.join(e,...r),l=T(t,i.join(...r));a.existsSync(s)&&(a.mkdirSync(i.dirname(l),{recursive:!0}),a.cpSync(s,l,{recursive:!0}),n.push(r.join("/")))}for(let r of ot){let s=i.join(t,"shared-platform-engineering","docker-templates",r);a.existsSync(s)||console.warn(`\u26A0\uFE0F Missing runtime asset after copy: ${s}`)}return n}async function ft(t,e={}){let n=T(t,i.join(".flisk",".flisk-out","flisk-cli-ext")),r=[];process.env.FLISK_EXTENSION_SOURCE&&r.push(process.env.FLISK_EXTENSION_SOURCE);let s=at();s&&r.push(s);let l=i.dirname(process.execPath);r.push(i.join(l,"flisk-cli")),r.push(i.join(t,"..","flisk-cli"));let o=process.env.FLISK_EXTENSION_SOURCE;o&&a.existsSync(o)&&!D(o)&&console.warn(`\u26A0\uFE0F FLISK_EXTENSION_SOURCE is not a usable Flisk extension and is ignored:
50
+ ${W(o)}`);let d="";for(let f of r)if(f&&D(f)){d=f;break}if(!d){let f=r.filter(c=>c&&a.existsSync(c)).map(c=>({candidate:c,report:P(c)})).filter(({report:c})=>c.kind==="mixed"||c.missing.length<5);console.warn("\u26A0\uFE0F Flisk extension not found - set FLISK_EXTENSION_SOURCE to its checkout path and re-run `flisk project` (or `flisk config regenerate`) to vendor it before `flisk up`."+f.map(({candidate:c,report:h})=>`
51
+ ${W(c,h)}`).join(""));return}a.existsSync(n)||a.mkdirSync(n,{recursive:!0}),a.copyFileSync(fe(d),i.join(n,"Tiltfile"));for(let f of st)ge(i.join(n,f)),a.cpSync(ce(d,f),i.join(n,f),{recursive:!0,filter:c=>!he(c)});e.quiet||console.log("\u2713 Vendored Flisk extension \u2192 .flisk/.flisk-out/flisk-cli-ext/");try{let{applyPremiumOverlay:f}=await import("./extension-fetch-VEFSCG4B.js");await f(t,n)}catch(f){console.warn(`\u26A0\uFE0F Premium overlay skipped: ${f.message}`)}}var Se="SYSTEM-GENERATED BY Flisk CLI";function Yt(t,e){let n=[],r=[],s=[],l=[],o=(g,E,y)=>{E!==y&&(n.push(`${E===void 0?"Missing file":"Out of sync"}: ${g} (run 'flisk config regenerate')`),s.push({file:g,diff:pt(g,E??"",y)}))},d=me(t),c=new L().generateAll(d),h=i.join(t,".flisk",".flisk-out");for(let g of ue){let E=c[g],y=i.join(h,g);o(`.flisk/.flisk-out/${g}`,a.existsSync(y)?a.readFileSync(y,"utf-8"):void 0,E)}let p=i.join(t,k),m=a.existsSync(p)?a.readFileSync(p,"utf-8"):void 0;m!==void 0&&!m.includes(Se)?r.push(".tiltignore: not generated by Flisk, left as is"):o(k,m,c[k]);let b=e?.manifestPaths??K(t);for(let g of b){let E=i.relative(t,g).split(i.sep).join("/");if(!e?.skipManifestValidation){let X=te(g,E);n.push(...X.errors),r.push(...X.warnings)}let y=dt(t,g);n.push(...y.errors),l.push(...y.handEdited)}return{valid:n.length===0,errors:n,warnings:r,diffs:s,handEdited:l}}function pt(t,e,n){let r=e.replace(/\n$/,"").split(`
52
+ `),s=n.replace(/\n$/,"").split(`
53
+ `),l=[`--- a/${t}`,`+++ b/${t}`,`@@ -1,${r.length} +1,${s.length} @@`];for(let o of r)l.push(`-${o}`);for(let o of s)l.push(`+${o}`);return l.join(`
54
+ `)}function dt(t,e){let n=i.dirname(e),r=i.join(n,I);if(!a.existsSync(r))return{errors:[],handEdited:[]};let s=[],l=(h,p="")=>{for(let m of a.readdirSync(h,{withFileTypes:!0})){if(p===""&&m.name===".flisk-contract")continue;let b=i.join(p,m.name),g=i.join(h,m.name);m.isDirectory()?l(g,b):m.isFile()&&s.push({fullPath:g,relativeFile:b})}};if(l(r),s.length===0)return{errors:[],handEdited:[]};let o=i.join(r,".flisk-contract"),d=i.join(o,"service.json.source"),f=[],c=[];a.existsSync(d)?a.readFileSync(d,"utf-8")!==a.readFileSync(e,"utf-8")&&f.push(i.relative(t,e)+": service.json changed since generated outputs were written (run flisk up)"):f.push(i.relative(t,d)+": generated-file contract snapshot is missing (run flisk up to regenerate)");for(let h of s){if(h.relativeFile==="service.yaml")continue;let p=i.join(o,h.relativeFile),m=i.relative(t,h.fullPath);a.existsSync(p)?a.readFileSync(h.fullPath,"utf-8")!==a.readFileSync(p,"utf-8")&&(c.push(m.split(i.sep).join("/")),f.push(`${m}: generated file differs from its Flisk snapshot (run flisk up to regenerate)`)):f.push(`${m}: generated-file snapshot is missing (run flisk up to regenerate)`)}return{errors:f,handEdited:c}}import{stdin as ut,stdout as mt}from"node:process";import{createInterface as ht}from"node:readline/promises";async function N(t){let e=ht({input:ut,output:mt});try{return await new Promise((n,r)=>{e.once("close",()=>r(new Error("No input available to answer the prompt. Run this in a terminal."))),e.question(t).then(s=>n(s.trim()),r)})}finally{e.close()}}async function Zt(t){let e=t.initial?` (${t.initial})`:"";for(;;){let r=await N(`${t.message}${e} `)||t.initial||"",s=t.validate?.(r)??!0;if(s===!0)return r;console.log(s)}}async function en(t){let e=t.initial??!0,n=e?"Y/n":"y/N";for(;;){let r=(await N(`${t.message} (${n}) `)).toLowerCase();if(!r)return e;if(["y","yes"].includes(r))return!0;if(["n","no"].includes(r))return!1;console.log("Please answer yes or no.")}}async function tn(t){for(console.log(t.message),t.choices.forEach((e,n)=>{console.log(` ${n+1}. ${e.title}`)});;){let e=await N("Choose one: "),n=Number.parseInt(e,10)-1,r=t.choices[n];if(r)return r.value;console.log(`Enter a number from 1 to ${t.choices.length}.`)}}async function nn(t){let e=t.choices.map((r,s)=>r.selected?s+1:null).filter(r=>r!==null),n=e.length>0?` [${e.join(",")}]`:"";for(console.log(t.message),t.choices.forEach((r,s)=>{let l=r.selected?"*":" ";console.log(` ${l} ${s+1}. ${r.title}`)});;){let r=await N(`Choose one or more numbers, comma-separated${n}: `),s=e;if(r){let d=r.split(",").map(c=>c.trim()),f=d.find(c=>{if(!/^\d+$/.test(c))return!0;let h=Number.parseInt(c,10);return!t.choices[h-1]});if(f!==void 0){console.log(`"${f}" is not a valid choice (1-${t.choices.length})`);continue}s=d.map(c=>Number.parseInt(c,10))}let l=Array.from(new Set(s)).map(d=>t.choices[d-1]).filter(d=>!!d).map(d=>d.value),o=t.validate?.(l)??!0;if(o===!0)return l;console.log(o)}}export{yt as a,_e as b,Et as c,xe as d,Tt as e,V as f,ce as g,fe as h,P as i,W as j,$ as k,L as l,Y as m,me as n,Bt as o,lt as p,ct as q,Yt as r,Zt as s,en as t,tn as u,nn as v};
@@ -1,5 +1,5 @@
1
- import{createRequire as __tdkRequire}from'node:module';const require=__tdkRequire(import.meta.url);
2
- import{b as N}from"./chunk-BHWJU6HY.js";import{a as m,ga as f,t as T}from"./chunk-AGXA5DOQ.js";import{C as M,L as O,e as $,f as C,i as U,j as E,m as F,n as P,x as l}from"./chunk-AT5MFZ3D.js";import{execFileSync as de,execSync as ue}from"node:child_process";import{existsSync as R,readdirSync as V,readFileSync as y}from"node:fs";import{basename as le,dirname as me,join as u,relative as k}from"node:path";function Oe(t){return I(t,!1)}function Ne(t){return I(t,!0)}function I(t,e){return`import { Hono } from 'hono';
1
+ import{createRequire as __fliskRequire}from'node:module';const require=__fliskRequire(import.meta.url);
2
+ import{b as N}from"./chunk-QQEV6D74.js";import{a as m,ga as f,t as T}from"./chunk-BWK6MPCB.js";import{C as M,L as O,e as $,f as C,i as U,j as E,m as F,n as P,x as u}from"./chunk-VHFFSBVJ.js";import{execFileSync as de,execSync as le}from"node:child_process";import{existsSync as R,readdirSync as V,readFileSync as y}from"node:fs";import{basename as ue,dirname as me,join as l,relative as k}from"node:path";function Oe(t){return I(t,!1)}function Ne(t){return I(t,!0)}function I(t,e){return`import { Hono } from 'hono';
3
3
  ${e?`import { sql } from 'drizzle-orm';
4
4
  import { db } from './db.js';
5
5
  `:""}
@@ -345,22 +345,22 @@ mod tests {
345
345
  assert_eq!(body["status"], "ok");
346
346
  }
347
347
  }
348
- `,description:"Generating backend source and smoke test",emoji:"\u{1F4BB}"}]}};var J="bun",h={bun:G,python:q,go:L,rust:H,node:B};function ae(t){let e=(t??J).trim().toLowerCase(),n=Object.hasOwn(h,e)?h[e]:void 0;if(!n){let s=Object.keys(h).join(", ");throw new O(`Unknown backend language "${t}". Supported languages: ${s}.`,[`Use one of: ${s}`,`Omit --language to use ${J}`])}return n}function qe(t,e){if(t!=="backend"){if(e!==void 0)throw new O("--language can only be used with --type backend.",["Add --type backend, or drop --language for this resource type"]);return}return ae(e)}import{exec as ie,execFile as ce}from"node:child_process";import{promisify as W}from"node:util";var pe=W(ie),z=async(t,e)=>{if(process.platform==="win32"){let s=t.match(/(?:[^\s"']+|"[^"]*"|'[^']*')+/g)??[],[o,...r]=s.map(c=>c.startsWith('"')||c.startsWith("'")?c.slice(1,-1):c);if(!o)throw new Error("Command is empty");let a=M(o)??o,{stdout:i}=await W(ce)(a,r,{encoding:"utf-8",timeout:e,windowsHide:!0,shell:!1});return i}let{stdout:n}=await pe(t,{encoding:"utf-8",timeout:e});return n};function Ke(t){let e=t;return e?.code==="ETIMEDOUT"||e?.killed===!0}var x=1e4,fe=/\.(?:[cm]?[jt]sx?|vue)$/,he=/(?:\.test\.|\.spec\.|\/tests?\/|\/__tests__\/)/,ge=7,ke=new Set(["node_modules",E,"dist","tests","__tests__"]);function Y(t){try{let e=JSON.parse(y(u(t,".tdk",F),"utf-8"));return typeof e?.project?.name=="string"?e.project.name:void 0}catch{return}}function ye(t){try{let e=JSON.parse(y(t,"utf-8")).params;return e&&typeof e=="object"?e:{}}catch{return{}}}function A(t){try{let e=JSON.parse(y(u(t,P),"utf-8"));return e&&typeof e=="object"?e:{}}catch{return{}}}function K(t){if(typeof t!="string")return;let e=t.match(/(?:^|[^0-9])(\d+)(?:\.|$)/);return e?Number(e[1]):void 0}function be(t){let e=S(t);if(e===void 0)return["missing prisma/schema.prisma"];let n=e.replace(/\/\*[\s\S]*?\*\//g,"").replace(/^\s*\/\/.*$/gm,""),s=[],o=n.match(/datasource\s+\w+\s*\{([^}]*)\}/)?.[1]??"";return/provider\s*=\s*["']postgresql["']/.test(o)||s.push("schema provider is not postgresql"),/\b(?:url|directUrl)\s*=/.test(n)&&s.push("schema still declares url/directUrl"),s}function we(t){let e=u(t,E,"prisma.config.autogenerated.ts"),s=[u(t,"prisma.config.ts"),e].find(a=>R(a));if(!s)return["missing prisma.config.ts or generated Prisma config"];let r=(S(s)??"").match(/datasource\s*:\s*\{([^}]*)\}/)?.[1]??"";return/url\s*:\s*(?:env\(["']DATABASE_URL["']\)|process\.env\.DATABASE_URL)\s*,?/.test(r)?[]:['Prisma config datasource.url is not env("DATABASE_URL")']}function it(t=l()??process.cwd(),e=f(t)){let n=e.filter(r=>r.config?.featuresEnabled?.includes("prisma")),s=[],o=e.filter(r=>r.config?.appType==="migrator");for(let r of e){let a=r.config?.features;Array.isArray(a)&&a.includes("prisma")&&!r.config?.featuresEnabled?.includes("prisma")&&s.push(`${r.name}: use featuresEnabled, not features, for Prisma`)}if(n.length===0)return s.length===0?{name:"Prisma 7 consistency",didPass:!0,isSkipped:!0,message:"No resources enable Prisma; Prisma consistency checks were skipped"}:{name:"Prisma 7 consistency",didPass:!1,message:`${m(s.length,"Prisma consistency error")}:
348
+ `,description:"Generating backend source and smoke test",emoji:"\u{1F4BB}"}]}};var J="bun",h={bun:G,python:q,go:L,rust:H,node:B};function ae(t){let e=(t??J).trim().toLowerCase(),n=Object.hasOwn(h,e)?h[e]:void 0;if(!n){let s=Object.keys(h).join(", ");throw new O(`Unknown backend language "${t}". Supported languages: ${s}.`,[`Use one of: ${s}`,`Omit --language to use ${J}`])}return n}function qe(t,e){if(t!=="backend"){if(e!==void 0)throw new O("--language can only be used with --type backend.",["Add --type backend, or drop --language for this resource type"]);return}return ae(e)}import{exec as ie,execFile as ce}from"node:child_process";import{promisify as W}from"node:util";var pe=W(ie),z=async(t,e)=>{if(process.platform==="win32"){let s=t.match(/(?:[^\s"']+|"[^"]*"|'[^']*')+/g)??[],[o,...r]=s.map(c=>c.startsWith('"')||c.startsWith("'")?c.slice(1,-1):c);if(!o)throw new Error("Command is empty");let a=M(o)??o,{stdout:i}=await W(ce)(a,r,{encoding:"utf-8",timeout:e,windowsHide:!0,shell:!1});return i}let{stdout:n}=await pe(t,{encoding:"utf-8",timeout:e});return n};function Ke(t){let e=t;return e?.code==="ETIMEDOUT"||e?.killed===!0}var x=1e4,fe=/\.(?:[cm]?[jt]sx?|vue)$/,he=/(?:\.test\.|\.spec\.|\/tests?\/|\/__tests__\/)/,ge=7,ke=new Set(["node_modules",E,"dist","tests","__tests__"]);function Y(t){try{let e=JSON.parse(y(l(t,".flisk",F),"utf-8"));return typeof e?.project?.name=="string"?e.project.name:void 0}catch{return}}function ye(t){try{let e=JSON.parse(y(t,"utf-8")).params;return e&&typeof e=="object"?e:{}}catch{return{}}}function A(t){try{let e=JSON.parse(y(l(t,P),"utf-8"));return e&&typeof e=="object"?e:{}}catch{return{}}}function K(t){if(typeof t!="string")return;let e=t.match(/(?:^|[^0-9])(\d+)(?:\.|$)/);return e?Number(e[1]):void 0}function be(t){let e=S(t);if(e===void 0)return["missing prisma/schema.prisma"];let n=e.replace(/\/\*[\s\S]*?\*\//g,"").replace(/^\s*\/\/.*$/gm,""),s=[],o=n.match(/datasource\s+\w+\s*\{([^}]*)\}/)?.[1]??"";return/provider\s*=\s*["']postgresql["']/.test(o)||s.push("schema provider is not postgresql"),/\b(?:url|directUrl)\s*=/.test(n)&&s.push("schema still declares url/directUrl"),s}function we(t){let e=l(t,E,"prisma.config.autogenerated.ts"),s=[l(t,"prisma.config.ts"),e].find(a=>R(a));if(!s)return["missing prisma.config.ts or generated Prisma config"];let r=(S(s)??"").match(/datasource\s*:\s*\{([^}]*)\}/)?.[1]??"";return/url\s*:\s*(?:env\(["']DATABASE_URL["']\)|process\.env\.DATABASE_URL)\s*,?/.test(r)?[]:['Prisma config datasource.url is not env("DATABASE_URL")']}function it(t=u()??process.cwd(),e=f(t)){let n=e.filter(r=>r.config?.featuresEnabled?.includes("prisma")),s=[],o=e.filter(r=>r.config?.appType==="migrator");for(let r of e){let a=r.config?.features;Array.isArray(a)&&a.includes("prisma")&&!r.config?.featuresEnabled?.includes("prisma")&&s.push(`${r.name}: use featuresEnabled, not features, for Prisma`)}if(n.length===0)return s.length===0?{name:"Prisma 7 consistency",didPass:!0,isSkipped:!0,message:"No resources enable Prisma; Prisma consistency checks were skipped"}:{name:"Prisma 7 consistency",didPass:!1,message:`${m(s.length,"Prisma consistency error")}:
349
349
  ${s.join(`
350
- `)}`,fix:"Use featuresEnabled to opt into the validated Prisma 7 shape"};for(let r of n){let a=A(r.path).dependencies,c={...A(r.path).devDependencies??{},...a??{}},d=K(c.prisma),p=K(c["@prisma/client"]);if(d===void 0||p===void 0?s.push(`${r.name}: prisma and @prisma/client are required`):(d!==p||d!==ge)&&s.push(`${r.name}: prisma packages must both be major 7`),s.push(...be(u(r.path,"prisma","schema.prisma")).map(g=>`${r.name}: ${g}`)),s.push(...we(r.path).map(g=>`${r.name}: ${g}`)),(r.config?.appType??r.type)==="migrator")r.config?.dependsOn?.some(w=>w==="postgres"||w===C)||s.push(`${r.name}: migrator must depend on postgres or database-management`);else{r.config?.dependsOn?.some(_=>o.some(v=>v.name===_))||s.push(`${r.name}: API must depend on its Prisma migrator, which depends on postgres or database-management`);let w=A(r.path).scripts;Object.entries(w??{}).some(([_,v])=>ee.has(_)&&typeof v=="string"&&/prisma\s+migrate/.test(v))&&s.push(`${r.name}: API start script must not run prisma migrate`);let te=u(r.path,r.config?.dockerfile??"Dockerfile");j(te,!0)&&s.push(`${r.name}: API image/startup must not run Prisma migrations`)}}return n.length>0&&!N(t,e).willStart&&s.push("shared platform Postgres will not start for the Prisma resources"),s.length===0?{name:"Prisma 7 consistency",didPass:!0,message:"Prisma resources use the validated Prisma 7 shape"}:{name:"Prisma 7 consistency",didPass:!1,message:`${m(s.length,"Prisma consistency error")}:
350
+ `)}`,fix:"Use featuresEnabled to opt into the validated Prisma 7 shape"};for(let r of n){let a=A(r.path).dependencies,c={...A(r.path).devDependencies??{},...a??{}},d=K(c.prisma),p=K(c["@prisma/client"]);if(d===void 0||p===void 0?s.push(`${r.name}: prisma and @prisma/client are required`):(d!==p||d!==ge)&&s.push(`${r.name}: prisma packages must both be major 7`),s.push(...be(l(r.path,"prisma","schema.prisma")).map(g=>`${r.name}: ${g}`)),s.push(...we(r.path).map(g=>`${r.name}: ${g}`)),(r.config?.appType??r.type)==="migrator")r.config?.dependsOn?.some(w=>w==="postgres"||w===C)||s.push(`${r.name}: migrator must depend on postgres or database-management`);else{r.config?.dependsOn?.some(_=>o.some(v=>v.name===_))||s.push(`${r.name}: API must depend on its Prisma migrator, which depends on postgres or database-management`);let w=A(r.path).scripts;Object.entries(w??{}).some(([_,v])=>ee.has(_)&&typeof v=="string"&&/prisma\s+migrate/.test(v))&&s.push(`${r.name}: API start script must not run prisma migrate`);let te=l(r.path,r.config?.dockerfile??"Dockerfile");j(te,!0)&&s.push(`${r.name}: API image/startup must not run Prisma migrations`)}}return n.length>0&&!N(t,e).willStart&&s.push("shared platform Postgres will not start for the Prisma resources"),s.length===0?{name:"Prisma 7 consistency",didPass:!0,message:"Prisma resources use the validated Prisma 7 shape"}:{name:"Prisma 7 consistency",didPass:!1,message:`${m(s.length,"Prisma consistency error")}:
351
351
  ${s.join(`
352
- `)}`,fix:"Use Prisma 7 packages and config, put migrations in a migrator, and make the API depend on that migrator"}}function X(t){let e=new Map;for(let n of t){let s=n.config?.port;T(n.config?.appType)&&typeof s=="number"&&e.set(n.name,s)}return e}function ve(t){let e=t.config?.language;return typeof e=="string"&&Object.hasOwn(h,e)&&h[e].createFiles!==void 0}function $e(t){return(t.config?.appType??t.type)===$}function ct(t=l()??process.cwd()){let e=f(t).filter(n=>!$e(n)&&!ve(n)&&!R(u(n.path,P))).map(n=>n.name);return e.length===0?{name:"Resource package.json",didPass:!0,message:"Every resource has a package.json"}:{name:"Resource package.json",didPass:!1,message:`${m(e.length,"resource")} without a package.json: ${e.join(", ")}. The image build stops at "COPY .../package.json: not found"`,fix:"Add a package.json next to each service.json (copy one from a working resource), or delete the folder's service.json if it is not a service"}}function pt(t=l()??process.cwd(),e=f(t)){let n=new Map;for(let r of e){let a=n.get(r.name)??[];a.push(k(t,r.configPath)||r.configPath),n.set(r.name,a)}let s=[...n].filter(([,r])=>r.length>1);if(s.length===0)return{name:"Duplicate resource names",didPass:!0,message:"Every resource has a unique appName"};let o=s.map(([r,a])=>`"${r}" in ${a.join(" and ")}`);return{name:"Duplicate resource names",didPass:!1,message:`${m(s.length,"appName")} used by more than one resource:
352
+ `)}`,fix:"Use Prisma 7 packages and config, put migrations in a migrator, and make the API depend on that migrator"}}function X(t){let e=new Map;for(let n of t){let s=n.config?.port;T(n.config?.appType)&&typeof s=="number"&&e.set(n.name,s)}return e}function ve(t){let e=t.config?.language;return typeof e=="string"&&Object.hasOwn(h,e)&&h[e].createFiles!==void 0}function $e(t){return(t.config?.appType??t.type)===$}function ct(t=u()??process.cwd()){let e=f(t).filter(n=>!$e(n)&&!ve(n)&&!R(l(n.path,P))).map(n=>n.name);return e.length===0?{name:"Resource package.json",didPass:!0,message:"Every resource has a package.json"}:{name:"Resource package.json",didPass:!1,message:`${m(e.length,"resource")} without a package.json: ${e.join(", ")}. The image build stops at "COPY .../package.json: not found"`,fix:"Add a package.json next to each service.json (copy one from a working resource), or delete the folder's service.json if it is not a service"}}function pt(t=u()??process.cwd(),e=f(t)){let n=new Map;for(let r of e){let a=n.get(r.name)??[];a.push(k(t,r.configPath)||r.configPath),n.set(r.name,a)}let s=[...n].filter(([,r])=>r.length>1);if(s.length===0)return{name:"Duplicate resource names",didPass:!0,message:"Every resource has a unique appName"};let o=s.map(([r,a])=>`"${r}" in ${a.join(" and ")}`);return{name:"Duplicate resource names",didPass:!1,message:`${m(s.length,"appName")} used by more than one resource:
353
353
  ${o.join(`
354
- `)}`,fix:'Give each resource its own "appName" in its service.json. The name becomes the Compose service and the Traefik router, so two resources with one name collide'}}function Pe(t){let e=t.config?.appType;return T(e)?!0:e===$&&t.config?.exposeViaProxy!==!1}function dt(t=l()??process.cwd()){let e=new Map;for(let o of f(t)){let r=o.config?.port;if(typeof r!="number"||!Pe(o))continue;let a=e.get(r)??[];a.push(o.name),e.set(r,a)}let n=[...e].filter(([,o])=>o.length>1);if(n.length===0)return{name:"Duplicate resource ports",didPass:!0,message:"No two routed resources use the same port"};let s=n.map(([o,r])=>`port ${o}: ${r.join(", ")}`);return{name:"Duplicate resource ports",didPass:!1,isWarning:!0,message:`${m(n.length,"port")} used by more than one routed resource:
354
+ `)}`,fix:'Give each resource its own "appName" in its service.json. The name becomes the Compose service and the Traefik router, so two resources with one name collide'}}function Pe(t){let e=t.config?.appType;return T(e)?!0:e===$&&t.config?.exposeViaProxy!==!1}function dt(t=u()??process.cwd()){let e=new Map;for(let o of f(t)){let r=o.config?.port;if(typeof r!="number"||!Pe(o))continue;let a=e.get(r)??[];a.push(o.name),e.set(r,a)}let n=[...e].filter(([,o])=>o.length>1);if(n.length===0)return{name:"Duplicate resource ports",didPass:!0,message:"No two routed resources use the same port"};let s=n.map(([o,r])=>`port ${o}: ${r.join(", ")}`);return{name:"Duplicate resource ports",didPass:!1,isWarning:!0,message:`${m(n.length,"port")} used by more than one routed resource:
355
355
  ${s.join(`
356
- `)}`,fix:'Usually a copied service.json. Each container can listen on the same port, but pick distinct "port" values (flisk resource assigns free ones) so URLs like http://<resource>:<port> and localhost checks stay unambiguous'}}var Te=/https?:\/\/([a-z][a-z0-9-]*):(\d+)/g;function ut(t=l()??process.cwd()){let e=f(t),n=X(e),s=new Map([...n].map(([r,a])=>[a,r])),o=[];for(let r of e)for(let[a,i]of Object.entries(ye(r.configPath)))for(let[,c,d]of String(i).matchAll(Te)){let p=Number(d),b=n.get(c);b!==void 0&&b!==p?o.push(`${r.name} param ${a}: ${c}:${p}, but ${c} listens on ${b}`):(c==="localhost"||c==="127.0.0.1")&&s.has(p)&&s.get(p)!==r.name&&o.push(`${r.name} param ${a}: localhost:${p} is ${r.name} itself inside its container; ${s.get(p)} is reached as ${s.get(p)}:${p}`)}return o.length===0?{name:"Service URL ports",didPass:!0,message:"Service URLs in params point at the ports the services listen on"}:{name:"Service URL ports",didPass:!1,message:`${m(o.length,"service URL")} in params that cannot connect:
356
+ `)}`,fix:'Usually a copied service.json. Each container can listen on the same port, but pick distinct "port" values (flisk resource assigns free ones) so URLs like http://<resource>:<port> and localhost checks stay unambiguous'}}var Te=/https?:\/\/([a-z][a-z0-9-]*):(\d+)/g;function lt(t=u()??process.cwd()){let e=f(t),n=X(e),s=new Map([...n].map(([r,a])=>[a,r])),o=[];for(let r of e)for(let[a,i]of Object.entries(ye(r.configPath)))for(let[,c,d]of String(i).matchAll(Te)){let p=Number(d),b=n.get(c);b!==void 0&&b!==p?o.push(`${r.name} param ${a}: ${c}:${p}, but ${c} listens on ${b}`):(c==="localhost"||c==="127.0.0.1")&&s.has(p)&&s.get(p)!==r.name&&o.push(`${r.name} param ${a}: localhost:${p} is ${r.name} itself inside its container; ${s.get(p)} is reached as ${s.get(p)}:${p}`)}return o.length===0?{name:"Service URL ports",didPass:!0,message:"Service URLs in params point at the ports the services listen on"}:{name:"Service URL ports",didPass:!1,message:`${m(o.length,"service URL")} in params that cannot connect:
357
357
  ${o.join(`
358
- `)}`,fix:'Flisk runs each backend on the "port" in its service.json, and containers reach each other by resource name (http://<resource>:<port>). Use that port in the URL'}}function D(t){let e=[],n;try{n=V(t,{withFileTypes:!0})}catch{return e}for(let s of n){let o=u(t,s.name);s.isDirectory()?ke.has(s.name)||e.push(...D(o)):fe.test(s.name)&&!he.test(o)&&e.push(o)}return e}var je=/(?:localhost|127\.0\.0\.1):(\d{2,5})\b/g,Q=/^\s*(?:\/\/|\/\*|\*|<!--|#)/;function lt(t=l()??process.cwd()){let e=new Map;for(let s of f(t)){let o=s.config;if(!(T(o?.appType)||o?.appType===$&&o.exposeViaProxy!==!1))continue;let a=me(s.path),i=o?.stack??le(a),c=`${a}\0${i}`,d=e.get(c)??{stack:i,resources:[]};d.resources.push(s),e.set(c,d)}let n=[];for(let{stack:s,resources:o}of e.values()){if(o.length<2)continue;let r=i=>!!(i.config?.traefik?.host||i.config?.traefik?.pathPrefix),a=o.filter(i=>!r(i)).map(i=>i.name);a.length>0&&n.push(`stack "${s}": ${a.sort().join(", ")} lose the shared /api/${s}-management route because ${o.length} backends share the stack; they are routed at /api/<name> only`);for(let i of["host","pathPrefix"]){let c=new Map;for(let d of o){let p=d.config?.traefik?.[i];p&&c.set(p,[...c.get(p)??[],d.name])}for(let[d,p]of c)p.length>1&&n.push(`stack "${s}": ${p.sort().join(" and ")} both set traefik.${i} "${d}", so Traefik cannot tell them apart`)}}return n.length===0?{name:"Stack API routes",didPass:!0,message:"No two backends in one service directory compete for one stack route"}:{name:"Stack API routes",didPass:!1,isWarning:!0,message:n.join(`
359
- `),fix:'Call each backend at /api/<name>, move one backend to its own stack, or give each its own "traefik.pathPrefix" in service.json'}}function mt(t=l()??process.cwd()){let e=f(t),n=new Map([...X(e)].map(([r,a])=>[a,r])),s=[];for(let r of e.filter(a=>a.config?.appType==="frontend"))for(let a of D(u(r.path,"src")))y(a,"utf-8").split(`
358
+ `)}`,fix:'Flisk runs each backend on the "port" in its service.json, and containers reach each other by resource name (http://<resource>:<port>). Use that port in the URL'}}function D(t){let e=[],n;try{n=V(t,{withFileTypes:!0})}catch{return e}for(let s of n){let o=l(t,s.name);s.isDirectory()?ke.has(s.name)||e.push(...D(o)):fe.test(s.name)&&!he.test(o)&&e.push(o)}return e}var je=/(?:localhost|127\.0\.0\.1):(\d{2,5})\b/g,Q=/^\s*(?:\/\/|\/\*|\*|<!--|#)/;function ut(t=u()??process.cwd()){let e=new Map;for(let s of f(t)){let o=s.config;if(!(T(o?.appType)||o?.appType===$&&o.exposeViaProxy!==!1))continue;let a=me(s.path),i=o?.stack??ue(a),c=`${a}\0${i}`,d=e.get(c)??{stack:i,resources:[]};d.resources.push(s),e.set(c,d)}let n=[];for(let{stack:s,resources:o}of e.values()){if(o.length<2)continue;let r=i=>!!(i.config?.traefik?.host||i.config?.traefik?.pathPrefix),a=o.filter(i=>!r(i)).map(i=>i.name);a.length>0&&n.push(`stack "${s}": ${a.sort().join(", ")} lose the shared /api/${s}-management route because ${o.length} backends share the stack; they are routed at /api/<name> only`);for(let i of["host","pathPrefix"]){let c=new Map;for(let d of o){let p=d.config?.traefik?.[i];p&&c.set(p,[...c.get(p)??[],d.name])}for(let[d,p]of c)p.length>1&&n.push(`stack "${s}": ${p.sort().join(" and ")} both set traefik.${i} "${d}", so Traefik cannot tell them apart`)}}return n.length===0?{name:"Stack API routes",didPass:!0,message:"No two backends in one service directory compete for one stack route"}:{name:"Stack API routes",didPass:!1,isWarning:!0,message:n.join(`
359
+ `),fix:'Call each backend at /api/<name>, move one backend to its own stack, or give each its own "traefik.pathPrefix" in service.json'}}function mt(t=u()??process.cwd()){let e=f(t),n=new Map([...X(e)].map(([r,a])=>[a,r])),s=[];for(let r of e.filter(a=>a.config?.appType==="frontend"))for(let a of D(l(r.path,"src")))y(a,"utf-8").split(`
360
360
  `).forEach((i,c)=>{if(!Q.test(i))for(let[,d]of i.matchAll(je)){let p=n.get(Number(d));p&&s.push(`${k(t,a)}:${c+1} calls localhost:${d} (${p})`)}});if(s.length===0)return{name:"Frontend backend URLs",didPass:!0,message:"No frontend calls a backend through a localhost port"};let o=Y(t)??"<project>";return{name:"Frontend backend URLs",didPass:!1,message:`${m(s.length,"frontend call")} to a backend port that Flisk does not publish on localhost:
361
361
  ${s.join(`
362
- `)}`,fix:`Backends are only reachable through Traefik: http://api.${o}.localhost/api/<name without -api>/... (for example catalog-api is /api/catalog). Use that URL, or the generated .autogenerated/env.ts`}}var Z=/\b(?:prisma\s+(?:migrate\s+(?:deploy|dev|resolve)|db\s+push)|drizzle-kit\s+(?:migrate|push)|knex\s+migrate:\w+|typeorm\s+migration:run|mikro-orm\s+migration:up|sequelize(?:-cli)?\s+db:migrate|dbmate\s+(?:up|migrate)|atlas\s+migrate\s+apply|alembic\s+upgrade)\b/,ee=new Set(["start","dev","serve","prestart","predev","preserve"]),xe=/\.(?:sh|bash)$/,Se=/^\s*(?:CMD|ENTRYPOINT)\b/i;function S(t){try{return y(t,"utf-8")}catch{return}}function _e(t){let e=S(u(t,P));if(e===void 0)return[];let n={};try{n=JSON.parse(e)?.scripts??{}}catch{return[]}return Object.entries(n).filter(([s,o])=>ee.has(s)&&typeof o=="string"&&Z.test(o)).map(([s])=>`package.json "${s}" script`)}function j(t,e){let n=S(t);return n===void 0?!1:n.split(`
363
- `).some(s=>Z.test(s.replace(/["'`,[\]]+/g," "))&&!Q.test(s)&&(!e||Se.test(s)))}function ft(t=l()??process.cwd()){let e=[];for(let n of f(t)){let s=n.config?.appType??n.type;if(s!=="backend"&&s!=="worker")continue;let o=n.path;for(let i of _e(o))e.push(`${n.name}: ${i}`);let r=u(o,n.config?.dockerfile??"Dockerfile");j(r,!0)&&e.push(`${n.name}: ${k(t,r)} CMD or ENTRYPOINT`);let a=[];try{a=V(o,{withFileTypes:!0})}catch{}for(let i of a){let c=u(o,i.name);i.isFile()&&xe.test(i.name)&&j(c,!1)&&e.push(`${n.name}: ${k(t,c)}`)}for(let i of D(u(o,"src")))j(i,!1)&&e.push(`${n.name}: ${k(t,i)}`)}return e.length===0?{name:"Migrations outside the API",didPass:!0,message:"No backend or worker runs a migration command from its own start-up"}:{name:"Migrations outside the API",didPass:!1,isWarning:!0,message:`${m(e.length,"migration command")} run from a backend or worker's own start-up:
362
+ `)}`,fix:`Backends are only reachable through Traefik: http://api.${o}.localhost/api/<name without -api>/... (for example catalog-api is /api/catalog). Use that URL, or the generated .autogenerated/env.ts`}}var Z=/\b(?:prisma\s+(?:migrate\s+(?:deploy|dev|resolve)|db\s+push)|drizzle-kit\s+(?:migrate|push)|knex\s+migrate:\w+|typeorm\s+migration:run|mikro-orm\s+migration:up|sequelize(?:-cli)?\s+db:migrate|dbmate\s+(?:up|migrate)|atlas\s+migrate\s+apply|alembic\s+upgrade)\b/,ee=new Set(["start","dev","serve","prestart","predev","preserve"]),xe=/\.(?:sh|bash)$/,Se=/^\s*(?:CMD|ENTRYPOINT)\b/i;function S(t){try{return y(t,"utf-8")}catch{return}}function _e(t){let e=S(l(t,P));if(e===void 0)return[];let n={};try{n=JSON.parse(e)?.scripts??{}}catch{return[]}return Object.entries(n).filter(([s,o])=>ee.has(s)&&typeof o=="string"&&Z.test(o)).map(([s])=>`package.json "${s}" script`)}function j(t,e){let n=S(t);return n===void 0?!1:n.split(`
363
+ `).some(s=>Z.test(s.replace(/["'`,[\]]+/g," "))&&!Q.test(s)&&(!e||Se.test(s)))}function ft(t=u()??process.cwd()){let e=[];for(let n of f(t)){let s=n.config?.appType??n.type;if(s!=="backend"&&s!=="worker")continue;let o=n.path;for(let i of _e(o))e.push(`${n.name}: ${i}`);let r=l(o,n.config?.dockerfile??"Dockerfile");j(r,!0)&&e.push(`${n.name}: ${k(t,r)} CMD or ENTRYPOINT`);let a=[];try{a=V(o,{withFileTypes:!0})}catch{}for(let i of a){let c=l(o,i.name);i.isFile()&&xe.test(i.name)&&j(c,!1)&&e.push(`${n.name}: ${k(t,c)}`)}for(let i of D(l(o,"src")))j(i,!1)&&e.push(`${n.name}: ${k(t,i)}`)}return e.length===0?{name:"Migrations outside the API",didPass:!0,message:"No backend or worker runs a migration command from its own start-up"}:{name:"Migrations outside the API",didPass:!1,isWarning:!0,message:`${m(e.length,"migration command")} run from a backend or worker's own start-up:
364
364
  ${e.join(`
365
- `)}`,fix:"Move the migration into a `migrator` resource (appType migrator) that the service depends on, so it runs once before the service starts instead of on every start and restart"}}function ht(t=l()??process.cwd()){let e=f(t).filter(s=>s.config?.featuresEnabled?.includes("nats")).map(s=>s.name);if(e.length===0)return{name:"NATS broker",didPass:!0,message:"No resource enables the nats feature",isSkipped:!0};if(R(u(t,"services","platform","messaging",U)))return{name:"NATS broker",didPass:!0,message:`${m(e.length,"resource")} enable nats and services/platform/messaging/docker-compose.yml is present`};let n=(Y(t)??"project").replace(/-/g,"_");return{name:"NATS broker",didPass:!1,message:`${e.join(", ")} enable the nats feature, but no NATS server will start: Flisk only starts one when services/platform/messaging/docker-compose.yml exists, and it does not generate that file`,fix:`Create it with a "nats" service (image nats with -js, container_name ${n}_nats, network ${n}_backend, external) and a "redis" service, which Flisk registers alongside it`}}function gt(t=l()??process.cwd()){let e=N(t),n=" (project resource set; flisk up may select a subset and not start Postgres)",s=e.focusWouldEnableDatabaseManagement?" Warning: generated Tiltfile default focus expands CORE_INFRA to database-management while project.json has it off; default flisk up takes the feature path.":"";if(e.unknownDependsOnNames.length>0){let r=e.unknownDependsOnNames.map(({resource:i,name:c})=>`"${c}" (from ${i})`).join(", "),a=e.willStart?` Postgres will start because ${e.reason==="feature"?"database-management is enabled":`resource(s) ${e.dependsOnUsers.join(", ")} depend on postgres/database-management`}${n}`:" Postgres will not start for this project.json/generated Tiltfile state.";return{name:"Shared platform Postgres",didPass:!1,message:`${m(e.unknownDependsOnNames.length,"unknown dependsOn name")}: ${r}. These are not known services or stacks, and are not the shared platform database names (postgres, database-management).${a}${s}`,fix:'Use "postgres" or "database-management" in dependsOn for the shared platform database, or fix the name to match an existing service'}}if(!e.willStart)return{name:"Shared platform Postgres",didPass:!0,isWarning:!!s,isSkipped:!s,message:s?s.trim():"Shared platform Postgres will not start: database-management is off and no resource depends on postgres or database-management."};if(e.reason==="feature"&&e.dependsOnUsers.length===0){let r=e.featureOnFromTiltfile||e.featureOnFromSpecMaster?" (generated Tiltfile/spec.master)":"";return{name:"Shared platform Postgres",didPass:!0,isWarning:!!s,message:`Shared platform Postgres will start because the database-management feature is enabled${r} (project-wide; not a flisk up selection).${s}`}}let o=e.reason==="feature"?`the database-management feature is enabled and resource(s) ${e.dependsOnUsers.join(", ")} depend on postgres/database-management`:`resource(s) ${e.dependsOnUsers.join(", ")} depend on postgres/database-management`;return{name:"Shared platform Postgres",didPass:!0,isWarning:!!s,message:`Shared platform Postgres will start because ${o}${n}${s}`}}function Ee(t){let e=[];for(let n of t.split(`
366
- `)){let s=n.match(/^\s*(\d+)\s+.*\btilt up\b.*?\s-f\s+(\S+)/i);s&&e.push({pid:Number(s[1]),root:s[2].split(/[\\/]\.tdk[\\/]/i)[0]})}return e}function kt(t=l()??process.cwd(),e=ue){let n;try{n=process.platform==="win32"?de("powershell.exe",["-NoProfile","-Command","Get-CimInstance Win32_Process | Where-Object { $_.Name -eq 'tilt.exe' } | ForEach-Object { '{0} {1}' -f $_.ProcessId, $_.CommandLine }"],{encoding:"utf-8",timeout:x,windowsHide:!0}):e("ps -Ao pid=,command=",{encoding:"utf-8",timeout:x})}catch{return{name:"Tilt processes",didPass:!0,isSkipped:!0,message:"Could not list processes"}}let s=Ee(n),o=s.filter(a=>a.root===t),r=s.filter(a=>a.root!==t);return o.length>1?{name:"Tilt processes",didPass:!1,message:`${o.length} Tilt processes are running for this project (pids ${o.map(a=>a.pid).join(", ")}). They fight over ports and containers`,fix:`Stop them all, then start one: flisk down && kill ${o.map(a=>a.pid).join(" ")} && flisk up`}:r.length>0?{name:"Tilt processes",didPass:!0,isSkipped:!0,message:`Another project's Tilt is running: ${r.map(i=>`${i.root} (pid ${i.pid})`).join(", ")}`,fix:"flisk up will use the next free Tilt UI port (10351, ...). If it is a leftover, run flisk down in that project"}:{name:"Tilt processes",didPass:!0,message:"No stray Tilt processes"}}async function yt(t=z){let e=`tdk_doctor_probe_${process.pid}`;try{await t(`docker network create ${e}`,x)}catch(n){let s=String(n.stderr??n);return/address pools/i.test(s)?{name:"Docker networks",didPass:!1,message:"Docker cannot create another network: all predefined address pools are in use. Each Flisk project needs several",fix:"run flisk down --prune-networks in projects you are not using, or docker network prune (removes all unused networks)"}:{name:"Docker networks",didPass:!0,isSkipped:!0,message:"Could not test network creation"}}try{await t(`docker network rm ${e}`,x)}catch{}return{name:"Docker networks",didPass:!0,message:"Docker can create networks"}}export{Oe as a,Ne as b,h as c,ae as d,qe as e,z as f,Ke as g,it as h,ct as i,pt as j,dt as k,ut as l,lt as m,mt as n,ft as o,ht as p,gt as q,Ee as r,kt as s,yt as t};
365
+ `)}`,fix:"Move the migration into a `migrator` resource (appType migrator) that the service depends on, so it runs once before the service starts instead of on every start and restart"}}function ht(t=u()??process.cwd()){let e=f(t).filter(s=>s.config?.featuresEnabled?.includes("nats")).map(s=>s.name);if(e.length===0)return{name:"NATS broker",didPass:!0,message:"No resource enables the nats feature",isSkipped:!0};if(R(l(t,"services","platform","messaging",U)))return{name:"NATS broker",didPass:!0,message:`${m(e.length,"resource")} enable nats and services/platform/messaging/docker-compose.yml is present`};let n=(Y(t)??"project").replace(/-/g,"_");return{name:"NATS broker",didPass:!1,message:`${e.join(", ")} enable the nats feature, but no NATS server will start: Flisk only starts one when services/platform/messaging/docker-compose.yml exists, and it does not generate that file`,fix:`Create it with a "nats" service (image nats with -js, container_name ${n}_nats, network ${n}_backend, external) and a "redis" service, which Flisk registers alongside it`}}function gt(t=u()??process.cwd()){let e=N(t),n=" (project resource set; flisk up may select a subset and not start Postgres)",s=e.focusWouldEnableDatabaseManagement?" Warning: generated Tiltfile default focus expands CORE_INFRA to database-management while project.json has it off; default flisk up takes the feature path.":"";if(e.unknownDependsOnNames.length>0){let r=e.unknownDependsOnNames.map(({resource:i,name:c})=>`"${c}" (from ${i})`).join(", "),a=e.willStart?` Postgres will start because ${e.reason==="feature"?"database-management is enabled":`resource(s) ${e.dependsOnUsers.join(", ")} depend on postgres/database-management`}${n}`:" Postgres will not start for this project.json/generated Tiltfile state.";return{name:"Shared platform Postgres",didPass:!1,message:`${m(e.unknownDependsOnNames.length,"unknown dependsOn name")}: ${r}. These are not known services or stacks, and are not the shared platform database names (postgres, database-management).${a}${s}`,fix:'Use "postgres" or "database-management" in dependsOn for the shared platform database, or fix the name to match an existing service'}}if(!e.willStart)return{name:"Shared platform Postgres",didPass:!0,isWarning:!!s,isSkipped:!s,message:s?s.trim():"Shared platform Postgres will not start: database-management is off and no resource depends on postgres or database-management."};if(e.reason==="feature"&&e.dependsOnUsers.length===0){let r=e.featureOnFromTiltfile||e.featureOnFromSpecMaster?" (generated Tiltfile/spec.master)":"";return{name:"Shared platform Postgres",didPass:!0,isWarning:!!s,message:`Shared platform Postgres will start because the database-management feature is enabled${r} (project-wide; not a flisk up selection).${s}`}}let o=e.reason==="feature"?`the database-management feature is enabled and resource(s) ${e.dependsOnUsers.join(", ")} depend on postgres/database-management`:`resource(s) ${e.dependsOnUsers.join(", ")} depend on postgres/database-management`;return{name:"Shared platform Postgres",didPass:!0,isWarning:!!s,message:`Shared platform Postgres will start because ${o}${n}${s}`}}function Ee(t){let e=[];for(let n of t.split(`
366
+ `)){let s=n.match(/^\s*(\d+)\s+.*\btilt up\b.*?\s-f\s+(\S+)/i);s&&e.push({pid:Number(s[1]),root:s[2].split(/[\\/]\.flisk[\\/]/i)[0]})}return e}function kt(t=u()??process.cwd(),e=le){let n;try{n=process.platform==="win32"?de("powershell.exe",["-NoProfile","-Command","Get-CimInstance Win32_Process | Where-Object { $_.Name -eq 'tilt.exe' } | ForEach-Object { '{0} {1}' -f $_.ProcessId, $_.CommandLine }"],{encoding:"utf-8",timeout:x,windowsHide:!0}):e("ps -Ao pid=,command=",{encoding:"utf-8",timeout:x})}catch{return{name:"Tilt processes",didPass:!0,isSkipped:!0,message:"Could not list processes"}}let s=Ee(n),o=s.filter(a=>a.root===t),r=s.filter(a=>a.root!==t);return o.length>1?{name:"Tilt processes",didPass:!1,message:`${o.length} Tilt processes are running for this project (pids ${o.map(a=>a.pid).join(", ")}). They fight over ports and containers`,fix:`Stop them all, then start one: flisk down && kill ${o.map(a=>a.pid).join(" ")} && flisk up`}:r.length>0?{name:"Tilt processes",didPass:!0,isSkipped:!0,message:`Another project's Tilt is running: ${r.map(i=>`${i.root} (pid ${i.pid})`).join(", ")}`,fix:"flisk up will use the next free Tilt UI port (10351, ...). If it is a leftover, run flisk down in that project"}:{name:"Tilt processes",didPass:!0,message:"No stray Tilt processes"}}async function yt(t=z){let e=`flisk_doctor_probe_${process.pid}`;try{await t(`docker network create ${e}`,x)}catch(n){let s=String(n.stderr??n);return/address pools/i.test(s)?{name:"Docker networks",didPass:!1,message:"Docker cannot create another network: all predefined address pools are in use. Each Flisk project needs several",fix:"run flisk down --prune-networks in projects you are not using, or docker network prune (removes all unused networks)"}:{name:"Docker networks",didPass:!0,isSkipped:!0,message:"Could not test network creation"}}try{await t(`docker network rm ${e}`,x)}catch{}return{name:"Docker networks",didPass:!0,message:"Docker can create networks"}}export{Oe as a,Ne as b,h as c,ae as d,qe as e,z as f,Ke as g,it as h,ct as i,pt as j,dt as k,lt as l,ut as m,mt as n,ft as o,ht as p,gt as q,Ee as r,kt as s,yt as t};
@@ -1,5 +1,5 @@
1
- import{createRequire as __tdkRequire}from'node:module';const require=__tdkRequire(import.meta.url);
2
- import{M as q,b as f,e as G,h as xe,i as Ee,m as ke,n as we,r as z,u as ve,v as be,x as T}from"./chunk-AT5MFZ3D.js";import st,{existsSync as O,readdirSync as nn,readFileSync as rn,statSync as ce}from"node:fs";import{dirname as on,join as w}from"node:path";var j=class{data;options;constructor(t){this.data=new Map,this.options=t}has(t){let n=this.data.get(t);return n?Date.now()-n.timestamp>this.options.ttlMs?(this.data.delete(t),!1):!0:!1}get(t){if(this.has(t))return this.data.get(t)?.value}set(t,n){this.data.set(t,{value:n,timestamp:Date.now()})}delete(t){this.data.delete(t)}clear(){this.data.clear()}keys(){let t=[];for(let n of this.data.keys())this.has(n)&&t.push(n);return t}size(){return this.keys().length}};function Te(e){let t=0;return{isValid(){return Date.now()-t<e},markUpdated(){t=Date.now()},reset(){t=0}}}function ct(e,t,n){return e===1?t:n||`${t}s`}function Re(e,t,n){return`${e} ${ct(e,t,n)}`}var ut={month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"};function Sn(e){return new Date(e).toLocaleString("en-US",ut)}function yn(e){return new Date(e).toLocaleDateString("en-US",{month:"short",day:"numeric"})}var K={success:{color:"green",icon:"\u2713",chalkFn:f.green},error:{color:"red",icon:"\u2717",chalkFn:f.red},warning:{color:"yellow",icon:"\u25CB",chalkFn:f.yellow},unknown:{color:"gray",icon:"?",chalkFn:f.gray}};function H(e){if(!e)return"unknown";let t=e.toLowerCase();return t==="ready"||t==="healthy"||t==="active"||t==="running"?"success":t==="error"||t==="failed"||t==="critical"||t==="stopped"?"error":t==="pending"||t==="starting"||t==="building"||t==="degraded"?"warning":"unknown"}function $n(e){return K[H(e)].color}function xn(e){return K[H(e)].icon}function En(e,t){return K[H(t)].chalkFn(e)}var ft={resources:{singular:"resource",command:"flisk resource <name>",context:`
1
+ import{createRequire as __fliskRequire}from'node:module';const require=__fliskRequire(import.meta.url);
2
+ import{N as q,b as f,e as G,h as xe,i as Ee,m as ke,n as we,r as z,u as ve,v as be,x as T}from"./chunk-VHFFSBVJ.js";import st,{existsSync as O,readdirSync as nn,readFileSync as rn,statSync as ce}from"node:fs";import{dirname as on,join as w}from"node:path";var j=class{data;options;constructor(t){this.data=new Map,this.options=t}has(t){let n=this.data.get(t);return n?Date.now()-n.timestamp>this.options.ttlMs?(this.data.delete(t),!1):!0:!1}get(t){if(this.has(t))return this.data.get(t)?.value}set(t,n){this.data.set(t,{value:n,timestamp:Date.now()})}delete(t){this.data.delete(t)}clear(){this.data.clear()}keys(){let t=[];for(let n of this.data.keys())this.has(n)&&t.push(n);return t}size(){return this.keys().length}};function Te(e){let t=0;return{isValid(){return Date.now()-t<e},markUpdated(){t=Date.now()},reset(){t=0}}}function ct(e,t,n){return e===1?t:n||`${t}s`}function Re(e,t,n){return`${e} ${ct(e,t,n)}`}var ut={month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"};function Sn(e){return new Date(e).toLocaleString("en-US",ut)}function yn(e){return new Date(e).toLocaleDateString("en-US",{month:"short",day:"numeric"})}var K={success:{color:"green",icon:"\u2713",chalkFn:f.green},error:{color:"red",icon:"\u2717",chalkFn:f.red},warning:{color:"yellow",icon:"\u25CB",chalkFn:f.yellow},unknown:{color:"gray",icon:"?",chalkFn:f.gray}};function H(e){if(!e)return"unknown";let t=e.toLowerCase();return t==="ready"||t==="healthy"||t==="active"||t==="running"?"success":t==="error"||t==="failed"||t==="critical"||t==="stopped"?"error":t==="pending"||t==="starting"||t==="building"||t==="degraded"?"warning":"unknown"}function $n(e){return K[H(e)].color}function xn(e){return K[H(e)].icon}function En(e,t){return K[H(t)].chalkFn(e)}var ft={resources:{singular:"resource",command:"flisk resource <name>",context:`
3
3
  To create a resource:`},stacks:{singular:"stack",command:"flisk stack <stack-name>",context:`
4
4
  To create a stack, use:`},services:{singular:"service",command:"flisk resource <name>",context:`
5
5
  To create a service:`},"stack-services":{singular:"service",command:"flisk resource <name> --stack <stack-name>",context:`
@@ -10,7 +10,7 @@ Or create a new resource with a stack:`)),console.log(f.gray(" flisk resource <
10
10
  `)}function bt(e){let t=e.match(/^[a-z][a-z0-9+.-]*:\/\/[^:/@\s]+:([^@\s]*)@/i);if(!(!t||t[1].includes("$")))return t[1]}function zn(e){let t=Q(e,".env"),n={missing:[],invalid:[],warnings:[]};if(!Z(t))return{missing:b.filter(a=>a.required).map(a=>a.name),invalid:[],warnings:[".env file not found - will be auto-generated"]};let r=R(Ce(t,"utf-8"));for(let a of b)a.required&&!r.has(a.name)&&n.missing.push(a.name),r.has(a.name)&&!(r.get(a.name)??"").trim()&&n.invalid.push(`${a.name} is set but empty`);let o=r.get("DATABASE_URL"),s=r.get("DB_PASSWORD");if(o&&s){let a=bt(o);a!==void 0&&a!==s&&n.warnings.push("DATABASE_URL carries a different password than DB_PASSWORD; the database container uses DB_PASSWORD")}return n}function Tt(e,t,n){if(!R(e).has(t))return e;let o=e.indexOf("=");if(o<0)return e;let s=e.slice(o+1),a=s.search(/\s#/),i=a<0?"":s.slice(a);return e.slice(0,o+1)+n+i}function qn(e){let t=Q(e,".env");if(!Z(t))return De(t,je(),{mode:384}),b.map(u=>u.name);let n=Ce(t,"utf-8"),r=R(n),o=b.filter(u=>u.complete?r.has(u.name)?!(r.get(u.name)??"").trim():!0:!1);if(o.length===0)return[];let s=o.filter(u=>!r.has(u.name)),a=o.filter(u=>r.has(u.name)),i=r.get("DB_PASSWORD"),c=i?.trim()?i:Fe(),d=n.split(/(\r\n|\n|\r)/);for(let u of a){let h=-1;for(let l=0;l<d.length;l+=2)R(d[l]).has(u.name)&&(h=l);if(h<0)throw new Error(`Could not locate empty .env assignment for ${u.name}`);d[h]=Tt(d[h],u.name,Y(u.name,c))}let p=d.join("");if(s.length>0){let u=["","# Added by Flisk: keys this version expects. Existing values above were not changed.",""];for(let l of s)u.push(...Ne(l)),u.push(`${l.name}=${Y(l.name,c)}`),u.push("");let h=p.endsWith(`
11
11
  `)||p.endsWith("\r")?"":`
12
12
  `;p+=h+u.join(`
13
- `)}return _e(t,p),o.map(u=>u.name)}function Kn(e){let t=Q(e,".env");return Z(t)?!1:(De(t,je(),{mode:384}),!0)}var Ot="[REDACTED]",X=class extends Error{path;constructor(t,n){super(`Could not read ${t}: ${n}`),this.path=t,this.name="EnvUnreadableError"}},Ct=8;function Dt(e,t=[]){let n=[...Pe(_t(e,".env")),...t.flatMap(r=>Pe(r))];return[...new Set(n)].sort((r,o)=>o.length-r.length)}function Pe(e){if(!At(e))return[];let t;try{t=Rt(e,"utf-8")}catch(n){throw new X(e,n instanceof Error?n.message:String(n))}return[...R(t).values()].filter(n=>n.length>=Ct)}function Me(e,t){let n=e;for(let r of t)n=n.split(r).join(Ot);return n}function Ie(e,t){return t.length===0?e:typeof e=="string"?Me(e,t):Array.isArray(e)?e.map(n=>Ie(n,t)):e!==null&&typeof e=="object"?Object.fromEntries(Object.entries(e).map(([n,r])=>[n,Ie(r,t)])):e}function Be(e,t=[]){let n;try{n=Dt(e,t)}catch(r){return()=>{throw r}}return r=>Me(r,n)}import{readFileSync as Ft}from"node:fs";import{join as Nt}from"node:path";function or(){return Ue(T())}function Ue(e){if(e)try{let t=Ft(Nt(e,".tdk",ke),"utf-8"),n=JSON.parse(t);if(n?.project?.name)return n.project.name}catch{}return"tdk-project"}function ee(e,t){let n=Ue(t??T()),r=process.env.TDK_SERVICE_BASE_URL??`http://${n}.localhost${e?`:${e}`:""}`;try{let o=new URL(r.includes("://")?r:`http://${r}`),s=o.hostname,a=o.protocol==="https:"?"443":"80",i=o.port||(e?String(e):""),c=i===a?"":i;if(s==="localhost"||/^\d+\.\d+\.\d+\.\d+$/.test(s))return{appBase:`${o.protocol}//${s}${c?`:${c}`:""}`,apiBase:`${o.protocol}//${s}${c?`:${c}`:""}`};let d=s.replace(/^(app|api)\./,"");return{appBase:`${o.protocol}//app.${d}${c?`:${c}`:""}`,apiBase:`${o.protocol}//api.${d}${c?`:${c}`:""}`}}catch{return{appBase:`http://app.${n}.localhost`,apiBase:`http://api.${n}.localhost`}}}function jt(e){return`${e.replace(/\/+$/,"")}/health`}function te(e){if(A(e.config?.appType)){let t=e.name.replace(/-api$/,"");return e.config?.apiPath??`/api/${t}`}return e.config?.basePath??`/${e.name}`}function sr(e,t){return Le(e,t,n=>jt(n))}function ar(e,t){return Le(e,t,n=>n)}function Le(e,t,n){let{appBase:r,apiBase:o}=ee(t);return e.filter(s=>s.config?.appType==="frontend"||A(s.config?.appType)).map(s=>{let a=A(s.config.appType)?o:r;return{name:s.name,appType:s.config.appType,url:`${a}${n(te(s))}`}})}async function Pt(e,t){try{let n=await fetch(e.url,{method:"GET",redirect:"manual",signal:AbortSignal.timeout(t)});return{...e,ok:n.ok,status:n.status}}catch(n){let r=n instanceof Error&&n.name==="TimeoutError"?`no response within ${t}ms`:n instanceof Error?n.message:String(n);return{...e,ok:!1,error:r}}}async function ir(e,t){return Promise.all(e.map(n=>Pt(n,t)))}var Ye=60,ze=1e3,qe=1e4,Ke=200,He=64*1024,Je=new Set([404,502,503,504]),Mt=new Set(["ECONNREFUSED","ENOTFOUND","EAI_AGAIN","EHOSTUNREACH","ENETUNREACH"]),Bt=new Set(["GET","HEAD","OPTIONS"]);function E(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Ut(e,t){if(Bt.has(t))return!0;if(!E(e))return!1;let n=E(e.cause)?e.cause:void 0,r=e.code??n?.code;return typeof r=="string"&&Mt.has(r)}function re(e){if(!E(e))return['smoke: must be an object with "via" and "steps"'];let t=[];return e.via!=="proxy"&&t.push('smoke.via: only "proxy" is supported (the check must go through the public URL)'),e.timeoutSeconds!==void 0&&!(typeof e.timeoutSeconds=="number"&&e.timeoutSeconds>0)&&t.push("smoke.timeoutSeconds: must be a number greater than 0"),!Array.isArray(e.steps)||e.steps.length===0?(t.push("smoke.steps: needs at least one step"),t):(e.steps.forEach((n,r)=>{let o=`smoke.steps[${r}]`;if(!E(n)){t.push(`${o}: must be an object`);return}let s=n.path;(typeof s!="string"||!s.startsWith("/")||s.startsWith("//"))&&t.push(`${o}.path: must start with "/" and is appended to the public URL; a full URL or relative path would skip the proxy`),n.expect!==void 0&&!(typeof n.expect=="number"&&Number.isInteger(n.expect)&&n.expect>=100&&n.expect<=599)&&t.push(`${o}.expect: must be an HTTP status between 100 and 599`),n.bodyContains!==void 0&&typeof n.bodyContains!="string"&&t.push(`${o}.bodyContains: must be a string`),n.save!==void 0&&(E(n.save)&&Object.values(n.save).every(i=>typeof i=="string"&&i.startsWith("$."))||t.push(`${o}.save: must map names to paths such as "$.id"`))}),t)}function hr(e,t){let{appBase:n,apiBase:r}=ee(t),o=[];for(let s of e){let a=s.config;if(!a?.smoke)continue;let i=a.appType,c=A(i)||i===G;if(!c&&i!=="frontend"||a.exposeViaProxy===!1)continue;let d=c?r:n,p=a.healthCheckPath||(c&&i!==G?"/health":void 0);o.push({name:s.name,baseUrl:`${d}${te(s).replace(/\/+$/,"")}`,...p?.startsWith("/")?{readyPath:p}:{},smoke:a.smoke})}return o}var Lt=10;function gr(e,t={}){let n=t.timeoutSeconds??Lt;return e.flatMap(r=>{let o=r.smoke.steps.filter(a=>(a.method??"GET").toUpperCase()==="GET"&&a.body===void 0&&!a.path.includes("{{")).map(a=>({...a,bodyContains:void 0}));if(o.length===0)return[];let s=Math.min(r.smoke.timeoutSeconds??Ye,n);return[{name:r.name,baseUrl:r.baseUrl,smoke:{via:r.smoke.via,timeoutSeconds:s,steps:o}}]})}function Vt(e,t){let n=t.replace(/^\$\.?/,"").match(/[^.[\]]+/g)??[],r=e;for(let o of n){if(r==null||o==="__proto__"||o==="constructor"||o==="prototype"||!Object.hasOwn(r,o))return;let s=Object.getOwnPropertyDescriptor(r,o);if(!s||!("value"in s))return;r=s.value}return r}function Ze(e,t){return e.replace(/\{\{(\w+)\}\}/g,(n,r)=>t[r]??n)}function ne(e,t){return typeof e=="string"?Ze(e,t):Array.isArray(e)?e.map(n=>ne(n,t)):E(e)?Object.fromEntries(Object.entries(e).map(([n,r])=>[n,ne(r,t)])):e}function M(e){let t=e.replace(/\s+/g," ").trim();return t.length>Ke?`${t.slice(0,Ke)}...`:t}function Qe(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"step"}function Wt(e,t){let n=Qe(t),r=(e.get(n)??0)+1;return e.set(n,r),r===1?n:`${n}-${r}`}function Gt(e,t,n,r,o){try{let s=_(e,Qe(n.service),t);It(s,{recursive:!0});let a=_(s,"latest.json"),i=_(s,"body.txt");return r===void 0?We(i,{force:!0}):Ge(i,r),Ge(a,`${JSON.stringify({...n,bodyPath:r===void 0?null:"body.txt"},null,2)}
13
+ `)}return _e(t,p),o.map(u=>u.name)}function Kn(e){let t=Q(e,".env");return Z(t)?!1:(De(t,je(),{mode:384}),!0)}var Ot="[REDACTED]",X=class extends Error{path;constructor(t,n){super(`Could not read ${t}: ${n}`),this.path=t,this.name="EnvUnreadableError"}},Ct=8;function Dt(e,t=[]){let n=[...Pe(_t(e,".env")),...t.flatMap(r=>Pe(r))];return[...new Set(n)].sort((r,o)=>o.length-r.length)}function Pe(e){if(!At(e))return[];let t;try{t=Rt(e,"utf-8")}catch(n){throw new X(e,n instanceof Error?n.message:String(n))}return[...R(t).values()].filter(n=>n.length>=Ct)}function Me(e,t){let n=e;for(let r of t)n=n.split(r).join(Ot);return n}function Ie(e,t){return t.length===0?e:typeof e=="string"?Me(e,t):Array.isArray(e)?e.map(n=>Ie(n,t)):e!==null&&typeof e=="object"?Object.fromEntries(Object.entries(e).map(([n,r])=>[n,Ie(r,t)])):e}function Be(e,t=[]){let n;try{n=Dt(e,t)}catch(r){return()=>{throw r}}return r=>Me(r,n)}import{readFileSync as Ft}from"node:fs";import{join as Nt}from"node:path";function or(){return Ue(T())}function Ue(e){if(e)try{let t=Ft(Nt(e,".flisk",ke),"utf-8"),n=JSON.parse(t);if(n?.project?.name)return n.project.name}catch{}return"flisk-project"}function ee(e,t){let n=Ue(t??T()),r=process.env.FLISK_SERVICE_BASE_URL??`http://${n}.localhost${e?`:${e}`:""}`;try{let o=new URL(r.includes("://")?r:`http://${r}`),s=o.hostname,a=o.protocol==="https:"?"443":"80",i=o.port||(e?String(e):""),c=i===a?"":i;if(s==="localhost"||/^\d+\.\d+\.\d+\.\d+$/.test(s))return{appBase:`${o.protocol}//${s}${c?`:${c}`:""}`,apiBase:`${o.protocol}//${s}${c?`:${c}`:""}`};let d=s.replace(/^(app|api)\./,"");return{appBase:`${o.protocol}//app.${d}${c?`:${c}`:""}`,apiBase:`${o.protocol}//api.${d}${c?`:${c}`:""}`}}catch{return{appBase:`http://app.${n}.localhost`,apiBase:`http://api.${n}.localhost`}}}function jt(e){return`${e.replace(/\/+$/,"")}/health`}function te(e){if(A(e.config?.appType)){let t=e.name.replace(/-api$/,"");return e.config?.apiPath??`/api/${t}`}return e.config?.basePath??`/${e.name}`}function sr(e,t){return Le(e,t,n=>jt(n))}function ar(e,t){return Le(e,t,n=>n)}function Le(e,t,n){let{appBase:r,apiBase:o}=ee(t);return e.filter(s=>s.config?.appType==="frontend"||A(s.config?.appType)).map(s=>{let a=A(s.config.appType)?o:r;return{name:s.name,appType:s.config.appType,url:`${a}${n(te(s))}`}})}async function Pt(e,t){try{let n=await fetch(e.url,{method:"GET",redirect:"manual",signal:AbortSignal.timeout(t)});return{...e,ok:n.ok,status:n.status}}catch(n){let r=n instanceof Error&&n.name==="TimeoutError"?`no response within ${t}ms`:n instanceof Error?n.message:String(n);return{...e,ok:!1,error:r}}}async function ir(e,t){return Promise.all(e.map(n=>Pt(n,t)))}var Ye=60,ze=1e3,qe=1e4,Ke=200,He=64*1024,Je=new Set([404,502,503,504]),Mt=new Set(["ECONNREFUSED","ENOTFOUND","EAI_AGAIN","EHOSTUNREACH","ENETUNREACH"]),Bt=new Set(["GET","HEAD","OPTIONS"]);function E(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Ut(e,t){if(Bt.has(t))return!0;if(!E(e))return!1;let n=E(e.cause)?e.cause:void 0,r=e.code??n?.code;return typeof r=="string"&&Mt.has(r)}function re(e){if(!E(e))return['smoke: must be an object with "via" and "steps"'];let t=[];return e.via!=="proxy"&&t.push('smoke.via: only "proxy" is supported (the check must go through the public URL)'),e.timeoutSeconds!==void 0&&!(typeof e.timeoutSeconds=="number"&&e.timeoutSeconds>0)&&t.push("smoke.timeoutSeconds: must be a number greater than 0"),!Array.isArray(e.steps)||e.steps.length===0?(t.push("smoke.steps: needs at least one step"),t):(e.steps.forEach((n,r)=>{let o=`smoke.steps[${r}]`;if(!E(n)){t.push(`${o}: must be an object`);return}let s=n.path;(typeof s!="string"||!s.startsWith("/")||s.startsWith("//"))&&t.push(`${o}.path: must start with "/" and is appended to the public URL; a full URL or relative path would skip the proxy`),n.expect!==void 0&&!(typeof n.expect=="number"&&Number.isInteger(n.expect)&&n.expect>=100&&n.expect<=599)&&t.push(`${o}.expect: must be an HTTP status between 100 and 599`),n.bodyContains!==void 0&&typeof n.bodyContains!="string"&&t.push(`${o}.bodyContains: must be a string`),n.save!==void 0&&(E(n.save)&&Object.values(n.save).every(i=>typeof i=="string"&&i.startsWith("$."))||t.push(`${o}.save: must map names to paths such as "$.id"`))}),t)}function hr(e,t){let{appBase:n,apiBase:r}=ee(t),o=[];for(let s of e){let a=s.config;if(!a?.smoke)continue;let i=a.appType,c=A(i)||i===G;if(!c&&i!=="frontend"||a.exposeViaProxy===!1)continue;let d=c?r:n,p=a.healthCheckPath||(c&&i!==G?"/health":void 0);o.push({name:s.name,baseUrl:`${d}${te(s).replace(/\/+$/,"")}`,...p?.startsWith("/")?{readyPath:p}:{},smoke:a.smoke})}return o}var Lt=10;function gr(e,t={}){let n=t.timeoutSeconds??Lt;return e.flatMap(r=>{let o=r.smoke.steps.filter(a=>(a.method??"GET").toUpperCase()==="GET"&&a.body===void 0&&!a.path.includes("{{")).map(a=>({...a,bodyContains:void 0}));if(o.length===0)return[];let s=Math.min(r.smoke.timeoutSeconds??Ye,n);return[{name:r.name,baseUrl:r.baseUrl,smoke:{via:r.smoke.via,timeoutSeconds:s,steps:o}}]})}function Vt(e,t){let n=t.replace(/^\$\.?/,"").match(/[^.[\]]+/g)??[],r=e;for(let o of n){if(r==null||o==="__proto__"||o==="constructor"||o==="prototype"||!Object.hasOwn(r,o))return;let s=Object.getOwnPropertyDescriptor(r,o);if(!s||!("value"in s))return;r=s.value}return r}function Ze(e,t){return e.replace(/\{\{(\w+)\}\}/g,(n,r)=>t[r]??n)}function ne(e,t){return typeof e=="string"?Ze(e,t):Array.isArray(e)?e.map(n=>ne(n,t)):E(e)?Object.fromEntries(Object.entries(e).map(([n,r])=>[n,ne(r,t)])):e}function M(e){let t=e.replace(/\s+/g," ").trim();return t.length>Ke?`${t.slice(0,Ke)}...`:t}function Qe(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"step"}function Wt(e,t){let n=Qe(t),r=(e.get(n)??0)+1;return e.set(n,r),r===1?n:`${n}-${r}`}function Gt(e,t,n,r,o){try{let s=_(e,Qe(n.service),t);It(s,{recursive:!0});let a=_(s,"latest.json"),i=_(s,"body.txt");return r===void 0?We(i,{force:!0}):Ge(i,r),Ge(a,`${JSON.stringify({...n,bodyPath:r===void 0?null:"body.txt"},null,2)}
14
14
  `),o&&(Ve(a,_(s,"last-success.json")),r===void 0?We(_(s,"last-success-body.txt"),{force:!0}):Ve(i,_(s,"last-success-body.txt"))),a}catch{return}}function zt(e){let t=Buffer.from(e,"utf8");if(t.length<=He)return{body:e,truncated:!1,bytes:t.length};let n=t.subarray(0,He).toString("utf8").replace(/\uFFFD$/,"");return{body:n,truncated:!0,bytes:Buffer.byteLength(n,"utf8")}}async function qt(e,t={}){let n=t.fetch??((p,u)=>fetch(p,u)),r=t.now??Date.now,o=t.sleep??(p=>new Promise(u=>setTimeout(u,p))),s=(e.smoke.timeoutSeconds??Ye)*1e3,a=r()+s,i={},c=re(e.smoke);if(c.length>0)return{name:e.name,ok:!1,failure:`${e.name}: invalid smoke block: ${c.join("; ")}`};if(e.readyPath){let p=`${e.baseUrl}${e.readyPath}`;for(;;){try{let u=await n(p,{method:"GET",signal:AbortSignal.timeout(qe)});if(await u.text(),!Je.has(u.status)&&u.status<500)break}catch{}if(r()>=a)break;await o(ze)}}a=r()+s;let d=new Map;for(let[p,u]of e.smoke.steps.entries()){let h=u.name??`step ${p+1}`,l=(u.method??"GET").toUpperCase(),me=`${e.baseUrl}${Ze(u.path,i)}`,C=u.expect??200,he=u.body!==void 0,S,D="",x,L;for(;;){x=void 0,L=void 0,S=void 0;let g=!1;try{let m=await n(me,{method:l,headers:he?{"content-type":"application/json"}:void 0,body:he?JSON.stringify(ne(u.body,i)):void 0,signal:AbortSignal.timeout(qe)});S=m.status,D=await m.text()}catch(m){g=Ut(m,l),x=m instanceof Error?m.message:String(m);let v=E(m)?m.code??(E(m.cause)?m.cause.code:void 0):void 0;L=typeof v=="string"?v:void 0}if(!(x!==void 0&&g||S!==void 0&&S!==C&&Je.has(S))||r()>=a)break;await o(ze)}let ge=!1,V=g=>{if(!ge){if(!t.redact)return g;try{return t.redact(g)}catch($){ge=!0;let m=$ instanceof Error?$.message:String($);t.warn?.(`${e.name}: ${h}: the response text was neither shown nor stored: ${m}`);return}}},W=V(me),y=S===void 0?void 0:V(D),Se=x===void 0?void 0:V(x),ye=x===void 0?void 0:L??Se,F=`${e.name}: ${h}: ${l} ${W??"(url withheld)"}`,$e;if(t.recordDir){let g=y===void 0?void 0:zt(y),$=x===void 0&&S===C&&(u.bodyContains===void 0||D.includes(u.bodyContains));$e=Gt(t.recordDir,Wt(d,h),{service:e.name,step:h,method:l,...W===void 0?{}:{url:W},expectedStatus:C,status:S??null,...ye===void 0?{}:{error:ye},truncated:g?.truncated??!1,bodyBytes:g?.bytes??0},g?.body,$)}let N=g=>({name:e.name,ok:!1,failure:g,recordPath:$e});if(x!==void 0)return N(`${F} never answered (${Se??"the error was withheld"})`);if(S!==C)return N(`${F} returned ${S}, expected ${C}${y?`: ${M(y)}`:""}`);if(u.bodyContains!==void 0&&!D.includes(u.bodyContains))return N(`${F} returned ${S} but the body does not contain "${u.bodyContains}"${y?`: ${M(y)}`:""}`);if(u.save){let g;try{g=JSON.parse(D)}catch{return N(`${F} returned a body that is not JSON, cannot save${y?`: ${M(y)}`:""}`)}for(let[$,m]of Object.entries(u.save)){let v=Vt(g,m);if(v==null||typeof v=="object")return N(`${F} response has no ${m} to save as {{${$}}}${y?`: ${M(y)}`:""}`);i[$]=String(v)}}}return{name:e.name,ok:!0}}function Sr(e){return`Smoke check failed: ${e.failure}${e.recordPath?` (record: ${e.recordPath})`:""}`}function yr(e,t,n={}){return{redact:Be(e,n.envFiles??[]),...t?{warn:t}:{}}}async function $r(e,t={}){return Promise.all(e.map(n=>qt(n,t)))}var Xe=1,wr="https://flisk.sh/schema.service.json",Kt={dependencies:"deprecated, use dependsOn (still read for now)",envVars:"deprecated, use params (still read when params is absent)",jwtSecret:"ignored. A secret must not be committed: remove it and set JWT_SECRET in the project .env"},Ht=new Set(["$schema","agent","apiBasePath","apiPath","appName","appType","backendName","basePath","build","buildContext","databaseName","dependencies","dev","dependsOn","dockerfile","enabled","exposeViaProxy","featuresEnabled","framework","healthCheckPath","image","language","name","nats","params","playwright","port","replicas","restart","runtime","sablier","schemaVersion","secrets","smoke","stack","syncs","traefik","type"]),Jt=[{path:["healthCheckPath"],pattern:/^\/[a-z0-9/-]*$/,expected:"a path such as /health"},{path:["traefik","host"],pattern:/^[A-Za-z0-9.-]+$/,expected:"a hostname such as shop.backend.myproject.local"},{path:["traefik","pathPrefix"],pattern:/^\/[a-z0-9/-]*$/,expected:"a path such as /api/v1/shop-management"},{path:["traefik","healthCheck"],pattern:/^\/[a-z0-9/-]*$/,expected:"a path such as /health"},{path:["nats","queueGroup"],pattern:/^[A-Za-z0-9_.-]+$/,expected:"letters, digits, '_', '.' or '-'"},{path:["databaseName"],pattern:/^[A-Za-z0-9_-]+$/,expected:"letters, digits, '_' or '-'"},{path:["stack"],pattern:/^[A-Za-z0-9_-]+$/,expected:"letters, digits, '_' or '-'"},{path:["image"],pattern:/^[A-Za-z0-9._/:@-]+$/,expected:"an image reference such as ghcr.io/acme/app:1.0"}];function B(e,t){let n=[],r=new Set;for(let{path:o,pattern:s,expected:a}of Jt){let i=e;for(let d of o)i=i&&typeof i=="object"&&!Array.isArray(i)?i[d]:void 0;if(i==null||i==="")continue;let c=`${t}.${o.join(".")}`;(typeof i!="string"||!s.test(i))&&r.add(c),typeof i!="string"?n.push(`${c}: expected a string`):s.test(i)||n.push(`${c}: must be ${a} (no spaces, line breaks or YAML syntax)`)}for(let[o,s]of Yt(e,t))r.has(o)||n.push(`${o}: ${s}`);return n}function oe(e){for(let t=0;t<e.length;t++){let n=e.charCodeAt(t);if(n<32||n===127||n===133||n===8232||n===8233)return!0}return!1}function Yt(e,t){let n=[],r=Object.entries(e).filter(([o])=>o!=="smoke").map(([o,s])=>[s,`${t}.${o}`]);for(let o of Object.keys(e))oe(o)&&n.push([t,"a key contains a line break"]);for(;r.length>0;){let[o,s]=r.pop();if(typeof o=="string")oe(o)&&n.push([s,"must not contain line breaks or control characters"]);else if(Array.isArray(o))for(let[a,i]of o.entries())r.push([i,`${s}[${a}]`]);else if(o&&typeof o=="object")for(let[a,i]of Object.entries(o))oe(a)?n.push([s,"a key contains a line break"]):r.push([i,`${s}.${a}`])}return n.sort(([o],[s])=>o.localeCompare(s))}var Zt=["apiPath","basePath"];function se(e){if(!e||typeof e!="object"||Array.isArray(e))return[];let t=e;return Zt.filter(n=>n in t&&typeof t[n]!="string")}function ae(e,t){if(!e||typeof e!="object"||Array.isArray(e))return{errors:[`${t}: expected a JSON object`],warnings:[]};let n=e,r=[];for(let i of["appName","appType","stack","schemaVersion"])i in n||r.push(`${t}.${i}: required field is missing`);for(let i of["appName","appType","stack"])i in n&&typeof n[i]!="string"&&r.push(`${t}.${i}: expected a string`);"schemaVersion"in n&&n.schemaVersion!==Xe&&r.push(`${t}.schemaVersion: unsupported version ${String(n.schemaVersion)} (supported: ${Xe})`);for(let i of se(n))r.push(`${t}.${i}: expected a string`);let o=n.dev,s=o&&typeof o=="object"&&!Array.isArray(o)?o.liveReload:void 0;if(s!==void 0&&typeof s!="boolean"&&r.push(`${t}.dev.liveReload: expected true or false`),r.push(...B(n,t)),"smoke"in n)for(let i of re(n.smoke))r.push(`${t}.${i}`);let a=Object.keys(n).flatMap(i=>{let c=Kt[i];return c?[`${t}.${i}: ${c}`]:Ht.has(i)?[]:[`${t}.${i}: unknown field is preserved`]});return s===!0&&n.language!=="go"&&a.push(`${t}.dev.liveReload: only applies to Go services (language "go"); it is ignored here`),{errors:r,warnings:a,manifest:n}}function vr(e,t){if(!et(e))return[];try{let n=JSON.parse(tt(e,"utf-8"));return!n||typeof n!="object"||Array.isArray(n)?[]:B(n,t)}catch{return[]}}function br(e,t){if(!et(e))return{errors:[`${t}: file is missing`],warnings:[]};try{let n=JSON.parse(tt(e,"utf-8"));return ae(n,t)}catch(n){let r=n instanceof Error?n.message:String(n);return{errors:[`${t}: invalid JSON (${r})`],warnings:[]}}}function nt(e){if(e.length===0||e.every(n=>n==="unknown"))return"unknown";let t=e.filter(n=>n==="ready").length/e.length;return t>.9?"healthy":t>.5?"degraded":"error"}var Qt=/^[a-z0-9-]+$/;function rt(e){return Qt.test(e)}var Xt="Use lowercase letters, numbers, and hyphens only";function ot(e,t){return`${e} "${t}" is not valid. ${Xt}, e.g. "${e==="Resource name"?"my-service":"my-stack"}".`}function en(e){return e.trim()?rt(e)?{valid:!0}:{valid:!1,error:ot("Resource name",e)}:{valid:!1,error:"Resource name is required"}}function tn(e){return e.trim()?rt(e)?{valid:!0}:{valid:!1,error:ot("Stack name",e)}:{valid:!1,error:"Stack name is required"}}function _r(e){let t=e==="resource"?en:tn;return n=>{let r=t(n);return r.valid?!0:r.error??"Invalid name"}}function Or(e){return ie(z,e)?{valid:!0}:{valid:!1,error:`Invalid service. Must be one of: ${z.join(", ")}`}}function Cr(e){return Number.isInteger(e)&&e>0&&e<=65535}function Dr(e){return!e.includes("\0")&&!/[<>:"|?*]/.test(e)}function Fr(e,t="_"){return e.replace(/[^a-zA-Z0-9-]/g,t).substring(0,100)}function ie(e,t){return e.includes(t)}var sn=xe;function de(e,t=5,n=0){let r=[];if(n>t)return r;let o=st.readdirSync(e,{withFileTypes:!0});for(let s of o){let a=w(e,s.name);if(s.isDirectory()){if(an(s.name))continue;r.push(...de(a,t,n+1))}else s.isFile()&&s.name===sn&&r.push(a)}return r}function zr(e){return de(e)}function an(e){return ie(ve,e)||e.startsWith(".")}function cn(e){if(!e||typeof e!="object")return!1;let t=e,n=typeof t.runtime=="string"||typeof t.appType=="string"||typeof t.type=="string";return typeof t.appName=="string"&&n}var P=new Set;function qr(){P.clear()}var k=class extends Error{reason;constructor(t){super(t),this.reason=t,this.name="InvalidServiceJsonError"}};function ue(e){return e instanceof Error?e.message:String(e)}function un(e){let t;try{t=st.readFileSync(e,"utf-8")}catch(c){throw new k(`could not read file: ${ue(c)}`)}let n;try{n=JSON.parse(t)}catch(c){throw new k(`invalid JSON: ${ue(c)}`)}if(!cn(n))throw new k("missing required fields (appName, runtime or appType)");let r=se(n);if(r.length>0)throw new k(r.map(c=>`${c}: expected a string`).join("; "));let o=B(n,e);if(o.length>0)throw new k(o.join("; "));let s=n;for(let c of ae(n,e).warnings)P.has(c)||(P.add(c),console.warn(`\u26A0\uFE0F ${c}`));let a={...s,appType:s.appType||s.type},i=on(e);return{name:a.appName,path:i,configPath:e,config:a,stack:a.stack,port:a.port,type:a.appType}}function at(e){let t=de(e),n=[],r=[];for(let o of t)try{n.push(un(o))}catch(s){r.push({path:o,reason:s instanceof k?s.reason:ue(s)})}return{resources:n,problems:r}}function fn(e){for(let t of e){let n=`skipped ${t.path}: ${t.reason}`;P.has(n)||(P.add(n),console.warn(`\u26A0\uFE0F ${n}`))}}function it(e){let{resources:t,problems:n}=at(e);return fn(n),t}function U(){let e=T();if(!e)throw q.notInProject();return it(e)}function Kr(e){let t=e;if(!t){let n=T();if(!n)throw q.notInProject();t=at(n)}if(t.problems.length>0)throw new Error(t.problems.map(n=>`Invalid service.json at ${n.path}: ${n.reason}`).join(`
15
15
  `));return t.resources}function Hr(e,t){let n=t??it(e);return pn(n)}function pn(e){let t=e||U(),n=new Set;for(let r of t)r.stack&&n.add(r.stack);return Array.from(n).sort()}function Jr(e=U()){let t=new Map;for(let r of e)if(r.stack){let o=t.get(r.stack);o?o.push(r):t.set(r.stack,[r])}let n=[];for(let[r,o]of t)n.push({name:r,description:Re(o.length,"resource"),resources:o,resourceCount:o.length});return n.sort((r,o)=>r.name.localeCompare(o.name))}function Yr(e,t){return(t??U()).filter(r=>r.stack===e)}function Zr(e,t){return(t??U()).some(r=>r.stack===e)}var le=5e3,fe=new j({ttlMs:le}),pe=new j({ttlMs:le}),I=Te(le);function Qr(){fe.clear(),pe.clear(),I.reset()}function dn(e,t){if(e==="Dockerfile"||e.startsWith("docker-compose"))return"docker";if(e==="Tiltfile"||e.endsWith(".star"))return"tilt";if(e==="vite.config.ts"||e==="tsconfig.json"||e===we)return"config";if(e==="schema.prisma"||e.includes("migration"))return"prisma";if(t){let n=t.split(`
16
16
  `).slice(0,10).join(`