@tdk-landscape/tdk-cli-core 1.3.70 → 1.3.72

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.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,14 @@ Notable changes to the `tdk` CLI. Versions match [npm](https://www.npmjs.com/pac
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ - `tdk doctor` no longer fails with "Verdaccio is not reachable" when the project config enables Verdaccio but no Premium license grants it. TDK does not start Verdaccio in that case, so the check could never pass; it is now skipped with a note. A registry your own `.npmrc` points at (`:4873`) is still checked. Found by the ERP CI workflow.
8
+
9
+ ## 1.3.71 (2026-09-28)
10
+
11
+ - `tdk project` in a freshly cloned repo (one that already has `.tdk/project.json`) now creates the missing `.env` with working defaults. Before, it regenerated the configs but left no `.env`, and `tdk doctor` then failed with "set VERDACCIO_URL_DOCKER=<value>". Doctor now says to run `tdk project` when there is no `.env` at all. Found by the ERP CI workflow.
12
+
13
+ ## 1.3.70 (2026-09-28)
14
+
7
15
  - **Fix for 1.3.69:** `tdk doctor` no longer reports "Environment not ready" for the ERP example. The new check for missing `@types/*` packages flagged its 7 frontends, but they build with `vite build`, which never type-checks, so `types: ["node"]` cannot fail their build. It now only flags a service whose `build` script runs `tsc` (following `bun|npm|pnpm|yarn run` hops). Found by the new ERP CI workflow on its first run.
8
16
 
9
17
  - New CI workflow that boots the public 100-service ERP example on a clean GitHub-hosted runner with the published CLI and waits for every backend to answer `/health` through Traefik, then writes the time to healthy and the resource use to the job summary. Manual (`full` or `one-stack`) and weekly.
@@ -3,8 +3,9 @@ import { existsSync, readdirSync, readFileSync } from "node:fs";
3
3
  import { dirname, join, normalize } from "node:path";
4
4
  import chalk from "chalk";
5
5
  import { Command } from "commander";
6
+ import { hasVerdaccioLicense } from "../generator/extension-fetch.js";
6
7
  import { MASTER_CONFIG_FILES, QUICKSTART_DOCS_URL, REQUIRED_PACKAGE_SCRIPTS, } from "../utils/constants.js";
7
- import { checkHealthRoutes, checkHostPorts, checkIngressPorts, checkPrivateNpmRegistry, checkTiltResourceHealth, summarizeServiceProbes, } from "../utils/doctor-runtime.js";
8
+ import { checkHealthRoutes, checkHostPorts, checkIngressPorts, checkPrivateNpmRegistry, checkTiltResourceHealth, projectConfigEnablesVerdaccio, summarizeServiceProbes, } from "../utils/doctor-runtime.js";
8
9
  import { validateEnvFile } from "../utils/env-validator.js";
9
10
  import { formatCount } from "../utils/formatting.js";
10
11
  import { findProjectRoot } from "../utils/paths.js";
@@ -177,7 +178,9 @@ function checkEnvironmentVariables() {
177
178
  name: "Environment Variables",
178
179
  didPass: false,
179
180
  message: `Missing required env variables: ${validation.missing.join(", ")}`,
180
- fix: `Edit .env and set these values:\n ${validation.missing.map((v) => `${v}=<value>`).join("\n ")}`,
181
+ fix: existsSync(join(projectRoot, ".env"))
182
+ ? `Edit .env and set these values:\n ${validation.missing.map((v) => `${v}=<value>`).join("\n ")}`
183
+ : "No .env file yet. Run `tdk project` to create one with working defaults.",
181
184
  };
182
185
  }
183
186
  if (validation.invalid.length > 0) {
@@ -753,7 +756,13 @@ export const doctorCommand = new Command("doctor")
753
756
  // Preflight: a local Postgres or web server on 5432/80/443.
754
757
  () => checkHostPorts(),
755
758
  // Preflight: Verdaccio down causes ImageBuild bun install ConnectionRefused.
756
- checkPrivateNpmRegistry,
759
+ async () => {
760
+ const root = findProjectRoot() ?? process.cwd();
761
+ const licensed = projectConfigEnablesVerdaccio(root)
762
+ ? await hasVerdaccioLicense(root)
763
+ : true;
764
+ return checkPrivateNpmRegistry(execSync, root, undefined, licensed);
765
+ },
757
766
  // Runtime checks: skip gracefully if the stack isn't started yet.
758
767
  checkContainerResourceHealth,
759
768
  // When Tilt is up, surface red resources (Traefik/apps never started).
@@ -218,6 +218,9 @@ export const projectCommand = new Command("project")
218
218
  }
