@flisk-sh/flisk 0.0.0-stage → 1.3.190

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (440) hide show
  1. package/CHANGELOG.md +492 -0
  2. package/LICENSE +21 -0
  3. package/README.md +479 -2
  4. package/Tiltfile +151 -0
  5. package/cli/bin/flisk.js +42 -0
  6. package/cli/dist/agent-runtimes/custom.js +335 -0
  7. package/cli/dist/agent-runtimes/registry.js +34 -0
  8. package/cli/dist/backend-frameworks/elysia.js +38 -0
  9. package/cli/dist/backend-frameworks/express.js +49 -0
  10. package/cli/dist/backend-frameworks/fastify.js +43 -0
  11. package/cli/dist/backend-frameworks/h3.js +37 -0
  12. package/cli/dist/backend-frameworks/koa.js +47 -0
  13. package/cli/dist/backend-frameworks/mcp.js +86 -0
  14. package/cli/dist/backend-frameworks/nestjs.js +55 -0
  15. package/cli/dist/backend-frameworks/registry.js +134 -0
  16. package/cli/dist/backend-frameworks/types.js +1 -0
  17. package/cli/dist/backend-languages/bun.js +76 -0
  18. package/cli/dist/backend-languages/go.js +125 -0
  19. package/cli/dist/backend-languages/node.js +122 -0
  20. package/cli/dist/backend-languages/python.js +94 -0
  21. package/cli/dist/backend-languages/registry.js +37 -0
  22. package/cli/dist/backend-languages/rust.js +82 -0
  23. package/cli/dist/backend-languages/types.js +1 -0
  24. package/cli/dist/cli.js +29 -0
  25. package/cli/dist/commands/__tests__/project-e2e-helpers.js +49 -0
  26. package/cli/dist/commands/__tests__/ui-loading-screen.test.js +16 -0
  27. package/cli/dist/commands/agent.js +182 -0
  28. package/cli/dist/commands/completion-candidates.js +116 -0
  29. package/cli/dist/commands/completion.js +843 -0
  30. package/cli/dist/commands/config.js +362 -0
  31. package/cli/dist/commands/doctor.js +1504 -0
  32. package/cli/dist/commands/down.js +114 -0
  33. package/cli/dist/commands/eject.js +108 -0
  34. package/cli/dist/commands/help.js +152 -0
  35. package/cli/dist/commands/import.js +164 -0
  36. package/cli/dist/commands/logs.js +119 -0
  37. package/cli/dist/commands/maintainers.js +102 -0
  38. package/cli/dist/commands/mcp.js +28 -0
  39. package/cli/dist/commands/networks.js +306 -0
  40. package/cli/dist/commands/project.js +447 -0
  41. package/cli/dist/commands/projects.js +103 -0
  42. package/cli/dist/commands/registry.js +53 -0
  43. package/cli/dist/commands/resource.js +992 -0
  44. package/cli/dist/commands/resources.js +127 -0
  45. package/cli/dist/commands/restart.js +89 -0
  46. package/cli/dist/commands/runtime.js +75 -0
  47. package/cli/dist/commands/stack.js +171 -0
  48. package/cli/dist/commands/stacks.js +71 -0
  49. package/cli/dist/commands/status.js +211 -0
  50. package/cli/dist/commands/ui.js +725 -0
  51. package/cli/dist/commands/up.js +609 -0
  52. package/cli/dist/commands/upgrade.js +840 -0
  53. package/cli/dist/commands/version.js +10 -0
  54. package/cli/dist/components/Accessible.js +11 -0
  55. package/cli/dist/components/BaseTooltip.js +30 -0
  56. package/cli/dist/components/DetailPanel.js +33 -0
  57. package/cli/dist/components/FileTree.js +51 -0
  58. package/cli/dist/components/ResourceSelectInput.js +42 -0
  59. package/cli/dist/components/ResourceTable.js +35 -0
  60. package/cli/dist/components/ServiceIssues.js +13 -0
  61. package/cli/dist/components/TUIHeader.js +27 -0
  62. package/cli/dist/components/TabBar.js +27 -0
  63. package/cli/dist/components/Tooltip.js +13 -0
  64. package/cli/dist/components/index.js +11 -0
  65. package/cli/dist/components/ui-theme.js +120 -0
  66. package/cli/dist/config/platform-standards.js +182 -0
  67. package/cli/dist/frontend-frameworks/lit.js +64 -0
  68. package/cli/dist/frontend-frameworks/preact.js +62 -0
  69. package/cli/dist/frontend-frameworks/qwik.js +61 -0
  70. package/cli/dist/frontend-frameworks/react.js +69 -0
  71. package/cli/dist/frontend-frameworks/registry.js +83 -0
  72. package/cli/dist/frontend-frameworks/solid.js +62 -0
  73. package/cli/dist/frontend-frameworks/svelte.js +67 -0
  74. package/cli/dist/frontend-frameworks/tanstack-router.js +101 -0
  75. package/cli/dist/frontend-frameworks/types.js +1 -0
  76. package/cli/dist/frontend-frameworks/vanilla.js +59 -0
  77. package/cli/dist/frontend-frameworks/vue.js +72 -0
  78. package/cli/dist/generator/__tests__/golden-helpers.js +43 -0
  79. package/cli/dist/generator/extension-fetch.js +291 -0
  80. package/cli/dist/generator/resource-templates.js +133 -0
  81. package/cli/dist/generator/template-engine.js +801 -0
  82. package/cli/dist/index.js +10 -0
  83. package/cli/dist/mcp/server.js +101 -0
  84. package/cli/dist/mcp/tools.js +351 -0
  85. package/cli/dist/program.js +37 -0
  86. package/cli/dist/types/index.js +38 -0
  87. package/cli/dist/utils/agent-host.js +36 -0
  88. package/cli/dist/utils/atomic-write.js +36 -0
  89. package/cli/dist/utils/bun-floor.js +9 -0
  90. package/cli/dist/utils/bun-requirement.js +10 -0
  91. package/cli/dist/utils/cache.js +63 -0
  92. package/cli/dist/utils/cold-preflight.js +257 -0
  93. package/cli/dist/utils/command-helpers.js +57 -0
  94. package/cli/dist/utils/constants.js +160 -0
  95. package/cli/dist/utils/discovery-context.js +71 -0
  96. package/cli/dist/utils/discovery-paths.js +93 -0
  97. package/cli/dist/utils/docker.js +34 -0
  98. package/cli/dist/utils/doctor-crashloop.js +161 -0
  99. package/cli/dist/utils/doctor-fix.js +391 -0
  100. package/cli/dist/utils/doctor-host.js +66 -0
  101. package/cli/dist/utils/doctor-report.js +78 -0
  102. package/cli/dist/utils/doctor-runtime.js +880 -0
  103. package/cli/dist/utils/doctor-starlark.js +132 -0
  104. package/cli/dist/utils/doctor-wiring.js +698 -0
  105. package/cli/dist/utils/down-cleanup.js +125 -0
  106. package/cli/dist/utils/env-validator.js +266 -0
  107. package/cli/dist/utils/errors.js +175 -0
  108. package/cli/dist/utils/exec-async.js +31 -0
  109. package/cli/dist/utils/file-helpers.js +104 -0
  110. package/cli/dist/utils/formatting.js +165 -0
  111. package/cli/dist/utils/generated-paths.js +51 -0
  112. package/cli/dist/utils/help-command.js +11 -0
  113. package/cli/dist/utils/host-port-config.js +140 -0
  114. package/cli/dist/utils/host-port-plan.js +100 -0
  115. package/cli/dist/utils/json-output.js +29 -0
  116. package/cli/dist/utils/machine-output.js +33 -0
  117. package/cli/dist/utils/paths.js +43 -0
  118. package/cli/dist/utils/platform.js +58 -0
  119. package/cli/dist/utils/port-assignment.js +75 -0
  120. package/cli/dist/utils/port-conflict-fix.js +25 -0
  121. package/cli/dist/utils/port-fallback-notice.js +17 -0
  122. package/cli/dist/utils/port-listener-probe.js +20 -0
  123. package/cli/dist/utils/project-config-defaults.js +17 -0
  124. package/cli/dist/utils/project-features.js +91 -0
  125. package/cli/dist/utils/project-templates.js +32 -0
  126. package/cli/dist/utils/prompt.js +97 -0
  127. package/cli/dist/utils/resource-features.js +184 -0
  128. package/cli/dist/utils/resource-kind.js +9 -0
  129. package/cli/dist/utils/schema-version-gate.js +45 -0
  130. package/cli/dist/utils/search-status.js +12 -0
  131. package/cli/dist/utils/secret-redaction.js +73 -0
  132. package/cli/dist/utils/service-config-checks.js +189 -0
  133. package/cli/dist/utils/service-manifest.js +254 -0
  134. package/cli/dist/utils/service-runtime-state.js +66 -0
  135. package/cli/dist/utils/service-urls.js +112 -0
  136. package/cli/dist/utils/services.js +360 -0
  137. package/cli/dist/utils/shared-infra.js +45 -0
  138. package/cli/dist/utils/shared-platform-postgres.js +232 -0
  139. package/cli/dist/utils/single-flight.js +21 -0
  140. package/cli/dist/utils/smoke.js +401 -0
  141. package/cli/dist/utils/spinner.js +40 -0
  142. package/cli/dist/utils/stack-features.js +15 -0
  143. package/cli/dist/utils/stack-status.js +14 -0
  144. package/cli/dist/utils/startup-report.js +78 -0
  145. package/cli/dist/utils/status-message.js +21 -0
  146. package/cli/dist/utils/status-ports.js +33 -0
  147. package/cli/dist/utils/suggestions.js +63 -0
  148. package/cli/dist/utils/tar.js +46 -0
  149. package/cli/dist/utils/tdk-version.js +51 -0
  150. package/cli/dist/utils/terminal-layout.js +19 -0
  151. package/cli/dist/utils/tilt-events.js +194 -0
  152. package/cli/dist/utils/tilt-logs.js +61 -0
  153. package/cli/dist/utils/tilt-port-owner.js +63 -0
  154. package/cli/dist/utils/tilt-process.js +54 -0
  155. package/cli/dist/utils/tilt-resource-state.js +32 -0
  156. package/cli/dist/utils/tilt-startup.js +49 -0
  157. package/cli/dist/utils/tilt-unreachable-message.js +9 -0
  158. package/cli/dist/utils/tilt.js +104 -0
  159. package/cli/dist/utils/ui-keymap.js +129 -0
  160. package/cli/dist/utils/ui-service-state.js +34 -0
  161. package/cli/dist/utils/up-only.js +28 -0
  162. package/cli/dist/utils/up-readiness.js +118 -0
  163. package/cli/dist/utils/url-actions.js +103 -0
  164. package/cli/dist/utils/validation.js +62 -0
  165. package/cli/dist/utils/which.js +56 -0
  166. package/cli/dist/utils/windows-doctor.js +176 -0
  167. package/cli/dist-bundle/chunk-6EA4DGCY.js +2 -0
  168. package/cli/dist-bundle/chunk-BZ4H7MM4.js +3 -0
  169. package/cli/dist-bundle/chunk-CLCUIDBH.js +510 -0
  170. package/cli/dist-bundle/cli.js +2017 -0
  171. package/cli/dist-bundle/cold-preflight-SY26O2IG.js +2 -0
  172. package/cli/dist-bundle/devtools-ZUHXW33W.js +5 -0
  173. package/cli/dist-bundle/extension-fetch-J4FFH7TJ.js +2 -0
  174. package/cli/package.json +83 -0
  175. package/cli/shared-platform-engineering/docker-templates/bun-hoisted-symlink-fix.sh +25 -0
  176. package/cli/shared-platform-engineering/docker-templates/infisical-entrypoint.sh +466 -0
  177. package/cli/shared-platform-engineering/docker-templates/install-deps.sh +154 -0
  178. package/cli/shared-platform-engineering/docker-templates/prisma-bun-client-link-fix.sh +14 -0
  179. package/cli/shared-platform-engineering/docker-templates/prisma-normalize-client.sh +58 -0
  180. package/cli/templates/.tiltignore.hbs +72 -0
  181. package/cli/templates/TILT_RESOURCE_DEFAULTS.star.hbs +220 -0
  182. package/cli/templates/TILT_TECH_STACK.star.hbs +149 -0
  183. package/cli/templates/Tiltfile.hbs +381 -0
  184. package/cli/templates/spec.master.hbs +192 -0
  185. package/discovery/AGENTS.md +362 -0
  186. package/discovery/TILT_DISCOVERY.star +429 -0
  187. package/discovery/Tiltfile +58 -0
  188. package/discovery/config.star +265 -0
  189. package/discovery/constants.star +167 -0
  190. package/discovery/deterministic.star +213 -0
  191. package/discovery/discovery_daemon.star +193 -0
  192. package/discovery/discovery_orchestrator.star +492 -0
  193. package/discovery/filtering.star +7 -0
  194. package/discovery/identity-management-backend/service.yaml +26 -0
  195. package/discovery/identity-management-frontend/service.yaml +29 -0
  196. package/discovery/identity-sdk/service.yaml +9 -0
  197. package/discovery/incremental_discovery.star +215 -0
  198. package/discovery/indexing.star +9 -0
  199. package/discovery/json_manifest_scanner.star +57 -0
  200. package/discovery/libraries.star +48 -0
  201. package/discovery/loading.star +25 -0
  202. package/discovery/manifest/constants.star +106 -0
  203. package/discovery/manifest/loading.star +418 -0
  204. package/discovery/manifest/normalize.star +289 -0
  205. package/discovery/manifest/validation.star +110 -0
  206. package/discovery/normalization.star +13 -0
  207. package/discovery/registry.star +562 -0
  208. package/discovery/resource_snapshot.py +384 -0
  209. package/discovery/resource_snapshot.star +145 -0
  210. package/discovery/schemas.star +3 -0
  211. package/discovery/services/platform/cdc/debezium/nats-connector/service.yaml +9 -0
  212. package/discovery/services/platform/cdc/nats-http-bridge/service.yaml +9 -0
  213. package/discovery/services/platform/orchestrator/orchestrator-glue-backend/service.yaml +26 -0
  214. package/discovery/services/platform/synthetic-monitor/service.yaml +9 -0
  215. package/discovery/test_resource_snapshot.py +253 -0
  216. package/discovery/validation.star +80 -0
  217. package/discovery/versioning.star +3 -0
  218. package/engine/AGENTS.md +706 -0
  219. package/engine/README.md +31 -0
  220. package/engine/REFACTORING_MANIFEST_SYSTEM.md +974 -0
  221. package/engine/Tiltfile +86 -0
  222. package/engine/assets/docker/golden-layers.Dockerfile +204 -0
  223. package/engine/assets/docker/wake-gateway/Dockerfile +28 -0
  224. package/engine/assets/docker/wake-gateway/decide.test.ts +177 -0
  225. package/engine/assets/docker/wake-gateway/decide.ts +135 -0
  226. package/engine/assets/docker/wake-gateway/server.ts +363 -0
  227. package/engine/assets/scripts/cleanup-completed-migrator-images.sh +39 -0
  228. package/engine/assets/scripts/cleanup-tilt-images.sh +122 -0
  229. package/engine/assets/scripts/mac-m1-resource-monitor.sh +123 -0
  230. package/engine/config.star +5 -0
  231. package/engine/entrypoint.star +101 -0
  232. package/engine/lifecycle/orchestrator.star +263 -0
  233. package/engine/paths.star +719 -0
  234. package/engine/schemas/project-schema.json +147 -0
  235. package/engine/schemas/service-schema.json +537 -0
  236. package/engine/scripts/README.md +89 -0
  237. package/engine/scripts/build-and-publish-lib.sh +207 -0
  238. package/engine/scripts/check-lib-publish.sh +87 -0
  239. package/engine/scripts/debug-container.sh +265 -0
  240. package/engine/scripts/generate-manifest.sh +200 -0
  241. package/engine/spec.master +702 -0
  242. package/engine/spec.master.example +341 -0
  243. package/engine/topologies/README.md +33 -0
  244. package/engine/topologies/platform/docker/AGENTS.md +59 -0
  245. package/engine/topologies/platform/docker/auth/auth.star +207 -0
  246. package/engine/topologies/platform/docker/build/frontend_build_plan.star +65 -0
  247. package/engine/topologies/platform/docker/build/golden_image.star +37 -0
  248. package/engine/topologies/platform/docker/build/golden_image_build.star +144 -0
  249. package/engine/topologies/platform/docker/build/golden_image_constants.star +100 -0
  250. package/engine/topologies/platform/docker/build/golden_image_dockerfile.star +263 -0
  251. package/engine/topologies/platform/docker/compose/compose.star +637 -0
  252. package/engine/topologies/platform/docker/compose/compose_helpers.star +54 -0
  253. package/engine/topologies/platform/docker/compose/traefik_standalone.star +171 -0
  254. package/engine/topologies/platform/docker/config/bunignore.star +144 -0
  255. package/engine/topologies/platform/docker/config/dockerignore.star +152 -0
  256. package/engine/topologies/platform/docker/config/healthcheck.star +58 -0
  257. package/engine/topologies/platform/docker/constants.star +211 -0
  258. package/engine/topologies/platform/docker/dockerfile/dockerfile.star +56 -0
  259. package/engine/topologies/platform/docker/dockerfile/language_dockerfile.star +264 -0
  260. package/engine/topologies/platform/docker/generators/golden_docker_generator_v2.star +76 -0
  261. package/engine/topologies/platform/docker/index.star +40 -0
  262. package/engine/topologies/platform/docker/layers/bun_helpers.star +25 -0
  263. package/engine/topologies/platform/docker/layers/infisical/index.star +42 -0
  264. package/engine/topologies/platform/docker/layers/infisical/infisical_docker.star +264 -0
  265. package/engine/topologies/platform/docker/layers/l1_base_layers.star +89 -0
  266. package/engine/topologies/platform/docker/layers/l2_dependency_layers.star +147 -0
  267. package/engine/topologies/platform/docker/layers/l3_builder_layers.star +229 -0
  268. package/engine/topologies/platform/docker/layers/l4_runtime_layers.star +282 -0
  269. package/engine/topologies/platform/docker/layers/prisma/constants.star +138 -0
  270. package/engine/topologies/platform/docker/layers/prisma/db_readiness.star +98 -0
  271. package/engine/topologies/platform/docker/layers/prisma/filesystem_setup.star +131 -0
  272. package/engine/topologies/platform/docker/layers/prisma/migrate_script.star +100 -0
  273. package/engine/topologies/platform/docker/layers/prisma/prisma_build.star +128 -0
  274. package/engine/topologies/platform/docker/layers/prisma/prisma_runtime.star +205 -0
  275. package/engine/topologies/platform/docker/layers/prisma/secret_resolution.star +121 -0
  276. package/engine/topologies/platform/docker/networking/api_path_constants.star +206 -0
  277. package/engine/topologies/platform/docker/networking/sablier_container_cycle.star +31 -0
  278. package/engine/topologies/platform/docker/networking/traefik.star +266 -0
  279. package/engine/topologies/platform/docker/networking/traefik_constants.star +148 -0
  280. package/engine/topologies/platform/docker/networking/traefik_helpers.star +162 -0
  281. package/engine/topologies/platform/docker/networking/traefik_static_routes.star +165 -0
  282. package/engine/topologies/platform/docker/secrets/env_secrets.star +74 -0
  283. package/engine/topologies/platform/docker/secrets/infisical.star +109 -0
  284. package/engine/topologies/platform/net/AGENTS.md +64 -0
  285. package/engine/topologies/platform/net/proxy.star +6 -0
  286. package/engine/topologies/platform/registries/local.star +6 -0
  287. package/engine/topologies/platform/registries/verdaccio_loader.star +20 -0
  288. package/engine/topologies/platform/security/AGENTS.md +49 -0
  289. package/engine/topologies/platform/security/secrets.star +241 -0
  290. package/engine/topologies/platform/state/AGENTS.md +64 -0
  291. package/engine/topologies/platform/state/relational.star +6 -0
  292. package/engine/topologies/tilt/common/AGENTS.md +59 -0
  293. package/engine/topologies/tilt/common/utils.star +409 -0
  294. package/engine/topologies/tilt/common/utils_debug.star +71 -0
  295. package/engine/topologies/tilt/common/utils_deterministic.star +170 -0
  296. package/engine/topologies/tilt/common/utils_docker_networks.star +54 -0
  297. package/engine/topologies/tilt/common/utils_env.star +92 -0
  298. package/engine/topologies/tilt/common/utils_output.star +99 -0
  299. package/engine/topologies/tilt/config/AGENTS.md +68 -0
  300. package/engine/topologies/tilt/config/defaults.star +5 -0
  301. package/engine/topologies/tilt/config/feature_flags.star +12 -0
  302. package/engine/topologies/tilt/config/global.star +57 -0
  303. package/engine/topologies/tilt/config/profiles.star +398 -0
  304. package/engine/topologies/tilt/generators/agents_md.star +64 -0
  305. package/engine/topologies/tilt/generators/api_gateway.star +147 -0
  306. package/engine/topologies/tilt/generators/index.star +126 -0
  307. package/engine/topologies/tilt/generators/infisical/README.md +424 -0
  308. package/engine/topologies/tilt/generators/infisical/examples.star +314 -0
  309. package/engine/topologies/tilt/generators/infisical/index.star +59 -0
  310. package/engine/topologies/tilt/generators/infisical/machine_identity.star +422 -0
  311. package/engine/topologies/tilt/generators/infisical/organization.star +536 -0
  312. package/engine/topologies/tilt/generators/infisical/path_manager.star +478 -0
  313. package/engine/topologies/tilt/generators/infisical/secrets_generator.star +422 -0
  314. package/engine/topologies/tilt/generators/nginx_conf.star +145 -0
  315. package/engine/topologies/tilt/generators/npmrc.star +132 -0
  316. package/engine/topologies/tilt/generators/tsconfig.star +25 -0
  317. package/engine/topologies/tilt/generators/typescript/backend_library_tsconfig.star +73 -0
  318. package/engine/topologies/tilt/generators/typescript/backend_tsconfig.star +137 -0
  319. package/engine/topologies/tilt/generators/typescript/common.star +9 -0
  320. package/engine/topologies/tilt/generators/typescript/frontend_library_tsconfig.star +78 -0
  321. package/engine/topologies/tilt/generators/typescript/frontend_tsconfig.star +140 -0
  322. package/engine/topologies/tilt/generators/typescript/include.star +25 -0
  323. package/engine/topologies/tilt/generators/typescript/playwright_config.star +42 -0
  324. package/engine/topologies/tilt/generators/typescript/prisma_config.star +51 -0
  325. package/engine/topologies/tilt/generators/validators.star +868 -0
  326. package/engine/topologies/tilt/generators/vite/backend.star +80 -0
  327. package/engine/topologies/tilt/generators/vite/frameworks/lit.star +92 -0
  328. package/engine/topologies/tilt/generators/vite/frameworks/preact.star +94 -0
  329. package/engine/topologies/tilt/generators/vite/frameworks/qwik.star +94 -0
  330. package/engine/topologies/tilt/generators/vite/frameworks/react.star +128 -0
  331. package/engine/topologies/tilt/generators/vite/frameworks/solid.star +94 -0
  332. package/engine/topologies/tilt/generators/vite/frameworks/svelte.star +94 -0
  333. package/engine/topologies/tilt/generators/vite/frameworks/vanilla.star +92 -0
  334. package/engine/topologies/tilt/generators/vite/frameworks/vue.star +94 -0
  335. package/engine/topologies/tilt/generators/vite/frontend.star +153 -0
  336. package/engine/topologies/tilt/generators/vite/generators.star +45 -0
  337. package/engine/topologies/tilt/generators/vite/helpers.star +256 -0
  338. package/engine/topologies/tilt/generators/vite/library.star +67 -0
  339. package/engine/topologies/tilt/generators/vite/sdk.star +75 -0
  340. package/engine/topologies/tilt/generators/vite/templates.star +460 -0
  341. package/engine/topologies/tilt/generators/vite_config.star +24 -0
  342. package/engine/topologies/tilt/manifest/AGENTS.md +61 -0
  343. package/engine/topologies/tilt/manifest/README.md +679 -0
  344. package/engine/topologies/tilt/manifest/__init__.star +220 -0
  345. package/engine/topologies/tilt/manifest/constants.star +262 -0
  346. package/engine/topologies/tilt/manifest/errors.star +268 -0
  347. package/engine/topologies/tilt/manifest/integration.star +348 -0
  348. package/engine/topologies/tilt/manifest/json_to_yaml.py +61 -0
  349. package/engine/topologies/tilt/manifest/loader.star +239 -0
  350. package/engine/topologies/tilt/manifest/mapper.star +229 -0
  351. package/engine/topologies/tilt/manifest/parser.star +490 -0
  352. package/engine/topologies/tilt/manifest/schema.star +502 -0
  353. package/engine/topologies/tilt/manifest/tests/test_integration.star +278 -0
  354. package/engine/topologies/tilt/manifest/tests/test_loader_parser.star +475 -0
  355. package/engine/topologies/tilt/manifest/tests/test_manifest.star +319 -0
  356. package/engine/topologies/tilt/manifest/tests/test_validator.star +472 -0
  357. package/engine/topologies/tilt/manifest/validator.star +744 -0
  358. package/engine/topologies/tilt/manifest/yaml_to_json.py +20 -0
  359. package/engine/topologies/tilt/resources/AGENTS.md +71 -0
  360. package/engine/topologies/tilt/resources/build_concurrency.star +56 -0
  361. package/engine/topologies/tilt/resources/conditions.star +5 -0
  362. package/engine/topologies/tilt/resources/databases.star +246 -0
  363. package/engine/topologies/tilt/resources/declaration.star +5 -0
  364. package/engine/topologies/tilt/resources/deps.star +5 -0
  365. package/engine/topologies/tilt/resources/infra-loader.star +504 -0
  366. package/engine/topologies/tilt/resources/libs.star +32 -0
  367. package/engine/topologies/tilt/resources/libs_discovery.star +104 -0
  368. package/engine/topologies/tilt/resources/libs_paths.star +81 -0
  369. package/engine/topologies/tilt/resources/libs_resource_definition.star +153 -0
  370. package/engine/topologies/tilt/resources/libs_setup.star +166 -0
  371. package/engine/topologies/tilt/resources/libs_tsconfig.star +39 -0
  372. package/engine/topologies/tilt/resources/orchestrator/apply.star +79 -0
  373. package/engine/topologies/tilt/resources/orchestrator/apply_compose_resource_registration.star +864 -0
  374. package/engine/topologies/tilt/resources/orchestrator/apply_manifest_orchestration.star +90 -0
  375. package/engine/topologies/tilt/resources/orchestrator/apply_migrator_orchestration.star +150 -0
  376. package/engine/topologies/tilt/resources/orchestrator/apply_resource_validation.star +38 -0
  377. package/engine/topologies/tilt/resources/orchestrator/apply_runtime_flags.star +46 -0
  378. package/engine/topologies/tilt/resources/orchestrator/builders/typescript.star +193 -0
  379. package/engine/topologies/tilt/resources/orchestrator/generators/dependencies/AGENTS.md +75 -0
  380. package/engine/topologies/tilt/resources/orchestrator/generators/dependencies/index.star +23 -0
  381. package/engine/topologies/tilt/resources/orchestrator/generators/dependencies/resolver.star +136 -0
  382. package/engine/topologies/tilt/resources/orchestrator/generators/env.star +219 -0
  383. package/engine/topologies/tilt/resources/orchestrator/generators/frontend.star +172 -0
  384. package/engine/topologies/tilt/resources/orchestrator/generators/manifest_resource.star +577 -0
  385. package/engine/topologies/tilt/resources/orchestrator/helpers.star +35 -0
  386. package/engine/topologies/tilt/resources/orchestrator.star +56 -0
  387. package/engine/topologies/tilt/resources/ordering.star +5 -0
  388. package/engine/topologies/tilt/resources/shared-platform-postgres.star +30 -0
  389. package/engine/topologies/tilt/resources/triggers.star +5 -0
  390. package/engine/topologies/tilt/resources/watchers.star +304 -0
  391. package/engine/where-things-live.star +719 -0
  392. package/examples/tdk-example/LICENSE +21 -0
  393. package/examples/tdk-example/README.md +23 -0
  394. package/examples/tdk-example/TILT_SERVICE_DEFAULTS.star +42 -0
  395. package/examples/tdk-example/TILT_TECH_STACK.star +67 -0
  396. package/examples/tdk-example/Tiltfile +25 -0
  397. package/examples/tdk-example/services/platform/messaging/docker-compose.yml +26 -0
  398. package/examples/tdk-example/services/shop/orders-api/package.json +20 -0
  399. package/examples/tdk-example/services/shop/orders-api/service.json +14 -0
  400. package/examples/tdk-example/services/shop/orders-api/src/index.ts +81 -0
  401. package/examples/tdk-example/services/shop/orders-app/index.html +12 -0
  402. package/examples/tdk-example/services/shop/orders-app/package.json +23 -0
  403. package/examples/tdk-example/services/shop/orders-app/public/.gitkeep +0 -0
  404. package/examples/tdk-example/services/shop/orders-app/service.json +9 -0
  405. package/examples/tdk-example/services/shop/orders-app/src/main.tsx +9 -0
  406. package/examples/tdk-example/services/shop/orders-app/src/orders.tsx +67 -0
  407. package/examples/tdk-example/services/shop/orders-app/src/style.css +15 -0
  408. package/examples/tdk-example/services/shop/orders-worker/package.json +18 -0
  409. package/examples/tdk-example/services/shop/orders-worker/service.json +13 -0
  410. package/examples/tdk-example/services/shop/orders-worker/src/index.ts +33 -0
  411. package/ext/Tiltfile +66 -0
  412. package/ext/ide-components/README.md +221 -0
  413. package/ext/ide-components/code_viewer/server.py +208 -0
  414. package/ext/ide-components/config_inspector/server.py +1052 -0
  415. package/ext/ide-components/file_browser/server.py +287 -0
  416. package/ext/ide-components/shared/config_service.py +471 -0
  417. package/ext/ide-components/shared/file_utils.py +300 -0
  418. package/ext/ide-components/shared/http_utils.py +234 -0
  419. package/ext/ide-components/shared/static/styles.css +1334 -0
  420. package/ext/ide-components/shared/syntax_highlighter.py +142 -0
  421. package/ext/ide-components/shared/template_engine.py +125 -0
  422. package/ext/ide-components/shared/templates/base.html +121 -0
  423. package/ext/ide-components/shared/test_config_service.py +328 -0
  424. package/ext/ide-components/shared/tilt_integration.py +160 -0
  425. package/ext/ui-enhancements/cron-status-server.sh +51 -0
  426. package/ext/ui-enhancements/cron-status-tracker.sh +148 -0
  427. package/ext/ui-enhancements/extension.yaml +36 -0
  428. package/ext/ui-enhancements/tiltfile.py +101 -0
  429. package/ext/ui-enhancements/ui/cron-jobs-tab.css +396 -0
  430. package/ext/ui-enhancements/ui/help-panel.css +279 -0
  431. package/ext/ui-enhancements/ui/icons.css +125 -0
  432. package/ext/ui-enhancements/ui/tooltips.css +114 -0
  433. package/package.json +94 -4
  434. package/shared-platform-engineering/docker-templates/bun-hoisted-symlink-fix.sh +25 -0
  435. package/shared-platform-engineering/docker-templates/infisical-entrypoint.sh +466 -0
  436. package/shared-platform-engineering/docker-templates/install-deps.sh +154 -0
  437. package/shared-platform-engineering/docker-templates/prisma-bun-client-link-fix.sh +14 -0
  438. package/shared-platform-engineering/docker-templates/prisma-normalize-client.sh +58 -0
  439. package/specs/specs/TILT_SERVICE_DEFAULTS.star +207 -0
  440. package/specs/specs/TILT_TECH_STACK.star +161 -0
