@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,162 +0,0 @@
1
- """
2
- Runtime container footprint: single Bun process, cheap healthchecks, lean golden images.
3
-
4
- Executes the real Starlark generators through Tilt's interpreter
5
- (`tilt alpha tiltfile-result`) instead of inspecting source text.
6
- Spec: openspec/changes/optimize-runtime-docker-layers/specs/runtime-container-footprint/spec.md
7
- """
8
-
9
- from __future__ import annotations
10
-
11
- import json
12
- import os
13
- import shutil
14
- import subprocess
15
- from pathlib import Path
16
-
17
- import pytest
18
-
19
- pytestmark = [
20
- pytest.mark.generator,
21
- pytest.mark.skipif(shutil.which("tilt") is None, reason="tilt CLI not installed"),
22
- ]
23
-
24
- DOCKER_DIR = Path(__file__).resolve().parents[2] / "engine" / "topologies" / "platform" / "docker"
25
- RESULT_MARKER = "Error in fail: RESULT"
26
-
27
-
28
- def run_starlark(tmp_path: Path, body: str, env: dict | None = None) -> dict:
29
- """Run `body` in a Tiltfile; `body` must assign a dict to `r`. `@DOCKER` is the engine docker dir."""
30
- tiltfile = tmp_path / "Tiltfile"
31
- tiltfile.write_text(
32
- f"HERE = '{tmp_path}'\n"
33
- + body.replace("@DOCKER", str(DOCKER_DIR))
34
- + "\nfail('RESULT' + encode_json(r))\n"
35
- )
36
- proc = subprocess.run(
37
- ["tilt", "alpha", "tiltfile-result", "-f", str(tiltfile)],
38
- capture_output=True,
39
- text=True,
40
- env={**os.environ, **(env or {})},
41
- timeout=180,
42
- )
43
- output = proc.stdout + proc.stderr
44
- assert RESULT_MARKER in output, output[-3000:]
45
- return json.loads(output.split(RESULT_MARKER, 1)[1].strip())
46
-
47
-
48
- def write_service(tmp_path: Path, name: str, start_script: str | None) -> None:
49
- service_dir = tmp_path / name
50
- service_dir.mkdir()
51
- scripts = {} if start_script is None else {"start": start_script}
52
- (service_dir / "package.json").write_text(json.dumps({"name": name, "scripts": scripts}))
53
-
54
-
55
- def cmd_lines(dockerfile: str) -> list[str]:
56
- return [line for line in dockerfile.splitlines() if line.startswith("CMD ")]
57
-
58
-
59
- def healthcheck_lines(dockerfile: str) -> list[str]:
60
- return [line for line in dockerfile.splitlines() if line.startswith("HEALTHCHECK")]
61
-
62
-
63
- @pytest.mark.parametrize(
64
- ("start_script", "expected_cmd"),
65
- [
66
- ("bun run dist/index.js", 'CMD ["bun", "dist/index.js"]'),
67
- ("bun dist/index.js", 'CMD ["bun", "dist/index.js"]'),
68
- ("bun run dist/index.js --port 4000", 'CMD ["bun", "run", "start"]'),
69
- ("NODE_ENV=x bun run dist/index.js", 'CMD ["bun", "run", "start"]'),
70
- ("tsc && bun dist/index.js", 'CMD ["bun", "run", "start"]'),
71
- ("bun run serve", 'CMD ["bun", "run", "start"]'),
72
- (None, 'CMD ["bun", "run", "start"]'),
73
- ],
74
- )
75
- def test_backend_cmd_follows_start_script(tmp_path, start_script, expected_cmd):
76
- write_service(tmp_path, "svc", start_script)
77
- r = run_starlark(
78
- tmp_path,
79
- "load('@DOCKER/layers/l4_runtime_layers.star', 'L4_generate_backend_runtime')\n"
80
- "r = {\n"
81
- " 'plain': L4_generate_backend_runtime(HERE + '/svc'),\n"
82
- " 'infisical': L4_generate_backend_runtime(HERE + '/svc', use_infisical=True, resource_name='svc'),\n"
83
- "}\n",
84
- )
85
- assert cmd_lines(r["plain"]) == [expected_cmd]
86
- assert cmd_lines(r["infisical"]) == [expected_cmd]
87
- assert 'ENTRYPOINT ["/entrypoint.sh"]' in r["infisical"]
88
-
89
-
90
- def test_explicit_cmd_override_is_kept(tmp_path):
91
- write_service(tmp_path, "svc", "bun run dist/index.js")
92
- r = run_starlark(
93
- tmp_path,
94
- "load('@DOCKER/layers/l4_runtime_layers.star', 'L4_generate_backend_runtime')\n"
95
- "r = {'df': L4_generate_backend_runtime(HERE + '/svc', cmd='bun run start:prod')}\n",
96
- )
97
- assert cmd_lines(r["df"]) == ['CMD ["bun", "run", "start:prod"]']
98
-
99
-
100
- def test_hugo_installed_only_for_services_declaring_it(tmp_path):
101
- write_service(tmp_path, "svc", "bun run dist/index.js")
102
- r = run_starlark(
103
- tmp_path,
104
- "load('@DOCKER/layers/l4_runtime_layers.star', 'L4_generate_backend_runtime')\n"
105
- "r = {\n"
106
- " 'with': L4_generate_backend_runtime(HERE + '/svc', manifest={'featuresEnabled': ['hugo']}),\n"
107
- " 'without': L4_generate_backend_runtime(HERE + '/svc', manifest={'featuresEnabled': []}),\n"
108
- "}\n",
109
- )
110
- assert "apk add --no-cache hugo" in r["with"]
111
- assert "apk add --no-cache hugo" not in r["without"]
112
-
113
-
114
- def test_golden_dockerfile_is_lean_and_uses_shared_healthcheck(tmp_path):
115
- r = run_starlark(
116
- tmp_path,
117
- "load('@DOCKER/build/golden_image_dockerfile.star', 'generate_golden_dockerfile')\n"
118
- "r = {'df': generate_golden_dockerfile()}\n",
119
- )
120
- df = r["df"]
121
- backend_bun_stage = df.split("AS l4_backend_bun", 1)[1].split("\nFROM ", 1)[0]
122
- migrator_stage = df.split("AS l4_migrator_golden", 1)[1].split("\nFROM ", 1)[0]
123
-
124
- assert "apk add --no-cache hugo" not in backend_bun_stage
125
- assert "HEALTHCHECK NONE" in migrator_stage
126
-
127
- checks = healthcheck_lines(df)
128
- assert checks, "golden Dockerfile has no HEALTHCHECK instructions"
129
- for line in checks:
130
- assert "bunx" not in line and "npx" not in line, line
131
- if line != "HEALTHCHECK NONE":
132
- assert "--interval=30s --start-interval=2s" in line, line
133
-
134
-
135
- def test_compose_entries_use_init_and_shared_healthcheck(tmp_path):
136
- r = run_starlark(
137
- tmp_path,
138
- "load('@DOCKER/compose/compose.star', 'generate_backend_compose_entry', 'generate_frontend_compose')\n"
139
- "r = {\n"
140
- " 'backend': generate_backend_compose_entry('services/finance', 'finance', {'name': 'cash-api'},"
141
- " {'stack': 'finance', 'port': 4018, 'appType': 'backend'}),\n"
142
- " 'frontend': generate_frontend_compose('services/finance', 'finance', {'name': 'dash-app'},"
143
- " {'stack': 'finance', 'port': 3010, 'appType': 'frontend'}),\n"
144
- "}\n",
145
- )
146
- for kind in ("backend", "frontend"):
147
- entry = r[kind]
148
- assert "init: true" in entry, kind
149
- assert "interval: 30s" in entry, kind
150
- assert "start_interval: 2s" in entry, kind
151
- assert "interval: 10s" not in entry, kind
152
-
153
-
154
- def test_healthcheck_interval_is_configurable(tmp_path):
155
- r = run_starlark(
156
- tmp_path,
157
- "load('@DOCKER/config/healthcheck.star', 'dockerfile_healthcheck_flags', 'compose_healthcheck_timing')\n"
158
- "r = {'flags': dockerfile_healthcheck_flags(), 'timing': compose_healthcheck_timing()}\n",
159
- env={"TDK_HEALTHCHECK_INTERVAL_SECONDS": "15"},
160
- )
161
- assert "--interval=15s" in r["flags"]
162
- assert "interval: 15s" in r["timing"]
@@ -1,237 +0,0 @@
1
- """
2
- sablier.deferStart: schema field and its enable-required cross-field rule.
3
-
4
- Executes the real Starlark validator through Tilt's interpreter
5
- (`tilt alpha tiltfile-result`) instead of inspecting source text.
6
- Spec: openspec/changes/prioritized-cold-start/specs/on-demand-resource-startup/spec.md
7
- """
8
-
9
- from __future__ import annotations
10
-
11
- import json
12
- import os
13
- import shutil
14
- import subprocess
15
- from pathlib import Path
16
-
17
- import pytest
18
-
19
- pytestmark = [
20
- pytest.mark.generator,
21
- pytest.mark.skipif(shutil.which("tilt") is None, reason="tilt CLI not installed"),
22
- ]
23
-
24
- MANIFEST_DIR = Path(__file__).resolve().parents[2] / "engine" / "topologies" / "tilt" / "manifest"
25
- ORCHESTRATOR_DIR = Path(__file__).resolve().parents[2] / "engine" / "topologies" / "tilt" / "resources" / "orchestrator"
26
- RESULT_MARKER = "Error in fail: RESULT"
27
-
28
-
29
- def run_starlark(tmp_path: Path, body: str) -> dict:
30
- """Run `body` in a Tiltfile; `body` must assign a dict to `r`. `@MANIFEST`/`@ORCHESTRATOR` are module dirs."""
31
- tiltfile = tmp_path / "Tiltfile"
32
- tiltfile.write_text(
33
- body.replace("@MANIFEST", str(MANIFEST_DIR)).replace("@ORCHESTRATOR", str(ORCHESTRATOR_DIR))
34
- + "\nfail('RESULT' + encode_json(r))\n"
35
- )
36
- proc = subprocess.run(
37
- ["tilt", "alpha", "tiltfile-result", "-f", str(tiltfile)],
38
- capture_output=True,
39
- text=True,
40
- timeout=180,
41
- )
42
- output = proc.stdout + proc.stderr
43
- assert RESULT_MARKER in output, output[-3000:]
44
- return json.loads(output.split(RESULT_MARKER, 1)[1].strip())
45
-
46
-
47
- def validate_sablier(tmp_path: Path, sablier: dict | None) -> dict:
48
- manifest = {"appType": "backend", "stack": "test"}
49
- if sablier is not None:
50
- manifest["sablier"] = sablier
51
- return run_starlark(
52
- tmp_path,
53
- "load('@MANIFEST/validator.star', 'ManifestValidator')\n"
54
- f"manifest = {manifest!r}\n"
55
- "result = ManifestValidator.validate(manifest, level='cross_field')\n"
56
- "r = {'valid': result.valid, 'errors': [e.message for e in result.errors]}\n",
57
- )
58
-
59
-
60
- @pytest.mark.parametrize(
61
- "sablier",
62
- [
63
- None,
64
- {"enable": False},
65
- {"enable": True},
66
- {"enable": True, "deferStart": True},
67
- {"enable": True, "deferStart": False},
68
- ],
69
- )
70
- def test_defer_start_with_enable_is_valid(tmp_path, sablier):
71
- r = validate_sablier(tmp_path, sablier)
72
- assert r["valid"], r["errors"]
73
-
74
-
75
- def test_defer_start_without_enable_is_rejected(tmp_path):
76
- r = validate_sablier(tmp_path, {"deferStart": True})
77
- assert not r["valid"]
78
- assert any("deferStart" in e and "enable" in e for e in r["errors"]), r["errors"]
79
-
80
-
81
- def test_defer_start_with_enable_false_is_rejected(tmp_path):
82
- r = validate_sablier(tmp_path, {"enable": False, "deferStart": True})
83
- assert not r["valid"]
84
- assert any("deferStart" in e and "enable" in e for e in r["errors"]), r["errors"]
85
-
86
-
87
- def resource_defers_start(tmp_path: Path, sablier: dict | None) -> bool:
88
- manifest = {"appType": "backend", "stack": "test"}
89
- if sablier is not None:
90
- manifest["sablier"] = sablier
91
- result = run_starlark(
92
- tmp_path,
93
- "load('@ORCHESTRATOR/apply_compose_resource_registration.star', 'resource_defers_start')\n"
94
- f"manifest = {manifest!r}\n"
95
- "r = {'defers': resource_defers_start(manifest)}\n",
96
- )
97
- return result["defers"]
98
-
99
-
100
- @pytest.mark.parametrize(
101
- "sablier",
102
- [
103
- None,
104
- {},
105
- {"enable": False},
106
- {"enable": True},
107
- {"enable": False, "deferStart": True},
108
- {"enable": True, "deferStart": False},
109
- {"enable": True, "deferStart": True},
110
- ],
111
- )
112
- def test_resource_defers_start_stays_off_without_a_license(tmp_path, sablier):
113
- """deferStart stays behind the same TDK_LICENSE_KEY gate as the rest of
114
- `sablier` (an explicit product decision -- see openspec/changes/
115
- prioritized-cold-start's design.md). This repo ships only the free-tier
116
- `sablier_container_cycle.star` stub, whose sablier_middleware_suffix()
117
- always reports disabled regardless of the manifest -- so every case here
118
- must resolve to False, including {"enable": True, "deferStart": True}.
119
- The corresponding "licensed and enabled" True case can only be exercised
120
- where the real premium module is actually vendored (tdk-cli-extensions),
121
- not from this repo's stub."""
122
- assert resource_defers_start(tmp_path, sablier) is False
123
-
124
-
125
- def _run_resolve_deps(tmp_path: Path, manifest: dict, resource_manifests: dict, all_services_map: dict) -> list:
126
- result = run_starlark(
127
- tmp_path,
128
- "load('@ORCHESTRATOR/apply_compose_resource_registration.star', 'resolve_defer_start_dependencies')\n"
129
- f"manifest = {manifest!r}\n"
130
- f"resource_manifests = {resource_manifests!r}\n"
131
- f"all_services_map = {all_services_map!r}\n"
132
- "r = {'deps': [list(pair) for pair in resolve_defer_start_dependencies(manifest, resource_manifests, all_services_map)]}\n",
133
- )
134
- return result["deps"]
135
-
136
-
137
- LICENSED_SABLIER_MANIFEST = {"appType": "backend", "stack": "test", "sablier": {"enable": True, "deferStart": True}}
138
-
139
-
140
- def test_resolve_defer_start_dependencies_excludes_non_defer_dependency(tmp_path):
141
- """A dependsOn entry that resolves to a real resource with no sablier.deferStart
142
- (e.g. always-on infra, or a normal backend) contributes nothing to X-Wake-Deps."""
143
- manifest = {"appType": "backend", "stack": "test", "dependsOn": ["plain-backend"]}
144
- resource_manifests = {"plain-backend": {"appType": "backend", "stack": "other"}}
145
- all_services_map = {"plain-backend": {"name": "other-service", "resources": [{"name": "plain-backend"}]}}
146
- assert _run_resolve_deps(tmp_path, manifest, resource_manifests, all_services_map) == []
147
-
148
-
149
- def test_resolve_defer_start_dependencies_excludes_unresolvable_name(tmp_path):
150
- """A dependsOn short name that doesn't match any known resource/service falls
151
- back (via _resolve_dependency_to_resource) to a name absent from
152
- resource_manifests, so it's quietly excluded rather than guessed at (D5)."""
153
- manifest = {"appType": "backend", "stack": "test", "dependsOn": ["nonexistent-thing"]}
154
- assert _run_resolve_deps(tmp_path, manifest, {}, {}) == []
155
-
156
-
157
- def test_resolve_defer_start_dependencies_stays_empty_without_a_license(tmp_path):
158
- """Even when a dependsOn entry resolves to a resource whose manifest asks for
159
- sablier.deferStart, this repo's free-tier stub keeps resource_defers_start()
160
- False for it too (same license gate as the resource's own deferStart check),
161
- so it's excluded here just as it would be for the resource itself."""
162
- manifest = {"appType": "backend", "stack": "test", "dependsOn": ["peer-backend"]}
163
- resource_manifests = {"peer-backend": LICENSED_SABLIER_MANIFEST}
164
- all_services_map = {"peer-backend": {"name": "peer-service", "resources": [{"name": "peer-backend"}]}}
165
- assert _run_resolve_deps(tmp_path, manifest, resource_manifests, all_services_map) == []
166
-
167
-
168
- def test_resolve_defer_start_dependencies_no_depends_on(tmp_path):
169
- manifest = {"appType": "backend", "stack": "test"}
170
- assert _run_resolve_deps(tmp_path, manifest, {}, {}) == []
171
-
172
-
173
- def _run_resolve_names(tmp_path: Path, manifest: dict, all_services_map: dict) -> list:
174
- result = run_starlark(
175
- tmp_path,
176
- "load('@ORCHESTRATOR/apply_compose_resource_registration.star', 'resolve_manifest_dependency_names')\n"
177
- f"manifest = {manifest!r}\n"
178
- f"all_services_map = {all_services_map!r}\n"
179
- "r = {'names': resolve_manifest_dependency_names(manifest, all_services_map)}\n",
180
- )
181
- return result["names"]
182
-
183
-
184
- def test_resolve_manifest_dependency_names_exact_match(tmp_path):
185
- """The common case: dependsOn already names a real resource exactly, so
186
- _resolve_dependency_to_resource returns it unchanged (no '-yaml' guess)."""
187
- manifest = {"dependsOn": ["identity-management-backend"]}
188
- all_services_map = {
189
- "identity-management-backend": {"name": "identity-management", "resources": [{"name": "identity-management-backend"}]},
190
- }
191
- assert _run_resolve_names(tmp_path, manifest, all_services_map) == ["identity-management-backend"]
192
-
193
-
194
- def test_prebuild_dockerignore_mirrors_docker_build_only_and_ignore(tmp_path):
195
- """A deferStart resource's image is pre-built by a plain `docker build`
196
- (auto_init=False skips the dc_resource's own docker_build -- found live,
197
- task 7.2). A plain build has no only= filter, so the generated allowlist
198
- must include exactly what docker_build's only= does (root lockfiles, the
199
- service, docker-templates, its internal libraries) and re-exclude its
200
- ignore= patterns, or the whole project root becomes the build context."""
201
- project = tmp_path / "project"
202
- service = project / "services" / "analytics" / "data-governance-api"
203
- (service / ".autogenerated").mkdir(parents=True)
204
- (service / "package.json").write_text(
205
- json.dumps({"dependencies": {"@tdk-project/platform-logging": "workspace:*", "zod": "^3"}})
206
- )
207
- dockerfile = service / ".autogenerated" / "Dockerfile.app.autogenerated"
208
- dockerfile.write_text("FROM scratch\n")
209
- (service / ".autogenerated" / "Dockerfile.app.autogenerated.dockerignore").write_text(
210
- "# comment\nnode_modules\n*.md\n!.env.example\n"
211
- )
212
- tiltdir = tmp_path / "tilt"
213
- tiltdir.mkdir()
214
- r = run_starlark(
215
- tiltdir,
216
- "load('@ORCHESTRATOR/builders/typescript.star', 'prebuild_dockerignore')\n"
217
- f"r = {{'content': prebuild_dockerignore({str(dockerfile)!r}, {str(project)!r}, "
218
- "'services/analytics/data-governance-api')}\n",
219
- )
220
- lines = r["content"].splitlines()
221
- res = "services/analytics/data-governance-api"
222
- assert lines[0] == "*"
223
- for allowed in ["package.json", "bun.lock", res, "shared-platform-engineering/docker-templates",
224
- "shared-platform-engineering/platform-logging"]:
225
- assert "!" + allowed in lines, (allowed, lines)
226
- # Only the service's own relative path is allowed, never the absolute one.
227
- assert not any(line.startswith("!" + str(project)) for line in lines), lines
228
- # Re-excludes come after the allowlist (dockerignore: later lines win).
229
- assert res + "/node_modules" in lines and res + "/*.md" in lines
230
- assert lines.index(res + "/node_modules") > lines.index("!" + res)
231
- # The Dockerfile's own negations aren't carried over (same as docker_build's ignore=).
232
- assert not any(".env.example" in line for line in lines)
233
-
234
-
235
- def test_resolve_manifest_dependency_names_dedupes_and_skips_empty(tmp_path):
236
- manifest = {"dependsOn": []}
237
- assert _run_resolve_names(tmp_path, manifest, {}) == []
@@ -1,84 +0,0 @@
1
- """
2
- Tests for safety shell aliases.
3
- Tests the alias configuration and functionality.
4
- """
5
-
6
- import pytest
7
-
8
-
9
- @pytest.mark.safety
10
- class TestSafetyAliases:
11
- """Tests for safety alias functionality."""
12
-
13
- def test_safe_prune_alias_works(self):
14
- """
15
- Scenario: Safe prune alias works
16
- WHEN a user runs `docker-prune-safe` after sourcing aliases
17
- THEN it SHALL execute `safe-docker-prune.sh standard`
18
- """
19
- alias_mapping = {
20
- "docker-prune-safe": "./scripts/safe-docker-prune.sh standard",
21
- }
22
-
23
- assert "docker-prune-safe" in alias_mapping
24
- assert "safe-docker-prune.sh" in alias_mapping["docker-prune-safe"]
25
- assert "standard" in alias_mapping["docker-prune-safe"]
26
-
27
- def test_full_prune_alias_works(self):
28
- """
29
- Scenario: Full prune alias works
30
- WHEN a user runs `docker-prune-full` after sourcing aliases
31
- THEN it SHALL execute `safe-docker-prune.sh full`
32
- """
33
- alias_mapping = {
34
- "docker-prune-full": "./scripts/safe-docker-prune.sh full",
35
- }
36
-
37
- assert "docker-prune-full" in alias_mapping
38
- assert "safe-docker-prune.sh" in alias_mapping["docker-prune-full"]
39
- assert "full" in alias_mapping["docker-prune-full"]
40
-
41
- def test_alias_is_idempotent(self):
42
- """
43
- Scenario: Alias is idempotent
44
- WHEN a user sources the aliases file multiple times
45
- THEN the aliases SHALL remain functional
46
- AND no duplicate definitions SHALL cause errors
47
- """
48
- # Simulate sourcing aliases multiple times
49
- aliases = {}
50
-
51
- # First source
52
- aliases["docker-prune-safe"] = "./scripts/safe-docker-prune.sh standard"
53
-
54
- # Second source (should overwrite, not duplicate)
55
- aliases["docker-prune-safe"] = "./scripts/safe-docker-prune.sh standard"
56
-
57
- # Third source
58
- aliases["docker-prune-safe"] = "./scripts/safe-docker-prune.sh standard"
59
-
60
- # Should still work correctly
61
- assert len(aliases) == 1
62
- assert aliases["docker-prune-safe"] == "./scripts/safe-docker-prune.sh standard"
63
-
64
- def test_protected_volumes_alias_exists(self):
65
- """Test that docker-protected-volumes alias exists."""
66
- alias_mapping = {
67
- "docker-protected-volumes": "docker volume ls | grep -E '(verdaccio|infisical)'",
68
- }
69
-
70
- assert "docker-protected-volumes" in alias_mapping
71
- assert "verdaccio" in alias_mapping["docker-protected-volumes"]
72
- assert "infisical" in alias_mapping["docker-protected-volumes"]
73
-
74
- def test_alias_commands_are_safe(self):
75
- """Test that aliased commands don't use --volumes with prune."""
76
- alias_commands = [
77
- "./scripts/safe-docker-prune.sh standard",
78
- "./scripts/safe-docker-prune.sh full",
79
- ]
80
-
81
- for cmd in alias_commands:
82
- # Safe commands should use the script, not direct docker prune
83
- assert "safe-docker-prune.sh" in cmd, "Should use safe script"
84
- assert "docker system prune" not in cmd or "--volumes" not in cmd, "Should not use dangerous direct prune"
@@ -1,136 +0,0 @@
1
- """
2
- Tests for snapshot diff detection functionality.
3
- Tests the comparison between old and new snapshots.
4
- """
5
-
6
- import pytest
7
- from pathlib import Path
8
- import sys
9
-
10
- sys.path.insert(0, str(Path("discovery").resolve()))
11
- from resource_snapshot import diff_snapshots
12
-
13
-
14
- @pytest.mark.snapshot
15
- class TestSnapshotDiff:
16
- """Tests for snapshot diff detection."""
17
-
18
- def test_detects_new_services(self):
19
- """
20
- Scenario: Detecting new services
21
- WHEN a new service.json file appears in a previously empty directory
22
- THEN the diff SHALL report "added" with the new service path and metadata
23
- """
24
- old = {"services": [], "count": 0}
25
- new = ["services/product/new/service.json"]
26
-
27
- added, removed, modified = diff_snapshots(old, new)
28
-
29
- assert added == {"services/product/new/service.json"}
30
- assert removed == set()
31
- assert modified == set()
32
-
33
- def test_detects_removed_services(self):
34
- """
35
- Scenario: Detecting removed services
36
- WHEN an existing service.json file is deleted
37
- THEN the diff SHALL report "removed" with the removed service path
38
- """
39
- old = {"services": ["services/product/old/service.json"], "count": 1}
40
- new = []
41
-
42
- added, removed, modified = diff_snapshots(old, new)
43
-
44
- assert added == set()
45
- assert removed == {"services/product/old/service.json"}
46
- assert modified == set()
47
-
48
- def test_detects_modified_services(self, temp_dir):
49
- """
50
- Scenario: Detecting modified services
51
- WHEN an existing service.json file changes its content (hash differs)
52
- THEN the diff SHALL report "modified" with the field changes and service path
53
- """
54
- import os
55
- original_dir = os.getcwd()
56
-
57
- try:
58
- os.chdir(temp_dir)
59
-
60
- # Create a service file
61
- resource_dir = temp_dir / "services" / "product" / "test"
62
- resource_dir.mkdir(parents=True)
63
- resource_file = resource_dir / "service.json"
64
- resource_file.write_text('{"name": "test", "version": "1.0.0"}')
65
-
66
- # Use relative path for service
67
- rel_path = "services/product/test/service.json"
68
-
69
- # Create old snapshot with hash of old content
70
- from resource_snapshot import compute_resource_hash
71
- old_hash = compute_resource_hash(rel_path)
72
- old = {
73
- "services": [rel_path],
74
- "count": 1,
75
- "resource_hashes": {rel_path: old_hash}
76
- }
77
-
78
- # Modify the file
79
- resource_file.write_text('{"name": "test", "version": "2.0.0"}')
80
- new = [rel_path]
81
-
82
- added, removed, modified = diff_snapshots(old, new, use_hashes=True)
83
-
84
- assert added == set()
85
- assert removed == set()
86
- assert modified == {rel_path}
87
- finally:
88
- os.chdir(original_dir)
89
-
90
- def test_no_changes_detected(self):
91
- """
92
- Scenario: No changes detected
93
- WHEN the filesystem matches the existing snapshot exactly
94
- THEN the diff SHALL report an empty changeset
95
- """
96
- old = {
97
- "services": [
98
- "services/product/a/service.json",
99
- "services/product/b/service.json"
100
- ],
101
- "count": 2,
102
- "hash": "abc123" # This hash will mismatch, but individual hashes match
103
- }
104
- new = [
105
- "services/product/a/service.json",
106
- "services/product/b/service.json"
107
- ]
108
-
109
- # Without actual hash computation, should find no changes
110
- added, removed, modified = diff_snapshots(old, new, use_hashes=False)
111
-
112
- assert added == set()
113
- assert removed == set()
114
- assert modified == set()
115
-
116
- def test_detects_both_added_and_removed(self):
117
- """Test detecting simultaneous additions and removals."""
118
- old = {"services": ["a/service.json", "b/service.json"], "count": 2}
119
- new = ["b/service.json", "c/service.json"]
120
-
121
- added, removed, modified = diff_snapshots(old, new)
122
-
123
- assert added == {"c/service.json"}
124
- assert removed == {"a/service.json"}
125
- assert modified == set()
126
-
127
- def test_empty_to_multiple_services(self):
128
- """Test diff when going from empty to multiple services."""
129
- old = {"services": [], "count": 0}
130
- new = ["a/service.json", "b/service.json", "c/service.json"]
131
-
132
- added, removed, modified = diff_snapshots(old, new)
133
-
134
- assert added == {"a/service.json", "b/service.json", "c/service.json"}
135
- assert removed == set()
136
- assert modified == set()