@tdk-landscape/tdk-cli-core 1.3.45 → 1.3.49

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 (431) hide show
  1. package/.github/workflows/release-binaries.yml +54 -0
  2. package/.pre-commit-config.yaml +57 -0
  3. package/Makefile +92 -0
  4. package/bun.lock +538 -0
  5. package/cli/AGENTS.md +390 -0
  6. package/cli/DESIGN.md +735 -0
  7. package/cli/biome.json +44 -0
  8. package/cli/dependency-graph.svg +1135 -0
  9. package/cli/knip.json +6 -0
  10. package/cli/package.json +77 -0
  11. package/cli/pnpm-lock.yaml +2305 -0
  12. package/cli/pnpm-workspace.yaml +2 -0
  13. package/cli/shared-platform-engineering/docker-templates/bun-hoisted-symlink-fix.sh +23 -0
  14. package/cli/shared-platform-engineering/docker-templates/infisical-entrypoint.sh +464 -0
  15. package/cli/shared-platform-engineering/docker-templates/install-deps.sh +152 -0
  16. package/cli/shared-platform-engineering/docker-templates/prisma-bun-client-link-fix.sh +12 -0
  17. package/cli/shared-platform-engineering/docker-templates/prisma-normalize-client.sh +56 -0
  18. package/{dist/cli.js → cli/src/cli.ts} +21 -13
  19. package/cli/src/commands/__tests__/always-enabled-infra.test.ts +115 -0
  20. package/cli/src/commands/__tests__/config.test.ts +146 -0
  21. package/cli/src/commands/__tests__/doctor.test.ts +557 -0
  22. package/cli/src/commands/__tests__/error-handling.test.ts +78 -0
  23. package/cli/src/commands/__tests__/phases-model.test.ts +163 -0
  24. package/cli/src/commands/__tests__/project-resource-features-e2e.test.ts +207 -0
  25. package/cli/src/commands/__tests__/project.test.ts +68 -0
  26. package/cli/src/commands/__tests__/resource.test.ts +226 -0
  27. package/cli/src/commands/__tests__/saas-starter-integration.test.ts +196 -0
  28. package/cli/src/commands/__tests__/stack-features-e2e.test.ts +129 -0
  29. package/cli/src/commands/__tests__/upgrade.test.ts +101 -0
  30. package/{dist/commands/completion.js → cli/src/commands/completion.ts} +78 -72
  31. package/cli/src/commands/config.ts +299 -0
  32. package/cli/src/commands/doctor.ts +790 -0
  33. package/cli/src/commands/down.ts +37 -0
  34. package/cli/src/commands/help.ts +150 -0
  35. package/cli/src/commands/networks-design.md +80 -0
  36. package/cli/src/commands/networks.ts +332 -0
  37. package/cli/src/commands/project.ts +439 -0
  38. package/cli/src/commands/projects.ts +82 -0
  39. package/cli/src/commands/resource.ts +652 -0
  40. package/cli/src/commands/resources.ts +95 -0
  41. package/cli/src/commands/stack.ts +128 -0
  42. package/cli/src/commands/stacks.ts +52 -0
  43. package/cli/src/commands/status.ts +88 -0
  44. package/cli/src/commands/ui.tsx +843 -0
  45. package/cli/src/commands/up.ts +150 -0
  46. package/cli/src/commands/upgrade.ts +570 -0
  47. package/{dist/commands/version.js → cli/src/commands/version.ts} +5 -5
  48. package/cli/src/components/Accessible.tsx +21 -0
  49. package/cli/src/components/BaseTooltip.tsx +66 -0
  50. package/cli/src/components/DetailPanel.tsx +146 -0
  51. package/cli/src/components/FileTree.tsx +89 -0
  52. package/cli/src/components/ResourceSelectInput.tsx +30 -0
  53. package/cli/src/components/ResourceTable.tsx +78 -0
  54. package/cli/src/components/TabBar.tsx +53 -0
  55. package/cli/src/components/Tooltip.tsx +11 -0
  56. package/{dist/components/index.js → cli/src/components/index.ts} +0 -1
  57. package/cli/src/config/platform-standards.test.ts +11 -0
  58. package/cli/src/config/platform-standards.ts +196 -0
  59. package/cli/src/generator/__tests__/extension-fetch.test.ts +220 -0
  60. package/cli/src/generator/__tests__/template-engine.test.ts +70 -0
  61. package/cli/src/generator/extension-fetch.ts +279 -0
  62. package/cli/src/generator/template-engine.ts +754 -0
  63. package/cli/src/index.ts +86 -0
  64. package/cli/src/templates.d.ts +4 -0
  65. package/cli/src/types/index.ts +351 -0
  66. package/cli/src/utils/__tests__/cache.test.ts +98 -0
  67. package/cli/src/utils/__tests__/formatting.test.ts +170 -0
  68. package/cli/src/utils/__tests__/paths.test.ts +180 -0
  69. package/cli/src/utils/__tests__/port-assignment.test.ts +121 -0
  70. package/cli/src/utils/__tests__/service-urls.test.ts +174 -0
  71. package/cli/src/utils/__tests__/services.test.ts +531 -0
  72. package/cli/src/utils/__tests__/tilt.test.ts +143 -0
  73. package/cli/src/utils/__tests__/validation.test.ts +148 -0
  74. package/cli/src/utils/cache.ts +76 -0
  75. package/cli/src/utils/command-helpers.ts +54 -0
  76. package/cli/src/utils/constants.ts +126 -0
  77. package/cli/src/utils/discovery-context.ts +49 -0
  78. package/cli/src/utils/docker.ts +20 -0
  79. package/cli/src/utils/doctor-runtime.ts +604 -0
  80. package/cli/src/utils/env-validator.ts +139 -0
  81. package/cli/src/utils/errors.ts +168 -0
  82. package/cli/src/utils/file-helpers.ts +62 -0
  83. package/cli/src/utils/formatting.ts +215 -0
  84. package/cli/src/utils/paths.ts +53 -0
  85. package/cli/src/utils/port-assignment.ts +106 -0
  86. package/cli/src/utils/project-features.ts +118 -0
  87. package/cli/src/utils/project-templates.ts +28 -0
  88. package/cli/src/utils/prompt.ts +123 -0
  89. package/cli/src/utils/resource-features.ts +209 -0
  90. package/cli/src/utils/service-urls.ts +124 -0
  91. package/cli/src/utils/services.ts +363 -0
  92. package/cli/src/utils/stack-features.ts +30 -0
  93. package/cli/src/utils/tar.ts +24 -0
  94. package/cli/src/utils/tilt.ts +113 -0
  95. package/cli/src/utils/validation.ts +67 -0
  96. package/{templates → cli/templates}/Tiltfile.hbs +1 -1
  97. package/cli/tsconfig.json +25 -0
  98. package/cli/tsconfig.typecheck.json +8 -0
  99. package/docs/FEATURES.md +279 -0
  100. package/engine/topologies/platform/docker/dockerfile/dockerfile.star +3 -3
  101. package/engine/topologies/platform/docker/generators/golden_docker_generator_v2.star +1 -1
  102. package/engine/topologies/platform/docker/layers/l2_dependency_layers.star +0 -3
  103. package/engine/topologies/platform/docker/layers/l3_builder_layers.star +1 -1
  104. package/engine/topologies/platform/docker/layers/l4_runtime_layers.star +1 -1
  105. package/engine/topologies/platform/docker/secrets/infisical.star +19 -47
  106. package/engine/topologies/tilt/resources/orchestrator/apply_migrator_orchestration.star +1 -1
  107. package/install.sh +242 -0
  108. package/knip.json +10 -0
  109. package/openspec/changes/add-vscode-tdk-troubleshooter-plugin/.openspec.yaml +2 -0
  110. package/openspec/changes/add-vscode-tdk-troubleshooter-plugin/design.md +102 -0
  111. package/openspec/changes/add-vscode-tdk-troubleshooter-plugin/proposal.md +31 -0
  112. package/openspec/changes/add-vscode-tdk-troubleshooter-plugin/specs/vscode-tdk-notifications/spec.md +48 -0
  113. package/openspec/changes/add-vscode-tdk-troubleshooter-plugin/specs/vscode-tdk-orchestration/spec.md +63 -0
  114. package/openspec/changes/add-vscode-tdk-troubleshooter-plugin/specs/vscode-tdk-troubleshooting/spec.md +56 -0
  115. package/openspec/changes/add-vscode-tdk-troubleshooter-plugin/tasks.md +61 -0
  116. package/openspec/changes/archive/2026-04-28-rename-domain-to-stack-service-to-resource/.openspec.yaml +2 -0
  117. package/openspec/changes/archive/2026-04-28-rename-domain-to-stack-service-to-resource/design.md +114 -0
  118. package/openspec/changes/archive/2026-04-28-rename-domain-to-stack-service-to-resource/proposal.md +32 -0
  119. package/openspec/changes/archive/2026-04-28-rename-domain-to-stack-service-to-resource/specs/manifest-field-migration/spec.md +20 -0
  120. package/openspec/changes/archive/2026-04-28-rename-domain-to-stack-service-to-resource/specs/resource-terminology-standard/spec.md +20 -0
  121. package/openspec/changes/archive/2026-04-28-rename-domain-to-stack-service-to-resource/specs/stack-terminology-standard/spec.md +20 -0
  122. package/openspec/changes/archive/2026-04-28-rename-domain-to-stack-service-to-resource/tasks.md +194 -0
  123. package/openspec/changes/archive/2026-04-28-star-files-parameter-fixes/.openspec.yaml +2 -0
  124. package/openspec/changes/archive/2026-04-28-star-files-parameter-fixes/design.md +111 -0
  125. package/openspec/changes/archive/2026-04-28-star-files-parameter-fixes/proposal.md +33 -0
  126. package/openspec/changes/archive/2026-04-28-star-files-parameter-fixes/specs/function-naming-alignment/spec.md +12 -0
  127. package/openspec/changes/archive/2026-04-28-star-files-parameter-fixes/specs/optional-parameter-patterns/spec.md +18 -0
  128. package/openspec/changes/archive/2026-04-28-star-files-parameter-fixes/specs/parameter-documentation/spec.md +16 -0
  129. package/openspec/changes/archive/2026-04-28-star-files-parameter-fixes/specs/parameter-naming-consistency/spec.md +12 -0
  130. package/openspec/changes/archive/2026-04-28-star-files-parameter-fixes/specs/parameter-ordering-standard/spec.md +12 -0
  131. package/openspec/changes/archive/2026-04-28-star-files-parameter-fixes/tasks.md +194 -0
  132. package/openspec/changes/archive/2026-04-29-scan-repo-gaps-fix/.openspec.yaml +2 -0
  133. package/openspec/changes/archive/2026-04-29-scan-repo-gaps-fix/codebase-audit-report.md +62 -0
  134. package/openspec/changes/archive/2026-04-29-scan-repo-gaps-fix/design.md +84 -0
  135. package/openspec/changes/archive/2026-04-29-scan-repo-gaps-fix/proposal.md +31 -0
  136. package/openspec/changes/archive/2026-04-29-scan-repo-gaps-fix/specs/codebase-audit/spec.md +27 -0
  137. package/openspec/changes/archive/2026-04-29-scan-repo-gaps-fix/specs/dead-code-cleanup/spec.md +27 -0
  138. package/openspec/changes/archive/2026-04-29-scan-repo-gaps-fix/specs/test-gap-fill/spec.md +23 -0
  139. package/openspec/changes/archive/2026-04-29-scan-repo-gaps-fix/specs/todo-resolution/spec.md +27 -0
  140. package/openspec/changes/archive/2026-04-29-scan-repo-gaps-fix/tasks.md +39 -0
  141. package/openspec/changes/archive/2026-05-04-comprehensive-cleanup-final/.openspec.yaml +5 -0
  142. package/openspec/changes/archive/2026-05-04-comprehensive-cleanup-final/design.md +94 -0
  143. package/openspec/changes/archive/2026-05-04-comprehensive-cleanup-final/proposal.md +46 -0
  144. package/openspec/changes/archive/2026-05-04-comprehensive-cleanup-final/specs/ai-slop-cleanup/CLEANUP_REPORT_8.md +174 -0
  145. package/openspec/changes/archive/2026-05-04-comprehensive-cleanup-final/specs/ai-slop-cleanup/CRITICAL_ASSESSMENT_8.md +160 -0
  146. package/openspec/changes/archive/2026-05-04-comprehensive-cleanup-final/specs/circular-deps/CRITICAL_ASSESSMENT_4.md +381 -0
  147. package/openspec/changes/archive/2026-05-04-comprehensive-cleanup-final/specs/dead-code/CRITICAL_ASSESSMENT_3.md +316 -0
  148. package/openspec/changes/archive/2026-05-04-comprehensive-cleanup-final/specs/deduplication/CRITICAL_ASSESSMENT_1.md +290 -0
  149. package/openspec/changes/archive/2026-05-04-comprehensive-cleanup-final/specs/deduplication/IMPLEMENTATION_SUMMARY_1.md +233 -0
  150. package/openspec/changes/archive/2026-05-04-comprehensive-cleanup-final/specs/defensive-cleanup/CRITICAL_ASSESSMENT_6.md +835 -0
  151. package/openspec/changes/archive/2026-05-04-comprehensive-cleanup-final/specs/legacy-cleanup/CRITICAL_ASSESSMENT_7.md +254 -0
  152. package/openspec/changes/archive/2026-05-04-comprehensive-cleanup-final/specs/legacy-cleanup/IMPLEMENTATION_SUMMARY_7.md +187 -0
  153. package/openspec/changes/archive/2026-05-04-comprehensive-cleanup-final/specs/strong-typing/CRITICAL_ASSESSMENT_5.md +269 -0
  154. package/openspec/changes/archive/2026-05-04-comprehensive-cleanup-final/specs/type-consolidation/CRITICAL_ASSESSMENT_2.md +312 -0
  155. package/openspec/changes/archive/2026-05-04-comprehensive-cleanup-final/specs/type-consolidation/IMPLEMENTATION_SUMMARY.md +170 -0
  156. package/openspec/changes/archive/2026-05-04-comprehensive-cleanup-final/tasks.md +137 -0
  157. package/openspec/changes/archive/2026-06-25-landscape-consolidation/.openspec.yaml +2 -0
  158. package/openspec/changes/archive/2026-06-25-landscape-consolidation/design.md +80 -0
  159. package/openspec/changes/archive/2026-06-25-landscape-consolidation/proposal.md +40 -0
  160. package/openspec/changes/archive/2026-06-25-landscape-consolidation/spec.md +52 -0
  161. package/openspec/changes/archive/2026-06-25-landscape-consolidation/tasks.md +51 -0
  162. package/openspec/changes/archive/2026-09-17-fix-generated-stack-boot/.openspec.yaml +2 -0
  163. package/openspec/changes/archive/2026-09-17-fix-generated-stack-boot/design.md +43 -0
  164. package/openspec/changes/archive/2026-09-17-fix-generated-stack-boot/proposal.md +29 -0
  165. package/openspec/changes/archive/2026-09-17-fix-generated-stack-boot/specs/self-contained-generated-projects/spec.md +67 -0
  166. package/openspec/changes/archive/2026-09-17-fix-generated-stack-boot/tasks.md +27 -0
  167. package/openspec/specs/manifest-field-migration/spec.md +24 -0
  168. package/openspec/specs/resource-terminology-standard/spec.md +24 -0
  169. package/openspec/specs/self-contained-generated-projects/spec.md +67 -0
  170. package/openspec/specs/stack-terminology-standard/spec.md +24 -0
  171. package/package.json +27 -64
  172. package/platform/services/platform/proxy/service.yaml +14 -0
  173. package/scripts/audit-codebase.sh +213 -0
  174. package/scripts/install-git-hooks.sh +14 -0
  175. package/scripts/release-binaries.sh +94 -0
  176. package/scripts/setup-pre-commit.sh +33 -0
  177. package/scripts/stage-npm-engine.sh +36 -0
  178. package/shared-platform-engineering/docker-templates/bun-hoisted-symlink-fix.sh +23 -0
  179. package/shared-platform-engineering/docker-templates/infisical-entrypoint.sh +464 -0
  180. package/shared-platform-engineering/docker-templates/install-deps.sh +152 -0
  181. package/shared-platform-engineering/docker-templates/prisma-bun-client-link-fix.sh +12 -0
  182. package/shared-platform-engineering/docker-templates/prisma-normalize-client.sh +56 -0
  183. package/tests/tilt-engine/__init__.py +5 -0
  184. package/tests/tilt-engine/conftest.py +182 -0
  185. package/tests/tilt-engine/fixtures/appointment-frontend-service.json +11 -0
  186. package/tests/tilt-engine/fixtures/identity-backend-service.json +12 -0
  187. package/tests/tilt-engine/fixtures/invalid-service.json +4 -0
  188. package/tests/tilt-engine/test_agents_md_generator.py +341 -0
  189. package/tests/tilt-engine/test_agents_md_integration.py +378 -0
  190. package/tests/tilt-engine/test_cache_operations.py +181 -0
  191. package/tests/tilt-engine/test_cache_persistence.py +142 -0
  192. package/tests/tilt-engine/test_code_executor.py +152 -0
  193. package/tests/tilt-engine/test_code_viewer.py +127 -0
  194. package/tests/tilt-engine/test_compose_port_anchors.py +310 -0
  195. package/tests/tilt-engine/test_config_inspector.py +162 -0
  196. package/tests/tilt-engine/test_daemon_focus_mode.py +89 -0
  197. package/tests/tilt-engine/test_daemon_polling.py +122 -0
  198. package/tests/tilt-engine/test_daemon_registration.py +115 -0
  199. package/tests/tilt-engine/test_daemon_validation.py +107 -0
  200. package/tests/tilt-engine/test_docker_generator_bugs.py +493 -0
  201. package/tests/tilt-engine/test_docker_prune.py +119 -0
  202. package/tests/tilt-engine/test_dockerignore_path_bug.py +82 -0
  203. package/tests/tilt-engine/test_file_browser.py +193 -0
  204. package/tests/tilt-engine/test_frontend_basepath_manifest.py +27 -0
  205. package/tests/tilt-engine/test_health_dependencies.py +130 -0
  206. package/tests/tilt-engine/test_health_endpoints.py +118 -0
  207. package/tests/tilt-engine/test_health_tilt_ui.py +85 -0
  208. package/tests/tilt-engine/test_safety_aliases.py +84 -0
  209. package/tests/tilt-engine/test_snapshot_diff.py +136 -0
  210. package/tests/tilt-engine/test_snapshot_persistence.py +163 -0
  211. package/tests/tilt-engine/test_snapshot_scanning.py +123 -0
  212. package/tests/tilt-engine/test_standalone_project_boot.py +61 -0
  213. package/tests/tilt-engine/test_standalone_traefik.py +108 -0
  214. package/dist/cli.d.ts +0 -3
  215. package/dist/cli.d.ts.map +0 -1
  216. package/dist/cli.js.map +0 -1
  217. package/dist/commands/completion.d.ts +0 -3
  218. package/dist/commands/completion.d.ts.map +0 -1
  219. package/dist/commands/completion.js.map +0 -1
  220. package/dist/commands/config.d.ts +0 -3
  221. package/dist/commands/config.d.ts.map +0 -1
  222. package/dist/commands/config.js +0 -231
  223. package/dist/commands/config.js.map +0 -1
  224. package/dist/commands/doctor.d.ts +0 -7
  225. package/dist/commands/doctor.d.ts.map +0 -1
  226. package/dist/commands/doctor.js +0 -597
  227. package/dist/commands/doctor.js.map +0 -1
  228. package/dist/commands/down.d.ts +0 -3
  229. package/dist/commands/down.d.ts.map +0 -1
  230. package/dist/commands/down.js +0 -32
  231. package/dist/commands/down.js.map +0 -1
  232. package/dist/commands/help.d.ts +0 -2
  233. package/dist/commands/help.d.ts.map +0 -1
  234. package/dist/commands/help.js +0 -130
  235. package/dist/commands/help.js.map +0 -1
  236. package/dist/commands/networks.d.ts +0 -3
  237. package/dist/commands/networks.d.ts.map +0 -1
  238. package/dist/commands/networks.js +0 -260
  239. package/dist/commands/networks.js.map +0 -1
  240. package/dist/commands/project.d.ts +0 -3
  241. package/dist/commands/project.d.ts.map +0 -1
  242. package/dist/commands/project.js +0 -373
  243. package/dist/commands/project.js.map +0 -1
  244. package/dist/commands/projects.d.ts +0 -3
  245. package/dist/commands/projects.d.ts.map +0 -1
  246. package/dist/commands/projects.js +0 -71
  247. package/dist/commands/projects.js.map +0 -1
  248. package/dist/commands/resource.d.ts +0 -69
  249. package/dist/commands/resource.d.ts.map +0 -1
  250. package/dist/commands/resource.js +0 -579
  251. package/dist/commands/resource.js.map +0 -1
  252. package/dist/commands/resources.d.ts +0 -3
  253. package/dist/commands/resources.d.ts.map +0 -1
  254. package/dist/commands/resources.js +0 -73
  255. package/dist/commands/resources.js.map +0 -1
  256. package/dist/commands/stack.d.ts +0 -3
  257. package/dist/commands/stack.d.ts.map +0 -1
  258. package/dist/commands/stack.js +0 -97
  259. package/dist/commands/stack.js.map +0 -1
  260. package/dist/commands/stacks.d.ts +0 -3
  261. package/dist/commands/stacks.d.ts.map +0 -1
  262. package/dist/commands/stacks.js +0 -43
  263. package/dist/commands/stacks.js.map +0 -1
  264. package/dist/commands/status.d.ts +0 -3
  265. package/dist/commands/status.d.ts.map +0 -1
  266. package/dist/commands/status.js +0 -71
  267. package/dist/commands/status.js.map +0 -1
  268. package/dist/commands/ui.d.ts +0 -3
  269. package/dist/commands/ui.d.ts.map +0 -1
  270. package/dist/commands/ui.js +0 -445
  271. package/dist/commands/ui.js.map +0 -1
  272. package/dist/commands/up.d.ts +0 -3
  273. package/dist/commands/up.d.ts.map +0 -1
  274. package/dist/commands/up.js +0 -110
  275. package/dist/commands/up.js.map +0 -1
  276. package/dist/commands/upgrade.d.ts +0 -11
  277. package/dist/commands/upgrade.d.ts.map +0 -1
  278. package/dist/commands/upgrade.js +0 -496
  279. package/dist/commands/upgrade.js.map +0 -1
  280. package/dist/commands/version.d.ts +0 -3
  281. package/dist/commands/version.d.ts.map +0 -1
  282. package/dist/commands/version.js.map +0 -1
  283. package/dist/components/Accessible.d.ts +0 -8
  284. package/dist/components/Accessible.d.ts.map +0 -1
  285. package/dist/components/Accessible.js +0 -10
  286. package/dist/components/Accessible.js.map +0 -1
  287. package/dist/components/BaseTooltip.d.ts +0 -4
  288. package/dist/components/BaseTooltip.d.ts.map +0 -1
  289. package/dist/components/BaseTooltip.js +0 -28
  290. package/dist/components/BaseTooltip.js.map +0 -1
  291. package/dist/components/DetailPanel.d.ts +0 -4
  292. package/dist/components/DetailPanel.d.ts.map +0 -1
  293. package/dist/components/DetailPanel.js +0 -18
  294. package/dist/components/DetailPanel.js.map +0 -1
  295. package/dist/components/FileTree.d.ts +0 -4
  296. package/dist/components/FileTree.d.ts.map +0 -1
  297. package/dist/components/FileTree.js +0 -47
  298. package/dist/components/FileTree.js.map +0 -1
  299. package/dist/components/ResourceSelectInput.d.ts +0 -4
  300. package/dist/components/ResourceSelectInput.d.ts.map +0 -1
  301. package/dist/components/ResourceSelectInput.js +0 -7
  302. package/dist/components/ResourceSelectInput.js.map +0 -1
  303. package/dist/components/ResourceTable.d.ts +0 -4
  304. package/dist/components/ResourceTable.d.ts.map +0 -1
  305. package/dist/components/ResourceTable.js +0 -18
  306. package/dist/components/ResourceTable.js.map +0 -1
  307. package/dist/components/TabBar.d.ts +0 -4
  308. package/dist/components/TabBar.d.ts.map +0 -1
  309. package/dist/components/TabBar.js +0 -17
  310. package/dist/components/TabBar.js.map +0 -1
  311. package/dist/components/Tooltip.d.ts +0 -12
  312. package/dist/components/Tooltip.d.ts.map +0 -1
  313. package/dist/components/Tooltip.js +0 -12
  314. package/dist/components/Tooltip.js.map +0 -1
  315. package/dist/components/index.d.ts +0 -8
  316. package/dist/components/index.d.ts.map +0 -1
  317. package/dist/components/index.js.map +0 -1
  318. package/dist/config/platform-standards.d.ts +0 -159
  319. package/dist/config/platform-standards.d.ts.map +0 -1
  320. package/dist/config/platform-standards.js +0 -181
  321. package/dist/config/platform-standards.js.map +0 -1
  322. package/dist/generator/extension-fetch.d.ts +0 -25
  323. package/dist/generator/extension-fetch.d.ts.map +0 -1
  324. package/dist/generator/extension-fetch.js +0 -252
  325. package/dist/generator/extension-fetch.js.map +0 -1
  326. package/dist/generator/template-engine.d.ts +0 -61
  327. package/dist/generator/template-engine.d.ts.map +0 -1
  328. package/dist/generator/template-engine.js +0 -557
  329. package/dist/generator/template-engine.js.map +0 -1
  330. package/dist/index.d.ts +0 -11
  331. package/dist/index.d.ts.map +0 -1
  332. package/dist/index.js +0 -11
  333. package/dist/index.js.map +0 -1
  334. package/dist/types/index.d.ts +0 -255
  335. package/dist/types/index.d.ts.map +0 -1
  336. package/dist/types/index.js +0 -17
  337. package/dist/types/index.js.map +0 -1
  338. package/dist/utils/cache.d.ts +0 -19
  339. package/dist/utils/cache.d.ts.map +0 -1
  340. package/dist/utils/cache.js +0 -64
  341. package/dist/utils/cache.js.map +0 -1
  342. package/dist/utils/command-helpers.d.ts +0 -17
  343. package/dist/utils/command-helpers.d.ts.map +0 -1
  344. package/dist/utils/command-helpers.js +0 -41
  345. package/dist/utils/command-helpers.js.map +0 -1
  346. package/dist/utils/constants.d.ts +0 -52
  347. package/dist/utils/constants.d.ts.map +0 -1
  348. package/dist/utils/constants.js +0 -112
  349. package/dist/utils/constants.js.map +0 -1
  350. package/dist/utils/discovery-context.d.ts +0 -4
  351. package/dist/utils/discovery-context.d.ts.map +0 -1
  352. package/dist/utils/discovery-context.js +0 -39
  353. package/dist/utils/discovery-context.js.map +0 -1
  354. package/dist/utils/docker.d.ts +0 -4
  355. package/dist/utils/docker.d.ts.map +0 -1
  356. package/dist/utils/docker.js +0 -19
  357. package/dist/utils/docker.js.map +0 -1
  358. package/dist/utils/doctor-runtime.d.ts +0 -66
  359. package/dist/utils/doctor-runtime.d.ts.map +0 -1
  360. package/dist/utils/doctor-runtime.js +0 -469
  361. package/dist/utils/doctor-runtime.js.map +0 -1
  362. package/dist/utils/env-validator.d.ts +0 -15
  363. package/dist/utils/env-validator.d.ts.map +0 -1
  364. package/dist/utils/env-validator.js +0 -109
  365. package/dist/utils/env-validator.js.map +0 -1
  366. package/dist/utils/errors.d.ts +0 -31
  367. package/dist/utils/errors.d.ts.map +0 -1
  368. package/dist/utils/errors.js +0 -140
  369. package/dist/utils/errors.js.map +0 -1
  370. package/dist/utils/file-helpers.d.ts +0 -14
  371. package/dist/utils/file-helpers.d.ts.map +0 -1
  372. package/dist/utils/file-helpers.js +0 -45
  373. package/dist/utils/file-helpers.js.map +0 -1
  374. package/dist/utils/formatting.d.ts +0 -30
  375. package/dist/utils/formatting.d.ts.map +0 -1
  376. package/dist/utils/formatting.js +0 -164
  377. package/dist/utils/formatting.js.map +0 -1
  378. package/dist/utils/paths.d.ts +0 -3
  379. package/dist/utils/paths.d.ts.map +0 -1
  380. package/dist/utils/paths.js +0 -41
  381. package/dist/utils/paths.js.map +0 -1
  382. package/dist/utils/port-assignment.d.ts +0 -6
  383. package/dist/utils/port-assignment.d.ts.map +0 -1
  384. package/dist/utils/port-assignment.js +0 -81
  385. package/dist/utils/port-assignment.js.map +0 -1
  386. package/dist/utils/project-features.d.ts +0 -23
  387. package/dist/utils/project-features.d.ts.map +0 -1
  388. package/dist/utils/project-features.js +0 -98
  389. package/dist/utils/project-features.js.map +0 -1
  390. package/dist/utils/project-templates.d.ts +0 -7
  391. package/dist/utils/project-templates.d.ts.map +0 -1
  392. package/dist/utils/project-templates.js +0 -24
  393. package/dist/utils/project-templates.js.map +0 -1
  394. package/dist/utils/prompt.d.ts +0 -28
  395. package/dist/utils/prompt.d.ts.map +0 -1
  396. package/dist/utils/prompt.js +0 -79
  397. package/dist/utils/prompt.js.map +0 -1
  398. package/dist/utils/resource-features.d.ts +0 -29
  399. package/dist/utils/resource-features.d.ts.map +0 -1
  400. package/dist/utils/resource-features.js +0 -171
  401. package/dist/utils/resource-features.js.map +0 -1
  402. package/dist/utils/service-urls.d.ts +0 -30
  403. package/dist/utils/service-urls.d.ts.map +0 -1
  404. package/dist/utils/service-urls.js +0 -93
  405. package/dist/utils/service-urls.js.map +0 -1
  406. package/dist/utils/services.d.ts +0 -18
  407. package/dist/utils/services.d.ts.map +0 -1
  408. package/dist/utils/services.js +0 -291
  409. package/dist/utils/services.js.map +0 -1
  410. package/dist/utils/stack-features.d.ts +0 -22
  411. package/dist/utils/stack-features.d.ts.map +0 -1
  412. package/dist/utils/stack-features.js +0 -13
  413. package/dist/utils/stack-features.js.map +0 -1
  414. package/dist/utils/tar.d.ts +0 -7
  415. package/dist/utils/tar.d.ts.map +0 -1
  416. package/dist/utils/tar.js +0 -21
  417. package/dist/utils/tar.js.map +0 -1
  418. package/dist/utils/tilt.d.ts +0 -19
  419. package/dist/utils/tilt.d.ts.map +0 -1
  420. package/dist/utils/tilt.js +0 -78
  421. package/dist/utils/tilt.js.map +0 -1
  422. package/dist/utils/validation.d.ts +0 -16
  423. package/dist/utils/validation.d.ts.map +0 -1
  424. package/dist/utils/validation.js +0 -58
  425. package/dist/utils/validation.js.map +0 -1
  426. /package/{README.md → cli/README.md} +0 -0
  427. /package/{bin → cli/bin}/tdk.js +0 -0
  428. /package/{templates → cli/templates}/.tiltignore.hbs +0 -0
  429. /package/{templates → cli/templates}/TILT_RESOURCE_DEFAULTS.star.hbs +0 -0
  430. /package/{templates → cli/templates}/TILT_TECH_STACK.star.hbs +0 -0
  431. /package/{templates → cli/templates}/spec.master.hbs +0 -0
