@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,24 +1,24 @@
1
- import{createRequire as __tdkRequire}from'node:module';const require=__tdkRequire(import.meta.url);
2
- import{E as x,a as h,ga as D,ha as L,t as _}from"./chunk-AGXA5DOQ.js";import{C as F,j as I,m as w,n as A,t as j,x as T}from"./chunk-AT5MFZ3D.js";import{execFileSync as B}from"node:child_process";import{existsSync as de,mkdirSync as le,readFileSync as K,realpathSync as fe,writeFileSync as pe}from"node:fs";import{join as S,resolve as he,sep as me}from"node:path";import{createServer as ie}from"node:net";import{connect as oe}from"node:net";function U(e,t=500){return new Promise(r=>{let s=oe({port:e,host:"127.0.0.1"}),n=o=>{s.destroy(),r(o)};s.setTimeout(t,()=>n(!1)),s.once("connect",()=>n(!0)),s.once("error",()=>n(!1))})}var ae={ingressHttp:{start:8080,end:8180},ingressHttps:{start:8443,end:8543},postgres:{start:15432,end:15532}},v={ingressHttp:"TDK_HTTP_PORT",ingressHttps:"TDK_HTTPS_PORT",postgres:"TDK_POSTGRES_PORT"},H={ingressHttp:80,ingressHttps:443,postgres:5432},E={ingressHttp:H.ingressHttp,ingressHttps:H.ingressHttps};function ce(e,t){return e==="EACCES"&&t==="darwin"}async function O(e){return await U(e)?!1:new Promise(t=>{let r=ie();r.once("error",s=>{t(ce(s.code,process.platform))}),r.listen(e,"127.0.0.1",()=>r.close(()=>t(!0)))})}function ue(e,t){let r=Number(t);if(!Number.isInteger(r)||r<1||r>65535)throw new Error(`${e} must be an integer between 1 and 65535 (received ${JSON.stringify(t)})`);return r}async function R(e={}){let t=e.env??process.env,r=e.isAvailable??O,s={ingressHttp:!1,ingressHttps:!1,postgres:!1},n={ingressHttp:"",ingressHttps:"",postgres:""},o={explicit:s},a=new Set;for(let c of["ingressHttp","ingressHttps","postgres"]){let u=t[v[c]],i=u!==void 0&&u.trim()!=="",d=e.ranges?.[c]??ae[c],l=E[c],f=i?[ue(v[c],u)]:[...l===void 0?[]:[l],...Array.from({length:d.end-d.start+1},(g,k)=>d.start+k)],m;for(let g of f)if(!a.has(g)){if(await r(g)){m=g;break}if(i)throw new Error(`${v[c]}=${g} is already in use. Choose a free host port and retry.`)}if(m===void 0)throw new Error(`No available host port in ${d.start}-${d.end} for ${c}. Set ${v[c]} to a free port and retry.`);a.add(m),o[c]=m,s[c]=i,n[c]=i?"explicit override":m===l?"requested port is free":`selected from fallback range ${d.start}-${d.end}`}return{...o,requested:{...H},reason:n}}function Ve(e){return`Host ports: HTTP ${e.ingressHttp}, HTTPS ${e.ingressHttps}, Postgres ${e.postgres}`}var G=S(".tdk",".tdk-out","host-ports.json");function ge(e,t,r){return e.split(`
3
- `).some(s=>{let[n="",o=""]=s.split("|"),a=n.toLowerCase(),c=t.toLowerCase();return(a.startsWith(`${c}_`)||a.startsWith(`${c}-`))&&o.includes(`:${r}->`)})}function V(e){let t=S(e,G);if(!de(t))return null;try{let r=JSON.parse(K(t,"utf-8"));if(!r||typeof r!="object")return null;let s=r;return!Number.isInteger(s.ingressHttp)||!Number.isInteger(s.ingressHttps)||!Number.isInteger(s.postgres)||!s.requested||!s.explicit||!s.reason?null:s}catch{return null}}function Ye(e,t){let r=S(e,G);le(S(e,".tdk",".tdk-out"),{recursive:!0}),pe(r,`${JSON.stringify(t,null,2)}
4
- `,{encoding:"utf-8",mode:384})}function Qe(e){process.env.TDK_HTTP_PORT=String(e.ingressHttp),process.env.TDK_HTTPS_PORT=String(e.ingressHttps),process.env.TDK_POSTGRES_PORT=String(e.postgres)}var ke="com.docker.compose.project.working_dir";function Pe(e,t,r){let s=new Set([he(t)]);try{s.add(fe(t))}catch{}return e.split(`
5
- `).some(n=>{let[,o="",a=""]=n.split("|");return!a||!o.includes(`:${r}->`)?!1:[...s].some(c=>a===c||a.startsWith(`${c}${me}`))})}function Xe(e,t,r=()=>B("docker",["ps","--format",`{{.Names}}|{{.Ports}}|{{.Label "${ke}"}}`],{encoding:"utf-8",timeout:5e3})){let s=V(e);if(!s||s.ingressHttp===t)return t;try{if(Pe(r(),e,s.ingressHttp))return s.ingressHttp}catch{}return t}async function et(e,t={}){let r=V(e),s=["TDK_HTTP_PORT","TDK_HTTPS_PORT","TDK_POSTGRES_PORT"].some(i=>process.env[i]);if(t.inspectDocker===!1&&r&&!s)return r;let n="";try{let i=JSON.parse(K(S(e,".tdk",w),"utf-8"));n=String(i?.project?.name??"tdk-project").replace(/-/g,"_").toLowerCase()}catch{n="tdk_project"}let o="";if(t.inspectDocker!==!1)try{o=B("docker",["ps","--format","{{.Names}}|{{.Ports}}"],{encoding:"utf-8",timeout:5e3})}catch{}let a=i=>ge(o,n,i),c=t.isPortFree??O,u=async i=>await c(i)||a(i);if(r&&!s){for(let i of[r.ingressHttp,r.ingressHttps,r.postgres])if(!await u(i))return R({isAvailable:u});for(let[i,d]of Object.entries(E)){let l=r[i];if(d!==void 0&&l!==d&&await u(d))return R({isAvailable:u})}return r}return R({isAvailable:u})}import{execFileSync as Q,execSync as $}from"node:child_process";import{existsSync as C,readdirSync as Te,readFileSync as N}from"node:fs";import{createServer as Se}from"node:net";import{join as P}from"node:path";function W(e,t){return e==="pending"||e==="in_progress"||e==="none"||t==="pending"||t==="none"}var J="container is running, but its health check is failing";function M(e){let t=e?.runtimeStatus??"";if(t!=="ok")return t;let r=e?.composeResourceInfo?.healthStatus;return r==="unhealthy"?"error":r==="starting"?"pending":t}var b=1e4,z=3e3,be="http://localhost:4873";function X(e){return`'${e.replace(/'/g,"'\\''")}'`}function y(e,t,r,s,n){return process.platform==="win32"?Q(F(t)??t,r,{...n,windowsHide:!0}):e(s,n)}var ye=[80,443];function $e(e){return e.replace(/-/g,"_")}function we(e,t){let r=new Set(t),s=[];for(let n of e.split(`
6
- `)){let o=n.trim();if(!o)continue;let a=o.indexOf(" "),c=a>=0?o.slice(0,a):o,u=a>=0?o.slice(a+1):"",i=[];for(let d of r)u.split(/[\s,]+/).some(f=>f.startsWith(`${d}->`)||f.includes(`:${d}->`))&&i.push(d);i.length>0&&s.push({name:c,ports:u,publishedPorts:i})}return s}function ee(e,t){let r=e.toLowerCase(),s=t.toLowerCase();return r===`${s}_traefik`||r.startsWith(`${s}_traefik`)}function ve(e,t){return e.filter(r=>!ee(r.name,t))}function Re(e){try{let t=e??L();return new Set(t.filter(r=>r.config?.sablier?.enable&&r.config?.sablier?.deferStart).map(r=>r.name))}catch{return new Set}}function _e(e,t=new Set){let s=JSON.parse(e).items??[],n=[],o=0,a=0,c=0;for(let u of s){let i=u.metadata?.name??"unknown",d=u.status?.updateStatus??"",l=M(u.status),f=l==="error"&&u.status?.runtimeStatus==="ok",g=(u.status?.buildHistory?.[0]?.error??"").trim()||(f?J:"");if(d==="error"||l==="error"){n.push({name:i,updateStatus:d,runtimeStatus:l,error:g.replace(/\s+/g," ").slice(0,800)});continue}if(d==="ok"&&(l==="ok"||l==="not_applicable")){c+=1;continue}i!=="(Tiltfile)"&&W(d,l)&&(t.has(i)?a+=1:o+=1)}return{failures:n,pendingCount:o,deferredCount:a,okCount:c,total:s.length}}var xe=/failed to resolve source metadata for docker\.io\/library\/([A-Za-z0-9._-]+-l[1-4](?:-[a-z]+)*)(?::[^\s:]+)?:/i;function te(e){let t=e.replace(/\s+/g," ").trim(),r=t.match(/Bind for [^ ]+:(\d+) failed: port is already allocated/i);if(r)return`host port ${r[1]} is already allocated`;if(/port is already allocated/i.test(t))return"a required host port is already allocated";let s=[...t.matchAll(/ConnectionRefused downloading package manifest (@[A-Za-z0-9._/-]+)/gi)].map(c=>c[1]);if(s.length>0){let c=[...new Set(s)],u=c.slice(0,4).join(", "),i=c.length>4?` (+${c.length-4} more)`:"";return`private registry ConnectionRefused for ${u}${i} \u2014 Verdaccio (:4873) is down or unreachable from the build`}let n=t.match(xe);if(n)return`base image ${n[1]} was missing when this build started (the golden layers weren't built yet, or golden-layers-build failed) - Tilt does not retry a failed build by itself`;if(/install-deps\.sh/i.test(t)||/bun install(?: --production)?/i.test(t)||/npm (?:ci|install)/i.test(t))return"dependency install failed during ImageBuild \u2014 usually Verdaccio (:4873) unreachable or missing @scoped packages (ConnectionRefused downloading package manifest)";let o=t.match(/No such image:\s*([^\s]+)/i)?.[1]??t.match(/pull access denied for ([^,:\s]+)/i)?.[1]??void 0,a=t.match(/\bup\s+-d\s+--no-build\s+([A-Za-z0-9._-]+)/i)?.[1];if(o||a||/docker compose .*\bup\s+-d\s+--no-build\b/i.test(t)){let c=o??`${a??"service"}:dev`,u=a?` for ${a}`:"";return`compose run failed because image is missing (${c})${u} \u2014 wait for the ImageBuild resource to finish, then re-trigger the *-run-only resource`}return/bun run build/i.test(t)?"ImageBuild failed during `bun run build` (compile/typecheck) \u2014 open the resource logs in Tilt for the TypeScript/build error":(/ImageBuild:/i.test(t)||/^Command "/i.test(t),t.slice(0,220))}function q(e){return/ConnectionRefused downloading package manifest|Verdaccio|private registry|dependency install failed during ImageBuild|install-deps\.sh|bun install/i.test(e)}function He(e=T()??process.cwd()){let t=P(e,".tdk",w);if(!C(t))return!1;try{let r=JSON.parse(N(t,"utf-8"));return r.optional_infra?.verdaccio===!0||Object.values(r.phases??{}).some(s=>(s.enabledStacks??[]).includes("verdaccio"))}catch{return!1}}function re(e){for(let t of[P(e,".npmrc"),P(e,A)])if(C(t))try{let r=N(t,"utf-8");if(/:4873\b/.test(r)||/verdaccio/i.test(r))return!0}catch{}return!1}function Ee(e=T()??process.cwd()){return He(e)||re(e)}function mt(e=$,t=T()??process.cwd(),r=process.env.VERDACCIO_URL??process.env.NPM_REGISTRY_URL??be,s=!0){if(!s&&!re(t))return{name:"Private npm registry",didPass:!0,isSkipped:!0,message:"Verdaccio is enabled in the project config but needs a Premium license, so Flisk will not start it - skipped"};if(!Ee(t))return{name:"Private npm registry",didPass:!0,isSkipped:!0,message:"Private npm registry (Verdaccio) not enabled for this project - skipped"};let n=!1;try{let c=y(e,"docker",["ps","--format","{{.Names}}"],"docker ps --format '{{.Names}}'",{stdio:"pipe",encoding:"utf-8",timeout:b});n=/verdaccio/i.test(c)}catch{}let o=!1,a="";try{let c=process.platform==="win32"?Q("curl.exe",["-fsS","-o","NUL","-w","%{http_code}","--max-time","2",r],{stdio:"pipe",encoding:"utf-8",timeout:z+1e3,windowsHide:!0}).trim():e(`curl -fsS -o /dev/null -w '%{http_code}' --max-time 2 ${X(r)}`,{stdio:"pipe",encoding:"utf-8",timeout:z+1e3}).trim();o=/^[23]\d\d$/.test(c),a=`HTTP ${c}`}catch(c){a=c instanceof Error?c.message.slice(0,120):"request failed"}return o?{name:"Private npm registry",didPass:!0,message:`Private npm registry reachable at ${r}${n?" (verdaccio container running)":""}`}:n?{name:"Private npm registry",didPass:!1,message:`Verdaccio container is running but ${r} is not responding (${a}). ImageBuilds that install @scoped packages will fail with ConnectionRefused downloading package manifest.`,fix:"Check `docker logs` for the verdaccio container, confirm port 4873 is published, then re-run `flisk doctor`."}:{name:"Private npm registry",didPass:!1,message:`Private npm registry (Verdaccio) is not reachable at ${r}. Docker ImageBuilds will fail with ConnectionRefused downloading package manifests for @flisk-sh/* and project-scoped packages.`,fix:"Start the registry with `bun run verdaccio:start` (or `docker compose -f docker-compose.verdaccio.yml up -d`), publish packages with `bun run publish:all` / `scripts/build/publish-to-verdaccio.sh`, then `tilt trigger` failed resources or re-run `flisk up`."}}function gt(e=$,t=x(),r=ye){let s=$e(t),n="";try{n=y(e,"docker",["ps","--format","{{.Names}}\\t{{.Ports}}"],"docker ps --format '{{.Names}}\\t{{.Ports}}'",{stdio:"pipe",encoding:"utf-8",timeout:b})}catch{return{name:"Ingress Ports",didPass:!0,isSkipped:!0,message:"Docker not available - skipped ingress port check"}}let o=we(n,r),a=ve(o,s);if(a.length===0){let u=o.filter(i=>ee(i.name,s));return u.length>0?{name:"Ingress Ports",didPass:!0,message:`Ingress ports ${r.join("/")} held by this project's Traefik (${u.map(i=>i.name).join(", ")})`}:{name:"Ingress Ports",didPass:!0,message:`Ingress ports ${r.join("/")} are free for Traefik`}}return{name:"Ingress Ports",didPass:!1,message:`Traefik cannot bind ingress ports because another container already owns them:
1
+ import{createRequire as __fliskRequire}from'node:module';const require=__fliskRequire(import.meta.url);
2
+ import{E as x,a as h,ga as j,ha as D,t as _}from"./chunk-BWK6MPCB.js";import{C as L,j as N,m as w,n as A,t as F,x as T}from"./chunk-VHFFSBVJ.js";import{execFileSync as B}from"node:child_process";import{existsSync as de,mkdirSync as le,readFileSync as K,realpathSync as fe,writeFileSync as pe}from"node:fs";import{join as b,resolve as he,sep as me}from"node:path";import{createServer as ie}from"node:net";import{connect as oe}from"node:net";function U(e,t=500){return new Promise(r=>{let s=oe({port:e,host:"127.0.0.1"}),n=o=>{s.destroy(),r(o)};s.setTimeout(t,()=>n(!1)),s.once("connect",()=>n(!0)),s.once("error",()=>n(!1))})}var ae={ingressHttp:{start:8080,end:8180},ingressHttps:{start:8443,end:8543},postgres:{start:15432,end:15532}},v={ingressHttp:"FLISK_HTTP_PORT",ingressHttps:"FLISK_HTTPS_PORT",postgres:"FLISK_POSTGRES_PORT"},H={ingressHttp:80,ingressHttps:443,postgres:5432},E={ingressHttp:H.ingressHttp,ingressHttps:H.ingressHttps};function ce(e,t){return e==="EACCES"&&t==="darwin"}async function O(e){return await U(e)?!1:new Promise(t=>{let r=ie();r.once("error",s=>{t(ce(s.code,process.platform))}),r.listen(e,"127.0.0.1",()=>r.close(()=>t(!0)))})}function ue(e,t){let r=Number(t);if(!Number.isInteger(r)||r<1||r>65535)throw new Error(`${e} must be an integer between 1 and 65535 (received ${JSON.stringify(t)})`);return r}async function R(e={}){let t=e.env??process.env,r=e.isAvailable??O,s={ingressHttp:!1,ingressHttps:!1,postgres:!1},n={ingressHttp:"",ingressHttps:"",postgres:""},o={explicit:s},a=new Set;for(let c of["ingressHttp","ingressHttps","postgres"]){let u=t[v[c]],i=u!==void 0&&u.trim()!=="",d=e.ranges?.[c]??ae[c],l=E[c],f=i?[ue(v[c],u)]:[...l===void 0?[]:[l],...Array.from({length:d.end-d.start+1},(g,k)=>d.start+k)],m;for(let g of f)if(!a.has(g)){if(await r(g)){m=g;break}if(i)throw new Error(`${v[c]}=${g} is already in use. Choose a free host port and retry.`)}if(m===void 0)throw new Error(`No available host port in ${d.start}-${d.end} for ${c}. Set ${v[c]} to a free port and retry.`);a.add(m),o[c]=m,s[c]=i,n[c]=i?"explicit override":m===l?"requested port is free":`selected from fallback range ${d.start}-${d.end}`}return{...o,requested:{...H},reason:n}}function Ve(e){return`Host ports: HTTP ${e.ingressHttp}, HTTPS ${e.ingressHttps}, Postgres ${e.postgres}`}var G=b(".flisk",".flisk-out","host-ports.json");function ge(e,t,r){return e.split(`
3
+ `).some(s=>{let[n="",o=""]=s.split("|"),a=n.toLowerCase(),c=t.toLowerCase();return(a.startsWith(`${c}_`)||a.startsWith(`${c}-`))&&o.includes(`:${r}->`)})}function V(e){let t=b(e,G);if(!de(t))return null;try{let r=JSON.parse(K(t,"utf-8"));if(!r||typeof r!="object")return null;let s=r;return!Number.isInteger(s.ingressHttp)||!Number.isInteger(s.ingressHttps)||!Number.isInteger(s.postgres)||!s.requested||!s.explicit||!s.reason?null:s}catch{return null}}function Ye(e,t){let r=b(e,G);le(b(e,".flisk",".flisk-out"),{recursive:!0}),pe(r,`${JSON.stringify(t,null,2)}
4
+ `,{encoding:"utf-8",mode:384})}function Qe(e){process.env.FLISK_HTTP_PORT=String(e.ingressHttp),process.env.FLISK_HTTPS_PORT=String(e.ingressHttps),process.env.FLISK_POSTGRES_PORT=String(e.postgres)}var ke="com.docker.compose.project.working_dir";function Pe(e,t,r){let s=new Set([he(t)]);try{s.add(fe(t))}catch{}return e.split(`
5
+ `).some(n=>{let[,o="",a=""]=n.split("|");return!a||!o.includes(`:${r}->`)?!1:[...s].some(c=>a===c||a.startsWith(`${c}${me}`))})}function Xe(e,t,r=()=>B("docker",["ps","--format",`{{.Names}}|{{.Ports}}|{{.Label "${ke}"}}`],{encoding:"utf-8",timeout:5e3})){let s=V(e);if(!s||s.ingressHttp===t)return t;try{if(Pe(r(),e,s.ingressHttp))return s.ingressHttp}catch{}return t}async function et(e,t={}){let r=V(e),s=["FLISK_HTTP_PORT","FLISK_HTTPS_PORT","FLISK_POSTGRES_PORT"].some(i=>process.env[i]);if(t.inspectDocker===!1&&r&&!s)return r;let n="";try{let i=JSON.parse(K(b(e,".flisk",w),"utf-8"));n=String(i?.project?.name??"flisk-project").replace(/-/g,"_").toLowerCase()}catch{n="flisk_project"}let o="";if(t.inspectDocker!==!1)try{o=B("docker",["ps","--format","{{.Names}}|{{.Ports}}"],{encoding:"utf-8",timeout:5e3})}catch{}let a=i=>ge(o,n,i),c=t.isPortFree??O,u=async i=>await c(i)||a(i);if(r&&!s){for(let i of[r.ingressHttp,r.ingressHttps,r.postgres])if(!await u(i))return R({isAvailable:u});for(let[i,d]of Object.entries(E)){let l=r[i];if(d!==void 0&&l!==d&&await u(d))return R({isAvailable:u})}return r}return R({isAvailable:u})}import{execFileSync as Q,execSync as S}from"node:child_process";import{existsSync as I,readdirSync as Se,readFileSync as C}from"node:fs";import{createServer as Te}from"node:net";import{join as P}from"node:path";function W(e,t){return e==="pending"||e==="in_progress"||e==="none"||t==="pending"||t==="none"}var J="container is running, but its health check is failing";function M(e){let t=e?.runtimeStatus??"";if(t!=="ok")return t;let r=e?.composeResourceInfo?.healthStatus;return r==="unhealthy"?"error":r==="starting"?"pending":t}var y=1e4,z=3e3,be="http://localhost:4873";function X(e){return`'${e.replace(/'/g,"'\\''")}'`}function $(e,t,r,s,n){return process.platform==="win32"&&e===S?Q(L(t)??t,r,{...n,windowsHide:!0}):e(s,n)}var ye=[80,443];function $e(e){return e.replace(/-/g,"_")}function we(e,t){let r=new Set(t),s=[];for(let n of e.split(`
6
+ `)){let o=n.trim();if(!o)continue;let a=o.indexOf(" "),c=a>=0?o.slice(0,a):o,u=a>=0?o.slice(a+1):"",i=[];for(let d of r)u.split(/[\s,]+/).some(f=>f.startsWith(`${d}->`)||f.includes(`:${d}->`))&&i.push(d);i.length>0&&s.push({name:c,ports:u,publishedPorts:i})}return s}function ee(e,t){let r=e.toLowerCase(),s=t.toLowerCase();return r===`${s}_traefik`||r.startsWith(`${s}_traefik`)}function ve(e,t){return e.filter(r=>!ee(r.name,t))}function Re(e){try{let t=e??D();return new Set(t.filter(r=>r.config?.sablier?.enable&&r.config?.sablier?.deferStart).map(r=>r.name))}catch{return new Set}}function _e(e,t=new Set){let s=JSON.parse(e).items??[],n=[],o=0,a=0,c=0;for(let u of s){let i=u.metadata?.name??"unknown",d=u.status?.updateStatus??"",l=M(u.status),f=l==="error"&&u.status?.runtimeStatus==="ok",g=(u.status?.buildHistory?.[0]?.error??"").trim()||(f?J:"");if(d==="error"||l==="error"){n.push({name:i,updateStatus:d,runtimeStatus:l,error:g.replace(/\s+/g," ").slice(0,800)});continue}if(d==="ok"&&(l==="ok"||l==="not_applicable")){c+=1;continue}i!=="(Tiltfile)"&&W(d,l)&&(t.has(i)?a+=1:o+=1)}return{failures:n,pendingCount:o,deferredCount:a,okCount:c,total:s.length}}var xe=/failed to resolve source metadata for docker\.io\/library\/([A-Za-z0-9._-]+-l[1-4](?:-[a-z]+)*)(?::[^\s:]+)?:/i;function te(e){let t=e.replace(/\s+/g," ").trim(),r=t.match(/Bind for [^ ]+:(\d+) failed: port is already allocated/i);if(r)return`host port ${r[1]} is already allocated`;if(/port is already allocated/i.test(t))return"a required host port is already allocated";let s=[...t.matchAll(/ConnectionRefused downloading package manifest (@[A-Za-z0-9._/-]+)/gi)].map(c=>c[1]);if(s.length>0){let c=[...new Set(s)],u=c.slice(0,4).join(", "),i=c.length>4?` (+${c.length-4} more)`:"";return`private registry ConnectionRefused for ${u}${i} \u2014 Verdaccio (:4873) is down or unreachable from the build`}let n=t.match(xe);if(n)return`base image ${n[1]} was missing when this build started (the golden layers weren't built yet, or golden-layers-build failed) - Tilt does not retry a failed build by itself`;if(/install-deps\.sh/i.test(t)||/bun install(?: --production)?/i.test(t)||/npm (?:ci|install)/i.test(t))return"dependency install failed during ImageBuild \u2014 usually Verdaccio (:4873) unreachable or missing @scoped packages (ConnectionRefused downloading package manifest)";let o=t.match(/No such image:\s*([^\s]+)/i)?.[1]??t.match(/pull access denied for ([^,:\s]+)/i)?.[1]??void 0,a=t.match(/\bup\s+-d\s+--no-build\s+([A-Za-z0-9._-]+)/i)?.[1];if(o||a||/docker compose .*\bup\s+-d\s+--no-build\b/i.test(t)){let c=o??`${a??"service"}:dev`,u=a?` for ${a}`:"";return`compose run failed because image is missing (${c})${u} \u2014 wait for the ImageBuild resource to finish, then re-trigger the *-run-only resource`}return/bun run build/i.test(t)?"ImageBuild failed during `bun run build` (compile/typecheck) \u2014 open the resource logs in Tilt for the TypeScript/build error":(/ImageBuild:/i.test(t)||/^Command "/i.test(t),t.slice(0,220))}function q(e){return/ConnectionRefused downloading package manifest|Verdaccio|private registry|dependency install failed during ImageBuild|install-deps\.sh|bun install/i.test(e)}function He(e=T()??process.cwd()){let t=P(e,".flisk",w);if(!I(t))return!1;try{let r=JSON.parse(C(t,"utf-8"));return r.optional_infra?.verdaccio===!0||Object.values(r.phases??{}).some(s=>(s.enabledStacks??[]).includes("verdaccio"))}catch{return!1}}function re(e){for(let t of[P(e,".npmrc"),P(e,A)])if(I(t))try{let r=C(t,"utf-8");if(/:4873\b/.test(r)||/verdaccio/i.test(r))return!0}catch{}return!1}function Ee(e=T()??process.cwd()){return He(e)||re(e)}function mt(e=S,t=T()??process.cwd(),r=process.env.VERDACCIO_URL??process.env.NPM_REGISTRY_URL??be,s=!0){if(!s&&!re(t))return{name:"Private npm registry",didPass:!0,isSkipped:!0,message:"Verdaccio is enabled in the project config but needs a Premium license, so Flisk will not start it - skipped"};if(!Ee(t))return{name:"Private npm registry",didPass:!0,isSkipped:!0,message:"Private npm registry (Verdaccio) not enabled for this project - skipped"};let n=!1;try{let c=$(e,"docker",["ps","--format","{{.Names}}"],"docker ps --format '{{.Names}}'",{stdio:"pipe",encoding:"utf-8",timeout:y});n=/verdaccio/i.test(c)}catch{}let o=!1,a="";try{let c=process.platform==="win32"?Q("curl.exe",["-fsS","-o","NUL","-w","%{http_code}","--max-time","2",r],{stdio:"pipe",encoding:"utf-8",timeout:z+1e3,windowsHide:!0}).trim():e(`curl -fsS -o /dev/null -w '%{http_code}' --max-time 2 ${X(r)}`,{stdio:"pipe",encoding:"utf-8",timeout:z+1e3}).trim();o=/^[23]\d\d$/.test(c),a=`HTTP ${c}`}catch(c){a=c instanceof Error?c.message.slice(0,120):"request failed"}return o?{name:"Private npm registry",didPass:!0,message:`Private npm registry reachable at ${r}${n?" (verdaccio container running)":""}`}:n?{name:"Private npm registry",didPass:!1,message:`Verdaccio container is running but ${r} is not responding (${a}). ImageBuilds that install @scoped packages will fail with ConnectionRefused downloading package manifest.`,fix:"Check `docker logs` for the verdaccio container, confirm port 4873 is published, then re-run `flisk doctor`."}:{name:"Private npm registry",didPass:!1,message:`Private npm registry (Verdaccio) is not reachable at ${r}. Docker ImageBuilds will fail with ConnectionRefused downloading package manifests for @flisk-sh/* and project-scoped packages.`,fix:"Start the registry with `bun run verdaccio:start` (or `docker compose -f docker-compose.verdaccio.yml up -d`), publish packages with `bun run publish:all` / `scripts/build/publish-to-verdaccio.sh`, then `tilt trigger` failed resources or re-run `flisk up`."}}function gt(e=S,t=x(),r=ye){let s=$e(t),n="";try{n=$(e,"docker",["ps","--format","{{.Names}}\\t{{.Ports}}"],"docker ps --format '{{.Names}}\\t{{.Ports}}'",{stdio:"pipe",encoding:"utf-8",timeout:y})}catch{return{name:"Ingress Ports",didPass:!0,isSkipped:!0,message:"Docker not available - skipped ingress port check"}}let o=we(n,r),a=ve(o,s);if(a.length===0){let u=o.filter(i=>ee(i.name,s));return u.length>0?{name:"Ingress Ports",didPass:!0,message:`Ingress ports ${r.join("/")} held by this project's Traefik (${u.map(i=>i.name).join(", ")})`}:{name:"Ingress Ports",didPass:!0,message:`Ingress ports ${r.join("/")} are free for Traefik`}}return{name:"Ingress Ports",didPass:!1,message:`Traefik cannot bind ingress ports because another container already owns them:
7
7
  ${a.map(u=>{let i=u.publishedPorts.join(", ");return`${u.name} (host ports ${i})`}).join(`
8
- `)}`,fix:`Stop the foreign container(s), e.g. \`docker stop ${a[0]?.name}\`, or shut down the other Flisk/Tilt project using that Traefik. Then re-run \`flisk up\`.`}}function Z(e,t){return new Promise(r=>{let s=Se();s.once("error",n=>r(n.code==="EADDRINUSE"?"in-use":"unknown")),s.once("listening",()=>s.close(()=>r("free"))),s.listen(e,t)})}async function kt(e){for(let t=0;t<2;t++){let r=await Z(e,"0.0.0.0");if(r==="unknown")return r;if(r==="free"){let s=await Z(e,"127.0.0.1");if(s==="free"||s==="unknown")return s}t===0&&await new Promise(s=>setTimeout(s,50))}return"in-use"}function Oe(e){let{status:t}=e;return t===void 0?e.error??"no response":t===404?"HTTP 404: Traefik is answering but has no route for this URL (container not started yet, or not running)":t===502||t===503||t===504?`HTTP ${t}: Traefik found the route but the container isn't answering (still starting, or unhealthy)`:`HTTP ${t}`}function Pt(e){let t=e.filter(o=>o.status!==void 0),r=e.filter(o=>!o.ok);if(t.length===0)return{name:"Service Health",didPass:!0,isSkipped:!0,message:`No services responded - skipped ping of ${h(e.length,"service")} (stack may be down, or Traefik never bound :80)`,fix:"If `flisk up` is already running, check Traefik/port 80 in the Tilt UI. Otherwise start with: flisk up"};if(r.length===0)return{name:"Service Health",didPass:!0,message:`All ${h(e.length,"service")} responding on /health`};let s=r.map(o=>`${o.name} (${Oe(o)})
8
+ `)}`,fix:`Stop the foreign container(s), e.g. \`docker stop ${a[0]?.name}\`, or shut down the other Flisk/Tilt project using that Traefik. Then re-run \`flisk up\`.`}}function Z(e,t){return new Promise(r=>{let s=Te();s.once("error",n=>r(n.code==="EADDRINUSE"?"in-use":"unknown")),s.once("listening",()=>s.close(()=>r("free"))),s.listen(e,t)})}async function kt(e){for(let t=0;t<2;t++){let r=await Z(e,"0.0.0.0");if(r==="unknown")return r;if(r==="free"){let s=await Z(e,"127.0.0.1");if(s==="free"||s==="unknown")return s}t===0&&await new Promise(s=>setTimeout(s,50))}return"in-use"}function Oe(e){let{status:t}=e;return t===void 0?e.error??"no response":t===404?"HTTP 404: Traefik is answering but has no route for this URL (container not started yet, or not running)":t===502||t===503||t===504?`HTTP ${t}: Traefik found the route but the container isn't answering (still starting, or unhealthy)`:`HTTP ${t}`}function Pt(e){let t=e.filter(o=>o.status!==void 0),r=e.filter(o=>!o.ok);if(t.length===0)return{name:"Service Health",didPass:!0,isSkipped:!0,message:`No services responded - skipped ping of ${h(e.length,"service")} (stack may be down, or Traefik never bound :80)`,fix:"If `flisk up` is already running, check Traefik/port 80 in the Tilt UI. Otherwise start with: flisk up"};if(r.length===0)return{name:"Service Health",didPass:!0,message:`All ${h(e.length,"service")} responding on /health`};let s=r.map(o=>`${o.name} (${Oe(o)})
9
9
  ${o.url}`).join(`
10
10
  `),n=r.some(o=>o.status===404);return{name:"Service Health",didPass:!1,message:`${h(r.length,"service")} not healthy (${e.length-r.length}/${e.length} healthy):
11
- ${s}`,fix:n?"If `flisk up` just started, images may still be building: re-run `flisk doctor` in a minute. Otherwise check `docker ps` and the resource in the Tilt UI, and compare `flisk networks` with the URL above.":"Check container state and routing: docker ps, then flisk networks to compare the advertised URLs against Traefik's routers"}}function Tt(e){if(e.length===0)return{name:"Service Smoke",didPass:!0,isSkipped:!0,message:"No read-only smoke checks declared"};let t=e.filter(s=>!s.ok);if(t.length===0)return{name:"Service Smoke",didPass:!0,message:`All ${h(e.length,"service")} pass their smoke checks`};let r=t.map(s=>s.failure??`${s.name}: failed`).join(`
11
+ ${s}`,fix:n?"If `flisk up` just started, images may still be building: re-run `flisk doctor` in a minute. Otherwise check `docker ps` and the resource in the Tilt UI, and compare `flisk networks` with the URL above.":"Check container state and routing: docker ps, then flisk networks to compare the advertised URLs against Traefik's routers"}}function St(e){if(e.length===0)return{name:"Service Smoke",didPass:!0,isSkipped:!0,message:"No read-only smoke checks declared"};let t=e.filter(s=>!s.ok);if(t.length===0)return{name:"Service Smoke",didPass:!0,message:`All ${h(e.length,"service")} pass their smoke checks`};let r=t.map(s=>s.failure??`${s.name}: failed`).join(`
12
12
  `);return{name:"Service Smoke",didPass:!1,message:`${h(t.length,"service")} failing a smoke check (${e.length-t.length}/${e.length} passing):
13
- ${r}`,fix:'Add the route the smoke step expects, or correct its "path" in the service.json "smoke" block. Then re-run flisk doctor.'}}function St(e){let t=e.filter(n=>n.status!==void 0);if(t.length===0)return{name:"Advertised Endpoints",didPass:!0,isSkipped:!0,message:"No services responded - skipped advertised endpoint check"};let r=t.filter(n=>n.status===404);if(r.length===0)return{name:"Advertised Endpoints",didPass:!0,message:`${h(t.length,"advertised endpoint")} reachable`};let s=r.map(n=>`${n.name} (404)
13
+ ${r}`,fix:'Add the route the smoke step expects, or correct its "path" in the service.json "smoke" block. Then re-run flisk doctor.'}}function Tt(e){let t=e.filter(n=>n.status!==void 0);if(t.length===0)return{name:"Advertised Endpoints",didPass:!0,isSkipped:!0,message:"No services responded - skipped advertised endpoint check"};let r=t.filter(n=>n.status===404);if(r.length===0)return{name:"Advertised Endpoints",didPass:!0,message:`${h(t.length,"advertised endpoint")} reachable`};let s=r.map(n=>`${n.name} (404)
14
14
  ${n.url}`).join(`
15
15
  `);return{name:"Advertised Endpoints",didPass:!0,isWarning:!0,message:`${h(r.length,"advertised link")} ${r.length===1?"returns":"return"} 404 (the service may be healthy, but nothing answers at this exact path):
16
- ${s}`,fix:'Nothing handles this exact path, so opening the link shows a 404 even when /health is fine. If this API has no root route, you can leave it. Otherwise add a GET route for it (for example one that returns the service name), or declare a read-only "smoke" step on a real route in service.json. The URL flisk networks and the Flisk App print stays the same until the CLI changes how it reports it.'}}function bt(e=$){let t="";try{t=y(e,"tilt",["get","uiresources","-o","json"],"tilt get uiresources -o json",{stdio:"pipe",encoding:"utf-8",timeout:b})}catch{return{name:"Tilt Resources",didPass:!0,isSkipped:!0,message:"Tilt is not running - skipped resource status check",fix:"Start them with: flisk up"}}let r;try{r=_e(t,Re())}catch{return{name:"Tilt Resources",didPass:!0,isSkipped:!0,message:"Could not parse Tilt resource status - skipped"}}if(r.total===0)return{name:"Tilt Resources",didPass:!0,isSkipped:!0,message:"No Tilt UIResources found"};if(r.failures.length===0){let p=r.deferredCount>0?`, ${r.deferredCount} deferred`:"";return{name:"Tilt Resources",didPass:!0,message:`Tilt resources healthy (${r.okCount} ok, ${r.pendingCount} pending${p})`}}let s=Ne(r.failures),o=s.slice(0,20),a=s.length-o.length,c=o.map(p=>({failure:p,why:Ae(p,e)})),u=c.map(({failure:p,why:ne})=>`${p.name}: ${ne}`).join(`
16
+ ${s}`,fix:'Nothing handles this exact path, so opening the link shows a 404 even when /health is fine. If this API has no root route, you can leave it. Otherwise add a GET route for it (for example one that returns the service name), or declare a read-only "smoke" step on a real route in service.json. The URL flisk networks and the Flisk App print stays the same until the CLI changes how it reports it.'}}function bt(e=S){let t="";try{t=$(e,"tilt",["get","uiresources","-o","json"],"tilt get uiresources -o json",{stdio:"pipe",encoding:"utf-8",timeout:y})}catch{return{name:"Tilt Resources",didPass:!0,isSkipped:!0,message:"Tilt is not running - skipped resource status check",fix:"Start them with: flisk up"}}let r;try{r=_e(t,Re())}catch{return{name:"Tilt Resources",didPass:!0,isSkipped:!0,message:"Could not parse Tilt resource status - skipped"}}if(r.total===0)return{name:"Tilt Resources",didPass:!0,isSkipped:!0,message:"No Tilt UIResources found"};if(r.failures.length===0){let p=r.deferredCount>0?`, ${r.deferredCount} deferred`:"";return{name:"Tilt Resources",didPass:!0,message:`Tilt resources healthy (${r.okCount} ok, ${r.pendingCount} pending${p})`}}let s=Ce(r.failures),o=s.slice(0,20),a=s.length-o.length,c=o.map(p=>({failure:p,why:Ae(p,e)})),u=c.map(({failure:p,why:ne})=>`${p.name}: ${ne}`).join(`
17
17
  `),i=a>0?`
18
18
  \u2026and ${h(a,"more failed resource")}`:"",d=r.pendingCount>0?`
19
19
  ${h(r.pendingCount,"resource")} still pending/not started \u2014 often blocked by the failures above.`:"",l=r.deferredCount>0?`
20
- ${h(r.deferredCount,"resource")} intentionally deferred (sablier.deferStart) \u2014 not started until first request, unrelated to the failures above.`:"",f=s.some(p=>/port is already allocated/i.test(p.error)),m=s.some(p=>q(p.error)||q(te(p.error))),g=c.some(({why:p})=>/Kafka broker unreachable|kafka:9092/i.test(p)),k="Open the Tilt UI URL printed by flisk up (default port "+j.tiltUi+" when TILT_PORT is unset), inspect the red resources, fix the listed errors, then `tilt trigger <resource>` or re-run `flisk up`.";return f?k="Free the conflicting host port (usually 80/443): `docker ps --filter publish=80` then `docker stop <other-traefik>`. Re-trigger Traefik in the Tilt UI or run `flisk up` again.":m?k="Start Verdaccio (`bun run verdaccio:start`), ensure packages are published (`bun run publish:all` or `bash scripts/build/publish-to-verdaccio.sh`), confirm `curl http://localhost:4873` works, then `tilt trigger` the failed resources.":g&&(k="Kafka is not running (optional infra). Start it, point the bridge at a real broker, or disable Kafka-dependent resources until Kafka is enabled."),{name:"Tilt Resources",didPass:!1,message:`Tilt reports ${h(r.failures.length,"failed resource")}:
21
- ${u}${i}${d}${l}`,fix:k}}var Ce=/^(traefik|postgres|nats|infisical|verdaccio|proxy)([.-]|$)/i;function Y(e){return Ce.test(e)}function Ne(e){return[...e].sort((t,r)=>{let s=Y(t.name)?0:1,n=Y(r.name)?0:1;return s!==n?s-n:t.name.localeCompare(r.name)})}function Ie(e,t=$,r=x()){try{let s=y(t,"docker",["ps","-a","--format","{{.Names}}"],"docker ps -a --format '{{.Names}}'",{stdio:"pipe",encoding:"utf-8",timeout:b}).split(`
22
- `).map(i=>i.trim()).filter(Boolean),n=`-autogenerated-${e}-1`,o=s.find(i=>i===e)??s.find(i=>i.startsWith(`${r}-`)&&i.endsWith(n))??s.find(i=>i.endsWith(n))??s.find(i=>i.includes(e));if(!o)return null;let a=y(t,"docker",["logs","--tail","120",o],`docker logs --tail 120 ${X(o)} 2>&1`,{stdio:"pipe",encoding:"utf-8",timeout:b});if(/getaddrinfo ENOTFOUND/i.test(a)&&/kafka:9092/i.test(a))return"runtime crash: Kafka broker unreachable (getaddrinfo ENOTFOUND kafka:9092)";if(/ECONNREFUSED/i.test(a)&&/kafka/i.test(a))return"runtime crash: Kafka connection refused";let c=a.match(/ConnectionRefused downloading package manifest (@[A-Za-z0-9._/-]+)/i);if(c?.[1])return`runtime/build log: private registry ConnectionRefused for ${c[1]}`;if(/ZodError/i.test(a)){let i=[...a.matchAll(/"path"\s*:\s*\[\s*"([^"]+)"\s*\]/g)].map(l=>l[1]),d=[...new Set(i)].slice(0,6);return d.length>0?`runtime crash: ZodError missing required config/env: ${d.join(", ")}`:"runtime crash: ZodError during config/env validation"}let u=a.match(/error:\s+Failed to [^:\n]+[^\n]{0,120}/i)?.[0]??a.match(/Failed to (?:start|initialize) [^\n]{0,120}/i)?.[0]??a.match(/^\s*error:\s+[^\n]{0,160}/im)?.[0];if(u)return`runtime crash: ${u.replace(/\s+/g," ").trim().slice(0,180)}`}catch{return null}return null}function Ae(e,t=$){return e.error?te(e.error):e.runtimeStatus==="error"?Ie(e.name,t)??"runtime error (container crashed or unhealthy \u2014 check Tilt/docker logs)":e.updateStatus||e.runtimeStatus||"unknown error"}var je=/\.(ts|tsx|mts|js|mjs|cjs)$/,Fe=new Set(["node_modules","dist",I,"tests","__tests__"]);function se(e){let t=[];for(let r of Te(e,{withFileTypes:!0}))r.isDirectory()?Fe.has(r.name)||t.push(...se(P(e,r.name))):je.test(r.name)&&!/\.(test|spec)\./.test(r.name)&&t.push(P(e,r.name));return t}function De(e){let t=e?.healthCheckPath||"/health";return{container:t,traefik:e?.traefik?.healthCheck||t}}function Le(e){let t=[];for(let r of e){if(!_(r.config?.appType))continue;let s=P(r.path,"src");if(!C(s))continue;let n=se(s);if(n.length===0)continue;let o=n.map(i=>N(i,"utf-8")),{container:a,traefik:c}=De(r.config),u=a===c?[{path:a,usedBy:"container and Traefik healthchecks"}]:[{path:a,usedBy:"container healthcheck"},{path:c,usedBy:"Traefik healthcheck"}];for(let{path:i,usedBy:d}of u){let l=["'",'"',"`"].map(f=>`${f}${i}${f}`);o.some(f=>l.some(m=>f.includes(m)))||t.push({name:r.name,healthPath:i,usedBy:d})}}return t}function yt(e=T()??process.cwd()){let t=[];try{t=D(e)}catch{return{name:"Health Routes",didPass:!0,isSkipped:!0,message:"Could not read services - skipped health route check"}}let r=t.filter(o=>_(o.config?.appType));if(r.length===0)return{name:"Health Routes",didPass:!0,isSkipped:!0,message:"No backend services to check"};let s=Le(r);return s.length===0?{name:"Health Routes",didPass:!0,message:`All ${h(r.length,"backend")} define their health route`}:{name:"Health Routes",didPass:!1,message:`Backends without a health route (the container never turns healthy, so Traefik returns 404):
20
+ ${h(r.deferredCount,"resource")} intentionally deferred (sablier.deferStart) \u2014 not started until first request, unrelated to the failures above.`:"",f=s.some(p=>/port is already allocated/i.test(p.error)),m=s.some(p=>q(p.error)||q(te(p.error))),g=c.some(({why:p})=>/Kafka broker unreachable|kafka:9092/i.test(p)),k="Open the Tilt UI URL printed by flisk up (default port "+F.tiltUi+" when TILT_PORT is unset), inspect the red resources, fix the listed errors, then `tilt trigger <resource>` or re-run `flisk up`.";return f?k="Free the conflicting host port (usually 80/443): `docker ps --filter publish=80` then `docker stop <other-traefik>`. Re-trigger Traefik in the Tilt UI or run `flisk up` again.":m?k="Start Verdaccio (`bun run verdaccio:start`), ensure packages are published (`bun run publish:all` or `bash scripts/build/publish-to-verdaccio.sh`), confirm `curl http://localhost:4873` works, then `tilt trigger` the failed resources.":g&&(k="Kafka is not running (optional infra). Start it, point the bridge at a real broker, or disable Kafka-dependent resources until Kafka is enabled."),{name:"Tilt Resources",didPass:!1,message:`Tilt reports ${h(r.failures.length,"failed resource")}:
21
+ ${u}${i}${d}${l}`,fix:k}}var Ie=/^(traefik|postgres|nats|infisical|verdaccio|proxy)([.-]|$)/i;function Y(e){return Ie.test(e)}function Ce(e){return[...e].sort((t,r)=>{let s=Y(t.name)?0:1,n=Y(r.name)?0:1;return s!==n?s-n:t.name.localeCompare(r.name)})}function Ne(e,t=S,r=x()){try{let s=$(t,"docker",["ps","-a","--format","{{.Names}}"],"docker ps -a --format '{{.Names}}'",{stdio:"pipe",encoding:"utf-8",timeout:y}).split(`
22
+ `).map(i=>i.trim()).filter(Boolean),n=`-autogenerated-${e}-1`,o=s.find(i=>i===e)??s.find(i=>i.startsWith(`${r}-`)&&i.endsWith(n))??s.find(i=>i.endsWith(n))??s.find(i=>i.includes(e));if(!o)return null;let a=$(t,"docker",["logs","--tail","120",o],`docker logs --tail 120 ${X(o)} 2>&1`,{stdio:"pipe",encoding:"utf-8",timeout:y});if(/getaddrinfo ENOTFOUND/i.test(a)&&/kafka:9092/i.test(a))return"runtime crash: Kafka broker unreachable (getaddrinfo ENOTFOUND kafka:9092)";if(/ECONNREFUSED/i.test(a)&&/kafka/i.test(a))return"runtime crash: Kafka connection refused";let c=a.match(/ConnectionRefused downloading package manifest (@[A-Za-z0-9._/-]+)/i);if(c?.[1])return`runtime/build log: private registry ConnectionRefused for ${c[1]}`;if(/ZodError/i.test(a)){let i=[...a.matchAll(/"path"\s*:\s*\[\s*"([^"]+)"\s*\]/g)].map(l=>l[1]),d=[...new Set(i)].slice(0,6);return d.length>0?`runtime crash: ZodError missing required config/env: ${d.join(", ")}`:"runtime crash: ZodError during config/env validation"}let u=a.match(/error:\s+Failed to [^:\n]+[^\n]{0,120}/i)?.[0]??a.match(/Failed to (?:start|initialize) [^\n]{0,120}/i)?.[0]??a.match(/^\s*error:\s+[^\n]{0,160}/im)?.[0];if(u)return`runtime crash: ${u.replace(/\s+/g," ").trim().slice(0,180)}`}catch{return null}return null}function Ae(e,t=S){return e.error?te(e.error):e.runtimeStatus==="error"?Ne(e.name,t)??"runtime error (container crashed or unhealthy \u2014 check Tilt/docker logs)":e.updateStatus||e.runtimeStatus||"unknown error"}var Fe=/\.(ts|tsx|mts|js|mjs|cjs)$/,Le=new Set(["node_modules","dist",N,"tests","__tests__"]);function se(e){let t=[];for(let r of Se(e,{withFileTypes:!0}))r.isDirectory()?Le.has(r.name)||t.push(...se(P(e,r.name))):Fe.test(r.name)&&!/\.(test|spec)\./.test(r.name)&&t.push(P(e,r.name));return t}function je(e){let t=e?.healthCheckPath||"/health";return{container:t,traefik:e?.traefik?.healthCheck||t}}function De(e){let t=[];for(let r of e){if(!_(r.config?.appType))continue;let s=P(r.path,"src");if(!I(s))continue;let n=se(s);if(n.length===0)continue;let o=n.map(i=>C(i,"utf-8")),{container:a,traefik:c}=je(r.config),u=a===c?[{path:a,usedBy:"container and Traefik healthchecks"}]:[{path:a,usedBy:"container healthcheck"},{path:c,usedBy:"Traefik healthcheck"}];for(let{path:i,usedBy:d}of u){let l=["'",'"',"`"].map(f=>`${f}${i}${f}`);o.some(f=>l.some(m=>f.includes(m)))||t.push({name:r.name,healthPath:i,usedBy:d})}}return t}function yt(e=T()??process.cwd()){let t=[];try{t=j(e)}catch{return{name:"Health Routes",didPass:!0,isSkipped:!0,message:"Could not read services - skipped health route check"}}let r=t.filter(o=>_(o.config?.appType));if(r.length===0)return{name:"Health Routes",didPass:!0,isSkipped:!0,message:"No backend services to check"};let s=De(r);return s.length===0?{name:"Health Routes",didPass:!0,message:`All ${h(r.length,"backend")} define their health route`}:{name:"Health Routes",didPass:!1,message:`Backends without a health route (the container never turns healthy, so Traefik returns 404):
23
23
  ${s.map(o=>`${o.name}: no "${o.healthPath}" route in src/ (probed by the ${o.usedBy})`).join(`
24
- `)}`,fix:`Add the route, e.g. for Hono: app.get("${s[0]?.healthPath}", (c) => c.json({ status: "ok" })). To use a different path, set "healthCheckPath" (container healthcheck) or "traefik.healthCheck" (Traefik) in its service.json.`}}export{R as a,Ve as b,V as c,Ye as d,Qe as e,Xe as f,et as g,W as h,M as i,$e as j,we as k,Re as l,_e as m,te as n,He as o,mt as p,gt as q,kt as r,Pt as s,Tt as t,St as u,bt as v,yt as w};
24
+ `)}`,fix:`Add the route, e.g. for Hono: app.get("${s[0]?.healthPath}", (c) => c.json({ status: "ok" })). To use a different path, set "healthCheckPath" (container healthcheck) or "traefik.healthCheck" (Traefik) in its service.json.`}}export{R as a,Ve as b,V as c,Ye as d,Qe as e,Xe as f,et as g,W as h,M as i,$e as j,we as k,Re as l,_e as m,te as n,He as o,mt as p,gt as q,kt as r,Pt as s,St as t,Tt as u,bt as v,yt as w};
@@ -0,0 +1,7 @@
1
+ import{createRequire as __fliskRequire}from'node:module';const require=__fliskRequire(import.meta.url);
2
+ import{b}from"./chunk-MINZ25AC.js";import{g as m,r as T}from"./chunk-D7N2GGJH.js";import{a as S}from"./chunk-QQEV6D74.js";import{F as k,H as $,ea as x,p as y,q as w}from"./chunk-BWK6MPCB.js";import{b as n,f as d,m as g,x as h}from"./chunk-VHFFSBVJ.js";import{Command as R}from"commander";import{readFileSync as N}from"node:fs";import{join as O}from"node:path";function F(o){let e=o.config;return e?Array.isArray(e.featuresEnabled)&&e.featuresEnabled.includes(d)?!0:(Array.isArray(e.dependsOn)?e.dependsOn:[]).some(a=>S.includes(a)):!1}function J(o,e){let s=o.replace(/-/g,"_"),a=[];for(let t of[...e].sort((r,c)=>r.name.localeCompare(c.name))){let r=t.resources.filter(F).map(c=>c.name);r.length!==0&&a.push({name:`${s}_${t.name.replace(/-/g,"_")}`,stack:t.name,services:r.sort()})}return a.length===0?null:{name:"postgres",databases:a}}function E(o){try{let e=JSON.parse(N(O(o,".flisk",g),"utf-8"));return typeof e?.project?.name=="string"?e.project.name:null}catch{return null}}var P=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"];function A(o){let e=process.stderr,s=e.isTTY===!0,a=0,t=o,r,c=()=>e.write(`\r\x1B[2K${n.cyan(P[a])} ${t}`);s?(c(),r=setInterval(()=>{a=(a+1)%P.length,c()},80)):e.write(`- ${t}
3
+ `);let l=(i,u)=>{r&&clearInterval(r),e.write(`${s?"\r\x1B[2K":""}${i} ${u??t}
4
+ `)};return{get text(){return t},set text(i){t=i,s||e.write(`- ${t}
5
+ `)},succeed:i=>l(n.green("\u2714"),i),fail:i=>l(n.red("\u2716"),i),warn:i=>l(n.yellow("\u26A0"),i)}}async function j(o){let{resources:e}=x(o),s=await m(o,{inspectDocker:!1}),{appBase:a}=k(s?.ingressHttp,o);return e.filter(t=>t.config?.appType==="frontend").map(t=>({name:t.name,url:`${a}${$(t)}`}))}async function v(o,e=2e3){try{return(await fetch(o,{signal:AbortSignal.timeout(e)})).status<500}catch{return!1}}async function D(o,e=3e4,s){if(o.length===0)return;let a=Date.now();for(;;){for(let r of o)if(await v(r.url))return r;let t=Date.now()-a;if(t>=e)return;s?.(t),await new Promise(r=>setTimeout(r,2e3))}}async function te(o,e=0,s){let a=await j(o);return D(a,e,s)}async function C(o){let e=o??h();if(!e)return console.log(n.yellow("Not in a Flisk project, so there is no frontend to open.")),console.log(n.gray("Run `flisk project --yes` first, or `flisk open` inside a project.")),null;let s=await j(e);if(s.length===0)return console.log(n.yellow("This project has no frontend service to open.")),console.log(n.gray("Start the stack with `flisk up` and add a frontend with `flisk resource`.")),null;let a=E(e);y(`Opening the first frontend of ${a??"this project"}`);for(let l of s)console.log(n.gray(` - ${l.name}: ${l.url}`));let t=A("Waiting for the frontend to answer..."),r=await D(s,12e4,l=>{t.text=`Waiting for the frontend to answer... ${Math.round(l/1e3)}s`});if(!r){t.fail("No frontend answered yet.");let i=(await m(e,{inspectDocker:!1}))?.ingressHttp,u=i?await T(i)==="in-use":!1;if(i&&!u){console.log(n.yellow(`The stack is running, but this machine cannot reach port ${i}.`)),console.log(n.gray(" Docker is not publishing the port to the host."));let{checkColima:f}=await import("./colima-GBURKN54.js"),p=f();p.isColima&&!p.running?(console.log(n.gray(` ${p.problem??"The Colima VM is not running"}`)),console.log(n.gray(` Fix: ${p.fix??"colima start"}`))):console.log(n.gray(" Restart the Docker runtime (Docker Desktop or Colima), then run `flisk open` again."))}else console.log(n.yellow("The stack is not serving the frontend yet.")),console.log(n.gray(" - Start the stack in another terminal: flisk up")),console.log(n.gray(" - Then run this again: flisk open"));for(let f of s)console.log(n.gray(` - ${f.name}: ${f.url}`));return null}t.succeed(`The frontend is up: ${r.name}`);let c=await b(r.url);return console.log(c?n.green(`
6
+ Opened ${r.url}`):n.yellow(`
7
+ Could not open a browser. Open ${r.url} yourself.`)),w("Run `flisk open` again to open the next frontend."),r.url}var ne=new R("open").description("Open the first frontend of the project in your browser").action(async()=>{await C()});export{J as a,E as b,A as c,j as d,v as e,D as f,te as g,C as h,ne as i};
@@ -0,0 +1,35 @@
1
+ import{createRequire as __fliskRequire}from'node:module';const require=__fliskRequire(import.meta.url);
2
+ import{a as C}from"./chunk-YL56J2WX.js";import{b as N,c as de,d as V,n as D,o as Y,s as J,t as L,v as O}from"./chunk-763VK575.js";import{$ as ie,ea as ae,fa as se,h as T,ha as ce,i as B,ja as le,ka as fe,la as pe,o as h,p as b,q as t,x as re,y as G,z as W}from"./chunk-BWK6MPCB.js";import{N as U,P as z,R as E,b as g,f as x,m as M,o as P,x as F}from"./chunk-VHFFSBVJ.js";import{execFileSync as Se}from"node:child_process";import{cpSync as je,existsSync as S,readdirSync as _e,readFileSync as K,writeFileSync as we}from"node:fs";import{basename as xe,dirname as Pe,isAbsolute as Ee,join as _,resolve as q}from"node:path";import{cwd as he}from"node:process";import{fileURLToPath as Oe}from"node:url";import{Command as Ce}from"commander";var ve="-y, --yes",ye="Skip prompts and confirmations; use defaults";function ue(e,o=ye){return e.option(ve,o,!1)}async function be(e,o=!0){let l=await L({message:e,initial:o});return l||T(),l}function Le(e,o=1){e.valid||E(e.error??"Validation failed",o)}function Ie(e,o,l,s){return e.dryRun?(s?s():(console.log(`Dry run - ${o}`),console.log(`Would run: ${l}`)),!0):!1}async function qe(e,o){return await be(e,!0)?!0:(o&&o(),!1)}var I=new Map;function me(e){e!==void 0?I.delete(e):I.clear()}function Be(e=!1){let o=F(),l=o??"";if(!e){let p=I.get(l);if(p)return p}let{resources:s,problems:f}=o?ae(o):{resources:ce(),problems:[]},u=pe(s),n=fe(s);se(f);let r=s.filter(p=>!p.stack),d=new Map;for(let p of s)if(p.stack){let a=d.get(p.stack)||[];a.push(p),d.set(p.stack,a)}let m={resources:s,problems:f,stacks:u,stackNames:n,unassignedResources:r,resourcesByStack:d};return I.set(l,m),m}var A={proxy:{name:"proxy",description:"Traefik reverse proxy and API gateway for routing all services",category:"core",phase:"pre_alpha",enabled_by_default:!0,dependsOn:[]},verdaccio:{name:"verdaccio",description:"Verdaccio npm registry for package management and local publishing (Premium - requires FLISK_LICENSE_KEY)",category:"premium",phase:"pre_alpha",enabled_by_default:!1,dependsOn:[]},[x]:{name:x,description:"PostgreSQL database for data persistence and SQL operations",category:"core",phase:"pre_alpha",enabled_by_default:!0,dependsOn:[]},monitoring:{name:"monitoring",description:"SigNoz or SkyWalking observability platform for monitoring and tracing",category:"optional",phase:"pre_alpha",enabled_by_default:!1,dependsOn:[x]},elk:{name:"elk",description:"Elasticsearch, Logstash, Kibana stack for log aggregation and analysis",category:"optional",phase:"pre_alpha",enabled_by_default:!1,dependsOn:[]},debezium:{name:"debezium",description:"Change Data Capture for real-time data streaming from databases",category:"optional",phase:"pre_alpha",enabled_by_default:!1,dependsOn:[x]},"golden-image":{name:"golden-image",description:"Pre-built Docker image layer for faster builds and smaller deployments",category:"optional",phase:"pre_alpha",enabled_by_default:!0,dependsOn:[]}};function H(e,o){try{return le(e,o)}catch{return[]}}function Ae(e){return new Set([...e.phases.pre_alpha.enabledStacks,...e.phases.alpha.enabledStacks,...e.phases.beta.enabledStacks,...e.phases.out_of_scope.enabledStacks])}function Q(e,o){let l=Ae(e),s=o.filter(f=>!l.has(f));return s.length===0?(e.phases.pre_alpha.enabledStacks=Array.from(new Set(e.phases.pre_alpha.enabledStacks)),[]):(e.phases.pre_alpha.enabledStacks=Array.from(new Set([...e.phases.pre_alpha.enabledStacks,...s])),s)}function gt(e,o){let l=_(e,".flisk",M);if(!S(l))return[];let s=D(e),f=Q(s,H(e,o));return f.length>0&&N(l,s),f}function $e(){return Object.values(A).filter(e=>e.enabled_by_default&&e.category==="core").map(e=>e.name)}function Re(e,o){return o||(C[e]?.repo.split("/").pop()??e).replace(/\.git$/,"")}function ge(e){return e.split(`
3
+ `).map(l=>l.trim()).filter(Boolean).pop()??"unknown error"}async function Fe(e,o,l,s={}){let f=C[e];if(!f){console.log(g.red(`
4
+ \u274C Unknown template: "${e}"`)),console.log(g.yellow(`
5
+ Available templates:`));for(let[r,d]of Object.entries(C))console.log(` ${g.cyan(r)} ${g.gray(`- ${d.description}`)}`);console.log(g.gray("\nOr run `flisk project` with no template for a blank project.")),process.exit(1)}let u=Re(e,o);ie(u)||U.invalidPath(u).exit();let n=Ee(u)?u:q(he(),u);S(n)&&_e(n).length>0&&U.directoryExists(n).exit(),s.quiet||(B(`Cloning template: ${e}`),t(`${f.description}
6
+ `,0),t(`Source: ${f.bundledPath?"bundled Flisk example":f.repo}`,0),t(`Destination: ${n}
7
+ `,0));try{if(f.bundledPath){let r=q(Pe(Oe(new URL("../dist/commands/project.js",import.meta.url).href)),"../../../");je(q(r,f.bundledPath),n,{recursive:!0});let d=xe(n).replace(/-/g,"_");for(let m of["services/platform/messaging/docker-compose.yml","services/shop/orders-api/service.json","services/shop/orders-api/src/index.ts","services/shop/orders-worker/service.json","services/shop/orders-worker/src/index.ts"]){let p=_(n,m),a=K(p,"utf-8");we(p,a.replaceAll("flisk_example",d))}}else Se("git",["clone",f.repo,n],{stdio:["ignore","pipe","pipe"],encoding:"utf-8"})}catch(r){let d=r instanceof Error?r.message:String(r),m=f.bundledPath?`Bundled example copy failed (${ge(d)}). Reinstall the Flisk CLI package and try again.`:`git clone failed: ${ge(d)}. Check you have git installed and network access.`;if(s.quiet)throw new Error(m);E(m)}if(me(),!s.quiet){console.log(g.green(`
8
+ \u2705 Cloned "${e}" into ${u}/`)),t(`
9
+ Next steps:`,0),t(`1. cd ${u}`),t("2. flisk doctor # check Docker/Tilt are ready"),t("3. flisk up # start the stack"),t(`
10
+ Runtime readiness:`,0);for(let r of l)t(r,0)}}var $={version:"1.0",project:{name:"",version:"1.0.0"},phases:{pre_alpha:{name:"Pre-Alpha",description:"Core infrastructure and MVP services",enabledStacks:$e()},alpha:{name:"Alpha",description:"Essential business services",enabledStacks:[]},beta:{name:"Beta",description:"Extended features",enabledStacks:[]},out_of_scope:{name:"Out of Scope",description:"Future releases",enabledStacks:[]}},optional_infra:{monitoring:!1,elk:!1,debezium:!1,golden_image:!0,verdaccio:!1},discovery:{paths:["services/*/*"]},overrides:{}},ht=ue(new Ce("project")).description("Initialize or validate project-level master configuration").argument("[template]",`Clone a starter example instead of a blank project (${Object.keys(C).join(", ")})`).option("--path <dir>","Directory to clone the template into (default: the template's repo name)").option("--check","Check if master configs exist and are in sync").option("--force","Overwrite existing configuration (dangerous)").option("--config-file <path>","Load project config from existing JSON file").option("-q, --quiet","Only print what fails; used by `flisk demo`",!1).action(async(e,o)=>{let{assertMachineReadyOrExit:l,detectRuntimePrerequisites:s,formatRuntimeNextSteps:f}=await import("./cold-preflight-ABU26DYW.js");await l({scope:"scaffold"});let u=f(s()),n=!!o.quiet;if(e){await z(async()=>Fe(e,o.path,u,{quiet:n}));return}await z(async()=>{let r=F();r||(r=he(),n||(b(`\u{1F680} Initializing new Flisk project...
11
+ `),t(`Location: ${r}
12
+ `,0)));let d=_(r,".flisk"),m=_(d,M);if(o.check){let c=P.every(k=>S(_(r,".flisk",".flisk-out",k))),v=S(m);if(c&&v){let k=D(r);h("Project configuration is valid"),t(`Project: ${k.project.name}`,3),t(`Phases: ${Object.keys(k.phases).join(", ")}`,3),process.exit(0)}else{if(console.log(g.yellow("\u26A0\uFE0F Project configuration incomplete:")),v||t(".flisk/project.json (not found)",3),!c)for(let k of P.filter(j=>!S(_(r,".flisk/.flisk-out",j))))t(`.flisk/.flisk-out/${k} (not found)`,3);t("Run `flisk project` to create them."),process.exit(1)}}n||(B("Project Configuration"),t(`Project root: ${r}
13
+ `,0)),S(d)||(de(d),n||h("Created: .flisk/ directory"));let p=S(m);if(p&&!o.force){n||h(".flisk/project.json exists");let c=JSON.parse(K(m,"utf-8")),v=D(r),k=H(r),j=Q(v,k);if((j.length>0||!c.phases)&&N(m,v),j.length>0&&!n&&t(`Auto-enabled discovered service stacks: ${j.join(", ")}`,0),n||b(`
14
+ \u{1F4CB} Regenerating master configuration files...
15
+ `),await Y(r,{quiet:n}),W(r))n||h("Created: .env (the defaults work as-is)");else{let y=G(r);y.length>0&&!n&&h(`Updated: .env (added ${y.join(", ")}; existing values unchanged)`)}let R=V(r);if(R.length>0&&!n&&h(`Added to .gitignore: ${R.join(", ")}`),!n){console.log(g.green(`
16
+ \u2705 Project configuration regenerated!`)),t(`
17
+ Generated in .flisk/.flisk-out/:`,0);for(let y of P)t(`- ${y}`);t(`
18
+ Runtime readiness:`,0);for(let y of u)t(y,0)}return}if(p&&o.force&&!o.yes&&(console.log(g.red(`
19
+ \u26A0\uFE0F WARNING: --force will overwrite .flisk/project.json!`)),!await L({message:"This will reset your project configuration. Continue?",initial:!1}))){T();return}let a,X=H(r);if(o.configFile){let c=q(o.configFile);S(c)||E(`Config file not found: ${c}`);let v=K(c,"utf-8");a=JSON.parse(v),n||h(`Loaded config from: ${c}`)}else if(o.yes)a=JSON.parse(JSON.stringify($)),a.project.name=r.split("/").pop()||"my-project",n||console.log(g.gray("Using default configuration (non-interactive mode)"));else{b(`\u{1F4DD} Project Setup Wizard
20
+ `);let c=await J({message:"Project name:",initial:r.split("/").pop()||"my-project",validate:i=>i.trim()!==""||"Project name is required"}),v=await J({message:"Project version:",initial:"1.0.0-alpha"}),k=Object.values(A).filter(i=>i.category==="core"&&i.phase==="pre_alpha"),j=new Set(k.map(i=>i.name)),oe=await O({message:"Select Pre-Alpha enabled stacks (core infrastructure):",choices:[...k.map(i=>({title:i.description,value:i.name,selected:i.enabled_by_default})),...X.filter(i=>!j.has(i)).map(i=>({title:`${i} (discovered service stack)`,value:i,selected:!0}))]}),R=await O({message:"Select Alpha enabled stacks (core business):",choices:[{title:"api (Backend API)",value:"api"},{title:"app (Frontend app)",value:"app"}]}),y=await O({message:"Select Beta enabled stacks (extended features):",choices:[{title:"worker (Background jobs)",value:"worker"},{title:"migrator (Database migrations)",value:"migrator"}]}),w=await O({message:"Enable optional infrastructure (high resource):",choices:Object.values(A).filter(i=>i.category==="optional").concat(Object.values(A).filter(i=>i.category==="premium")).map(i=>({title:i.description,value:i.name,selected:i.enabled_by_default}))});b(`
21
+ \u{1F4C2} Service discovery`),t("What: folder patterns Flisk scans for a service.json in each match."),t("Where: type one or more globs, comma-separated."),t("How: saved as discovery.paths in .flisk/project.json - editable later."),t(`Example: ${$.discovery.paths.join(", ")}
22
+ `);let ke=await J({message:"Folders to scan:",initial:$.discovery.paths.join(", ")});a=JSON.parse(JSON.stringify($)),a.project.name=c,a.project.version=v,a.phases.pre_alpha.enabledStacks=Array.from(new Set(oe)),a.phases.alpha.enabledStacks=Array.from(new Set(R)),a.phases.beta.enabledStacks=Array.from(new Set(y)),a.optional_infra.monitoring=w.includes("monitoring"),a.optional_infra.elk=w.includes("elk"),a.optional_infra.debezium=w.includes("debezium"),a.optional_infra.golden_image=w.includes("golden_image"),a.optional_infra.verdaccio=w.includes("verdaccio");let ne=ke.split(",").map(i=>i.trim()).filter(i=>i.length>0);a.discovery.paths=ne.length>0?ne:$.discovery.paths}let Z=Q(a,X);if(Z.length>0&&!n&&t(`Auto-enabled discovered service stacks: ${Z.join(", ")}`,0),n||b(`
23
+ \u{1F4CB} Creating project configuration...
24
+ `),N(m,a),n||(h("Created: .flisk/project.json"),t(`\u2192 Project: ${a.project.name}`),b(`
25
+ \u{1F4CB} Generating master configuration files...
26
+ `)),await Y(r,{quiet:n}),n||b(`
27
+ \u{1F527} Setting up environment variables...
28
+ `),W(r))n||h("Created: .env (the defaults work as-is)");else{let c=G(r);c.length>0?n||h(`Updated: .env (added ${c.join(", ")}; existing values unchanged)`):n||h("Found: .env (environment already configured)")}let ee=re(r);if(ee.missing.length>0){console.log(g.yellow(`
29
+ \u26A0\uFE0F Missing required environment variables:`));for(let c of ee.missing)t(`- ${c}`,1);t("\u2192 Edit .env and fill in these values before running `flisk up`",1)}let te=V(r);if(te.length>0&&!n&&h(`Added to .gitignore: ${te.join(", ")}`),!n){console.log(g.green(`
30
+ \u2705 Project configuration complete!`)),t(`
31
+ Generated files in .flisk/.flisk-out/:`,0);for(let c of P)t(`- ${c}`);t(`
32
+ Environment configuration:`,0),t("- .env (contains all required variables)"),t(`
33
+ Source file:`,0),t("- .flisk/project.json (edit this to change project structure)"),t(`
34
+ Next steps:`,0),t("1. flisk resource api --type backend --stack app # scaffold a service"),t("2. flisk up app # start it"),t(`
35
+ Runtime readiness:`,0);for(let c of u)t(c,0);t("\nAfter editing .flisk/project.json, run `flisk config regenerate`.",0)}})});export{me as a,Be as b,ue as c,Le as d,Ie as e,qe as f,gt as g,Re as h,Fe as i,ht as j};
@@ -0,0 +1,3 @@
1
+ import{createRequire as __fliskRequire}from'node:module';const require=__fliskRequire(import.meta.url);
2
+ import{randomUUID as F}from"node:crypto";import{existsSync as p,mkdirSync as g,readFileSync as y,statSync as M,writeFileSync as h}from"node:fs";import{homedir as P}from"node:os";import{join as a}from"node:path";import{spawnSync as _}from"node:child_process";import{existsSync as N,mkdirSync as w,mkdtempSync as C,readdirSync as $,renameSync as L,rmSync as v,statSync as j,writeFileSync as O}from"node:fs";import{tmpdir as D}from"node:os";import{join as c}from"node:path";function S(e,n){let r=C(c(D(),"flisk-ext-")),o=c(r,"bundle.tar.gz");O(o,e),w(n,{recursive:!0});let t=process.platform==="win32"?"tar.exe":"tar",i=_(t,["xzf",o,"-C",n,"--strip-components=1"],{stdio:"pipe",windowsHide:!0});if(i.status!==0){let s=c(r,"fallback");w(s,{recursive:!0});let f=_(t,["xzf",o,"-C",s],{stdio:"pipe",windowsHide:!0});if(f.status!==0)throw v(r,{recursive:!0,force:!0}),new Error(`tar extraction failed: ${f.stderr?.toString()||i.stderr?.toString()||"unknown error"}`);let l=$(s),[u]=l,m=l.length===1&&u!==void 0&&N(c(s,u))&&j(c(s,u)).isDirectory()?c(s,u):s;for(let d of $(m))L(c(m,d),c(n,d))}v(r,{recursive:!0,force:!0})}var U="https://tdk-extension-dist.oranguman.workers.dev/v1/premium/bundle.tar.gz",A=["playwright","c4-diagram","logging","agents-md","sablier","verdaccio"],z=720*60*1e3,k={"typescript/playwright_config.star":"engine/topologies/tilt/generators/typescript/playwright_config.star","generators/agents_md.star":"engine/topologies/tilt/generators/agents_md.star","c4_diagram.star":"engine/topologies/tilt/generators/c4_diagram.star","observability/logging.star":"engine/topologies/platform/observability/logging.star","generators/database_provisioner.star":"engine/topologies/tilt/generators/database_provisioner.star","generators/dependency_manifest.star":"engine/topologies/tilt/generators/dependency_manifest.star","generators/fixed_frontend_tsconfig.star":"engine/topologies/tilt/generators/typescript/fixed_frontend_tsconfig.star","synthetic_monitor.star":"engine/resources/synthetic_monitor.star","synthetic-monitor-topology.star":"engine/topologies/platform/services/synthetic-monitor.star","database-management-service.yaml":"platform/services/platform/database-management/service.yaml","networking/sablier_container_cycle.star":"engine/topologies/platform/docker/networking/sablier_container_cycle.star","registries/verdaccio_loader.star":"engine/topologies/platform/registries/verdaccio_loader.star"};function I(){return process.env.FLISK_LICENSE_KEY?.trim()||null}function R(){return process.env.FLISK_PREMIUM_ENDPOINT?.trim()||U}function x(e){let n=a(e,".flisk",".project-id");if(p(n))return y(n,"utf-8").trim();let r=F();return g(a(e,".flisk"),{recursive:!0}),h(n,`${r}
3
+ `),r}function B(e){let n=e.replace(/[^a-zA-Z0-9_-]/g,"_");return a(P(),".flisk","cache",`premium-${n}`,"premium.tar.gz")}function T(e){return p(e)?Date.now()-M(e).mtimeMs<z:!1}async function E(e,n,r){let o=`${R()}?resource=${encodeURIComponent(n)}&projectId=${encodeURIComponent(r)}`,t=await fetch(o,{headers:{Authorization:`Bearer ${e}`}});return t.status!==401?t:(await t.arrayBuffer().catch(()=>{}),fetch(`${o}&key=${encodeURIComponent(e)}`))}async function H(e,n){let r=[];for(let o of A){let t;try{t=await E(e,o,n)}catch(i){return console.warn(`\u26A0\uFE0F Premium fetch failed (network error): ${i.message}`),null}if(t.ok){let i=Buffer.from(await t.arrayBuffer());return console.info(`\u{1F50E} Premium entitlement probe: granted resource=${o} (HTTP ${t.status}); prior denials=${r.join(", ")||"none"}`),console.info(`\u{1F50E} Premium bundle download: ${i.byteLength} bytes`),i}if(t.status===401||t.status===403){r.push(`${o}=${t.status}`);continue}return console.warn(`\u26A0\uFE0F Premium fetch failed: ${o} returned HTTP ${t.status}; prior entitlement probes: ${r.join(", ")||"none"}`),null}return console.warn(`\u26A0\uFE0F Premium entitlement probes denied: ${r.join(", ")}`),null}async function re(e,n){let r=I();if(!r)return!1;let o=B(r);if(T(o))console.info("\u{1F50E} Premium bundle cache: hit (cached bundle reused)");else{console.info("\u{1F50E} Premium bundle cache: miss; requesting bundle from distribution service");let t=x(e),i=await H(r,t);if(!i)return console.warn("\u26A0\uFE0F No premium resources unlocked for this key - using free tier only."),!1;g(a(o,".."),{recursive:!0}),h(o,i)}try{let t=a(o,"..","extracted");g(t,{recursive:!0}),S(y(o),t);let i=0,s=[];for(let[l,u]of Object.entries(k)){let m=a(t,l);if(!p(m)){s.push(l);continue}let d=a(n,u);g(a(d,".."),{recursive:!0}),h(d,y(m)),i++}let f=a(t,"networking/sablier_container_cycle.star");if(console.info(`\u{1F50E} Premium bundle contents: mapped=${i}/${Object.keys(k).length}; sablier_overlay=${p(f)?"present":"MISSING"}`),s.length>0&&console.info(`\u{1F50E} Premium bundle missing mapped files: ${s.join(", ")}`),!p(f)&&process.env.FLISK_PREMIUM_DIAGNOSTICS==="1"){let l=await G(e);console.info(`\u{1F50E} Sablier entitlement check: ${l?"granted":"not confirmed"}; compare with sablier_overlay above to distinguish license access from bundle contents`)}return i>0?(console.log(`\u2713 Premium resources unlocked (${i} file${i===1?"":"s"})`),!0):!1}catch(t){return console.warn(`\u26A0\uFE0F Failed to apply premium overlay: ${t.message}`),!1}}function K(e,n){let r=e.replace(/[^a-zA-Z0-9_-]/g,"_");return a(P(),".flisk","cache",`premium-${r}`,`${n}-access.json`)}async function b(e,n){let r=I();if(!r)return!1;let o=K(r,n);if(T(o))try{let s=JSON.parse(y(o,"utf-8"));return console.info(`\u{1F50E} ${n} entitlement probe: cache=${s.granted===!0?"granted":"denied"}`),s.granted===!0}catch{}let t=x(e),i=!1;try{let s=await E(r,n,t);i=s.ok,console.info(`\u{1F50E} ${n} entitlement probe: HTTP ${s.status} (${i?"granted":"denied"})`),s.body&&await s.arrayBuffer().catch(()=>{})}catch(s){return console.warn(`\u26A0\uFE0F ${n} license check failed (network error): ${s.message}`),!1}try{g(a(o,".."),{recursive:!0}),h(o,JSON.stringify({granted:i,checked:new Date().toISOString()}))}catch{}return i}async function ne(e){return b(e,"verdaccio")}async function oe(e){return b(e,"ddd")}async function G(e){return b(e,"sablier")}export{S as a,re as b,ne as c,oe as d,G as e};
@@ -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
  var g=Object.create;var e=Object.defineProperty;var h=Object.getOwnPropertyDescriptor;var i=Object.getOwnPropertyNames;var j=Object.getPrototypeOf,k=Object.prototype.hasOwnProperty;var m=(a=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(a,{get:(b,c)=>(typeof require<"u"?require:b)[c]}):a)(function(a){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+a+'" is not supported')});var n=(a,b)=>()=>{try{return b||a((b={exports:{}}).exports,b),b.exports}catch(c){throw b=0,c}},o=(a,b)=>{for(var c in b)e(a,c,{get:b[c],enumerable:!0})},l=(a,b,c,f)=>{if(b&&typeof b=="object"||typeof b=="function")for(let d of i(b))!k.call(a,d)&&d!==c&&e(a,d,{get:()=>b[d],enumerable:!(f=h(b,d))||f.enumerable});return a};var p=(a,b,c)=>(c=a!=null?g(j(a)):{},l(b||!a||!a.__esModule?e(c,"default",{value:a,enumerable:!0}):c,a));export{m as a,n as b,o as c,p as d};
@@ -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{spawn as c}from"node:child_process";function d(n){try{let o=new URL(n);return o.protocol==="http:"||o.protocol==="https:"}catch{return!1}}function f(n,o=process.platform,s=c){if(!d(n))return Promise.resolve(!1);let t,r;return o==="darwin"?(t="open",r=[n]):o==="win32"?(t="rundll32.exe",r=["url.dll,FileProtocolHandler",n]):(t="xdg-open",r=[n]),new Promise(i=>{try{let e=s(t,r,{stdio:"ignore",detached:!0,windowsHide:!0});e.once("error",()=>i(!1)),e.once("spawn",()=>{typeof e.unref=="function"&&e.unref(),i(!0)})}catch{i(!1)}})}function a(n,o=process.platform,s=c){return new Promise(t=>{let r,i;o==="darwin"?(r="pbcopy",i=[]):o==="win32"?(r="clip",i=[]):(r="xclip",i=["-selection","clipboard"]);try{let e=s(r,i,{stdio:["pipe","ignore","ignore"],windowsHide:!0});e.on("error",()=>{t(!1)}),e.on("close",l=>{t(l===0)}),e.stdin?(e.stdin.on("error",()=>{t(!1)}),e.stdin.write(n,"utf-8"),e.stdin.end()):t(!1)}catch{t(!1)}})}export{d as a,f as b,a as c};
@@ -1,2 +1,2 @@
1
- import{createRequire as __tdkRequire}from'node:module';const require=__tdkRequire(import.meta.url);
2
- import{r as c}from"./chunk-5LRMAY67.js";import{execFileSync as u}from"node:child_process";import{realpathSync as l}from"node:fs";import{resolve as p}from"node:path";var m=(o,t)=>u(o,t,{encoding:"utf-8",stdio:"pipe",timeout:5e3,windowsHide:!0});function a(o,t=process.platform,e=m){if(t==="win32")return null;try{let s=e("lsof",["-nP",`-iTCP:${o}`,"-sTCP:LISTEN","-t"]).split(/\r?\n/).map(r=>r.trim()).filter(Boolean);for(let r of s){let n=e("ps",["-p",r,"-o","command="]).trim(),[i]=c(`${r} ${n}`);if(i)return i}}catch{}return null}function f(o){try{return l(o)}catch{return p(o)}}function d(o,t){return o!==null&&f(o.root)!==f(t)}async function P(o,t,e,s=a){let r={running:[],foreign:[]};for(let n of o){if(!await e(n))continue;let i=s(n);i&&d(i,t)?r.foreign.push({port:n,root:i.root}):r.running.push(n)}return r}export{a,d as b,P as c};
1
+ import{createRequire as __fliskRequire}from'node:module';const require=__fliskRequire(import.meta.url);
2
+ import{r as c}from"./chunk-B6Q5VKL7.js";import{execFileSync as u}from"node:child_process";import{realpathSync as l}from"node:fs";import{resolve as p}from"node:path";var m=(o,t)=>u(o,t,{encoding:"utf-8",stdio:"pipe",timeout:5e3,windowsHide:!0});function a(o,t=process.platform,e=m){if(t==="win32")return null;try{let s=e("lsof",["-nP",`-iTCP:${o}`,"-sTCP:LISTEN","-t"]).split(/\r?\n/).map(r=>r.trim()).filter(Boolean);for(let r of s){let n=e("ps",["-p",r,"-o","command="]).trim(),[i]=c(`${r} ${n}`);if(i)return i}}catch{}return null}function f(o){try{return l(o)}catch{return p(o)}}function d(o,t){return o!==null&&f(o.root)!==f(t)}async function P(o,t,e,s=a){let r={running:[],foreign:[]};for(let n of o){if(!await e(n))continue;let i=s(n);i&&d(i,t)?r.foreign.push({port:n,root:i.root}):r.running.push(n)}return r}export{a,d as b,P as c};
@@ -0,0 +1,2 @@
1
+ import{createRequire as __fliskRequire}from'node:module';const require=__fliskRequire(import.meta.url);
2
+ import{a as A}from"./chunk-5EZ4EX6U.js";import{ga as _}from"./chunk-BWK6MPCB.js";import{f as u,m as S}from"./chunk-VHFFSBVJ.js";import{existsSync as w,readFileSync as h}from"node:fs";import{join as i}from"node:path";var O=["postgres",u],y=["pre_alpha","alpha","beta","out_of_scope"];function D(e){return O.includes(e)}function b(e){try{return JSON.parse(h(i(e,".flisk",S),"utf-8"))}catch{return}}function l(e){try{return w(e)?h(e,"utf-8"):void 0}catch{return}}function k(e,n){let s=r=>{let t=r;for(;t<e.length&&/\s/.test(e[t]);)t+=1;return t},a=0;for(;;){let r=e.indexOf(n,a);if(r===-1)return;let t=s(r+n.length);if(e[t]==="="&&(t=s(t+1),e[t]==="[")){let o=e.indexOf("]",t+1);return o===-1?void 0:[...e.slice(t+1,o).matchAll(/"([^"]+)"|'([^']+)'/g)].map(f=>f[1]??f[2]??"")}a=r+n.length}}function N(e){let n=i(e,".flisk",".flisk-out","Tiltfile"),s=l(n);if(s)return k(s,"ALWAYS_ENABLED_INFRA")}function M(e){let n=i(e,".flisk",".flisk-out","spec.master"),s=l(n);if(s!==void 0)return/"database-management"\s*:\s*True/.test(s)}function x(e){let n=i(e,".flisk",".flisk-out"),s=l(i(n,"Tiltfile")),a=l(i(n,"spec.master")),r=l(i(n,"flisk-cli-ext","discovery","config.star")),t=l(i(n,"flisk-cli-ext","engine","topologies","tilt","config","profiles.star"));if(!s||!a||!r||!t)return!1;let o=a.match(/PRE_ALPHA_RESOURCES\s*=\s*\{([^}]*)\}/)?.[1],f=k(r,"CORE_INFRA");return/FOCUS_MODE\s*,\s*FOCUS_ENABLED_ALL\s*,\s*FOCUS_ENABLED_RESOURCES\s*=\s*Config\.apply_focus\(cfg\)/.test(s)&&/if FOCUS_MODE and FOCUS_ENABLED_ALL\s*:/.test(s)&&/"[^"]+"\s*:\s*True|'[^']+'\s*:\s*True/.test(o??"")&&(f?.includes("postgres")??!1)&&/["']postgres["']\s*:\s*["']database-management["']/.test(r)&&/for infra in CORE_INFRA_EXPORT\s*:/.test(t)&&/needed\[INFRA_STACK_MAP_EXPORT\[infra\]\]\s*=\s*True/.test(t)}function C(e){let n=b(e);if(!n)return!1;let s=n.phases??{};for(let r of y){let t=s[r]?.enabledStacks;if(Array.isArray(t)&&t.includes(u))return!0}let a=n.always_enabled_infra??A;return Array.isArray(a)&&a.includes(u)}function L(e,n){let s=new Set;for(let t of O)s.add(t);for(let t of n)s.add(t.name),t.stack&&s.add(t.stack);let a=b(e);if(a){let t=a.phases??{};for(let f of y){let d=t[f]?.enabledStacks;if(Array.isArray(d))for(let c of d)s.add(c)}let o=a.always_enabled_infra??A;if(Array.isArray(o))for(let f of o)s.add(f)}let r=N(e);if(Array.isArray(r))for(let t of r)s.add(t);return s}function $(e,n=_(e)){let s=C(e),a=N(e),r=Array.isArray(a)&&a.includes(u),t=M(e)===!0,o=s||r||t,f=!s&&x(e),d=L(e,n),c=[],E=[];for(let p of n){let P=p.config?.dependsOn??[],g=!1;for(let m of P){if(D(m)){g=!0;continue}d.has(m)||E.push({resource:p.name,name:m})}g&&c.push(p.name)}let T=o||c.length>0,F=o?"feature":c.length>0?"dependsOn":"none";return{featureOn:o,featureOnFromProjectJson:s,featureOnFromTiltfile:r,featureOnFromSpecMaster:t,focusWouldEnableDatabaseManagement:f,dependsOnUsers:c,willStart:T,reason:F,unknownDependsOnNames:E}}export{O as a,$ as b};
@@ -0,0 +1,10 @@
1
+ import{createRequire as __fliskRequire}from'node:module';const require=__fliskRequire(import.meta.url);
2
+ function G(e,t,r){let o=e.indexOf(t);if(o===-1)return e;let n=t.length,s=0,i="";do i+=e.slice(s,o)+t+r,s=o+n,o=e.indexOf(t,s);while(o!==-1);return i+=e.slice(s),i}function V(e,t,r,o){let n=0,s="";do{let i=e[o-1]==="\r";s+=e.slice(n,i?o-1:o)+t+(i?`\r
3
+ `:`
4
+ `)+r,n=o+1,o=e.indexOf(`
5
+ `,n)}while(o!==-1);return s+=e.slice(n),s}var Y=(e=0)=>t=>`\x1B[${t+e}m`,S=(e=0)=>t=>`\x1B[${38+e};5;${t}m`,I=(e=0)=>(t,r,o)=>`\x1B[${38+e};2;${t};${r};${o}m`,he=e=>`\x1B[58;5;${e<90?e-30:e-90+8}m`,l={modifier:{reset:[0,0],bold:[1,22],dim:[2,22],italic:[3,23],underline:[4,24],underlineDouble:["4:2",24],underlineCurly:["4:3",24],underlineDotted:["4:4",24],underlineDashed:["4:5",24],overline:[53,55],inverse:[7,27],hidden:[8,28],strikethrough:[9,29]},color:{black:[30,39],red:[31,39],green:[32,39],yellow:[33,39],blue:[34,39],magenta:[35,39],cyan:[36,39],white:[37,39],blackBright:[90,39],gray:[90,39],grey:[90,39],redBright:[91,39],greenBright:[92,39],yellowBright:[93,39],blueBright:[94,39],magentaBright:[95,39],cyanBright:[96,39],whiteBright:[97,39]},bgColor:{bgBlack:[40,49],bgRed:[41,49],bgGreen:[42,49],bgYellow:[43,49],bgBlue:[44,49],bgMagenta:[45,49],bgCyan:[46,49],bgWhite:[47,49],bgBlackBright:[100,49],bgGray:[100,49],bgGrey:[100,49],bgRedBright:[101,49],bgGreenBright:[102,49],bgYellowBright:[103,49],bgBlueBright:[104,49],bgMagentaBright:[105,49],bgCyanBright:[106,49],bgWhiteBright:[107,49]},underlineColor:{underlineBlack:["58;5;0",59],underlineRed:["58;5;1",59],underlineGreen:["58;5;2",59],underlineYellow:["58;5;3",59],underlineBlue:["58;5;4",59],underlineMagenta:["58;5;5",59],underlineCyan:["58;5;6",59],underlineWhite:["58;5;7",59],underlineBlackBright:["58;5;8",59],underlineGray:["58;5;8",59],underlineGrey:["58;5;8",59],underlineRedBright:["58;5;9",59],underlineGreenBright:["58;5;10",59],underlineYellowBright:["58;5;11",59],underlineBlueBright:["58;5;12",59],underlineMagentaBright:["58;5;13",59],underlineCyanBright:["58;5;14",59],underlineWhiteBright:["58;5;15",59]}},K=Object.keys(l.modifier),_=Object.keys(l.color),N=Object.keys(l.bgColor),ge=Object.keys(l.underlineColor),H=[..._,...N];function be(){let e=new Map;for(let[t,r]of Object.entries(l)){for(let[o,n]of Object.entries(r))l[o]={open:`\x1B[${n[0]}m`,close:`\x1B[${n[1]}m`},r[o]=l[o],e.set(Number.parseInt(n[0],10),n[1]);Object.defineProperty(l,t,{value:r,enumerable:!1})}return Object.defineProperty(l,"codes",{value:e,enumerable:!1}),l.color.close="\x1B[39m",l.bgColor.close="\x1B[49m",l.underlineColor.close="\x1B[59m",l.color.ansi=Y(),l.color.ansi256=S(),l.color.ansi16m=I(),l.bgColor.ansi=Y(10),l.bgColor.ansi256=S(10),l.bgColor.ansi16m=I(10),l.underlineColor.ansi=he,l.underlineColor.ansi256=S(20),l.underlineColor.ansi16m=I(20),Object.defineProperties(l,{rgbToAnsi256:{value(t,r,o){return t===r&&r===o?t<8?16:t>248?231:Math.round((t-8)/247*24)+232:16+36*Math.round(t/255*5)+6*Math.round(r/255*5)+Math.round(o/255*5)},enumerable:!1},hexToRgb:{value(t){let r=/[\da-f]{6}|[\da-f]{3}/i.exec(t.toString(16));if(!r)return[0,0,0];let[o]=r;o.length===3&&(o=[...o].map(s=>s+s).join(""));let n=Number.parseInt(o,16);return[n>>16&255,n>>8&255,n&255]},enumerable:!1},hexToAnsi256:{value:t=>l.rgbToAnsi256(...l.hexToRgb(t)),enumerable:!1},ansi256ToAnsi:{value(t){if(t<8)return 30+t;if(t<16)return 90+(t-8);let r,o,n;if(t>=232)r=((t-232)*10+8)/255,o=r,n=r;else{t-=16;let a=t%36;r=Math.floor(t/36)/5,o=Math.floor(a/6)/5,n=a%6/5}let s=Math.max(r,o,n)*2;if(s===0)return 30;let i=30+(Math.round(n)<<2|Math.round(o)<<1|Math.round(r));return s===2&&(i+=60),i},enumerable:!1},rgbToAnsi:{value:(t,r,o)=>l.ansi256ToAnsi(l.rgbToAnsi256(t,r,o)),enumerable:!1},hexToAnsi:{value:t=>l.ansi256ToAnsi(l.hexToAnsi256(t)),enumerable:!1}}),l}var xe=be(),m=xe;import j from"node:process";import Ee from"node:os";import W from"node:tty";function d(e,t=globalThis.Deno?globalThis.Deno.args:j.argv){let r=e.startsWith("-")?"":e.length===1?"-":"--",o=t.indexOf(r+e),n=t.indexOf("--");return o!==-1&&(n===-1||o<n)}var{env:c}=j,R;d("no-color")||d("no-colors")||d("color=false")||d("color=never")?R=0:(d("color")||d("colors")||d("color=true")||d("color=always"))&&(R=1);function z(){return/^\d+$/.test(c.FORCE_COLOR)}function Te(){if("FORCE_COLOR"in c){if(c.FORCE_COLOR==="false")return 0;if(c.FORCE_COLOR==="true"||c.FORCE_COLOR.length===0)return 1;if(z())return Math.min(Number.parseInt(c.FORCE_COLOR,10),3)}}function Ce(e){return e===0?!1:{level:e,hasBasic:!0,has256:e>=2,has16m:e>=3}}function Re(e,{streamIsTTY:t,sniffFlags:r=!0}={}){let o=Te();o!==void 0&&(R=o);let n=r?R:o;if(n===0)return 0;if(r){if(d("color=16m")||d("color=full")||d("color=truecolor"))return 3;if(d("color=256"))return 2}if(n!==void 0&&z())return n;if("TF_BUILD"in c&&"AGENT_NAME"in c)return 1;if(e&&!t&&n===void 0)return 0;let s=n||0;if(c.TERM==="dumb")return s;if(j.platform==="win32"){let i=Ee.release().split(".");return Number(i[0])>=10&&Number(i[2])>=10586?Number(i[2])>=14931?3:2:1}if("CI"in c)return["GITHUB_ACTIONS","GITEA_ACTIONS","CIRCLECI"].some(i=>i in c)?3:["TRAVIS","APPVEYOR","GITLAB_CI","BUILDKITE","DRONE"].some(i=>i in c)||c.CI_NAME==="codeship"?1:s;if("TEAMCITY_VERSION"in c)return/^(?:9\.0*[1-9]\d*\.|\d{2,}\.)/.test(c.TEAMCITY_VERSION)?1:0;if(c.COLORTERM==="truecolor"||c.TERM==="xterm-kitty"||c.TERM==="xterm-ghostty"||c.TERM==="wezterm")return 3;if("TERM_PROGRAM"in c){let i=Number.parseInt((c.TERM_PROGRAM_VERSION||"").split(".",1)[0],10);switch(c.TERM_PROGRAM){case"iTerm.app":return i>=3?3:2;case"Apple_Terminal":return 2}}return/-256(?:color)?$/i.test(c.TERM)?2:/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(c.TERM)||"COLORTERM"in c?1:s}function J(e,t={}){let r=Re(e,{streamIsTTY:e&&e.isTTY,...t});return Ce(r)}var ke={stdout:J({isTTY:W.isatty(1)}),stderr:J({isTTY:W.isatty(2)})},X=ke;var{stdout:q,stderr:Q}=X,b=Symbol("GENERATOR"),x=Symbol("STYLER"),y=Symbol("IS_EMPTY"),k=Symbol("LEVEL"),E=Object.create(null),Z=e=>{if(!Number.isSafeInteger(e)||e<0||e>3)throw new Error("The `level` should be an integer from 0 to 3")},ye={enumerable:!0,get(){return this[k]},set(e){Z(e),this[k]=e}},Oe=(e,t={})=>{t.level!==void 0&&Z(t.level);let r=q?q.level:0;e[k]=t.level===void 0?r:t.level};var ve=e=>{let t=(...r)=>r.join(" ");return Oe(t,e),Object.setPrototypeOf(t,T.prototype),t};function T(e){return ve(e)}Object.setPrototypeOf(T.prototype,Function.prototype);for(let[e,t]of Object.entries(m))E[e]={get(){let r=M(this,ee(t.open,t.close,this[x]),this[y]);return Object.defineProperty(this,e,{value:r}),r}};E.visible={get(){let e=M(this,this[x],!0);return Object.defineProperty(this,"visible",{value:e}),e}};var Ae=(e,t)=>{let r=m[t];if(e==="rgb"){let n=(i,a,u)=>r.ansi(m.rgbToAnsi(i,a,u));return[n,n,(i,a,u)=>r.ansi256(m.rgbToAnsi256(i,a,u)),r.ansi16m]}if(e==="hex"){let n=i=>r.ansi(m.hexToAnsi(i));return[n,n,i=>r.ansi256(m.hexToAnsi256(i)),i=>r.ansi16m(...m.hexToRgb(i))]}let o=n=>r.ansi(m.ansi256ToAnsi(n));return[o,o,r.ansi256,r.ansi256]},we=["rgb","hex","ansi256"];for(let e of we){let t=e[0].toUpperCase()+e.slice(1);for(let[r,o]of[[e,"color"],["bg"+t,"bgColor"],["underline"+t,"underlineColor"]]){let{close:n}=m[o],s=Ae(e,o);E[r]={get(){let i=function(a,u,f){let me=s[this.level](a,u,f);return M(this,ee(me,n,this[x]),this[y])};return Object.defineProperty(this,r,{value:i}),i}}}}var Se=Object.defineProperties(()=>{},{...E,level:{enumerable:!0,get(){return this[b].level},set(e){this[b].level=e}}}),ee=(e,t,r)=>{let o,n;return r===void 0?(o=e,n=t):(o=r.openAll+e,n=t+r.closeAll),{open:e,close:t,openAll:o,closeAll:n,parent:r}},M=(e,t,r)=>{let o=(...n)=>n.length===1?F(o,""+n[0]):n.length===2?F(o,`${n[0]??""} ${n[1]??""}`):F(o,n.join(" "));return Object.setPrototypeOf(o,Se),o[b]=e[b]??e,o[x]=t,o[y]=r,o},F=(e,t)=>{if(e[b][k]<=0||!t)return e[y]?"":t;let r=e[x];if(r===void 0)return t;let{openAll:o,closeAll:n}=r;if(t.includes("\x1B"))for(;r!==void 0;)t=G(t,r.close,r.open),r=r.parent;let s=t.indexOf(`
6
+ `);return s!==-1&&(t=V(t,n,o,s)),o+t+n};Object.defineProperties(T.prototype,{...E,level:ye});var Ie=T(),ut=T({level:Q?Q.level:0});var h=Ie;var te={name:"flisk-cli-internal",private:!0,version:"1.4.0",description:"Flisk CLI \u2014 start services on your machine.",keywords:["flisk","tilt","cli","local-dev","microservices"],homepage:"https://github.com/flisk-sh/flisk#readme",bugs:{url:"https://github.com/flisk-sh/flisk/issues"},repository:{type:"git",url:"git+https://github.com/flisk-sh/flisk.git",directory:"cli"},license:"MIT",author:"Flisk Team",type:"module",main:"./dist/index.js",types:"./dist/index.d.ts",bin:{flisk:"bin/flisk.js"},files:["dist","dist-bundle","bin","templates","README.md","Tiltfile","engine","discovery","specs","ext","!ext/ide-components/code_executor","shared-platform-engineering/docker-templates"],scripts:{build:"tsc && node scripts/bundle.mjs","build:watch":"tsc --watch","check:dist":"npm run build && ../scripts/check-cli-dist.sh",lint:"biome check . ../tests/generated ../tests/runtime-layout","lint:fix":"biome check . ../tests/generated ../tests/runtime-layout --write",typecheck:"tsc --project tsconfig.typecheck.json",clean:"rm -rf dist",dev:"bun run build:watch",test:"vitest run","test:watch":"vitest","test:coverage":"vitest run --coverage --coverage.reportOnFailure --coverage.reporter=text --coverage.reporter=html --coverage.reporter=json-summary --coverage.reporter=json --coverage.reportsDirectory=coverage --reporter=default --reporter=json --outputFile.json=test-results/vitest.json",prepack:"../scripts/stage-npm-engine.sh && npm run build"},dependencies:{commander:"^15.0.0",handlebars:"^4.7.8"},devDependencies:{"@biomejs/biome":"^2.5.13","@types/node":"^26.6.5","@types/react":"^19.3.0","@vitest/coverage-v8":"5.0.5",ajv:"^8.17.1",chalk:"^6.0.1",esbuild:"^0.28.2",ink:"^8.0.0",knip:"^6.38.0",react:"^19.3.0","react-devtools-core":"^8.0.0",typescript:"^7.0.2",vite:"^8.3.3",vitest:"5.0.5"},engines:{node:">=22.12.0"}};var mt="Container Runtime",P="bring-your-own";var ht="database-management",gt=".tiltignore",bt="service.json",Ne="docker-compose.yml",xt=".autogenerated",je="TILT_TECH_STACK.star",Fe="TILT_RESOURCE_DEFAULTS.star",re="project.json",Et="package.json",Tt=[je,Fe,"spec.master"],Ct=["backend","frontend","library","sdk","worker","migrator","mcp","agent",P],Rt={backend:["dev","build","start"],worker:["dev","build","start"],migrator:["dev","build","start"],mcp:["dev","build","start"],agent:["dev","build","start"],frontend:["dev","build"],library:["dev","build"],sdk:["dev","build"],[P]:[]};var kt=["monitoring","elk","debezium","golden_image","verdaccio"],yt={frontend:{base:3e3,min:3e3,max:3999,range:"3000-3999"},backend:{base:4e3,min:4e3,max:4999,range:"4000-4999"},mcp:{base:4e3,min:4e3,max:5999,range:"4000-5999"},agent:{base:4e3,min:4e3,max:5999,range:"4000-5999"},[P]:{base:4e3,min:4e3,max:5999,range:"4000-5999"},worker:{base:6e3,min:6e3,max:6999,range:"6000-6999"},health:{base:5e3,min:5e3,max:5999,range:"5000-5999"},migrator:{base:7e3,min:7e3,max:7999,range:"7000-7999"}},Ot={tiltUi:10350,traefik:8080},B="https://flisk.sh/docs/quickstart/";var vt=["node_modules",".git",".tilt",".tilt-engine","dist","build",".prisma",".turbo","coverage","tmp","temp","__tests__","test","tests",".github",".vscode","docs"],At=["Dockerfile",Ne,"docker-compose.yaml","Tiltfile","vite.config.ts","tsconfig.json","tsconfig.build.json"],Me={infra:"\u{1F3D7}\uFE0F",core:"\u{1F527}",api:"\u26A1",app:"\u{1F3A8}",orchestrator:"\u2699\uFE0F"};function wt(e){let t=e.toLowerCase();for(let[r,o]of Object.entries(Me))if(t.includes(r))return o;return"\u{1F4E6}"}import{existsSync as Pe}from"node:fs";import{dirname as Be,join as De,resolve as oe}from"node:path";import{cwd as Le}from"node:process";function v(e=Le()){let t=oe(e),r=oe("/");for(;t!==r;){if(Pe(De(t,".flisk",re)))return t;let o=Be(t);if(o===t)break;t=o}return null}var O=null;function $e(){if(O)return O;let e=te;if(!e||typeof e!="object"||Array.isArray(e))throw new Error("Invalid package.json: expected object");let t=e;return O={name:String(t.name??"@flisk-sh/flisk"),version:String(t.version??"0.0.0"),fullPackage:t},O}function Mt(){return $e().version}import{existsSync as ne}from"node:fs";import{delimiter as se,extname as ie,join as le}from"node:path";import{delimiter as Dt,extname as Ue}from"node:path";function C(){return process.platform==="win32"}function Ge(e){return e==="linux"?"linux":e==="darwin"?"darwin":e==="win32"?"windows":null}function Ve(e){return e==="x64"?"amd64":e==="arm64"?"arm64":null}function Ye(e,t){let r=Ge(e),o=Ve(t);if(!r||!o||r==="windows"&&o!=="amd64")return null;let n=`tdk-${r}-${o}`;return r==="windows"?`${n}.exe`:n}function Lt(){return Ye(process.platform,process.arch)}function $t(){return C()?"flisk.exe":"flisk"}function D(e,t=C()){return t?Ue(e)?[e]:[e,`${e}.exe`,`${e}.cmd`,`${e}.bat`]:[e]}function A(e){let t=process.env.PATH??process.env.Path??"",r=C(),o=D(e,r);if(r&&!ie(e))for(let n of(process.env.PATHEXT??".EXE;.CMD;.BAT;.COM").split(";")){let s=n.toLowerCase();s&&!o.includes(`${e}${s}`)&&o.push(`${e}${s}`)}for(let n of t.split(se))if(n)for(let s of o){let i=le(n,s);if(ne(i))return i}return null}function Kt(e){let t=process.env.PATH??process.env.Path??"",r=C(),o=D(e,r);if(r&&!ie(e))for(let i of(process.env.PATHEXT??".EXE;.CMD;.BAT;.COM").split(";")){let a=i.toLowerCase();a&&!o.includes(`${e}${a}`)&&o.push(`${e}${a}`)}let n=[],s=new Set;for(let i of t.split(se))if(i)for(let a of o){let u=le(i,a);if(!ne(u))continue;let f=r?u.toLowerCase():u;s.has(f)||(s.add(f),n.push(u))}return n}import{execFileSync as Ke,execSync as He}from"node:child_process";var ce=1e4;function ae(){let e=!1;if(process.platform==="win32")try{return Ke(A("docker")??"docker",["ps"],{stdio:"ignore",timeout:ce,windowsHide:!0}),"running"}catch(t){return t.code==="ETIMEDOUT"?"unresponsive":"missing"}for(let t of["docker ps","colima status","podman ps"])try{return He(t,{stdio:"ignore",timeout:ce}),"running"}catch(r){r.code==="ETIMEDOUT"&&(e=!0)}return e?"unresponsive":"missing"}function w(e,t){return e[t]??0}function We(e,t){let r=Array.from({length:t.length+1},(o,n)=>n);for(let o=1;o<=e.length;o++){let n=[o];for(let s=1;s<=t.length;s++){let i=e[o-1]===t[s-1]?0:1;n[s]=Math.min(w(n,s-1)+1,w(r,s)+1,w(r,s-1)+i)}r=n}return w(r,t.length)}function Je(e,t){if(e.length!==t.length)return!1;for(let r=0;r<e.length-1;r++)if(e[r]!==t[r]&&e[r]===t[r+1]&&e[r+1]===t[r]&&e.slice(0,r)===t.slice(0,r)&&e.slice(r+2)===t.slice(r+2))return!0;return!1}function ue(e,t){if(e.length<2||t.length===0||t.includes(e))return;let r=e.toLowerCase(),o,n=Number.POSITIVE_INFINITY;for(let s of t){if(s.length===0)continue;let i=s.toLowerCase(),a=Je(r,i)?1:We(r,i),u=Math.max(1,Math.min(2,Math.floor(Math.max(r.length,i.length)/3)));a>u||(a<n||a===n&&(o===void 0||s<o))&&(o=s,n=a)}return o}import{spawn as ze}from"node:child_process";import{join as Xe}from"node:path";function qe(e,t=[],r={}){return new Promise((o,n)=>{let s=[e,...t];r.verbose&&console.log(`Executing: tilt ${s.join(" ")}`);let i=ze(A("tilt")??"tilt",s,{stdio:r.inheritStdio?"inherit":"pipe",shell:!1,windowsHide:process.platform==="win32",timeout:r.timeoutMs}),a="",u="";r.inheritStdio||(i.stdout?.on("data",f=>{a+=f.toString()}),i.stderr?.on("data",f=>{u+=f.toString()})),i.on("close",f=>{o({exitCode:f??1,stdout:a,stderr:u})}),i.on("error",f=>{n(new Error(`Failed to spawn tilt: ${f.message}`))})})}async function fe(){try{return(await qe("version",[],{inheritStdio:!1,timeoutMs:1e4})).exitCode===0}catch{return!1}}function Qe(){let e=v();if(!e)throw g.notInProject();return Xe(e,".flisk",".flisk-out","Tiltfile")}function de(e){let t=Qe();e.push("-f",t)}function rr(e,t={}){let r=[];return de(r),t.focusTargets&&t.focusTargets.length>0&&r.push("--",`--focus=${t.focusTargets.join(",")}`),r.push(...e),t.verbose&&!t.quiet&&r.push("--verbose"),t.watch&&r.push("--watch"),r}function or(e={}){let t=[];return de(t),e.focusTargets&&e.focusTargets.length>0&&t.push("--",`--focus=${e.focusTargets.join(",")}`),t}function pe(e){return e instanceof Error?e.message:String(e)}function fr(e,t){if(process.env.FLISK_VERBOSE){let r=t!==void 0?`: ${pe(t)}`:"";console.warn(h.gray(`${e}${r}`))}}var p=class extends Error{suggestions;exitCode;constructor(t,r=[],o=1){super(t),this.name="FliskError",this.suggestions=r,this.exitCode=o}display(){U(this.message,void 0,this.suggestions)}exit(){this.display(),process.exit(this.exitCode)}},$=class extends Error{code;constructor(t=1){super(`process.exit(${t})`),this.name="ProcessExitError",this.code=t}};function L(e,t,r=!1){let o=new Set;for(let n of e){let s=ue(n,t);s&&o.add(r?`Did you mean "${s}" for "${n}"?`:`Did you mean "${s}"?`)}return[...o]}var g={tiltNotInstalled:()=>new p("Tilt CLI is not installed",["Install Tilt: `brew install tilt` (macOS)","Or download from: https://docs.tilt.dev/install.html","Verify with: `tilt version`",`Setup guide: ${B}`]),dockerNotAvailable:()=>new p("Docker (or a compatible container runtime) is not running",["Start Docker Desktop, then verify with: `docker ps`","Or start Colima: `colima start`","Or start the Docker service on Linux: `sudo systemctl start docker`",`Setup guide: ${B}`]),dockerNotResponding:()=>new p("Docker is running but not responding (`docker ps` hung for 10s)",["Quit and reopen Docker Desktop, or run `colima restart`","Then verify with: `docker ps`"]),stackNotFound:(e,t=[])=>new p(`Stack "${e}" not found`,[...L([e],t),"Run `flisk stacks` to see available stacks","Run `flisk stack` to assign resources to a stack"]),resourceNotFound:(e,t=[])=>new p(`Resource "${e}" not found`,[...L([e],t),"Run `flisk resources` to list all resources","Check the resource name spelling"]),unknownServices:(e,t)=>{let r=L(e,t,e.length>1);return new p(`Unknown service ${e.join(", ")}. Valid names: ${t.join(", ")}`,r,2)},directoryExists:e=>new p(`Directory already exists: ${e}`,["Use `--path` to specify a different location","Remove the existing directory if no longer needed"]),invalidPath:e=>new p(`Invalid path: ${e}`,["Path must be within the project directory",'Path cannot contain special characters like <>:"|?*']),notInProject:()=>new p("Could not find project root (no .flisk/project.json found)",["Run this from within a Flisk project","Run `flisk project --yes` to initialize a new project"])};function dr(){let e=v();return e||g.notInProject().exit()}function Ze(e){e instanceof p&&e.exit(),U(pe(e)),process.exit(1)}async function et(e,t){try{return await e()}catch(r){if(r instanceof $)throw r;return t?.verbose&&r instanceof Error&&r.stack&&console.error(h.gray(r.stack)),Ze(r)}}async function pr(e,t){let r=[],o=ae();return o==="unresponsive"?r.push(g.dockerNotResponding()):o==="missing"&&r.push(g.dockerNotAvailable()),await fe()||r.push(g.tiltNotInstalled()),r.length>0&&(console.error(h.red(`
7
+ Flisk can't start - missing prerequisites:
8
+ `)),r.forEach((n,s)=>{s>0&&console.error(""),n.display()}),console.error(h.gray("\nRun `flisk doctor` for a full environment check.")),process.exit(1)),et(e,t)}function mr(e,t=1,r){U(e,void 0,r),process.exit(t)}function U(e,t,r){if(console.error(h.red(`\u274C ${e}`)),t&&console.error(h.gray(` ${t}`)),r&&r.length>0){console.error(h.yellow(`
9
+ \u{1F4A1} Suggestions:`));for(let o of r)console.error(h.cyan(` \u2192 ${o}`))}}function hr(e,t){console.error(h.red(`
10
+ tilt ${e} failed with exit code ${t}`)),process.exit(t)}export{_ as a,h as b,te as c,mt as d,P as e,ht as f,gt as g,bt as h,Ne as i,xt as j,je as k,Fe as l,re as m,Et as n,Tt as o,Ct as p,Rt as q,kt as r,yt as s,Ot as t,vt as u,At as v,wt as w,v as x,Mt as y,C as z,Lt as A,$t as B,A as C,Kt as D,qe as E,fe as F,Qe as G,rr as H,or as I,pe as J,fr as K,p as L,$ as M,g as N,dr as O,et as P,pr as Q,mr as R,U as S,hr as T};
@@ -0,0 +1,57 @@
1
+ import{createRequire as __fliskRequire}from'node:module';const require=__fliskRequire(import.meta.url);
2
+ import{n as mt,t as ht}from"./chunk-763VK575.js";import{f as O,g as gt,h as kt,i as St,j as se,k as yt,l as wt,m as xt,n as Pt,o as bt,p as ne,q as vt,s as Dt,t as $t}from"./chunk-B6Q5VKL7.js";import{c as ft}from"./chunk-K6SOCO6V.js";import{b as W,c as Ct,d as K}from"./chunk-3J6XI3NX.js";import{a as dt,f as pt,g as te,j as Nt,k as Tt,l as Et,m as Rt,o as Ot,p as xe,q as Pe,r as _t,s as be,t as ve,u as At,v as De,w as jt}from"./chunk-D7N2GGJH.js";import{A as rt,B as Se,C as Q,D as ot,E as Z,I as ye,J as it,K as ee,L as at,M as ct,O as lt,P as ut,Q as we,a as N,ga as x,t as st,x as nt}from"./chunk-BWK6MPCB.js";import{C as b,D as et,L as tt,b as h,d as v,j as M,m as H,n as G,o as ge,q as ke,x as g,y as Ze}from"./chunk-VHFFSBVJ.js";import{execFileSync as Os}from"node:child_process";import{readFileSync as Kr}from"node:fs";import{join as qr}from"node:path";import{execFileSync as tr,execSync as gs}from"node:child_process";import{existsSync as $,readdirSync as sr,readFileSync as B}from"node:fs";import{join as P,normalize as Be,relative as Ve}from"node:path";import{Command as nr}from"commander";import{existsSync as Ls}from"node:fs";var re="docs/agent-hosts.md",$e=`WebContainers cannot run Flisk: there is no Docker daemon or Tilt. Run \`flisk up\` on a machine with Docker. See ${re}.`,Ft=`Docker is not reachable from this Dev Container. Mount the host Docker socket (-v /var/run/docker.sock:/var/run/docker.sock) or add the docker-outside-of-docker feature to devcontainer.json, then retry. Docker-in-docker is not supported. See ${re}.`;function Ms(){return{env:process.env,versions:process.versions,platform:process.platform,fileExists:Ls}}function It(e=Ms()){let{env:t,versions:s,platform:n,fileExists:r}=e;return s.webcontainer?{kind:"webcontainer",canUp:!1}:t.CODESPACES==="true"?{kind:"codespaces",canUp:!0}:t.REMOTE_CONTAINERS||r("/.dockerenv")&&t.DEVCONTAINER?{kind:"devcontainer",canUp:!0}:n==="win32"?{kind:"native-windows",canUp:t.FLISK_ALLOW_NATIVE_WINDOWS==="1"}:n==="linux"&&t.WSL_DISTRO_NAME?{kind:"wsl2",canUp:!0}:{kind:"local",canUp:!0}}function Lt(e){return e==="devcontainer"||e==="codespaces"}function oe(e){return e.some(t=>st(t.config?.appType)||t.config?.appType==="frontend"||t.config?.appType==="worker")}import{existsSync as Hs,readFileSync as Ws}from"node:fs";import{join as Bs,relative as Mt,resolve as Ht,sep as Vs}from"node:path";var Us=2,Wt=["services/*/*"];function Bt(e){return e.split(Vs).filter(Boolean)}function Gs(e,t){let s=0,n=0,r=-1,o=0;for(;n<t.length;)if(s<e.length&&e[s]!=="*"&&(e[s]==="?"||e[s]===t[n]))s++,n++;else if(s<e.length&&e[s]==="*")r=s++,o=n;else if(r!==-1)s=r+1,n=++o;else return!1;for(;s<e.length&&e[s]==="*";)s++;return s===e.length}function Ks(e,t){return e.length===t.length&&e.every((s,n)=>Gs(s,t[n]))}function Ce(e){let t=Bs(e,".flisk",H);if(!Hs(t))return Wt;try{let s=JSON.parse(Ws(t,"utf-8"))?.discovery?.paths;if(Array.isArray(s)&&s.every(n=>typeof n=="string"))return s}catch{}return Wt}function ie(e,t,s){let n=Bt(Mt(e,Ht(e,t)));return s.some(r=>{let o=Bt(Mt(e,Ht(e,r)));for(let i=0;i<=Us;i++){let a=n.length-i;if(a>0&&Ks(o,n.slice(0,a)))return!0}return!1})}function ao(e,t,s,n){let r=Ce(e);if(ie(e,t,r))return{path:t};let o=`services/${s}/${n}`;return ie(e,o,r)?{path:o,adjustedFrom:t}:{path:t}}import{execFile as qs}from"node:child_process";import{promisify as Js}from"node:util";var zs=Js(qs),Xs=1e4,Ys=5,Vt=10*6e4,Qs=3,Zs=200,en=async e=>{let{stdout:t,stderr:s}=await zs("docker",e,{encoding:"utf-8",timeout:Xs,windowsHide:!0});return`${t}${s}`};function tn(e,t){let s=Nt(t).toLowerCase(),n=e.replace(/-/g,"_").toLowerCase();return n===s||n.startsWith(`${s}_`)}function sn(e,t=Date.now()){if(e.status==="restarting")return!0;if(e.restartCount<Ys)return!1;if(e.status==="running"){let n=Date.parse(e.startedAt);return Number.isNaN(n)||t-n<Vt}let s=Date.parse(e.finishedAt??"");return e.exitCode!==0&&!Number.isNaN(s)&&t-s<Vt}function nn(e,t){let s=/database "([^"]+)" does not exist/i.exec(e);return s?`database "${s[1]}" does not exist: re-run the project's database provisioning (flisk up) or create it`:/Cannot find module|MODULE_NOT_FOUND|module not found/i.test(e)?"a module is missing from the image: rebuild it (flisk up --force) after checking the resource's dependencies":/EADDRINUSE|address already in use/i.test(e)?"the port inside the container is already in use: check for two processes started by the same command":/ECONNREFUSED|connection refused|could not connect/i.test(e)?"a dependency is not reachable: check that the service it connects to is running and healthy":/\b(?:environment variable|env var)\b.*\b(?:missing|not set|required|undefined)\b/i.test(e)||/\b[A-Z][A-Z0-9_]{2,}\b (?:is )?(?:not set|required|missing)\b/.test(e)?"a required environment variable is missing: check the project's .env":t.exitCode===137?"killed (exit 137), usually out of memory: raise the container's memory limit":null}function rn(e){let t=[];for(let s of e.split(/\r?\n/)){let[n,r,o,i,a,c]=s.split(" ");!n||r===void 0||t.push({name:n.replace(/^\//,""),restartCount:Number(r)||0,status:o??"",startedAt:i??"",exitCode:Number(a)||0,finishedAt:c??""})}return t}async function Ut(e,t=[],s=en,n=Date.now()){let r="Crash-looping containers",o;try{o=(await s(["ps","-a","--format",'{{.ID}} {{.Label "com.docker.compose.project"}}'])).split(/\r?\n/).map(m=>m.split(" ")).filter(([m,d])=>m&&d&&tn(d,e)).map(([m])=>m)}catch{return{name:r,didPass:!0,isSkipped:!0,message:"Docker not available - skipped crash-loop check"}}if(o.length===0)return{name:r,didPass:!0,isSkipped:!0,message:"No project containers to check"};let i;try{i=rn(await s(["inspect","--format","{{.Name}} {{.RestartCount}} {{.State.Status}} {{.State.StartedAt}} {{.State.ExitCode}} {{.State.FinishedAt}}",...o]))}catch{return{name:r,didPass:!0,isSkipped:!0,message:"Containers changed while checking - skipped crash-loop check"}}let a=i.filter(f=>sn(f,n));if(a.length===0)return{name:r,didPass:!0,message:"No project container is crash-looping"};let c=[],l=new Set;for(let f of a){let m="";try{m=await s(["logs","--tail",String(Qs),f.name])}catch{}let d=Q(m,t).split(/\r?\n/).map(k=>k.trim().slice(0,Zs)).filter(Boolean),S=nn(m,f);S&&l.add(S),c.push([`${f.name}: ${f.status}, restarted ${f.restartCount} times`,...d.map(k=>` | ${k}`)].join(`
3
+ `))}return{name:r,didPass:!1,message:`${a.length} container${a.length===1?" is":"s are"} crash-looping:
4
+ ${c.join(`
5
+ `)}`,fix:[...l,"Read the full log: docker logs <container>"].join("; ")}}import{execFile as Sn,execFileSync as yn}from"node:child_process";import{existsSync as wn,realpathSync as Xt,statfsSync as xn}from"node:fs";import{homedir as Pn}from"node:os";import{join as bn}from"node:path";import{promisify as vn}from"node:util";import{statfsSync as on}from"node:fs";import{homedir as an}from"node:os";var ae="Disk Space",cn=1024**3,ln=2,Ne=10,Gt=["Free disk space, then retry: flisk doctor"," docker system prune -af # unused images and build cache (needs Docker running)"," npm cache clean --force"," bun pm cache rm"," brew cleanup -s"].join(`
6
+ `);function Kt(e=on,t=an()){let s;try{let r=e(t);s=Number(r.bavail)*Number(r.bsize)/cn}catch{return{name:ae,didPass:!0,isSkipped:!0,message:"Could not read free disk space"}}let n=`${s.toFixed(1)} GB free`;return s<ln?{name:ae,didPass:!1,message:`${n}: Docker cannot build or start containers`,fix:Gt}:s<Ne?{name:ae,didPass:!1,isWarning:!0,message:`${n}: image builds may fail`,fix:Gt}:{name:ae,didPass:!0,message:n}}var un="Quit Docker Desktop completely (whale icon > Quit Docker Desktop), reopen it, and wait until it shows Running. If it keeps getting stuck, check free disk space. Then retry: flisk doctor";function qt(e,t=process.platform){return t!=="darwin"||!e?null:{name:"Container Runtime",didPass:!1,message:"Docker Desktop is open, but its engine is not responding",fix:un}}import{execFileSync as dn}from"node:child_process";var Te=(e,t)=>dn(e,t,{encoding:"utf-8",stdio:"pipe",windowsHide:!0}),Jt=["traefik-public","traefik-private","backend","database","infisical-network","verdaccio-network","proxy"];function Ee(e){let t=e.replace(/-/g,"_");return Jt.map(s=>`${t}_${s}`)}function zt(e){let t=new Set;for(let s of e)for(let n of["traefik-public","traefik-private"])s.endsWith(`_${n}`)&&t.add(s.slice(0,-(n.length+1)));return t}function Re(e,t){for(let s of Jt)if(e.endsWith(`_${s}`)){let n=e.slice(0,-(s.length+1));if(t.has(n))return n}return null}function yo(e,t=Te){let s=new Set(t("docker",["network","ls","--format","{{.Name}}"]).split(/\r?\n/).map(r=>r.trim()).filter(Boolean)),n={removed:[],kept:[]};for(let r of Ee(e))if(s.has(r))try{t("docker",["network","rm",r]),n.removed.push(r)}catch(o){let i=String(o.stderr??o).trim();n.kept.push({name:r,reason:i.split(/\r?\n/)[0]??""})}return n}function ce(e,t=process.platform,s=Te){if(t==="win32")return[];let n;try{n=s("ps",["-axo","pid=,command="])}catch{return[]}let r=[];for(let o of n.split(/\r?\n/)){let i=/^\s*(\d+)\s+(.*)$/.exec(o);if(!i)continue;let a=i[2]??"",c=(a.split(/\s+/)[0]??"").split("/").at(-1),l=` -f ${e}`,f=a.indexOf(l),m=a[f+l.length];c==="tilt"&&/^\S+\s+up\s/.test(a)&&f>0&&(m===void 0||m===" ")&&r.push(Number(i[1]))}return r}function wo(e,t=process.platform,s=Te){let n=ce(e,t,s);for(let r of n)try{s("kill",["-TERM",String(r)])}catch{}return n}async function xo(e,t=8e3,s=ce){let n=Date.now()+t;for(;s(e).length>0;){if(Date.now()>=n)return!1;await new Promise(r=>setTimeout(r,250))}return!0}import{execFile as pn}from"node:child_process";function Oe(e){return new Promise(t=>{pn(b("tilt")??"tilt",["get","uiresources","-o","json","--port",String(e)],{timeout:15e3,maxBuffer:16*1024*1024},(s,n)=>t(s?null:n))})}function fn(e){let s=(JSON.parse(e).items??[]).filter(n=>n.status?.disableStatus?.state!=="Disabled").map(n=>n.status?.updateStatus==="not_applicable"?{...n,status:{...n.status,updateStatus:"ok"}}:n);return JSON.stringify({items:s})}function mn(e){return(JSON.parse(e).items??[]).filter(t=>t.status?.disableStatus?.state!=="Disabled").flatMap(t=>t.metadata?.name?[t.metadata.name]:[])}function hn(e,t){let s=JSON.parse(e).items??[],n=new Map(s.map(r=>[r.metadata?.name,r]));return{missing:t.filter(r=>!n.has(r)),disabled:t.filter(r=>n.get(r)?.status?.disableStatus?.state==="Disabled")}}function gn(e){return e.endsWith("-typecheck")}function kn(e,t,s){let n=Rt(fn(e),t),r=n.failures.filter(i=>!gn(i.name)),o={ready:r.length===0&&n.pendingCount===0&&n.okCount>0,failures:r.map(i=>({name:i.name,message:i.error||`${i.updateStatus}/${i.runtimeStatus}`})),pending:n.pendingCount,timedOut:!1,enabled:mn(e)};if(s&&s.length>0){let{missing:i,disabled:a}=hn(e,s);if(i.length>0&&(o={...o,ready:!1,pending:o.pending+i.length}),a.length>0)return{settled:!0,result:{...o,ready:!1,failures:[...o.failures,...a.map(c=>({name:c,message:"disabled in Tilt"}))]}}}return{result:o,settled:o.ready||o.failures.length>0&&o.pending===0}}async function $o(e,t={}){let s=t.timeoutMs??Number(process.env.FLISK_UP_READY_TIMEOUT_MS??9e5),n=t.intervalMs??2e3,r=t.fetchJson??Oe,o=t.deferred??Et(),i=Date.now()+s,a={ready:!1,failures:[],pending:0,timedOut:!1,enabled:[]};for(;;){let c=await r(e);if(c)try{let l=kn(c,o,t.expected);if(a=l.result,l.settled||a.failures.length>0&&t.isStalled?.(c))return a}catch{}if(Date.now()>=i)return{...a,ready:!1,timedOut:!0};await new Promise(l=>setTimeout(l,n))}}var F=vn(Sn),Dn=15e3,$n=/^flisk_doctor_probe_(\d+)$/,Cn=async e=>{let{stdout:t}=await F("docker",e,{encoding:"utf-8",timeout:Dn,windowsHide:!0});return t};function Nn(){try{return yn("docker",["info","--format","{{.ServerVersion}}"],{encoding:"utf-8",timeout:15e3,stdio:["ignore","pipe","ignore"]}),!0}catch{return!1}}function le(e){return String(e.stderr??e).trim().split(/\r?\n/)[0]??""}var Tn=120;function En(e){let t=/^\s*(?:(?:(\d+)-)?(\d+):)?(\d+):(\d+)\s*$/.exec(e);if(!t)return null;let[,s="0",n="0",r="0",o="0"]=t;return((Number(s)*24+Number(n))*60+Number(r))*60+Number(o)}async function Rn(e,t=Oe,s=2,n=r=>new Promise(o=>setTimeout(o,r))){for(let r=0;r<s;r++){r>0&&await n(1e3);for(let o of e)if(await t(o)!==null)return!0}return!1}async function On(e){if(process.platform==="win32")return"unknown";try{let{stdout:t}=await F("ps",["-p",String(e),"-o","etime="],{encoding:"utf-8",timeout:5e3}),s=En(t);if(s===null||s<Tn)return"unknown";let{stdout:n}=await F("lsof",["-nP","-a","-p",String(e),"-iTCP","-sTCP:LISTEN","-Fn"],{encoding:"utf-8",timeout:5e3}),r=[...n.matchAll(/^n.*:(\d+)$/gm)].map(o=>Number(o[1]));return await Rn(r)?"healthy":"stale"}catch{return"unknown"}}function _n(e=Cn){return{colima:An,colimaStatus:()=>W(),dockerAnswers:Nn,async listNetworks(){let t=(await e(["network","ls","--format","{{.Name}}"])).split(/\r?\n/).map(n=>n.trim()).filter(Boolean);return(await Promise.all(t.map(async n=>{try{let r=await e(["network","inspect","--format","{{len .Containers}}",n]);return{name:n,containers:Number(r.trim())||0}}catch(r){if(/no such network|not found/i.test(String(r)))return null;throw r}}))).filter(n=>n!==null)},async removeNetwork(t){try{await e(["network","rm",t])}catch(s){throw new Error(le(s))}},freeDiskGib(){try{let t=xn(Pn());return Number(t.bavail)*Number(t.bsize)/1024**3}catch{return null}},async reclaimable(){let t=null;try{let n=await e(["system","df","--format","{{.Type}} {{.Reclaimable}}"]);for(let r of n.split(/\r?\n/)){let[o,i]=r.split(" ");o==="Build Cache"&&i&&(t=i.replace(/\s*\(.*\)/,"").trim())}}catch{}let s=0;try{s=(await e(["images","-q","-f","dangling=true"])).split(/\r?\n/).filter(Boolean).length}catch{}return{buildCache:t,danglingImages:s}},async prune(t){try{await e(t==="builder"?["builder","prune","-f"]:["image","prune","-f"])}catch(s){throw new Error(le(s))}},async tiltStatus(t){return On(t)},stopProcess(t){process.kill(t,"SIGTERM")},isProcessAlive(t){try{return process.kill(t,0),!0}catch(s){return s.code==="EPERM"}}}}var Yt=_n();async function An(e){if(e==="native-lima"){let n=K();if(!n){let o=wn("/opt/homebrew/bin/brew")?"/opt/homebrew/bin/brew":"brew";if(await F(o,["reinstall","lima"],{encoding:"utf-8",timeout:3e5}),n=K(),!n)throw new Error("brew reinstall lima did not provide a native limactl")}let r=n?{...process.env,PATH:`${n}:${process.env.PATH??""}`}:process.env;await F("colima",["start"],{encoding:"utf-8",timeout:3e5,env:r});return}let t=K(),s=t?{...process.env,PATH:`${t}:${process.env.PATH??""}`}:process.env;await F("colima",[e],{encoding:"utf-8",timeout:3e5,env:s})}async function Qt(e,t=Yt,s={}){let n=[],r=[];for(let d of s.tiltPids??[])await t.tiltStatus(d)==="stale"?n.push({id:`stop-tilt:${d}`,check:"Tilt processes",scope:"project",command:`kill -TERM ${d}`,status:"planned",reason:"this project's Tilt is running but its UI does not answer"}):r.push(d);let o=r.length>0?`Tilt is running for this project (pid ${r.join(", ")}); run flisk down first`:void 0,i=t.colimaStatus(),a=Ct(i,t.dockerAnswers());if(a==="start")n.push({id:"colima:start",check:"Colima",scope:"host",command:"colima start",status:"planned",reason:i.problem??"the Colima VM is not running"});else if(a==="restart")n.push({id:"colima:restart",check:"Colima",scope:"host",command:"colima restart",status:"planned",reason:"the Colima VM is running but its Docker daemon does not answer"});else if(a==="native-lima"){let d=K();n.push({id:"colima:native-lima",check:"Colima",scope:"host",command:d?`PATH="${d}:$PATH" colima start`:"brew reinstall lima",status:"planned",reason:d?`the colima CLI on this PATH cannot see the VM; a native limactl is installed in ${d}`:"the colima CLI on this PATH cannot see the VM; lima is installed as an x86_64 build (brew reinstall lima)"})}let c=await t.listNetworks(),l=t.freeDiskGib();if(l!==null&&l<Ne){let{buildCache:d,danglingImages:S}=await t.reclaimable(),k=`${l.toFixed(1)} GB free`;d&&!/^0(\.0+)?\s*B$/i.test(d)&&n.push({id:"prune:builder",check:"Disk Space",scope:"host",command:"docker builder prune -f",status:"planned",reason:`${k}; ${d} of build cache reclaimable`}),S>0&&n.push({id:"prune:images",check:"Disk Space",scope:"host",command:"docker image prune -f",status:"planned",reason:`${k}; ${S} untagged image${S===1?"":"s"}`})}let f=new Set(e?Ee(e):[]),m=zt(c.map(d=>d.name));for(let d of c){let S=$n.exec(d.name),k,y,p="unused network";if(S)k="probe",y="Orphaned probe networks";else if(f.has(d.name))k="project",y="Docker networks";else if(s.machine&&Re(d.name,m))k="machine",y="Docker networks",p=`unused network of project "${Re(d.name,m)}"`;else continue;let D={id:`remove-network:${d.name}`,check:y,scope:k,command:`docker network rm ${d.name}`,status:"planned",reason:p};d.containers>0?(D.status="skipped",D.reason=`${d.containers} container(s) still attached`):k==="project"&&o?(D.status="skipped",D.reason=o):S&&t.isProcessAlive(Number(S[1]))&&(D.status="skipped",D.reason=`probe of a running process (pid ${S[1]})`),n.push(D)}return n}async function Zt(e,t,s=Yt){let n=[];for(let r of e){if(r.status!=="planned"||t.dryRun){n.push(r);continue}if(!t.confirm){n.push({...r,status:"skipped",reason:"confirmation required; run in a terminal or pass --yes"});continue}let o=!1;try{o=await t.confirm(r)}catch{}if(!o){n.push({...r,status:"skipped",reason:"not confirmed"});continue}try{if(r.id.startsWith("prune:")){await s.prune(r.id==="prune:builder"?"builder":"images"),n.push({...r,status:"applied",reason:"pruned"});continue}if(r.id.startsWith("colima:")){let i=r.id.slice(7);if(i==="start"||i==="restart"){await s.colima(i),n.push({...r,status:"applied",reason:`colima ${i} ran`});continue}try{await s.colima("native-lima"),n.push({...r,status:"applied",reason:"native lima repaired and colima started"})}catch(a){n.push({...r,status:"failed",reason:le(a)})}continue}if(r.id.startsWith("stop-tilt:")){s.stopProcess(Number(r.id.slice(10))),n.push({...r,status:"applied",reason:"stopped"});continue}await s.removeNetwork(r.id.slice(15)),n.push({...r,status:"applied",reason:"removed"})}catch(i){n.push({...r,status:"failed",reason:le(i)})}}return n}function es(e){return e.some(t=>t.status==="failed")}async function jn(e){try{let{stdout:t}=await F(e,["--version"],{encoding:"utf-8",timeout:5e3,windowsHide:!0});return t.trim().split(/\r?\n/)[0]||null}catch{return null}}async function Fn(e=et("flisk"),t=jn){let s=new Set,n=[];for(let r of e){let o=r;try{o=Xt(r)}catch{}s.has(o)||(s.add(o),n.push({path:r,version:await t(r)}))}return n}async function ts(e){let t=e??await Fn();if(t.length<=1)return{name:"Flisk installs",didPass:!0,message:"One flisk install on PATH"};let s=t.map(r=>`${r.path} (${r.version??"version unknown"})`).join(", "),n=new Set(t.map(r=>r.version));return{name:"Flisk installs",didPass:!1,isWarning:!0,message:`${t.length} flisk installs on PATH${n.size>1?" with different versions":""}: ${s}`,fix:"Keep one: remove the others, or run flisk upgrade. The first on PATH is the one your shell runs; tools that launch /usr/local/bin/flisk directly may use another"}}function ss(e,t=ce){let s=new Set([e]);try{s.add(Xt(e))}catch{}let n=new Set;for(let r of s)for(let o of t(bn(r,".flisk",".flisk-out","Tiltfile")))n.add(o);return[...n]}var _e=1;function In(e,t=[]){return{schemaVersion:_e,data:e,errors:t}}function Ln(e){return e instanceof tt?{error:{code:"COMMAND_FAILED",message:e.message,...e.suggestions.length>0?{suggestions:e.suggestions}:{}},exitCode:e.exitCode}:{error:{code:"INTERNAL",message:e instanceof Error?e.message:String(e)},exitCode:2}}function Ho(e){let t=Ln(e);console.log(JSON.stringify(In(null,[t.error]))),console.error(t.error.message),process.exit(t.exitCode)}async function rs(e,t){let s=[],n=[],r=o=>{o.status==="fulfilled"?s.push(o.value):n.push({code:"INTERNAL",message:o.reason instanceof Error?o.reason.message:String(o.reason)})};for(let o of await Promise.allSettled(e.map(i=>Promise.resolve().then(i))))r(o);for(let o of t)for(let i of await Promise.allSettled([Promise.resolve().then(o)]))r(i);return{checks:s,errors:n}}function ns(e){let t=e.find(s=>s.name===v);return t?t.didPass:null}function j(e,t,s=[],n,r){return{schemaVersion:_e,data:{ready:s.length===0&&e.every(o=>o.didPass||o.isSkipped||o.isWarning),inProject:t,checks:e,...r?{host:{...r,containerRuntimeReachable:ns(e),canUp:r.canUp&&ns(e)!==!1}}:{},...n!==void 0?{ports:{http:{requested:n?.requested.ingressHttp??80,chosen:n?.ingressHttp??null,explicit:n?.explicit.ingressHttp??!!process.env.FLISK_HTTP_PORT,reason:n?.reason.ingressHttp??"port planning failed"},https:{requested:n?.requested.ingressHttps??443,chosen:n?.ingressHttps??null,explicit:n?.explicit.ingressHttps??!!process.env.FLISK_HTTPS_PORT,reason:n?.reason.ingressHttps??"port planning failed"},postgres:{requested:n?.requested.postgres??5432,chosen:n?.postgres??null,explicit:n?.explicit.postgres??!!process.env.FLISK_POSTGRES_PORT,reason:n?.reason.postgres??"port planning failed"}}}:{}},errors:s}}function os(e){return e.errors.length>0?2:e.data.ready?0:1}import{existsSync as je,readFileSync as is}from"node:fs";import{dirname as Mn,join as Ae,normalize as Hn}from"node:path";function Wn(e){let t=new Set,s=/^load\s*\(([\s\S]*?)\)/gm;for(let n of e.matchAll(s)){let r=n[1]??"",o=/["']([^"']+)["']/g,i=Array.from(r.matchAll(o),a=>a[1]);for(let a of i.slice(1))a.startsWith("_")&&t.add(a)}return Array.from(t).sort()}function as(e,t,s){return t==="ext://flisk-cli"?Ae(s,".flisk",".flisk-out","flisk-cli-ext","Tiltfile"):t.startsWith(".")||!t.includes("://")&&!t.startsWith("@")?Hn(Ae(Mn(e),t)):null}function Bn(e,t,s){let n=[],r=/^load\s*\(([\s\S]*?)\)/gm;for(let o of t.matchAll(r)){let c=(o[1]??"").match(/["']([^"']+)["']/)?.[1];if(!c)continue;let l=as(e,c,s);l&&(je(l)||n.push(`${e}: ${c} -> ${l}`))}return n}function Vn(e,t,s){let n=[],r=/^load\s*\(([\s\S]*?)\)/gm;for(let o of t.matchAll(r)){let c=(o[1]??"").match(/["']([^"']+)["']/)?.[1];if(c){let l=as(e,c,s);l&&n.push(l)}}return n}function Un(e,t){let s=new Set,n=[e];for(;n.length>0;){let r=n.pop();if(!r||s.has(r)||!je(r))continue;s.add(r);let o=is(r,"utf-8");for(let i of Vn(r,o,t))s.has(i)||n.push(i)}return Array.from(s).sort()}function cs(){let e=g()??process.cwd(),t=Ae(e,".flisk",".flisk-out","Tiltfile");if(!je(t))return{name:"Starlark Load Exports",didPass:!0,isSkipped:!0,message:"No generated Tiltfile to check"};let s=[],n=[],r=Un(t,e);for(let i of r){let a=is(i,"utf-8"),c=Wn(a);c.length>0&&s.push(`${i}: ${c.join(", ")}`);for(let l of Bn(i,a,e))n.push(l)}if(s.length===0&&n.length===0)return{name:"Starlark Load Exports",didPass:!0,message:`${N(r.length,"reachable Starlark file")} ${r.length===1?"has":"have"} valid load exports and paths`};let o=[];return s.length>0&&o.push(`Private exported symbols:
7
+ ${s.join(`
8
+ `)}`),n.length>0&&o.push(`Missing relative load targets:
9
+ ${n.join(`
10
+ `)}`),{name:"Starlark Load Exports",didPass:!1,message:`Starlark load() issues will stop Tilt before services start:
11
+ ${o.join(`
12
+
13
+ `)}`,fix:"Regenerate with a current Flisk (`flisk config regenerate`). If the issue remains, rename loaded symbols without leading underscores and update stale load paths."}}import{readFileSync as Gn}from"node:fs";import{join as Kn}from"node:path";function ls(e){let t=e.trim().match(/(\d+)\.(\d+)(?:\.(\d+))?/);return t?[Number(t[1]),Number(t[2]),Number(t[3]??0)]:null}function qn(e){try{return JSON.parse(Gn(Kn(e,".flisk",H),"utf-8"))?.minFliskVersion}catch{return}}function us(e,t){let s=qn(e);if(s===void 0)return{status:"none"};let n=typeof s=="string"?ls(s):null;if(!n||!/^\d+\.\d+\.\d+$/.test(String(s).trim()))return{status:"malformed",message:`.flisk/project.json minFliskVersion ${JSON.stringify(s)} is not a version like "1.3.80"`,fix:'Set minFliskVersion to a MAJOR.MINOR.PATCH string, for example "1.3.80".'};let r=ls(t),o=r!==null&&(()=>{for(let[a,c]of n.entries()){let l=r[a]??0;if(l!==c)return l>c}return!0})(),i=n.join(".");return o?{status:"ok",required:i}:{status:"too-old",required:i,message:`flisk ${t} is older than the ${i} this project requires (minFliskVersion)`,fix:"Run: flisk upgrade"}}import{relative as Jn}from"node:path";function ue(e,t){return Jn(e,t.configPath)||t.configPath}function ds(e){let t=e.config?.dependsOn;return t===void 0?[]:Array.isArray(t)&&t.every(s=>typeof s=="string")?t:null}function zn(e){let t=new Set(e.map(a=>a.name)),s=new Map(e.map(a=>[a.name,(ds(a)??[]).filter(c=>t.has(c))])),n=new Map,r=new Map,o=[],i=a=>{r.set(a,"visiting"),o.push(a);for(let c of s.get(a)??[])if(r.get(c)==="visiting"){let l=o.slice(o.indexOf(c)),f=l.indexOf([...l].sort()[0]??c),m=[...l.slice(f),...l.slice(0,f)];n.set(m.join(">"),[...m,m[0]??c])}else r.has(c)||i(c);o.pop(),r.set(a,"done")};for(let a of[...s.keys()].sort())r.has(a)||i(a);return[...n.values()]}function Fe(e=g()??process.cwd(),t=x(e)){let s=t.flatMap(n=>ds(n)===null?[`${ue(e,n)} dependsOn ${JSON.stringify(n.config?.dependsOn)}: expected an array of service names`]:[]);return s.length===0?{name:"dependsOn",didPass:!0,message:"Every dependsOn is a list of service names"}:{name:"dependsOn",didPass:!1,message:`${N(s.length,"invalid dependsOn","invalid dependsOn")}:
14
+ ${s.join(`
15
+ `)}`,fix:'Write "dependsOn" as an array of service names, for example ["postgres", "api"]'}}function Ie(e=g()??process.cwd(),t=x(e)){let s=new Map(t.map(o=>[o.name,o])),n=zn(t);if(n.length===0)return{name:"Circular dependencies",didPass:!0,message:"No service depends on itself through dependsOn"};let r=n.map(o=>{let i=s.get(o[0]??""),a=o[1]??"";return`${i?ue(e,i):o[0]} dependsOn "${a}": circular dependency ${o.join(" -> ")}`});return{name:"Circular dependencies",didPass:!1,message:`${n.length} ${n.length===1?"circular dependency":"circular dependencies"}:
16
+ ${r.join(`
17
+ `)}`,fix:'Remove one "dependsOn" entry in each cycle so the services no longer wait on each other, or move what they share into a third service'}}function Le(e=g()??process.cwd(),t=x(e)){let s=t.flatMap(n=>{let r=n.config?.port;return r===void 0?[]:typeof r=="number"&&Number.isInteger(r)&&r>=1&&r<=65535?[]:[`${ue(e,n)} port ${JSON.stringify(r)}: not an integer from 1 to 65535`]});return s.length===0?{name:"Service ports",didPass:!0,message:"Every declared port is valid"}:{name:"Service ports",didPass:!1,message:`${N(s.length,"invalid port")}:
18
+ ${s.join(`
19
+ `)}`,fix:'Set "port" to the port the service listens on, an integer from 1 to 65535'}}function Me(e=g()??process.cwd(),t=!1,s=x(e)){let n=[],r=[];for(let i of s){let a=i.config?.schemaVersion;if(a===we)continue;let c=ue(e,i);a===void 0?n.push(`${c} schemaVersion: missing`):r.push(`${c} schemaVersion ${JSON.stringify(a)}: this flisk supports ${we}`)}if(n.length===0&&r.length===0)return{name:"schemaVersion",didPass:!0,message:"Every service.json has a supported schemaVersion"};let o=[...n.length>0?["Run `flisk config migrate` to add the missing schemaVersion"]:[],...r.length>0?["A version this flisk does not support cannot be migrated: upgrade flisk"]:[]];return{name:"schemaVersion",didPass:!1,isWarning:!t,message:`${N(n.length+r.length,"service.json file")} without a supported schemaVersion:
20
+ ${[...n,...r].join(`
21
+ `)}`,fix:o.join(". ")}}function ai(e,t){let s=Me(e,!1,t);s.didPass||(console.warn(h.yellow(`\u26A0 ${s.message}`)),s.fix&&console.warn(h.gray(` ${s.fix}`)))}function ci(e,t={},s=process.exit){let n=t.resources??x(e),r=[se(e,n),Fe(e,n),Ie(e,n),Le(e,n)].filter(i=>!i.didPass);if(r.length===0)return;let o=r.map(i=>`${i.message}${i.fix?`
22
+ Fix: ${i.fix}`:""}`).join(`
23
+ `);t.onInvalid?.(o);for(let i of r)console.error(h.red(`\u2717 ${i.message}`)),i.fix&&console.error(h.gray(` Fix: ${i.fix}`));s(1)}import{execFileSync as q}from"node:child_process";import{lookup as Xn}from"node:dns/promises";var ps="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.";function Yn(e){return e.length>0&&e.every(t=>t==="127.0.0.1"||t==="::1")}function Qn(e){return e.split(/\r?\n/).flatMap(t=>{let s=t.match(/^\s*(\d+)\s+(\d+)(?:\s|$)/);return s?[[Number(s[1]),Number(s[2])]]:[]})}function Zn(e,t,s){let n=s.replace(/-/g,"_").toLowerCase();return e.filter(r=>{let o=t.find(a=>a.publishedPorts.includes(r));if(!o||!n)return!0;let i=o.name.toLowerCase();return!i.startsWith(`${n}_`)&&!i.startsWith(`${n}-`)})}function er(){return b("docker")}function fs(){let e=er();if(!e)return{name:"Windows Runtime Tools",didPass:!1,message:"Docker is not running. Start Docker Desktop, wait until it is Running, then retry flisk doctor.",fix:"Install Docker Desktop and start it in Linux container mode."};if(!b("tilt"))return{name:"Windows Runtime Tools",didPass:!1,message:"tilt.exe not found on PATH. Install Tilt from https://docs.tilt.dev/install.html"};let t=b("bun");return((process.argv[1]??"").toLowerCase().includes("node_modules")?b("node"):!0)?{name:"Windows Runtime Tools",didPass:!0,message:t?`Docker (${e}), Tilt, and Bun found on PATH`:`Docker (${e}) and Tilt found on PATH; \u26A0\uFE0F Bun was not found (generated services need Bun)`}:{name:"Windows Runtime Tools",didPass:!1,message:"node.exe not found on PATH for this npm installation."}}function ms(){try{return q(b("docker")??"docker",["info","--format","{{.OSType}}"],{encoding:"utf-8",timeout:1e4,windowsHide:!0}).trim().toLowerCase()==="windows"?{name:"Docker container mode",didPass:!1,message:"Docker Desktop is using Windows containers. Switch to Linux containers. Flisk stacks are Linux images.",fix:"Switch Docker Desktop to Linux containers. Flisk does not run Windows containers."}:{name:"Docker container mode",didPass:!0,message:"Docker Desktop is using Linux containers"}}catch{return{name:"Docker container mode",didPass:!1,message:"Docker is not running. Start Docker Desktop, wait until it is Running, then retry flisk doctor."}}}async function hs(){let e=[],t=[];try{let l=q("netsh",["interface","ipv4","show","excludedportrange","protocol=tcp"],{encoding:"utf-8",timeout:1e4,windowsHide:!0});t=Qn(l)}catch{e.push("Could not inspect Windows Hyper-V excluded TCP port ranges.")}let s=[80,443,5432],n=s.filter(l=>t.some(([f,m])=>l>=f&&l<=m));n.length>0&&e.push(`\u26A0\uFE0F Windows reserved port${n.length>1?"s":""} ${n.join(", ")} for Hyper-V/WSL. Fix: disable the conflicting Windows feature or change Flisk ports in project config. Common fix: run \`net stop winnat\` then \`net start winnat\` in an Administrator terminal, then retry \`flisk doctor\`.`);let r=[];for(let l of s)await _t(l)==="in-use"&&r.push(l);let o=[];try{let l=q(b("docker")??"docker",["ps","--format","{{.Names}}\\t{{.Ports}}"],{encoding:"utf-8",timeout:1e4,windowsHide:!0});o=Tt(l,s)}catch{}let i=g()?Z():"",a=Zn(r,o,i);if(a.length>0)try{let l=q("powershell.exe",["-NoProfile","-Command",`$ports = '${a.join(",")}'.Split(','); foreach ($port in $ports) { Get-NetTCPConnection -LocalPort ([int]$port) -State Listen -ErrorAction SilentlyContinue | ForEach-Object { $connection = $_; $service = Get-CimInstance Win32_Service | Where-Object { $_.ProcessId -eq $connection.OwningProcess } | Select-Object -First 1; if ([int]$port -eq 80 -and ($service.Name -eq 'W3SVC' -or $connection.OwningProcess -eq 4)) { '80: IIS / World Wide Web Publishing (HTTP.sys)' } elseif ($service) { '{0}: {1}' -f $port, $service.DisplayName } else { '{0}: PID {1}' -f $port, $connection.OwningProcess } } }`],{encoding:"utf-8",timeout:1e4,windowsHide:!0}).trim();e.push(`\u26A0\uFE0F Ports ${a.join(", ")} are already listening${l?`:
24
+ ${l}`:"."}`)}catch{e.push(`\u26A0\uFE0F Ports ${a.join(", ")} are already in use.`)}let c=!0;for(let l of["flisk.localhost","example.flisk.localhost"])try{let f=await Xn(l,{all:!0,verbatim:!0});Yn(f.map(m=>m.address))||(c=!1)}catch{c=!1}c||e.push(`${ps}
25
+ Add these lines to C:\\Windows\\System32\\drivers\\etc\\hosts (Administrator Notepad):
26
+ 127.0.0.1 flisk.localhost
27
+ 127.0.0.1 example.flisk.localhost`);try{q("git",["config","core.autocrlf"],{encoding:"utf-8",timeout:5e3,windowsHide:!0}).trim().toLowerCase()==="true"&&e.push("git core.autocrlf is true; generated files may get CRLF while Docker Linux containers expect LF. Recommended: git config core.autocrlf input in Flisk repos.")}catch{}return e.push("Docker Desktop Settings \u2192 Resources \u2192 File sharing must include this project directory."),{name:"Windows ports and DNS",didPass:c&&a.length===0,message:e.length>0?e.join(`
28
+ `):"Required ports are available and Flisk localhost DNS resolves to loopback",...c?{}:{fix:ps}}}var R=1e4,E={dockerMissing:"See https://docs.docker.com/get-docker/",dockerDaemonDown:"Start Docker Desktop, OrbStack, or Colima, then retry: flisk doctor",tiltMissing:"curl -fsSL https://raw.githubusercontent.com/tilt-dev/tilt/master/scripts/install.sh | bash",bunMissing:"curl -fsSL https://bun.sh/install | bash",port80:"Stop the process bound to port 80, or stop local nginx/caddy. Then: flisk doctor",port5432:"Stop local Postgres or change the host port. Then: flisk doctor",notProject:"flisk project --yes"},ks="WSL2 detected. Use Docker Desktop WSL integration. Guide: docs/wsl2.md",Ss="Native Windows landscape boot is unsupported. Use WSL2 Ubuntu with Docker Desktop integration. Guide: docs/wsl2.md",He=[0,25,0],I=[1,2,0];function pe(e,t){let s=Ge(e);return s?Ke(s,t):!1}function rr(e,t,s=process.platform==="linux"&&!!process.env.WSL_DISTRO_NAME){if(!s)return{name:"WSL project location",didPass:!0,isSkipped:!0,message:"Not running in WSL2 - skipped project filesystem check"};let n=e.replace(/\\/g,"/").replace(/\/+$/,"").toLowerCase();if(n!=="/mnt/c"&&!n.startsWith("/mnt/c/"))return{name:"WSL project location",didPass:!0,message:`${ks} Project is on the WSL filesystem.`};let r=`${ks} Project is under /mnt/c (${e}); hot reload may be broken. Move it into the WSL filesystem, such as ~/projects.`;return{name:"WSL project location",didPass:!t,isWarning:!t,message:r,fix:"Move the repository under your WSL home directory (for example, ~/projects) and retry flisk doctor."}}function or(e){let t=e.replace(/^\[(.*)\]$/,"$1");return t==="0.0.0.0"||/^[0:]*:0\.0\.0\.0$/.test(t)?!0:t.includes(":")&&/^[0:]+$/.test(t)}function ir(e=process.env,t=!1){let s=(e.FLISK_BIND_ADDRESS??"").trim();return or(s)?{name:"Dev Port Bind Address",didPass:!t,isWarning:!t,message:`FLISK_BIND_ADDRESS is ${s}: Traefik and Postgres are reachable from other machines on the network.`,fix:"Unset FLISK_BIND_ADDRESS to keep dev ports on 127.0.0.1. Keep it only when you test from another device on purpose."}:{name:"Dev Port Bind Address",didPass:!0,message:s?`Dev ports bind to ${s}`:"Dev ports bind to 127.0.0.1 (this machine only)"}}function xs(e){let t=e.filter(n=>!n.didPass&&!n.isSkipped&&!n.isWarning),s=e.filter(n=>n.didPass||n.isSkipped||n.isWarning);return t.sort((n,r)=>{let o=i=>i.name==="Host Ports"&&/\b5432\b/.test(i.message)?0:i.name==="Host Ports"?1:i.name==="Ingress Ports"?2:3;return o(n)-o(r)}),[...t,...s]}function ar(e,t){return t?e?"Doctor passed. Next: flisk up":"Doctor passed. Next: flisk project example":"Doctor failed. Fix the items above, then run: flisk doctor"}var Ue={checkDockerOperatingSystem:"Docker OS",checkDockerCompose:"Docker Compose",checkDockerVersions:"Docker Versions",checkDockerNetworkCapacity:"Docker Network Pool",checkContainerResourceHealth:"Container Resource Health",checkCrashLoopingContainers:"Crash-looping containers",checkTiltResourceHealth:"Tilt Resources",checkServiceHealth:"Service Health",checkServiceSmoke:"Service Smoke",checkAdvertisedEndpoints:"Advertised Endpoints"},ys=new Set(["Docker OS","Docker Compose","Docker Versions","Docker Network Pool","Container Resource Health","Crash-looping containers","Tilt Resources","Service Health","Service Smoke","Advertised Endpoints",...Object.keys(Ue)]);function cr(e){return!!(e.requiresContainerRuntime||e.checkName&&ys.has(e.checkName)||e.name&&ys.has(e.name))}function T(e,t){let s=()=>t();return s.requiresContainerRuntime=!0,s.checkName=e,s}async function lr(e,t={}){let s=[],n=!!t.containerRuntimeFailed;for(let r of e){if(n&&cr(r)){let i=r.checkName??(r.name&&Ue[r.name]?Ue[r.name]:r.name&&r.name!=="check"&&r.name!=="fn"?r.name:"Container check");s.push({name:i,didPass:!0,isSkipped:!0,message:`Docker not running - skipped ${i} check`});continue}let o=await r();if(s.push(o),o.name===v&&!o.didPass&&(n=!0),!t.all&&!o.didPass&&!o.isSkipped&&!o.isWarning)break}return s}function ur(e){let t=0,s=0,n=0,r=0;for(let o of e)o.isSkipped?n++:o.isWarning?r++:o.didPass?t++:s++;return r>0?`${t} passed, ${r} warned, ${s} failed, ${n} skipped`:`${t} passed, ${s} failed, ${n} skipped`}function Je(e){return gt(e)}function dr(e,t,s,n,r){return async(o=O)=>{try{return await o(t,R),{name:e,didPass:!0,message:s}}catch(i){return Je(i)?{name:e,didPass:!1,message:`${e} did not respond within ${R/1e3}s`,fix:r}:{name:e,didPass:!1,message:n,fix:r}}}}async function We(e){try{return await O(e,R),!0}catch{return!1}}async function pr(){let e=W();return e.isColima?e.running&&!e.problem?{name:"Colima",didPass:!0,message:`Colima VM is running${e.arch?` (${e.arch})`:""}`}:{name:"Colima",didPass:!1,message:e.problem??"The Colima VM is not running",fix:e.fix}:{name:"Colima",didPass:!0,message:"Docker does not run on Colima"}}async function ze(){if(process.platform==="win32")try{return await O("docker ps",R),{name:v,didPass:!0,message:"Docker Desktop Linux container engine is running"}}catch{return{name:v,didPass:!1,message:"Docker is not running",fix:E.dockerDaemonDown}}let e=!!b("docker");try{return await O("docker ps",R),{name:v,didPass:!0,message:"Docker daemon is running"}}catch(s){if(Je(s))return{name:v,didPass:!1,message:"Docker daemon is not responding",fix:E.dockerDaemonDown}}let t=qt(await We("pgrep -f com.docker.backend"));return t||(await We("colima status")?{name:v,didPass:!0,message:"Colima (Docker runtime) is running"}:b("colima")?{name:v,didPass:!1,message:"Colima is installed but not running",fix:E.dockerDaemonDown}:await We("podman ps")?{name:v,didPass:!0,message:"Podman is running"}:e?{name:v,didPass:!1,message:"Docker daemon is not running",fix:E.dockerDaemonDown}:{name:v,didPass:!1,message:"Docker is not running",fix:E.dockerMissing})}var J=dr("Docker Compose","docker compose version","Docker Compose plugin available","Docker Compose plugin not found","Install Docker Compose: https://docs.docker.com/compose/install/");J.requiresContainerRuntime=!0;J.checkName="Docker Compose";var fr=[25,0,0],mr=[2,20,2];function Ge(e){let t=e.trim().match(/(\d+)\.(\d+)(?:\.(\d+))?/);return t?[Number(t[1]),Number(t[2]),Number(t[3]??0)]:null}function Ke(e,t){for(let[s,n]of t.entries()){let r=e[s]??0;if(r!==n)return r>n}return!0}async function z(e=O){let t=async a=>String(await e(a,R)).trim(),s,n;try{[s,n]=await Promise.all([t("docker version --format '{{.Server.Version}}'"),t("docker compose version --short")])}catch{return{name:"Docker Versions",didPass:!0,isSkipped:!0,message:"Could not read Docker Engine/Compose versions - skipped version check"}}let r=Ge(s),o=Ge(n);if(!r||!o)return{name:"Docker Versions",didPass:!0,isSkipped:!0,message:`Unrecognized Docker version output (engine "${s}", compose "${n}") - skipped version check`};let i=[];return Ke(r,fr)||i.push(`Docker Engine ${s} (need 25.0+)`),Ke(o,mr)||i.push(`Docker Compose ${n} (need 2.20.2+)`),i.length===0?{name:"Docker Versions",didPass:!0,message:`Docker Engine ${s} and Compose ${n} support generated healthchecks`}:{name:"Docker Versions",didPass:!1,message:`Docker is too old for generated healthchecks (they use start_interval):
29
+ ${i.join(`
30
+ `)}`,fix:"Update Docker Desktop, or on Linux update docker-ce and the docker-compose-plugin package"}}z.requiresContainerRuntime=!0;z.checkName="Docker Versions";async function Xe(e=O){let t;try{t=String(await e("tilt version",R)).trim()}catch{return{name:"Tilt CLI",didPass:!1,message:"Tilt CLI not found",fix:E.tiltMissing}}return pe(t,He)?{name:"Tilt CLI",didPass:!0,message:`Tilt ${t} is available`}:{name:"Tilt CLI",didPass:!1,message:`Tilt ${t||"version unknown"} is below the required v${He.join(".")} floor`,fix:`Install Tilt v${He.join(".")} or newer: https://docs.tilt.dev/install.html`}}async function Ye(e=O){let t;try{t=String(await e("docker info --format '{{.OSType}}'",R)).trim().toLowerCase()}catch{return{name:"Docker OS",didPass:!0,isSkipped:!0,message:"Docker OS unavailable - daemon failure reported separately"}}return t!=="linux"?{name:"Docker OS",didPass:!1,message:`Docker is using the ${t||"unknown"} engine; Flisk requires Linux containers`,fix:"Switch Docker Desktop to Linux containers, enable WSL2 integration, then retry flisk doctor."}:{name:"Docker OS",didPass:!0,message:"Docker is using Linux containers"}}Ye.requiresContainerRuntime=!0;Ye.checkName="Docker OS";async function hr(e=O){let t=g();if(!t)return{name:"Bun",didPass:!0,isSkipped:!0,message:"Not in a project - skipping Bun check"};if(!oe(x(t)))return{name:"Bun",didPass:!0,isSkipped:!0,message:"No generated JS services - skipping Bun check"};try{let s=String(await e("bun --version",R)).trim();return pe(s,I)?{name:"Bun",didPass:!0,message:`Bun ${s} is available`}:{name:"Bun",didPass:!1,message:`Bun ${s||"version unknown"} is below the required ${I.join(".")} floor`,fix:`Install Bun ${I.join(".")} or newer: https://bun.sh/install`}}catch{return{name:"Bun",didPass:!1,message:"Bun is not available",fix:E.bunMissing}}}function gr(){let e=g()??process.cwd(),t=nt(e);if(t.missing.length>0)return{name:"Environment Variables",didPass:!1,message:`Missing required env variables: ${t.missing.join(", ")}`,fix:$(P(e,".env"))?`Edit .env and set these values:
31
+ ${t.missing.map(n=>`${n}=<value>`).join(`
32
+ `)}`:"No .env file yet. Run `flisk project` to create one with working defaults."};if(t.invalid.length>0)return{name:"Environment Variables",didPass:!1,message:`Invalid env variables: ${t.invalid.join(", ")}`,fix:"Edit .env and provide values for empty variables"};let s=t.warnings.filter(n=>!n.startsWith(".env file not found"));return{name:"Environment Variables",didPass:!0,message:s.length>0?`All required environment variables are set (warning: ${s.join("; ")})`:"All required environment variables are set"}}function kr(){let e=g()??process.cwd(),t=P(e,".flisk",".flisk-out"),s=ge.filter(n=>!$(P(t,n)));return s.length===0?{name:"Master Configs",didPass:!0,message:`${ge.join(", ")} found`}:{name:"Master Configs",didPass:!1,message:`Master configs missing: ${s.join(", ")}`,fix:"Run: flisk project"}}function Sr(e=Ze()){let t=g();if(!t)return{name:"Flisk version",didPass:!0,isSkipped:!0,message:"Not in a project - skipping Flisk version check"};let s=us(t,e);return s.status==="none"?{name:"Flisk version",didPass:!0,isSkipped:!0,message:`flisk ${e} (no minFliskVersion in .flisk/project.json)`}:s.status==="malformed"||s.status==="too-old"?{name:"Flisk version",didPass:!1,message:s.message,fix:s.fix}:{name:"Flisk version",didPass:!0,message:`flisk ${e} meets minFliskVersion ${s.required}`}}function yr(){let e=g()??process.cwd(),t=Ce(e),s=x(e).filter(r=>!ie(e,r.path,t));if(s.length===0)return{name:"Resource Discovery",didPass:!0,message:`All resources are covered by discovery.paths ${JSON.stringify(t)}`};let n=s.map(r=>Be(Ve(e,r.path))).join(", ");return{name:"Resource Discovery",didPass:!1,message:`${N(s.length,"resource")} outside discovery.paths ${JSON.stringify(t)}: ${n}. \`flisk up\` will not start them`,fix:"Move each under services/<stack>/<name>, or add a matching pattern to discovery.paths in .flisk/project.json and run: flisk config regenerate"}}var wr=["install-deps.sh","bun-hoisted-symlink-fix.sh","prisma-bun-client-link-fix.sh","prisma-normalize-client.sh","infisical-entrypoint.sh"],xr=/shared-platform-engineering\/docker-templates\/([\w.-]+)/g;function Pr(e){let t=new Set;for(let s of x(e)){let n=P(s.path,M);if($(n)){for(let r of sr(n))if(!(!r.startsWith("Dockerfile")||r.endsWith(".dockerignore")))for(let o of B(P(n,r),"utf-8").matchAll(xr))t.add(o[1])}}return[...t]}function br(){let e=g()??process.cwd(),t=[];$(P(e,G))||t.push(`${G} (workspace root manifest)`);let s=P(e,"shared-platform-engineering","docker-templates"),n=[];try{n=Pr(e)}catch{}for(let r of new Set([...wr,...n]))$(P(s,r))||t.push(`shared-platform-engineering/docker-templates/${r}`);return t.length===0?{name:"Generated Runtime Assets",didPass:!0,message:"Generated Docker runtime assets are present"}:{name:"Generated Runtime Assets",didPass:!1,message:`Generated Dockerfiles reference missing project runtime assets:
33
+ ${t.join(`
34
+ `)}`,fix:"Run `flisk project --yes` (or `flisk config regenerate`) with an updated Flisk. `flisk up` also refreshes these assets before starting Tilt."}}function vr(){let e=g()??process.cwd(),t=x(e),s=[];for(let n of t){let r=P(n.path,G);if(!$(r))continue;let o=n.config?.appType??"backend",i=ke[o]??ke.backend,a;try{a=JSON.parse(B(r,"utf-8")).scripts??{}}catch{s.push(`${n.name} (package.json is invalid JSON)`);continue}let c=i.filter(l=>!a[l]);c.length>0&&s.push(`${n.name}: missing "${c.join('", "')}"`)}return s.length===0?{name:"Startup Scripts",didPass:!0,message:"All services have required package.json scripts"}:{name:"Startup Scripts",didPass:!1,message:`Services missing required package.json scripts:
35
+ ${s.join(`
36
+ `)}`,fix:`Add the missing scripts to each service's package.json, e.g.:
37
+ "dev": "bun run src/index.ts",
38
+ "build": "tsc",
39
+ "start": "bun run dist/index.js"`}}function Ps(e){if(e.startsWith("@"))return[e.split("/").slice(0,2).join("/")];let t=e.split("/")[0]??e;return[`@types/${t}`,t]}function bs(e,t,s=0){let n=e[t];if(typeof n!="string"||s>3)return!1;if(/(^|[\s;&|(])tsc(\s|$)/.test(n))return!0;for(let r of n.matchAll(/\b(?:bun|npm|pnpm|yarn)\s+run\s+([\w:.-]+)/g))if(bs(e,r[1],s+1))return!0;return!1}function ws(e){let t=Ps(e);return e.includes("/")||e.startsWith("@")?t[t.length-1]:t[0]}var Dr={"@types/bun":"^1.4.2","@types/node":"^20.0.0"};function $r(e,t){return(t.includes("bun")||e.has("@types/bun"))&&!e.has("@types/node")}function Cr(){let e=g()??process.cwd(),t=x(e),s=[],n=new Set;for(let o of t){let i=P(o.path,G),a=P(o.path,M,"tsconfig.docker.autogenerated.json");if(!$(i)||!$(a))continue;let f=qe(a)?.compilerOptions?.types;if(!Array.isArray(f))continue;let m=qe(i),d=m?.scripts??{};if(!bs(d,"build"))continue;let S=new Set([...Object.keys(m?.devDependencies??{}),...Object.keys(m?.dependencies??{})]),k=f.filter(y=>typeof y=="string").filter(y=>!Ps(y).some(p=>S.has(p)));for(let y of k)n.add(ws(y));if(k.length>0){let y=k.map(p=>`"${p}" (needs ${ws(p)})`).join(", ");s.push(`${o.name}: "types" lists ${y}`)}$r(S,f)&&(n.add("@types/node"),s.push(`${o.name}: uses @types/bun, which references node types internally, but @types/node is not a direct dependency`))}if(s.length===0)return{name:"TypeScript Type Dependencies",didPass:!0,message:`Every service's Docker tsconfig "types" entry has its @types package installed`};let r=[...n].map(o=>{let i=Dr[o];return i?`"${o}": "${i}"`:`${o} (bun add -d ${o})`});return{name:"TypeScript Type Dependencies",didPass:!1,message:`\`bun run build\` will fail with TS2688 (Cannot find type definition file) because a @types package it needs is not a direct dependency:
40
+ ${s.join(`
41
+ `)}`,fix:`Add to each service's package.json devDependencies: ${r.join(", ")}`}}function qe(e){try{return JSON.parse(B(e,"utf-8"))}catch{return null}}function Nr(e){let s=qe(e)?.compilerOptions;return s?.allowSyntheticDefaultImports===!0||s?.esModuleInterop===!0}function Tr(){let e=g()??process.cwd(),t=x(e).filter(n=>n.config?.appType==="frontend");if(t.length===0)return{name:"Frontend Docker Preflight",didPass:!0,isSkipped:!0,message:"No frontend services to check"};let s=[];for(let n of t){$(P(n.path,"public"))||s.push(`${n.name}: no public/ folder, but the Docker build copies it. Create it: mkdir -p ${Be(Ve(e,P(n.path,"public")))} && touch ${Be(Ve(e,P(n.path,"public",".gitkeep")))}`);let r=P(n.path,M,"Dockerfile.app.autogenerated"),o=P(n.path,M,"tsconfig.docker.autogenerated.json");if($(r)){let i=B(r,"utf-8"),a=/\bEXPOSE\s+80\b/.test(i),c=n.config?.stack,l=c?P(e,"services",c,M,"docker-compose.app.autogenerated.yml"):"";if(a&&l&&$(l)){let f=B(l,"utf-8"),m=n.name.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),d=new RegExp(`traefik\\.http\\.services\\.${m}\\.loadbalancer\\.server\\.port=(\\d+)`),k=f.match(d)?.[1];k&&k!=="80"&&s.push(`${n.name}: nginx runtime exposes 80, but generated Traefik routes to ${k}`)}}if($(o)&&!Nr(o)){let i=P(n.path,"src","main.tsx");if($(i)){let a=B(i,"utf-8"),c=[/import\s+\w+\s+from\s+["']react["']/,/import\s+\w+\s+from\s+["']react-dom\/client["']/].filter(l=>l.test(a)).map(l=>l.source.includes("react-dom")?"react-dom/client":"react");c.length>0&&s.push(`${n.name}: Docker tsconfig does not allow synthetic default imports, but src/main.tsx default-imports ${c.join(" and ")}`)}}}return s.length===0?{name:"Frontend Docker Preflight",didPass:!0,message:`${N(t.length,"frontend")} ${t.length===1?"has":"have"} compatible Docker build/routing metadata`}:{name:"Frontend Docker Preflight",didPass:!1,message:`Frontend Docker metadata has issues that will make \`flisk up\` fail or route 404:
42
+ ${s.join(`
43
+ `)}`,fix:'Regenerate with a current Flisk (`flisk config regenerate`) and ensure frontend nginx runtimes route to port 80. For React entrypoints, prefer named imports: `import { StrictMode } from "react"` and `import { createRoot } from "react-dom/client"`.'}}var Er=90,Rr=80;function Or(e){return e.split(`
44
+ `).map(t=>t.trim()).filter(Boolean).map(t=>{let[s,n,r]=t.split(",");return{name:s??"unknown",memPct:Number.parseFloat((n??"").replace(/%/g,"")),cpuPct:Number.parseFloat((r??"").replace(/%/g,""))}}).filter(t=>Number.isFinite(t.memPct)&&Number.isFinite(t.cpuPct))}var _r=Object.assign(function(){let t;try{t=tr(b("docker")??"docker",["stats","--no-stream","--format","{{.Name}},{{.MemPerc}},{{.CPUPerc}}"],{stdio:"pipe",encoding:"utf-8",timeout:R,windowsHide:process.platform==="win32"})}catch(o){return{name:"Container Resource Health",didPass:!0,isSkipped:!0,message:Je(o)?"Docker not responding - skipped container resource check":"Docker not running - skipped container resource check"}}let s=Or(t);if(s.length===0)return{name:"Container Resource Health",didPass:!0,isSkipped:!0,message:"No running containers to check"};let n=s.filter(o=>o.memPct>=Er&&o.cpuPct>=Rr);if(n.length===0)return{name:"Container Resource Health",didPass:!0,message:`${N(s.length,"container")} within normal resource usage`};let r=n.map(o=>`${o.name} (mem ${o.memPct.toFixed(0)}%, cpu ${o.cpuPct.toFixed(0)}%)`).join(`
45
+ `);return{name:"Container Resource Health",didPass:!1,message:`${N(n.length,"container")} pinned near its memory limit while burning CPU -- likely stuck in a boot-time retry/fetch loop, not a normal crash:
46
+ ${r}`,fix:"Check the container's boot logs for a network fetch loop (e.g. `bunx <pkg>` re-downloading a CLI on every start instead of using one already installed): docker logs <container>. If a Prisma auto-migration is the cause, set AUTO_MIGRATE=false in the project's .env as a temporary unblock."}},{requiresContainerRuntime:!0,checkName:"Container Resource Health"}),Ar=5e3;async function jr(e,t){let s=g()??process.cwd(),n=ye(x(s),t);return n.length===0?{name:"Service Health",didPass:!0,isSkipped:!0,message:"No routable services to ping"}:be(await ee(n,e))}async function Fr(e,t){let s=g()??process.cwd(),n=x(s),r=ct(at(n,t),{timeoutSeconds:Math.ceil(e/1e3)});return r.length===0?ve([]):(await ee(ye(n,t),e)).some(i=>i.status!==void 0)?ve(await ut(r,lt(s))):{name:"Service Smoke",didPass:!0,isSkipped:!0,message:"No services responded - skipped smoke checks"}}async function Ir(e,t){let s=g()??process.cwd(),n=x(s),r=it(n,t);return r.length===0?{name:"Advertised Endpoints",didPass:!0,isSkipped:!0,message:"No routable services to check"}:At(await ee(r,e))}function Lr(e,t){if(e.length===0){console.log(`${h.green("\u2713")} Nothing to repair
47
+ `);return}for(let s of e){let n=s.status==="planned"?`${h.cyan("would run")}`:s.status==="applied"?h.green("ran"):s.status==="failed"?h.red("failed"):h.gray("skipped"),r=s.status==="planned"?"":` (${s.reason})`;console.log(`${n}: ${s.command}${r}`)}t&&console.log(h.gray(`
48
+ Dry run: nothing was changed.`)),console.log("")}function de(e){for(let t of xs(e))!t.didPass&&!t.isSkipped&&!t.isWarning?(console.log(`${h.red("\u2717")} ${t.message}`),t.fix&&console.log(`${h.blue("\u2139")} Fix: ${t.fix}`)):t.isWarning?(console.log(`${h.yellow("\u26A0")} ${h.yellow(t.message)}`),t.fix&&console.log(`${h.blue("\u2139")} Fix: ${t.fix}`)):t.isSkipped?(console.log(`${h.gray("\u25CB")} ${h.gray(t.message)}`),t.fix&&console.log(`${h.blue("\u2139")} ${t.fix}`)):console.log(`${h.green("\u2713")} ${t.message}`)}function Mr(e,t,s,n={},r){let o=r??[...e,...t];n.all?(console.log(h.bold("Machine")),de(e),console.log(`
49
+ ${h.bold("Project")}`),s?t.length>0&&de(t):console.log(`${h.gray("\u25CB")} ${h.gray("Not in a Flisk project, so project checks were skipped")}`),console.log(""),console.log(ur(o))):(de(o),console.log(""),o.every(a=>a.didPass||a.isSkipped||a.isWarning)&&!s&&(console.log(`${h.gray("\u25CB")} ${h.gray("Not in a Flisk project, so project checks were skipped")}`),console.log("")))}var Hr=new nr("doctor").description("Check environment readiness for Flisk").option("--all","Run every check and show Machine and Project sections with a summary",!1).option("--json","Output a versioned JSON readiness report",!1).exitOverride(e=>{e.exitCode===0&&process.exit(0),Hr.opts().json&&console.log(JSON.stringify(j([],!1,[{code:"USAGE",message:e.message}]))),process.exit(2)}).option("--no-ping","Skip pinging running services' /health endpoints").option("--strict","Fail warnings such as a WSL project under /mnt/c").option("--fix","Repair this project's unused Docker networks and leftover doctor probes",!1).option("--dry-run","With --fix: list the repairs without changing anything",!1).option("--scope <scope>","With --fix: project (default) or machine, which also removes unused networks of other Flisk projects","project").option("-y, --yes","With --fix: apply every repair without asking",!1).option("--ping-timeout <ms>","Per-service ping timeout in milliseconds",String(Ar)).action(async e=>{let t=Number(e.pingTimeout);if(!/^\d+$/.test(e.pingTimeout)||!Number.isSafeInteger(t)||t<=0){let u="--ping-timeout must be a positive integer number of milliseconds";e.json&&console.log(JSON.stringify(j([],!1,[{code:"USAGE",message:u}]))),console.error(u),process.exit(2);return}let s=!["project","machine"].includes(e.scope),n=e.scope!=="project"&&!e.fix;if(s||n||(e.dryRun||e.yes)&&!e.fix){let u=s?`--scope must be project or machine, got "${e.scope}"`:n?"--scope only applies with --fix":`${e.dryRun?"--dry-run":"--yes"} only applies with --fix`;e.json&&console.log(JSON.stringify(j([],!1,[{code:"USAGE",message:u}]))),console.error(u),process.exit(2);return}e.json||console.log("Flisk doctor checks your local Docker + Tilt development environment; it does not check cluster deployments.");let r=It();if(process.platform==="win32"){let w=[{name:"Native Windows support",didPass:!1,message:Ss,fix:"Use WSL2 Ubuntu with Docker Desktop integration. Guide: docs/wsl2.md"},fs(),ms(),await hs()],L=null;try{L=await dt()}catch{}e.json?console.log(JSON.stringify(j(w,!!g(),[],L,{...r,canUp:!1}))):(de(w),console.log("")),console.error(Ss),process.exit(1);return}if(r.kind==="webcontainer"){let u=j([{name:"Host",didPass:!1,message:$e,fix:`Use a machine with Docker. Guide: ${re}`}],!!g(),[],void 0,r);e.json&&console.log(JSON.stringify(u)),console.error($e),process.exit(1);return}e.json||(console.log(`
50
+ ${h.bold("\u{1F50D} Flisk Doctor")}
51
+ `),console.log(`Checking environment...
52
+ `));let o=g(),i;if(e.fix){try{let u;if(o)try{u=mt(o).project.name}catch{}let w=o?ss(o):[],L=await Qt(u,void 0,{tiltPids:w,machine:e.scope==="machine"});i=await Zt(L,{dryRun:e.dryRun,confirm:e.yes||!e.json&&process.stdin.isTTY?async C=>e.yes||await ht({message:`Run \`${C.command}\` (${C.check}, ${C.reason})?`}):void 0})}catch(u){i=[{id:"plan-fixes",check:"Docker networks",scope:"project",command:"docker network ls",status:"failed",reason:`could not list Docker networks: ${(u instanceof Error?u.message:String(u)).split(/\r?\n/)[0]}`}]}e.json||Lr(i,e.dryRun)}let a,c;try{a=await te(o??process.cwd())}catch(u){a=null,c=u instanceof Error?u.message:String(u)}let l=[()=>a?{name:"Host Ports",didPass:!0,message:`HTTP ${a.ingressHttp}, HTTPS ${a.ingressHttps}, Postgres ${a.postgres}`}:{name:"Host Ports",didPass:!1,message:c??"Could not select host ports",fix:"Set FLISK_HTTP_PORT, FLISK_HTTPS_PORT, or FLISK_POSTGRES_PORT to available host ports."},()=>a?Pe(gs,void 0,[a.ingressHttp,a.ingressHttps]):{name:"Ingress Ports",didPass:!1,message:"Ingress port plan is unavailable"},pr,ze,()=>Kt(),T("Docker OS",Ye),Xe,T("Docker Compose",J),T("Docker Versions",z),hr,()=>rr(g()??process.cwd(),e.strict),()=>ir(process.env,e.strict),T("Docker Network Pool",()=>$t()),()=>ts()],f=[()=>Sr(),kr,br,cs,vr,()=>jt(),Cr,Tr,yr,()=>St(),()=>se(),()=>Fe(),()=>Ie(),()=>Le(),()=>Me(void 0,e.strict),()=>yt(),()=>wt(),()=>Pt(),()=>xt(),()=>ne(),()=>kt(),()=>vt(),()=>bt(),()=>Dt(),gr,async()=>{let u=g()??process.cwd(),w=Ot(u)?await ft(u):!0;return xe(gs,u,void 0,w)},T("Container Resource Health",_r),T("Crash-looping containers",()=>{let u=g()??process.cwd(),w=[];try{w=Se(u)}catch{return{name:"Crash-looping containers",didPass:!0,isSkipped:!0,message:"Could not read .env - skipped crash-loop check"}}return Ut(Z(),w)}),T("Tilt Resources",De)];if(e.ping){let u=o?pt(o,a?.ingressHttp):a?.ingressHttp;f.push(T("Service Health",()=>jr(t,u))),f.push(T("Service Smoke",()=>Fr(t,u))),f.push(T("Advertised Endpoints",()=>Ir(t,u)))}let m=!!o,d=[],S=[],k,y=[];if(e.json||!e.all){let u=await rs(l,m?f:[]);k=u.checks,y=u.errors}else{let u=async(C,Fs=!1)=>{let Is=C.map(Y=>{let me=async()=>{try{return await Y()}catch(he){return y.push({code:"INTERNAL",message:he instanceof Error?he.message:String(he)}),{name:Y.checkName??"Doctor check",didPass:!1,isSkipped:!1,message:"Check failed with an internal error"}}};return me.requiresContainerRuntime=Y.requiresContainerRuntime,me.checkName=Y.checkName,me});return lr(Is,{all:!!e.all,containerRuntimeFailed:Fs})};d=await u(l);let w=d.some(C=>!C.didPass&&!C.isSkipped&&!C.isWarning),L=d.some(C=>C.name===v&&!C.didPass);m&&(e.all||!w)&&(S=await u(f,L)),k=[...d,...S]}if(Lt(r.kind))for(let u of k)u.name===v&&!u.didPass&&(u.fix=Ft);let p=j(xs(k),m,y,a,r);i&&(p.data.actions=i),i&&es(i)&&(p.data.ready=!1);let A=os(p),U=p.data.ready;if(e.json){let u;try{u=Se(g()??process.cwd())}catch(w){if(!(w instanceof rt))throw w;console.log(JSON.stringify(j([],m,[...y,{code:"ENV_UNREADABLE",message:w.message}]))),console.error(w.message),process.exit(1)}console.log(JSON.stringify(ot(p,u)));for(let w of y)console.error(Q(w.message,u));A!==0&&process.exit(A);return}for(let u of y)console.error(`${h.red("\u2717")} Doctor check failed: ${u.message}`);Mr(d,S,m,e,k);let Qe=ar(m,U);console.log(`${U?h.green(h.bold("\u2713")):h.red(h.bold("\u2717"))} ${Qe}`),A!==0&&process.exit(A)});function vs(e){return pe(e,I)}var X=`${I[0]}.${I[1]}+`;import{execFileSync as Ds}from"node:child_process";import{accessSync as $s,constants as Cs,readdirSync as Wr}from"node:fs";import{delimiter as Br,join as V}from"node:path";var _="flisk",Ns="@flisk-sh/flisk",Vr="https://github.com/flisk-sh/flisk",Ts="@tdk-landscape/tdk-cli-core";function Es(e=_,t=process.env){let s=t.PATH??t.Path??"";for(let n of s.split(Br)){if(!n)continue;let r=[V(n,e),V(n,`${e}.cmd`),V(n,`${e}.exe`)];for(let o of r)try{return $s(o,Cs.X_OK),!0}catch{}}return!1}function Ur(e=process.env){let t=e.HOME??e.USERPROFILE??"";if(!t)return"flisk-workspace";let s=V(t,"Documents");try{return $s(s,Cs.F_OK),V(s,"flisk")}catch{return V(t,"flisk")}}function Gr(e){try{return Wr(e).every(t=>t.startsWith("."))}catch{return!0}}function Rs(e=process.env,t=process.cwd()){if(!Es(_,e))return`The \`${_}\` command is not on PATH (this run is not a global install). Install it with \`npm install -g ${Ns}\`, then run \`${_} project --yes\`. If npm reports EEXIST for \`flisk\`, the old package still owns that command: run \`npm uninstall -g ${Ts}\` first. The current release is published from ${Vr}.`;if(Gr(t))return`Next: ${_} project --yes`;let s=Ur(e);return`Next: mkdir -p ${s} && cd ${s} && ${_} project --yes
53
+ (${_} project writes .flisk/ and the master configs into the current folder, so it starts clean in a folder of its own. Or clone a starter: ${_} project example)`}function oa(e=process.env){if(Es(_,e))return"present";let t=e.npm_execpath?.includes("bun")?"bun":"npm",s=t==="bun"?"bun remove -g":"npm uninstall -g";try{Ds(s,[Ts],{stdio:"ignore",timeout:12e4})}catch{}try{return Ds(t,["install","-g",Ns],{stdio:"ignore",timeout:3e5}),"installed"}catch{return"failed"}}var Jr=["docker","compose","tilt"],As=["node","bun","ports"],js=["node",...Jr,"bun","ports"];function zr(e,t){return{id:e,ok:t.didPass||!!t.isSkipped,message:t.message,fix:t.fix}}function _s(e){let[t=0,s=0]=String(e).split(".").map(n=>Number.parseInt(n,10));return!Number.isFinite(t)||!Number.isFinite(s)||t<22||t===22&&s<12}async function fe(e,t,s){try{return zr(e,await t())}catch{return{id:e,ok:!1,message:s}}}function Xr(e){return e.isSkipped?{...e,didPass:!1,isSkipped:!1,message:`Could not verify Docker Engine/Compose minimum versions: ${e.message}`,fix:e.fix??"Start Docker and ensure Docker Engine 25+ and Compose 2.20.2+ are installed."}:e}function Yr(e){try{return x(e).some(t=>t.config?.featuresEnabled?.includes("prisma")??!1)}catch{return!1}}async function Qr(e={}){let t=e.cwd??process.cwd(),s=e.scope??"runtime",n=g(t),r=!!n,o=[],i=process.versions.node;if(o.push({id:"node",ok:!_s(i),message:i,fix:_s(i)?`Install Node.js 22.12+ (current: ${i}). https://nodejs.org`:void 0}),s==="runtime"){let p=W();p.isColima&&o.push({id:"colima",ok:p.running,message:p.running?`Colima VM is running${p.arch?` (${p.arch})`:""}`:p.problem??"The Colima VM is not running",fix:p.running?void 0:p.fix}),o.push(await fe("docker",ze,"Docker daemon is not running")),o.push(await fe("compose",async()=>{let[D,A]=await Promise.all([J(),z()]);return D.didPass?Xr(A):D},"Docker Engine or Compose version check failed")),o.push(await fe("tilt",Xe,"Tilt CLI not found"))}let a=n?oe(x(n)):!0,c=!1,l=a?b("bun"):void 0;if(l)try{let p=Os(l,["--version"],{encoding:"utf-8",timeout:3e3}).trim();c=vs(p)}catch{}o.push(a?{id:"bun",ok:c,message:c?`Bun ${X} is available on PATH`:`Bun ${X} not found on PATH`,fix:c?void 0:"curl -fsSL https://bun.sh/install | bash"}:{id:"bun",ok:!0,message:"Bun not needed: no generated JS services"});try{let p=await te(n??t,s==="scaffold"?{inspectDocker:!1}:{});o.push({id:"ports",ok:!0,message:`HTTP ${p.ingressHttp}, HTTPS ${p.ingressHttps}, Postgres ${p.postgres}`})}catch(p){o.push({id:"ports",ok:!1,message:p instanceof Error?p.message:String(p),fix:"Set FLISK_HTTP_PORT, FLISK_HTTPS_PORT, or FLISK_POSTGRES_PORT to available host ports."})}if(n&&s==="runtime"){let p=await fe("nats",()=>ne(n),"NATS broker check failed");if(p.ok||o.push(p),Yr(n)){let D=!1;try{let A=JSON.parse(Kr(qr(n,".flisk",H),"utf-8")),U=String(A?.project?.name??"").replace(/-/g,"_");U&&(D=Os(b("docker")??"docker",["ps","--filter",`label=com.docker.compose.project=${U}`,"--filter","label=com.docker.compose.service=postgres","--filter","health=healthy","--format","{{.Names}}"],{encoding:"utf-8",timeout:3e3}).trim().length>0)}catch{}D||o.push({id:"prisma",ok:!1,message:"A Prisma resource is configured, but the project Postgres service is not healthy",fix:"Run `flisk up` to start the bundled Postgres, then check `flisk doctor`."})}}let f=o.filter(p=>!p.ok).slice(0,8),m=s==="scaffold"?As:js,d=f.some(p=>m.includes(p.id)),S=f.some(p=>p.id==="bun"),k=f.length?d?s==="scaffold"?S?`Project setup blocked. Bun ${X} must be installed on PATH.
54
+ Fix the machine checks below.`:"Project setup blocked. Fix the machine checks below.":S?`Cold start blocked. Bun ${X} must be installed on PATH.
55
+ Prisma/NATS configuration is project-specific and generated after \`flisk project\`. Fix the machine checks below.`:"Cold start blocked. Bun/Prisma/NATS are not the first failure.\nThey are generated after `flisk project`. Fix the machine checks below.":"Machine is ready. Project wiring is not.":"",y=f.length?"":r?"Environment ready for Flisk":`This machine is ready for Flisk.
56
+ ${Rs()}`;return{ok:f.length===0,inProject:r,items:f,header:k,footer:y}}function Zr(e,t={}){let s=[e.header];for(let n of e.items)s.push(`FAIL ${n.id.padEnd(7)} ${n.message}`),n.fix&&s.push(` ${n.fix}`);return e.footer&&(t.includeSuccessFooter??!0)&&s.push(e.footer),s.filter(Boolean).join(`
57
+ `)}async function xa(e={}){let t=e.scope??"runtime",s=await Qr({scope:t}),n=t==="scaffold"?As:js;s.items.some(o=>n.includes(o.id))&&(console.error(Zr(s)),process.exit(1))}function Pa(e=b){return{hasDockerCli:!!e("docker"),hasTiltCli:!!e("tilt")}}function ba(e){let t=[];return e.hasDockerCli||t.push(`Docker is not installed. ${E.dockerMissing}`),e.hasTiltCli||t.push(`Tilt is not installed. ${E.tiltMissing}`),t.push("Docker and Tilt are only needed to start the stack: start them, then run `flisk doctor` (readiness) and `flisk up`."),t}export{In as a,Ln as b,Ho as c,$e as d,Ft as e,It as f,Lt as g,Ce as h,ie as i,ao as j,yo as k,wo as l,xo as m,Oe as n,fn as o,kn as p,$o as q,us as r,ai as s,ci as t,Hr as u,Ts as v,oa as w,Jr as x,As as y,js as z,_s as A,Xr as B,Qr as C,Zr as D,xa as E,Pa as F,ba as G};
@@ -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
  var e="Landscape startup needs Ubuntu on WSL2. Native Windows is inspect-only.";function i(n,t){return n!=="win32"||t==="1"?null:e}export{e as a,i as b};