219
219
  showStep("\nšŸ“‹ Regenerating master configuration files...\n");
220
220
  await generateMasterConfigs(projectRoot);
221
+ if (ensureEnvFile(projectRoot)) {
222
+ showSuccess("Created: .env (the defaults work as-is)");
223
+ }
221
224
  const ignored = ensureGitignore(projectRoot);
222
225
  if (ignored.length > 0) {
223
226
  showSuccess(`Added to .gitignore: ${ignored.join(", ")}`);
@@ -175,23 +175,20 @@ export function summarizeTiltBuildError(error) {
175
175
  export function isRegistryRelatedBuildError(error) {
176
176
  return /ConnectionRefused downloading package manifest|Verdaccio|private registry|dependency install failed during ImageBuild|install-deps\.sh|bun install/i.test(error);
177
177
  }
178
- export function projectExpectsVerdaccio(projectRoot = findProjectRoot() ?? process.cwd()) {
178
+ export function projectConfigEnablesVerdaccio(projectRoot = findProjectRoot() ?? process.cwd()) {
179
179
  const projectJsonPath = join(projectRoot, ".tdk", "project.json");
180
- if (existsSync(projectJsonPath)) {
181
- try {
182
- const parsed = JSON.parse(readFileSync(projectJsonPath, "utf-8"));
183
- if (parsed.optional_infra?.verdaccio === true) {
184
- return true;
185
- }
186
- if (Object.values(parsed.phases ?? {}).some((phase) => (phase.enabledStacks ?? []).includes("verdaccio"))) {
187
- return true;
188
- }
189
- }
190
- catch {
191
- // Fall through to npmrc heuristics.
192
- }
180
+ if (!existsSync(projectJsonPath))
181
+ return false;
182
+ try {
183
+ const parsed = JSON.parse(readFileSync(projectJsonPath, "utf-8"));
184
+ return (parsed.optional_infra?.verdaccio === true ||
185
+ Object.values(parsed.phases ?? {}).some((phase) => (phase.enabledStacks ?? []).includes("verdaccio")));
193
186
  }
194
- // Heuristic: scoped private registry pointed at :4873
187
+ catch {
188
+ return false;
189
+ }
190
+ }
191
+ function npmrcPointsAtVerdaccio(projectRoot) {
195
192
  for (const candidate of [join(projectRoot, ".npmrc"), join(projectRoot, "package.json")]) {
196
193
  if (!existsSync(candidate))
197
194
  continue;
@@ -207,13 +204,24 @@ export function projectExpectsVerdaccio(projectRoot = findProjectRoot() ?? proce
207
204
  }
208
205
  return false;
209
206
  }
207
+ export function projectExpectsVerdaccio(projectRoot = findProjectRoot() ?? process.cwd()) {
208
+ return projectConfigEnablesVerdaccio(projectRoot) || npmrcPointsAtVerdaccio(projectRoot);
209
+ }
210
210
  /**
211
211
  * When the project uses a local Verdaccio registry, fail early with a clear
212
212
  * fix instead of only showing truncated ImageBuild exit codes later.
213
213
  */
214
214
  export function checkPrivateNpmRegistry(exec = execSync, projectRoot = findProjectRoot() ?? process.cwd(), registryUrl = process.env.VERDACCIO_URL ??
215
215
  process.env.NPM_REGISTRY_URL ??
216
- DEFAULT_VERDACCIO_URL) {
216
+ DEFAULT_VERDACCIO_URL, verdaccioLicensed = true) {
217
+ if (!verdaccioLicensed && !npmrcPointsAtVerdaccio(projectRoot)) {
218
+ return {
219
+ name: "Private npm registry",
220
+ didPass: true,
221
+ isSkipped: true,
222
+ message: "Verdaccio is enabled in the project config but needs a Premium license, so TDK will not start it - skipped",
223
+ };
224
+ }
217
225
  if (!projectExpectsVerdaccio(projectRoot)) {
218
226
  return {
219
227
  name: "Private npm registry",
package/cli/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "tdk-cli-internal",
3
3
  "private": true,
4
- "version": "1.3.70",
4
+ "version": "1.3.72",
5
5
  "description": "TDK CLI - Tilt Development Kit command line interface",
6
6
  "keywords": [
7
7
  "tdk",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tdk-landscape/tdk-cli-core",
3
- "version": "1.3.70",
3
+ "version": "1.3.72",
4
4
  "description": "Run 100 microservices on a 16 GB laptop without Kubernetes. Scaffold services and run them locally with hot reload, built on Tilt.",
5
5
  "homepage": "https://tdk-landscape.github.io/tdk-website",
6
6
  "repository": {