@tdk-landscape/tdk-cli-core 1.3.53 → 1.3.55

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 (392) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/README.md +1 -1
  3. package/cli/dist/commands/doctor.js +21 -3
  4. package/cli/dist/commands/upgrade.js +7 -7
  5. package/cli/dist/generator/extension-fetch.js +16 -9
  6. package/cli/dist/utils/spinner.js +39 -0
  7. package/cli/package.json +1 -2
  8. package/package.json +16 -2
  9. package/.claude/skills/layer-autoresearch/SKILL.md +0 -48
  10. package/.claude/skills/tdk-troubleshoot/SKILL.md +0 -222
  11. package/.github/ISSUE_TEMPLATE/bug_report.yml +0 -40
  12. package/.github/ISSUE_TEMPLATE/config.yml +0 -11
  13. package/.github/ISSUE_TEMPLATE/feature_request.yml +0 -18
  14. package/.github/ISSUE_TEMPLATE/premium_license.yml +0 -43
  15. package/.github/dependabot.yml +0 -33
  16. package/.github/pull_request_template.md +0 -5
  17. package/.github/workflows/ci.yml +0 -200
  18. package/.github/workflows/release-binaries.yml +0 -139
  19. package/.github/zizmor.yml +0 -9
  20. package/.pre-commit-config.yaml +0 -57
  21. package/CODE_OF_CONDUCT.md +0 -9
  22. package/CONTRIBUTING.md +0 -42
  23. package/Makefile +0 -92
  24. package/SECURITY.md +0 -17
  25. package/benchmarks/results/container-scale-2026-09-25T20-54-49-736Z.json +0 -45
  26. package/benchmarks/results/container-scale-2026-09-25T21-01-20-540Z.json +0 -150
  27. package/benchmarks/results/container-scale-2026-09-25T21-15-01-441Z.json +0 -73
  28. package/benchmarks/results/container-scale-2026-09-25T22-09-01-630Z.json +0 -77
  29. package/benchmarks/results/container-scale-2026-09-25T22-18-28-371Z.json +0 -202
  30. package/cli/AGENTS.md +0 -390
  31. package/cli/DESIGN.md +0 -735
  32. package/cli/README.md +0 -292
  33. package/cli/biome.json +0 -40
  34. package/cli/dependency-graph.svg +0 -1135
  35. package/cli/dist/cli.d.ts +0 -3
  36. package/cli/dist/cli.d.ts.map +0 -1
  37. package/cli/dist/cli.js.map +0 -1
  38. package/cli/dist/commands/completion.d.ts +0 -3
  39. package/cli/dist/commands/completion.d.ts.map +0 -1
  40. package/cli/dist/commands/completion.js.map +0 -1
  41. package/cli/dist/commands/config.d.ts +0 -3
  42. package/cli/dist/commands/config.d.ts.map +0 -1
  43. package/cli/dist/commands/config.js.map +0 -1
  44. package/cli/dist/commands/doctor.d.ts +0 -19
  45. package/cli/dist/commands/doctor.d.ts.map +0 -1
  46. package/cli/dist/commands/doctor.js.map +0 -1
  47. package/cli/dist/commands/down.d.ts +0 -3
  48. package/cli/dist/commands/down.d.ts.map +0 -1
  49. package/cli/dist/commands/down.js.map +0 -1
  50. package/cli/dist/commands/help.d.ts +0 -2
  51. package/cli/dist/commands/help.d.ts.map +0 -1
  52. package/cli/dist/commands/help.js.map +0 -1
  53. package/cli/dist/commands/networks.d.ts +0 -3
  54. package/cli/dist/commands/networks.d.ts.map +0 -1
  55. package/cli/dist/commands/networks.js.map +0 -1
  56. package/cli/dist/commands/project.d.ts +0 -9
  57. package/cli/dist/commands/project.d.ts.map +0 -1
  58. package/cli/dist/commands/project.js.map +0 -1
  59. package/cli/dist/commands/projects.d.ts +0 -3
  60. package/cli/dist/commands/projects.d.ts.map +0 -1
  61. package/cli/dist/commands/projects.js.map +0 -1
  62. package/cli/dist/commands/resource.d.ts +0 -69
  63. package/cli/dist/commands/resource.d.ts.map +0 -1
  64. package/cli/dist/commands/resource.js.map +0 -1
  65. package/cli/dist/commands/resources.d.ts +0 -3
  66. package/cli/dist/commands/resources.d.ts.map +0 -1
  67. package/cli/dist/commands/resources.js.map +0 -1
  68. package/cli/dist/commands/stack.d.ts +0 -3
  69. package/cli/dist/commands/stack.d.ts.map +0 -1
  70. package/cli/dist/commands/stack.js.map +0 -1
  71. package/cli/dist/commands/stacks.d.ts +0 -3
  72. package/cli/dist/commands/stacks.d.ts.map +0 -1
  73. package/cli/dist/commands/stacks.js.map +0 -1
  74. package/cli/dist/commands/status.d.ts +0 -3
  75. package/cli/dist/commands/status.d.ts.map +0 -1
  76. package/cli/dist/commands/status.js.map +0 -1
  77. package/cli/dist/commands/ui.d.ts +0 -3
  78. package/cli/dist/commands/ui.d.ts.map +0 -1
  79. package/cli/dist/commands/ui.js.map +0 -1
  80. package/cli/dist/commands/up.d.ts +0 -3
  81. package/cli/dist/commands/up.d.ts.map +0 -1
  82. package/cli/dist/commands/up.js.map +0 -1
  83. package/cli/dist/commands/upgrade.d.ts +0 -14
  84. package/cli/dist/commands/upgrade.d.ts.map +0 -1
  85. package/cli/dist/commands/upgrade.js.map +0 -1
  86. package/cli/dist/commands/version.d.ts +0 -3
  87. package/cli/dist/commands/version.d.ts.map +0 -1
  88. package/cli/dist/commands/version.js.map +0 -1
  89. package/cli/dist/components/Accessible.d.ts +0 -8
  90. package/cli/dist/components/Accessible.d.ts.map +0 -1
  91. package/cli/dist/components/Accessible.js.map +0 -1
  92. package/cli/dist/components/BaseTooltip.d.ts +0 -4
  93. package/cli/dist/components/BaseTooltip.d.ts.map +0 -1
  94. package/cli/dist/components/BaseTooltip.js.map +0 -1
  95. package/cli/dist/components/DetailPanel.d.ts +0 -4
  96. package/cli/dist/components/DetailPanel.d.ts.map +0 -1
  97. package/cli/dist/components/DetailPanel.js.map +0 -1
  98. package/cli/dist/components/FileTree.d.ts +0 -4
  99. package/cli/dist/components/FileTree.d.ts.map +0 -1
  100. package/cli/dist/components/FileTree.js.map +0 -1
  101. package/cli/dist/components/ResourceSelectInput.d.ts +0 -4
  102. package/cli/dist/components/ResourceSelectInput.d.ts.map +0 -1
  103. package/cli/dist/components/ResourceSelectInput.js.map +0 -1
  104. package/cli/dist/components/ResourceTable.d.ts +0 -4
  105. package/cli/dist/components/ResourceTable.d.ts.map +0 -1
  106. package/cli/dist/components/ResourceTable.js.map +0 -1
  107. package/cli/dist/components/TabBar.d.ts +0 -4
  108. package/cli/dist/components/TabBar.d.ts.map +0 -1
  109. package/cli/dist/components/TabBar.js.map +0 -1
  110. package/cli/dist/components/Tooltip.d.ts +0 -12
  111. package/cli/dist/components/Tooltip.d.ts.map +0 -1
  112. package/cli/dist/components/Tooltip.js.map +0 -1
  113. package/cli/dist/components/index.d.ts +0 -8
  114. package/cli/dist/components/index.d.ts.map +0 -1
  115. package/cli/dist/components/index.js.map +0 -1
  116. package/cli/dist/config/platform-standards.d.ts +0 -159
  117. package/cli/dist/config/platform-standards.d.ts.map +0 -1
  118. package/cli/dist/config/platform-standards.js.map +0 -1
  119. package/cli/dist/generator/extension-fetch.d.ts +0 -25
  120. package/cli/dist/generator/extension-fetch.d.ts.map +0 -1
  121. package/cli/dist/generator/extension-fetch.js.map +0 -1
  122. package/cli/dist/generator/template-engine.d.ts +0 -62
  123. package/cli/dist/generator/template-engine.d.ts.map +0 -1
  124. package/cli/dist/generator/template-engine.js.map +0 -1
  125. package/cli/dist/index.d.ts +0 -11
  126. package/cli/dist/index.d.ts.map +0 -1
  127. package/cli/dist/index.js.map +0 -1
  128. package/cli/dist/types/index.d.ts +0 -257
  129. package/cli/dist/types/index.d.ts.map +0 -1
  130. package/cli/dist/types/index.js.map +0 -1
  131. package/cli/dist/utils/cache.d.ts +0 -19
  132. package/cli/dist/utils/cache.d.ts.map +0 -1
  133. package/cli/dist/utils/cache.js.map +0 -1
  134. package/cli/dist/utils/command-helpers.d.ts +0 -17
  135. package/cli/dist/utils/command-helpers.d.ts.map +0 -1
  136. package/cli/dist/utils/command-helpers.js.map +0 -1
  137. package/cli/dist/utils/constants.d.ts +0 -53
  138. package/cli/dist/utils/constants.d.ts.map +0 -1
  139. package/cli/dist/utils/constants.js.map +0 -1
  140. package/cli/dist/utils/discovery-context.d.ts +0 -4
  141. package/cli/dist/utils/discovery-context.d.ts.map +0 -1
  142. package/cli/dist/utils/discovery-context.js.map +0 -1
  143. package/cli/dist/utils/docker.d.ts +0 -4
  144. package/cli/dist/utils/docker.d.ts.map +0 -1
  145. package/cli/dist/utils/docker.js.map +0 -1
  146. package/cli/dist/utils/doctor-runtime.d.ts +0 -81
  147. package/cli/dist/utils/doctor-runtime.d.ts.map +0 -1
  148. package/cli/dist/utils/doctor-runtime.js.map +0 -1
  149. package/cli/dist/utils/env-validator.d.ts +0 -15
  150. package/cli/dist/utils/env-validator.d.ts.map +0 -1
  151. package/cli/dist/utils/env-validator.js.map +0 -1
  152. package/cli/dist/utils/errors.d.ts +0 -31
  153. package/cli/dist/utils/errors.d.ts.map +0 -1
  154. package/cli/dist/utils/errors.js.map +0 -1
  155. package/cli/dist/utils/file-helpers.d.ts +0 -14
  156. package/cli/dist/utils/file-helpers.d.ts.map +0 -1
  157. package/cli/dist/utils/file-helpers.js.map +0 -1
  158. package/cli/dist/utils/formatting.d.ts +0 -30
  159. package/cli/dist/utils/formatting.d.ts.map +0 -1
  160. package/cli/dist/utils/formatting.js.map +0 -1
  161. package/cli/dist/utils/paths.d.ts +0 -3
  162. package/cli/dist/utils/paths.d.ts.map +0 -1
  163. package/cli/dist/utils/paths.js.map +0 -1
  164. package/cli/dist/utils/port-assignment.d.ts +0 -6
  165. package/cli/dist/utils/port-assignment.d.ts.map +0 -1
  166. package/cli/dist/utils/port-assignment.js.map +0 -1
  167. package/cli/dist/utils/project-features.d.ts +0 -23
  168. package/cli/dist/utils/project-features.d.ts.map +0 -1
  169. package/cli/dist/utils/project-features.js.map +0 -1
  170. package/cli/dist/utils/project-templates.d.ts +0 -7
  171. package/cli/dist/utils/project-templates.d.ts.map +0 -1
  172. package/cli/dist/utils/project-templates.js.map +0 -1
  173. package/cli/dist/utils/prompt.d.ts +0 -28
  174. package/cli/dist/utils/prompt.d.ts.map +0 -1
  175. package/cli/dist/utils/prompt.js.map +0 -1
  176. package/cli/dist/utils/resource-features.d.ts +0 -29
  177. package/cli/dist/utils/resource-features.d.ts.map +0 -1
  178. package/cli/dist/utils/resource-features.js.map +0 -1
  179. package/cli/dist/utils/service-urls.d.ts +0 -30
  180. package/cli/dist/utils/service-urls.d.ts.map +0 -1
  181. package/cli/dist/utils/service-urls.js.map +0 -1
  182. package/cli/dist/utils/services.d.ts +0 -18
  183. package/cli/dist/utils/services.d.ts.map +0 -1
  184. package/cli/dist/utils/services.js.map +0 -1
  185. package/cli/dist/utils/stack-features.d.ts +0 -22
  186. package/cli/dist/utils/stack-features.d.ts.map +0 -1
  187. package/cli/dist/utils/stack-features.js.map +0 -1
  188. package/cli/dist/utils/tar.d.ts +0 -7
  189. package/cli/dist/utils/tar.d.ts.map +0 -1
  190. package/cli/dist/utils/tar.js.map +0 -1
  191. package/cli/dist/utils/tilt.d.ts +0 -20
  192. package/cli/dist/utils/tilt.d.ts.map +0 -1
  193. package/cli/dist/utils/tilt.js.map +0 -1
  194. package/cli/dist/utils/validation.d.ts +0 -16
  195. package/cli/dist/utils/validation.d.ts.map +0 -1
  196. package/cli/dist/utils/validation.js.map +0 -1
  197. package/cli/knip.json +0 -6
  198. package/cli/pnpm-lock.yaml +0 -2305
  199. package/cli/pnpm-workspace.yaml +0 -2
  200. package/cli/src/cli.ts +0 -72
  201. package/cli/src/commands/__tests__/always-enabled-infra.test.ts +0 -109
  202. package/cli/src/commands/__tests__/config.test.ts +0 -146
  203. package/cli/src/commands/__tests__/doctor.test.ts +0 -730
  204. package/cli/src/commands/__tests__/error-handling.test.ts +0 -78
  205. package/cli/src/commands/__tests__/phases-model.test.ts +0 -161
  206. package/cli/src/commands/__tests__/project-resource-features-e2e.test.ts +0 -187
  207. package/cli/src/commands/__tests__/project.test.ts +0 -68
  208. package/cli/src/commands/__tests__/resource.test.ts +0 -226
  209. package/cli/src/commands/__tests__/saas-starter-integration.test.ts +0 -194
  210. package/cli/src/commands/__tests__/stack-features-e2e.test.ts +0 -135
  211. package/cli/src/commands/__tests__/upgrade.test.ts +0 -198
  212. package/cli/src/commands/completion.ts +0 -300
  213. package/cli/src/commands/config.ts +0 -299
  214. package/cli/src/commands/doctor.ts +0 -926
  215. package/cli/src/commands/down.ts +0 -37
  216. package/cli/src/commands/help.ts +0 -143
  217. package/cli/src/commands/networks-design.md +0 -80
  218. package/cli/src/commands/networks.ts +0 -332
  219. package/cli/src/commands/project.ts +0 -456
  220. package/cli/src/commands/projects.ts +0 -82
  221. package/cli/src/commands/resource.ts +0 -652
  222. package/cli/src/commands/resources.ts +0 -95
  223. package/cli/src/commands/stack.ts +0 -128
  224. package/cli/src/commands/stacks.ts +0 -52
  225. package/cli/src/commands/status.ts +0 -88
  226. package/cli/src/commands/ui.tsx +0 -843
  227. package/cli/src/commands/up.ts +0 -169
  228. package/cli/src/commands/upgrade.ts +0 -628
  229. package/cli/src/commands/version.ts +0 -9
  230. package/cli/src/components/Accessible.tsx +0 -21
  231. package/cli/src/components/BaseTooltip.tsx +0 -66
  232. package/cli/src/components/DetailPanel.tsx +0 -146
  233. package/cli/src/components/FileTree.tsx +0 -89
  234. package/cli/src/components/ResourceSelectInput.tsx +0 -30
  235. package/cli/src/components/ResourceTable.tsx +0 -78
  236. package/cli/src/components/TabBar.tsx +0 -53
  237. package/cli/src/components/Tooltip.tsx +0 -11
  238. package/cli/src/components/index.ts +0 -7
  239. package/cli/src/config/platform-standards.test.ts +0 -11
  240. package/cli/src/config/platform-standards.ts +0 -196
  241. package/cli/src/generator/__tests__/extension-fetch.test.ts +0 -242
  242. package/cli/src/generator/__tests__/template-engine.test.ts +0 -70
  243. package/cli/src/generator/extension-fetch.ts +0 -286
  244. package/cli/src/generator/template-engine.ts +0 -752
  245. package/cli/src/index.ts +0 -86
  246. package/cli/src/templates.d.ts +0 -4
  247. package/cli/src/types/index.ts +0 -353
  248. package/cli/src/utils/__tests__/cache.test.ts +0 -98
  249. package/cli/src/utils/__tests__/formatting.test.ts +0 -170
  250. package/cli/src/utils/__tests__/paths.test.ts +0 -180
  251. package/cli/src/utils/__tests__/port-assignment.test.ts +0 -121
  252. package/cli/src/utils/__tests__/service-urls.test.ts +0 -174
  253. package/cli/src/utils/__tests__/services.test.ts +0 -531
  254. package/cli/src/utils/__tests__/tilt.test.ts +0 -172
  255. package/cli/src/utils/__tests__/validation.test.ts +0 -148
  256. package/cli/src/utils/cache.ts +0 -76
  257. package/cli/src/utils/command-helpers.ts +0 -54
  258. package/cli/src/utils/constants.ts +0 -130
  259. package/cli/src/utils/discovery-context.ts +0 -49
  260. package/cli/src/utils/docker.ts +0 -20
  261. package/cli/src/utils/doctor-runtime.ts +0 -644
  262. package/cli/src/utils/env-validator.ts +0 -139
  263. package/cli/src/utils/errors.ts +0 -168
  264. package/cli/src/utils/file-helpers.ts +0 -62
  265. package/cli/src/utils/formatting.ts +0 -215
  266. package/cli/src/utils/paths.ts +0 -53
  267. package/cli/src/utils/port-assignment.ts +0 -106
  268. package/cli/src/utils/project-features.ts +0 -118
  269. package/cli/src/utils/project-templates.ts +0 -29
  270. package/cli/src/utils/prompt.ts +0 -128
  271. package/cli/src/utils/resource-features.ts +0 -215
  272. package/cli/src/utils/service-urls.ts +0 -124
  273. package/cli/src/utils/services.ts +0 -364
  274. package/cli/src/utils/stack-features.ts +0 -30
  275. package/cli/src/utils/tar.ts +0 -24
  276. package/cli/src/utils/tilt.ts +0 -133
  277. package/cli/src/utils/validation.ts +0 -67
  278. package/cli/tsconfig.json +0 -25
  279. package/cli/tsconfig.typecheck.json +0 -8
  280. package/docs/FEATURES.md +0 -281
  281. package/docs/demo.svg +0 -217
  282. package/engine/docs/AUTODISCOVERY_TEST.md +0 -182
  283. package/engine/docs/C4-ARCHITECTURE-operations.md +0 -396
  284. package/engine/docs/C4-ARCHITECTURE-overview.md +0 -284
  285. package/engine/docs/C4-ARCHITECTURE.md +0 -17
  286. package/engine/docs/GOLDEN_IMAGE_INTEGRATION.md +0 -349
  287. package/engine/docs/MANIFEST_DRIVEN_ARCHITECTURE.md +0 -357
  288. package/engine/docs/README.md +0 -284
  289. package/install.sh +0 -19
  290. package/knip.json +0 -10
  291. package/openspec/changes/add-vscode-tdk-troubleshooter-plugin/.openspec.yaml +0 -2
  292. package/openspec/changes/add-vscode-tdk-troubleshooter-plugin/design.md +0 -102
  293. package/openspec/changes/add-vscode-tdk-troubleshooter-plugin/proposal.md +0 -31
  294. package/openspec/changes/add-vscode-tdk-troubleshooter-plugin/specs/vscode-tdk-notifications/spec.md +0 -48
  295. package/openspec/changes/add-vscode-tdk-troubleshooter-plugin/specs/vscode-tdk-orchestration/spec.md +0 -63
  296. package/openspec/changes/add-vscode-tdk-troubleshooter-plugin/specs/vscode-tdk-troubleshooting/spec.md +0 -56
  297. package/openspec/changes/add-vscode-tdk-troubleshooter-plugin/tasks.md +0 -61
  298. package/openspec/changes/archive/2026-04-28-rename-domain-to-stack-service-to-resource/.openspec.yaml +0 -2
  299. package/openspec/changes/archive/2026-04-28-rename-domain-to-stack-service-to-resource/design.md +0 -114
  300. package/openspec/changes/archive/2026-04-28-rename-domain-to-stack-service-to-resource/proposal.md +0 -32
  301. package/openspec/changes/archive/2026-04-28-rename-domain-to-stack-service-to-resource/specs/manifest-field-migration/spec.md +0 -20
  302. package/openspec/changes/archive/2026-04-28-rename-domain-to-stack-service-to-resource/specs/resource-terminology-standard/spec.md +0 -20
  303. package/openspec/changes/archive/2026-04-28-rename-domain-to-stack-service-to-resource/specs/stack-terminology-standard/spec.md +0 -20
  304. package/openspec/changes/archive/2026-04-28-rename-domain-to-stack-service-to-resource/tasks.md +0 -194
  305. package/openspec/changes/archive/2026-04-28-star-files-parameter-fixes/.openspec.yaml +0 -2
  306. package/openspec/changes/archive/2026-04-28-star-files-parameter-fixes/design.md +0 -111
  307. package/openspec/changes/archive/2026-04-28-star-files-parameter-fixes/proposal.md +0 -33
  308. package/openspec/changes/archive/2026-04-28-star-files-parameter-fixes/specs/function-naming-alignment/spec.md +0 -12
  309. package/openspec/changes/archive/2026-04-28-star-files-parameter-fixes/specs/optional-parameter-patterns/spec.md +0 -18
  310. package/openspec/changes/archive/2026-04-28-star-files-parameter-fixes/specs/parameter-documentation/spec.md +0 -16
  311. package/openspec/changes/archive/2026-04-28-star-files-parameter-fixes/specs/parameter-naming-consistency/spec.md +0 -12
  312. package/openspec/changes/archive/2026-04-28-star-files-parameter-fixes/specs/parameter-ordering-standard/spec.md +0 -12
  313. package/openspec/changes/archive/2026-04-28-star-files-parameter-fixes/tasks.md +0 -194
  314. package/openspec/changes/archive/2026-04-29-scan-repo-gaps-fix/.openspec.yaml +0 -2
  315. package/openspec/changes/archive/2026-04-29-scan-repo-gaps-fix/design.md +0 -84
  316. package/openspec/changes/archive/2026-04-29-scan-repo-gaps-fix/proposal.md +0 -31
  317. package/openspec/changes/archive/2026-04-29-scan-repo-gaps-fix/specs/codebase-audit/spec.md +0 -27
  318. package/openspec/changes/archive/2026-04-29-scan-repo-gaps-fix/specs/dead-code-cleanup/spec.md +0 -27
  319. package/openspec/changes/archive/2026-04-29-scan-repo-gaps-fix/specs/test-gap-fill/spec.md +0 -23
  320. package/openspec/changes/archive/2026-04-29-scan-repo-gaps-fix/specs/todo-resolution/spec.md +0 -27
  321. package/openspec/changes/archive/2026-04-29-scan-repo-gaps-fix/tasks.md +0 -39
  322. package/openspec/changes/archive/2026-06-25-landscape-consolidation/.openspec.yaml +0 -2
  323. package/openspec/changes/archive/2026-06-25-landscape-consolidation/design.md +0 -80
  324. package/openspec/changes/archive/2026-06-25-landscape-consolidation/proposal.md +0 -40
  325. package/openspec/changes/archive/2026-06-25-landscape-consolidation/spec.md +0 -52
  326. package/openspec/changes/archive/2026-06-25-landscape-consolidation/tasks.md +0 -51
  327. package/openspec/changes/archive/2026-09-17-fix-generated-stack-boot/.openspec.yaml +0 -2
  328. package/openspec/changes/archive/2026-09-17-fix-generated-stack-boot/design.md +0 -43
  329. package/openspec/changes/archive/2026-09-17-fix-generated-stack-boot/proposal.md +0 -29
  330. package/openspec/changes/archive/2026-09-17-fix-generated-stack-boot/specs/self-contained-generated-projects/spec.md +0 -67
  331. package/openspec/changes/archive/2026-09-17-fix-generated-stack-boot/tasks.md +0 -27
  332. package/openspec/changes/optimize-runtime-docker-layers/.openspec.yaml +0 -3
  333. package/openspec/changes/optimize-runtime-docker-layers/design.md +0 -81
  334. package/openspec/changes/optimize-runtime-docker-layers/proposal.md +0 -44
  335. package/openspec/changes/optimize-runtime-docker-layers/specs/runtime-container-footprint/spec.md +0 -79
  336. package/openspec/changes/optimize-runtime-docker-layers/tasks.md +0 -36
  337. package/openspec/changes/prioritized-cold-start/.openspec.yaml +0 -4
  338. package/openspec/changes/prioritized-cold-start/design.md +0 -137
  339. package/openspec/changes/prioritized-cold-start/proposal.md +0 -41
  340. package/openspec/changes/prioritized-cold-start/specs/on-demand-resource-startup/spec.md +0 -98
  341. package/openspec/changes/prioritized-cold-start/tasks.md +0 -69
  342. package/openspec/config.yaml +0 -1
  343. package/openspec/specs/manifest-field-migration/spec.md +0 -24
  344. package/openspec/specs/resource-terminology-standard/spec.md +0 -24
  345. package/openspec/specs/self-contained-generated-projects/spec.md +0 -67
  346. package/openspec/specs/stack-terminology-standard/spec.md +0 -24
  347. package/platform/services/platform/proxy/service.yaml +0 -14
  348. package/scripts/audit-codebase.sh +0 -213
  349. package/scripts/autoresearch/layer-eval.sh +0 -65
  350. package/scripts/benchmark/README.md +0 -25
  351. package/scripts/benchmark/container-scale.ts +0 -503
  352. package/scripts/benchmark/pre-release-gate.sh +0 -9
  353. package/scripts/install-git-hooks.sh +0 -14
  354. package/scripts/measure-idle-footprint.sh +0 -58
  355. package/scripts/record-demo.sh +0 -43
  356. package/scripts/release-binaries.sh +0 -97
  357. package/scripts/setup-pre-commit.sh +0 -33
  358. package/scripts/stage-npm-engine.sh +0 -36
  359. package/tests/tilt-engine/__init__.py +0 -5
  360. package/tests/tilt-engine/conftest.py +0 -182
  361. package/tests/tilt-engine/fixtures/appointment-frontend-service.json +0 -11
  362. package/tests/tilt-engine/fixtures/identity-backend-service.json +0 -12
  363. package/tests/tilt-engine/fixtures/invalid-service.json +0 -4
  364. package/tests/tilt-engine/test_agents_md_generator.py +0 -341
  365. package/tests/tilt-engine/test_agents_md_integration.py +0 -378
  366. package/tests/tilt-engine/test_cache_operations.py +0 -181
  367. package/tests/tilt-engine/test_cache_persistence.py +0 -142
  368. package/tests/tilt-engine/test_code_executor.py +0 -152
  369. package/tests/tilt-engine/test_code_viewer.py +0 -127
  370. package/tests/tilt-engine/test_compose_port_anchors.py +0 -310
  371. package/tests/tilt-engine/test_config_inspector.py +0 -162
  372. package/tests/tilt-engine/test_daemon_focus_mode.py +0 -89
  373. package/tests/tilt-engine/test_daemon_polling.py +0 -122
  374. package/tests/tilt-engine/test_daemon_registration.py +0 -115
  375. package/tests/tilt-engine/test_daemon_validation.py +0 -107
  376. package/tests/tilt-engine/test_docker_generator_bugs.py +0 -493
  377. package/tests/tilt-engine/test_docker_prune.py +0 -119
  378. package/tests/tilt-engine/test_dockerignore_path_bug.py +0 -82
  379. package/tests/tilt-engine/test_file_browser.py +0 -193
  380. package/tests/tilt-engine/test_frontend_basepath_manifest.py +0 -27
  381. package/tests/tilt-engine/test_health_dependencies.py +0 -130
  382. package/tests/tilt-engine/test_health_endpoints.py +0 -118
  383. package/tests/tilt-engine/test_health_tilt_ui.py +0 -85
  384. package/tests/tilt-engine/test_runtime_container_footprint.py +0 -162
  385. package/tests/tilt-engine/test_sablier_defer_start.py +0 -237
  386. package/tests/tilt-engine/test_safety_aliases.py +0 -84
  387. package/tests/tilt-engine/test_snapshot_diff.py +0 -136
  388. package/tests/tilt-engine/test_snapshot_persistence.py +0 -163
  389. package/tests/tilt-engine/test_snapshot_scanning.py +0 -123
  390. package/tests/tilt-engine/test_standalone_project_boot.py +0 -61
  391. package/tests/tilt-engine/test_standalone_traefik.py +0 -160
  392. package/tests/tilt-engine/test_traefik_static_wake_route.py +0 -187