@@ -0,0 +1,112 @@
1
+ // Copyright (c) 2026 Flisk Landscape contributors
2
+ // SPDX-License-Identifier: MIT
3
+ import { readFileSync } from "node:fs";
4
+ import { join } from "node:path";
5
+ import { PROJECT_JSON } from "./constants.js";
6
+ import { findProjectRoot } from "./paths.js";
7
+ import { isApiServiceType } from "./resource-kind.js";
8
+ export function getProjectName() {
9
+ const root = findProjectRoot();
10
+ if (root) {
11
+ try {
12
+ const content = readFileSync(join(root, ".tdk", PROJECT_JSON), "utf-8");
13
+ const parsed = JSON.parse(content);
14
+ if (parsed?.project?.name) {
15
+ return parsed.project.name;
16
+ }
17
+ }
18
+ catch { }
19
+ }
20
+ return "tdk-project";
21
+ }
22
+ export function resolveSubdomainBases(ingressPort) {
23
+ const projectName = getProjectName();
24
+ const raw = process.env.TDK_SERVICE_BASE_URL ??
25
+ `http://${projectName}.localhost${ingressPort ? `:${ingressPort}` : ""}`;
26
+ try {
27
+ const u = new URL(raw.includes("://") ? raw : `http://${raw}`);
28
+ const host = u.hostname;
29
+ // URL drops a default port (80 for http, 443 for https), so u.port is empty
30
+ // for http://x.localhost:80. Keep it empty instead of re-adding ingressPort.
31
+ const defaultPort = u.protocol === "https:" ? "443" : "80";
32
+ const explicitPort = u.port || (ingressPort ? String(ingressPort) : "");
33
+ const port = explicitPort === defaultPort ? "" : explicitPort;
34
+ if (host === "localhost" || /^\d+\.\d+\.\d+\.\d+$/.test(host)) {
35
+ return {
36
+ appBase: `${u.protocol}//${host}${port ? `:${port}` : ""}`,
37
+ apiBase: `${u.protocol}//${host}${port ? `:${port}` : ""}`,
38
+ };
39
+ }
40
+ const bare = host.replace(/^(app|api)\./, "");
41
+ return {
42
+ appBase: `${u.protocol}//app.${bare}${port ? `:${port}` : ""}`,
43
+ apiBase: `${u.protocol}//api.${bare}${port ? `:${port}` : ""}`,
44
+ };
45
+ }
46
+ catch {
47
+ return {
48
+ appBase: `http://app.${projectName}.localhost`,
49
+ apiBase: `http://api.${projectName}.localhost`,
50
+ };
51
+ }
52
+ }
53
+ export function appendHealthPath(path) {
54
+ return `${path.replace(/\/+$/, "")}/health`;
55
+ }
56
+ /** The route `flisk up` advertises for a service, without the /health suffix. */
57
+ export function resolveServicePath(resource) {
58
+ if (isApiServiceType(resource.config?.appType)) {
59
+ const servicePathName = resource.name.replace(/-api$/, "");
60
+ return resource.config?.apiPath ?? `/api/${servicePathName}`;
61
+ }
62
+ return resource.config?.basePath ?? `/${resource.name}`;
63
+ }
64
+ /**
65
+ * Health URLs for every routable service, matching what `flisk up` prints.
66
+ * Workers, libraries, SDKs and migrators have no Traefik route, so they are
67
+ * skipped rather than reported as unreachable.
68
+ */
69
+ export function buildHealthTargets(resources, ingressPort) {
70
+ return routableTargets(resources, ingressPort, (path) => appendHealthPath(path));
71
+ }
72
+ /**
73
+ * The URL `flisk up` and `flisk networks` advertise for each routable service, with no suffix. A service can answer /health while
74
+ * this URL is a 404 (nothing handles the bare path), which is the dead link users click.
75
+ */
76
+ export function buildAdvertisedTargets(resources, ingressPort) {
77
+ return routableTargets(resources, ingressPort, (path) => path);
78
+ }
79
+ function routableTargets(resources, ingressPort, toPath) {
80
+ const { appBase, apiBase } = resolveSubdomainBases(ingressPort);
81
+ return resources
82
+ .filter((resource) => resource.config?.appType === "frontend" || isApiServiceType(resource.config?.appType))
83
+ .map((resource) => {
84
+ const base = isApiServiceType(resource.config.appType) ? apiBase : appBase;
85
+ return {
86
+ name: resource.name,
87
+ appType: resource.config.appType,
88
+ url: `${base}${toPath(resolveServicePath(resource))}`,
89
+ };
90
+ });
91
+ }
92
+ export async function pingHealthTarget(target, timeoutMs) {
93
+ try {
94
+ const response = await fetch(target.url, {
95
+ method: "GET",
96
+ redirect: "manual",
97
+ signal: AbortSignal.timeout(timeoutMs),
98
+ });
99
+ return { ...target, ok: response.ok, status: response.status };
100
+ }
101
+ catch (err) {
102
+ const error = err instanceof Error && err.name === "TimeoutError"
103
+ ? `no response within ${timeoutMs}ms`
104
+ : err instanceof Error
105
+ ? err.message
106
+ : String(err);
107
+ return { ...target, ok: false, error };
108
+ }
109
+ }
110
+ export async function pingHealthTargets(targets, timeoutMs) {
111
+ return Promise.all(targets.map((target) => pingHealthTarget(target, timeoutMs)));
112
+ }
@@ -0,0 +1,360 @@
1
+ // Copyright (c) 2026 Flisk Landscape contributors
2
+ // SPDX-License-Identifier: MIT
3
+ import fs, { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
4
+ import { dirname, join } from "node:path";
5
+ import { Cache, createCacheValidator } from "./cache.js";
6
+ import { AUTOGENERATED_FILE_PATTERNS, DOCKER_COMPOSE_FILE, PACKAGE_JSON, SERVICE_JSON, SKIP_DIRECTORIES, } from "./constants.js";
7
+ import { errorFactories } from "./errors.js";
8
+ import { formatCount } from "./formatting.js";
9
+ import { findProjectRoot } from "./paths.js";
10
+ import { getInvalidServiceRoutePathFields, validateGeneratedStringFields, validateServiceManifest, } from "./service-manifest.js";
11
+ import { deriveStackStatus } from "./stack-status.js";
12
+ import { includes } from "./validation.js";
13
+ const RESOURCE_JSON_FILENAME = SERVICE_JSON;
14
+ function findServiceJsonFiles(dir, maxDepth = 5, currentDepth = 0) {
15
+ const results = [];
16
+ if (currentDepth > maxDepth) {
17
+ return results;
18
+ }
19
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
20
+ for (const entry of entries) {
21
+ const fullPath = join(dir, entry.name);
22
+ if (entry.isDirectory()) {
23
+ if (shouldSkipDirectory(entry.name))
24
+ continue;
25
+ results.push(...findServiceJsonFiles(fullPath, maxDepth, currentDepth + 1));
26
+ }
27
+ else if (entry.isFile() && entry.name === RESOURCE_JSON_FILENAME) {
28
+ results.push(fullPath);
29
+ }
30
+ }
31
+ return results;
32
+ }
33
+ export function discoverServiceManifestPaths(projectRoot) {
34
+ return findServiceJsonFiles(projectRoot);
35
+ }
36
+ function shouldSkipDirectory(name) {
37
+ return includes(SKIP_DIRECTORIES, name) || name.startsWith(".");
38
+ }
39
+ function isValidResourceConfig(value) {
40
+ if (!value || typeof value !== "object")
41
+ return false;
42
+ const config = value;
43
+ // Accept runtime, appType, or type (for backward compatibility with existing service.json files)
44
+ const hasRuntimeOrAppType = typeof config.runtime === "string" ||
45
+ typeof config.appType === "string" ||
46
+ typeof config.type === "string";
47
+ return typeof config.appName === "string" && hasRuntimeOrAppType;
48
+ }
49
+ // Discovery may be invoked more than once per process,
50
+ // so remember what was already printed and show each warning once.
51
+ const printedWarnings = new Set();
52
+ export function resetPrintedServiceWarnings() {
53
+ printedWarnings.clear();
54
+ }
55
+ class InvalidServiceJsonError extends Error {
56
+ reason;
57
+ constructor(reason) {
58
+ super(reason);
59
+ this.reason = reason;
60
+ this.name = "InvalidServiceJsonError";
61
+ }
62
+ }
63
+ function errorMessage(error) {
64
+ return error instanceof Error ? error.message : String(error);
65
+ }
66
+ function parseResource(serviceJsonPath) {
67
+ let content;
68
+ try {
69
+ content = fs.readFileSync(serviceJsonPath, "utf-8");
70
+ }
71
+ catch (error) {
72
+ throw new InvalidServiceJsonError(`could not read file: ${errorMessage(error)}`);
73
+ }
74
+ let parsed;
75
+ try {
76
+ parsed = JSON.parse(content);
77
+ }
78
+ catch (error) {
79
+ throw new InvalidServiceJsonError(`invalid JSON: ${errorMessage(error)}`);
80
+ }
81
+ if (!isValidResourceConfig(parsed)) {
82
+ throw new InvalidServiceJsonError("missing required fields (appName, runtime or appType)");
83
+ }
84
+ const invalidRoutePathFields = getInvalidServiceRoutePathFields(parsed);
85
+ if (invalidRoutePathFields.length > 0) {
86
+ throw new InvalidServiceJsonError(invalidRoutePathFields.map((field) => `${field}: expected a string`).join("; "));
87
+ }
88
+ const unsafeFields = validateGeneratedStringFields(parsed, serviceJsonPath);
89
+ if (unsafeFields.length > 0)
90
+ throw new InvalidServiceJsonError(unsafeFields.join("; "));
91
+ const parsedConfig = parsed;
92
+ for (const warning of validateServiceManifest(parsed, serviceJsonPath).warnings) {
93
+ // The warning names the file and field and says what is wrong (unknown, deprecated, ignored), so do not prefix it.
94
+ if (printedWarnings.has(warning))
95
+ continue;
96
+ printedWarnings.add(warning);
97
+ console.warn(`⚠️ ${warning}`);
98
+ }
99
+ const config = {
100
+ ...parsedConfig,
101
+ appType: (parsedConfig.appType ||
102
+ parsedConfig.type),
103
+ };
104
+ const resourceDir = dirname(serviceJsonPath);
105
+ return {
106
+ name: config.appName,
107
+ path: resourceDir,
108
+ configPath: serviceJsonPath,
109
+ config,
110
+ stack: config.stack,
111
+ port: config.port,
112
+ type: config.appType,
113
+ };
114
+ }
115
+ export function discoverResourcesWithProblems(projectRoot) {
116
+ const serviceJsonPaths = findServiceJsonFiles(projectRoot);
117
+ const resources = [];
118
+ const problems = [];
119
+ for (const path of serviceJsonPaths) {
120
+ try {
121
+ resources.push(parseResource(path));
122
+ }
123
+ catch (error) {
124
+ problems.push({
125
+ path,
126
+ reason: error instanceof InvalidServiceJsonError ? error.reason : errorMessage(error),
127
+ });
128
+ }
129
+ }
130
+ return { resources, problems };
131
+ }
132
+ export function warnAboutSkippedFiles(problems) {
133
+ for (const problem of problems) {
134
+ const warning = `skipped ${problem.path}: ${problem.reason}`;
135
+ if (printedWarnings.has(warning))
136
+ continue;
137
+ printedWarnings.add(warning);
138
+ console.warn(`⚠️ ${warning}`);
139
+ }
140
+ }
141
+ export function discoverResourcesFromRoot(projectRoot) {
142
+ const { resources, problems } = discoverResourcesWithProblems(projectRoot);
143
+ warnAboutSkippedFiles(problems);
144
+ return resources;
145
+ }
146
+ export function discoverResources() {
147
+ const projectRoot = findProjectRoot();
148
+ if (!projectRoot) {
149
+ throw errorFactories.notInProject();
150
+ }
151
+ return discoverResourcesFromRoot(projectRoot);
152
+ }
153
+ export function discoverResourcesStrict(discovered) {
154
+ let result = discovered;
155
+ if (!result) {
156
+ const projectRoot = findProjectRoot();
157
+ if (!projectRoot) {
158
+ throw errorFactories.notInProject();
159
+ }
160
+ result = discoverResourcesWithProblems(projectRoot);
161
+ }
162
+ if (result.problems.length > 0) {
163
+ throw new Error(result.problems
164
+ .map((problem) => `Invalid service.json at ${problem.path}: ${problem.reason}`)
165
+ .join("\n"));
166
+ }
167
+ return result.resources;
168
+ }
169
+ /**
170
+ * Unique, sorted `stack` values across discovered service.json files under `projectRoot`.
171
+ * Tilt's discovery groups services by this same field (see tdk-cli-extensions
172
+ * discovery_orchestrator.star), so these are the names that must appear in a
173
+ * stack's `services` list in .tdk/project.json for that group to be enabled.
174
+ */
175
+ export function discoverStackNames(projectRoot, resources) {
176
+ const resourcesToScan = resources ?? discoverResourcesFromRoot(projectRoot);
177
+ return getAllStacks(resourcesToScan);
178
+ }
179
+ export function getAllStacks(resources) {
180
+ const resourcesToScan = resources || discoverResources();
181
+ const stacks = new Set();
182
+ for (const resource of resourcesToScan) {
183
+ if (resource.stack) {
184
+ stacks.add(resource.stack);
185
+ }
186
+ }
187
+ return Array.from(stacks).sort();
188
+ }
189
+ export function discoverStacks(resources = discoverResources()) {
190
+ const stackMap = new Map();
191
+ for (const resource of resources) {
192
+ if (resource.stack) {
193
+ const stackResources = stackMap.get(resource.stack);
194
+ if (stackResources) {
195
+ stackResources.push(resource);
196
+ }
197
+ else {
198
+ stackMap.set(resource.stack, [resource]);
199
+ }
200
+ }
201
+ }
202
+ const stacks = [];
203
+ for (const [name, stackResources] of stackMap) {
204
+ stacks.push({
205
+ name,
206
+ description: formatCount(stackResources.length, "resource"),
207
+ resources: stackResources,
208
+ resourceCount: stackResources.length,
209
+ });
210
+ }
211
+ return stacks.sort((a, b) => a.name.localeCompare(b.name));
212
+ }
213
+ export function getResourcesForStack(stackName, resources) {
214
+ const allResources = resources ?? discoverResources();
215
+ return allResources.filter((r) => r.stack === stackName);
216
+ }
217
+ export function stackExists(stackName, resources) {
218
+ const resourcesToSearch = resources ?? discoverResources();
219
+ return resourcesToSearch.some((resource) => resource.stack === stackName);
220
+ }
221
+ /**
222
+ * Cache TTL in milliseconds
223
+ */
224
+ const CACHE_TTL_MS = 5000;
225
+ const resourcesCache = new Cache({ ttlMs: CACHE_TTL_MS });
226
+ const stacksCache = new Cache({ ttlMs: CACHE_TTL_MS });
227
+ const cacheValidator = createCacheValidator(CACHE_TTL_MS);
228
+ export function clearMetadataCache() {
229
+ resourcesCache.clear();
230
+ stacksCache.clear();
231
+ cacheValidator.reset();
232
+ }
233
+ function detectFileType(filename, content) {
234
+ if (filename === "Dockerfile" || filename.startsWith("docker-compose")) {
235
+ return "docker";
236
+ }
237
+ if (filename === "Tiltfile" || filename.endsWith(".star")) {
238
+ return "tilt";
239
+ }
240
+ if (filename === "vite.config.ts" || filename === "tsconfig.json" || filename === PACKAGE_JSON) {
241
+ return "config";
242
+ }
243
+ if (filename === "schema.prisma" || filename.includes("migration")) {
244
+ return "prisma";
245
+ }
246
+ if (content) {
247
+ const firstLines = content.split("\n").slice(0, 10).join("\n");
248
+ if (firstLines.includes("GENERATED BY Flisk") || firstLines.includes("AUTOGENERATED")) {
249
+ return "generated";
250
+ }
251
+ }
252
+ return "unknown";
253
+ }
254
+ export function getResourceMetadata(resource) {
255
+ const cacheKey = resource.configPath;
256
+ if (cacheValidator.isValid()) {
257
+ const cached = resourcesCache.get(cacheKey);
258
+ if (cached) {
259
+ return cached;
260
+ }
261
+ }
262
+ const resourceDir = resource.path;
263
+ const stats = statSync(resource.configPath);
264
+ const createdAt = stats.mtime.toISOString();
265
+ const lastModified = stats.mtime.toISOString();
266
+ const autogeneratedFiles = discoverAutogeneratedFiles(resourceDir);
267
+ const hasDockerfile = existsSync(join(resourceDir, "Dockerfile"));
268
+ const hasTiltfile = existsSync(join(resourceDir, "Tiltfile"));
269
+ const hasDockerCompose = existsSync(join(resourceDir, DOCKER_COMPOSE_FILE)) ||
270
+ existsSync(join(resourceDir, "docker-compose.yaml"));
271
+ const configType = resource.config?.appType;
272
+ let type = configType || "backend";
273
+ if (!configType) {
274
+ if (resource.name.includes("frontend")) {
275
+ type = "frontend";
276
+ }
277
+ else if (resource.name.includes("sdk") ||
278
+ resource.name.includes("lib") ||
279
+ resource.name.includes("infra")) {
280
+ type = "library";
281
+ }
282
+ }
283
+ const metadata = {
284
+ name: resource.name,
285
+ stack: resource.stack,
286
+ type,
287
+ port: resource.config?.port,
288
+ createdAt,
289
+ lastModified,
290
+ dependencies: resource.config?.dependsOn ?? [],
291
+ hasDockerfile,
292
+ hasTiltfile,
293
+ hasDockerCompose,
294
+ autogeneratedFiles,
295
+ status: "unknown",
296
+ };
297
+ resourcesCache.set(cacheKey, metadata);
298
+ cacheValidator.markUpdated();
299
+ return metadata;
300
+ }
301
+ function discoverAutogeneratedFiles(resourceDir) {
302
+ const files = [];
303
+ for (const pattern of AUTOGENERATED_FILE_PATTERNS) {
304
+ const filePath = join(resourceDir, pattern);
305
+ if (existsSync(filePath)) {
306
+ const stats = statSync(filePath);
307
+ const content = readFileSync(filePath, "utf-8");
308
+ files.push({
309
+ name: pattern,
310
+ path: filePath,
311
+ type: detectFileType(pattern, content),
312
+ size: stats.size,
313
+ lastModified: stats.mtime.toISOString(),
314
+ });
315
+ }
316
+ }
317
+ const prismaDir = join(resourceDir, "prisma");
318
+ if (existsSync(prismaDir)) {
319
+ const entries = readdirSync(prismaDir);
320
+ for (const entry of entries) {
321
+ if (entry === "schema.prisma" || entry.includes("migration")) {
322
+ const filePath = join(prismaDir, entry);
323
+ const stats = statSync(filePath);
324
+ files.push({
325
+ name: `prisma/${entry}`,
326
+ path: filePath,
327
+ type: "prisma",
328
+ size: stats.size,
329
+ lastModified: stats.mtime.toISOString(),
330
+ });
331
+ }
332
+ }
333
+ }
334
+ return files.sort((a, b) => a.name.localeCompare(b.name));
335
+ }
336
+ export function getStackMetadata(stack) {
337
+ const cacheKey = stack.name;
338
+ if (cacheValidator.isValid()) {
339
+ const cached = stacksCache.get(cacheKey);
340
+ if (cached) {
341
+ return cached;
342
+ }
343
+ }
344
+ const resourcesMetadata = stack.resources.map((r) => getResourceMetadata(r));
345
+ const timestamps = resourcesMetadata.map((r) => new Date(r.createdAt).getTime());
346
+ const earliestTimestamp = Math.min(...timestamps);
347
+ const latestTimestamp = Math.max(...timestamps);
348
+ const overallStatus = deriveStackStatus(resourcesMetadata.map((r) => r.status));
349
+ const metadata = {
350
+ name: stack.name,
351
+ resourceCount: resourcesMetadata.length,
352
+ createdAt: new Date(earliestTimestamp).toISOString(),
353
+ lastModified: new Date(latestTimestamp).toISOString(),
354
+ resources: resourcesMetadata,
355
+ overallStatus,
356
+ };
357
+ stacksCache.set(cacheKey, metadata);
358
+ cacheValidator.markUpdated();
359
+ return metadata;
360
+ }
@@ -0,0 +1,45 @@
1
+ // Copyright (c) 2026 Flisk Landscape contributors
2
+ // SPDX-License-Identifier: MIT
3
+ import { readFileSync } from "node:fs";
4
+ import { join } from "node:path";
5
+ import { DATABASE_MANAGEMENT_FEATURE, PROJECT_JSON } from "./constants.js";
6
+ import { POSTGRES_DEPENDENCY_NAMES } from "./shared-platform-postgres.js";
7
+ /** A resource uses the shared database when its features or dependsOn ask for it. */
8
+ export function usesSharedPostgres(resource) {
9
+ const config = resource.config;
10
+ if (!config)
11
+ return false;
12
+ // service.json is not type-checked here, so a malformed value must not throw inside `flisk status`.
13
+ if (Array.isArray(config.featuresEnabled) &&
14
+ config.featuresEnabled.includes(DATABASE_MANAGEMENT_FEATURE))
15
+ return true;
16
+ const dependsOn = Array.isArray(config.dependsOn) ? config.dependsOn : [];
17
+ return dependsOn.some((name) => POSTGRES_DEPENDENCY_NAMES.includes(name));
18
+ }
19
+ export function groupSharedPostgres(projectName, stacks) {
20
+ const prefix = projectName.replace(/-/g, "_");
21
+ const databases = [];
22
+ for (const stack of [...stacks].sort((a, b) => a.name.localeCompare(b.name))) {
23
+ const services = stack.resources.filter(usesSharedPostgres).map((resource) => resource.name);
24
+ if (services.length === 0)
25
+ continue;
26
+ databases.push({
27
+ name: `${prefix}_${stack.name.replace(/-/g, "_")}`,
28
+ stack: stack.name,
29
+ services: services.sort(),
30
+ });
31
+ }
32
+ if (databases.length === 0)
33
+ return null;
34
+ return { name: "postgres", databases };
35
+ }
36
+ /** `project.name` from `.tdk/project.json`, or null when the project file is missing or unreadable. */
37
+ export function readProjectName(projectRoot) {
38
+ try {
39
+ const parsed = JSON.parse(readFileSync(join(projectRoot, ".tdk", PROJECT_JSON), "utf-8"));
40
+ return typeof parsed?.project?.name === "string" ? parsed.project.name : null;
41
+ }
42
+ catch {
43
+ return null;
44
+ }
45
+ }