@tdk-landscape/tdk-cli-core 1.3.124 → 1.3.125
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 +284 -18
- package/README.md +19 -1
- package/cli/dist/commands/doctor.js +3 -127
- package/cli/dist/commands/down.js +8 -1
- package/cli/dist/commands/eject.js +2 -2
- package/cli/dist/commands/logs.js +16 -10
- package/cli/dist/commands/networks.js +10 -10
- package/cli/dist/commands/resource.js +7 -126
- package/cli/dist/commands/ui.js +35 -14
- package/cli/dist/commands/upgrade.js +39 -52
- package/cli/dist/components/TabBar.js +2 -7
- package/cli/dist/generator/resource-templates.js +127 -0
- package/cli/dist/utils/doctor-starlark.js +131 -0
- package/cli/dist/utils/env-validator.js +61 -19
- package/cli/dist/utils/service-manifest.js +11 -0
- package/cli/dist/utils/services.js +5 -1
- package/cli/dist/utils/tilt.js +2 -1
- package/cli/dist/utils/ui-keymap.js +118 -0
- package/cli/package.json +1 -1
- package/engine/topologies/tilt/common/utils.star +3 -3
- package/engine/topologies/tilt/common/utils_debug.star +1 -1
- package/engine/topologies/tilt/generators/typescript/frontend_tsconfig.star +4 -6
- package/engine/topologies/tilt/resources/infra-loader.star +12 -11
- package/engine/topologies/tilt/resources/orchestrator/apply.star +2 -1
- package/engine/topologies/tilt/resources/orchestrator/apply_compose_resource_registration.star +19 -18
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,28 +4,294 @@ Notable changes to the `tdk` CLI. Versions match [npm](https://www.npmjs.com/pac
|
|
|
4
4
|
|
|
5
5
|
## Unreleased
|
|
6
6
|
|
|
7
|
+
## 1.3.125 (2026-10-08)
|
|
8
|
+
|
|
9
|
+
- `tdk upgrade` no longer falls back to installing from the repository's moving GitHub default branch when the npm or Bun registry install fails. It reports the original install error, exits non-zero and prints the published-package command (`npm install -g @tdk-landscape/tdk-cli-core@latest` or `bun install -g @tdk-landscape/tdk-cli-core@latest`). npm `EACCES`/`EPERM` failures also point at npm's global-prefix docs and the official installer. Fixes #702.
|
|
10
|
+
- `tdk networks` now lists routable frontend, backend and MCP services that omit `basePath`, using the same default route the generator uses. `--json`, `--raw` and stack filtering are unchanged, and the advice that `basePath` is required is gone. Fixes #719.
|
|
11
|
+
- `tdk down`, `tdk eject` and `tdk logs` report a missing or invalid project root with the shared error and suggestions, before any Docker or Tilt check. `down --json` and `logs --json` return it in one schema-versioned envelope. Fixes #722.
|
|
12
|
+
- Registering an SDK resource whose path has no `service.json` now stops before scaffolding with the path and the next step (add a `service.json` with `"appType": "sdk"`, then rerun), instead of a raw `Object.entries` exception. Fixes #714.
|
|
13
|
+
- Repairing an empty generated value in an existing `.env` now rewrites the file atomically and keeps its mode; a failed write leaves the old file intact. Other lines and comments are unchanged. Fixes #724.
|
|
14
|
+
- The engine's remaining Starlark `DEBUG` lines are now printed only with `TDK_DEBUG=1` (`TILT_DEBUG` still works). Fixes #701.
|
|
15
|
+
- Internal: `tdk ui` key bindings come from one typed keymap shared by the help panel, footer and tab bar (#448); the scaffold templates moved to `cli/src/generator/resource-templates.ts` (#699) and doctor's Starlark load checks to `cli/src/utils/doctor-starlark.ts` (#698). No behaviour change.
|
|
16
|
+
- Docs: `docs/ui.md` lists every `tdk ui` key binding (#697); new contributor guides for finding bugs (`docs/contributing/finding-bugs.md`) and for reviewing PRs with the AI buttons (`docs/contributing/04-review-a-pr.md`); a new README intro on why TDK generates the local infrastructure (#738).
|
|
17
|
+
|
|
18
|
+
## 1.3.124 (2026-10-07)
|
|
19
|
+
|
|
20
|
+
- A `service.json` with a `schemaVersion` this tdk does not know now stops `tdk up` (dry run included) before anything starts and names the file; a missing `schemaVersion` still only warns. `tdk up` requires Bun only when the project has services that need it, the same rule `tdk doctor` uses (#731).
|
|
21
|
+
- Discovered resources now carry their `port` and `type`, so `tdk resources --ports`/`--verbose` and `tdk status --json` show real values, and new services no longer all get port 4000 (#736).
|
|
22
|
+
- `.env` files are parsed like Compose does: inline comments after whitespace, BOM and CRLF, matching quotes and the documented escapes; `N= # c` stays empty. Fixes #725 (#737).
|
|
23
|
+
- CI: `wsl2-smoke` runs only when started by hand (#716, #717, #730).
|
|
24
|
+
|
|
25
|
+
## 1.3.123 (2026-10-07)
|
|
26
|
+
|
|
27
|
+
- Version-only release: `package.json` on `main` was brought back in line with the published version (#734). Same code as 1.3.122.
|
|
28
|
+
|
|
29
|
+
## 1.3.122 (2026-10-07)
|
|
30
|
+
|
|
7
31
|
- `tdk stack` can assign named resources in scripts with `--resources` (space- or comma-separated) and skip confirmation with `--yes`. Unknown names list valid resources, and non-TTY assignments without explicit resource names fail with a command hint. Invalid JSON encountered while writing now names the affected `service.json`.
|
|
8
|
-
-
|
|
9
|
-
- `tdk
|
|
10
|
-
- `tdk
|
|
11
|
-
- `tdk
|
|
12
|
-
-
|
|
13
|
-
- `tdk
|
|
14
|
-
- `
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
32
|
+
- Security (GHSA-3hj3-f39v-j2x5): the standalone Traefik (80/443) and Postgres ports bind to loopback instead of `0.0.0.0`, so others on the network can no longer reach them, and the Traefik API/dashboard (`--api.insecure`) is off (#720).
|
|
33
|
+
- `tdk logs`, `tdk doctor --json` and error messages replace values from the project's `.env` (8 characters or longer) with `[REDACTED]` (#703).
|
|
34
|
+
- `tdk up` and `tdk doctor` say when `schemaVersion` is missing or unsupported (#687), and refuse circular `dependsOn` and invalid ports before anything starts (#681).
|
|
35
|
+
- `tdk up` names the next step when another process holds a port (#711) and checks Bun against the same minimum version as `tdk doctor` (#688).
|
|
36
|
+
- Two backends in one stack no longer share the stack-scoped Traefik routers, so each gets its own route (#732).
|
|
37
|
+
- `tdk doctor` no longer reports a port another process listens on as free (#691) and links the Tilt UI URL that is actually running (#712).
|
|
38
|
+
- `tdk logs` tells you to run `tdk up` when Tilt is not reachable (#693).
|
|
39
|
+
- Tech-stack validation messages are fully formatted (#690).
|
|
40
|
+
- `tdk --help` and the cheat sheet list `logs`, `eject`, `import` and `mcp` (#727).
|
|
41
|
+
- `tdk ui` gains a Tilt events timeline (#655).
|
|
42
|
+
- Engine: the no-op port replacement pass in `compose.star` is removed (#477).
|
|
43
|
+
- Tests: the generated Tilt and Compose files are locked with golden copies (#689); the engine tests declare their Python packages (#729).
|
|
44
|
+
- Docs: command cheat sheet (#692), `up`/`down`/`status` flags (#660), one product description (#694), quick-start URL fixes (#704, #726), issue-claiming and quick setup with a Starlark recipe (#728).
|
|
45
|
+
- CI: the Biome autofix no longer breaks Lint on every new PR (#685).
|
|
46
|
+
|
|
47
|
+
## 1.3.121 (2026-10-07)
|
|
48
|
+
|
|
49
|
+
- `tdk status` shows readiness per service and marks a service blocked by a failed dependency (#678); `tdk ui` shows the same readiness and names the failed dependency (#679).
|
|
50
|
+
- `tdk up` names the service that failed and what it blocks, and prints `TDK is up.` only once everything is ready (#669). A Tilt resource that is still building is no longer counted as ready (#677).
|
|
51
|
+
- `tdk up` names the host port it wanted, the one it chose and how to force one (#667). A second `tdk up` no longer starts another Tilt on a new port: it prints `Environment is already running` and exits 0, and `--force` replaces the running one (#663).
|
|
52
|
+
- Misspelled stack and resource names get a "did you mean" suggestion (#618).
|
|
53
|
+
- Generated files are written atomically (#668), and their headers say to run `tdk config regenerate` (#680).
|
|
54
|
+
- `tdk ui`: a stack with no known service status shows as unknown, not error (#671).
|
|
55
|
+
- Docs: `tdk doctor --no-ping` and `--ping-timeout` (#659), the MCP agent guide (#675), Codex MCP setup (#674, #676), project history notes (#670, #672); OpenSpec for stabilizing local-dev commands (#662). #665 (drift gate spec) was reverted by #666 after it left conflict markers on `main`.
|
|
56
|
+
|
|
57
|
+
## 1.3.120 (2026-10-07)
|
|
58
|
+
|
|
59
|
+
- Tests only: coverage for the env-validator, file and command helper utilities (#656, #657, #658). No behaviour change.
|
|
60
|
+
|
|
61
|
+
## 1.3.119 (2026-10-06)
|
|
62
|
+
|
|
63
|
+
- Adds a CLI start-up benchmark (#653). No behaviour change.
|
|
64
|
+
|
|
65
|
+
## 1.3.118 (2026-10-06)
|
|
66
|
+
|
|
67
|
+
- A resource that `dependsOn` the shared platform Postgres now starts it (#643, #646).
|
|
68
|
+
- `tdk resource --feature prisma` on a backend also creates a `<api>-migrator` resource that runs `prisma migrate deploy`, and the API depends on it (#649), and `tdk doctor` fails inconsistent Prisma 7 setups (#647, #648).
|
|
69
|
+
- `tdk ui` shows the CLI version and the discovered resources (#638), pages through long lists with the keyboard (#645), and hides the unfinished Events tab (#622).
|
|
70
|
+
- Docs: `TILT_TECH_STACK` version scope (#625); OpenSpec for a NestJS bring-your-own example (#636).
|
|
71
|
+
- CI: conflict-resolution buttons on PRs, spec badges kept on one line (#651).
|
|
72
|
+
|
|
73
|
+
## 1.3.117 (2026-10-06)
|
|
74
|
+
|
|
75
|
+
- CI: repository spell check (#639); AI review buttons also run for fork PRs and render as one line of product badges (#640, #641, #642).
|
|
76
|
+
- Docs: OpenSpec for `dependsOn` starting the shared platform Postgres (#644).
|
|
77
|
+
|
|
78
|
+
## 1.3.116 (2026-10-06)
|
|
79
|
+
|
|
80
|
+
- `tdk ui` adapts its layout to the terminal size (#635) and the resource table columns are clearer (#637).
|
|
81
|
+
- CI: "Write spec" buttons on issue bodies (#632).
|
|
82
|
+
|
|
83
|
+
## 1.3.115 (2026-10-05)
|
|
84
|
+
|
|
85
|
+
- CI: Grok, Claude and Codex review buttons are appended to PR bodies (#626, #627, #629, #630).
|
|
86
|
+
|
|
87
|
+
## 1.3.114 (2026-10-05)
|
|
88
|
+
|
|
89
|
+
- `tdk status` pointed to a `tdk list-stacks` command that does not exist; it now points to `tdk stacks`. `--json` adds the resource count, each stack's resources and the unassigned ones. Fixes #79 (#621).
|
|
90
|
+
|
|
91
|
+
## 1.3.113 (2026-10-05)
|
|
92
|
+
|
|
93
|
+
- Docs: the README demo shows the generated frontend files (#620); generated service files and drift checks are documented (#619).
|
|
94
|
+
|
|
95
|
+
## 1.3.112 (2026-10-05)
|
|
96
|
+
|
|
97
|
+
- `tdk eject` no longer claims files it does not create or prints a command that cannot work. It still writes only `EJECTED.md` (no file is copied, moved or generated; the Tiltfile and engine stay in git-ignored `.tdk/.tdk-out/`, and the per-service Compose files, golden-layer Dockerfile and Traefik file only exist after Tilt has run). `EJECTED.md` no longer lists them under "Keep" and says the Tiltfile still reads `.tdk/project.json` and the `service.json` files. `Next: tilt up` (which finds no Tiltfile at the project root) is replaced by `tilt up -f .tdk/.tdk-out/Tiltfile -- --focus=<stack>`, the form `tdk up` runs. A project that already has an `EJECTED.md` keeps its old text (the file is never overwritten) and is now told so. `--dry-run` headings read `Generated files, left where they are (git-ignored):` and `Files written:`. A command that exports plain Compose files and Dockerfiles does not exist. Fixes #610. (#611)
|
|
98
|
+
|
|
99
|
+
## 1.3.111 (2026-10-05)
|
|
100
|
+
|
|
101
|
+
- `tdk config regenerate` now restores a root `.tiltignore` that TDK wrote (it carries the `SYSTEM-GENERATED BY TDK CLI` header) and that was edited by hand, and prints `Restored: .tiltignore → project root (hand edits discarded)`. Before, it only copied the file when none existed, so `tdk config verify` kept failing with `Out of sync: .tiltignore (run 'tdk config regenerate')` after the advice was followed. A root `.tiltignore` without the header is still never overwritten, and plain `tdk project --yes` still does not overwrite an existing one. Docs: `docs/adopt-tdk.md` now quotes the current `tdk doctor` unknown-field wording. (#615)
|
|
102
|
+
- `tdk doctor` now checks the project's own resource configs for duplicates. Two resources with the same `appName` fail (`Duplicate resource names`, naming both `service.json` paths): the name becomes the Compose service and Traefik router, so they collide, and before nothing reported it. Two backend, mcp or routed bring-your-own resources on the same `port` give a warning, not a failure (`Duplicate resource ports`): service ports are not published on the host and each service has its own container, so the pair can run, but it is usually a copied `service.json`. Frontends, workers, libraries and a missing `port` are ignored. Fixes #76. (#609)
|
|
103
|
+
- `tdk doctor` no longer fails with `N resources without a package.json` for a bring-your-own resource. A bring-your-own resource (`--image`, `--dockerfile` or `buildContext`) is a plain container: its image is pulled or built from its own Dockerfile, never from the generated Dockerfile that copies a `package.json`, so the check was a false positive that made `tdk doctor` (and CI recipes that gate on it) exit non-zero right after wrapping an existing service. Backend, frontend, worker, migrator, mcp, library and sdk resources without a `package.json` still fail; Python, Go and Rust backends were already exempt. The other doctor checks were run on a project with only bring-your-own resources and report nothing. Fixes #599. (#600)
|
|
104
|
+
- A scaffolded frontend now says why `bun run build` / `bun run dev` cannot run on the host before `tdk up`: the `.autogenerated/vite.config.*.autogenerated.ts` files its scripts point at are written by the engine (Tilt) when `tdk up` loads the resource, and neither `tdk resource` nor `tdk config regenerate` creates them. Before, `vite` stopped with an esbuild `Could not resolve` stack trace. New `predev`/`prebuild` scripts print what is missing and how to get it; once the file exists (and inside the engine image build) they pass silently. Existing frontends need the two scripts added by hand. Backend, worker and mcp scaffolds are unchanged. Fixes #592. (#594)
|
|
105
|
+
- `tdk up` now honours `minTdkVersion` from `.tdk/project.json`, like `tdk doctor`. On an older CLI (or a malformed value) it exits 1 before the Docker checks and before Tilt starts, with `tdk X is older than the Y this project requires (minTdkVersion)` and `Run: tdk upgrade`; `--dry-run` reports it the same way. New `tdk up --ignore-version` skips the check with a warning. A project without `minTdkVersion` behaves as before. The check lives in `cli/src/utils/tdk-version.ts`, shared with doctor. (#595)
|
|
106
|
+
- `init-networks` now fails with Docker's own message when a network that does not exist cannot be created. It ran `docker network create X 2>/dev/null && echo ... || true`, so a failure such as `all predefined address pools have been fully subnetted` was reported as `Docker networks initialized` and Postgres and Traefik then failed with `network ... declared as external, but could not be found`. An already existing network (including one another process creates between the check and the create) is still not an error, and a network with incorrect compose labels is still removed first when unused. Fixes #587. (#589)
|
|
107
|
+
- A freshly scaffolded worker now type-checks: its `src/index.ts` typed `Job.payload` as `Record<string, JsonValue>`, but `JsonValue` is a type internal to the CLI that the generated project neither defines nor imports, so `bun run build` failed with `TS2304: Cannot find name 'JsonValue'`. The payload is now `Record<string, unknown>`. Existing workers need the same one-word edit. Fixes #588. (#590)
|
|
108
|
+
- A freshly scaffolded backend, worker or mcp service now builds on the host: its `tsconfig.json` sets `"types": ["node"]`, matching the generated Docker tsconfig. Before, `bun run build` failed with `TS2591: Cannot find name 'process'` because TypeScript 7 no longer auto-includes `@types/*`. Frontend scaffolds are unchanged. Existing services need `"types": ["node"]` added by hand. Closes #581. (#586)
|
|
109
|
+
- The `Dockerfile` that `tdk resource` writes next to `service.json` now follows the service: `PORT`, `EXPOSE` and the health check use the `port` (and `healthCheckPath`) from `service.json` instead of a fixed 3000, the health probe no longer needs `curl` (not in `oven/bun`), `bun.lock` is optional in the `COPY` (a TDK workspace keeps it at the project root, so the old file stopped at `"/bun.lock": not found`), and a header comment says `tdk up` does not build this file (it builds `.autogenerated/Dockerfile.app.autogenerated`). A worker, which declares no health path, gets no HEALTHCHECK. Fixes #579. (#580)
|
|
110
|
+
- `tdk down` now removes what `tdk up <stack>` started. It ran `tilt down` without `--focus`, so the Tiltfile fell back to its default phase and did not register the stack's own compose project: the generated service container (`shop-autogenerated-orders-api-1`) kept running and only Traefik and Postgres were removed. It now passes every stack to the Tiltfile, and it stops the project's own `tilt up` process first (it kept running, and a live Tilt re-creates removed containers). Only a `tilt up` started with this project's Tiltfile is stopped. New `tdk down --prune-networks` also removes the project's Docker networks (`<project>_backend`, `_database`, `_traefik-public`, ...) that no container is attached to; without the flag they are kept, as before. `tdk doctor`'s "all predefined address pools are in use" fix now names it. (#585)
|
|
111
|
+
- `tdk resources --type <type>` filters the list (#616).
|
|
112
|
+
- `tdk resource --yes` no longer prompts for a stack: a new project uses `main`, a single existing stack is reused, and several stacks require `--stack` (#591).
|
|
113
|
+
- `tdk upgrade` of a binary install left `tdk` non-executable (mode 0644); it now sets 0755, and a failed check prints `chmod +x <path>` (#596).
|
|
114
|
+
- Shell completion accepts the shell as a positional argument (#578).
|
|
115
|
+
- Docs: troubleshooting page for tdk and Tilt messages (#612), a GitHub Actions recipe for `tdk config verify` and `tdk up` (#608), how to leave TDK (#607), scope and non-goals for team leads (#577), services spread over several repos (#582), the database is per stack (#584), adoption-docs accuracy sweep (#597).
|
|
116
|
+
- CI: "Shipped in vX" comments on fixed issues after each release (#606), issue claiming (#605), contributor thanks and welcome messages (#598, #613), hall-of-fame issue with kyu/dan ranks (#601, #604).
|
|
117
|
+
|
|
118
|
+
## 1.3.110 (2026-10-05)
|
|
119
|
+
|
|
120
|
+
- `tdk config verify` no longer fails on a root `.tiltignore` the repository already had. `tdk project` never overwrote it, but verify compared it with the generated one and reported `Out of sync: .tiltignore`; it now warns `not generated by TDK, left as is`. A `.tiltignore` carrying TDK's generated header that was edited is still reported. Refs #568. (#574)
|
|
121
|
+
- A repo can pin the oldest CLI it works with: add `"minTdkVersion": "1.3.80"` to `.tdk/project.json`, and `tdk doctor` fails with `Run: tdk upgrade` on an older `tdk` (a value that is not `MAJOR.MINOR.PATCH` also fails). It is a floor, not an exact pin. Documented in `docs/upgrading.md`. Refs #564. (#572)
|
|
122
|
+
- `tdk ui` search shows the match count and a no-matches message (#562).
|
|
123
|
+
- Docs: `SUPPORT.md` for team leads (#575), local Postgres data, reset, seed and snapshot (#573), network calls, secrets and images (#571).
|
|
124
|
+
|
|
125
|
+
## 1.3.109 (2026-10-05)
|
|
126
|
+
|
|
127
|
+
- `tdk ui` replaces the fake 100% loading bar with a spinner (#561).
|
|
128
|
+
- The local loop can be handed over: drift gate, runbook and adopters list (#548).
|
|
129
|
+
- Docs: `tdk-import` 0.1.1 pinned and its release alignment (#558, #559, #560); README install-size badge fixed (#557).
|
|
130
|
+
|
|
131
|
+
## 1.3.108 (2026-10-05)
|
|
132
|
+
|
|
133
|
+
- `tdk resources` and `tdk networks` exit non-zero with the stack-not-found error when `--stack` names a stack that does not exist. Fixes #439 (#551).
|
|
134
|
+
- Docs: `--version` and `--verbose` flags clarified (#555). Tests for `tdk down` projects and stacks (#554).
|
|
135
|
+
|
|
136
|
+
## 1.3.107 (2026-10-05)
|
|
137
|
+
|
|
138
|
+
- `TILT_PORT` is validated before start-up (#550).
|
|
139
|
+
- Shell completions cover every registered command (#556).
|
|
140
|
+
- `tdk ui`: a new status message cancels the previous message's clear timer, so overlapping messages no longer disappear early. Fixes #454 (#553).
|
|
141
|
+
|
|
142
|
+
## 1.3.106 (2026-10-04)
|
|
143
|
+
|
|
144
|
+
- `tdk doctor` warns when a backend or worker applies database migrations from its own start-up (a `start`/`dev` script, a Dockerfile `CMD`/`ENTRYPOINT`, a shell entrypoint or its source: Prisma, Drizzle, Knex, TypeORM, MikroORM, Sequelize, dbmate, Atlas, Alembic). It is a warning, not a failure: such services work, but migrations belong in a `migrator` resource that runs once before the services that depend on it. `migrator` and bring-your-own resources are not checked. (#546)
|
|
145
|
+
- New `tdk mcp`: a stdio MCP server that exposes the `--json` commands to agents (#549).
|
|
146
|
+
- New `tdk logs`: a bounded log snapshot, with `--json` (#542).
|
|
147
|
+
- `tdk stacks --json` and `tdk projects --json` (#541, #544).
|
|
148
|
+
- `tdk up --only` (spike), and readiness no longer waits on Tilt resources that are disabled (#545).
|
|
149
|
+
- CI: `wsl2-smoke` runs less often on pull requests (#543).
|
|
150
|
+
|
|
151
|
+
## 1.3.105 (2026-10-04)
|
|
152
|
+
|
|
153
|
+
- `tdk status --json` reports each service's URL, container port and host port, plus stack ports (#539).
|
|
154
|
+
- TDK detects Dev Container, Codespaces and WebContainer hosts; `tdk up --json` and `tdk down --json` (#534).
|
|
155
|
+
- `tdk ui` suggests existing commands in its empty state (#536).
|
|
156
|
+
- OpenSpec: agent-host runtime contract (#528).
|
|
157
|
+
|
|
158
|
+
## 1.3.104 (2026-10-04)
|
|
159
|
+
|
|
160
|
+
- Bring-your-own services can build from a source tree with `buildContext` (#520, #525).
|
|
161
|
+
- Docs: issue labels and a documentation issue form (#530); install-size badge points at the latest version (#526).
|
|
162
|
+
|
|
163
|
+
## 1.3.103 (2026-10-04)
|
|
164
|
+
|
|
165
|
+
- `tdk import` delegates to the separate `tdk-import` tool (#511, #520, #521).
|
|
166
|
+
- Docs: npm version and size badges (#523).
|
|
167
|
+
|
|
168
|
+
## 1.3.102 (2026-10-04)
|
|
169
|
+
|
|
170
|
+
- Focus only enables `<name>-image` prebuilds that are registered (#522).
|
|
171
|
+
- Go: deferred-start live-reload services prebuild the development target; Fiber, Echo and chi verified (#369, #519).
|
|
172
|
+
|
|
173
|
+
## 1.3.101 (2026-10-04)
|
|
174
|
+
|
|
175
|
+
- Go services can opt in to a live development loop with `"dev": { "liveReload": true }` in `service.json`: edits are copied into the running container and recompiled without an image rebuild, while `go.mod`, `go.sum` and the generated Dockerfile still rebuild the image. The watcher compiles into a staging binary while the old build keeps serving and swaps only on success, so a compile error shows in the Tilt log and the last good build keeps answering (Air, tried first, stopped the app before compiling and left it down for the whole compile; in 2 of 6 edits a Traefik health check then returned 503 for 10 s). Measured on one loaded Mac: median edit-to-ready 1.63 s for the scaffold. The default Go image (`golang:1.23`) now sets `GOTOOLCHAIN=auto`, so a `go.mod` that needs a newer Go, such as Gin 1.12 (`go 1.25`), downloads that toolchain instead of stopping with `requires go >= 1.25`. Offline or air-gapped builds of a go.mod newer than 1.23 still fail, but now at the toolchain download rather than at the version check. `scripts/e2e/go-dev-loop.sh` checks all of this through a real `tdk up`. Refs #369. (#495)
|
|
176
|
+
- Docs: adoption guide for team leads (#499), FAQ for agencies (#503), friendlier issue templates (#502), "Who uses TDK" and `ADOPTERS.md` (#496, #498), governance docs and maintainers check (#488).
|
|
177
|
+
|
|
178
|
+
## 1.3.100 (2026-10-04)
|
|
179
|
+
|
|
180
|
+
- `tdk ui`: Esc at the top level shows a quit hint instead of exiting (#482).
|
|
181
|
+
|
|
182
|
+
## 1.3.99 (2026-10-04)
|
|
183
|
+
|
|
184
|
+
- First version of the opt-in Go dev loop via `dev.liveReload` (#369, #483); replaced by the build-then-swap watcher in 1.3.101.
|
|
185
|
+
- Docs: Japanese and Chinese READMEs (#484).
|
|
186
|
+
- CI: `wsl2-smoke` skipped for docs, BYO-example and TUI-only changes (#487); journey-map workflow fixes (#485, #486).
|
|
187
|
+
|
|
188
|
+
## 1.3.98 (2026-10-03)
|
|
189
|
+
|
|
190
|
+
- Rebuild of 1.3.97 from the same source commit; no change.
|
|
191
|
+
|
|
192
|
+
## 1.3.97 (2026-10-03)
|
|
193
|
+
|
|
194
|
+
- `tdk up` keeps each smoke step's status and response body under `.tdk/smoke/<service>/<step>/` (`latest.json` and `body.txt`, body capped at 64 KiB), plus `last-success.json` and `last-success-body.txt` that a later failure never overwrites, so a regression can be diffed against the last good response. The failure line ends with the record path, and `tdk project` gitignores `.tdk/smoke/`. A new `smoke-e2e` workflow runs `scripts/verify-smoke.sh` and uploads the records. Before its first step a smoke check now waits for the service's health path (`healthCheckPath`, default `/health` for backends) with GETs until it answers something other than a connection error, 404 or 5xx, so a write is no longer the first request to hit a service that is still building; write retry rules are unchanged. (#480)
|
|
195
|
+
- Each `service.json` warning is printed once per command (#479).
|
|
196
|
+
- Stack names are validated, and name errors show the invalid value (#478).
|
|
197
|
+
- `tdk status` checks for a project before printing (#470).
|
|
198
|
+
- `tdk resource` rejects an unknown `--type` instead of prompting (#472).
|
|
199
|
+
- `tdk help <unknown>` reports an unknown command and exits 1 (#473).
|
|
200
|
+
- `tdk ui`: the dead `a` shortcut is gone from the help panel and footer (#475).
|
|
201
|
+
- Frontend framework inventory, picker and meta-framework handoff (#467).
|
|
202
|
+
- Bring-your-own examples: Tornado, Polka, Sanic, Falcon, Starlette, Hapi (#430, #431, #432, #446, #457, #468).
|
|
203
|
+
- Docs: contributor journey map with islands and kyu/dan ranks (#466, #471, #474).
|
|
204
|
+
|
|
205
|
+
## 1.3.96 (2026-10-03)
|
|
206
|
+
|
|
207
|
+
- Rebuild of 1.3.95 from the same source commit; no change.
|
|
208
|
+
|
|
209
|
+
## 1.3.95 (2026-10-03)
|
|
210
|
+
|
|
211
|
+
- New frontend provider: TanStack Router (#234, #420).
|
|
212
|
+
- Bring-your-own examples: Slim (PHP), Actix Web (Rust), Hanami (Ruby) (#422, #424, #426); SvelteKit verified through `tdk up` (#428).
|
|
213
|
+
- Tests for `tdk status` output and options (#14, #427).
|
|
214
|
+
- Release notes no longer repeat changelog text from earlier releases (#418, #419).
|
|
215
|
+
|
|
216
|
+
## 1.3.94 (2026-10-03)
|
|
217
|
+
|
|
218
|
+
- Release workflow starts its version search from the newest published version (#417). No CLI change.
|
|
219
|
+
|
|
220
|
+
## 1.3.93 (2026-10-02)
|
|
221
|
+
|
|
222
|
+
- `service.json` JSON Schema for editor completion and validation (#416).
|
|
223
|
+
- The `service.yaml` mirror is written deterministically (#415).
|
|
224
|
+
|
|
225
|
+
## 1.3.92 (2026-10-02)
|
|
226
|
+
|
|
227
|
+
- New `mcp` resource type for Model Context Protocol servers (#388), treated as an API service by `up`, `networks` and `doctor` (#391), verified with the official MCP SDK client (#406).
|
|
228
|
+
- `tdk up` runs a `smoke` block that checks each service's public URL after start-up (#413, #414).
|
|
229
|
+
- Env: secrets are injected, the shared JWT default is gone, `AUTH_MODE=None` works and params are quoted (#390). The engine parses `.env` in Starlark instead of shelling out to `cat` (#400) and builds one identity URL and auth config for the env file and Compose (#399).
|
|
230
|
+
- Scaffolds write `dependsOn` (not the deprecated `dependencies`) (#409) and `healthCheckPath`, the key the engine reads (#408).
|
|
231
|
+
- `tdk doctor` warns that `dependencies` and `envVars` are deprecated instead of calling them unknown (#401).
|
|
232
|
+
- Turso (libSQL) runs locally as a TDK resource (#386).
|
|
233
|
+
- Bring-your-own examples: create-hono, Elysia, Micronaut, Sinatra, Echo, chi, Strapi, dbmate job (#363, #365, #367, #379, #381, #384, #403, #404).
|
|
234
|
+
- All 8 frontend frameworks are verified through `tdk up` (#412). CI's Test job gets a 10-minute hang guard (#407).
|
|
235
|
+
|
|
236
|
+
## 1.3.91 (2026-10-02)
|
|
237
|
+
|
|
238
|
+
- Native backend frameworks: h3 and Koa (#354, #356).
|
|
239
|
+
- Bring-your-own examples: Symfony and Gin (#358, #360).
|
|
240
|
+
- Verify runs also remove the golden-layer images they build (#352).
|
|
241
|
+
|
|
242
|
+
## 1.3.90 (2026-10-02)
|
|
243
|
+
|
|
244
|
+
- Native backends: NestJS (#350) and Rust (#348).
|
|
245
|
+
- Bring-your-own example: Docusaurus (#346).
|
|
246
|
+
|
|
247
|
+
## 1.3.89 (2026-10-02)
|
|
248
|
+
|
|
249
|
+
- Native backends: Go (#340), Fastify (#317) and Elysia (#315, recovered after it never reached `main`).
|
|
250
|
+
- New frontend provider: vanilla TypeScript (Vite SPA) (#319).
|
|
251
|
+
- Bring-your-own examples: Flask, Rails, SvelteKit, Django, Angular, Next.js, .NET, Laravel, Spring, Phoenix, Deno Fresh (#320, #322, #324, #326, #328, #330, #332, #334, #336, #338, #342); five migration job examples recovered (#316).
|
|
252
|
+
|
|
253
|
+
## 1.3.88 (2026-10-02)
|
|
254
|
+
|
|
255
|
+
- Native backend framework: Express (#298).
|
|
256
|
+
- New frontend providers (Vite SPA): Svelte, Preact, Lit, Solid, Qwik (#260, #261, #276, #277, #296).
|
|
257
|
+
- Bring-your-own: a restart policy so one-shot jobs are not restarted (#275), and verified examples for full-stack-fastapi-template, loco, React Router, Nuxt, Astro, express-generator, Refine, Analog, Bati, Ember, AdonisJS, Mastra and Better-T-Stack, plus a dbmate job and a verify script (#274, #279–#285, #297, #300–#304, #313).
|
|
258
|
+
- The schema accepts open framework and language ids and is published from `main` (#278).
|
|
259
|
+
- Docs: reorganised docs folder and bring-your-own guide (#288, #262, #287); Rsbuild and moon recipes (#286, #295).
|
|
260
|
+
|
|
261
|
+
## 1.3.87 (2026-10-01)
|
|
262
|
+
|
|
263
|
+
- Add an opt-in Python backend: `tdk resource <name> --type backend --language python` scaffolds a FastAPI service (`pyproject.toml`, `src/main.py`, a pytest smoke test) and TDK generates its Docker image (`python:3.12-slim`, with `test` and `production` stages). The choice is saved as `language` in `service.json` only when you pass the flag; omitting it keeps the existing Bun + Hono output byte for byte. Unknown ids and `--language` on non-backend types fail before any file is written. A runnable example is in `examples/one-backend-python`, and the provider contract is in `docs/backend-language-providers.md`. Node.js is not included. (#227)
|
|
25
264
|
- `tdk doctor` no longer reports "resource without a package.json" for a Python backend, and a Python service missing `pyproject.toml` or `src/main.py` now fails early with the missing file named.
|
|
26
|
-
- Live reload now works: Tilt `live_update` sync paths were relative to the project root while Tilt resolves them against `.tdk/.tdk-out`, so they never matched and every source edit rebuilt the image ("Found file(s) not matching any sync"). An edit under `src/` is now copied into the running container without a rebuild, for Bun and Python services. Dependency file changes (`package.json`, `pyproject.toml`) still rebuild the image.
|
|
265
|
+
- Live reload now works: Tilt `live_update` sync paths were relative to the project root while Tilt resolves them against `.tdk/.tdk-out`, so they never matched and every source edit rebuilt the image ("Found file(s) not matching any sync"). An edit under `src/` is now copied into the running container without a rebuild, for Bun and Python services. Dependency file changes (`package.json`, `pyproject.toml`) still rebuild the image. (#228, #230)
|
|
27
266
|
- The service schema (`https://tdk-landscape.github.io/schema.service.json`) gains the `language` field (`bun`, `python`).
|
|
28
267
|
- Fix the routed health URL in the `one-backend` example README.
|
|
268
|
+
- CI: WSL2 landscape gate and native Windows refusal (#220, #222, #223, #224).
|
|
269
|
+
|
|
270
|
+
## 1.3.86 (2026-10-01)
|
|
271
|
+
|
|
272
|
+
- Cold start: the Sablier plugin loads and the cold health URL is found (#219, #217).
|
|
273
|
+
|
|
274
|
+
## 1.3.85 (2026-10-01)
|
|
275
|
+
|
|
276
|
+
- Expanded focus includes deferred images (#210).
|
|
277
|
+
|
|
278
|
+
## 1.3.84 (2026-10-01)
|
|
279
|
+
|
|
280
|
+
- Stack focus includes deferred image builds (#209); the cold-start delay type-checks with `tsc` (#208).
|
|
281
|
+
|
|
282
|
+
## 1.3.83 (2026-10-01)
|
|
283
|
+
|
|
284
|
+
- Docs: README SVG demo restored and public copy aligned (#205, #206).
|
|
285
|
+
|
|
286
|
+
## 1.3.82 (2026-10-01)
|
|
287
|
+
|
|
288
|
+
- Docs: quick-start claims and example E2E ports aligned (#201).
|
|
289
|
+
|
|
290
|
+
## 1.3.81 (2026-10-01)
|
|
291
|
+
|
|
292
|
+
- Host port planning is wired into the CLI at run time (#198).
|
|
293
|
+
- Windows release assets are smoke-tested before a release is published (#199, #200).
|
|
294
|
+
- README: demo, comparison table and benchmark restored (#197).
|
|
29
295
|
|
|
30
296
|
## 1.3.80 (2026-09-30)
|
|
31
297
|
|
package/README.md
CHANGED
|
@@ -13,6 +13,19 @@
|
|
|
13
13
|
|
|
14
14
|
English | [简体中文](docs/README-zh_cn.md) | [繁體中文](docs/README-zh_tw.md) | [日本語](docs/README-ja.md) | [한국어](docs/README-ko.md)
|
|
15
15
|
|
|
16
|
+
### Stop letting AI hallucinate your local infrastructure.
|
|
17
|
+
|
|
18
|
+
LLMs are brilliant at writing application logic, but notoriously terrible at maintaining local infrastructure. Every time your AI rewrites a `Dockerfile`, misconfigures a `Tiltfile`, or breaks an `nginx.conf`, it wastes your developer focus and burns thousands of unnecessary API tokens.
|
|
19
|
+
|
|
20
|
+
**TDK CLI Core** bridges the gap. You write the clean web application logic, and TDK instantly autodetects your stack to generate, link, and orchestrate the local environment for you.
|
|
21
|
+
|
|
22
|
+
### ⚡ Zero-Config Local Stacks in 3 Seconds
|
|
23
|
+
No vendor lock-in. No tedious plumbing. Run a single command to natively orchestrate **72 different integration tiers** including:
|
|
24
|
+
* **Runtimes & Frameworks:** Bun, Node, Python, Go, Rust, React, Vue, Svelte, Elysia, Fastify, NestJS
|
|
25
|
+
* **Databases & Tooling:** Prisma, Drizzle, Atlas, Dbmate
|
|
26
|
+
* **Messaging & Gateway:** NATS, Traefik
|
|
27
|
+
|
|
28
|
+
|
|
16
29
|
TDK CLI — start services on your laptop. It is not a deploy and not a Compose file: define each service in `service.json`, then run `tdk up`. No Kubernetes is needed on the machine.
|
|
17
30
|
|
|
18
31
|
Stability: 1.x local dev. Write `service.json`; TDK generates the local runtime files. See [what TDK writes](docs/generated-files.md) and how to check for drift. Core CLI is MIT and needs no key. Premium is optional.
|
|
@@ -21,6 +34,8 @@ Docker runs the containers. Tilt watches services and live-updates containers wh
|
|
|
21
34
|
|
|
22
35
|
[Website](https://tdk-landscape.github.io/tdk-website/) · [Quickstart](https://tdk-landscape.github.io/tdk-website/docs/quickstart/) · [Examples](https://tdk-landscape.github.io/tdk-website/docs/examples/) · [Awesome TDK](https://github.com/tdk-landscape/awesome-tdk-framework) · [Demo](https://tdk-landscape.github.io/tdk-demo-animation/) · [Report a bug](https://github.com/tdk-landscape/tdk-cli-core/issues)
|
|
23
36
|
|
|
37
|
+
`tdk ui` opens an interactive terminal dashboard for inspecting running services. Move with `↑/↓` or `j/k`, search with `/`, and press `1`–`5` to jump between tabs. See [docs/ui.md](docs/ui.md) for every key binding.
|
|
38
|
+
|
|
24
39
|
## Who uses TDK
|
|
25
40
|
|
|
26
41
|
No teams are listed yet. Be the first: [tell us you use TDK](https://github.com/tdk-landscape/tdk-cli-core/issues/new?template=we-use-tdk.yml) or [add a row to ADOPTERS.md](ADOPTERS.md).
|
|
@@ -90,6 +105,9 @@ curl -fsSL https://tdk-landscape.github.io/install.sh | sh
|
|
|
90
105
|
- Helm is your whole development workflow and you do not want local services on Docker.
|
|
91
106
|
- You do not want `service.json` manifests and generated local configuration.
|
|
92
107
|
|
|
108
|
+
## Troubleshooting
|
|
109
|
+
Set `TDK_DEBUG=1` before running `tdk up --verbose` to include Starlark debug logs in Tilt output.
|
|
110
|
+
|
|
93
111
|
## Docs
|
|
94
112
|
|
|
95
113
|
- [CLI command cheat sheet](cli/README.md#cheat-sheet)
|
|
@@ -149,7 +167,7 @@ Core stays free. Premium is a separate key for the extras above; no key required
|
|
|
149
167
|
|
|
150
168
|
## Contributing and license
|
|
151
169
|
|
|
152
|
-
Contributions are welcome. Start with [CONTRIBUTING.md](CONTRIBUTING.md) and the [contributor guide](docs/contributing/README.md). Report security issues using [SECURITY.md](SECURITY.md).
|
|
170
|
+
Contributions are welcome. Start with [CONTRIBUTING.md](CONTRIBUTING.md) and the [contributor guide](docs/contributing/README.md). To review pull requests, see [Review a pull request](docs/contributing/04-review-a-pr.md). Report security issues using [SECURITY.md](SECURITY.md).
|
|
153
171
|
|
|
154
172
|
TDK is MIT-licensed; see [LICENSE](LICENSE). The [license boundary](GOVERNANCE.md#license-boundary-and-donation-scope) says which code is MIT and which is downloaded with a key.
|
|
155
173
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { execFileSync, execSync } from "node:child_process";
|
|
2
2
|
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
3
|
-
import {
|
|
3
|
+
import { join, normalize, relative } from "node:path";
|
|
4
4
|
import chalk from "chalk";
|
|
5
5
|
import { Command } from "commander";
|
|
6
6
|
import { hasVerdaccioLicense } from "../generator/extension-fetch.js";
|
|
@@ -10,6 +10,7 @@ import { MASTER_CONFIG_FILES, REQUIRED_PACKAGE_SCRIPTS } from "../utils/constant
|
|
|
10
10
|
import { isPathDiscovered, readDiscoveryPaths } from "../utils/discovery-paths.js";
|
|
11
11
|
import { collectDoctorChecks, createDoctorReport, getDoctorExitCode, } from "../utils/doctor-report.js";
|
|
12
12
|
import { checkHealthRoutes, checkIngressPorts, checkPrivateNpmRegistry, checkTiltResourceHealth, projectConfigEnablesVerdaccio, summarizeServiceProbes, } from "../utils/doctor-runtime.js";
|
|
13
|
+
import { checkStarlarkLoadExports } from "../utils/doctor-starlark.js";
|
|
13
14
|
import { checkDockerNetworkCapacity, checkDuplicateResourceNames, checkDuplicateResourcePorts, checkFrontendBackendUrls, checkMigrationsInApi, checkNatsBroker, checkPrismaConsistency, checkResourcePackageJson, checkServiceUrlPorts, checkSharedPlatformPostgres, checkSharedStackRoutes, checkTiltInstances, } from "../utils/doctor-wiring.js";
|
|
14
15
|
import { validateEnvFile } from "../utils/env-validator.js";
|
|
15
16
|
import { execAsync, isExecTimeout } from "../utils/exec-async.js";
|
|
@@ -24,6 +25,7 @@ import { discoverResourcesFromRoot } from "../utils/services.js";
|
|
|
24
25
|
import { evaluateTdkVersionFloor } from "../utils/tdk-version.js";
|
|
25
26
|
import { findOnPath } from "../utils/which.js";
|
|
26
27
|
export { checkIngressPorts, checkPrivateNpmRegistry, checkTiltResourceHealth, summarizeServiceProbes, summarizeTiltBuildError, } from "../utils/doctor-runtime.js";
|
|
28
|
+
export { checkStarlarkLoadExports };
|
|
27
29
|
// A wedged Docker daemon makes `docker ps` block forever instead of failing,
|
|
28
30
|
// and doctor is exactly the tool people run when their environment is broken.
|
|
29
31
|
const EXEC_TIMEOUT_MS = 10_000;
|
|
@@ -567,132 +569,6 @@ export function checkGeneratedProjectRuntimeAssets() {
|
|
|
567
569
|
fix: "Run `tdk project --yes` (or `tdk config regenerate`) with an updated TDK. `tdk up` also refreshes these assets before starting Tilt.",
|
|
568
570
|
};
|
|
569
571
|
}
|
|
570
|
-
function findPrivateStarlarkLoadExports(content) {
|
|
571
|
-
const privateExports = new Set();
|
|
572
|
-
const loadCallPattern = /^load\s*\(([\s\S]*?)\)/gm;
|
|
573
|
-
for (const loadMatch of content.matchAll(loadCallPattern)) {
|
|
574
|
-
const args = loadMatch[1] ?? "";
|
|
575
|
-
const quotedValuePattern = /["']([^"']+)["']/g;
|
|
576
|
-
const quotedValues = Array.from(args.matchAll(quotedValuePattern), (match) => match[1]);
|
|
577
|
-
// First quoted arg is the module path. Later quoted args are exported names
|
|
578
|
-
// or alias targets, and Starlark refuses to export names beginning with "_".
|
|
579
|
-
for (const value of quotedValues.slice(1)) {
|
|
580
|
-
if (value.startsWith("_")) {
|
|
581
|
-
privateExports.add(value);
|
|
582
|
-
}
|
|
583
|
-
}
|
|
584
|
-
}
|
|
585
|
-
return Array.from(privateExports).sort();
|
|
586
|
-
}
|
|
587
|
-
function resolveStarlarkLoadTarget(file, modulePath, projectRoot) {
|
|
588
|
-
if (modulePath === "ext://tdk-cli") {
|
|
589
|
-
return join(projectRoot, ".tdk", ".tdk-out", "tdk-cli-ext", "Tiltfile");
|
|
590
|
-
}
|
|
591
|
-
if (modulePath.startsWith(".") || (!modulePath.includes("://") && !modulePath.startsWith("@"))) {
|
|
592
|
-
return normalize(join(dirname(file), modulePath));
|
|
593
|
-
}
|
|
594
|
-
return null;
|
|
595
|
-
}
|
|
596
|
-
function findMissingRelativeStarlarkLoads(file, content, projectRoot) {
|
|
597
|
-
const missing = [];
|
|
598
|
-
const loadCallPattern = /^load\s*\(([\s\S]*?)\)/gm;
|
|
599
|
-
for (const loadMatch of content.matchAll(loadCallPattern)) {
|
|
600
|
-
const args = loadMatch[1] ?? "";
|
|
601
|
-
const moduleMatch = args.match(/["']([^"']+)["']/);
|
|
602
|
-
const modulePath = moduleMatch?.[1];
|
|
603
|
-
if (!modulePath) {
|
|
604
|
-
continue;
|
|
605
|
-
}
|
|
606
|
-
const resolved = resolveStarlarkLoadTarget(file, modulePath, projectRoot);
|
|
607
|
-
if (!resolved) {
|
|
608
|
-
continue;
|
|
609
|
-
}
|
|
610
|
-
if (!existsSync(resolved)) {
|
|
611
|
-
missing.push(`${file}: ${modulePath} -> ${resolved}`);
|
|
612
|
-
}
|
|
613
|
-
}
|
|
614
|
-
return missing;
|
|
615
|
-
}
|
|
616
|
-
function findRelativeStarlarkLoadTargets(file, content, projectRoot) {
|
|
617
|
-
const targets = [];
|
|
618
|
-
const loadCallPattern = /^load\s*\(([\s\S]*?)\)/gm;
|
|
619
|
-
for (const loadMatch of content.matchAll(loadCallPattern)) {
|
|
620
|
-
const args = loadMatch[1] ?? "";
|
|
621
|
-
const moduleMatch = args.match(/["']([^"']+)["']/);
|
|
622
|
-
const modulePath = moduleMatch?.[1];
|
|
623
|
-
if (modulePath) {
|
|
624
|
-
const target = resolveStarlarkLoadTarget(file, modulePath, projectRoot);
|
|
625
|
-
if (target) {
|
|
626
|
-
targets.push(target);
|
|
627
|
-
}
|
|
628
|
-
}
|
|
629
|
-
}
|
|
630
|
-
return targets;
|
|
631
|
-
}
|
|
632
|
-
function collectReachableStarlarkFiles(entryFile, projectRoot) {
|
|
633
|
-
const visited = new Set();
|
|
634
|
-
const pending = [entryFile];
|
|
635
|
-
while (pending.length > 0) {
|
|
636
|
-
const file = pending.pop();
|
|
637
|
-
if (!file || visited.has(file) || !existsSync(file)) {
|
|
638
|
-
continue;
|
|
639
|
-
}
|
|
640
|
-
visited.add(file);
|
|
641
|
-
const content = readFileSync(file, "utf-8");
|
|
642
|
-
for (const target of findRelativeStarlarkLoadTargets(file, content, projectRoot)) {
|
|
643
|
-
if (!visited.has(target)) {
|
|
644
|
-
pending.push(target);
|
|
645
|
-
}
|
|
646
|
-
}
|
|
647
|
-
}
|
|
648
|
-
return Array.from(visited).sort();
|
|
649
|
-
}
|
|
650
|
-
export function checkStarlarkLoadExports() {
|
|
651
|
-
const projectRoot = findProjectRoot() ?? process.cwd();
|
|
652
|
-
const entryFile = join(projectRoot, ".tdk", ".tdk-out", "Tiltfile");
|
|
653
|
-
if (!existsSync(entryFile)) {
|
|
654
|
-
return {
|
|
655
|
-
name: "Starlark Load Exports",
|
|
656
|
-
didPass: true,
|
|
657
|
-
isSkipped: true,
|
|
658
|
-
message: "No generated Tiltfile to check",
|
|
659
|
-
};
|
|
660
|
-
}
|
|
661
|
-
const privateExportProblems = [];
|
|
662
|
-
const missingLoadProblems = [];
|
|
663
|
-
const reachableFiles = collectReachableStarlarkFiles(entryFile, projectRoot);
|
|
664
|
-
for (const file of reachableFiles) {
|
|
665
|
-
const content = readFileSync(file, "utf-8");
|
|
666
|
-
const privateExports = findPrivateStarlarkLoadExports(content);
|
|
667
|
-
if (privateExports.length > 0) {
|
|
668
|
-
privateExportProblems.push(`${file}: ${privateExports.join(", ")}`);
|
|
669
|
-
}
|
|
670
|
-
for (const missingLoad of findMissingRelativeStarlarkLoads(file, content, projectRoot)) {
|
|
671
|
-
missingLoadProblems.push(missingLoad);
|
|
672
|
-
}
|
|
673
|
-
}
|
|
674
|
-
if (privateExportProblems.length === 0 && missingLoadProblems.length === 0) {
|
|
675
|
-
const fileCount = formatCount(reachableFiles.length, "reachable Starlark file");
|
|
676
|
-
return {
|
|
677
|
-
name: "Starlark Load Exports",
|
|
678
|
-
didPass: true,
|
|
679
|
-
message: `${fileCount} ${reachableFiles.length === 1 ? "has" : "have"} valid load exports and paths`,
|
|
680
|
-
};
|
|
681
|
-
}
|
|
682
|
-
const sections = [];
|
|
683
|
-
if (privateExportProblems.length > 0) {
|
|
684
|
-
sections.push(`Private exported symbols:\n ${privateExportProblems.join("\n ")}`);
|
|
685
|
-
}
|
|
686
|
-
if (missingLoadProblems.length > 0) {
|
|
687
|
-
sections.push(`Missing relative load targets:\n ${missingLoadProblems.join("\n ")}`);
|
|
688
|
-
}
|
|
689
|
-
return {
|
|
690
|
-
name: "Starlark Load Exports",
|
|
691
|
-
didPass: false,
|
|
692
|
-
message: `Starlark load() issues will stop Tilt before services start:\n ${sections.join("\n\n ")}`,
|
|
693
|
-
fix: "Regenerate with a current TDK (`tdk config regenerate`). If the issue remains, rename loaded symbols without leading underscores and update stale load paths.",
|
|
694
|
-
};
|
|
695
|
-
}
|
|
696
572
|
function checkStartupScripts() {
|
|
697
573
|
const projectRoot = findProjectRoot() ?? process.cwd();
|
|
698
574
|
const resources = discoverResourcesFromRoot(projectRoot);
|
|
@@ -3,8 +3,9 @@ import { Command } from "commander";
|
|
|
3
3
|
import { readProjectConfig } from "../generator/template-engine.js";
|
|
4
4
|
import { handleDryRun } from "../utils/command-helpers.js";
|
|
5
5
|
import { pruneProjectNetworks, stopProjectTiltUp, waitForTiltUpExit, } from "../utils/down-cleanup.js";
|
|
6
|
-
import { handleTiltFailure, withTiltCheck } from "../utils/errors.js";
|
|
6
|
+
import { errorFactories, handleTiltFailure, withTiltCheck } from "../utils/errors.js";
|
|
7
7
|
import { createJsonEmitter } from "../utils/json-output.js";
|
|
8
|
+
import { writeMachineError } from "../utils/machine-output.js";
|
|
8
9
|
import { findProjectRoot } from "../utils/paths.js";
|
|
9
10
|
import { discoverResources, discoverStacks } from "../utils/services.js";
|
|
10
11
|
import { buildTiltDownArgs, getTiltfilePath, runTilt } from "../utils/tilt.js";
|
|
@@ -48,6 +49,12 @@ export const downCommand = new Command("down")
|
|
|
48
49
|
.option("--dry-run", "Show what would be stopped without stopping", false)
|
|
49
50
|
.option("--json", "Print one JSON object on stdout; implies quiet human output", false)
|
|
50
51
|
.action(async (options) => {
|
|
52
|
+
if (!findProjectRoot()) {
|
|
53
|
+
const projectRootError = errorFactories.notInProject();
|
|
54
|
+
if (options.json)
|
|
55
|
+
writeMachineError(projectRootError);
|
|
56
|
+
projectRootError.exit();
|
|
57
|
+
}
|
|
51
58
|
const emit = options.json ? createJsonEmitter("DOWN_FAILED", "tdk down") : undefined;
|
|
52
59
|
await withTiltCheck(async () => {
|
|
53
60
|
if (emit && options.dryRun) {
|
|
@@ -3,7 +3,7 @@ import { join } from "node:path";
|
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
import { Command } from "commander";
|
|
5
5
|
import { confirmOrCancel } from "../utils/command-helpers.js";
|
|
6
|
-
import { runCommand } from "../utils/errors.js";
|
|
6
|
+
import { errorFactories, runCommand } from "../utils/errors.js";
|
|
7
7
|
import { findProjectRoot } from "../utils/paths.js";
|
|
8
8
|
// Same location `tdk up` hands to Tilt (see getTiltfilePath in utils/tilt.ts), relative to the project root.
|
|
9
9
|
export const TILTFILE_RELATIVE_PATH = ".tdk/.tdk-out/Tiltfile";
|
|
@@ -48,7 +48,7 @@ export const ejectCommand = new Command("eject")
|
|
|
48
48
|
await runCommand(async () => {
|
|
49
49
|
const projectRoot = findProjectRoot();
|
|
50
50
|
if (!projectRoot) {
|
|
51
|
-
throw
|
|
51
|
+
throw errorFactories.notInProject();
|
|
52
52
|
}
|
|
53
53
|
const generatedPaths = [".tdk/.tdk-out"];
|
|
54
54
|
const presentPaths = generatedPaths.filter((path) => existsSync(join(projectRoot, path)));
|