@@ -1,752 +0,0 @@
1
- import * as fs from "node:fs";
2
- import * as path from "node:path";
3
- import { fileURLToPath } from "node:url";
4
- import Handlebars from "handlebars";
5
- import { PLATFORM_STANDARDS } from "../config/platform-standards.js";
6
- import type { JsonValue, ProjectConfig } from "../types/index.js";
7
- import { writeTextFile } from "../utils/file-helpers.js";
8
- import { discoverResourcesFromRoot } from "../utils/services.js";
9
- import { isStackFeatureEnabledInStacks } from "../utils/stack-features.js";
10
- import { hasSablierLicense, hasVerdaccioLicense } from "./extension-fetch.js";
11
-
12
- const __filename = fileURLToPath(import.meta.url);
13
- const __dirname = path.dirname(__filename);
14
-
15
- // Helper function to load templates with robust path resolution
16
- export function loadTemplate(filename: string): string {
17
- // Try multiple possible template directory locations
18
- const templateDirs = [
19
- path.join(__dirname, "..", "..", "templates"), // Standard: dist/generator -> templates (also covers src/generator -> ../../templates in dev/test)
20
- path.join(__dirname, "..", "templates"), // Installed: dist/generator -> dist/templates
21
- path.join(__dirname, "..", "..", "..", "templates"), // Development: cli/dist/generator -> cli/templates
22
- path.join(process.cwd(), "node_modules", "@tdk-landscape", "tdk-cli-core", "templates"), // Monorepo root
23
- // Compiled single-file binary (bun build --compile): __dirname resolves inside the
24
- // virtual $bunfs filesystem, not a real path, so fall back to the directory the actual
25
- // executable lives in. release-binaries.sh bundles cli/templates at tdk-cli/cli/templates
26
- // next to the platform binaries.
27
- path.join(path.dirname(process.execPath), "tdk-cli", "cli", "templates"),
28
- ];
29
-
30
- const triedPaths: string[] = [];
31
- for (const templateDir of templateDirs) {
32
- const templatePath = path.join(templateDir, filename);
33
- triedPaths.push(templatePath);
34
- try {
35
- return fs.readFileSync(templatePath, "utf-8");
36
- } catch (_error) {}
37
- }
38
-
39
- throw new Error(
40
- `Failed to load template ${filename} from any of these paths: ${triedPaths.join(", ")}`,
41
- );
42
- }
43
-
44
- // Templates used to be loaded eagerly here, at module initialization. That
45
- // meant importing this module at all (e.g. via cli.ts -> config.ts/project.ts)
46
- // threw immediately whenever the bundled templates folder was missing or
47
- // stale - bricking every single `tdk` command, including `tdk upgrade`, the
48
- // one command meant to repair a stale install. Load lazily instead, on first
49
- // actual use, so commands that don't need templates (upgrade, doctor,
50
- // version, ...) keep working even when the templates folder is absent, and
51
- // `tdk upgrade` can run to fix it.
52
- let embeddedTemplatesCache: Record<string, string> | null = null;
53
- function getEmbeddedTemplates(): Record<string, string> {
54
- if (!embeddedTemplatesCache) {
55
- embeddedTemplatesCache = {
56
- ".tiltignore": loadTemplate(".tiltignore.hbs"),
57
- "TILT_RESOURCE_DEFAULTS.star": loadTemplate("TILT_RESOURCE_DEFAULTS.star.hbs"),
58
- "TILT_TECH_STACK.star": loadTemplate("TILT_TECH_STACK.star.hbs"),
59
- Tiltfile: loadTemplate("Tiltfile.hbs"),
60
- "spec.master": loadTemplate("spec.master.hbs"),
61
- };
62
- }
63
- return embeddedTemplatesCache;
64
- }
65
-
66
- interface GeneratorContext {
67
- version: string;
68
- timestamp: string;
69
- tech: typeof PLATFORM_STANDARDS.tech;
70
- ports: typeof PLATFORM_STANDARDS.ports;
71
- health: typeof PLATFORM_STANDARDS.health;
72
- naming: typeof PLATFORM_STANDARDS.naming;
73
- traefik: typeof PLATFORM_STANDARDS.traefik;
74
- filewatchIgnores: string[];
75
- serviceTypes: typeof PLATFORM_STANDARDS.serviceTypes;
76
- paths: typeof PLATFORM_STANDARDS.paths;
77
- discovery: { scanIntervalSeconds: number; maxManifestsPerRoot: number; paths: string[] };
78
- docker: typeof PLATFORM_STANDARDS.docker;
79
- runtime: typeof PLATFORM_STANDARDS.runtime;
80
- project: ProjectConfig["project"];
81
- phases: ProjectConfig["phases"];
82
- alwaysEnabledInfra: string[];
83
- optionalInfra: ProjectConfig["optional_infra"];
84
- serviceDescriptions: Record<string, string>;
85
- infraDescriptions: Record<string, string>;
86
- }
87
-
88
- // Generic resource descriptions - no hardcoded service names
89
- // Users define their own service descriptions in project.json
90
- const RESOURCE_DESCRIPTIONS: Record<string, string> = {
91
- proxy: "Traefik reverse proxy",
92
- verdaccio: "Private npm registry",
93
- "database-management": "PostgreSQL database",
94
- };
95
-
96
- const INFRA_DESCRIPTIONS: Record<string, string> = {
97
- monitoring: "Signoz, SkyWalking (RAM intensive)",
98
- elk: "Elasticsearch/Logstash/Kibana",
99
- debezium: "CDC with Kafka/Zookeeper",
100
- golden_image: "Golden image rebuild (one-time)",
101
- verdaccio: "Premium local npm registry",
102
- };
103
-
104
- /**
105
- * List of all files generated by the template engine.
106
- * Used for iteration and type-safe access to generated content.
107
- */
108
- const ALL_GENERATED_FILES = [
109
- "TILT_TECH_STACK.star",
110
- "TILT_RESOURCE_DEFAULTS.star",
111
- "spec.master",
112
- "Tiltfile",
113
- ".tiltignore",
114
- ] as const;
115
-
116
- /**
117
- * Type representing valid generated file names.
118
- * Derived from ALL_GENERATED_FILES const array for type safety.
119
- */
120
- type GeneratedFileName = (typeof ALL_GENERATED_FILES)[number];
121
-
122
- export class TemplateEngine {
123
- private templatesDir: string;
124
-
125
- constructor(templatesDir?: string) {
126
- const currentDir = import.meta.dirname || path.dirname(new URL(import.meta.url).pathname);
127
- this.templatesDir = templatesDir || path.join(currentDir, "..", "..", "templates");
128
- this.registerHelpers();
129
- }
130
-
131
- private formatStarlarkValue(val: JsonValue): string {
132
- if (val === null || val === undefined) {
133
- return "None";
134
- }
135
- if (typeof val === "string") {
136
- return `"${val.replace(/"/g, '\\"')}"`;
137
- }
138
- if (typeof val === "boolean") {
139
- return val ? "True" : "False";
140
- }
141
- if (typeof val === "number") {
142
- return String(val);
143
- }
144
- if (Array.isArray(val)) {
145
- const items = val.map((item) => this.formatStarlarkValue(item));
146
- return `[${items.join(", ")}]`;
147
- }
148
- if (typeof val === "object") {
149
- const entries = Object.entries(val).map(([key, v]) => {
150
- return `"${key}": ${this.formatStarlarkValue(v)}`;
151
- });
152
- return `{${entries.join(", ")}}`;
153
- }
154
- return String(val);
155
- }
156
-
157
- private registerHelpers(): void {
158
- Handlebars.registerHelper("starlark", (value: JsonValue): Handlebars.SafeString => {
159
- return new Handlebars.SafeString(this.formatStarlarkValue(value));
160
- });
161
-
162
- Handlebars.registerHelper("starlarkArray", (value: JsonValue[]): Handlebars.SafeString => {
163
- if (!Array.isArray(value)) return new Handlebars.SafeString("[]");
164
- const items = value.map((item) => this.formatStarlarkValue(item));
165
- return new Handlebars.SafeString(`[${items.join(", ")}]`);
166
- });
167
-
168
- Handlebars.registerHelper("json", (value: JsonValue): string => {
169
- return JSON.stringify(value);
170
- });
171
- }
172
-
173
- buildContext(projectConfig: ProjectConfig): GeneratorContext {
174
- return {
175
- version: PLATFORM_STANDARDS.version,
176
- timestamp: new Date().toISOString(),
177
- tech: PLATFORM_STANDARDS.tech,
178
- ports: PLATFORM_STANDARDS.ports,
179
- health: PLATFORM_STANDARDS.health,
180
- naming: PLATFORM_STANDARDS.naming,
181
- traefik: PLATFORM_STANDARDS.traefik,
182
- filewatchIgnores: [...PLATFORM_STANDARDS.filewatchIgnores],
183
- serviceTypes: PLATFORM_STANDARDS.serviceTypes,
184
- paths: PLATFORM_STANDARDS.paths,
185
- discovery: {
186
- scanIntervalSeconds: PLATFORM_STANDARDS.discovery.scanIntervalSeconds,
187
- maxManifestsPerRoot: PLATFORM_STANDARDS.discovery.maxManifestsPerRoot,
188
- paths: projectConfig.discovery.paths,
189
- },
190
- docker: PLATFORM_STANDARDS.docker,
191
- runtime: PLATFORM_STANDARDS.runtime,
192
- project: projectConfig.project,
193
- phases: dedupePhaseEnabledStacks(projectConfig.phases),
194
- alwaysEnabledInfra: projectConfig.always_enabled_infra ?? ["database-management", "proxy"],
195
- optionalInfra: projectConfig.optional_infra,
196
- serviceDescriptions: RESOURCE_DESCRIPTIONS,
197
- infraDescriptions: INFRA_DESCRIPTIONS,
198
- };
199
- }
200
-
201
- private loadTemplate(templateName: string): HandlebarsTemplateDelegate {
202
- const templatePath = path.join(this.templatesDir, `${templateName}.hbs`);
203
- const templateSource = fs.existsSync(templatePath)
204
- ? fs.readFileSync(templatePath, "utf-8")
205
- : getEmbeddedTemplates()[templateName];
206
- if (!templateSource) {
207
- throw new Error(`Template not found: ${templatePath}`);
208
- }
209
- return Handlebars.compile(templateSource);
210
- }
211
-
212
- generateTechStack(context: GeneratorContext): string {
213
- const template = this.loadTemplate("TILT_TECH_STACK.star");
214
- return template(context);
215
- }
216
-
217
- generateServiceDefaults(context: GeneratorContext): string {
218
- const template = this.loadTemplate("TILT_RESOURCE_DEFAULTS.star");
219
- return template(context);
220
- }
221
-
222
- generateSpecMaster(context: GeneratorContext): string {
223
- const template = this.loadTemplate("spec.master");
224
- return template(context);
225
- }
226
-
227
- generateTiltfile(context: GeneratorContext): string {
228
- const template = this.loadTemplate("Tiltfile");
229
- return template(context);
230
- }
231
-
232
- generateTiltIgnore(context: GeneratorContext): string {
233
- const template = this.loadTemplate(".tiltignore");
234
- return template(context);
235
- }
236
-
237
- generateAll(projectConfig: ProjectConfig): Record<GeneratedFileName, string> {
238
- const context = this.buildContext(projectConfig);
239
-
240
- return {
241
- "TILT_TECH_STACK.star": this.generateTechStack(context),
242
- "TILT_RESOURCE_DEFAULTS.star": this.generateServiceDefaults(context),
243
- "spec.master": this.generateSpecMaster(context),
244
- Tiltfile: this.generateTiltfile(context),
245
- ".tiltignore": this.generateTiltIgnore(context),
246
- };
247
- }
248
- }
249
-
250
- // spec.master.hbs emits one Starlark dict entry per enabledStacks[] item, so a
251
- // duplicate name in project.json (e.g. from the interactive wizard offering
252
- // the same service as both a core feature and a discovered stack) becomes a
253
- // duplicate dict key, which fails Starlark parsing at `tdk up`. Dedupe here
254
- // so a bad project.json can't break generation.
255
- function dedupePhaseEnabledStacks(phases: ProjectConfig["phases"]): ProjectConfig["phases"] {
256
- const deduped = { ...phases };
257
- for (const key of Object.keys(deduped) as (keyof ProjectConfig["phases"])[]) {
258
- deduped[key] = {
259
- ...deduped[key],
260
- enabledStacks: Array.from(new Set(deduped[key].enabledStacks)),
261
- };
262
- }
263
- return deduped;
264
- }
265
-
266
- function toComposeProjectName(projectName: string): string {
267
- return projectName.replace(/-/g, "_");
268
- }
269
-
270
- export function generateDatabaseManagementCompose(projectConfig: ProjectConfig): string {
271
- const name = toComposeProjectName(projectConfig.project.name || "tdk_project");
272
- return `###############################################################################
273
- # SYSTEM-GENERATED - DO NOT EDIT
274
- # Stack feature: database-management
275
- # Source: .tdk/project.json phases.*.enabledStacks includes "database-management"
276
- ###############################################################################
277
-
278
- services:
279
- postgres:
280
- image: postgres:16-alpine
281
- container_name: ${name}_postgres
282
- restart: unless-stopped
283
- environment:
284
- POSTGRES_USER: ${name}
285
- POSTGRES_PASSWORD: \${DB_PASSWORD}
286
- POSTGRES_DB: postgres
287
- ports:
288
- - "5432:5432"
289
- volumes:
290
- - ${name}_postgres_data:/var/lib/postgresql/data
291
- networks:
292
- - database
293
- healthcheck:
294
- test: ["CMD-SHELL", "pg_isready -U ${name} -d postgres"]
295
- interval: 5s
296
- timeout: 5s
297
- retries: 20
298
-
299
- networks:
300
- database:
301
- name: ${name}_database
302
- external: true
303
-
304
- volumes:
305
- ${name}_postgres_data:
306
- `;
307
- }
308
-
309
- /**
310
- * Type guard to validate if an unknown value is a valid ProjectConfig.
311
- *
312
- * NOTE: The `as` assertions below are INTENTIONAL and SAFE:
313
- * - We've already verified `typeof value === 'object'` and `value !== null`
314
- * - TypeScript doesn't automatically narrow `{}` to `Record<string, unknown>`
315
- * - Each assertion is immediately followed by property type checks
316
- * - This pattern is standard for deep object validation in type guards
317
- */
318
- function hasPhaseShape(value: unknown, fieldName: "enabledStacks" | "services"): boolean {
319
- if (!value || typeof value !== "object") return false;
320
- const phases = value as Record<string, unknown>;
321
- for (const phaseName of ["pre_alpha", "alpha", "beta", "out_of_scope"]) {
322
- const phase = phases[phaseName];
323
- if (!phase || typeof phase !== "object") return false;
324
- if (!Array.isArray((phase as Record<string, unknown>)[fieldName])) return false;
325
- }
326
- return true;
327
- }
328
-
329
- function normalizeProjectConfig(value: unknown): ProjectConfig | null {
330
- if (!value || typeof value !== "object") {
331
- return null;
332
- }
333
-
334
- // Safe to assert as Record after null and object type checks
335
- const config = value as Record<string, unknown>;
336
-
337
- if (typeof config.version !== "string") {
338
- return null;
339
- }
340
-
341
- if (!config.project || typeof config.project !== "object") {
342
- return null;
343
- }
344
- const project = config.project as Record<string, unknown>;
345
- if (typeof project.name !== "string" || typeof project.version !== "string") {
346
- return null;
347
- }
348
-
349
- let phases: ProjectConfig["phases"] | null = null;
350
- if (hasPhaseShape(config.phases, "enabledStacks")) {
351
- phases = config.phases as ProjectConfig["phases"];
352
- } else if (hasPhaseShape(config.stacks, "services")) {
353
- const legacyStacks = config.stacks as NonNullable<ProjectConfig["stacks"]>;
354
- phases = {
355
- pre_alpha: {
356
- name: legacyStacks.pre_alpha.name,
357
- description: legacyStacks.pre_alpha.description,
358
- enabledStacks: legacyStacks.pre_alpha.services,
359
- },
360
- alpha: {
361
- name: legacyStacks.alpha.name,
362
- description: legacyStacks.alpha.description,
363
- enabledStacks: legacyStacks.alpha.services,
364
- },
365
- beta: {
366
- name: legacyStacks.beta.name,
367
- description: legacyStacks.beta.description,
368
- enabledStacks: legacyStacks.beta.services,
369
- },
370
- out_of_scope: {
371
- name: legacyStacks.out_of_scope.name,
372
- description: legacyStacks.out_of_scope.description,
373
- enabledStacks: legacyStacks.out_of_scope.services,
374
- },
375
- };
376
- }
377
-
378
- if (!phases) {
379
- return null;
380
- }
381
-
382
- if (!config.optional_infra || typeof config.optional_infra !== "object") {
383
- return null;
384
- }
385
- const optionalInfra = config.optional_infra as Record<string, unknown>;
386
- if (
387
- typeof optionalInfra.monitoring !== "boolean" ||
388
- typeof optionalInfra.elk !== "boolean" ||
389
- typeof optionalInfra.debezium !== "boolean" ||
390
- typeof optionalInfra.golden_image !== "boolean" ||
391
- typeof optionalInfra.verdaccio !== "boolean"
392
- ) {
393
- return null;
394
- }
395
-
396
- if (!config.discovery || typeof config.discovery !== "object") {
397
- return null;
398
- }
399
- const discovery = config.discovery as Record<string, unknown>;
400
- if (!Array.isArray(discovery.paths)) {
401
- return null;
402
- }
403
-
404
- return {
405
- version: config.version,
406
- project: config.project as ProjectConfig["project"],
407
- phases,
408
- always_enabled_infra: config.always_enabled_infra as string[] | undefined,
409
- optional_infra: config.optional_infra as ProjectConfig["optional_infra"],
410
- discovery: config.discovery as ProjectConfig["discovery"],
411
- overrides: config.overrides as ProjectConfig["overrides"],
412
- };
413
- }
414
-
415
- export function readProjectConfig(projectRoot: string): ProjectConfig {
416
- const projectJsonPath = path.join(projectRoot, ".tdk", "project.json");
417
-
418
- if (!fs.existsSync(projectJsonPath)) {
419
- throw new Error(`Project config not found: ${projectJsonPath}. Run 'tdk project init' first.`);
420
- }
421
-
422
- const jsonContent = fs.readFileSync(projectJsonPath, "utf-8");
423
- const parsed: unknown = JSON.parse(jsonContent);
424
-
425
- const projectConfig = normalizeProjectConfig(parsed);
426
- if (!projectConfig) {
427
- throw new Error(
428
- "Invalid project.json: missing or invalid required fields. " +
429
- "Expected: version (string), project (object with name/version), " +
430
- "phases (object with pre_alpha/alpha/beta/out_of_scope enabledStacks), " +
431
- "optional_infra (object with boolean flags), " +
432
- "discovery (object with paths array)",
433
- );
434
- }
435
-
436
- return projectConfig;
437
- }
438
-
439
- // Sablier ("sablier: {enable: true}" on a resource's own service.json) is
440
- // Premium, but unlike Verdaccio below, this is NOT the enforcement - it's a
441
- // friendly heads-up. The real gate is that engine/.../sablier_container_cycle.star
442
- // in this (public) repo is a free-tier stub that always returns disabled; the
443
- // working implementation only exists in the private tdk-cli-extensions/premium/
444
- // bundle, applied by vendorTdkExtension()'s applyPremiumOverlay() below when a
445
- // license grants it. Forking this repo and deleting a license check (as you
446
- // could with Verdaccio/DDD) gets you nothing here, because there's no check to
447
- // delete - the actual code simply isn't present without the overlay. This just
448
- // tells a confused free-tier user why their `sablier` block silently does
449
- // nothing, instead of leaving them to guess.
450
- async function warnIfSablierUnlicensed(projectRoot: string): Promise<void> {
451
- const resources = discoverResourcesFromRoot(projectRoot).filter(
452
- (r) => r.config?.sablier?.enable === true,
453
- );
454
- if (resources.length === 0) return;
455
-
456
- const granted = await hasSablierLicense(projectRoot);
457
- if (granted) return;
458
-
459
- console.warn(
460
- `⚠️ Sablier (on-demand scaling) is a Premium feature - no valid license key found. ` +
461
- `${resources.length} resource${resources.length === 1 ? " has" : "s have"} a \`sablier\` block, ` +
462
- "but it will have no effect without a license. Set TDK_LICENSE_KEY to a key that grants it, " +
463
- "or remove the `sablier` block from the affected service.json file(s) to silence this warning.",
464
- );
465
- }
466
-
467
- function ensureRootWorkspaceManifest(projectRoot: string, projectConfig: ProjectConfig): boolean {
468
- const packageJsonPath = path.join(projectRoot, "package.json");
469
- if (fs.existsSync(packageJsonPath)) {
470
- return false;
471
- }
472
-
473
- const manifest = {
474
- name: projectConfig.project.name || path.basename(projectRoot),
475
- version: projectConfig.project.version || "1.0.0",
476
- private: true,
477
- type: "module",
478
- workspaces: projectConfig.discovery.paths,
479
- };
480
-
481
- writeTextFile(packageJsonPath, `${JSON.stringify(manifest, null, 2)}\n`);
482
- return true;
483
- }
484
-
485
- export async function generateMasterConfigs(projectRoot: string): Promise<void> {
486
- const projectConfig = readProjectConfig(projectRoot);
487
-
488
- await warnIfSablierUnlicensed(projectRoot);
489
-
490
- if (ensureRootWorkspaceManifest(projectRoot, projectConfig)) {
491
- console.log("✓ Generated: package.json (workspace root)");
492
- }
493
-
494
- // Verdaccio is Premium, but unlike the old posture here, this is NOT the
495
- // enforcement - it's a friendly heads-up. The real gate is that
496
- // engine/topologies/platform/registries/verdaccio_loader.star in this
497
- // (public) repo is a free-tier stub that always skips; the working loader
498
- // only exists in the private tdk-cli-extensions/premium/ bundle, applied
499
- // by vendorTdkExtension()'s applyPremiumOverlay() below when a license
500
- // grants it. Forking this repo and deleting a license check gets you
501
- // nothing, because there's no check left to delete - the actual code
502
- // simply isn't present without the overlay. This just tells a confused
503
- // free-tier user why enabling Verdaccio silently did nothing, instead of
504
- // leaving them to guess.
505
- const verdaccioInPhase = Object.values(projectConfig.phases).some((phase) =>
506
- phase.enabledStacks.includes("verdaccio"),
507
- );
508
- if (projectConfig.optional_infra.verdaccio || verdaccioInPhase) {
509
- const granted = await hasVerdaccioLicense(projectRoot);
510
- if (!granted) {
511
- console.warn(
512
- "⚠️ Verdaccio is a Premium feature - no valid license key found. It's enabled in " +
513
- "this project's config, but will have no effect without a license. Set TDK_LICENSE_KEY " +
514
- "to a key that grants it, or run `tdk config disable-infra verdaccio` to silence this warning.",
515
- );
516
- }
517
- }
518
-
519
- const outputDir = path.join(projectRoot, ".tdk", ".tdk-out");
520
- if (!fs.existsSync(outputDir)) {
521
- fs.mkdirSync(outputDir, { recursive: true });
522
- }
523
-
524
- const engine = new TemplateEngine();
525
- const files = engine.generateAll(projectConfig);
526
-
527
- for (const filename of ALL_GENERATED_FILES) {
528
- const content = files[filename];
529
- const filePath = path.join(outputDir, filename);
530
- writeTextFile(filePath, content);
531
- console.log(`✓ Generated: .tdk/.tdk-out/${filename}`);
532
- }
533
-
534
- if (isStackFeatureEnabledInStacks(projectConfig.phases, "database-management")) {
535
- const composeDir = path.join(projectRoot, "services", "platform", "database-management");
536
- fs.mkdirSync(composeDir, { recursive: true });
537
- const composePath = path.join(composeDir, "docker-compose.yml");
538
- writeTextFile(composePath, generateDatabaseManagementCompose(projectConfig));
539
- console.log("✓ Generated: services/platform/database-management/docker-compose.yml");
540
- }
541
-
542
- // Copy .tiltignore to project root so Tilt uses it
543
- const tiltignoreSource = path.join(outputDir, ".tiltignore");
544
- const tiltignoreTarget = path.join(projectRoot, ".tiltignore");
545
- if (fs.existsSync(tiltignoreSource)) {
546
- fs.copyFileSync(tiltignoreSource, tiltignoreTarget);
547
- console.log(`✓ Copied: .tiltignore → project root`);
548
- }
549
-
550
- const copiedAssets = ensureProjectRuntimeAssets(projectRoot);
551
- for (const asset of copiedAssets) {
552
- console.log(`✓ Copied: ${asset} → project root`);
553
- }
554
-
555
- await vendorTdkExtension(projectRoot);
556
-
557
- console.log("");
558
- console.log("💡 To start Tilt: tdk up");
559
- }
560
-
561
- // The generated Tiltfile loads the TDK Tilt extension (engine, discovery,
562
- // specs, ext starlark modules). The extension repo may stay private, so we
563
- // vendor a working copy into .tdk/.tdk-out/tdk-cli-ext/ at generation time.
564
- // This makes `tdk up` work offline and on any machine - no hardcoded paths,
565
- // no dependency on a private GitHub repo.
566
- const TDK_EXTENSION_DIRS = ["engine", "discovery", "specs", "ext"] as string[];
567
- const PROJECT_RUNTIME_ASSET_DIRS = [["shared-platform-engineering", "docker-templates"]] as const;
568
- const REQUIRED_DOCKER_TEMPLATE_FILES = [
569
- "install-deps.sh",
570
- "bun-hoisted-symlink-fix.sh",
571
- "prisma-bun-client-link-fix.sh",
572
- "prisma-normalize-client.sh",
573
- ] as const;
574
-
575
- // Walk up from this module's own location looking for a directory that has
576
- // both Tiltfile and engine/ next to it - true when cli/ and engine/ ship
577
- // together in the same repo (the public tdk-cli-core layout, where a plain
578
- // `git clone` + `bun run` needs zero extra config to find the engine).
579
- function findSelfContainedEngineRoot(): string | null {
580
- let dir = import.meta.dirname || process.cwd();
581
- for (let i = 0; i < 6; i++) {
582
- if (fs.existsSync(path.join(dir, "Tiltfile")) && fs.existsSync(path.join(dir, "engine"))) {
583
- return dir;
584
- }
585
- const parent = path.dirname(dir);
586
- if (parent === dir) break;
587
- dir = parent;
588
- }
589
- return null;
590
- }
591
-
592
- function findCliAssetRoot(): string | null {
593
- let dir = import.meta.dirname || process.cwd();
594
- for (let i = 0; i < 8; i++) {
595
- if (fs.existsSync(path.join(dir, "shared-platform-engineering", "docker-templates"))) {
596
- return dir;
597
- }
598
- const parent = path.dirname(dir);
599
- if (parent === dir) break;
600
- dir = parent;
601
- }
602
-
603
- const exeDir = path.dirname(process.execPath);
604
- const candidates = [
605
- path.join(exeDir, "tdk-cli"),
606
- path.join(process.cwd(), "node_modules", "@tdk-landscape", "tdk-cli-core"),
607
- ];
608
-
609
- return (
610
- candidates.find((candidate) =>
611
- fs.existsSync(path.join(candidate, "shared-platform-engineering", "docker-templates")),
612
- ) ?? null
613
- );
614
- }
615
-
616
- export function ensureProjectRuntimeAssets(projectRoot: string): string[] {
617
- const sourceRoot = findCliAssetRoot();
618
- const copied: string[] = [];
619
-
620
- if (!sourceRoot) {
621
- console.warn(
622
- "⚠️ TDK runtime assets not found - generated Dockerfiles may fail. " +
623
- "Reinstall or upgrade TDK, then re-run `tdk project`.",
624
- );
625
- return copied;
626
- }
627
-
628
- for (const parts of PROJECT_RUNTIME_ASSET_DIRS) {
629
- const source = path.join(sourceRoot, ...parts);
630
- const target = path.join(projectRoot, ...parts);
631
- if (!fs.existsSync(source)) {
632
- continue;
633
- }
634
-
635
- fs.mkdirSync(path.dirname(target), { recursive: true });
636
- fs.cpSync(source, target, { recursive: true });
637
- copied.push(parts.join("/"));
638
- }
639
-
640
- for (const file of REQUIRED_DOCKER_TEMPLATE_FILES) {
641
- const filePath = path.join(
642
- projectRoot,
643
- "shared-platform-engineering",
644
- "docker-templates",
645
- file,
646
- );
647
- if (!fs.existsSync(filePath)) {
648
- console.warn(`⚠️ Missing runtime asset after copy: ${filePath}`);
649
- }
650
- }
651
-
652
- return copied;
653
- }
654
-
655
- async function vendorTdkExtension(projectRoot: string): Promise<void> {
656
- const outputDir = path.join(projectRoot, ".tdk", ".tdk-out");
657
- const vendoredDir = path.join(outputDir, "tdk-cli-ext");
658
-
659
- // Source resolution order:
660
- // 1. $TDK_EXTENSION_SOURCE (explicit override)
661
- // 2. Self-contained repo (engine/ ships next to cli/ - public tdk-cli-core)
662
- // 3. Executable-adjacent checkout (bundled installs)
663
- // 4. Relative ../tdk-cli sibling (monorepo maintainer layout)
664
- const sources: string[] = [];
665
- if (process.env.TDK_EXTENSION_SOURCE) {
666
- sources.push(process.env.TDK_EXTENSION_SOURCE);
667
- }
668
- const selfContainedRoot = findSelfContainedEngineRoot();
669
- if (selfContainedRoot) {
670
- sources.push(selfContainedRoot);
671
- }
672
- // process.execPath is the compiled binary's own path when running as a
673
- // standalone executable (what we actually need here). In dev mode it's
674
- // the bun CLI's own path instead (e.g. ~/.bun/bin/bun) - harmless, that
675
- // candidate just won't match anything and falls through to the next
676
- // one. Note: process.executablePath is not a real property on Node or
677
- // Bun's process object - it was always undefined, silently falling
678
- // back to cwd() instead of the binary's real location.
679
- const exeDir = path.dirname(process.execPath);
680
- sources.push(path.join(exeDir, "tdk-cli"));
681
- sources.push(path.join(projectRoot, "..", "tdk-cli"));
682
-
683
- let sourceRoot = "";
684
- for (const candidate of sources) {
685
- if (
686
- candidate &&
687
- fs.existsSync(path.join(candidate, "Tiltfile")) &&
688
- fs.existsSync(path.join(candidate, "engine"))
689
- ) {
690
- sourceRoot = candidate;
691
- break;
692
- }
693
- }
694
-
695
- if (!sourceRoot) {
696
- console.warn(
697
- "⚠️ TDK extension not found - set TDK_EXTENSION_SOURCE to its checkout path " +
698
- "and re-run `tdk project` (or `tdk config regenerate`) to vendor it before `tdk up`.",
699
- );
700
- return;
701
- }
702
-
703
- if (!fs.existsSync(vendoredDir)) {
704
- fs.mkdirSync(vendoredDir, { recursive: true });
705
- }
706
- fs.copyFileSync(path.join(sourceRoot, "Tiltfile"), path.join(vendoredDir, "Tiltfile"));
707
- for (const dir of TDK_EXTENSION_DIRS) {
708
- fs.cpSync(path.join(sourceRoot, dir), path.join(vendoredDir, dir), {
709
- recursive: true,
710
- });
711
- }
712
- console.log(`✓ Vendored TDK extension → .tdk/.tdk-out/tdk-cli-ext/`);
713
-
714
- // Best-effort: if TDK_LICENSE_KEY is set and grants any paid resource,
715
- // overlay the premium bundle over the stub files just vendored above.
716
- // No-ops silently (beyond a warning) if there's no key, the fetch
717
- // fails, or nothing's granted - the free engine already works fine on
718
- // its own.
719
- try {
720
- const { applyPremiumOverlay } = await import("./extension-fetch.js");
721
- await applyPremiumOverlay(projectRoot, vendoredDir);
722
- } catch (err) {
723
- console.warn(`⚠️ Premium overlay skipped: ${(err as Error).message}`);
724
- }
725
- }
726
-
727
- export function verifyMasterConfigs(projectRoot: string): { valid: boolean; errors: string[] } {
728
- const errors: string[] = [];
729
-
730
- const projectConfig = readProjectConfig(projectRoot);
731
- const engine = new TemplateEngine();
732
- const expectedFiles = engine.generateAll(projectConfig);
733
-
734
- const outputDir = path.join(projectRoot, ".tdk", ".tdk-out");
735
-
736
- for (const filename of ALL_GENERATED_FILES) {
737
- const expectedContent = expectedFiles[filename];
738
- const filePath = path.join(outputDir, filename);
739
-
740
- if (!fs.existsSync(filePath)) {
741
- errors.push(`Missing file: .tdk/.tdk-out/${filename}`);
742
- continue;
743
- }
744
-
745
- const actualContent = fs.readFileSync(filePath, "utf-8");
746
- if (actualContent !== expectedContent) {
747
- errors.push(`Out of sync: .tdk/.tdk-out/${filename} (run 'tdk config regenerate')`);
748
- }
749
- }
750
-
751
- return { valid: errors.length === 0, errors };
752
- }