@tdk-landscape/tdk-cli-core 1.3.52 → 1.3.54

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 (390) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/README.md +1 -1
  3. package/cli/dist/commands/config.js +1 -1
  4. package/cli/dist/commands/resource.js +1 -1
  5. package/cli/dist/generator/extension-fetch.js +16 -9
  6. package/cli/package.json +1 -1
  7. package/package.json +16 -1
  8. package/.claude/skills/layer-autoresearch/SKILL.md +0 -48
  9. package/.claude/skills/tdk-troubleshoot/SKILL.md +0 -222
  10. package/.github/ISSUE_TEMPLATE/bug_report.yml +0 -40
  11. package/.github/ISSUE_TEMPLATE/config.yml +0 -8
  12. package/.github/ISSUE_TEMPLATE/feature_request.yml +0 -18
  13. package/.github/dependabot.yml +0 -33
  14. package/.github/pull_request_template.md +0 -5
  15. package/.github/workflows/ci.yml +0 -200
  16. package/.github/workflows/release-binaries.yml +0 -139
  17. package/.github/zizmor.yml +0 -9
  18. package/.pre-commit-config.yaml +0 -57
  19. package/CODE_OF_CONDUCT.md +0 -9
  20. package/CONTRIBUTING.md +0 -42
  21. package/Makefile +0 -92
  22. package/SECURITY.md +0 -17
  23. package/benchmarks/results/container-scale-2026-09-25T20-54-49-736Z.json +0 -45
  24. package/benchmarks/results/container-scale-2026-09-25T21-01-20-540Z.json +0 -150
  25. package/benchmarks/results/container-scale-2026-09-25T21-15-01-441Z.json +0 -73
  26. package/benchmarks/results/container-scale-2026-09-25T22-09-01-630Z.json +0 -77
  27. package/benchmarks/results/container-scale-2026-09-25T22-18-28-371Z.json +0 -202
  28. package/cli/AGENTS.md +0 -390
  29. package/cli/DESIGN.md +0 -735
  30. package/cli/README.md +0 -292
  31. package/cli/biome.json +0 -40
  32. package/cli/dependency-graph.svg +0 -1135
  33. package/cli/dist/cli.d.ts +0 -3
  34. package/cli/dist/cli.d.ts.map +0 -1
  35. package/cli/dist/cli.js.map +0 -1
  36. package/cli/dist/commands/completion.d.ts +0 -3
  37. package/cli/dist/commands/completion.d.ts.map +0 -1
  38. package/cli/dist/commands/completion.js.map +0 -1
  39. package/cli/dist/commands/config.d.ts +0 -3
  40. package/cli/dist/commands/config.d.ts.map +0 -1
  41. package/cli/dist/commands/config.js.map +0 -1
  42. package/cli/dist/commands/doctor.d.ts +0 -19
  43. package/cli/dist/commands/doctor.d.ts.map +0 -1
  44. package/cli/dist/commands/doctor.js.map +0 -1
  45. package/cli/dist/commands/down.d.ts +0 -3
  46. package/cli/dist/commands/down.d.ts.map +0 -1
  47. package/cli/dist/commands/down.js.map +0 -1
  48. package/cli/dist/commands/help.d.ts +0 -2
  49. package/cli/dist/commands/help.d.ts.map +0 -1
  50. package/cli/dist/commands/help.js.map +0 -1
  51. package/cli/dist/commands/networks.d.ts +0 -3
  52. package/cli/dist/commands/networks.d.ts.map +0 -1
  53. package/cli/dist/commands/networks.js.map +0 -1
  54. package/cli/dist/commands/project.d.ts +0 -9
  55. package/cli/dist/commands/project.d.ts.map +0 -1
  56. package/cli/dist/commands/project.js.map +0 -1
  57. package/cli/dist/commands/projects.d.ts +0 -3
  58. package/cli/dist/commands/projects.d.ts.map +0 -1
  59. package/cli/dist/commands/projects.js.map +0 -1
  60. package/cli/dist/commands/resource.d.ts +0 -69
  61. package/cli/dist/commands/resource.d.ts.map +0 -1
  62. package/cli/dist/commands/resource.js.map +0 -1
  63. package/cli/dist/commands/resources.d.ts +0 -3
  64. package/cli/dist/commands/resources.d.ts.map +0 -1
  65. package/cli/dist/commands/resources.js.map +0 -1
  66. package/cli/dist/commands/stack.d.ts +0 -3
  67. package/cli/dist/commands/stack.d.ts.map +0 -1
  68. package/cli/dist/commands/stack.js.map +0 -1
  69. package/cli/dist/commands/stacks.d.ts +0 -3
  70. package/cli/dist/commands/stacks.d.ts.map +0 -1
  71. package/cli/dist/commands/stacks.js.map +0 -1
  72. package/cli/dist/commands/status.d.ts +0 -3
  73. package/cli/dist/commands/status.d.ts.map +0 -1
  74. package/cli/dist/commands/status.js.map +0 -1
  75. package/cli/dist/commands/ui.d.ts +0 -3
  76. package/cli/dist/commands/ui.d.ts.map +0 -1
  77. package/cli/dist/commands/ui.js.map +0 -1
  78. package/cli/dist/commands/up.d.ts +0 -3
  79. package/cli/dist/commands/up.d.ts.map +0 -1
  80. package/cli/dist/commands/up.js.map +0 -1
  81. package/cli/dist/commands/upgrade.d.ts +0 -14
  82. package/cli/dist/commands/upgrade.d.ts.map +0 -1
  83. package/cli/dist/commands/upgrade.js.map +0 -1
  84. package/cli/dist/commands/version.d.ts +0 -3
  85. package/cli/dist/commands/version.d.ts.map +0 -1
  86. package/cli/dist/commands/version.js.map +0 -1
  87. package/cli/dist/components/Accessible.d.ts +0 -8
  88. package/cli/dist/components/Accessible.d.ts.map +0 -1
  89. package/cli/dist/components/Accessible.js.map +0 -1
  90. package/cli/dist/components/BaseTooltip.d.ts +0 -4
  91. package/cli/dist/components/BaseTooltip.d.ts.map +0 -1
  92. package/cli/dist/components/BaseTooltip.js.map +0 -1
  93. package/cli/dist/components/DetailPanel.d.ts +0 -4
  94. package/cli/dist/components/DetailPanel.d.ts.map +0 -1
  95. package/cli/dist/components/DetailPanel.js.map +0 -1
  96. package/cli/dist/components/FileTree.d.ts +0 -4
  97. package/cli/dist/components/FileTree.d.ts.map +0 -1
  98. package/cli/dist/components/FileTree.js.map +0 -1
  99. package/cli/dist/components/ResourceSelectInput.d.ts +0 -4
  100. package/cli/dist/components/ResourceSelectInput.d.ts.map +0 -1
  101. package/cli/dist/components/ResourceSelectInput.js.map +0 -1
  102. package/cli/dist/components/ResourceTable.d.ts +0 -4
  103. package/cli/dist/components/ResourceTable.d.ts.map +0 -1
  104. package/cli/dist/components/ResourceTable.js.map +0 -1
  105. package/cli/dist/components/TabBar.d.ts +0 -4
  106. package/cli/dist/components/TabBar.d.ts.map +0 -1
  107. package/cli/dist/components/TabBar.js.map +0 -1
  108. package/cli/dist/components/Tooltip.d.ts +0 -12
  109. package/cli/dist/components/Tooltip.d.ts.map +0 -1
  110. package/cli/dist/components/Tooltip.js.map +0 -1
  111. package/cli/dist/components/index.d.ts +0 -8
  112. package/cli/dist/components/index.d.ts.map +0 -1
  113. package/cli/dist/components/index.js.map +0 -1
  114. package/cli/dist/config/platform-standards.d.ts +0 -159
  115. package/cli/dist/config/platform-standards.d.ts.map +0 -1
  116. package/cli/dist/config/platform-standards.js.map +0 -1
  117. package/cli/dist/generator/extension-fetch.d.ts +0 -25
  118. package/cli/dist/generator/extension-fetch.d.ts.map +0 -1
  119. package/cli/dist/generator/extension-fetch.js.map +0 -1
  120. package/cli/dist/generator/template-engine.d.ts +0 -62
  121. package/cli/dist/generator/template-engine.d.ts.map +0 -1
  122. package/cli/dist/generator/template-engine.js.map +0 -1
  123. package/cli/dist/index.d.ts +0 -11
  124. package/cli/dist/index.d.ts.map +0 -1
  125. package/cli/dist/index.js.map +0 -1
  126. package/cli/dist/types/index.d.ts +0 -257
  127. package/cli/dist/types/index.d.ts.map +0 -1
  128. package/cli/dist/types/index.js.map +0 -1
  129. package/cli/dist/utils/cache.d.ts +0 -19
  130. package/cli/dist/utils/cache.d.ts.map +0 -1
  131. package/cli/dist/utils/cache.js.map +0 -1
  132. package/cli/dist/utils/command-helpers.d.ts +0 -17
  133. package/cli/dist/utils/command-helpers.d.ts.map +0 -1
  134. package/cli/dist/utils/command-helpers.js.map +0 -1
  135. package/cli/dist/utils/constants.d.ts +0 -53
  136. package/cli/dist/utils/constants.d.ts.map +0 -1
  137. package/cli/dist/utils/constants.js.map +0 -1
  138. package/cli/dist/utils/discovery-context.d.ts +0 -4
  139. package/cli/dist/utils/discovery-context.d.ts.map +0 -1
  140. package/cli/dist/utils/discovery-context.js.map +0 -1
  141. package/cli/dist/utils/docker.d.ts +0 -4
  142. package/cli/dist/utils/docker.d.ts.map +0 -1
  143. package/cli/dist/utils/docker.js.map +0 -1
  144. package/cli/dist/utils/doctor-runtime.d.ts +0 -81
  145. package/cli/dist/utils/doctor-runtime.d.ts.map +0 -1
  146. package/cli/dist/utils/doctor-runtime.js.map +0 -1
  147. package/cli/dist/utils/env-validator.d.ts +0 -15
  148. package/cli/dist/utils/env-validator.d.ts.map +0 -1
  149. package/cli/dist/utils/env-validator.js.map +0 -1
  150. package/cli/dist/utils/errors.d.ts +0 -31
  151. package/cli/dist/utils/errors.d.ts.map +0 -1
  152. package/cli/dist/utils/errors.js.map +0 -1
  153. package/cli/dist/utils/file-helpers.d.ts +0 -14
  154. package/cli/dist/utils/file-helpers.d.ts.map +0 -1
  155. package/cli/dist/utils/file-helpers.js.map +0 -1
  156. package/cli/dist/utils/formatting.d.ts +0 -30
  157. package/cli/dist/utils/formatting.d.ts.map +0 -1
  158. package/cli/dist/utils/formatting.js.map +0 -1
  159. package/cli/dist/utils/paths.d.ts +0 -3
  160. package/cli/dist/utils/paths.d.ts.map +0 -1
  161. package/cli/dist/utils/paths.js.map +0 -1
  162. package/cli/dist/utils/port-assignment.d.ts +0 -6
  163. package/cli/dist/utils/port-assignment.d.ts.map +0 -1
  164. package/cli/dist/utils/port-assignment.js.map +0 -1
  165. package/cli/dist/utils/project-features.d.ts +0 -23
  166. package/cli/dist/utils/project-features.d.ts.map +0 -1
  167. package/cli/dist/utils/project-features.js.map +0 -1
  168. package/cli/dist/utils/project-templates.d.ts +0 -7
  169. package/cli/dist/utils/project-templates.d.ts.map +0 -1
  170. package/cli/dist/utils/project-templates.js.map +0 -1
  171. package/cli/dist/utils/prompt.d.ts +0 -28
  172. package/cli/dist/utils/prompt.d.ts.map +0 -1
  173. package/cli/dist/utils/prompt.js.map +0 -1
  174. package/cli/dist/utils/resource-features.d.ts +0 -29
  175. package/cli/dist/utils/resource-features.d.ts.map +0 -1
  176. package/cli/dist/utils/resource-features.js.map +0 -1
  177. package/cli/dist/utils/service-urls.d.ts +0 -30
  178. package/cli/dist/utils/service-urls.d.ts.map +0 -1
  179. package/cli/dist/utils/service-urls.js.map +0 -1
  180. package/cli/dist/utils/services.d.ts +0 -18
  181. package/cli/dist/utils/services.d.ts.map +0 -1
  182. package/cli/dist/utils/services.js.map +0 -1
  183. package/cli/dist/utils/stack-features.d.ts +0 -22
  184. package/cli/dist/utils/stack-features.d.ts.map +0 -1
  185. package/cli/dist/utils/stack-features.js.map +0 -1
  186. package/cli/dist/utils/tar.d.ts +0 -7
  187. package/cli/dist/utils/tar.d.ts.map +0 -1
  188. package/cli/dist/utils/tar.js.map +0 -1
  189. package/cli/dist/utils/tilt.d.ts +0 -20
  190. package/cli/dist/utils/tilt.d.ts.map +0 -1
  191. package/cli/dist/utils/tilt.js.map +0 -1
  192. package/cli/dist/utils/validation.d.ts +0 -16
  193. package/cli/dist/utils/validation.d.ts.map +0 -1
  194. package/cli/dist/utils/validation.js.map +0 -1
  195. package/cli/knip.json +0 -6
  196. package/cli/pnpm-lock.yaml +0 -2305
  197. package/cli/pnpm-workspace.yaml +0 -2
  198. package/cli/src/cli.ts +0 -72
  199. package/cli/src/commands/__tests__/always-enabled-infra.test.ts +0 -109
  200. package/cli/src/commands/__tests__/config.test.ts +0 -146
  201. package/cli/src/commands/__tests__/doctor.test.ts +0 -730
  202. package/cli/src/commands/__tests__/error-handling.test.ts +0 -78
  203. package/cli/src/commands/__tests__/phases-model.test.ts +0 -161
  204. package/cli/src/commands/__tests__/project-resource-features-e2e.test.ts +0 -187
  205. package/cli/src/commands/__tests__/project.test.ts +0 -68
  206. package/cli/src/commands/__tests__/resource.test.ts +0 -226
  207. package/cli/src/commands/__tests__/saas-starter-integration.test.ts +0 -194
  208. package/cli/src/commands/__tests__/stack-features-e2e.test.ts +0 -135
  209. package/cli/src/commands/__tests__/upgrade.test.ts +0 -198
  210. package/cli/src/commands/completion.ts +0 -300
  211. package/cli/src/commands/config.ts +0 -299
  212. package/cli/src/commands/doctor.ts +0 -926
  213. package/cli/src/commands/down.ts +0 -37
  214. package/cli/src/commands/help.ts +0 -143
  215. package/cli/src/commands/networks-design.md +0 -80
  216. package/cli/src/commands/networks.ts +0 -332
  217. package/cli/src/commands/project.ts +0 -456
  218. package/cli/src/commands/projects.ts +0 -82
  219. package/cli/src/commands/resource.ts +0 -652
  220. package/cli/src/commands/resources.ts +0 -95
  221. package/cli/src/commands/stack.ts +0 -128
  222. package/cli/src/commands/stacks.ts +0 -52
  223. package/cli/src/commands/status.ts +0 -88
  224. package/cli/src/commands/ui.tsx +0 -843
  225. package/cli/src/commands/up.ts +0 -169
  226. package/cli/src/commands/upgrade.ts +0 -628
  227. package/cli/src/commands/version.ts +0 -9
  228. package/cli/src/components/Accessible.tsx +0 -21
  229. package/cli/src/components/BaseTooltip.tsx +0 -66
  230. package/cli/src/components/DetailPanel.tsx +0 -146
  231. package/cli/src/components/FileTree.tsx +0 -89
  232. package/cli/src/components/ResourceSelectInput.tsx +0 -30
  233. package/cli/src/components/ResourceTable.tsx +0 -78
  234. package/cli/src/components/TabBar.tsx +0 -53
  235. package/cli/src/components/Tooltip.tsx +0 -11
  236. package/cli/src/components/index.ts +0 -7
  237. package/cli/src/config/platform-standards.test.ts +0 -11
  238. package/cli/src/config/platform-standards.ts +0 -196
  239. package/cli/src/generator/__tests__/extension-fetch.test.ts +0 -242
  240. package/cli/src/generator/__tests__/template-engine.test.ts +0 -70
  241. package/cli/src/generator/extension-fetch.ts +0 -286
  242. package/cli/src/generator/template-engine.ts +0 -752
  243. package/cli/src/index.ts +0 -86
  244. package/cli/src/templates.d.ts +0 -4
  245. package/cli/src/types/index.ts +0 -353
  246. package/cli/src/utils/__tests__/cache.test.ts +0 -98
  247. package/cli/src/utils/__tests__/formatting.test.ts +0 -170
  248. package/cli/src/utils/__tests__/paths.test.ts +0 -180
  249. package/cli/src/utils/__tests__/port-assignment.test.ts +0 -121
  250. package/cli/src/utils/__tests__/service-urls.test.ts +0 -174
  251. package/cli/src/utils/__tests__/services.test.ts +0 -531
  252. package/cli/src/utils/__tests__/tilt.test.ts +0 -172
  253. package/cli/src/utils/__tests__/validation.test.ts +0 -148
  254. package/cli/src/utils/cache.ts +0 -76
  255. package/cli/src/utils/command-helpers.ts +0 -54
  256. package/cli/src/utils/constants.ts +0 -130
  257. package/cli/src/utils/discovery-context.ts +0 -49
  258. package/cli/src/utils/docker.ts +0 -20
  259. package/cli/src/utils/doctor-runtime.ts +0 -644
  260. package/cli/src/utils/env-validator.ts +0 -139
  261. package/cli/src/utils/errors.ts +0 -168
  262. package/cli/src/utils/file-helpers.ts +0 -62
  263. package/cli/src/utils/formatting.ts +0 -215
  264. package/cli/src/utils/paths.ts +0 -53
  265. package/cli/src/utils/port-assignment.ts +0 -106
  266. package/cli/src/utils/project-features.ts +0 -118
  267. package/cli/src/utils/project-templates.ts +0 -29
  268. package/cli/src/utils/prompt.ts +0 -128
  269. package/cli/src/utils/resource-features.ts +0 -215
  270. package/cli/src/utils/service-urls.ts +0 -124
  271. package/cli/src/utils/services.ts +0 -364
  272. package/cli/src/utils/stack-features.ts +0 -30
  273. package/cli/src/utils/tar.ts +0 -24
  274. package/cli/src/utils/tilt.ts +0 -133
  275. package/cli/src/utils/validation.ts +0 -67
  276. package/cli/tsconfig.json +0 -25
  277. package/cli/tsconfig.typecheck.json +0 -8
  278. package/docs/FEATURES.md +0 -279
  279. package/docs/demo.svg +0 -217
  280. package/engine/docs/AUTODISCOVERY_TEST.md +0 -182
  281. package/engine/docs/C4-ARCHITECTURE-operations.md +0 -396
  282. package/engine/docs/C4-ARCHITECTURE-overview.md +0 -284
  283. package/engine/docs/C4-ARCHITECTURE.md +0 -17
  284. package/engine/docs/GOLDEN_IMAGE_INTEGRATION.md +0 -349
  285. package/engine/docs/MANIFEST_DRIVEN_ARCHITECTURE.md +0 -357
  286. package/engine/docs/README.md +0 -284
  287. package/install.sh +0 -19
  288. package/knip.json +0 -10
  289. package/openspec/changes/add-vscode-tdk-troubleshooter-plugin/.openspec.yaml +0 -2
  290. package/openspec/changes/add-vscode-tdk-troubleshooter-plugin/design.md +0 -102
  291. package/openspec/changes/add-vscode-tdk-troubleshooter-plugin/proposal.md +0 -31
  292. package/openspec/changes/add-vscode-tdk-troubleshooter-plugin/specs/vscode-tdk-notifications/spec.md +0 -48
  293. package/openspec/changes/add-vscode-tdk-troubleshooter-plugin/specs/vscode-tdk-orchestration/spec.md +0 -63
  294. package/openspec/changes/add-vscode-tdk-troubleshooter-plugin/specs/vscode-tdk-troubleshooting/spec.md +0 -56
  295. package/openspec/changes/add-vscode-tdk-troubleshooter-plugin/tasks.md +0 -61
  296. package/openspec/changes/archive/2026-04-28-rename-domain-to-stack-service-to-resource/.openspec.yaml +0 -2
  297. package/openspec/changes/archive/2026-04-28-rename-domain-to-stack-service-to-resource/design.md +0 -114
  298. package/openspec/changes/archive/2026-04-28-rename-domain-to-stack-service-to-resource/proposal.md +0 -32
  299. package/openspec/changes/archive/2026-04-28-rename-domain-to-stack-service-to-resource/specs/manifest-field-migration/spec.md +0 -20
  300. package/openspec/changes/archive/2026-04-28-rename-domain-to-stack-service-to-resource/specs/resource-terminology-standard/spec.md +0 -20
  301. package/openspec/changes/archive/2026-04-28-rename-domain-to-stack-service-to-resource/specs/stack-terminology-standard/spec.md +0 -20
  302. package/openspec/changes/archive/2026-04-28-rename-domain-to-stack-service-to-resource/tasks.md +0 -194
  303. package/openspec/changes/archive/2026-04-28-star-files-parameter-fixes/.openspec.yaml +0 -2
  304. package/openspec/changes/archive/2026-04-28-star-files-parameter-fixes/design.md +0 -111
  305. package/openspec/changes/archive/2026-04-28-star-files-parameter-fixes/proposal.md +0 -33
  306. package/openspec/changes/archive/2026-04-28-star-files-parameter-fixes/specs/function-naming-alignment/spec.md +0 -12
  307. package/openspec/changes/archive/2026-04-28-star-files-parameter-fixes/specs/optional-parameter-patterns/spec.md +0 -18
  308. package/openspec/changes/archive/2026-04-28-star-files-parameter-fixes/specs/parameter-documentation/spec.md +0 -16
  309. package/openspec/changes/archive/2026-04-28-star-files-parameter-fixes/specs/parameter-naming-consistency/spec.md +0 -12
  310. package/openspec/changes/archive/2026-04-28-star-files-parameter-fixes/specs/parameter-ordering-standard/spec.md +0 -12
  311. package/openspec/changes/archive/2026-04-28-star-files-parameter-fixes/tasks.md +0 -194
  312. package/openspec/changes/archive/2026-04-29-scan-repo-gaps-fix/.openspec.yaml +0 -2
  313. package/openspec/changes/archive/2026-04-29-scan-repo-gaps-fix/design.md +0 -84
  314. package/openspec/changes/archive/2026-04-29-scan-repo-gaps-fix/proposal.md +0 -31
  315. package/openspec/changes/archive/2026-04-29-scan-repo-gaps-fix/specs/codebase-audit/spec.md +0 -27
  316. package/openspec/changes/archive/2026-04-29-scan-repo-gaps-fix/specs/dead-code-cleanup/spec.md +0 -27
  317. package/openspec/changes/archive/2026-04-29-scan-repo-gaps-fix/specs/test-gap-fill/spec.md +0 -23
  318. package/openspec/changes/archive/2026-04-29-scan-repo-gaps-fix/specs/todo-resolution/spec.md +0 -27
  319. package/openspec/changes/archive/2026-04-29-scan-repo-gaps-fix/tasks.md +0 -39
  320. package/openspec/changes/archive/2026-06-25-landscape-consolidation/.openspec.yaml +0 -2
  321. package/openspec/changes/archive/2026-06-25-landscape-consolidation/design.md +0 -80
  322. package/openspec/changes/archive/2026-06-25-landscape-consolidation/proposal.md +0 -40
  323. package/openspec/changes/archive/2026-06-25-landscape-consolidation/spec.md +0 -52
  324. package/openspec/changes/archive/2026-06-25-landscape-consolidation/tasks.md +0 -51
  325. package/openspec/changes/archive/2026-09-17-fix-generated-stack-boot/.openspec.yaml +0 -2
  326. package/openspec/changes/archive/2026-09-17-fix-generated-stack-boot/design.md +0 -43
  327. package/openspec/changes/archive/2026-09-17-fix-generated-stack-boot/proposal.md +0 -29
  328. package/openspec/changes/archive/2026-09-17-fix-generated-stack-boot/specs/self-contained-generated-projects/spec.md +0 -67
  329. package/openspec/changes/archive/2026-09-17-fix-generated-stack-boot/tasks.md +0 -27
  330. package/openspec/changes/optimize-runtime-docker-layers/.openspec.yaml +0 -3
  331. package/openspec/changes/optimize-runtime-docker-layers/design.md +0 -81
  332. package/openspec/changes/optimize-runtime-docker-layers/proposal.md +0 -44
  333. package/openspec/changes/optimize-runtime-docker-layers/specs/runtime-container-footprint/spec.md +0 -79
  334. package/openspec/changes/optimize-runtime-docker-layers/tasks.md +0 -36
  335. package/openspec/changes/prioritized-cold-start/.openspec.yaml +0 -4
  336. package/openspec/changes/prioritized-cold-start/design.md +0 -137
  337. package/openspec/changes/prioritized-cold-start/proposal.md +0 -41
  338. package/openspec/changes/prioritized-cold-start/specs/on-demand-resource-startup/spec.md +0 -98
  339. package/openspec/changes/prioritized-cold-start/tasks.md +0 -69
  340. package/openspec/config.yaml +0 -1
  341. package/openspec/specs/manifest-field-migration/spec.md +0 -24
  342. package/openspec/specs/resource-terminology-standard/spec.md +0 -24
  343. package/openspec/specs/self-contained-generated-projects/spec.md +0 -67
  344. package/openspec/specs/stack-terminology-standard/spec.md +0 -24
  345. package/platform/services/platform/proxy/service.yaml +0 -14
  346. package/scripts/audit-codebase.sh +0 -213
  347. package/scripts/autoresearch/layer-eval.sh +0 -65
  348. package/scripts/benchmark/README.md +0 -25
  349. package/scripts/benchmark/container-scale.ts +0 -503
  350. package/scripts/benchmark/pre-release-gate.sh +0 -9
  351. package/scripts/install-git-hooks.sh +0 -14
  352. package/scripts/measure-idle-footprint.sh +0 -58
  353. package/scripts/record-demo.sh +0 -43
  354. package/scripts/release-binaries.sh +0 -97
  355. package/scripts/setup-pre-commit.sh +0 -33
  356. package/scripts/stage-npm-engine.sh +0 -36
  357. package/tests/tilt-engine/__init__.py +0 -5
  358. package/tests/tilt-engine/conftest.py +0 -182
  359. package/tests/tilt-engine/fixtures/appointment-frontend-service.json +0 -11
  360. package/tests/tilt-engine/fixtures/identity-backend-service.json +0 -12
  361. package/tests/tilt-engine/fixtures/invalid-service.json +0 -4
  362. package/tests/tilt-engine/test_agents_md_generator.py +0 -341
  363. package/tests/tilt-engine/test_agents_md_integration.py +0 -378
  364. package/tests/tilt-engine/test_cache_operations.py +0 -181
  365. package/tests/tilt-engine/test_cache_persistence.py +0 -142
  366. package/tests/tilt-engine/test_code_executor.py +0 -152
  367. package/tests/tilt-engine/test_code_viewer.py +0 -127
  368. package/tests/tilt-engine/test_compose_port_anchors.py +0 -310
  369. package/tests/tilt-engine/test_config_inspector.py +0 -162
  370. package/tests/tilt-engine/test_daemon_focus_mode.py +0 -89
  371. package/tests/tilt-engine/test_daemon_polling.py +0 -122
  372. package/tests/tilt-engine/test_daemon_registration.py +0 -115
  373. package/tests/tilt-engine/test_daemon_validation.py +0 -107
  374. package/tests/tilt-engine/test_docker_generator_bugs.py +0 -493
  375. package/tests/tilt-engine/test_docker_prune.py +0 -119
  376. package/tests/tilt-engine/test_dockerignore_path_bug.py +0 -82
  377. package/tests/tilt-engine/test_file_browser.py +0 -193
  378. package/tests/tilt-engine/test_frontend_basepath_manifest.py +0 -27
  379. package/tests/tilt-engine/test_health_dependencies.py +0 -130
  380. package/tests/tilt-engine/test_health_endpoints.py +0 -118
  381. package/tests/tilt-engine/test_health_tilt_ui.py +0 -85
  382. package/tests/tilt-engine/test_runtime_container_footprint.py +0 -162
  383. package/tests/tilt-engine/test_sablier_defer_start.py +0 -237
  384. package/tests/tilt-engine/test_safety_aliases.py +0 -84
  385. package/tests/tilt-engine/test_snapshot_diff.py +0 -136
  386. package/tests/tilt-engine/test_snapshot_persistence.py +0 -163
  387. package/tests/tilt-engine/test_snapshot_scanning.py +0 -123
  388. package/tests/tilt-engine/test_standalone_project_boot.py +0 -61
  389. package/tests/tilt-engine/test_standalone_traefik.py +0 -160
  390. 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
- }