@@ -0,0 +1,570 @@
1
+ import { execSync } from "node:child_process";
2
+ import { accessSync, constants, existsSync, realpathSync } from "node:fs";
3
+ import { dirname, join, resolve } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import chalk from "chalk";
6
+ import { Command } from "commander";
7
+ import ora from "ora";
8
+ import { getErrorMessage, logVerbose, showErrorAndExit } from "../utils/errors.js";
9
+ import { showCancelled } from "../utils/formatting.js";
10
+ import { getPackageVersion } from "../utils/paths.js";
11
+ import { promptConfirm } from "../utils/prompt.js";
12
+
13
+ interface InstallInfo {
14
+ method: "npm" | "bun" | "git" | "binary" | "unknown";
15
+ path?: string;
16
+ version?: string;
17
+ }
18
+
19
+ function isStandaloneBinary(tdkPath: string): boolean {
20
+ try {
21
+ const fileInfo = execSync(`file -b ${JSON.stringify(tdkPath)}`, { encoding: "utf-8" });
22
+ return /Mach-O|ELF/.test(fileInfo);
23
+ } catch (err: unknown) {
24
+ logVerbose("Binary detection (file command) error", err);
25
+ return false;
26
+ }
27
+ }
28
+
29
+ function detectInstallation(): InstallInfo {
30
+ try {
31
+ const tdkPath = execSync("which tdk", { encoding: "utf-8" }).trim();
32
+
33
+ // `readlink -f` is not available on macOS. Use Node's cross-platform
34
+ // realpath implementation so standalone binaries are detected there too.
35
+ const realPath = realpathSync(tdkPath);
36
+ // If the real path contains tdk-cli and has .git, it's a linked git install
37
+ if (realPath.includes("tdk-cli")) {
38
+ const possibleGitRoot = resolve(realPath, "..", "..", "..");
39
+ if (existsSync(join(possibleGitRoot, ".git"))) {
40
+ return { method: "git", path: possibleGitRoot };
41
+ }
42
+ }
43
+
44
+ if (tdkPath.includes("node_modules") || tdkPath.includes(".npm") || tdkPath.includes(".bun")) {
45
+ if (tdkPath.includes(".bun")) {
46
+ return { method: "bun", path: tdkPath };
47
+ }
48
+ return { method: "npm", path: tdkPath };
49
+ }
50
+
51
+ const cliRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..", "..", "..");
52
+ if (existsSync(join(cliRoot, ".git"))) {
53
+ return { method: "git", path: cliRoot };
54
+ }
55
+
56
+ // Standalone prebuilt binary from tdk-cli-releases (installed to e.g. /usr/local/bin),
57
+ // not a node_modules/.bun link and not sitting inside a git checkout.
58
+ if (isStandaloneBinary(realPath)) {
59
+ return { method: "binary", path: realPath };
60
+ }
61
+
62
+ return { method: "unknown", path: tdkPath };
63
+ } catch (err: unknown) {
64
+ console.warn(chalk.yellow("⚠️ Could not detect installation method"));
65
+ logVerbose("Installation detection error", err);
66
+ return { method: "unknown" };
67
+ }
68
+ }
69
+
70
+ const BINARY_RELEASE_REPO = "tdk-landscape/tdk-cli-releases";
71
+
72
+ function binaryAssetName(): string | null {
73
+ const osName = process.platform === "darwin" ? "darwin" : process.platform === "linux" ? "linux" : null;
74
+ const archName = process.arch === "arm64" ? "arm64" : process.arch === "x64" ? "amd64" : null;
75
+ if (!osName || !archName) return null;
76
+ return `tdk-${osName}-${archName}`;
77
+ }
78
+
79
+ const ENGINE_ASSET_NAME = "tdk-cli-engine.tar.gz";
80
+
81
+ export interface BinaryRelease {
82
+ tag: string;
83
+ assetName: string;
84
+ downloadUrl: string;
85
+ engineDownloadUrl: string;
86
+ }
87
+
88
+ async function getLatestBinaryRelease(): Promise<BinaryRelease | null> {
89
+ const assetName = binaryAssetName();
90
+ if (!assetName) return null;
91
+
92
+ try {
93
+ const raw = execSync(
94
+ `curl -fsSL https://api.github.com/repos/${BINARY_RELEASE_REPO}/releases/latest`,
95
+ { encoding: "utf-8", timeout: 10000 },
96
+ );
97
+ const data = JSON.parse(raw) as { tag_name?: string };
98
+ if (!data.tag_name) return null;
99
+
100
+ return {
101
+ tag: data.tag_name,
102
+ assetName,
103
+ downloadUrl: `https://github.com/${BINARY_RELEASE_REPO}/releases/download/${data.tag_name}/${assetName}`,
104
+ engineDownloadUrl: `https://github.com/${BINARY_RELEASE_REPO}/releases/download/${data.tag_name}/${ENGINE_ASSET_NAME}`,
105
+ };
106
+ } catch (err: unknown) {
107
+ logVerbose("Binary release lookup error", err);
108
+ return null;
109
+ }
110
+ }
111
+
112
+ export function isWritable(path: string): boolean {
113
+ try {
114
+ accessSync(path, constants.W_OK);
115
+ return true;
116
+ } catch {
117
+ return false;
118
+ }
119
+ }
120
+
121
+ export async function upgradeViaBinary(tdkPath: string, release: BinaryRelease): Promise<boolean> {
122
+ // Never shells out to sudo - if the install dir isn't user-writable, fail
123
+ // fast with the manual curl command instead of downloading first and
124
+ // elevating automatically. The user runs that curl themselves.
125
+ const installDir = dirname(tdkPath);
126
+ if (!isWritable(installDir)) {
127
+ console.log(chalk.yellow(`\n🔒 ${installDir} isn't writable by your user.`));
128
+ console.log(chalk.yellow("💡 Upgrade manually instead:"));
129
+ console.log(chalk.cyan(` curl -fsSL -o ${tdkPath} ${release.downloadUrl}`));
130
+ console.log(chalk.cyan(` chmod +x ${tdkPath}`));
131
+ return false;
132
+ }
133
+
134
+ const spinner = ora(`Downloading ${release.assetName} (${release.tag})...`).start();
135
+ // Download to /tmp first (both the binary and the engine bundle below) so a
136
+ // failed network step can't leave a half-written binary at tdkPath.
137
+ const tmpPath = `/tmp/tdk-upgrade-${release.assetName}`;
138
+ const engineTmpPath = `/tmp/tdk-upgrade-engine-${release.tag}.tar.gz`;
139
+ const engineDir = join(installDir, "tdk-cli");
140
+
141
+ try {
142
+ execSync(`curl -fsSL -o ${JSON.stringify(tmpPath)} ${JSON.stringify(release.downloadUrl)}`, {
143
+ stdio: "pipe",
144
+ timeout: 120000,
145
+ });
146
+ execSync(`chmod +x ${JSON.stringify(tmpPath)}`);
147
+
148
+ // The compiled binary has no source checkout to find engine/ or
149
+ // cli/templates/ in, so it looks for a tdk-cli/ folder next to itself
150
+ // (see template-engine.ts loadTemplate() / vendorTdkExtension()).
151
+ // `tdk upgrade` only used to swap the binary, leaving that folder
152
+ // stale/missing after an upgrade - refresh it here too, every time,
153
+ // the same way install.sh does on a fresh install.
154
+ spinner.text = `Downloading bundled engine (${release.tag})...`;
155
+ execSync(
156
+ `curl -fsSL -o ${JSON.stringify(engineTmpPath)} ${JSON.stringify(release.engineDownloadUrl)}`,
157
+ { stdio: "pipe", timeout: 120000 },
158
+ );
159
+
160
+ execSync(`mv ${JSON.stringify(tmpPath)} ${JSON.stringify(tdkPath)}`);
161
+ execSync(`rm -rf ${JSON.stringify(engineDir)}`);
162
+ execSync(`mkdir -p ${JSON.stringify(engineDir)}`);
163
+ execSync(
164
+ `tar -xzf ${JSON.stringify(engineTmpPath)} -C ${JSON.stringify(engineDir)} --strip-components=1`,
165
+ );
166
+
167
+ spinner.succeed(`Upgraded to ${release.tag}`);
168
+ return true;
169
+ } catch (err: unknown) {
170
+ spinner.fail(`Binary upgrade failed: ${getErrorMessage(err)}`);
171
+ logVerbose("Binary upgrade error", err);
172
+ console.log(chalk.yellow("\n💡 If this failed due to permissions, upgrade manually instead:"));
173
+ console.log(chalk.cyan(` curl -fsSL -o ${tdkPath} ${release.downloadUrl}`));
174
+ console.log(chalk.cyan(` chmod +x ${tdkPath}`));
175
+ console.log(chalk.cyan(` rm -rf ${engineDir} && mkdir -p ${engineDir}`));
176
+ console.log(
177
+ chalk.cyan(` curl -fsSL ${release.engineDownloadUrl} | tar -xzf - -C ${engineDir} --strip-components=1`),
178
+ );
179
+ return false;
180
+ } finally {
181
+ try {
182
+ execSync(`rm -f ${JSON.stringify(tmpPath)} ${JSON.stringify(engineTmpPath)}`);
183
+ } catch {
184
+ // best-effort cleanup
185
+ }
186
+ }
187
+ }
188
+
189
+ function getCurrentVersion(): string {
190
+ try {
191
+ return getPackageVersion();
192
+ } catch (err: unknown) {
193
+ logVerbose("Version detection error", err);
194
+ return "unknown";
195
+ }
196
+ }
197
+
198
+ async function getLatestVersion(): Promise<string | null> {
199
+ const spinner = ora("Checking for latest version...").start();
200
+
201
+ try {
202
+ const result = execSync("npm view @tdk-landscape/tdk-cli-core version", {
203
+ encoding: "utf-8",
204
+ timeout: 10000,
205
+ }).trim();
206
+ spinner.succeed(`Latest version: ${chalk.green(result)}`);
207
+ return result;
208
+ } catch (_err: unknown) {
209
+ // npm registry failed - package not published yet
210
+ spinner.warn("Package not yet published to npm registry");
211
+ console.log(chalk.yellow("\n💡 For now, please upgrade manually from GitHub:"));
212
+ console.log(chalk.cyan(" npm install -g github:tdk-landscape/tdk-cli-core"));
213
+ console.log(chalk.cyan(" bun install -g github:tdk-landscape/tdk-cli-core"));
214
+ console.log(chalk.gray("\n (npm package will be available soon)"));
215
+ return null;
216
+ }
217
+ }
218
+
219
+ async function upgradeViaNpm(): Promise<boolean> {
220
+ const spinner = ora("Upgrading via npm...").start();
221
+
222
+ try {
223
+ execSync("npm install -g @tdk-landscape/tdk-cli-core@latest", {
224
+ stdio: "inherit",
225
+ timeout: 120000,
226
+ });
227
+ spinner.succeed("Upgraded successfully via npm");
228
+ return true;
229
+ } catch (err: unknown) {
230
+ // npm registry failed (package may not exist or network issue) - try GitHub fallback
231
+ spinner.text = "npm registry failed, trying GitHub...";
232
+ logVerbose("npm registry error", err);
233
+ try {
234
+ execSync("npm install -g github:tdk-landscape/tdk-cli-core", {
235
+ stdio: "inherit",
236
+ timeout: 120000,
237
+ });
238
+ spinner.succeed("Upgraded successfully via GitHub");
239
+ return true;
240
+ } catch (err: unknown) {
241
+ spinner.fail(`Upgrade failed: ${getErrorMessage(err)}`);
242
+ return false;
243
+ }
244
+ }
245
+ }
246
+
247
+ async function upgradeViaBun(): Promise<boolean> {
248
+ const spinner = ora("Upgrading via bun...").start();
249
+
250
+ try {
251
+ execSync("bun install -g @tdk-landscape/tdk-cli-core@latest", {
252
+ stdio: "inherit",
253
+ timeout: 120000,
254
+ });
255
+ spinner.succeed("Upgraded successfully via bun");
256
+ return true;
257
+ } catch (err: unknown) {
258
+ // bun registry failed (package may not exist or network issue) - try GitHub fallback
259
+ spinner.text = "bun registry failed, trying GitHub...";
260
+ logVerbose("bun registry error", err);
261
+ try {
262
+ execSync("bun install -g github:tdk-landscape/tdk-cli-core", {
263
+ stdio: "inherit",
264
+ timeout: 120000,
265
+ });
266
+ spinner.succeed("Upgraded successfully via GitHub");
267
+ return true;
268
+ } catch (err: unknown) {
269
+ spinner.fail(`Upgrade failed: ${getErrorMessage(err)}`);
270
+ return false;
271
+ }
272
+ }
273
+ }
274
+
275
+ async function upgradeViaGit(path: string): Promise<boolean> {
276
+ const spinner = ora("Pulling latest changes from git...").start();
277
+
278
+ try {
279
+ execSync("git rev-parse --git-dir", {
280
+ cwd: path,
281
+ stdio: "pipe",
282
+ });
283
+
284
+ spinner.text = "Fetching from origin...";
285
+ execSync("git fetch origin", {
286
+ cwd: path,
287
+ stdio: "pipe",
288
+ timeout: 30000,
289
+ });
290
+
291
+ const branch = execSync("git rev-parse --abbrev-ref HEAD", {
292
+ cwd: path,
293
+ encoding: "utf-8",
294
+ }).trim();
295
+
296
+ spinner.text = `Pulling latest on ${branch}...`;
297
+ execSync(`git pull origin ${branch}`, {
298
+ cwd: path,
299
+ stdio: "pipe",
300
+ timeout: 30000,
301
+ });
302
+
303
+ if (existsSync(join(path, "cli", "package.json"))) {
304
+ spinner.text = "Rebuilding CLI...";
305
+ execSync("bun install && bun run build", {
306
+ cwd: join(path, "cli"),
307
+ stdio: "pipe",
308
+ timeout: 60000,
309
+ });
310
+ }
311
+
312
+ spinner.text = "Re-linking CLI...";
313
+ execSync("bun link --force", {
314
+ cwd: join(path, "cli"),
315
+ stdio: "pipe",
316
+ timeout: 30000,
317
+ });
318
+
319
+ spinner.succeed("Upgraded successfully via git pull");
320
+ return true;
321
+ } catch (err: unknown) {
322
+ spinner.fail(`Git upgrade failed: ${getErrorMessage(err)}`);
323
+ return false;
324
+ }
325
+ }
326
+
327
+ export const upgradeCommand = new Command("upgrade")
328
+ .alias("update")
329
+ .description("Upgrade TDK CLI to the latest version")
330
+ .option("-f, --force", "Force upgrade even if already on latest", false)
331
+ .option("--dry-run", "Show what would be upgraded without actually doing it", false)
332
+ .option("-y, --yes", "Skip confirmation prompt", false)
333
+ .action(async (options) => {
334
+ console.log(chalk.cyan("🚀 TDK CLI Upgrade\n"));
335
+
336
+ const currentVersion = getCurrentVersion();
337
+ console.log(chalk.gray(`Current version: ${currentVersion}`));
338
+
339
+ const installInfo = detectInstallation();
340
+ console.log(chalk.gray(`Installation method: ${installInfo.method}`));
341
+ console.log();
342
+
343
+ if (installInfo.method === "unknown") {
344
+ console.error(chalk.red("❌ Could not detect installation method"));
345
+ console.log(chalk.yellow("\n💡 Manual upgrade (package not on npm yet, use GitHub):"));
346
+ console.log(chalk.cyan(" npm: npm install -g github:tdk-landscape/tdk-cli-core"));
347
+ console.log(chalk.cyan(" bun: bun install -g github:tdk-landscape/tdk-cli-core"));
348
+ console.log(chalk.cyan(" git: cd /path/to/tdk-cli && git pull && bun link --force"));
349
+ process.exit(1);
350
+ }
351
+
352
+ let latestVersion: string | null = null;
353
+ let binaryRelease: BinaryRelease | null = null;
354
+
355
+ if (installInfo.method === "binary" && installInfo.path) {
356
+ console.log(chalk.blue("📦 Standalone binary installation detected"));
357
+
358
+ binaryRelease = await getLatestBinaryRelease();
359
+
360
+ if (!binaryRelease) {
361
+ showErrorAndExit(
362
+ `Could not determine latest release for this platform (${process.platform}/${process.arch})`,
363
+ );
364
+ }
365
+
366
+ latestVersion = binaryRelease.tag.replace(/^v/, "").split("-")[0];
367
+
368
+ if (latestVersion === currentVersion && !options.force) {
369
+ console.log(chalk.green("\n✅ You are already on the latest version!"));
370
+ console.log(chalk.gray(` ${currentVersion} (current) = ${latestVersion} (latest)`));
371
+ process.exit(0);
372
+ }
373
+
374
+ if (latestVersion !== currentVersion) {
375
+ console.log(chalk.yellow(`\n⬆️ Upgrade available: ${currentVersion} → ${latestVersion}`));
376
+ } else if (options.force) {
377
+ console.log(chalk.yellow(`\n🔄 Force upgrade requested (currently ${currentVersion})`));
378
+ }
379
+ } else if (installInfo.method === "git" && installInfo.path) {
380
+ console.log(chalk.blue("📦 Git installation detected - will pull latest from origin"));
381
+
382
+ try {
383
+ execSync("git fetch origin", { cwd: installInfo.path, stdio: "pipe" });
384
+ const localHash = execSync("git rev-parse HEAD", {
385
+ cwd: installInfo.path,
386
+ encoding: "utf-8",
387
+ }).trim();
388
+ const remoteHash = execSync("git rev-parse origin/main", {
389
+ cwd: installInfo.path,
390
+ encoding: "utf-8",
391
+ }).trim();
392
+
393
+ if (localHash === remoteHash && !options.force) {
394
+ console.log(chalk.green("\n✅ Already up to date with origin/main!"));
395
+ console.log(chalk.gray(` Current: ${localHash.substring(0, 7)}`));
396
+ console.log(chalk.gray("\n Tip: Use --force to pull and rebuild anyway"));
397
+ process.exit(0);
398
+ }
399
+
400
+ if (localHash !== remoteHash) {
401
+ console.log(chalk.yellow(`\n⬆️ Updates available:`));
402
+ console.log(chalk.gray(` Local: ${localHash.substring(0, 7)}`));
403
+ console.log(chalk.gray(` Remote: ${remoteHash.substring(0, 7)}`));
404
+ } else {
405
+ console.log(chalk.yellow(`\n🔄 Force upgrade requested`));
406
+ }
407
+
408
+ latestVersion = remoteHash.substring(0, 7);
409
+ } catch (err: unknown) {
410
+ console.warn(chalk.yellow("⚠️ Could not check git remote, will attempt upgrade anyway"));
411
+ logVerbose("Git remote check failed", err);
412
+ latestVersion = "latest";
413
+ }
414
+ } else {
415
+ latestVersion = await getLatestVersion();
416
+
417
+ if (!latestVersion) {
418
+ showErrorAndExit("Could not determine latest version");
419
+ }
420
+
421
+ if (currentVersion === latestVersion && !options.force) {
422
+ console.log(chalk.green("\n✅ You are already on the latest version!"));
423
+ console.log(chalk.gray(` ${currentVersion} (current) = ${latestVersion} (latest)`));
424
+ process.exit(0);
425
+ }
426
+
427
+ if (currentVersion !== latestVersion) {
428
+ console.log(chalk.yellow(`\n⬆️ Upgrade available: ${currentVersion} → ${latestVersion}`));
429
+ } else if (options.force) {
430
+ console.log(chalk.yellow(`\n🔄 Force upgrade requested (currently ${currentVersion})`));
431
+ }
432
+ }
433
+
434
+ if (options.dryRun) {
435
+ console.log(chalk.blue("\n📋 Dry run mode - would perform:"));
436
+ console.log(chalk.gray(` Method: ${installInfo.method}`));
437
+ if (installInfo.path) {
438
+ console.log(chalk.gray(` Path: ${installInfo.path}`));
439
+ }
440
+ if (installInfo.method === "git") {
441
+ console.log(
442
+ chalk.gray(" Action: git pull origin main && bun install && bun link --force"),
443
+ );
444
+ } else if (installInfo.method === "binary" && binaryRelease) {
445
+ console.log(chalk.gray(` Action: Download and replace with ${binaryRelease.downloadUrl}`));
446
+ console.log(chalk.gray(` Action: Refresh bundled engine from ${binaryRelease.engineDownloadUrl}`));
447
+ } else {
448
+ console.log(chalk.gray(` Action: Upgrade to ${latestVersion}`));
449
+ }
450
+ console.log(chalk.yellow("\n (Not actually upgrading due to --dry-run)"));
451
+ process.exit(0);
452
+ }
453
+
454
+ if (!options.yes) {
455
+ console.log();
456
+ const confirm = await promptConfirm({
457
+ message: "Proceed with upgrade?",
458
+ initial: true,
459
+ });
460
+
461
+ if (!confirm) {
462
+ showCancelled();
463
+ process.exit(0);
464
+ }
465
+ } else {
466
+ console.log(chalk.gray("⚡ Auto-confirming (--yes flag)\n"));
467
+ }
468
+
469
+ console.log();
470
+
471
+ let success = false;
472
+
473
+ switch (installInfo.method) {
474
+ case "npm":
475
+ success = await upgradeViaNpm();
476
+ break;
477
+ case "bun":
478
+ success = await upgradeViaBun();
479
+ break;
480
+ case "git":
481
+ if (installInfo.path) {
482
+ success = await upgradeViaGit(installInfo.path);
483
+ }
484
+ break;
485
+ case "binary":
486
+ if (installInfo.path && binaryRelease) {
487
+ success = await upgradeViaBinary(installInfo.path, binaryRelease);
488
+ }
489
+ break;
490
+ }
491
+
492
+ if (!success) {
493
+ console.error(chalk.red("\n❌ Upgrade failed"));
494
+ console.log(
495
+ chalk.yellow("\n💡 Try manual upgrade (use GitHub until npm package is published):"),
496
+ );
497
+ if (installInfo.method === "npm") {
498
+ console.log(chalk.cyan(" npm install -g github:tdk-landscape/tdk-cli-core"));
499
+ } else if (installInfo.method === "bun") {
500
+ console.log(chalk.cyan(" bun install -g github:tdk-landscape/tdk-cli-core"));
501
+ } else if (installInfo.method === "git") {
502
+ console.log(chalk.cyan(` cd ${installInfo.path} && git pull && bun link --force`));
503
+ } else if (installInfo.method === "binary" && binaryRelease && installInfo.path) {
504
+ const engineDir = join(dirname(installInfo.path), "tdk-cli");
505
+ console.log(
506
+ chalk.cyan(` curl -fsSL -o ${installInfo.path} ${binaryRelease.downloadUrl}`),
507
+ );
508
+ console.log(chalk.cyan(` chmod +x ${installInfo.path}`));
509
+ console.log(chalk.cyan(` rm -rf ${engineDir} && mkdir -p ${engineDir}`));
510
+ console.log(
511
+ chalk.cyan(
512
+ ` curl -fsSL ${binaryRelease.engineDownloadUrl} | tar -xzf - -C ${engineDir} --strip-components=1`,
513
+ ),
514
+ );
515
+ }
516
+ process.exit(1);
517
+ }
518
+
519
+ console.log();
520
+ const verifySpinner = ora("Verifying upgrade...").start();
521
+
522
+ try {
523
+ const newVersion = execSync("tdk version", { encoding: "utf-8" }).trim();
524
+ verifySpinner.succeed(`Verified: now running ${chalk.green(newVersion)}`);
525
+
526
+ console.log();
527
+ console.log(chalk.green.bold("✨ Upgrade complete!"));
528
+ console.log(chalk.gray(` Version: ${currentVersion} → ${newVersion}`));
529
+
530
+ console.log();
531
+ console.log(chalk.cyan.bold("📍 Installation Details:"));
532
+ if (installInfo.method === "git" && installInfo.path) {
533
+ console.log(chalk.gray(` Location: ${installInfo.path}`));
534
+ console.log(chalk.gray(` Method: git clone + bun link`));
535
+ } else {
536
+ console.log(chalk.gray(` Method: ${installInfo.method}`));
537
+ }
538
+ console.log(
539
+ chalk.gray(` Binary: ${execSync("which tdk", { encoding: "utf-8" }).trim()}`),
540
+ );
541
+
542
+ console.log();
543
+ console.log(chalk.cyan.bold("🚀 Quick Start:"));
544
+ console.log(chalk.white(` tdk --help Show all commands`));
545
+ console.log(chalk.white(` tdk networks View service URLs`));
546
+ console.log(chalk.white(` tdk doctor Check environment`));
547
+
548
+ if (newVersion === currentVersion && !options.force) {
549
+ console.log();
550
+ console.log(
551
+ chalk.yellow("💡 Tip: Version appears unchanged. You may need to restart your terminal."),
552
+ );
553
+ }
554
+
555
+ console.log();
556
+ console.log(chalk.green("Happy coding! 🎉"));
557
+ } catch (err: unknown) {
558
+ verifySpinner.warn("Could not verify new version");
559
+ console.error(chalk.red(`Verification error: ${getErrorMessage(err)}`));
560
+ console.log();
561
+ console.log(chalk.yellow("⚠️ Upgrade status unknown - verification failed"));
562
+ console.log();
563
+ console.log(chalk.yellow("💡 Verify manually:"));
564
+ console.log(chalk.white(" 1. Restart your terminal"));
565
+ console.log(chalk.white(" 2. Run: tdk version"));
566
+ if (installInfo.path) {
567
+ console.log(chalk.white(` 3. Compare with: git -C ${installInfo.path} rev-parse HEAD`));
568
+ }
569
+ }
570
+ });
@@ -1,9 +1,9 @@
1
1
  import { Command } from "commander";
