@tdk-landscape/tdk-cli-core 1.3.49 → 1.3.51
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/.claude/skills/layer-autoresearch/SKILL.md +48 -0
- package/.claude/skills/tdk-troubleshoot/SKILL.md +222 -0
- package/.github/ISSUE_TEMPLATE/bug_report.yml +40 -0
- package/.github/ISSUE_TEMPLATE/config.yml +8 -0
- package/.github/ISSUE_TEMPLATE/feature_request.yml +18 -0
- package/.github/dependabot.yml +33 -0
- package/.github/pull_request_template.md +5 -0
- package/.github/workflows/ci.yml +187 -0
- package/.github/workflows/release-binaries.yml +19 -9
- package/.github/zizmor.yml +9 -0
- package/CODE_OF_CONDUCT.md +9 -0
- package/CONTRIBUTING.md +42 -0
- package/LICENSE +21 -0
- package/README.md +151 -0
- package/SECURITY.md +17 -0
- package/benchmarks/results/container-scale-2026-09-25T20-54-49-736Z.json +45 -0
- package/benchmarks/results/container-scale-2026-09-25T21-01-20-540Z.json +150 -0
- package/benchmarks/results/container-scale-2026-09-25T21-15-01-441Z.json +73 -0
- package/benchmarks/results/container-scale-2026-09-25T22-09-01-630Z.json +77 -0
- package/benchmarks/results/container-scale-2026-09-25T22-18-28-371Z.json +202 -0
- package/cli/README.md +25 -0
- package/cli/biome.json +1 -1
- package/cli/dist/cli.d.ts +3 -0
- package/cli/dist/cli.d.ts.map +1 -0
- package/cli/dist/cli.js +64 -0
- package/cli/dist/cli.js.map +1 -0
- package/cli/dist/commands/completion.d.ts +3 -0
- package/cli/dist/commands/completion.d.ts.map +1 -0
- package/cli/dist/commands/completion.js +294 -0
- package/cli/dist/commands/completion.js.map +1 -0
- package/cli/dist/commands/config.d.ts +3 -0
- package/cli/dist/commands/config.d.ts.map +1 -0
- package/cli/dist/commands/config.js +231 -0
- package/cli/dist/commands/config.js.map +1 -0
- package/cli/dist/commands/doctor.d.ts +19 -0
- package/cli/dist/commands/doctor.d.ts.map +1 -0
- package/cli/dist/commands/doctor.js +745 -0
- package/cli/dist/commands/doctor.js.map +1 -0
- package/cli/dist/commands/down.d.ts +3 -0
- package/cli/dist/commands/down.d.ts.map +1 -0
- package/cli/dist/commands/down.js +32 -0
- package/cli/dist/commands/down.js.map +1 -0
- package/cli/dist/commands/help.d.ts +2 -0
- package/cli/dist/commands/help.d.ts.map +1 -0
- package/cli/dist/commands/help.js +138 -0
- package/cli/dist/commands/help.js.map +1 -0
- package/cli/dist/commands/networks.d.ts +3 -0
- package/cli/dist/commands/networks.d.ts.map +1 -0
- package/cli/dist/commands/networks.js +260 -0
- package/cli/dist/commands/networks.js.map +1 -0
- package/cli/dist/commands/project.d.ts +3 -0
- package/cli/dist/commands/project.d.ts.map +1 -0
- package/cli/dist/commands/project.js +370 -0
- package/cli/dist/commands/project.js.map +1 -0
- package/cli/dist/commands/projects.d.ts +3 -0
- package/cli/dist/commands/projects.d.ts.map +1 -0
- package/cli/dist/commands/projects.js +71 -0
- package/cli/dist/commands/projects.js.map +1 -0
- package/cli/dist/commands/resource.d.ts +69 -0
- package/cli/dist/commands/resource.d.ts.map +1 -0
- package/cli/dist/commands/resource.js +579 -0
- package/cli/dist/commands/resource.js.map +1 -0
- package/cli/dist/commands/resources.d.ts +3 -0
- package/cli/dist/commands/resources.d.ts.map +1 -0
- package/cli/dist/commands/resources.js +73 -0
- package/cli/dist/commands/resources.js.map +1 -0
- package/cli/dist/commands/stack.d.ts +3 -0
- package/cli/dist/commands/stack.d.ts.map +1 -0
- package/cli/dist/commands/stack.js +97 -0
- package/cli/dist/commands/stack.js.map +1 -0
- package/cli/dist/commands/stacks.d.ts +3 -0
- package/cli/dist/commands/stacks.d.ts.map +1 -0
- package/cli/dist/commands/stacks.js +43 -0
- package/cli/dist/commands/stacks.js.map +1 -0
- package/cli/dist/commands/status.d.ts +3 -0
- package/cli/dist/commands/status.d.ts.map +1 -0
- package/cli/dist/commands/status.js +71 -0
- package/cli/dist/commands/status.js.map +1 -0
- package/cli/dist/commands/ui.d.ts +3 -0
- package/cli/dist/commands/ui.d.ts.map +1 -0
- package/cli/dist/commands/ui.js +445 -0
- package/cli/dist/commands/ui.js.map +1 -0
- package/cli/dist/commands/up.d.ts +3 -0
- package/cli/dist/commands/up.d.ts.map +1 -0
- package/cli/dist/commands/up.js +124 -0
- package/cli/dist/commands/up.js.map +1 -0
- package/cli/dist/commands/upgrade.d.ts +11 -0
- package/cli/dist/commands/upgrade.d.ts.map +1 -0
- package/cli/dist/commands/upgrade.js +496 -0
- package/cli/dist/commands/upgrade.js.map +1 -0
- package/cli/dist/commands/version.d.ts +3 -0
- package/cli/dist/commands/version.d.ts.map +1 -0
- package/cli/dist/commands/version.js +9 -0
- package/cli/dist/commands/version.js.map +1 -0
- package/cli/dist/components/Accessible.d.ts +8 -0
- package/cli/dist/components/Accessible.d.ts.map +1 -0
- package/cli/dist/components/Accessible.js +10 -0
- package/cli/dist/components/Accessible.js.map +1 -0
- package/cli/dist/components/BaseTooltip.d.ts +4 -0
- package/cli/dist/components/BaseTooltip.d.ts.map +1 -0
- package/cli/dist/components/BaseTooltip.js +28 -0
- package/cli/dist/components/BaseTooltip.js.map +1 -0
- package/cli/dist/components/DetailPanel.d.ts +4 -0
- package/cli/dist/components/DetailPanel.d.ts.map +1 -0
- package/cli/dist/components/DetailPanel.js +18 -0
- package/cli/dist/components/DetailPanel.js.map +1 -0
- package/cli/dist/components/FileTree.d.ts +4 -0
- package/cli/dist/components/FileTree.d.ts.map +1 -0
- package/cli/dist/components/FileTree.js +47 -0
- package/cli/dist/components/FileTree.js.map +1 -0
- package/cli/dist/components/ResourceSelectInput.d.ts +4 -0
- package/cli/dist/components/ResourceSelectInput.d.ts.map +1 -0
- package/cli/dist/components/ResourceSelectInput.js +7 -0
- package/cli/dist/components/ResourceSelectInput.js.map +1 -0
- package/cli/dist/components/ResourceTable.d.ts +4 -0
- package/cli/dist/components/ResourceTable.d.ts.map +1 -0
- package/cli/dist/components/ResourceTable.js +18 -0
- package/cli/dist/components/ResourceTable.js.map +1 -0
- package/cli/dist/components/TabBar.d.ts +4 -0
- package/cli/dist/components/TabBar.d.ts.map +1 -0
- package/cli/dist/components/TabBar.js +17 -0
- package/cli/dist/components/TabBar.js.map +1 -0
- package/cli/dist/components/Tooltip.d.ts +12 -0
- package/cli/dist/components/Tooltip.d.ts.map +1 -0
- package/cli/dist/components/Tooltip.js +12 -0
- package/cli/dist/components/Tooltip.js.map +1 -0
- package/cli/dist/components/index.d.ts +8 -0
- package/cli/dist/components/index.d.ts.map +1 -0
- package/cli/dist/components/index.js +8 -0
- package/cli/dist/components/index.js.map +1 -0
- package/cli/dist/config/platform-standards.d.ts +159 -0
- package/cli/dist/config/platform-standards.d.ts.map +1 -0
- package/cli/dist/config/platform-standards.js +181 -0
- package/cli/dist/config/platform-standards.js.map +1 -0
- package/cli/dist/generator/extension-fetch.d.ts +25 -0
- package/cli/dist/generator/extension-fetch.d.ts.map +1 -0
- package/cli/dist/generator/extension-fetch.js +259 -0
- package/cli/dist/generator/extension-fetch.js.map +1 -0
- package/cli/dist/generator/template-engine.d.ts +62 -0
- package/cli/dist/generator/template-engine.d.ts.map +1 -0
- package/cli/dist/generator/template-engine.js +623 -0
- package/cli/dist/generator/template-engine.js.map +1 -0
- package/cli/dist/index.d.ts +11 -0
- package/cli/dist/index.d.ts.map +1 -0
- package/cli/dist/index.js +11 -0
- package/cli/dist/index.js.map +1 -0
- package/cli/dist/types/index.d.ts +257 -0
- package/cli/dist/types/index.d.ts.map +1 -0
- package/cli/dist/types/index.js +17 -0
- package/cli/dist/types/index.js.map +1 -0
- package/cli/dist/utils/cache.d.ts +19 -0
- package/cli/dist/utils/cache.d.ts.map +1 -0
- package/cli/dist/utils/cache.js +64 -0
- package/cli/dist/utils/cache.js.map +1 -0
- package/cli/dist/utils/command-helpers.d.ts +17 -0
- package/cli/dist/utils/command-helpers.d.ts.map +1 -0
- package/cli/dist/utils/command-helpers.js +41 -0
- package/cli/dist/utils/command-helpers.js.map +1 -0
- package/cli/dist/utils/constants.d.ts +53 -0
- package/cli/dist/utils/constants.d.ts.map +1 -0
- package/cli/dist/utils/constants.js +115 -0
- package/cli/dist/utils/constants.js.map +1 -0
- package/cli/dist/utils/discovery-context.d.ts +4 -0
- package/cli/dist/utils/discovery-context.d.ts.map +1 -0
- package/cli/dist/utils/discovery-context.js +39 -0
- package/cli/dist/utils/discovery-context.js.map +1 -0
- package/cli/dist/utils/docker.d.ts +4 -0
- package/cli/dist/utils/docker.d.ts.map +1 -0
- package/cli/dist/utils/docker.js +19 -0
- package/cli/dist/utils/docker.js.map +1 -0
- package/cli/dist/utils/doctor-runtime.d.ts +81 -0
- package/cli/dist/utils/doctor-runtime.d.ts.map +1 -0
- package/cli/dist/utils/doctor-runtime.js +498 -0
- package/cli/dist/utils/doctor-runtime.js.map +1 -0
- package/cli/dist/utils/env-validator.d.ts +15 -0
- package/cli/dist/utils/env-validator.d.ts.map +1 -0
- package/cli/dist/utils/env-validator.js +109 -0
- package/cli/dist/utils/env-validator.js.map +1 -0
- package/cli/dist/utils/errors.d.ts +31 -0
- package/cli/dist/utils/errors.d.ts.map +1 -0
- package/cli/dist/utils/errors.js +140 -0
- package/cli/dist/utils/errors.js.map +1 -0
- package/cli/dist/utils/file-helpers.d.ts +14 -0
- package/cli/dist/utils/file-helpers.d.ts.map +1 -0
- package/cli/dist/utils/file-helpers.js +45 -0
- package/cli/dist/utils/file-helpers.js.map +1 -0
- package/cli/dist/utils/formatting.d.ts +30 -0
- package/cli/dist/utils/formatting.d.ts.map +1 -0
- package/cli/dist/utils/formatting.js +164 -0
- package/cli/dist/utils/formatting.js.map +1 -0
- package/cli/dist/utils/paths.d.ts +3 -0
- package/cli/dist/utils/paths.d.ts.map +1 -0
- package/cli/dist/utils/paths.js +41 -0
- package/cli/dist/utils/paths.js.map +1 -0
- package/cli/dist/utils/port-assignment.d.ts +6 -0
- package/cli/dist/utils/port-assignment.d.ts.map +1 -0
- package/cli/dist/utils/port-assignment.js +81 -0
- package/cli/dist/utils/port-assignment.js.map +1 -0
- package/cli/dist/utils/project-features.d.ts +23 -0
- package/cli/dist/utils/project-features.d.ts.map +1 -0
- package/cli/dist/utils/project-features.js +98 -0
- package/cli/dist/utils/project-features.js.map +1 -0
- package/cli/dist/utils/project-templates.d.ts +7 -0
- package/cli/dist/utils/project-templates.d.ts.map +1 -0
- package/cli/dist/utils/project-templates.js +24 -0
- package/cli/dist/utils/project-templates.js.map +1 -0
- package/cli/dist/utils/prompt.d.ts +28 -0
- package/cli/dist/utils/prompt.d.ts.map +1 -0
- package/cli/dist/utils/prompt.js +79 -0
- package/cli/dist/utils/prompt.js.map +1 -0
- package/cli/dist/utils/resource-features.d.ts +29 -0
- package/cli/dist/utils/resource-features.d.ts.map +1 -0
- package/cli/dist/utils/resource-features.js +175 -0
- package/cli/dist/utils/resource-features.js.map +1 -0
- package/cli/dist/utils/service-urls.d.ts +30 -0
- package/cli/dist/utils/service-urls.d.ts.map +1 -0
- package/cli/dist/utils/service-urls.js +93 -0
- package/cli/dist/utils/service-urls.js.map +1 -0
- package/cli/dist/utils/services.d.ts +18 -0
- package/cli/dist/utils/services.d.ts.map +1 -0
- package/cli/dist/utils/services.js +292 -0
- package/cli/dist/utils/services.js.map +1 -0
- package/cli/dist/utils/stack-features.d.ts +22 -0
- package/cli/dist/utils/stack-features.d.ts.map +1 -0
- package/cli/dist/utils/stack-features.js +13 -0
- package/cli/dist/utils/stack-features.js.map +1 -0
- package/cli/dist/utils/tar.d.ts +7 -0
- package/cli/dist/utils/tar.d.ts.map +1 -0
- package/cli/dist/utils/tar.js +21 -0
- package/cli/dist/utils/tar.js.map +1 -0
- package/cli/dist/utils/tilt.d.ts +20 -0
- package/cli/dist/utils/tilt.d.ts.map +1 -0
- package/cli/dist/utils/tilt.js +95 -0
- package/cli/dist/utils/tilt.js.map +1 -0
- package/cli/dist/utils/validation.d.ts +16 -0
- package/cli/dist/utils/validation.d.ts.map +1 -0
- package/cli/dist/utils/validation.js +58 -0
- package/cli/dist/utils/validation.js.map +1 -0
- package/cli/package.json +11 -12
- package/cli/src/commands/__tests__/always-enabled-infra.test.ts +2 -8
- package/cli/src/commands/__tests__/doctor.test.ts +181 -8
- package/cli/src/commands/__tests__/phases-model.test.ts +2 -4
- package/cli/src/commands/__tests__/project-resource-features-e2e.test.ts +4 -24
- package/cli/src/commands/__tests__/saas-starter-integration.test.ts +8 -10
- package/cli/src/commands/__tests__/stack-features-e2e.test.ts +10 -4
- package/cli/src/commands/__tests__/upgrade.test.ts +23 -13
- package/cli/src/commands/doctor.ts +136 -0
- package/cli/src/commands/help.ts +13 -3
- package/cli/src/commands/project.ts +11 -14
- package/cli/src/commands/projects.ts +2 -2
- package/cli/src/commands/up.ts +13 -4
- package/cli/src/commands/upgrade.ts +11 -4
- package/cli/src/config/platform-standards.test.ts +6 -6
- package/cli/src/generator/__tests__/extension-fetch.test.ts +36 -14
- package/cli/src/generator/extension-fetch.ts +12 -5
- package/cli/src/generator/template-engine.ts +19 -21
- package/cli/src/types/index.ts +2 -0
- package/cli/src/utils/__tests__/tilt.test.ts +29 -0
- package/cli/src/utils/constants.ts +4 -0
- package/cli/src/utils/doctor-runtime.ts +67 -27
- package/cli/src/utils/env-validator.ts +2 -2
- package/cli/src/utils/project-templates.ts +2 -1
- package/cli/src/utils/prompt.ts +2 -4
- package/cli/src/utils/resource-features.ts +10 -4
- package/cli/src/utils/services.ts +2 -1
- package/cli/src/utils/tilt.ts +20 -0
- package/docs/demo.svg +217 -0
- package/engine/assets/docker/wake-gateway/Dockerfile +27 -0
- package/engine/assets/docker/wake-gateway/decide.test.ts +133 -0
- package/engine/assets/docker/wake-gateway/decide.ts +105 -0
- package/engine/assets/docker/wake-gateway/server.ts +311 -0
- package/engine/topologies/platform/docker/build/golden_image_dockerfile.star +13 -23
- package/engine/topologies/platform/docker/compose/compose.star +7 -14
- package/engine/topologies/platform/docker/compose/compose_helpers.star +1 -1
- package/engine/topologies/platform/docker/compose/traefik_standalone.star +66 -6
- package/engine/topologies/platform/docker/config/healthcheck.star +56 -0
- package/engine/topologies/platform/docker/constants.star +10 -0
- package/engine/topologies/platform/docker/layers/l1_base_layers.star +1 -1
- package/engine/topologies/platform/docker/layers/l4_runtime_layers.star +55 -20
- package/engine/topologies/platform/docker/networking/traefik_static_routes.star +161 -0
- package/engine/topologies/tilt/generators/typescript/backend_tsconfig.star +2 -2
- package/engine/topologies/tilt/generators/typescript/frontend_tsconfig.star +1 -1
- package/engine/topologies/tilt/manifest/schema.star +6 -0
- package/engine/topologies/tilt/manifest/validator.star +16 -0
- package/engine/topologies/tilt/resources/orchestrator/apply_compose_resource_registration.star +143 -9
- package/engine/topologies/tilt/resources/orchestrator/builders/typescript.star +12 -6
- package/engine/topologies/tilt/resources/orchestrator/generators/manifest_resource.star +2 -1
- package/knip.json +1 -1
- package/openspec/changes/optimize-runtime-docker-layers/.openspec.yaml +3 -0
- package/openspec/changes/optimize-runtime-docker-layers/design.md +81 -0
- package/openspec/changes/optimize-runtime-docker-layers/proposal.md +44 -0
- package/openspec/changes/optimize-runtime-docker-layers/specs/runtime-container-footprint/spec.md +79 -0
- package/openspec/changes/optimize-runtime-docker-layers/tasks.md +36 -0
- package/openspec/changes/prioritized-cold-start/.openspec.yaml +4 -0
- package/openspec/changes/prioritized-cold-start/design.md +133 -0
- package/openspec/changes/prioritized-cold-start/proposal.md +41 -0
- package/openspec/changes/prioritized-cold-start/specs/on-demand-resource-startup/spec.md +92 -0
- package/openspec/changes/prioritized-cold-start/tasks.md +56 -0
- package/openspec/config.yaml +1 -0
- package/package.json +35 -5
- package/scripts/autoresearch/layer-eval.sh +65 -0
- package/scripts/benchmark/README.md +25 -0
- package/scripts/benchmark/container-scale.ts +503 -0
- package/scripts/benchmark/pre-release-gate.sh +9 -0
- package/scripts/measure-idle-footprint.sh +58 -0
- package/scripts/record-demo.sh +43 -0
- package/tests/tilt-engine/test_runtime_container_footprint.py +162 -0
- package/tests/tilt-engine/test_sablier_defer_start.py +196 -0
- package/tests/tilt-engine/test_standalone_traefik.py +52 -0
- package/tests/tilt-engine/test_traefik_static_wake_route.py +187 -0
- package/bun.lock +0 -538
|
@@ -130,6 +130,81 @@ const checkDockerCompose = createExecCheck(
|
|
|
130
130
|
"Install Docker Compose: https://docs.docker.com/compose/install/",
|
|
131
131
|
);
|
|
132
132
|
|
|
133
|
+
// Generated healthchecks use `start_interval`, which older engines/compose reject.
|
|
134
|
+
const MIN_DOCKER_ENGINE_VERSION = [25, 0, 0] as const;
|
|
135
|
+
const MIN_DOCKER_COMPOSE_VERSION = [2, 20, 2] as const;
|
|
136
|
+
|
|
137
|
+
function parseVersion(raw: string): number[] | null {
|
|
138
|
+
const match = raw.trim().match(/(\d+)\.(\d+)(?:\.(\d+))?/);
|
|
139
|
+
if (!match) {
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
return [Number(match[1]), Number(match[2]), Number(match[3] ?? 0)];
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function isAtLeast(version: number[], minimum: readonly number[]): boolean {
|
|
146
|
+
for (const [index, required] of minimum.entries()) {
|
|
147
|
+
const actual = version[index] ?? 0;
|
|
148
|
+
if (actual !== required) {
|
|
149
|
+
return actual > required;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return true;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export function checkDockerVersions(exec: typeof execSync = execSync): CheckResult {
|
|
156
|
+
const run = (command: string): string =>
|
|
157
|
+
String(exec(command, { stdio: "pipe", encoding: "utf-8", timeout: EXEC_TIMEOUT_MS })).trim();
|
|
158
|
+
|
|
159
|
+
let engineRaw: string;
|
|
160
|
+
let composeRaw: string;
|
|
161
|
+
try {
|
|
162
|
+
engineRaw = run("docker version --format '{{.Server.Version}}'");
|
|
163
|
+
composeRaw = run("docker compose version --short");
|
|
164
|
+
} catch {
|
|
165
|
+
return {
|
|
166
|
+
name: "Docker Versions",
|
|
167
|
+
didPass: true,
|
|
168
|
+
isSkipped: true,
|
|
169
|
+
message: "Could not read Docker Engine/Compose versions - skipped version check",
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const engine = parseVersion(engineRaw);
|
|
174
|
+
const compose = parseVersion(composeRaw);
|
|
175
|
+
if (!engine || !compose) {
|
|
176
|
+
return {
|
|
177
|
+
name: "Docker Versions",
|
|
178
|
+
didPass: true,
|
|
179
|
+
isSkipped: true,
|
|
180
|
+
message: `Unrecognized Docker version output (engine "${engineRaw}", compose "${composeRaw}") - skipped version check`,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const problems: string[] = [];
|
|
185
|
+
if (!isAtLeast(engine, MIN_DOCKER_ENGINE_VERSION)) {
|
|
186
|
+
problems.push(`Docker Engine ${engineRaw} (need 25.0+)`);
|
|
187
|
+
}
|
|
188
|
+
if (!isAtLeast(compose, MIN_DOCKER_COMPOSE_VERSION)) {
|
|
189
|
+
problems.push(`Docker Compose ${composeRaw} (need 2.20.2+)`);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (problems.length === 0) {
|
|
193
|
+
return {
|
|
194
|
+
name: "Docker Versions",
|
|
195
|
+
didPass: true,
|
|
196
|
+
message: `Docker Engine ${engineRaw} and Compose ${composeRaw} support generated healthchecks`,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
return {
|
|
201
|
+
name: "Docker Versions",
|
|
202
|
+
didPass: false,
|
|
203
|
+
message: `Docker is too old for generated healthchecks (they use start_interval):\n ${problems.join("\n ")}`,
|
|
204
|
+
fix: "Update Docker Desktop, or on Linux update docker-ce and the docker-compose-plugin package",
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
|
|
133
208
|
const checkTilt = createExecCheck(
|
|
134
209
|
"Tilt CLI",
|
|
135
210
|
"tilt version",
|
|
@@ -197,6 +272,9 @@ const REQUIRED_DOCKER_TEMPLATE_FILES = [
|
|
|
197
272
|
"bun-hoisted-symlink-fix.sh",
|
|
198
273
|
"prisma-bun-client-link-fix.sh",
|
|
199
274
|
"prisma-normalize-client.sh",
|
|
275
|
+
"prisma-runtime-relink.sh",
|
|
276
|
+
"infisical-entrypoint.sh",
|
|
277
|
+
"migrate.sh",
|
|
200
278
|
] as const;
|
|
201
279
|
|
|
202
280
|
export function checkGeneratedProjectRuntimeAssets(): CheckResult {
|
|
@@ -442,6 +520,62 @@ function checkStartupScripts(): CheckResult {
|
|
|
442
520
|
};
|
|
443
521
|
}
|
|
444
522
|
|
|
523
|
+
/**
|
|
524
|
+
* Backend/frontend tsconfig generators set `"types": ["bun"]` on the
|
|
525
|
+
* assumption that `@types/bun` is a direct devDependency (`tdk resource`
|
|
526
|
+
* adds it for new services). Nothing re-adds it if a service's package.json
|
|
527
|
+
* loses that entry -- e.g. a checkout missing it entirely, or a manual edit
|
|
528
|
+
* -- and the failure only surfaces later as `tsc: TS2688: Cannot find type
|
|
529
|
+
* definition file for 'bun'` inside `bun run build`, mid Docker image build.
|
|
530
|
+
*/
|
|
531
|
+
export function checkTypeScriptTypeDependencies(): CheckResult {
|
|
532
|
+
const projectRoot = findProjectRoot() ?? process.cwd();
|
|
533
|
+
const resources = discoverResourcesFromRoot(projectRoot);
|
|
534
|
+
|
|
535
|
+
const problems: string[] = [];
|
|
536
|
+
|
|
537
|
+
for (const resource of resources) {
|
|
538
|
+
const packageJsonPath = join(resource.path, "package.json");
|
|
539
|
+
const dockerTsconfigPath = join(
|
|
540
|
+
resource.path,
|
|
541
|
+
".autogenerated",
|
|
542
|
+
"tsconfig.docker.autogenerated.json",
|
|
543
|
+
);
|
|
544
|
+
|
|
545
|
+
if (!existsSync(packageJsonPath) || !existsSync(dockerTsconfigPath)) {
|
|
546
|
+
continue;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
const tsconfig = readJsonFile(dockerTsconfigPath);
|
|
550
|
+
const compilerOptions = tsconfig?.compilerOptions as Record<string, unknown> | undefined;
|
|
551
|
+
const types = compilerOptions?.types;
|
|
552
|
+
if (!Array.isArray(types) || !types.includes("bun")) {
|
|
553
|
+
continue;
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
const pkg = readJsonFile(packageJsonPath);
|
|
557
|
+
const devDependencies = (pkg?.devDependencies as Record<string, string> | undefined) ?? {};
|
|
558
|
+
if (!devDependencies["@types/bun"]) {
|
|
559
|
+
problems.push(resource.name);
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
if (problems.length === 0) {
|
|
564
|
+
return {
|
|
565
|
+
name: "TypeScript Type Dependencies",
|
|
566
|
+
didPass: true,
|
|
567
|
+
message: "All services with a bun-typed tsconfig have @types/bun installed",
|
|
568
|
+
};
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
return {
|
|
572
|
+
name: "TypeScript Type Dependencies",
|
|
573
|
+
didPass: false,
|
|
574
|
+
message: `Services set "types": ["bun"] in their Docker tsconfig but are missing the "@types/bun" devDependency, so \`bun run build\` fails with TS2688:\n ${problems.join("\n ")}`,
|
|
575
|
+
fix: 'Add to each service\'s package.json devDependencies: "@types/bun": "^1.4.2"',
|
|
576
|
+
};
|
|
577
|
+
}
|
|
578
|
+
|
|
445
579
|
function readJsonFile(path: string): Record<string, unknown> | null {
|
|
446
580
|
try {
|
|
447
581
|
return JSON.parse(readFileSync(path, "utf-8")) as Record<string, unknown>;
|
|
@@ -730,10 +864,12 @@ export const doctorCommand = new Command("doctor")
|
|
|
730
864
|
checkDockerRuntime,
|
|
731
865
|
checkTilt,
|
|
732
866
|
checkDockerCompose,
|
|
867
|
+
checkDockerVersions,
|
|
733
868
|
checkMasterConfigs,
|
|
734
869
|
checkGeneratedProjectRuntimeAssets,
|
|
735
870
|
checkStarlarkLoadExports,
|
|
736
871
|
checkStartupScripts,
|
|
872
|
+
checkTypeScriptTypeDependencies,
|
|
737
873
|
checkFrontendDockerPreflight,
|
|
738
874
|
checkEnvironmentVariables,
|
|
739
875
|
// Preflight: catch "port 80 already allocated" BEFORE claiming ready.
|
package/cli/src/commands/help.ts
CHANGED
|
@@ -62,7 +62,11 @@ const COMMAND_GROUPS = [
|
|
|
62
62
|
emoji: "🌐",
|
|
63
63
|
color: chalk.blueBright,
|
|
64
64
|
commands: [
|
|
65
|
-
{
|
|
65
|
+
{
|
|
66
|
+
name: "networks, traefik",
|
|
67
|
+
desc: "Show Traefik-routed URLs for all services",
|
|
68
|
+
alias: "--stack, --json",
|
|
69
|
+
},
|
|
66
70
|
],
|
|
67
71
|
},
|
|
68
72
|
{
|
|
@@ -71,7 +75,11 @@ const COMMAND_GROUPS = [
|
|
|
71
75
|
color: chalk.cyan,
|
|
72
76
|
commands: [
|
|
73
77
|
{ name: "ui, interactive", desc: "Interactive TUI for managing services", alias: "" },
|
|
74
|
-
{
|
|
78
|
+
{
|
|
79
|
+
name: "config",
|
|
80
|
+
desc: "Manage project configuration and regenerate master files",
|
|
81
|
+
alias: "regenerate, verify, edit",
|
|
82
|
+
},
|
|
75
83
|
{ name: "doctor", desc: "Check environment readiness", alias: "" },
|
|
76
84
|
{ name: "completion", desc: "Generate shell completions", alias: "--install --shell zsh" },
|
|
77
85
|
{ name: "upgrade, update", desc: "Self-update to latest version", alias: "--force" },
|
|
@@ -144,7 +152,9 @@ export function showHelp(): void {
|
|
|
144
152
|
);
|
|
145
153
|
console.log(chalk.gray(` ${"═".repeat(50)}`));
|
|
146
154
|
console.log(chalk.gray(` For more help: ${chalk.cyan("tdk help [command]}")}`));
|
|
147
|
-
console.log(
|
|
155
|
+
console.log(
|
|
156
|
+
chalk.gray(` GitHub: ${chalk.cyan("https://github.com/tdk-landscape/tdk-cli-core")}`),
|
|
157
|
+
);
|
|
148
158
|
console.log();
|
|
149
159
|
console.log(chalk.green.bold(" Happy coding! 🚀\n"));
|
|
150
160
|
}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { execFileSync } from "node:child_process";
|
|
2
|
-
import { existsSync,
|
|
2
|
+
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
3
3
|
import { join, resolve } from "node:path";
|
|
4
4
|
import { cwd } from "node:process";
|
|
5
5
|
import chalk from "chalk";
|
|
6
6
|
import { Command } from "commander";
|
|
7
7
|
import { generateMasterConfigs, readProjectConfig } from "../generator/template-engine.js";
|
|
8
|
+
import type { ProjectConfig } from "../types/index.js";
|
|
8
9
|
import { MASTER_CONFIG_FILES } from "../utils/constants.js";
|
|
10
|
+
import { ensureEnvFile, validateEnvFile } from "../utils/env-validator.js";
|
|
9
11
|
import { errorFactories, runCommand, showErrorAndExit } from "../utils/errors.js";
|
|
10
12
|
import { ensureDirectory, writeJsonFile } from "../utils/file-helpers.js";
|
|
11
13
|
import {
|
|
@@ -16,13 +18,11 @@ import {
|
|
|
16
18
|
showSuccess,
|
|
17
19
|
} from "../utils/formatting.js";
|
|
18
20
|
import { findProjectRoot } from "../utils/paths.js";
|
|
21
|
+
import { PROJECT_FEATURES } from "../utils/project-features.js";
|
|
19
22
|
import { PROJECT_TEMPLATES } from "../utils/project-templates.js";
|
|
23
|
+
import { promptConfirm, promptMultiSelect, promptText } from "../utils/prompt.js";
|
|
20
24
|
import { discoverStackNames } from "../utils/services.js";
|
|
21
25
|
import { isPathSafe } from "../utils/validation.js";
|
|
22
|
-
import { ensureEnvFile, validateEnvFile } from "../utils/env-validator.js";
|
|
23
|
-
import { PROJECT_FEATURES } from "../utils/project-features.js";
|
|
24
|
-
import { promptConfirm, promptMultiSelect, promptText } from "../utils/prompt.js";
|
|
25
|
-
import type { ProjectConfig } from "../types/index.js";
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
28
|
* Stack names discovered from service.json files already in the repo (e.g. a
|
|
@@ -63,10 +63,7 @@ function syncDiscoveredStacksToPreAlpha(
|
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
projectConfig.phases.pre_alpha.enabledStacks = Array.from(
|
|
66
|
-
new Set([
|
|
67
|
-
...projectConfig.phases.pre_alpha.enabledStacks,
|
|
68
|
-
...missingStacks,
|
|
69
|
-
]),
|
|
66
|
+
new Set([...projectConfig.phases.pre_alpha.enabledStacks, ...missingStacks]),
|
|
70
67
|
);
|
|
71
68
|
|
|
72
69
|
return missingStacks;
|
|
@@ -240,7 +237,10 @@ export const projectCommand = new Command("project")
|
|
|
240
237
|
|
|
241
238
|
if (projectJsonExists && !options.force) {
|
|
242
239
|
showSuccess(".tdk/project.json exists");
|
|
243
|
-
const rawProjectConfig = JSON.parse(readFileSync(projectJsonPath, "utf-8")) as Record<
|
|
240
|
+
const rawProjectConfig = JSON.parse(readFileSync(projectJsonPath, "utf-8")) as Record<
|
|
241
|
+
string,
|
|
242
|
+
unknown
|
|
243
|
+
>;
|
|
244
244
|
const projectConfig = readProjectConfig(projectRoot);
|
|
245
245
|
const discoveredStacks = discoverExistingServiceStacks(projectRoot);
|
|
246
246
|
const autoEnabledStacks = syncDiscoveredStacksToPreAlpha(projectConfig, discoveredStacks);
|
|
@@ -251,10 +251,7 @@ export const projectCommand = new Command("project")
|
|
|
251
251
|
}
|
|
252
252
|
|
|
253
253
|
if (autoEnabledStacks.length > 0) {
|
|
254
|
-
showDetail(
|
|
255
|
-
`Auto-enabled discovered service stacks: ${autoEnabledStacks.join(", ")}`,
|
|
256
|
-
0,
|
|
257
|
-
);
|
|
254
|
+
showDetail(`Auto-enabled discovered service stacks: ${autoEnabledStacks.join(", ")}`, 0);
|
|
258
255
|
}
|
|
259
256
|
|
|
260
257
|
showStep("\n📋 Regenerating master configuration files...\n");
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { existsSync } from "node:fs";
|
|
2
|
-
import { join
|
|
2
|
+
import { join } from "node:path";
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
import { Command } from "commander";
|
|
5
|
+
import { MASTER_CONFIG_FILES } from "../utils/constants.js";
|
|
5
6
|
import { createDiscoveryContext } from "../utils/discovery-context.js";
|
|
6
7
|
import { requireProjectRoot, runCommand } from "../utils/errors.js";
|
|
7
8
|
import { formatCount } from "../utils/formatting.js";
|
|
8
|
-
import { MASTER_CONFIG_FILES } from "../utils/constants.js";
|
|
9
9
|
|
|
10
10
|
export const projectsCommand = new Command("projects")
|
|
11
11
|
.description("Show project information and configuration status")
|
package/cli/src/commands/up.ts
CHANGED
|
@@ -5,8 +5,8 @@ import { ensureProjectRuntimeAssets } from "../generator/template-engine.js";
|
|
|
5
5
|
import { handleDryRun } from "../utils/command-helpers.js";
|
|
6
6
|
import { errorFactories, handleTiltFailure, withTiltCheck } from "../utils/errors.js";
|
|
7
7
|
import { formatCount } from "../utils/formatting.js";
|
|
8
|
-
import { findAvailablePort } from "../utils/port-assignment.js";
|
|
9
8
|
import { findProjectRoot } from "../utils/paths.js";
|
|
9
|
+
import { findAvailablePort } from "../utils/port-assignment.js";
|
|
10
10
|
import { appendHealthPath, resolveSubdomainBases } from "../utils/service-urls.js";
|
|
11
11
|
import {
|
|
12
12
|
discoverResources,
|
|
@@ -89,15 +89,23 @@ export const upCommand = new Command("up")
|
|
|
89
89
|
backends.forEach((svc) => {
|
|
90
90
|
const servicePathName = svc.name.replace(/-api$/, "");
|
|
91
91
|
const apiPath = svc.config?.apiPath ?? `/api/${servicePathName}`;
|
|
92
|
+
const sablier = svc.config?.sablier;
|
|
93
|
+
const deferredTag =
|
|
94
|
+
sablier?.enable && sablier?.deferStart
|
|
95
|
+
? chalk.dim(" (deferred — starts on first request)")
|
|
96
|
+
: "";
|
|
92
97
|
console.log(
|
|
93
|
-
chalk.gray(
|
|
98
|
+
chalk.gray(
|
|
99
|
+
` - ${svc.name}: ${apiBase}${chalk.cyan(appendHealthPath(apiPath))}${deferredTag}`,
|
|
100
|
+
),
|
|
94
101
|
);
|
|
95
102
|
});
|
|
96
103
|
}
|
|
97
104
|
}
|
|
98
105
|
|
|
99
|
-
const dryRunCommand =
|
|
100
|
-
|
|
106
|
+
const dryRunCommand = stackName
|
|
107
|
+
? `tilt up -- --focus=${stackName} ${focusServiceNames.join(" ")}`
|
|
108
|
+
: "tilt up";
|
|
101
109
|
if (handleDryRun(options, "not starting services", dryRunCommand)) {
|
|
102
110
|
return;
|
|
103
111
|
}
|
|
@@ -130,6 +138,7 @@ export const upCommand = new Command("up")
|
|
|
130
138
|
verbose: options.verbose,
|
|
131
139
|
quiet: options.quiet,
|
|
132
140
|
force: options.force,
|
|
141
|
+
focusTargets: stackName ? [stackName] : undefined,
|
|
133
142
|
});
|
|
134
143
|
|
|
135
144
|
if (!options.quiet) {
|
|
@@ -70,7 +70,8 @@ function detectInstallation(): InstallInfo {
|
|
|
70
70
|
const BINARY_RELEASE_REPO = "tdk-landscape/tdk-cli-releases";
|
|
71
71
|
|
|
72
72
|
function binaryAssetName(): string | null {
|
|
73
|
-
const osName =
|
|
73
|
+
const osName =
|
|
74
|
+
process.platform === "darwin" ? "darwin" : process.platform === "linux" ? "linux" : null;
|
|
74
75
|
const archName = process.arch === "arm64" ? "arm64" : process.arch === "x64" ? "amd64" : null;
|
|
75
76
|
if (!osName || !archName) return null;
|
|
76
77
|
return `tdk-${osName}-${archName}`;
|
|
@@ -174,7 +175,9 @@ export async function upgradeViaBinary(tdkPath: string, release: BinaryRelease):
|
|
|
174
175
|
console.log(chalk.cyan(` chmod +x ${tdkPath}`));
|
|
175
176
|
console.log(chalk.cyan(` rm -rf ${engineDir} && mkdir -p ${engineDir}`));
|
|
176
177
|
console.log(
|
|
177
|
-
chalk.cyan(
|
|
178
|
+
chalk.cyan(
|
|
179
|
+
` curl -fsSL ${release.engineDownloadUrl} | tar -xzf - -C ${engineDir} --strip-components=1`,
|
|
180
|
+
),
|
|
178
181
|
);
|
|
179
182
|
return false;
|
|
180
183
|
} finally {
|
|
@@ -442,8 +445,12 @@ export const upgradeCommand = new Command("upgrade")
|
|
|
442
445
|
chalk.gray(" Action: git pull origin main && bun install && bun link --force"),
|
|
443
446
|
);
|
|
444
447
|
} else if (installInfo.method === "binary" && binaryRelease) {
|
|
445
|
-
console.log(
|
|
446
|
-
|
|
448
|
+
console.log(
|
|
449
|
+
chalk.gray(` Action: Download and replace with ${binaryRelease.downloadUrl}`),
|
|
450
|
+
);
|
|
451
|
+
console.log(
|
|
452
|
+
chalk.gray(` Action: Refresh bundled engine from ${binaryRelease.engineDownloadUrl}`),
|
|
453
|
+
);
|
|
447
454
|
} else {
|
|
448
455
|
console.log(chalk.gray(` Action: Upgrade to ${latestVersion}`));
|
|
449
456
|
}
|
|
@@ -2,10 +2,10 @@ import { describe, expect, it } from "vitest";
|
|
|
2
2
|
import { PLATFORM_STANDARDS } from "./platform-standards.js";
|
|
3
3
|
|
|
4
4
|
describe("platform standards", () => {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
it("keeps the low-level Traefik host generic and uses a non-privileged port", () => {
|
|
6
|
+
expect(PLATFORM_STANDARDS.traefik.defaultHost).toBe("localhost");
|
|
7
|
+
expect(PLATFORM_STANDARDS.traefik.appHost).toBe("app.localhost");
|
|
8
|
+
expect(PLATFORM_STANDARDS.traefik.apiHost).toBe("api.localhost");
|
|
9
|
+
expect(PLATFORM_STANDARDS.traefik.defaultPort).toBe(8080);
|
|
10
|
+
});
|
|
11
11
|
});
|
|
@@ -8,7 +8,15 @@
|
|
|
8
8
|
// so this exercises the same code path `tdk project` actually runs.
|
|
9
9
|
|
|
10
10
|
import { execFileSync } from "node:child_process";
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
existsSync,
|
|
13
|
+
mkdirSync,
|
|
14
|
+
mkdtempSync,
|
|
15
|
+
readFileSync,
|
|
16
|
+
rmSync,
|
|
17
|
+
utimesSync,
|
|
18
|
+
writeFileSync,
|
|
19
|
+
} from "node:fs";
|
|
12
20
|
import { tmpdir } from "node:os";
|
|
13
21
|
import { join } from "node:path";
|
|
14
22
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
@@ -23,7 +31,7 @@ function buildFixtureTarball(): Buffer {
|
|
|
23
31
|
mkdirSync(join(src, "typescript"), { recursive: true });
|
|
24
32
|
writeFileSync(
|
|
25
33
|
join(src, "typescript", "playwright_config.star"),
|
|
26
|
-
"# REAL premium playwright config\ndef generate_playwright_config(): pass\n"
|
|
34
|
+
"# REAL premium playwright config\ndef generate_playwright_config(): pass\n",
|
|
27
35
|
);
|
|
28
36
|
writeFileSync(join(src, "c4_diagram.star"), "# REAL premium c4 diagram generator\n");
|
|
29
37
|
|
|
@@ -49,7 +57,7 @@ beforeEach(() => {
|
|
|
49
57
|
mkdirSync(join(destDir, "engine/topologies/tilt/generators/typescript"), { recursive: true });
|
|
50
58
|
writeFileSync(
|
|
51
59
|
join(destDir, "engine/topologies/tilt/generators/typescript/playwright_config.star"),
|
|
52
|
-
"# unlicensed stub\n"
|
|
60
|
+
"# unlicensed stub\n",
|
|
53
61
|
);
|
|
54
62
|
|
|
55
63
|
process.env.HOME = fakeHome;
|
|
@@ -79,15 +87,17 @@ describe("applyPremiumOverlay", () => {
|
|
|
79
87
|
expect(
|
|
80
88
|
readFileSync(
|
|
81
89
|
join(destDir, "engine/topologies/tilt/generators/typescript/playwright_config.star"),
|
|
82
|
-
"utf-8"
|
|
83
|
-
)
|
|
90
|
+
"utf-8",
|
|
91
|
+
),
|
|
84
92
|
).toBe("# unlicensed stub\n");
|
|
85
93
|
});
|
|
86
94
|
|
|
87
95
|
it("scenario 2: invalid/ungranted key -> tries every known resource, then falls back to free tier", async () => {
|
|
88
96
|
process.env.TDK_LICENSE_KEY = "tdk-fa411b"; // the mistyped key from the real session
|
|
89
97
|
|
|
90
|
-
const fetchSpy = vi
|
|
98
|
+
const fetchSpy = vi
|
|
99
|
+
.fn()
|
|
100
|
+
.mockResolvedValue(new Response("key does not grant resource", { status: 403 }));
|
|
91
101
|
vi.stubGlobal("fetch", fetchSpy);
|
|
92
102
|
|
|
93
103
|
const { applyPremiumOverlay } = await import("../extension-fetch.js");
|
|
@@ -103,8 +113,8 @@ describe("applyPremiumOverlay", () => {
|
|
|
103
113
|
expect(
|
|
104
114
|
readFileSync(
|
|
105
115
|
join(destDir, "engine/topologies/tilt/generators/typescript/playwright_config.star"),
|
|
106
|
-
"utf-8"
|
|
107
|
-
)
|
|
116
|
+
"utf-8",
|
|
117
|
+
),
|
|
108
118
|
).toBe("# unlicensed stub\n");
|
|
109
119
|
});
|
|
110
120
|
|
|
@@ -129,12 +139,15 @@ describe("applyPremiumOverlay", () => {
|
|
|
129
139
|
|
|
130
140
|
const playwrightOut = readFileSync(
|
|
131
141
|
join(destDir, "engine/topologies/tilt/generators/typescript/playwright_config.star"),
|
|
132
|
-
"utf-8"
|
|
142
|
+
"utf-8",
|
|
133
143
|
);
|
|
134
144
|
expect(playwrightOut).toContain("REAL premium playwright config");
|
|
135
145
|
expect(playwrightOut).not.toContain("unlicensed stub");
|
|
136
146
|
|
|
137
|
-
const c4Out = readFileSync(
|
|
147
|
+
const c4Out = readFileSync(
|
|
148
|
+
join(destDir, "engine/topologies/tilt/generators/c4_diagram.star"),
|
|
149
|
+
"utf-8",
|
|
150
|
+
);
|
|
138
151
|
expect(c4Out).toContain("REAL premium c4 diagram generator");
|
|
139
152
|
});
|
|
140
153
|
|
|
@@ -142,7 +155,7 @@ describe("applyPremiumOverlay", () => {
|
|
|
142
155
|
process.env.TDK_LICENSE_KEY = "tdk-fa411b";
|
|
143
156
|
const seenProjectIds: string[] = [];
|
|
144
157
|
const fetchSpy = vi.fn().mockImplementation((url: string) => {
|
|
145
|
-
seenProjectIds.push(new URL(url).searchParams.get("projectId")
|
|
158
|
+
seenProjectIds.push(new URL(url).searchParams.get("projectId") ?? "");
|
|
146
159
|
return Promise.resolve(new Response("not granted", { status: 403 }));
|
|
147
160
|
});
|
|
148
161
|
vi.stubGlobal("fetch", fetchSpy);
|
|
@@ -161,7 +174,9 @@ describe("applyPremiumOverlay", () => {
|
|
|
161
174
|
process.env.TDK_LICENSE_KEY = "tdk-fa411a";
|
|
162
175
|
fixtureTarball ??= buildFixtureTarball();
|
|
163
176
|
|
|
164
|
-
const fetchSpy = vi
|
|
177
|
+
const fetchSpy = vi
|
|
178
|
+
.fn()
|
|
179
|
+
.mockResolvedValue(new Response(new Uint8Array(fixtureTarball), { status: 200 }));
|
|
165
180
|
vi.stubGlobal("fetch", fetchSpy);
|
|
166
181
|
|
|
167
182
|
const { applyPremiumOverlay } = await import("../extension-fetch.js");
|
|
@@ -178,7 +193,11 @@ describe("applyPremiumOverlay", () => {
|
|
|
178
193
|
// A Response body can only be read once - mockResolvedValue would
|
|
179
194
|
// reuse the same instance across both calls in this test, so build a
|
|
180
195
|
// fresh Response per invocation instead.
|
|
181
|
-
const fetchSpy = vi
|
|
196
|
+
const fetchSpy = vi
|
|
197
|
+
.fn()
|
|
198
|
+
.mockImplementation(() =>
|
|
199
|
+
Promise.resolve(new Response(new Uint8Array(fixtureTarball), { status: 200 })),
|
|
200
|
+
);
|
|
182
201
|
vi.stubGlobal("fetch", fetchSpy);
|
|
183
202
|
|
|
184
203
|
const { applyPremiumOverlay } = await import("../extension-fetch.js");
|
|
@@ -197,7 +216,10 @@ describe("applyPremiumOverlay", () => {
|
|
|
197
216
|
fixtureTarball ??= buildFixtureTarball();
|
|
198
217
|
|
|
199
218
|
process.env.TDK_LICENSE_KEY = "tdk-fa411a";
|
|
200
|
-
vi.stubGlobal(
|
|
219
|
+
vi.stubGlobal(
|
|
220
|
+
"fetch",
|
|
221
|
+
vi.fn().mockResolvedValue(new Response(new Uint8Array(fixtureTarball), { status: 200 })),
|
|
222
|
+
);
|
|
201
223
|
const { applyPremiumOverlay } = await import("../extension-fetch.js");
|
|
202
224
|
await applyPremiumOverlay(projectRoot, destDir);
|
|
203
225
|
|
|
@@ -30,13 +30,21 @@ import { homedir } from "node:os";
|
|
|
30
30
|
import { join } from "node:path";
|
|
31
31
|
import { extractTarball } from "../utils/tar.js";
|
|
32
32
|
|
|
33
|
-
const DEFAULT_ENDPOINT =
|
|
33
|
+
const DEFAULT_ENDPOINT =
|
|
34
|
+
"https://tdk-extension-dist.oranguman.workers.dev/v1/premium/bundle.tar.gz";
|
|
34
35
|
|
|
35
36
|
// Tried in order until one is granted - the worker unlocks the whole
|
|
36
37
|
// bundle on the first resource name a key is found to grant, since
|
|
37
38
|
// premium.tar.gz ships all paid resources together. Keep in sync with
|
|
38
39
|
// what issue-key.yml/update-key.yml accept as `resources` entries.
|
|
39
|
-
const KNOWN_RESOURCES = [
|
|
40
|
+
const KNOWN_RESOURCES = [
|
|
41
|
+
"playwright",
|
|
42
|
+
"c4-diagram",
|
|
43
|
+
"logging",
|
|
44
|
+
"agents-md",
|
|
45
|
+
"sablier",
|
|
46
|
+
"verdaccio",
|
|
47
|
+
];
|
|
40
48
|
|
|
41
49
|
// Re-check the license periodically rather than trusting a local cache
|
|
42
50
|
// forever - an expired or revoked key shouldn't keep unlocking premium
|
|
@@ -61,8 +69,7 @@ const PREMIUM_PATH_MAP: Record<string, string> = {
|
|
|
61
69
|
"engine/topologies/tilt/generators/typescript/fixed_frontend_tsconfig.star",
|
|
62
70
|
"synthetic_monitor.star": "engine/resources/synthetic_monitor.star",
|
|
63
71
|
"synthetic-monitor-topology.star": "engine/topologies/platform/services/synthetic-monitor.star",
|
|
64
|
-
"database-management-service.yaml":
|
|
65
|
-
"platform/services/platform/database-management/service.yaml",
|
|
72
|
+
"database-management-service.yaml": "platform/services/platform/database-management/service.yaml",
|
|
66
73
|
"networking/sablier_container_cycle.star":
|
|
67
74
|
"engine/topologies/platform/docker/networking/sablier_container_cycle.star",
|
|
68
75
|
"registries/verdaccio_loader.star": "engine/topologies/platform/registries/verdaccio_loader.star",
|
|
@@ -86,7 +93,7 @@ function getOrCreateProjectId(projectRoot: string): string {
|
|
|
86
93
|
}
|
|
87
94
|
const id = randomUUID();
|
|
88
95
|
mkdirSync(join(projectRoot, ".tdk"), { recursive: true });
|
|
89
|
-
writeFileSync(idPath, id
|
|
96
|
+
writeFileSync(idPath, `${id}\n`);
|
|
90
97
|
return id;
|
|
91
98
|
}
|
|
92
99
|
|
|
@@ -33,13 +33,12 @@ export function loadTemplate(filename: string): string {
|
|
|
33
33
|
triedPaths.push(templatePath);
|
|
34
34
|
try {
|
|
35
35
|
return fs.readFileSync(templatePath, "utf-8");
|
|
36
|
-
} catch (
|
|
37
|
-
// Try next path
|
|
38
|
-
continue;
|
|
39
|
-
}
|
|
36
|
+
} catch (_error) {}
|
|
40
37
|
}
|
|
41
38
|
|
|
42
|
-
throw new Error(
|
|
39
|
+
throw new Error(
|
|
40
|
+
`Failed to load template ${filename} from any of these paths: ${triedPaths.join(", ")}`,
|
|
41
|
+
);
|
|
43
42
|
}
|
|
44
43
|
|
|
45
44
|
// Templates used to be loaded eagerly here, at module initialization. That
|
|
@@ -192,10 +191,7 @@ export class TemplateEngine {
|
|
|
192
191
|
runtime: PLATFORM_STANDARDS.runtime,
|
|
193
192
|
project: projectConfig.project,
|
|
194
193
|
phases: dedupePhaseEnabledStacks(projectConfig.phases),
|
|
195
|
-
alwaysEnabledInfra: projectConfig.always_enabled_infra ?? [
|
|
196
|
-
"database-management",
|
|
197
|
-
"proxy",
|
|
198
|
-
],
|
|
194
|
+
alwaysEnabledInfra: projectConfig.always_enabled_infra ?? ["database-management", "proxy"],
|
|
199
195
|
optionalInfra: projectConfig.optional_infra,
|
|
200
196
|
serviceDescriptions: RESOURCE_DESCRIPTIONS,
|
|
201
197
|
infraDescriptions: INFRA_DESCRIPTIONS,
|
|
@@ -538,10 +534,7 @@ export async function generateMasterConfigs(projectRoot: string): Promise<void>
|
|
|
538
534
|
if (isStackFeatureEnabledInStacks(projectConfig.phases, "database-management")) {
|
|
539
535
|
const composeDir = path.join(projectRoot, "services", "platform", "database-management");
|
|
540
536
|
fs.mkdirSync(composeDir, { recursive: true });
|
|
541
|
-
const composePath = path.join(
|
|
542
|
-
composeDir,
|
|
543
|
-
"docker-compose.yml",
|
|
544
|
-
);
|
|
537
|
+
const composePath = path.join(composeDir, "docker-compose.yml");
|
|
545
538
|
writeTextFile(composePath, generateDatabaseManagementCompose(projectConfig));
|
|
546
539
|
console.log("✓ Generated: services/platform/database-management/docker-compose.yml");
|
|
547
540
|
}
|
|
@@ -571,9 +564,7 @@ export async function generateMasterConfigs(projectRoot: string): Promise<void>
|
|
|
571
564
|
// This makes `tdk up` work offline and on any machine - no hardcoded paths,
|
|
572
565
|
// no dependency on a private GitHub repo.
|
|
573
566
|
const TDK_EXTENSION_DIRS = ["engine", "discovery", "specs", "ext"] as string[];
|
|
574
|
-
const PROJECT_RUNTIME_ASSET_DIRS = [
|
|
575
|
-
["shared-platform-engineering", "docker-templates"],
|
|
576
|
-
] as const;
|
|
567
|
+
const PROJECT_RUNTIME_ASSET_DIRS = [["shared-platform-engineering", "docker-templates"]] as const;
|
|
577
568
|
const REQUIRED_DOCKER_TEMPLATE_FILES = [
|
|
578
569
|
"install-deps.sh",
|
|
579
570
|
"bun-hoisted-symlink-fix.sh",
|
|
@@ -615,9 +606,11 @@ function findCliAssetRoot(): string | null {
|
|
|
615
606
|
path.join(process.cwd(), "node_modules", "@tdk-landscape", "tdk-cli-core"),
|
|
616
607
|
];
|
|
617
608
|
|
|
618
|
-
return
|
|
619
|
-
|
|
620
|
-
|
|
609
|
+
return (
|
|
610
|
+
candidates.find((candidate) =>
|
|
611
|
+
fs.existsSync(path.join(candidate, "shared-platform-engineering", "docker-templates")),
|
|
612
|
+
) ?? null
|
|
613
|
+
);
|
|
621
614
|
}
|
|
622
615
|
|
|
623
616
|
export function ensureProjectRuntimeAssets(projectRoot: string): string[] {
|
|
@@ -645,7 +638,12 @@ export function ensureProjectRuntimeAssets(projectRoot: string): string[] {
|
|
|
645
638
|
}
|
|
646
639
|
|
|
647
640
|
for (const file of REQUIRED_DOCKER_TEMPLATE_FILES) {
|
|
648
|
-
const filePath = path.join(
|
|
641
|
+
const filePath = path.join(
|
|
642
|
+
projectRoot,
|
|
643
|
+
"shared-platform-engineering",
|
|
644
|
+
"docker-templates",
|
|
645
|
+
file,
|
|
646
|
+
);
|
|
649
647
|
if (!fs.existsSync(filePath)) {
|
|
650
648
|
console.warn(`⚠️ Missing runtime asset after copy: ${filePath}`);
|
|
651
649
|
}
|
|
@@ -663,7 +661,7 @@ async function vendorTdkExtension(projectRoot: string): Promise<void> {
|
|
|
663
661
|
// 2. Self-contained repo (engine/ ships next to cli/ - public tdk-cli-core)
|
|
664
662
|
// 3. Executable-adjacent checkout (bundled installs)
|
|
665
663
|
// 4. Relative ../tdk-cli sibling (monorepo maintainer layout)
|
|
666
|
-
|
|
664
|
+
const sources: string[] = [];
|
|
667
665
|
if (process.env.TDK_EXTENSION_SOURCE) {
|
|
668
666
|
sources.push(process.env.TDK_EXTENSION_SOURCE);
|
|
669
667
|
}
|
package/cli/src/types/index.ts
CHANGED
|
@@ -26,6 +26,8 @@ export interface ResourceConfig {
|
|
|
26
26
|
enable?: boolean;
|
|
27
27
|
group?: string;
|
|
28
28
|
sessionDuration?: string;
|
|
29
|
+
/** Skip this resource during `tdk up` entirely; a Traefik static route wakes it on first request. Requires enable: true. */
|
|
30
|
+
deferStart?: boolean;
|
|
29
31
|
};
|
|
30
32
|
}
|
|
31
33
|
|