@tdk-landscape/tdk-cli-core 1.3.151 → 1.3.153

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/README.md CHANGED
@@ -37,8 +37,17 @@ Docker runs the containers. Tilt watches services and live-updates containers wh
37
37
 
38
38
  [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)
39
39
 
40
+ If TDK helps you run your local stack, a ⭐ on [this repo](https://github.com/tdk-landscape/tdk-cli-core) helps other developers find it.
41
+
40
42
  `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.
41
43
 
44
+ ## Why TDK CLI?
45
+
46
+ - **One `service.json` per service.** TDK generates the Dockerfile, Traefik routing, and Tiltfile from it. You do not hand-write a `docker-compose.yml` or `nginx.conf`.
47
+ - **Local stack without Kubernetes.** Services run on Docker and Tilt on your machine. You do not need a local cluster such as kind or minikube.
48
+ - **Hot reload while you code.** Tilt live-updates the containers when files change.
49
+ - **Generated files you can check.** `tdk` records the generated files and reports drift, so local config stays in sync. See [generated files and drift checks](docs/generated-files.md).
50
+
42
51
  ## Who uses TDK
43
52
 
44
53
  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).
@@ -3,6 +3,7 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
3
3
  // SPDX-License-Identifier: MIT
4
4
  import { Box, Text } from "ink";
5
5
  import { useTUITheme } from "./ui-theme.js";
6
+ const TRUNCATE = "truncate-end";
6
7
  export const TUIHeader = ({ projectRoot, resourceCount, terminalWidth, version, }) => {
7
8
  const theme = useTUITheme();
8
9
  const compact = terminalWidth < 80;
@@ -14,13 +15,13 @@ export const TUIHeader = ({ projectRoot, resourceCount, terminalWidth, version,
14
15
  const contentWidth = Math.max(1, terminalWidth - paddingX * 2);
15
16
  if (compact) {
16
17
  const splitHeading = title.length + " | ".length + resourceLabel.length > contentWidth;
17
- return (_jsxs(Box, { flexDirection: "column", paddingX: paddingX, width: terminalWidth, children: [splitHeading ? (_jsxs(_Fragment, { children: [_jsx(Box, { width: contentWidth, children: _jsx(Text, { color: theme.accent, bold: true, wrap: "truncate-end", children: title }) }), _jsx(Box, { width: contentWidth, children: _jsx(Text, { color: theme.success, wrap: "truncate-end", children: resourceLabel }) })] })) : (_jsx(Box, { width: contentWidth, children: _jsxs(Text, { wrap: "truncate-end", children: [_jsx(Text, { color: theme.accent, bold: true, children: title }), _jsx(Text, { color: theme.muted, children: " | " }), _jsx(Text, { color: theme.success, children: resourceLabel })] }) })), _jsx(Box, { width: contentWidth, children: _jsx(Text, { color: theme.foreground, wrap: "truncate-end", children: projectRoot }) })] }));
18
+ return (_jsxs(Box, { flexDirection: "column", paddingX: paddingX, width: terminalWidth, children: [splitHeading ? (_jsxs(_Fragment, { children: [_jsx(Box, { width: contentWidth, children: _jsx(Text, { color: theme.accent, bold: true, wrap: TRUNCATE, children: title }) }), _jsx(Box, { width: contentWidth, children: _jsx(Text, { color: theme.success, wrap: TRUNCATE, children: resourceLabel }) })] })) : (_jsx(Box, { width: contentWidth, children: _jsxs(Text, { wrap: TRUNCATE, children: [_jsx(Text, { color: theme.accent, bold: true, children: title }), _jsx(Text, { color: theme.muted, children: " | " }), _jsx(Text, { color: theme.success, children: resourceLabel })] }) })), _jsx(Box, { width: contentWidth, children: _jsx(Text, { color: theme.foreground, wrap: TRUNCATE, children: projectRoot }) })] }));
18
19
  }
19
20
  const separatorsWidth = " | ".length * 2;
20
21
  const headingWidth = title.length + resourceLabel.length + separatorsWidth;
21
22
  if (headingWidth >= contentWidth) {
22
- return (_jsxs(Box, { flexDirection: "column", paddingX: paddingX, width: terminalWidth, children: [_jsx(Box, { width: contentWidth, children: _jsx(Text, { color: theme.accent, bold: true, wrap: "truncate-end", children: title }) }), _jsx(Box, { width: contentWidth, children: _jsx(Text, { color: theme.success, wrap: "truncate-end", children: resourceLabel }) }), _jsx(Box, { width: contentWidth, children: _jsx(Text, { color: theme.foreground, wrap: "truncate-end", children: projectRoot }) })] }));
23
+ return (_jsxs(Box, { flexDirection: "column", paddingX: paddingX, width: terminalWidth, children: [_jsx(Box, { width: contentWidth, children: _jsx(Text, { color: theme.accent, bold: true, wrap: TRUNCATE, children: title }) }), _jsx(Box, { width: contentWidth, children: _jsx(Text, { color: theme.success, wrap: TRUNCATE, children: resourceLabel }) }), _jsx(Box, { width: contentWidth, children: _jsx(Text, { color: theme.foreground, wrap: TRUNCATE, children: projectRoot }) })] }));
23
24
  }
24
25
  const rootWidth = contentWidth - headingWidth;
25
- return (_jsxs(Box, { flexDirection: "row", paddingX: paddingX, width: terminalWidth, children: [_jsx(Text, { color: theme.accent, bold: true, children: title }), _jsx(Text, { color: theme.muted, children: " | " }), _jsx(Box, { flexShrink: 0, width: rootWidth, children: _jsx(Text, { color: theme.foreground, wrap: "truncate-end", children: projectRoot }) }), _jsx(Text, { color: theme.muted, children: " | " }), _jsx(Text, { color: theme.success, children: resourceLabel })] }));
26
+ return (_jsxs(Box, { flexDirection: "row", paddingX: paddingX, width: terminalWidth, children: [_jsx(Text, { color: theme.accent, bold: true, children: title }), _jsx(Text, { color: theme.muted, children: " | " }), _jsx(Box, { flexShrink: 0, width: rootWidth, children: _jsx(Text, { color: theme.foreground, wrap: TRUNCATE, children: projectRoot }) }), _jsx(Text, { color: theme.muted, children: " | " }), _jsx(Text, { color: theme.success, children: resourceLabel })] }));
26
27
  };
@@ -10,7 +10,7 @@ To create a stack, use:`},services:{singular:"service",command:"tdk resource <na
10
10
  To create a service:`},"stack-services":{singular:"service",command:"tdk resource <name> --stack <stack-name>",context:`
11
11
  To add services to this stack:`}};function td(e,t){let r=Co[e];console.log(t?f.yellow(`No ${r.singular}s found${t}.`):f.yellow(`No ${r.singular}s found.`)),console.log(f.gray(r.context)),console.log(f.gray(` ${r.command}`)),e==="stacks"&&(console.log(f.gray(`
12
12
  Or create a new resource with a stack:`)),console.log(f.gray(" tdk resource <name> --stack <stack-name>")))}function rd(e){console.log(f.yellow(e||"Cancelled."))}function nd(e){console.log(f.blue(`TDK ${e}
13
- `))}function sd(e,t){console.log(f.green(`All ${e} are ${t}!`))}var mt=62;function od(e="\u2500",t=mt){return e.repeat(t)}function Wr(e,t=mt-2){let r=Math.max(0,t-e.length),n=Math.floor(r/2),s=r-n;return" ".repeat(n)+e+" ".repeat(s)}function id(e,t){return e.length>t?`${e.slice(0,t-1)}\u2026`:e.padEnd(t)}function ad(e,t){return e.length<=t?e:`${e.slice(0,t-3)}...`}function cd(e){console.log(f.green(`\u2713 ${e}`))}function ud(e){console.log(f.blue(e))}function dd(e,t=2){console.log(f.gray(`${" ".repeat(t)}${e}`))}function ld(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`}function pd(e,t,r=mt){let n=r-2,s="\u2500".repeat(n);console.log(),console.log(f.cyan(`\u256D${s}\u256E`)),console.log(f.cyan("\u2502")+f.bold.white(Wr(e,n))+f.cyan("\u2502")),t&&(console.log(f.cyan(`\u251C${s}\u2524`)),console.log(f.cyan("\u2502")+f.gray(Wr(t,n))+f.cyan("\u2502"))),console.log(f.cyan(`\u2570${s}\u256F`))}import{existsSync as jo}from"node:fs";import{dirname as Io,join as Fo,resolve as qr}from"node:path";import{cwd as Mo}from"node:process";var Jr={name:"tdk-cli-internal",private:!0,version:"1.3.151",description:"TDK CLI \u2014 start services on your machine.",keywords:["tdk","tilt","cli","local-dev","microservices"],homepage:"https://github.com/tdk-landscape/tdk-cli-core#readme",bugs:{url:"https://github.com/tdk-landscape/tdk-cli-core/issues"},repository:{type:"git",url:"git+https://github.com/tdk-landscape/tdk-cli-core.git",directory:"cli"},license:"MIT",author:"TDK Team",type:"module",main:"./dist/index.js",types:"./dist/index.d.ts",bin:{tdk:"bin/tdk.js","tdk-cli":"bin/tdk.js"},files:["dist","dist-bundle","bin","templates","README.md","Tiltfile","engine","discovery","specs","ext","!ext/ide-components/code_executor","shared-platform-engineering/docker-templates"],scripts:{build:"tsc && node scripts/bundle.mjs","build:watch":"tsc --watch",lint:"biome check .","lint:fix":"biome check . --write",typecheck:"tsc --project tsconfig.typecheck.json",clean:"rm -rf dist",dev:"bun run build:watch",test:"vitest run","test:watch":"vitest",prepack:"../scripts/stage-npm-engine.sh && npm run build"},dependencies:{commander:"^15.0.0",handlebars:"^4.7.8"},devDependencies:{"@biomejs/biome":"^2.5.13","@types/node":"^22.0.0","@types/react":"^19.3.0",ajv:"^8.17.1",chalk:"^6.0.1",esbuild:"^0.28.2",ink:"^7.1.1",knip:"^6.38.0",react:"^19.3.0","react-devtools-core":"^8.0.0",typescript:"^7.0.2",vite:"^8.3.1",vitest:"^5.0.0"},engines:{node:">=22.12.0"}};function m(e=Mo()){let t=qr(e),r=qr("/");for(;t!==r;){if(jo(Fo(t,".tdk",P)))return t;let n=Io(t);if(n===t)break;t=n}return null}var Ne=null;function Lo(){if(Ne)return Ne;let e=Jr;if(!e||typeof e!="object"||Array.isArray(e))throw new Error("Invalid package.json: expected object");let t=e;return Ne={name:String(t.name??"@tdk-landscape/tdk-cli-core"),version:String(t.version??"0.0.0"),fullPackage:t},Ne}function zr(){return Lo().version}import{readFileSync as Bo}from"node:fs";import{join as Uo}from"node:path";function je(){let e=m();if(e)try{let t=Bo(Uo(e,".tdk",P),"utf-8"),r=JSON.parse(t);if(r?.project?.name)return r.project.name}catch{}return"tdk-project"}function ht(e){let t=je(),r=process.env.TDK_SERVICE_BASE_URL??`http://${t}.localhost${e?`:${e}`:""}`;try{let n=new URL(r.includes("://")?r:`http://${r}`),s=n.hostname,o=n.protocol==="https:"?"443":"80",i=n.port||(e?String(e):""),a=i===o?"":i;if(s==="localhost"||/^\d+\.\d+\.\d+\.\d+$/.test(s))return{appBase:`${n.protocol}//${s}${a?`:${a}`:""}`,apiBase:`${n.protocol}//${s}${a?`:${a}`:""}`};let c=s.replace(/^(app|api)\./,"");return{appBase:`${n.protocol}//app.${c}${a?`:${a}`:""}`,apiBase:`${n.protocol}//api.${c}${a?`:${a}`:""}`}}catch{return{appBase:`http://app.${t}.localhost`,apiBase:`http://api.${t}.localhost`}}}function Ho(e){return`${e.replace(/\/+$/,"")}/health`}function gt(e){if(w(e.config?.appType)){let t=e.name.replace(/-api$/,"");return e.config?.apiPath??`/api/${t}`}return e.config?.basePath??`/${e.name}`}function kt(e,t){return Xr(e,t,r=>Ho(r))}function Yr(e,t){return Xr(e,t,r=>r)}function Xr(e,t,r){let{appBase:n,apiBase:s}=ht(t);return e.filter(o=>o.config?.appType==="frontend"||w(o.config?.appType)).map(o=>{let i=w(o.config.appType)?s:n;return{name:o.name,appType:o.config.appType,url:`${i}${r(gt(o))}`}})}async function Vo(e,t){try{let r=await fetch(e.url,{method:"GET",redirect:"manual",signal:AbortSignal.timeout(t)});return{...e,ok:r.ok,status:r.status}}catch(r){let n=r instanceof Error&&r.name==="TimeoutError"?`no response within ${t}ms`:r instanceof Error?r.message:String(r);return{...e,ok:!1,error:n}}}async function Ie(e,t){return Promise.all(e.map(r=>Vo(r,t)))}import{existsSync as ee,readdirSync as wn,readFileSync as $n,statSync as Et}from"node:fs";import{dirname as Ri,join as J}from"node:path";var ge=class{data;options;constructor(t){this.data=new Map,this.options=t}has(t){let r=this.data.get(t);return r?Date.now()-r.timestamp>this.options.ttlMs?(this.data.delete(t),!1):!0:!1}get(t){if(this.has(t))return this.data.get(t)?.value}set(t,r){this.data.set(t,{value:r,timestamp:Date.now()})}delete(t){this.data.delete(t)}clear(){this.data.clear()}keys(){let t=[];for(let r of this.data.keys())this.has(r)&&t.push(r);return t}size(){return this.keys().length}};function Zr(e){let t=0;return{isValid(){return Date.now()-t<e},markUpdated(){t=Date.now()},reset(){t=0}}}import{execFileSync as Zo,execSync as Qo}from"node:child_process";import{existsSync as qo}from"node:fs";import{delimiter as zo,extname as Yo,join as Xo}from"node:path";import{delimiter as _d,extname as Ko}from"node:path";function Fe(){return process.platform==="win32"}function Go(e){return e==="linux"?"linux":e==="darwin"?"darwin":e==="win32"?"windows":null}function Wo(e){return e==="x64"?"amd64":e==="arm64"?"arm64":null}function Jo(e,t){let r=Go(e),n=Wo(t);if(!r||!n||r==="windows"&&n!=="amd64")return null;let s=`tdk-${r}-${n}`;return r==="windows"?`${s}.exe`:s}function Od(){return Jo(process.platform,process.arch)}function Ad(){return Fe()?"tdk.exe":"tdk"}function Qr(e,t=Fe()){return t?Ko(e)?[e]:[e,`${e}.exe`,`${e}.cmd`,`${e}.bat`]:[e]}function $(e){let t=process.env.PATH??process.env.Path??"",r=Fe(),n=Qr(e,r);if(r&&!Yo(e))for(let s of(process.env.PATHEXT??".EXE;.CMD;.BAT;.COM").split(";")){let o=s.toLowerCase();o&&!n.includes(`${e}${o}`)&&n.push(`${e}${o}`)}for(let s of t.split(zo))if(s)for(let o of n){let i=Xo(s,o);if(qo(i))return i}return null}var en=1e4;function tn(){let e=!1;if(process.platform==="win32")try{return Zo($("docker")??"docker",["ps"],{stdio:"ignore",timeout:en,windowsHide:!0}),"running"}catch(t){return t.code==="ETIMEDOUT"?"unresponsive":"missing"}for(let t of["docker ps","colima status","podman ps"])try{return Qo(t,{stdio:"ignore",timeout:en}),"running"}catch(r){r.code==="ETIMEDOUT"&&(e=!0)}return e?"unresponsive":"missing"}function Me(e,t){return e[t]??0}function ei(e,t){let r=Array.from({length:t.length+1},(n,s)=>s);for(let n=1;n<=e.length;n++){let s=[n];for(let o=1;o<=t.length;o++){let i=e[n-1]===t[o-1]?0:1;s[o]=Math.min(Me(s,o-1)+1,Me(r,o)+1,Me(r,o-1)+i)}r=s}return Me(r,t.length)}function ti(e,t){if(e.length!==t.length)return!1;for(let r=0;r<e.length-1;r++)if(e[r]!==t[r]&&e[r]===t[r+1]&&e[r+1]===t[r]&&e.slice(0,r)===t.slice(0,r)&&e.slice(r+2)===t.slice(r+2))return!0;return!1}function rn(e,t){if(e.length<2||t.length===0||t.includes(e))return;let r=e.toLowerCase(),n,s=Number.POSITIVE_INFINITY;for(let o of t){if(o.length===0)continue;let i=o.toLowerCase(),a=ti(r,i)?1:ei(r,i),c=Math.max(1,Math.min(2,Math.floor(Math.max(r.length,i.length)/3)));a>c||(a<s||a===s&&(n===void 0||o<n))&&(n=o,s=a)}return n}import{spawn as ri}from"node:child_process";import{join as ni}from"node:path";function si(e,t=[],r={}){return new Promise((n,s)=>{let o=[e,...t];r.verbose&&console.log(`Executing: tilt ${o.join(" ")}`);let i=ri($("tilt")??"tilt",o,{stdio:r.inheritStdio?"inherit":"pipe",shell:!1,windowsHide:process.platform==="win32",timeout:r.timeoutMs}),a="",c="";r.inheritStdio||(i.stdout?.on("data",u=>{a+=u.toString()}),i.stderr?.on("data",u=>{c+=u.toString()})),i.on("close",u=>{n({exitCode:u??1,stdout:a,stderr:c})}),i.on("error",u=>{s(new Error(`Failed to spawn tilt: ${u.message}`))})})}async function nn(){try{return(await si("version",[],{inheritStdio:!1,timeoutMs:1e4})).exitCode===0}catch{return!1}}function oi(){let e=m();if(!e)throw V.notInProject();return ni(e,".tdk",".tdk-out","Tiltfile")}function sn(e){let t=oi();e.push("-f",t)}function Wd(e,t={}){let r=[];return sn(r),t.focusTargets&&t.focusTargets.length>0&&r.push("--",`--focus=${t.focusTargets.join(",")}`),r.push(...e),t.verbose&&!t.quiet&&r.push("--verbose"),t.watch&&r.push("--watch"),r}function Jd(e={}){let t=[];return sn(t),e.force&&t.push("--force"),e.focusTargets&&e.focusTargets.length>0&&t.push("--",`--focus=${e.focusTargets.join(",")}`),t}function on(e){return e instanceof Error?e.message:String(e)}function tl(e,t){if(process.env.TDK_VERBOSE){let r=t!==void 0?`: ${on(t)}`:"";console.warn(f.gray(`${e}${r}`))}}var R=class extends Error{suggestions;exitCode;constructor(t,r=[],n=1){super(t),this.name="TdkError",this.suggestions=r,this.exitCode=n}display(){ci(this.message,void 0,this.suggestions)}exit(){this.display(),process.exit(this.exitCode)}};function yt(e,t,r=!1){let n=new Set;for(let s of e){let o=rn(s,t);o&&n.add(r?`Did you mean "${o}" for "${s}"?`:`Did you mean "${o}"?`)}return[...n]}var V={tiltNotInstalled:()=>new R("Tilt CLI is not installed",["Install Tilt: `brew install tilt` (macOS)","Or download from: https://docs.tilt.dev/install.html","Verify with: `tilt version`",`Setup guide: ${dt}`]),dockerNotAvailable:()=>new R("Docker (or a compatible container runtime) is not running",["Start Docker Desktop, then verify with: `docker ps`","Or start Colima: `colima start`","Or start the Docker service on Linux: `sudo systemctl start docker`",`Setup guide: ${dt}`]),dockerNotResponding:()=>new R("Docker is running but not responding (`docker ps` hung for 10s)",["Quit and reopen Docker Desktop, or run `colima restart`","Then verify with: `docker ps`"]),stackNotFound:(e,t=[])=>new R(`Stack "${e}" not found`,[...yt([e],t),"Run `tdk stacks` to see available stacks","Run `tdk stack` to assign resources to a stack"]),resourceNotFound:(e,t=[])=>new R(`Resource "${e}" not found`,[...yt([e],t),"Run `tdk resources` to list all resources","Check the resource name spelling"]),unknownServices:(e,t)=>{let r=yt(e,t,e.length>1);return new R(`Unknown service ${e.join(", ")}. Valid names: ${t.join(", ")}`,r,2)},directoryExists:e=>new R(`Directory already exists: ${e}`,["Use `--path` to specify a different location","Remove the existing directory if no longer needed"]),invalidPath:e=>new R(`Invalid path: ${e}`,["Path must be within the project directory",'Path cannot contain special characters like <>:"|?*']),notInProject:()=>new R("Could not find project root (no .tdk/project.json found)",["Run this from within a TDK project","Run `tdk project --yes` to initialize a new project"])};function rl(){let e=m();return e||V.notInProject().exit()}function ii(e){e instanceof R&&e.exit(),console.error(f.red(`Error: ${on(e)}`)),process.exit(1)}async function ai(e,t){try{return await e()}catch(r){return t?.verbose&&r instanceof Error&&r.stack&&console.error(f.gray(r.stack)),ii(r)}}async function nl(e,t){let r=[],n=tn();return n==="unresponsive"?r.push(V.dockerNotResponding()):n==="missing"&&r.push(V.dockerNotAvailable()),await nn()||r.push(V.tiltNotInstalled()),r.length>0&&(console.error(f.red(`
13
+ `))}function sd(e,t){console.log(f.green(`All ${e} are ${t}!`))}var mt=62;function od(e="\u2500",t=mt){return e.repeat(t)}function Wr(e,t=mt-2){let r=Math.max(0,t-e.length),n=Math.floor(r/2),s=r-n;return" ".repeat(n)+e+" ".repeat(s)}function id(e,t){return e.length>t?`${e.slice(0,t-1)}\u2026`:e.padEnd(t)}function ad(e,t){return e.length<=t?e:`${e.slice(0,t-3)}...`}function cd(e){console.log(f.green(`\u2713 ${e}`))}function ud(e){console.log(f.blue(e))}function dd(e,t=2){console.log(f.gray(`${" ".repeat(t)}${e}`))}function ld(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`}function pd(e,t,r=mt){let n=r-2,s="\u2500".repeat(n);console.log(),console.log(f.cyan(`\u256D${s}\u256E`)),console.log(f.cyan("\u2502")+f.bold.white(Wr(e,n))+f.cyan("\u2502")),t&&(console.log(f.cyan(`\u251C${s}\u2524`)),console.log(f.cyan("\u2502")+f.gray(Wr(t,n))+f.cyan("\u2502"))),console.log(f.cyan(`\u2570${s}\u256F`))}import{existsSync as jo}from"node:fs";import{dirname as Io,join as Fo,resolve as qr}from"node:path";import{cwd as Mo}from"node:process";var Jr={name:"tdk-cli-internal",private:!0,version:"1.3.153",description:"TDK CLI \u2014 start services on your machine.",keywords:["tdk","tilt","cli","local-dev","microservices"],homepage:"https://github.com/tdk-landscape/tdk-cli-core#readme",bugs:{url:"https://github.com/tdk-landscape/tdk-cli-core/issues"},repository:{type:"git",url:"git+https://github.com/tdk-landscape/tdk-cli-core.git",directory:"cli"},license:"MIT",author:"TDK Team",type:"module",main:"./dist/index.js",types:"./dist/index.d.ts",bin:{tdk:"bin/tdk.js","tdk-cli":"bin/tdk.js"},files:["dist","dist-bundle","bin","templates","README.md","Tiltfile","engine","discovery","specs","ext","!ext/ide-components/code_executor","shared-platform-engineering/docker-templates"],scripts:{build:"tsc && node scripts/bundle.mjs","build:watch":"tsc --watch",lint:"biome check .","lint:fix":"biome check . --write",typecheck:"tsc --project tsconfig.typecheck.json",clean:"rm -rf dist",dev:"bun run build:watch",test:"vitest run","test:watch":"vitest",prepack:"../scripts/stage-npm-engine.sh && npm run build"},dependencies:{commander:"^15.0.0",handlebars:"^4.7.8"},devDependencies:{"@biomejs/biome":"^2.5.13","@types/node":"^22.0.0","@types/react":"^19.3.0",ajv:"^8.17.1",chalk:"^6.0.1",esbuild:"^0.28.2",ink:"^7.1.1",knip:"^6.38.0",react:"^19.3.0","react-devtools-core":"^8.0.0",typescript:"^7.0.2",vite:"^8.3.1",vitest:"^5.0.0"},engines:{node:">=22.12.0"}};function m(e=Mo()){let t=qr(e),r=qr("/");for(;t!==r;){if(jo(Fo(t,".tdk",P)))return t;let n=Io(t);if(n===t)break;t=n}return null}var Ne=null;function Lo(){if(Ne)return Ne;let e=Jr;if(!e||typeof e!="object"||Array.isArray(e))throw new Error("Invalid package.json: expected object");let t=e;return Ne={name:String(t.name??"@tdk-landscape/tdk-cli-core"),version:String(t.version??"0.0.0"),fullPackage:t},Ne}function zr(){return Lo().version}import{readFileSync as Bo}from"node:fs";import{join as Uo}from"node:path";function je(){let e=m();if(e)try{let t=Bo(Uo(e,".tdk",P),"utf-8"),r=JSON.parse(t);if(r?.project?.name)return r.project.name}catch{}return"tdk-project"}function ht(e){let t=je(),r=process.env.TDK_SERVICE_BASE_URL??`http://${t}.localhost${e?`:${e}`:""}`;try{let n=new URL(r.includes("://")?r:`http://${r}`),s=n.hostname,o=n.protocol==="https:"?"443":"80",i=n.port||(e?String(e):""),a=i===o?"":i;if(s==="localhost"||/^\d+\.\d+\.\d+\.\d+$/.test(s))return{appBase:`${n.protocol}//${s}${a?`:${a}`:""}`,apiBase:`${n.protocol}//${s}${a?`:${a}`:""}`};let c=s.replace(/^(app|api)\./,"");return{appBase:`${n.protocol}//app.${c}${a?`:${a}`:""}`,apiBase:`${n.protocol}//api.${c}${a?`:${a}`:""}`}}catch{return{appBase:`http://app.${t}.localhost`,apiBase:`http://api.${t}.localhost`}}}function Ho(e){return`${e.replace(/\/+$/,"")}/health`}function gt(e){if(w(e.config?.appType)){let t=e.name.replace(/-api$/,"");return e.config?.apiPath??`/api/${t}`}return e.config?.basePath??`/${e.name}`}function kt(e,t){return Xr(e,t,r=>Ho(r))}function Yr(e,t){return Xr(e,t,r=>r)}function Xr(e,t,r){let{appBase:n,apiBase:s}=ht(t);return e.filter(o=>o.config?.appType==="frontend"||w(o.config?.appType)).map(o=>{let i=w(o.config.appType)?s:n;return{name:o.name,appType:o.config.appType,url:`${i}${r(gt(o))}`}})}async function Vo(e,t){try{let r=await fetch(e.url,{method:"GET",redirect:"manual",signal:AbortSignal.timeout(t)});return{...e,ok:r.ok,status:r.status}}catch(r){let n=r instanceof Error&&r.name==="TimeoutError"?`no response within ${t}ms`:r instanceof Error?r.message:String(r);return{...e,ok:!1,error:n}}}async function Ie(e,t){return Promise.all(e.map(r=>Vo(r,t)))}import{existsSync as ee,readdirSync as wn,readFileSync as $n,statSync as Et}from"node:fs";import{dirname as Ri,join as J}from"node:path";var ge=class{data;options;constructor(t){this.data=new Map,this.options=t}has(t){let r=this.data.get(t);return r?Date.now()-r.timestamp>this.options.ttlMs?(this.data.delete(t),!1):!0:!1}get(t){if(this.has(t))return this.data.get(t)?.value}set(t,r){this.data.set(t,{value:r,timestamp:Date.now()})}delete(t){this.data.delete(t)}clear(){this.data.clear()}keys(){let t=[];for(let r of this.data.keys())this.has(r)&&t.push(r);return t}size(){return this.keys().length}};function Zr(e){let t=0;return{isValid(){return Date.now()-t<e},markUpdated(){t=Date.now()},reset(){t=0}}}import{execFileSync as Zo,execSync as Qo}from"node:child_process";import{existsSync as qo}from"node:fs";import{delimiter as zo,extname as Yo,join as Xo}from"node:path";import{delimiter as _d,extname as Ko}from"node:path";function Fe(){return process.platform==="win32"}function Go(e){return e==="linux"?"linux":e==="darwin"?"darwin":e==="win32"?"windows":null}function Wo(e){return e==="x64"?"amd64":e==="arm64"?"arm64":null}function Jo(e,t){let r=Go(e),n=Wo(t);if(!r||!n||r==="windows"&&n!=="amd64")return null;let s=`tdk-${r}-${n}`;return r==="windows"?`${s}.exe`:s}function Od(){return Jo(process.platform,process.arch)}function Ad(){return Fe()?"tdk.exe":"tdk"}function Qr(e,t=Fe()){return t?Ko(e)?[e]:[e,`${e}.exe`,`${e}.cmd`,`${e}.bat`]:[e]}function $(e){let t=process.env.PATH??process.env.Path??"",r=Fe(),n=Qr(e,r);if(r&&!Yo(e))for(let s of(process.env.PATHEXT??".EXE;.CMD;.BAT;.COM").split(";")){let o=s.toLowerCase();o&&!n.includes(`${e}${o}`)&&n.push(`${e}${o}`)}for(let s of t.split(zo))if(s)for(let o of n){let i=Xo(s,o);if(qo(i))return i}return null}var en=1e4;function tn(){let e=!1;if(process.platform==="win32")try{return Zo($("docker")??"docker",["ps"],{stdio:"ignore",timeout:en,windowsHide:!0}),"running"}catch(t){return t.code==="ETIMEDOUT"?"unresponsive":"missing"}for(let t of["docker ps","colima status","podman ps"])try{return Qo(t,{stdio:"ignore",timeout:en}),"running"}catch(r){r.code==="ETIMEDOUT"&&(e=!0)}return e?"unresponsive":"missing"}function Me(e,t){return e[t]??0}function ei(e,t){let r=Array.from({length:t.length+1},(n,s)=>s);for(let n=1;n<=e.length;n++){let s=[n];for(let o=1;o<=t.length;o++){let i=e[n-1]===t[o-1]?0:1;s[o]=Math.min(Me(s,o-1)+1,Me(r,o)+1,Me(r,o-1)+i)}r=s}return Me(r,t.length)}function ti(e,t){if(e.length!==t.length)return!1;for(let r=0;r<e.length-1;r++)if(e[r]!==t[r]&&e[r]===t[r+1]&&e[r+1]===t[r]&&e.slice(0,r)===t.slice(0,r)&&e.slice(r+2)===t.slice(r+2))return!0;return!1}function rn(e,t){if(e.length<2||t.length===0||t.includes(e))return;let r=e.toLowerCase(),n,s=Number.POSITIVE_INFINITY;for(let o of t){if(o.length===0)continue;let i=o.toLowerCase(),a=ti(r,i)?1:ei(r,i),c=Math.max(1,Math.min(2,Math.floor(Math.max(r.length,i.length)/3)));a>c||(a<s||a===s&&(n===void 0||o<n))&&(n=o,s=a)}return n}import{spawn as ri}from"node:child_process";import{join as ni}from"node:path";function si(e,t=[],r={}){return new Promise((n,s)=>{let o=[e,...t];r.verbose&&console.log(`Executing: tilt ${o.join(" ")}`);let i=ri($("tilt")??"tilt",o,{stdio:r.inheritStdio?"inherit":"pipe",shell:!1,windowsHide:process.platform==="win32",timeout:r.timeoutMs}),a="",c="";r.inheritStdio||(i.stdout?.on("data",u=>{a+=u.toString()}),i.stderr?.on("data",u=>{c+=u.toString()})),i.on("close",u=>{n({exitCode:u??1,stdout:a,stderr:c})}),i.on("error",u=>{s(new Error(`Failed to spawn tilt: ${u.message}`))})})}async function nn(){try{return(await si("version",[],{inheritStdio:!1,timeoutMs:1e4})).exitCode===0}catch{return!1}}function oi(){let e=m();if(!e)throw V.notInProject();return ni(e,".tdk",".tdk-out","Tiltfile")}function sn(e){let t=oi();e.push("-f",t)}function Wd(e,t={}){let r=[];return sn(r),t.focusTargets&&t.focusTargets.length>0&&r.push("--",`--focus=${t.focusTargets.join(",")}`),r.push(...e),t.verbose&&!t.quiet&&r.push("--verbose"),t.watch&&r.push("--watch"),r}function Jd(e={}){let t=[];return sn(t),e.force&&t.push("--force"),e.focusTargets&&e.focusTargets.length>0&&t.push("--",`--focus=${e.focusTargets.join(",")}`),t}function on(e){return e instanceof Error?e.message:String(e)}function tl(e,t){if(process.env.TDK_VERBOSE){let r=t!==void 0?`: ${on(t)}`:"";console.warn(f.gray(`${e}${r}`))}}var R=class extends Error{suggestions;exitCode;constructor(t,r=[],n=1){super(t),this.name="TdkError",this.suggestions=r,this.exitCode=n}display(){ci(this.message,void 0,this.suggestions)}exit(){this.display(),process.exit(this.exitCode)}};function yt(e,t,r=!1){let n=new Set;for(let s of e){let o=rn(s,t);o&&n.add(r?`Did you mean "${o}" for "${s}"?`:`Did you mean "${o}"?`)}return[...n]}var V={tiltNotInstalled:()=>new R("Tilt CLI is not installed",["Install Tilt: `brew install tilt` (macOS)","Or download from: https://docs.tilt.dev/install.html","Verify with: `tilt version`",`Setup guide: ${dt}`]),dockerNotAvailable:()=>new R("Docker (or a compatible container runtime) is not running",["Start Docker Desktop, then verify with: `docker ps`","Or start Colima: `colima start`","Or start the Docker service on Linux: `sudo systemctl start docker`",`Setup guide: ${dt}`]),dockerNotResponding:()=>new R("Docker is running but not responding (`docker ps` hung for 10s)",["Quit and reopen Docker Desktop, or run `colima restart`","Then verify with: `docker ps`"]),stackNotFound:(e,t=[])=>new R(`Stack "${e}" not found`,[...yt([e],t),"Run `tdk stacks` to see available stacks","Run `tdk stack` to assign resources to a stack"]),resourceNotFound:(e,t=[])=>new R(`Resource "${e}" not found`,[...yt([e],t),"Run `tdk resources` to list all resources","Check the resource name spelling"]),unknownServices:(e,t)=>{let r=yt(e,t,e.length>1);return new R(`Unknown service ${e.join(", ")}. Valid names: ${t.join(", ")}`,r,2)},directoryExists:e=>new R(`Directory already exists: ${e}`,["Use `--path` to specify a different location","Remove the existing directory if no longer needed"]),invalidPath:e=>new R(`Invalid path: ${e}`,["Path must be within the project directory",'Path cannot contain special characters like <>:"|?*']),notInProject:()=>new R("Could not find project root (no .tdk/project.json found)",["Run this from within a TDK project","Run `tdk project --yes` to initialize a new project"])};function rl(){let e=m();return e||V.notInProject().exit()}function ii(e){e instanceof R&&e.exit(),console.error(f.red(`Error: ${on(e)}`)),process.exit(1)}async function ai(e,t){try{return await e()}catch(r){return t?.verbose&&r instanceof Error&&r.stack&&console.error(f.gray(r.stack)),ii(r)}}async function nl(e,t){let r=[],n=tn();return n==="unresponsive"?r.push(V.dockerNotResponding()):n==="missing"&&r.push(V.dockerNotAvailable()),await nn()||r.push(V.tiltNotInstalled()),r.length>0&&(console.error(f.red(`
14
14
  TDK can't start - missing prerequisites:
15
15
  `)),r.forEach((s,o)=>{o>0&&console.error(""),s.display()}),console.error(f.gray("\nRun `tdk doctor` for a full environment check.")),process.exit(1)),ai(e,t)}function sl(e,t=1){console.error(f.red(`Error: ${e}`)),process.exit(t)}function ci(e,t,r){if(console.error(f.red(`\u274C ${e}`)),t&&console.error(f.gray(` ${t}`)),r&&r.length>0){console.error(f.yellow(`
16
16
  \u{1F4A1} Suggestions:`));for(let n of r)console.error(f.cyan(` \u2192 ${n}`))}}function ol(e,t){console.error(f.red(`