@flisk-sh/flisk 0.0.0-stage → 1.3.189

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-QWYXYAX6.js +510 -0
  170. package/cli/dist-bundle/cli.js +2017 -0
  171. package/cli/dist-bundle/cold-preflight-MM46GFQA.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
package/Tiltfile ADDED
@@ -0,0 +1,151 @@
1
+ # =============================================================================
2
+ # šŸŽÆ Flisk CLI - Combined Tilt Development Kit
3
+ # =============================================================================
4
+ # This is the unified Tiltfile entry point for tdk-cli.
5
+ # It combines: engine, discovery, specs, and ext into one repository.
6
+ #
7
+ # Usage:
8
+ # v1alpha1.extension_repo(name='tdk-cli', url='https://github.com/tdk-landscape/tdk-cli')
9
+ # load('ext://tdk-cli', 'Utils', 'Manifest', ...)
10
+ # =============================================================================
11
+
12
+ # =============================================================================
13
+ # ENGINE (Core orchestration)
14
+ # =============================================================================
15
+ load('./engine/topologies/tilt/common/utils.star', _Utils='Utils')
16
+ load('./discovery/loading.star', _Manifest='Manifest')
17
+ load('./engine/topologies/tilt/config/global.star', _Config='Config')
18
+ load('./discovery/registry.star',
19
+ _GLOBAL_CONFIG_EXPORT='GLOBAL_CONFIG_EXPORT',
20
+ _INFRA_RESOURCES_EXPORT='INFRA_RESOURCES_EXPORT',
21
+ _DDD_LIBS_EXPORT='DDD_LIBS_EXPORT',
22
+ _DEFAULTS_EXPORT='DEFAULTS_EXPORT',
23
+ _get_platform_libs_export='get_platform_libs_export',
24
+ _get_product_libs_export='get_product_libs_export',
25
+ _Registry='Registry',
26
+ _APP_RESOURCES='APP_RESOURCES',
27
+ )
28
+ load('./engine/topologies/tilt/generators/vite_config.star', _Vite='Vite')
29
+ load('./engine/topologies/tilt/generators/tsconfig.star', _TSConfig='TSConfig')
30
+ load('./engine/topologies/platform/docker/index.star', _Docker='Docker')
31
+ load('./engine/topologies/tilt/generators/npmrc.star', _PackageConfig='PackageConfig')
32
+ load('./engine/topologies/tilt/common/utils_deterministic.star', _Determinism='Determinism')
33
+ load('./engine/topologies/tilt/resources/deps.star', _Libs='Libs')
34
+ load('./engine/topologies/tilt/resources/conditions.star', _Database='Database')
35
+ load('./engine/topologies/tilt/resources/declaration.star', _Orchestrator='Orchestrator')
36
+ load('./engine/topologies/tilt/resources/ordering.star', _Infra='Infra')
37
+ load('./engine/topologies/tilt/resources/triggers.star', _Watchers='Watchers')
38
+ load('./engine/topologies/tilt/resources/orchestrator/apply_compose_resource_registration.star', _resource_defers_start='resource_defers_start')
39
+ load('./engine/topologies/platform/docker/build/frontend_build_plan.star', _frontend_build_plan='frontend_build_plan')
40
+
41
+ # =============================================================================
42
+ # SPECS (Tech stack and standards)
43
+ # =============================================================================
44
+ load('./specs/specs/TILT_TECH_STACK.star', _assert_tech_stack='assert_tech_stack', _TECH_STACK='TECH_STACK')
45
+
46
+ # =============================================================================
47
+ # DISCOVERY (Service discovery)
48
+ # =============================================================================
49
+ load('./discovery/constants.star',
50
+ _MANIFEST_FILENAME='MANIFEST_FILENAME',
51
+ _MANIFEST_FILENAME_YAML='MANIFEST_FILENAME_YAML',
52
+ _RESOURCES_ROOT='RESOURCES_ROOT',
53
+ _DISCOVERY_SCAN_ROOTS='DISCOVERY_SCAN_ROOTS',
54
+ )
55
+ load('./discovery/discovery_orchestrator.star', _initialize_discovery='initialize_discovery')
56
+ load('./discovery/resource_snapshot.star', _get_resource_snapshot_path='get_resource_snapshot_path')
57
+
58
+ # =============================================================================
59
+ # EXT (UI enhancements and IDE components)
60
+ # =============================================================================
61
+ # UI enhancements are inlined for self-containment
62
+ def load_ui_enhancements(config):
63
+ """Load UI enhancements configuration."""
64
+ enable_tooltips = config.get('enable_tooltips', True)
65
+ enable_icons = config.get('enable_icons', True)
66
+ enable_help_panel = config.get('enable_help_panel', True)
67
+ enable_cron_jobs_tab = config.get('enable_cron_jobs_tab', True)
68
+
69
+
70
+ def get_ide_components_path():
71
+ """Return the path to IDE components."""
72
+ return './ext/ide-components'
73
+
74
+ def get_file_browser_script():
75
+ """Return the path to file browser server script."""
76
+ return './ext/ide-components/file_browser/server.py'
77
+
78
+ def get_code_viewer_script():
79
+ """Return the path to code viewer server script."""
80
+ return './ext/ide-components/code_viewer/server.py'
81
+
82
+ def get_config_inspector_script():
83
+ """Return the path to config inspector server script."""
84
+ return './ext/ide-components/config_inspector/server.py'
85
+
86
+ def get_code_executor_script():
87
+ """Return the path to code executor server script."""
88
+ return './ext/ide-components/code_executor/server.py'
89
+
90
+ IDE_PORTS = {
91
+ 'file_browser': 9765,
92
+ 'code_viewer': 9766,
93
+ 'config_inspector': 9767,
94
+ 'code_executor': 9768,
95
+ }
96
+
97
+ # =============================================================================
98
+ # RE-EXPORTS (Unified API)
99
+ # =============================================================================
100
+
101
+ # Core
102
+ Utils = _Utils
103
+ Manifest = _Manifest
104
+ Config = _Config
105
+
106
+ # Registry Data
107
+ GLOBAL_CONFIG_EXPORT = _GLOBAL_CONFIG_EXPORT
108
+ INFRA_RESOURCES_EXPORT = _INFRA_RESOURCES_EXPORT
109
+ DDD_LIBS_EXPORT = _DDD_LIBS_EXPORT
110
+ DEFAULTS_EXPORT = _DEFAULTS_EXPORT
111
+ APP_RESOURCES = _APP_RESOURCES
112
+ Registry = _Registry
113
+
114
+ def get_platform_libs_export():
115
+ return _get_platform_libs_export()
116
+
117
+ def get_product_libs_export():
118
+ return _get_product_libs_export()
119
+
120
+ # Providers
121
+ Vite = _Vite
122
+ TSConfig = _TSConfig
123
+ Docker = _Docker
124
+ PackageConfig = _PackageConfig
125
+
126
+ # Lifecycle
127
+ Libs = _Libs
128
+ Database = _Database
129
+ Orchestrator = _Orchestrator
130
+ Infra = _Infra
131
+ Watchers = _Watchers
132
+
133
+ # True when a manifest's deferStart is actually active (licensed); decides whether a `<name>-image` prebuild resource exists.
134
+ # The generated Tiltfile loads this from ext://tdk-cli, which resolves to this root Tiltfile.
135
+ resource_defers_start = _resource_defers_start
136
+ FrontendBuildPlan = _frontend_build_plan
137
+
138
+ # Specs
139
+ assert_tech_stack = _assert_tech_stack
140
+ TECH_STACK = _TECH_STACK
141
+
142
+ # Discovery
143
+ MANIFEST_FILENAME = _MANIFEST_FILENAME
144
+ MANIFEST_FILENAME_YAML = _MANIFEST_FILENAME_YAML
145
+ RESOURCES_ROOT = _RESOURCES_ROOT
146
+ DISCOVERY_SCAN_ROOTS = _DISCOVERY_SCAN_ROOTS
147
+ initialize_discovery = _initialize_discovery
148
+ get_resource_snapshot_path = _get_resource_snapshot_path
149
+
150
+ # Determinism Utilities
151
+ Determinism = _Determinism
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env node
2
+ // Copyright (c) 2026 Flisk contributors
3
+ // SPDX-License-Identifier: MIT
4
+
5
+ import { existsSync } from "node:fs";
6
+ import { dirname, join } from "node:path";
7
+ import { fileURLToPath, pathToFileURL } from "node:url";
8
+
9
+ const __filename = fileURLToPath(import.meta.url);
10
+ const __dirname = dirname(__filename);
11
+
12
+ function nodeTooOld(version) {
13
+ const [major = 0, minor = 0] = String(version)
14
+ .split(".")
15
+ .map((part) => Number.parseInt(part, 10));
16
+ return (
17
+ !Number.isFinite(major) || !Number.isFinite(minor) || major < 22 || (major === 22 && minor < 12)
18
+ );
19
+ }
20
+
21
+ if (nodeTooOld(process.versions.node)) {
22
+ console.error(
23
+ "Flisk CLI needs Node.js 22.12+ (current: " +
24
+ process.versions.node +
25
+ ").\n" +
26
+ "This is the first cold-npx failure. Bun/Prisma/NATS are not involved yet.\n" +
27
+ "Install Node 22.12+ and rerun.",
28
+ );
29
+ process.exit(1);
30
+ }
31
+
32
+ // dist-bundle/ (ink/react/chalk inlined) exists only in a packed npm package;
33
+ // a git checkout runs the committed dist/ instead.
34
+ const bundledCliPath = join(__dirname, "..", "dist-bundle", "cli.js");
35
+ const cliPath = existsSync(bundledCliPath)
36
+ ? bundledCliPath
37
+ : join(__dirname, "..", "dist", "cli.js");
38
+
39
+ import(pathToFileURL(cliPath).href).catch((err) => {
40
+ console.error("Failed to start Flisk:", err);
41
+ process.exit(1);
42
+ });
@@ -0,0 +1,335 @@
1
+ /**
2
+ * The `custom` agent runtime: a plain Bun HTTP service with no model SDK, no agent framework and no vendor dependency.
3
+ * It is the escape hatch the agent resource type is built on. Replace the `runTurn` body with your model call and tools;
4
+ * the process contract around it (health, readiness, session checkpoints, SIGTERM drain) is what Flisk relies on.
5
+ */
6
+ export function getCustomAgentIndexTemplate(name, durability = "files") {
7
+ if (durability === "postgres") {
8
+ return `import { createServer, type IncomingMessage, type ServerResponse } from 'node:http';
9
+ import { Client } from 'pg';
10
+
11
+ // Contract with Flisk (see docs/agents/ai-agents.md):
12
+ // AGENT_DURABILITY postgres
13
+ // DATABASE_URL Postgres connection string injected by Flisk
14
+ // PORT port to listen on
15
+ // /health: the process is alive. /ready: the checkpoint store is reachable. Idle is healthy, so /health never checks the store.
16
+
17
+ const DURABILITY = 'postgres';
18
+ const PORT = Number(process.env.PORT || 3000);
19
+ const DRAIN_TIMEOUT_MS = 10_000;
20
+ const DATABASE_URL = process.env.DATABASE_URL || 'postgresql://postgres:postgres@localhost:5432/postgres';
21
+
22
+ interface Checkpoint {
23
+ sessionId: string;
24
+ messages: Array<{ role: 'user' | 'agent'; content: string; at: string }>;
25
+ }
26
+
27
+ let client: Client | null = null;
28
+ let initialized = false;
29
+
30
+ async function getClient(): Promise<Client> {
31
+ if (client) return client;
32
+ const c = new Client({ connectionString: DATABASE_URL });
33
+ await c.connect();
34
+ if (!initialized) {
35
+ await c.query(\`
36
+ CREATE TABLE IF NOT EXISTS tdk_agent_sessions (
37
+ session_id VARCHAR(128) PRIMARY KEY,
38
+ messages JSONB NOT NULL DEFAULT '[]'::jsonb,
39
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
40
+ );
41
+ \`);
42
+ initialized = true;
43
+ }
44
+ client = c;
45
+ return client;
46
+ }
47
+
48
+ const store = {
49
+ async ready(): Promise<boolean> {
50
+ try {
51
+ const c = await getClient();
52
+ await c.query('SELECT 1');
53
+ return true;
54
+ } catch {
55
+ client = null;
56
+ return false;
57
+ }
58
+ },
59
+ async load(sessionId: string): Promise<Checkpoint> {
60
+ try {
61
+ const c = await getClient();
62
+ const res = await c.query('SELECT messages FROM tdk_agent_sessions WHERE session_id = $1', [sessionId]);
63
+ if (res.rows.length > 0 && res.rows[0].messages) {
64
+ return { sessionId, messages: res.rows[0].messages };
65
+ }
66
+ return { sessionId, messages: [] };
67
+ } catch (err) {
68
+ console.error('[agent] load checkpoint failed:', err);
69
+ return { sessionId, messages: [] };
70
+ }
71
+ },
72
+ async save(checkpoint: Checkpoint): Promise<void> {
73
+ const c = await getClient();
74
+ await c.query(
75
+ \`INSERT INTO tdk_agent_sessions (session_id, messages, updated_at)
76
+ VALUES ($1, $2, NOW())
77
+ ON CONFLICT (session_id) DO UPDATE
78
+ SET messages = EXCLUDED.messages, updated_at = NOW()\`,
79
+ [checkpoint.sessionId, JSON.stringify(checkpoint.messages)],
80
+ );
81
+ },
82
+ async close(): Promise<void> {
83
+ if (client) {
84
+ try {
85
+ await client.end();
86
+ } catch (err) {
87
+ console.warn('[agent] closing the checkpoint client failed:', err);
88
+ }
89
+ client = null;
90
+ }
91
+ },
92
+ };
93
+
94
+ // Replace this with the agent's work: call your model, run tools, return the reply. Keep it a pure function of the
95
+ // checkpoint so a resumed session continues from what was saved.
96
+ async function runTurn(checkpoint: Checkpoint, input: string): Promise<string> {
97
+ // The caller has already appended this turn's user message, so the turn number is half the message count, rounded up.
98
+ return 'received ' + input + ' (turn ' + Math.ceil(checkpoint.messages.length / 2) + ')';
99
+ }
100
+
101
+ let draining = false;
102
+ let inFlight = 0;
103
+
104
+ function sendJson(res: ServerResponse, status: number, body: unknown) {
105
+ res.statusCode = status;
106
+ res.setHeader('content-type', 'application/json');
107
+ res.end(JSON.stringify(body));
108
+ }
109
+
110
+ async function readJson(req: IncomingMessage): Promise<any> {
111
+ const chunks: Buffer[] = [];
112
+ for await (const chunk of req) chunks.push(chunk as Buffer);
113
+ const raw = Buffer.concat(chunks).toString('utf8');
114
+ return raw ? JSON.parse(raw) : {};
115
+ }
116
+
117
+ const server = createServer(async (req, res) => {
118
+ inFlight++;
119
+ res.on('close', () => inFlight--);
120
+ const url = new URL(req.url ?? '/', 'http://localhost');
121
+
122
+ try {
123
+ if (url.pathname === '/health') {
124
+ return sendJson(res, 200, { status: 'ok', service: '${name}', draining });
125
+ }
126
+
127
+ if (url.pathname === '/ready') {
128
+ const ok = !draining && (await store.ready());
129
+ return sendJson(res, ok ? 200 : 503, { ready: ok, durability: DURABILITY });
130
+ }
131
+
132
+ // Session routing: the session id comes from the x-session-id header, so several instances of one agent can
133
+ // share a Traefik route and each session still reaches its own checkpoint.
134
+ if (url.pathname === '/turn' && req.method === 'POST') {
135
+ if (draining) return sendJson(res, 503, { error: 'draining' });
136
+ const sessionId = String(req.headers['x-session-id'] ?? '');
137
+ if (!/^[A-Za-z0-9_-]{1,128}$/.test(sessionId)) {
138
+ return sendJson(res, 400, { error: 'x-session-id header is required (1-128 letters, digits, - or _)' });
139
+ }
140
+ const body = await readJson(req);
141
+ const input = String(body.input ?? '');
142
+ const checkpoint = await store.load(sessionId);
143
+ checkpoint.messages.push({ role: 'user', content: input, at: new Date().toISOString() });
144
+ const reply = await runTurn(checkpoint, input);
145
+ checkpoint.messages.push({ role: 'agent', content: reply, at: new Date().toISOString() });
146
+ await store.save(checkpoint);
147
+ return sendJson(res, 200, { sessionId, reply, turns: checkpoint.messages.length / 2 });
148
+ }
149
+
150
+ if (url.pathname === '/session' && req.method === 'GET') {
151
+ const sessionId = String(req.headers['x-session-id'] ?? '');
152
+ if (!/^[A-Za-z0-9_-]{1,128}$/.test(sessionId)) return sendJson(res, 400, { error: 'x-session-id header is required' });
153
+ const checkpoint = await store.load(sessionId);
154
+ return sendJson(res, 200, { sessionId, turns: checkpoint.messages.length / 2, messages: checkpoint.messages });
155
+ }
156
+
157
+ return sendJson(res, 404, { error: 'not_found' });
158
+ } catch (error) {
159
+ console.error('[agent] request failed:', error);
160
+ return sendJson(res, 500, { error: 'internal_error' });
161
+ }
162
+ });
163
+
164
+ // Bind beyond loopback: Traefik reaches the container over the Docker network.
165
+ server.listen(PORT, '0.0.0.0', () => {
166
+ console.log('\\nšŸ¤– ${name} agent on http://localhost:' + PORT + ' (durability: ' + DURABILITY + ')');
167
+ });
168
+
169
+ // Drain on SIGTERM (flisk down, hot reload, docker stop): stop taking turns, let in-flight turns finish, then exit 0.
170
+ // Checkpoints are written before a turn is answered, so a drained exit loses no acknowledged turn.
171
+ function shutdown(signal: string) {
172
+ if (draining) return;
173
+ draining = true;
174
+ console.log('[agent] ' + signal + ' received, draining ' + inFlight + ' in-flight request(s)');
175
+ server.close(async () => {
176
+ await store.close();
177
+ });
178
+ const deadline = Date.now() + DRAIN_TIMEOUT_MS;
179
+ const timer = setInterval(async () => {
180
+ if (inFlight === 0 || Date.now() > deadline) {
181
+ clearInterval(timer);
182
+ await store.close();
183
+ process.exit(0);
184
+ }
185
+ }, 100);
186
+ }
187
+ process.on('SIGTERM', () => shutdown('SIGTERM'));
188
+ process.on('SIGINT', () => shutdown('SIGINT'));
189
+ `;
190
+ }
191
+ return `import { createServer, type IncomingMessage, type ServerResponse } from 'node:http';
192
+ import { mkdirSync, readFileSync, renameSync, writeFileSync, existsSync } from 'node:fs';
193
+ import { join } from 'node:path';
194
+
195
+ // Contract with Flisk (see docs/agents/ai-agents.md):
196
+ // AGENT_DURABILITY files (set by flisk from service.json agent.durability)
197
+ // AGENT_STATE_DIR where files-durability checkpoints live (a named volume that survives flisk down)
198
+ // PORT port to listen on
199
+ // /health: the process is alive. /ready: the checkpoint store is reachable. Idle is healthy, so /health never checks the store.
200
+
201
+ const DURABILITY = 'files';
202
+ const STATE_DIR = process.env.AGENT_STATE_DIR || join(process.cwd(), '.agent-state');
203
+ const PORT = Number(process.env.PORT || 3000);
204
+ const DRAIN_TIMEOUT_MS = 10_000;
205
+
206
+ interface Checkpoint {
207
+ sessionId: string;
208
+ messages: Array<{ role: 'user' | 'agent'; content: string; at: string }>;
209
+ }
210
+
211
+ // Session store. files: one JSON checkpoint per session, written atomically (temp file, then rename), so a kill
212
+ // mid-write leaves the previous checkpoint intact.
213
+ const store = {
214
+ ready(): boolean {
215
+ try {
216
+ mkdirSync(STATE_DIR, { recursive: true });
217
+ return true;
218
+ } catch {
219
+ return false;
220
+ }
221
+ },
222
+ load(sessionId: string): Checkpoint {
223
+ const file = join(STATE_DIR, sessionId + '.json');
224
+ return existsSync(file) ? JSON.parse(readFileSync(file, 'utf8')) : { sessionId, messages: [] };
225
+ },
226
+ save(checkpoint: Checkpoint): void {
227
+ mkdirSync(STATE_DIR, { recursive: true });
228
+ const file = join(STATE_DIR, checkpoint.sessionId + '.json');
229
+ const tmp = file + '.' + process.pid + '.tmp';
230
+ writeFileSync(tmp, JSON.stringify(checkpoint));
231
+ renameSync(tmp, file);
232
+ },
233
+ };
234
+
235
+ // Replace this with the agent's work: call your model, run tools, return the reply. Keep it a pure function of the
236
+ // checkpoint so a resumed session continues from what was saved.
237
+ async function runTurn(checkpoint: Checkpoint, input: string): Promise<string> {
238
+ // The caller has already appended this turn's user message, so the turn number is half the message count, rounded up.
239
+ return 'received ' + input + ' (turn ' + Math.ceil(checkpoint.messages.length / 2) + ')';
240
+ }
241
+
242
+ let draining = false;
243
+ let inFlight = 0;
244
+
245
+ function sendJson(res: ServerResponse, status: number, body: unknown) {
246
+ res.statusCode = status;
247
+ res.setHeader('content-type', 'application/json');
248
+ res.end(JSON.stringify(body));
249
+ }
250
+
251
+ async function readJson(req: IncomingMessage): Promise<any> {
252
+ const chunks: Buffer[] = [];
253
+ for await (const chunk of req) chunks.push(chunk as Buffer);
254
+ const raw = Buffer.concat(chunks).toString('utf8');
255
+ return raw ? JSON.parse(raw) : {};
256
+ }
257
+
258
+ const server = createServer(async (req, res) => {
259
+ inFlight++;
260
+ res.on('close', () => inFlight--);
261
+ const url = new URL(req.url ?? '/', 'http://localhost');
262
+
263
+ try {
264
+ if (url.pathname === '/health') {
265
+ return sendJson(res, 200, { status: 'ok', service: '${name}', draining });
266
+ }
267
+
268
+ if (url.pathname === '/ready') {
269
+ const ok = !draining && (await store.ready());
270
+ return sendJson(res, ok ? 200 : 503, { ready: ok, durability: DURABILITY });
271
+ }
272
+
273
+ // Session routing: the session id comes from the x-session-id header, so several instances of one agent can
274
+ // share a Traefik route and each session still reaches its own checkpoint.
275
+ if (url.pathname === '/turn' && req.method === 'POST') {
276
+ if (draining) return sendJson(res, 503, { error: 'draining' });
277
+ const sessionId = String(req.headers['x-session-id'] ?? '');
278
+ if (!/^[A-Za-z0-9_-]{1,128}$/.test(sessionId)) {
279
+ return sendJson(res, 400, { error: 'x-session-id header is required (1-128 letters, digits, - or _)' });
280
+ }
281
+ const body = await readJson(req);
282
+ const input = String(body.input ?? '');
283
+ const checkpoint = await store.load(sessionId);
284
+ checkpoint.messages.push({ role: 'user', content: input, at: new Date().toISOString() });
285
+ const reply = await runTurn(checkpoint, input);
286
+ checkpoint.messages.push({ role: 'agent', content: reply, at: new Date().toISOString() });
287
+ await store.save(checkpoint);
288
+ return sendJson(res, 200, { sessionId, reply, turns: checkpoint.messages.length / 2 });
289
+ }
290
+
291
+ if (url.pathname === '/session' && req.method === 'GET') {
292
+ const sessionId = String(req.headers['x-session-id'] ?? '');
293
+ if (!/^[A-Za-z0-9_-]{1,128}$/.test(sessionId)) return sendJson(res, 400, { error: 'x-session-id header is required' });
294
+ const checkpoint = await store.load(sessionId);
295
+ return sendJson(res, 200, { sessionId, turns: checkpoint.messages.length / 2, messages: checkpoint.messages });
296
+ }
297
+
298
+ return sendJson(res, 404, { error: 'not_found' });
299
+ } catch (error) {
300
+ console.error('[agent] request failed:', error);
301
+ return sendJson(res, 500, { error: 'internal_error' });
302
+ }
303
+ });
304
+
305
+ // Bind beyond loopback: Traefik reaches the container over the Docker network.
306
+ server.listen(PORT, '0.0.0.0', () => {
307
+ console.log('\\nšŸ¤– ${name} agent on http://localhost:' + PORT + ' (durability: ' + DURABILITY + ')');
308
+ });
309
+
310
+ // Drain on SIGTERM (flisk down, hot reload, docker stop): stop taking turns, let in-flight turns finish, then exit 0.
311
+ // Checkpoints are written before a turn is answered, so a drained exit loses no acknowledged turn.
312
+ function shutdown(signal: string) {
313
+ if (draining) return;
314
+ draining = true;
315
+ console.log('[agent] ' + signal + ' received, draining ' + inFlight + ' in-flight request(s)');
316
+ server.close();
317
+ const deadline = Date.now() + DRAIN_TIMEOUT_MS;
318
+ const timer = setInterval(() => {
319
+ if (inFlight === 0 || Date.now() > deadline) {
320
+ clearInterval(timer);
321
+ process.exit(0);
322
+ }
323
+ }, 100);
324
+ }
325
+ process.on('SIGTERM', () => shutdown('SIGTERM'));
326
+ process.on('SIGINT', () => shutdown('SIGINT'));
327
+ `;
328
+ }
329
+ export const customAgentRuntime = {
330
+ id: "custom",
331
+ label: "Custom agent runtime (Bun HTTP, no vendor dependency)",
332
+ dependencies: {},
333
+ devDependencies: {},
334
+ createIndex: getCustomAgentIndexTemplate,
335
+ };
@@ -0,0 +1,34 @@
1
+ // Copyright (c) 2026 Flisk Landscape contributors
2
+ // SPDX-License-Identifier: MIT
3
+ import { TdkError } from "../utils/errors.js";
4
+ import { customAgentRuntime } from "./custom.js";
5
+ /**
6
+ * Agent runtimes an `agent` resource can be scaffolded with. No runtime is privileged: each is a scaffold plus the
7
+ * process contract in its index file, and `custom` is the default because it has no vendor dependency.
8
+ */
9
+ export const AGENT_RUNTIMES = {
10
+ custom: customAgentRuntime,
11
+ };
12
+ export const DEFAULT_AGENT_RUNTIME = "custom";
13
+ export const AGENT_DURABILITY_OPTIONS = ["files", "postgres"];
14
+ export function resolveAgentRuntime(runtimeId) {
15
+ const id = runtimeId ?? DEFAULT_AGENT_RUNTIME;
16
+ const provider = AGENT_RUNTIMES[id];
17
+ if (!provider) {
18
+ const supported = Object.keys(AGENT_RUNTIMES).join(", ");
19
+ throw new TdkError(`Unknown agent runtime "${id}". Supported runtimes: ${supported}.`, [
20
+ `Use one of: ${supported}`,
21
+ `Omit --runtime to use ${DEFAULT_AGENT_RUNTIME}`,
22
+ ]);
23
+ }
24
+ return provider;
25
+ }
26
+ export function resolveAgentDurability(value) {
27
+ const durability = value ?? "files";
28
+ if (!AGENT_DURABILITY_OPTIONS.includes(durability)) {
29
+ throw new TdkError(`Unknown --durability "${durability}".`, [
30
+ `Use one of: ${AGENT_DURABILITY_OPTIONS.join(", ")}`,
31
+ ]);
32
+ }
33
+ return durability;
34
+ }
@@ -0,0 +1,38 @@
1
+ export function getElysiaIndexTemplate(name) {
2
+ return `import { Elysia } from 'elysia';
3
+
4
+ const port = Number(process.env.PORT || 3000);
5
+
6
+ const app = new Elysia()
7
+ // Health check endpoint (required by TILT_RESOURCE_DEFAULTS.star)
8
+ .get('/health', () => ({ status: 'ok', service: '${name}' }))
9
+ .get('/health/live', () => ({ status: 'alive', timestamp: Date.now() }))
10
+ .get('/health/ready', ({ set }) => {
11
+ const dependencies: Record<string, string> = {};
12
+ let allReady = true;
13
+
14
+ // Add dependency checks here (database, cache, etc.)
15
+ // Mark allReady = false if any dependency is unhealthy
16
+
17
+ set.status = allReady ? 200 : 503;
18
+ return { status: allReady ? 'ready' : 'not_ready', dependencies };
19
+ })
20
+ .get('/', () => ({
21
+ service: '${name}',
22
+ version: '1.0.0',
23
+ endpoints: ['/health', '/health/live', '/health/ready']
24
+ }))
25
+ // Bind beyond loopback: Traefik reaches the container over the Docker network.
26
+ .listen({ port, hostname: '0.0.0.0' });
27
+
28
+ console.log('\\nšŸš€ ${name} running on http://localhost:' + app.server?.port);
29
+ console.log('šŸ“Š Health check: http://localhost:' + app.server?.port + '/health\\n');
30
+ `;
31
+ }
32
+ export const elysiaBackendProvider = {
33
+ id: "elysia",
34
+ label: "Bun + Elysia",
35
+ dependencies: { elysia: "^1.3.0" },
36
+ devDependencies: {},
37
+ createIndex: getElysiaIndexTemplate,
38
+ };
@@ -0,0 +1,49 @@
1
+ export function getExpressIndexTemplate(name) {
2
+ return `import express from 'express';
3
+
4
+ const app = express();
5
+
6
+ // Health check endpoint (required by TILT_RESOURCE_DEFAULTS.star)
7
+ app.get('/health', (_req, res) => {
8
+ res.json({ status: 'ok', service: '${name}' });
9
+ });
10
+
11
+ app.get('/health/live', (_req, res) => {
12
+ res.json({ status: 'alive', timestamp: Date.now() });
13
+ });
14
+
15
+ app.get('/health/ready', async (_req, res) => {
16
+ const dependencies: Record<string, string> = {};
17
+ let allReady = true;
18
+
19
+ // Add dependency checks here (database, cache, etc.)
20
+ // Mark allReady = false if any dependency is unhealthy
21
+
22
+ const status = allReady ? 'ready' : 'not_ready';
23
+ res.status(allReady ? 200 : 503).json({ status, dependencies });
24
+ });
25
+
26
+ app.get('/', (_req, res) => {
27
+ res.json({
28
+ service: '${name}',
29
+ version: '1.0.0',
30
+ endpoints: ['/health', '/health/live', '/health/ready']
31
+ });
32
+ });
33
+
34
+ const port = Number(process.env.PORT || 3000);
35
+
36
+ // Bind beyond loopback: Traefik reaches the container over the Docker network.
37
+ app.listen(port, '0.0.0.0', () => {
38
+ console.log('\\nšŸš€ ${name} running on http://localhost:' + port);
39
+ console.log('šŸ“Š Health check: http://localhost:' + port + '/health\\n');
40
+ });
41
+ `;
42
+ }
43
+ export const expressBackendProvider = {
44
+ id: "express",
45
+ label: "Bun + Express",
46
+ dependencies: { express: "^5.1.0" },
47
+ devDependencies: { "@types/express": "^5.0.0" },
48
+ createIndex: getExpressIndexTemplate,
49
+ };