2
2
  import { getPackageVersion } from "../utils/paths.js";
3
+
3
4
  export const versionCommand = new Command("version")
4
- .description("Display version number")
5
- .alias("v")
6
- .action(() => {
5
+ .description("Display version number")
6
+ .alias("v")
7
+ .action(() => {
7
8
  console.log(getPackageVersion());
8
- });
9
- //# sourceMappingURL=version.js.map
9
+ });
@@ -0,0 +1,21 @@
1
+ import type React from "react";
2
+ import type { BaseTooltipProps } from "../types/index.js";
3
+ import { BaseTooltip } from "./BaseTooltip.js";
4
+
5
+ /**
6
+ * Info tooltip variant with predefined accessibility styling.
7
+ * Uses ℹ prefix and adds margin for better visibility.
8
+ */
9
+ export const AccessibleTooltip: React.FC<
10
+ Pick<BaseTooltipProps, "content" | "shortcut" | "visible">
11
+ > = ({ content, shortcut, visible }) => {
12
+ return (
13
+ <BaseTooltip
14
+ content={content}
15
+ shortcut={shortcut}
16
+ visible={visible}
17
+ prefix="ℹ "
18
+ marginTop={1}
19
+ />
20
+ );
21
+ };
@@ -0,0 +1,66 @@
1
+ import { Box, Text } from "ink";
2
+ import type React from "react";
3
+ import type { BaseTooltipProps } from "../types/index.js";
4
+
5
+ export const BaseTooltip: React.FC<BaseTooltipProps> = ({
6
+ content,
7
+ shortcut,
8
+ visible,
9
+ maxWidth = 40,
10
+ wrapText = false,
11
+ prefix = "",
12
+ marginTop = 0,
13
+ }) => {
14
+ if (!visible) return null;
15
+
16
+ // Wrap text to maxWidth if requested
17
+ const lines: string[] = wrapText ? wrapContent(content, maxWidth) : [content];
18
+
19
+ return (
20
+ <Box
21
+ flexDirection="column"
22
+ borderStyle="single"
23
+ borderColor="yellow"
24
+ paddingX={1}
25
+ paddingY={1}
26
+ backgroundColor="black"
27
+ marginTop={marginTop}
28
+ >
29
+ {lines.map((line, i) => (
30
+ // biome-ignore lint/suspicious/noArrayIndexKey: static color-chip list, stable order
31
+ <Text key={i} color="yellow">
32
+ {prefix}
33
+ {line}
34
+ </Text>
35
+ ))}
36
+ {shortcut && (
37
+ <Box marginTop={1}>
38
+ <Text color="gray">Press </Text>
39
+ <Text color="cyan" bold>
40
+ {shortcut.startsWith("[") ? shortcut : `[${shortcut}]`}
41
+ </Text>
42
+ <Text color="gray"> to use</Text>
43
+ </Box>
44
+ )}
45
+ </Box>
46
+ );
47
+ };
48
+
49
+ function wrapContent(content: string, maxWidth: number): string[] {
50
+ const words = content.split(" ");
51
+ const lines: string[] = [];
52
+ let currentLine = "";
53
+
54
+ for (const word of words) {
55
+ if ((currentLine + word).length > maxWidth - 2) {
56
+ lines.push(currentLine.trim());
57
+ currentLine = `${word} `;
58
+ } else {
59
+ currentLine += `${word} `;
60
+ }
61
+ }
62
+ if (currentLine) {
63
+ lines.push(currentLine.trim());
64
+ }
65
+ return lines;
66
+ }