@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,122 @@
1
+ export const NODE_DEV_COMMAND = "node --watch src/index.js";
2
+ export const nodeBackendProvider = {
3
+ id: "node",
4
+ label: "Node.js 22",
5
+ devCommand: NODE_DEV_COMMAND,
6
+ watch: ["src/**/*"],
7
+ installHint: "npm install # optional: Docker builds the image for you",
8
+ createFiles(name) {
9
+ return [
10
+ {
11
+ filename: "package.json",
12
+ content: `{
13
+ "name": "${name}",
14
+ "version": "1.0.0",
15
+ "type": "module",
16
+ "scripts": {
17
+ "dev": "node --watch src/index.js",
18
+ "start": "node src/index.js",
19
+ "test": "node --test"
20
+ }
21
+ }
22
+ `,
23
+ description: "Generating package.json",
24
+ emoji: "📦",
25
+ },
26
+ {
27
+ // The generated Dockerfile runs `npm ci`, which needs a lockfile. This one matches the dependency-free package.json;
28
+ // `npm install` regenerates it once the project adds dependencies.
29
+ filename: "package-lock.json",
30
+ content: `{
31
+ "name": "${name}",
32
+ "version": "1.0.0",
33
+ "lockfileVersion": 3,
34
+ "requires": true,
35
+ "packages": {
36
+ "": {
37
+ "name": "${name}",
38
+ "version": "1.0.0"
39
+ }
40
+ }
41
+ }
42
+ `,
43
+ description: "Generating package-lock.json",
44
+ emoji: "🔒",
45
+ },
46
+ {
47
+ filename: "src/index.js",
48
+ content: `import http from "node:http";
49
+
50
+ const name = "${name}";
51
+ const port = Number(process.env.PORT) || 3000;
52
+
53
+ function sendJson(res, status, data) {
54
+ res.writeHead(status, { "Content-Type": "application/json" });
55
+ res.end(JSON.stringify(data));
56
+ }
57
+
58
+ export const server = http.createServer((req, res) => {
59
+ const url = new URL(req.url, \`http://\${req.headers.host || "localhost"}\`);
60
+
61
+ // Health check endpoint (required by TILT_RESOURCE_DEFAULTS.star)
62
+ if (req.method === "GET" && url.pathname === "/health") {
63
+ return sendJson(res, 200, { status: "ok", service: name });
64
+ }
65
+
66
+ if (req.method === "GET" && url.pathname === "/") {
67
+ return sendJson(res, 200, {
68
+ service: name,
69
+ version: "1.0.0",
70
+ endpoints: ["/health"],
71
+ });
72
+ }
73
+
74
+ return sendJson(res, 404, { error: "Not Found" });
75
+ });
76
+
77
+ if (process.env.NODE_ENV !== "test") {
78
+ // "0.0.0.0" listens on every interface, which Traefik needs inside the container network.
79
+ server.listen(port, "0.0.0.0", () => {
80
+ console.log(\`\\n🚀 \${name} running on http://localhost:\${port}\`);
81
+ console.log(\`📊 Health check: http://localhost:\${port}/health\\n\`);
82
+ });
83
+ }
84
+ `,
85
+ description: "Generating backend source",
86
+ emoji: "💻",
87
+ },
88
+ {
89
+ filename: "tests/health.test.js",
90
+ content: `import assert from "node:assert/strict";
91
+ import { after, before, describe, it } from "node:test";
92
+ import { server } from "../src/index.js";
93
+
94
+ describe("health check", () => {
95
+ let baseUrl;
96
+
97
+ before((_, done) => {
98
+ server.listen(0, "127.0.0.1", () => {
99
+ const address = server.address();
100
+ baseUrl = \`http://127.0.0.1:\${address.port}\`;
101
+ done();
102
+ });
103
+ });
104
+
105
+ after((_, done) => {
106
+ server.close(done);
107
+ });
108
+
109
+ it("GET /health returns 200 with ok status", async () => {
110
+ const res = await fetch(\`\${baseUrl}/health\`);
111
+ assert.equal(res.status, 200);
112
+ const body = await res.json();
113
+ assert.deepEqual(body, { status: "ok", service: "${name}" });
114
+ });
115
+ });
116
+ `,
117
+ description: "Generating smoke test",
118
+ emoji: "🧪",
119
+ },
120
+ ];
121
+ },
122
+ };
@@ -0,0 +1,94 @@
1
+ export const PYTHON_DEV_COMMAND = "uvicorn main:app --app-dir src --host 0.0.0.0 --port ${PORT:-4000} --reload --reload-dir src";
2
+ export const pythonBackendProvider = {
3
+ id: "python",
4
+ label: "Python 3.12 + FastAPI",
5
+ devCommand: PYTHON_DEV_COMMAND,
6
+ watch: ["src/**/*"],
7
+ installHint: 'pip install -e ".[dev]" # optional: Docker builds the image for you',
8
+ createFiles(name) {
9
+ return [
10
+ {
11
+ filename: "pyproject.toml",
12
+ content: `[project]
13
+ name = "${name}"
14
+ version = "0.0.1"
15
+ requires-python = ">=3.12"
16
+ dependencies = [
17
+ "fastapi==0.115.6",
18
+ "uvicorn[standard]==0.34.0",
19
+ ]
20
+
21
+ [project.optional-dependencies]
22
+ dev = [
23
+ "pytest==9.0.3",
24
+ "httpx==0.28.1",
25
+ ]
26
+
27
+ [build-system]
28
+ requires = ["setuptools>=68"]
29
+ build-backend = "setuptools.build_meta"
30
+
31
+ # Only the dependencies are installed into the image; the source is synced for live reload.
32
+ [tool.setuptools]
33
+ py-modules = []
34
+
35
+ [tool.pytest.ini_options]
36
+ pythonpath = ["src"]
37
+ testpaths = ["tests"]
38
+ `,
39
+ description: "Generating pyproject.toml",
40
+ emoji: "📦",
41
+ },
42
+ {
43
+ filename: "src/main.py",
44
+ content: `import os
45
+
46
+ from fastapi import FastAPI
47
+
48
+ app = FastAPI(title="${name}")
49
+
50
+
51
+ @app.get("/health")
52
+ def health() -> dict[str, str]:
53
+ return {"status": "ok", "service": "${name}"}
54
+
55
+
56
+ @app.get("/")
57
+ def root() -> dict[str, object]:
58
+ return {"service": "${name}", "version": "1.0.0", "endpoints": ["/health"]}
59
+
60
+
61
+ if __name__ == "__main__":
62
+ import uvicorn
63
+
64
+ uvicorn.run(app, host="0.0.0.0", port=int(os.environ.get("PORT", "3000")))
65
+ `,
66
+ description: "Generating backend source",
67
+ emoji: "💻",
68
+ },
69
+ {
70
+ filename: "tests/test_health.py",
71
+ content: `from fastapi.testclient import TestClient
72
+
73
+ from main import app
74
+
75
+ client = TestClient(app)
76
+
77
+
78
+ def test_health() -> None:
79
+ response = client.get("/health")
80
+ assert response.status_code == 200
81
+ assert response.json() == {"status": "ok", "service": "${name}"}
82
+
83
+
84
+ def test_root() -> None:
85
+ response = client.get("/")
86
+ assert response.status_code == 200
87
+ assert response.json() == {"service": "${name}", "version": "1.0.0", "endpoints": ["/health"]}
88
+ `,
89
+ description: "Generating test file",
90
+ emoji: "🧪",
91
+ },
92
+ ];
93
+ },
94
+ };
@@ -0,0 +1,37 @@
1
+ // Copyright (c) 2026 Flisk Landscape contributors
2
+ // SPDX-License-Identifier: MIT
3
+ import { TdkError } from "../utils/errors.js";
4
+ import { bunBackendProvider } from "./bun.js";
5
+ import { goBackendProvider } from "./go.js";
6
+ import { nodeBackendProvider } from "./node.js";
7
+ import { pythonBackendProvider } from "./python.js";
8
+ import { rustBackendProvider } from "./rust.js";
9
+ export const DEFAULT_BACKEND_LANGUAGE = "bun";
10
+ export const BACKEND_LANGUAGES = {
11
+ bun: bunBackendProvider,
12
+ python: pythonBackendProvider,
13
+ go: goBackendProvider,
14
+ rust: rustBackendProvider,
15
+ node: nodeBackendProvider,
16
+ };
17
+ export function getBackendLanguage(languageId) {
18
+ const id = (languageId ?? DEFAULT_BACKEND_LANGUAGE).trim().toLowerCase();
19
+ const provider = Object.hasOwn(BACKEND_LANGUAGES, id) ? BACKEND_LANGUAGES[id] : undefined;
20
+ if (!provider) {
21
+ const supportedIds = Object.keys(BACKEND_LANGUAGES).join(", ");
22
+ throw new TdkError(`Unknown backend language "${languageId}". Supported languages: ${supportedIds}.`, [`Use one of: ${supportedIds}`, `Omit --language to use ${DEFAULT_BACKEND_LANGUAGE}`]);
23
+ }
24
+ return provider;
25
+ }
26
+ /** Returns the provider for a backend, or undefined for other types. Rejects --language elsewhere. */
27
+ export function resolveBackendLanguage(resourceType, languageId) {
28
+ if (resourceType !== "backend") {
29
+ if (languageId !== undefined) {
30
+ throw new TdkError("--language can only be used with --type backend.", [
31
+ "Add --type backend, or drop --language for this resource type",
32
+ ]);
33
+ }
34
+ return undefined;
35
+ }
36
+ return getBackendLanguage(languageId);
37
+ }
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Rust is compiled into the image and has no reload process, so the dev command is only what a developer
3
+ * would run by hand. Tilt rebuilds the image when a watched file changes (the engine returns no live-update rules).
4
+ */
5
+ export const RUST_DEV_COMMAND = "cargo run";
6
+ export const rustBackendProvider = {
7
+ id: "rust",
8
+ label: "Rust (axum)",
9
+ devCommand: RUST_DEV_COMMAND,
10
+ watch: ["src/**/*.rs", "Cargo.toml", "Cargo.lock"],
11
+ installHint: "cargo build # optional: Docker builds the image for you",
12
+ createFiles(name) {
13
+ return [
14
+ {
15
+ filename: "Cargo.toml",
16
+ content: `[package]
17
+ name = "${name}"
18
+ version = "0.1.0"
19
+ edition = "2021"
20
+
21
+ # The image copies the release binary by this fixed name.
22
+ [[bin]]
23
+ name = "app"
24
+ path = "src/main.rs"
25
+
26
+ [dependencies]
27
+ axum = "0.8"
28
+ serde_json = "1"
29
+ tokio = { version = "1", features = ["macros", "rt-multi-thread", "net"] }
30
+ `,
31
+ description: "Generating Cargo.toml",
32
+ emoji: "📦",
33
+ },
34
+ {
35
+ filename: "src/main.rs",
36
+ content: `use axum::{routing::get, Json, Router};
37
+ use serde_json::{json, Value};
38
+
39
+ fn app() -> Router {
40
+ Router::new()
41
+ .route("/", get(root))
42
+ // Health check endpoint (required by TILT_RESOURCE_DEFAULTS.star)
43
+ .route("/health", get(health))
44
+ }
45
+
46
+ async fn root() -> Json<Value> {
47
+ Json(json!({ "service": "${name}", "version": "1.0.0", "endpoints": ["/health"] }))
48
+ }
49
+
50
+ async fn health() -> Json<Value> {
51
+ Json(json!({ "status": "ok", "service": "${name}" }))
52
+ }
53
+
54
+ #[tokio::main]
55
+ async fn main() {
56
+ let port = std::env::var("PORT").unwrap_or_else(|_| "3000".to_string());
57
+
58
+ // 0.0.0.0 listens on every interface, which Traefik needs inside the container network.
59
+ let listener = tokio::net::TcpListener::bind(format!("0.0.0.0:{port}"))
60
+ .await
61
+ .expect("failed to bind the port");
62
+ println!("${name} listening on 0.0.0.0:{port}");
63
+ axum::serve(listener, app()).await.expect("server error");
64
+ }
65
+
66
+ #[cfg(test)]
67
+ mod tests {
68
+ use super::*;
69
+
70
+ #[tokio::test]
71
+ async fn health_reports_ok() {
72
+ let Json(body) = health().await;
73
+ assert_eq!(body["status"], "ok");
74
+ }
75
+ }
76
+ `,
77
+ description: "Generating backend source and smoke test",
78
+ emoji: "💻",
79
+ },
80
+ ];
81
+ },
82
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env node
2
+ // Copyright (c) 2026 Flisk Landscape contributors
3
+ // SPDX-License-Identifier: MIT
4
+ import { showHelp } from "./commands/help.js";
5
+ import { createProgram } from "./program.js";
6
+ import { formatColdPreflight, runColdPreflight } from "./utils/cold-preflight.js";
7
+ import { unknownHelpTarget } from "./utils/help-command.js";
8
+ const program = createProgram();
9
+ // Default: show help if no command provided
10
+ if (process.argv.length === 2) {
11
+ const result = await runColdPreflight();
12
+ console.log(formatColdPreflight(result));
13
+ console.log("\nCommands: flisk doctor | flisk project --yes | flisk --help");
14
+ process.exit(result.ok ? 0 : 1);
15
+ }
16
+ if (process.argv[2] === "--doctor")
17
+ process.argv[2] = "doctor";
18
+ if (process.argv.length === 3 && ["-h", "--help", "help"].includes(process.argv[2])) {
19
+ showHelp();
20
+ process.exit(0);
21
+ }
22
+ const unknownHelp = unknownHelpTarget(process.argv.slice(2), program.commands);
23
+ if (unknownHelp) {
24
+ program.error(`error: unknown command '${unknownHelp}'`, {
25
+ exitCode: 1,
26
+ code: "commander.unknownCommand",
27
+ });
28
+ }
29
+ program.parse();
@@ -0,0 +1,49 @@
1
+ // Copyright (c) 2026 Flisk Landscape contributors
2
+ // SPDX-License-Identifier: MIT
3
+ import { execFileSync, spawnSync } from "node:child_process";
4
+ import { cpSync, mkdtempSync } from "node:fs";
5
+ import { tmpdir } from "node:os";
6
+ import { dirname, join, resolve } from "node:path";
7
+ import { fileURLToPath } from "node:url";
8
+ import { expect } from "vitest";
9
+ const __dirname = dirname(fileURLToPath(import.meta.url));
10
+ export const repoRoot = resolve(__dirname, "../../../..");
11
+ export const cliBin = join(repoRoot, "cli", "bin", "flisk.js");
12
+ export function runTdk(args, cwd, input) {
13
+ return execFileSync(process.execPath, [cliBin, ...args], {
14
+ cwd,
15
+ encoding: "utf-8",
16
+ input,
17
+ env: {
18
+ ...process.env,
19
+ TDK_EXTENSION_SOURCE: repoRoot,
20
+ },
21
+ });
22
+ }
23
+ /** `flisk doctor` exits non-zero on machines without Docker, so read its output either way. */
24
+ export function runTdkAllowFailure(args, cwd) {
25
+ const result = spawnSync(process.execPath, [cliBin, ...args], {
26
+ cwd,
27
+ encoding: "utf-8",
28
+ env: { ...process.env, TDK_EXTENSION_SOURCE: repoRoot },
29
+ });
30
+ return `${result.stdout}${result.stderr}`;
31
+ }
32
+ /**
33
+ * Copies a project that `flisk project --yes` already generated into a fresh temp directory. Scaffolding costs
34
+ * several seconds per run, so a file generates one base project in `beforeAll` and each test copies it instead.
35
+ * Only use a copy for a test that starts from a generated project; a test that checks generation itself must
36
+ * generate its own.
37
+ */
38
+ export function copyProject(source) {
39
+ const target = mkdtempSync(join(tmpdir(), "flisk-project-copy-"));
40
+ cpSync(source, target, { recursive: true });
41
+ return target;
42
+ }
43
+ export function starlarkSection(content, name) {
44
+ const start = content.indexOf(`${name} = {`);
45
+ expect(start).toBeGreaterThanOrEqual(0);
46
+ const end = content.indexOf("\n}", start);
47
+ expect(end).toBeGreaterThan(start);
48
+ return content.slice(start, end + 2);
49
+ }
@@ -0,0 +1,16 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { renderToString } from "ink";
3
+ import { describe, expect, it } from "vitest";
4
+ import { LoadingScreen } from "../ui.js";
5
+ describe("ui LoadingScreen", () => {
6
+ it("shows honest text with no percentage", () => {
7
+ const out = renderToString(_jsx(LoadingScreen, { animated: false }));
8
+ expect(out).toContain("Discovering resources...");
9
+ expect(out).not.toContain("%");
10
+ });
11
+ it("renders a spinner frame only when animated", () => {
12
+ expect(renderToString(_jsx(LoadingScreen, { animated: true }))).toMatch(/[⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏] Discovering/);
13
+ expect(renderToString(_jsx(LoadingScreen, { animated: false }))).not.toMatch(/[⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏]/);
14
+ });
15
+ });
16
+ //# sourceMappingURL=ui-loading-screen.test.js.map
@@ -0,0 +1,182 @@
1
+ // Copyright (c) 2026 Flisk Landscape contributors
2
+ // SPDX-License-Identifier: MIT
3
+ import * as http from "node:http";
4
+ import chalk from "chalk";
5
+ import { Command } from "commander";
6
+ import { createDiscoveryContext } from "../utils/discovery-context.js";
7
+ import { errorFactories, runCommand, TdkError } from "../utils/errors.js";
8
+ import { getHostPortPlan } from "../utils/host-port-config.js";
9
+ import { createMachineEnvelope, writeMachineError } from "../utils/machine-output.js";
10
+ import { findProjectRoot } from "../utils/paths.js";
11
+ import { buildServicePorts } from "../utils/status-ports.js";
12
+ const SESSION_REQUEST_TIMEOUT_MS = 10_000;
13
+ /** GET with node:http because fetch silently drops a custom Host header, which is what Traefik routes on. */
14
+ export function httpGet(url, headers, timeoutMs) {
15
+ return new Promise((resolve, reject) => {
16
+ // One signal covers the connection and the body read, so a hung agent cannot block the CLI.
17
+ const req = http.get(url, { headers, signal: AbortSignal.timeout(timeoutMs) }, (res) => {
18
+ const chunks = [];
19
+ res.on("data", (chunk) => chunks.push(chunk));
20
+ res.on("end", () => {
21
+ const status = res.statusCode ?? 0;
22
+ resolve({
23
+ ok: status >= 200 && status < 300,
24
+ status,
25
+ text: Buffer.concat(chunks).toString("utf-8"),
26
+ });
27
+ });
28
+ res.on("error", reject);
29
+ });
30
+ req.on("error", reject);
31
+ });
32
+ }
33
+ /**
34
+ * Agent containers publish no host port; the only way in is the Traefik route that `flisk status` prints as `url`
35
+ * (for example http://api.<project>.localhost:8080/api/bot). `*.localhost` does not resolve everywhere (glibc without
36
+ * systemd-resolved), so connect to loopback and keep the route's host in the Host header, which is all Traefik matches on.
37
+ */
38
+ export function agentSessionRequest(routeUrl, sessionId) {
39
+ const route = new URL(routeUrl);
40
+ const headers = { "x-session-id": sessionId };
41
+ if (route.hostname.endsWith(".localhost")) {
42
+ headers.host = route.host;
43
+ route.hostname = "127.0.0.1";
44
+ }
45
+ return { url: `${route.origin}${route.pathname.replace(/\/$/, "")}/session`, headers };
46
+ }
47
+ export const agentCommand = new Command("agent").description("Inspect and operate AI agent resources");
48
+ agentCommand
49
+ .command("sessions <resource>")
50
+ .description("Inspect session checkpoints from a running AI agent resource")
51
+ .option("--session-id <id>", "Session ID to fetch (required)")
52
+ .option("--json", "Output one JSON object and exit", false)
53
+ .action(async (resourceName, options) => {
54
+ const action = async () => {
55
+ const root = findProjectRoot();
56
+ if (!root) {
57
+ const error = errorFactories.notInProject();
58
+ if (options.json)
59
+ writeMachineError(error);
60
+ error.exit();
61
+ }
62
+ const discovery = createDiscoveryContext();
63
+ const resource = discovery.resources.find((r) => r.name === resourceName);
64
+ if (!resource) {
65
+ const msg = `Resource "${resourceName}" not found in project.`;
66
+ if (options.json) {
67
+ console.log(JSON.stringify(createMachineEnvelope(null, [{ code: "UNKNOWN_RESOURCE", message: msg }])));
68
+ process.exit(1);
69
+ }
70
+ throw new TdkError(msg);
71
+ }
72
+ const appType = resource.config?.appType ?? resource.type;
73
+ if (appType !== "agent") {
74
+ const msg = `Resource "${resourceName}" is of type "${appType}", not "agent".`;
75
+ if (options.json) {
76
+ console.log(JSON.stringify(createMachineEnvelope(null, [{ code: "NOT_AN_AGENT", message: msg }])));
77
+ process.exit(1);
78
+ }
79
+ throw new TdkError(msg);
80
+ }
81
+ const port = resource.port;
82
+ if (!port) {
83
+ const msg = `Agent "${resourceName}" has no assigned port.`;
84
+ if (options.json) {
85
+ console.log(JSON.stringify(createMachineEnvelope(null, [{ code: "NO_PORT", message: msg }])));
86
+ process.exit(1);
87
+ }
88
+ throw new TdkError(msg);
89
+ }
90
+ // The agent runtime keys GET /session by x-session-id and has no list endpoint, so a missing id
91
+ // would only come back as a confusing 400. Fail before any request. Checked after resource
92
+ // validation so UNKNOWN_RESOURCE, NOT_AN_AGENT and NO_PORT keep their precedence.
93
+ const sessionId = typeof options.sessionId === "string" ? options.sessionId.trim() : "";
94
+ if (!sessionId) {
95
+ const msg = `--session-id is required: the agent "${resourceName}" returns the checkpoint of one session.`;
96
+ if (options.json) {
97
+ console.log(JSON.stringify(createMachineEnvelope(null, [{ code: "SESSION_ID_REQUIRED", message: msg }])));
98
+ process.exit(1);
99
+ }
100
+ throw new TdkError(msg, [`Run: flisk agent sessions ${resourceName} --session-id <id>`]);
101
+ }
102
+ const portPlan = root
103
+ ? await getHostPortPlan(root, { inspectDocker: false }).catch(() => null)
104
+ : null;
105
+ const routeUrl = buildServicePorts(resource, portPlan?.ingressHttp).url;
106
+ if (!routeUrl) {
107
+ const msg = `Agent "${resourceName}" has no ingress route to reach it through.`;
108
+ if (options.json) {
109
+ console.log(JSON.stringify(createMachineEnvelope(null, [{ code: "NO_ROUTE", message: msg }])));
110
+ process.exit(1);
111
+ }
112
+ throw new TdkError(msg);
113
+ }
114
+ const request = agentSessionRequest(routeUrl, sessionId);
115
+ // Nothing answered, or Traefik answered for a missing backend: either way the agent is not up.
116
+ const notRunning = () => {
117
+ const msg = `Agent "${resourceName}" is not responding at ${routeUrl}. Is the stack running?`;
118
+ if (options.json) {
119
+ console.log(JSON.stringify(createMachineEnvelope(null, [{ code: "AGENT_NOT_RUNNING", message: msg }])));
120
+ process.exit(1);
121
+ }
122
+ throw new TdkError(msg, ["Start the stack with: flisk up"]);
123
+ };
124
+ let res;
125
+ let bodyText;
126
+ try {
127
+ const reply = await httpGet(request.url, request.headers, SESSION_REQUEST_TIMEOUT_MS);
128
+ res = reply;
129
+ bodyText = reply.text;
130
+ }
131
+ catch {
132
+ return notRunning();
133
+ }
134
+ let body = {};
135
+ try {
136
+ body = bodyText ? JSON.parse(bodyText) : {};
137
+ }
138
+ catch {
139
+ body = { raw: bodyText };
140
+ }
141
+ // Traefik answers 502/503/504 when the route has no live container and a plain-text 404 when it has no route at
142
+ // all. An agent's own errors are JSON, so a non-JSON 404 is the gateway, not the agent.
143
+ const gatewayText = typeof body === "object" && body !== null && "raw" in body;
144
+ if (!res.ok &&
145
+ ([502, 503, 504].includes(res.status) || (res.status === 404 && gatewayText))) {
146
+ return notRunning();
147
+ }
148
+ if (!res.ok) {
149
+ const detail = body?.error ?? bodyText;
150
+ if (options.json) {
151
+ console.log(JSON.stringify(createMachineEnvelope(null, [
152
+ {
153
+ code: "AGENT_REQUEST_FAILED",
154
+ message: `Agent returned ${res.status}: ${detail}`,
155
+ },
156
+ ])));
157
+ process.exit(1);
158
+ }
159
+ throw new TdkError(`Agent error (${res.status}): ${detail}`);
160
+ }
161
+ if (options.json) {
162
+ console.log(JSON.stringify(createMachineEnvelope({
163
+ agent: resourceName,
164
+ port,
165
+ session: body,
166
+ })));
167
+ return;
168
+ }
169
+ console.log(chalk.bold(`Sessions for ${resourceName}:`));
170
+ console.log(JSON.stringify(body, null, 2));
171
+ };
172
+ if (options.json) {
173
+ try {
174
+ await action();
175
+ }
176
+ catch (err) {
177
+ writeMachineError(err);
178
+ }
179
+ return;
180
+ }
181
+ await runCommand(action);
182
+ });