@tdk-landscape/tdk-cli-core 1.3.135 → 1.3.136

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.
@@ -831,8 +831,8 @@ function parseDockerStats(raw) {
831
831
  const [name, memPctRaw, cpuPctRaw] = line.split(",");
832
832
  return {
833
833
  name: name ?? "unknown",
834
- memPct: Number.parseFloat((memPctRaw ?? "").replace("%", "")),
835
- cpuPct: Number.parseFloat((cpuPctRaw ?? "").replace("%", "")),
834
+ memPct: Number.parseFloat((memPctRaw ?? "").replace(/%/g, "")),
835
+ cpuPct: Number.parseFloat((cpuPctRaw ?? "").replace(/%/g, "")),
836
836
  };
837
837
  })
838
838
  .filter((stat) => Number.isFinite(stat.memPct) && Number.isFinite(stat.cpuPct));
@@ -93,12 +93,16 @@ export class TemplateEngine {
93
93
  this.templatesDir = templatesDir || path.join(currentDir, "..", "..", "templates");
94
94
  this.registerHelpers();
95
95
  }
96
+ // Backslashes must be escaped before quotes, or a value ending in a backslash escapes the closing quote.
97
+ quoteStarlarkString(s) {
98
+ return `"${s.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
99
+ }
96
100
  formatStarlarkValue(val) {
97
101
  if (val === null || val === undefined) {
98
102
  return "None";
99
103
  }
100
104
  if (typeof val === "string") {
101
- return `"${val.replace(/"/g, '\\"')}"`;
105
+ return this.quoteStarlarkString(val);
102
106
  }
103
107
  if (typeof val === "boolean") {
104
108
  return val ? "True" : "False";
@@ -112,7 +116,7 @@ export class TemplateEngine {
112
116
  }
113
117
  if (typeof val === "object") {
114
118
  const entries = Object.entries(val).map(([key, v]) => {
115
- return `"${key}": ${this.formatStarlarkValue(v)}`;
119
+ return `${this.quoteStarlarkString(key)}: ${this.formatStarlarkValue(v)}`;
116
120
  });
117
121
  return `{${entries.join(", ")}}`;
118
122
  }
@@ -11,12 +11,36 @@ const DEFAULT_DISCOVERY_PATHS = ["services/*/*"];
11
11
  function segments(path) {
12
12
  return path.split(sep).filter(Boolean);
13
13
  }
14
+ // Wildcard match without building a RegExp: `*` matches any run of characters, `?` one character,
15
+ // everything else is literal. Greedy with a single backtrack point, so it stays linear-ish on
16
+ // hostile patterns such as "a*a*a*b".
14
17
  function segmentMatches(pattern, name) {
15
- const source = pattern
16
- .replace(/[.+^${}()|[\]\\]/g, "\\$&")
17
- .replace(/\*/g, "[^/]*")
18
- .replace(/\?/g, "[^/]");
19
- return new RegExp(`^${source}$`).test(name);
18
+ let p = 0;
19
+ let n = 0;
20
+ let starP = -1;
21
+ let starN = 0;
22
+ while (n < name.length) {
23
+ if (p < pattern.length &&
24
+ pattern[p] !== "*" &&
25
+ (pattern[p] === "?" || pattern[p] === name[n])) {
26
+ p++;
27
+ n++;
28
+ }
29
+ else if (p < pattern.length && pattern[p] === "*") {
30
+ starP = p++;
31
+ starN = n;
32
+ }
33
+ else if (starP !== -1) {
34
+ p = starP + 1;
35
+ n = ++starN;
36
+ }
37
+ else {
38
+ return false;
39
+ }
40
+ }
41
+ while (p < pattern.length && pattern[p] === "*")
42
+ p++;
43
+ return p === pattern.length;
20
44
  }
21
45
  function globMatchesDir(patternSegments, dirSegments) {
22
46
  return (patternSegments.length === dirSegments.length &&
@@ -56,9 +56,12 @@ export function parsePublishedPortHolders(dockerPsOutput, ports) {
56
56
  const portsField = tab >= 0 ? trimmed.slice(tab + 1) : "";
57
57
  const publishedPorts = [];
58
58
  for (const port of wanted) {
59
- // Matches 0.0.0.0:80->, :::80->, 127.0.0.1:80->
60
- const pattern = new RegExp(`(?:^|[\\s,])(?:\\d[\\d.]*:|\\[::\\]:|::)?${port}->`);
61
- if (pattern.test(portsField) || portsField.includes(`:${port}->`)) {
59
+ // Each mapping is "[ip:]hostPort->containerPort/proto"; match the host port exactly
60
+ // (80-> or 0.0.0.0:80->, :::80->, 127.0.0.1:80->), never a longer number such as 1080->.
61
+ const published = portsField
62
+ .split(/[\s,]+/)
63
+ .some((mapping) => mapping.startsWith(`${port}->`) || mapping.includes(`:${port}->`));
64
+ if (published) {
62
65
  publishedPorts.push(port);
63
66
  }
64
67
  }
@@ -11,7 +11,7 @@ export function isDockerPortOwnedByProject(dockerPs, projectPrefix, port) {
11
11
  const containerName = name.toLowerCase();
12
12
  const prefix = projectPrefix.toLowerCase();
13
13
  return ((containerName.startsWith(`${prefix}_`) || containerName.startsWith(`${prefix}-`)) &&
14
- new RegExp(`:${port}->`).test(ports));
14
+ ports.includes(`:${port}->`));
15
15
  });
16
16
  }
17
17
  export function readSavedHostPortPlan(projectRoot) {
@@ -39,12 +39,31 @@ function readTextIfExists(path) {
39
39
  return undefined;
40
40
  }
41
41
  }
42
+ // Finds `name = [ ... ]` and returns its quoted strings. Plain string scanning, not a RegExp built from the name.
42
43
  function parseStarlarkStringList(source, name) {
43
- const re = new RegExp(`${name}\\s*=\\s*\\[([^\\]]*)\\]`);
44
- const m = source.match(re);
45
- if (!m)
46
- return undefined;
47
- return [...m[1].matchAll(/"([^"]+)"|'([^']+)'/g)].map((x) => x[1] ?? x[2] ?? "");
44
+ const skipSpaces = (at) => {
45
+ let i = at;
46
+ while (i < source.length && /\s/.test(source[i]))
47
+ i += 1;
48
+ return i;
49
+ };
50
+ let from = 0;
51
+ for (;;) {
52
+ const at = source.indexOf(name, from);
53
+ if (at === -1)
54
+ return undefined;
55
+ let i = skipSpaces(at + name.length);
56
+ if (source[i] === "=") {
57
+ i = skipSpaces(i + 1);
58
+ if (source[i] === "[") {
59
+ const end = source.indexOf("]", i + 1);
60
+ if (end === -1)
61
+ return undefined;
62
+ return [...source.slice(i + 1, end).matchAll(/"([^"]+)"|'([^']+)'/g)].map((x) => x[1] ?? x[2] ?? "");
63
+ }
64
+ }
65
+ from = at + name.length;
66
+ }
48
67
  }
49
68
  function tiltfileAlwaysEnabledInfra(projectRoot) {
50
69
  const path = join(projectRoot, ".tdk", ".tdk-out", "Tiltfile");
@@ -110,6 +110,9 @@ function readPath(value, path) {
110
110
  for (const part of parts) {
111
111
  if (current === null || current === undefined)
112
112
  return undefined;
113
+ // Own properties only: a path like "__proto__" must not reach inherited values.
114
+ if (!Object.hasOwn(current, part))
115
+ return undefined;
113
116
  current = current[part];
114
117
  }
115
118
  return current;
@@ -3,22 +3,22 @@ import{c as tn}from"./chunk-OBQS5CYC.js";import{execFileSync as xs}from"node:chi
3
3
  `:`
4
4
  `)+n,s=r+1,r=e.indexOf(`
5
5
  `,s)}while(r!==-1);return o+=e.slice(s),o}var sn=(e=0)=>t=>`\x1B[${t+e}m`,We=(e=0)=>t=>`\x1B[${38+e};5;${t}m`,Ke=(e=0)=>(t,n,r)=>`\x1B[${38+e};2;${t};${n};${r}m`,ws=e=>`\x1B[58;5;${e<90?e-30:e-90+8}m`,x={modifier:{reset:[0,0],bold:[1,22],dim:[2,22],italic:[3,23],underline:[4,24],underlineDouble:["4:2",24],underlineCurly:["4:3",24],underlineDotted:["4:4",24],underlineDashed:["4:5",24],overline:[53,55],inverse:[7,27],hidden:[8,28],strikethrough:[9,29]},color:{black:[30,39],red:[31,39],green:[32,39],yellow:[33,39],blue:[34,39],magenta:[35,39],cyan:[36,39],white:[37,39],blackBright:[90,39],gray:[90,39],grey:[90,39],redBright:[91,39],greenBright:[92,39],yellowBright:[93,39],blueBright:[94,39],magentaBright:[95,39],cyanBright:[96,39],whiteBright:[97,39]},bgColor:{bgBlack:[40,49],bgRed:[41,49],bgGreen:[42,49],bgYellow:[43,49],bgBlue:[44,49],bgMagenta:[45,49],bgCyan:[46,49],bgWhite:[47,49],bgBlackBright:[100,49],bgGray:[100,49],bgGrey:[100,49],bgRedBright:[101,49],bgGreenBright:[102,49],bgYellowBright:[103,49],bgBlueBright:[104,49],bgMagentaBright:[105,49],bgCyanBright:[106,49],bgWhiteBright:[107,49]},underlineColor:{underlineBlack:["58;5;0",59],underlineRed:["58;5;1",59],underlineGreen:["58;5;2",59],underlineYellow:["58;5;3",59],underlineBlue:["58;5;4",59],underlineMagenta:["58;5;5",59],underlineCyan:["58;5;6",59],underlineWhite:["58;5;7",59],underlineBlackBright:["58;5;8",59],underlineGray:["58;5;8",59],underlineGrey:["58;5;8",59],underlineRedBright:["58;5;9",59],underlineGreenBright:["58;5;10",59],underlineYellowBright:["58;5;11",59],underlineBlueBright:["58;5;12",59],underlineMagentaBright:["58;5;13",59],underlineCyanBright:["58;5;14",59],underlineWhiteBright:["58;5;15",59]}},Ac=Object.keys(x.modifier),vs=Object.keys(x.color),Ps=Object.keys(x.bgColor),Dc=Object.keys(x.underlineColor),Cc=[...vs,...Ps];function $s(){let e=new Map;for(let[t,n]of Object.entries(x)){for(let[r,s]of Object.entries(n))x[r]={open:`\x1B[${s[0]}m`,close:`\x1B[${s[1]}m`},n[r]=x[r],e.set(Number.parseInt(s[0],10),s[1]);Object.defineProperty(x,t,{value:n,enumerable:!1})}return Object.defineProperty(x,"codes",{value:e,enumerable:!1}),x.color.close="\x1B[39m",x.bgColor.close="\x1B[49m",x.underlineColor.close="\x1B[59m",x.color.ansi=sn(),x.color.ansi256=We(),x.color.ansi16m=Ke(),x.bgColor.ansi=sn(10),x.bgColor.ansi256=We(10),x.bgColor.ansi16m=Ke(10),x.underlineColor.ansi=ws,x.underlineColor.ansi256=We(20),x.underlineColor.ansi16m=Ke(20),Object.defineProperties(x,{rgbToAnsi256:{value(t,n,r){return t===n&&n===r?t<8?16:t>248?231:Math.round((t-8)/247*24)+232:16+36*Math.round(t/255*5)+6*Math.round(n/255*5)+Math.round(r/255*5)},enumerable:!1},hexToRgb:{value(t){let n=/[\da-f]{6}|[\da-f]{3}/i.exec(t.toString(16));if(!n)return[0,0,0];let[r]=n;r.length===3&&(r=[...r].map(o=>o+o).join(""));let s=Number.parseInt(r,16);return[s>>16&255,s>>8&255,s&255]},enumerable:!1},hexToAnsi256:{value:t=>x.rgbToAnsi256(...x.hexToRgb(t)),enumerable:!1},ansi256ToAnsi:{value(t){if(t<8)return 30+t;if(t<16)return 90+(t-8);let n,r,s;if(t>=232)n=((t-232)*10+8)/255,r=n,s=n;else{t-=16;let a=t%36;n=Math.floor(t/36)/5,r=Math.floor(a/6)/5,s=a%6/5}let o=Math.max(n,r,s)*2;if(o===0)return 30;let i=30+(Math.round(s)<<2|Math.round(r)<<1|Math.round(n));return o===2&&(i+=60),i},enumerable:!1},rgbToAnsi:{value:(t,n,r)=>x.ansi256ToAnsi(x.rgbToAnsi256(t,n,r)),enumerable:!1},hexToAnsi:{value:t=>x.ansi256ToAnsi(x.hexToAnsi256(t)),enumerable:!1}}),x}var Es=$s(),j=Es;import Ge from"node:process";import Rs from"node:os";import on from"node:tty";function A(e,t=globalThis.Deno?globalThis.Deno.args:Ge.argv){let n=e.startsWith("-")?"":e.length===1?"-":"--",r=t.indexOf(n+e),s=t.indexOf("--");return r!==-1&&(s===-1||r<s)}var{env:T}=Ge,be;A("no-color")||A("no-colors")||A("color=false")||A("color=never")?be=0:(A("color")||A("colors")||A("color=true")||A("color=always"))&&(be=1);function cn(){return/^\d+$/.test(T.FORCE_COLOR)}function _s(){if("FORCE_COLOR"in T){if(T.FORCE_COLOR==="false")return 0;if(T.FORCE_COLOR==="true"||T.FORCE_COLOR.length===0)return 1;if(cn())return Math.min(Number.parseInt(T.FORCE_COLOR,10),3)}}function Os(e){return e===0?!1:{level:e,hasBasic:!0,has256:e>=2,has16m:e>=3}}function As(e,{streamIsTTY:t,sniffFlags:n=!0}={}){let r=_s();r!==void 0&&(be=r);let s=n?be:r;if(s===0)return 0;if(n){if(A("color=16m")||A("color=full")||A("color=truecolor"))return 3;if(A("color=256"))return 2}if(s!==void 0&&cn())return s;if("TF_BUILD"in T&&"AGENT_NAME"in T)return 1;if(e&&!t&&s===void 0)return 0;let o=s||0;if(T.TERM==="dumb")return o;if(Ge.platform==="win32"){let i=Rs.release().split(".");return Number(i[0])>=10&&Number(i[2])>=10586?Number(i[2])>=14931?3:2:1}if("CI"in T)return["GITHUB_ACTIONS","GITEA_ACTIONS","CIRCLECI"].some(i=>i in T)?3:["TRAVIS","APPVEYOR","GITLAB_CI","BUILDKITE","DRONE"].some(i=>i in T)||T.CI_NAME==="codeship"?1:o;if("TEAMCITY_VERSION"in T)return/^(?:9\.0*[1-9]\d*\.|\d{2,}\.)/.test(T.TEAMCITY_VERSION)?1:0;if(T.COLORTERM==="truecolor"||T.TERM==="xterm-kitty"||T.TERM==="xterm-ghostty"||T.TERM==="wezterm")return 3;if("TERM_PROGRAM"in T){let i=Number.parseInt((T.TERM_PROGRAM_VERSION||"").split(".",1)[0],10);switch(T.TERM_PROGRAM){case"iTerm.app":return i>=3?3:2;case"Apple_Terminal":return 2}}return/-256(?:color)?$/i.test(T.TERM)?2:/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(T.TERM)||"COLORTERM"in T?1:o}function an(e,t={}){let n=As(e,{streamIsTTY:e&&e.isTTY,...t});return Os(n)}var Ds={stdout:an({isTTY:on.isatty(1)}),stderr:an({isTTY:on.isatty(2)})},un=Ds;var{stdout:dn,stderr:ln}=un,se=Symbol("GENERATOR"),oe=Symbol("STYLER"),Te=Symbol("IS_EMPTY"),xe=Symbol("LEVEL"),ie=Object.create(null),pn=e=>{if(!Number.isSafeInteger(e)||e<0||e>3)throw new Error("The `level` should be an integer from 0 to 3")},Cs={enumerable:!0,get(){return this[xe]},set(e){pn(e),this[xe]=e}},Ns=(e,t={})=>{t.level!==void 0&&pn(t.level);let n=dn?dn.level:0;e[xe]=t.level===void 0?n:t.level};var js=e=>{let t=(...n)=>n.join(" ");return Ns(t,e),Object.setPrototypeOf(t,ae.prototype),t};function ae(e){return js(e)}Object.setPrototypeOf(ae.prototype,Function.prototype);for(let[e,t]of Object.entries(j))ie[e]={get(){let n=Je(this,fn(t.open,t.close,this[oe]),this[Te]);return Object.defineProperty(this,e,{value:n}),n}};ie.visible={get(){let e=Je(this,this[oe],!0);return Object.defineProperty(this,"visible",{value:e}),e}};var Is=(e,t)=>{let n=j[t];if(e==="rgb"){let s=(i,a,c)=>n.ansi(j.rgbToAnsi(i,a,c));return[s,s,(i,a,c)=>n.ansi256(j.rgbToAnsi256(i,a,c)),n.ansi16m]}if(e==="hex"){let s=i=>n.ansi(j.hexToAnsi(i));return[s,s,i=>n.ansi256(j.hexToAnsi256(i)),i=>n.ansi16m(...j.hexToRgb(i))]}let r=s=>n.ansi(j.ansi256ToAnsi(s));return[r,r,n.ansi256,n.ansi256]},Fs=["rgb","hex","ansi256"];for(let e of Fs){let t=e[0].toUpperCase()+e.slice(1);for(let[n,r]of[[e,"color"],["bg"+t,"bgColor"],["underline"+t,"underlineColor"]]){let{close:s}=j[r],o=Is(e,r);ie[n]={get(){let i=function(a,c,u){let d=o[this.level](a,c,u);return Je(this,fn(d,s,this[oe]),this[Te])};return Object.defineProperty(this,n,{value:i}),i}}}}var Ms=Object.defineProperties(()=>{},{...ie,level:{enumerable:!0,get(){return this[se].level},set(e){this[se].level=e}}}),fn=(e,t,n)=>{let r,s;return n===void 0?(r=e,s=t):(r=n.openAll+e,s=t+n.closeAll),{open:e,close:t,openAll:r,closeAll:s,parent:n}},Je=(e,t,n)=>{let r=(...s)=>s.length===1?qe(r,""+s[0]):s.length===2?qe(r,`${s[0]??""} ${s[1]??""}`):qe(r,s.join(" "));return Object.setPrototypeOf(r,Ms),r[se]=e[se]??e,r[oe]=t,r[Te]=n,r},qe=(e,t)=>{if(e[se][xe]<=0||!t)return e[Te]?"":t;let n=e[oe];if(n===void 0)return t;let{openAll:r,closeAll:s}=n;if(t.includes("\x1B"))for(;n!==void 0;)t=nn(t,n.close,n.open),n=n.parent;let o=t.indexOf(`
6
- `);return o!==-1&&(t=rn(t,s,r,o)),r+t+s};Object.defineProperties(ae.prototype,{...ie,level:Cs});var Ls=ae(),Hc=ae({level:ln?ln.level:0});var f=Ls;import{Command as Ga}from"commander";import{existsSync as Bs}from"node:fs";var we="docs/agent-hosts.md",ze=`WebContainers cannot run TDK: there is no Docker daemon or Tilt. Run \`tdk up\` on a machine with Docker. See ${we}.`,mn=`Docker is not reachable from this Dev Container. Mount the host Docker socket (-v /var/run/docker.sock:/var/run/docker.sock) or add the docker-outside-of-docker feature to devcontainer.json, then retry. Docker-in-docker is not supported. See ${we}.`;function Us(){return{env:process.env,versions:process.versions,platform:process.platform,fileExists:Bs}}function hn(e=Us()){let{env:t,versions:n,platform:r,fileExists:s}=e;return n.webcontainer?{kind:"webcontainer",canUp:!1}:t.CODESPACES==="true"?{kind:"codespaces",canUp:!0}:t.REMOTE_CONTAINERS||s("/.dockerenv")&&t.DEVCONTAINER?{kind:"devcontainer",canUp:!0}:r==="win32"?{kind:"native-windows",canUp:t.TDK_ALLOW_NATIVE_WINDOWS==="1"}:r==="linux"&&t.WSL_DISTRO_NAME?{kind:"wsl2",canUp:!0}:{kind:"local",canUp:!0}}function gn(e){return e==="devcontainer"||e==="codespaces"}function P(e){return e==="backend"||e==="mcp"}function ve(e){return e.some(t=>P(t.config?.appType)||t.config?.appType==="frontend"||t.config?.appType==="worker")}var Ye=["TILT_TECH_STACK.star","TILT_RESOURCE_DEFAULTS.star","spec.master"],zc=["backend","frontend","library","sdk","worker","migrator","mcp","bring-your-own"],Xe={backend:["dev","build","start"],worker:["dev","build","start"],migrator:["dev","build","start"],mcp:["dev","build","start"],frontend:["dev","build"],library:["dev","build"],sdk:["dev","build"],"bring-your-own":[]};var Ze=["monitoring","elk","debezium","golden_image","verdaccio"],Yc={frontend:{base:3e3,min:3e3,max:3999,range:"3000-3999"},backend:{base:4e3,min:4e3,max:4999,range:"4000-4999"},mcp:{base:4e3,min:4e3,max:5999,range:"4000-5999"},"bring-your-own":{base:4e3,min:4e3,max:5999,range:"4000-5999"},worker:{base:6e3,min:6e3,max:6999,range:"6000-6999"},health:{base:5e3,min:5e3,max:5999,range:"5000-5999"},migrator:{base:7e3,min:7e3,max:7999,range:"7000-7999"}},kn={tiltUi:10350,traefik:8080},Qe="https://tdk-landscape.github.io/tdk-website/docs/quickstart/";var yn=["node_modules",".git",".tilt",".tilt-engine","dist","build",".prisma",".turbo","coverage","tmp","temp","__tests__","test","tests",".github",".vscode","docs"],Sn=["Dockerfile","docker-compose.yml","docker-compose.yaml","Tiltfile","vite.config.ts","tsconfig.json","tsconfig.build.json"],Hs={infra:"\u{1F3D7}\uFE0F",core:"\u{1F527}",api:"\u26A1",app:"\u{1F3A8}",orchestrator:"\u2699\uFE0F"};function Xc(e){let t=e.toLowerCase();for(let[n,r]of Object.entries(Hs))if(t.includes(n))return r;return"\u{1F4E6}"}import{existsSync as Vs,readFileSync as Ws}from"node:fs";import{join as Ks,relative as bn,resolve as xn,sep as Gs}from"node:path";var qs=2,Tn=["services/*/*"];function wn(e){return e.split(Gs).filter(Boolean)}function Js(e,t){let n=e.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*/g,"[^/]*").replace(/\?/g,"[^/]");return new RegExp(`^${n}$`).test(t)}function zs(e,t){return e.length===t.length&&e.every((n,r)=>Js(n,t[r]))}function et(e){let t=Ks(e,".tdk","project.json");if(!Vs(t))return Tn;try{let n=JSON.parse(Ws(t,"utf-8"))?.discovery?.paths;if(Array.isArray(n)&&n.every(r=>typeof r=="string"))return n}catch{}return Tn}function Pe(e,t,n){let r=wn(bn(e,xn(e,t)));return n.some(s=>{let o=wn(bn(e,xn(e,s)));for(let i=0;i<=qs;i++){let a=r.length-i;if(a>0&&zs(o,r.slice(0,a)))return!0}return!1})}function tu(e,t,n,r){let s=et(e);if(Pe(e,t,s))return{path:t};let o=`services/${n}/${r}`;return Pe(e,o,s)?{path:o,adjustedFrom:t}:{path:t}}async function Pn(e,t){let n=[],r=[],s=o=>{o.status==="fulfilled"?n.push(o.value):r.push({code:"INTERNAL",message:o.reason instanceof Error?o.reason.message:String(o.reason)})};for(let o of await Promise.allSettled(e.map(i=>Promise.resolve().then(i))))s(o);for(let o of t)for(let i of await Promise.allSettled([Promise.resolve().then(o)]))s(i);return{checks:n,errors:r}}function vn(e){let t=e.find(n=>n.name==="Container Runtime");return t?t.didPass:null}function W(e,t,n=[],r,s){return{schemaVersion:1,data:{ready:n.length===0&&e.every(o=>o.didPass||o.isSkipped||o.isWarning),inProject:t,checks:e,...s?{host:{...s,containerRuntimeReachable:vn(e),canUp:s.canUp&&vn(e)!==!1}}:{},...r!==void 0?{ports:{http:{requested:r?.requested.ingressHttp??80,chosen:r?.ingressHttp??null,explicit:r?.explicit.ingressHttp??!!process.env.TDK_HTTP_PORT,reason:r?.reason.ingressHttp??"port planning failed"},https:{requested:r?.requested.ingressHttps??443,chosen:r?.ingressHttps??null,explicit:r?.explicit.ingressHttps??!!process.env.TDK_HTTPS_PORT,reason:r?.reason.ingressHttps??"port planning failed"},postgres:{requested:r?.requested.postgres??5432,chosen:r?.postgres??null,explicit:r?.explicit.postgres??!!process.env.TDK_POSTGRES_PORT,reason:r?.reason.postgres??"port planning failed"}}}:{}},errors:n}}function $n(e){return e.errors.length>0?2:e.data.ready?0:1}import{execFileSync as lr,execSync as me}from"node:child_process";import{existsSync as bt,readdirSync as ri,readFileSync as xt}from"node:fs";import{join as z}from"node:path";function Ys(e,t,n){return e===1?t:n||`${t}s`}function S(e,t,n){return`${e} ${Ys(e,t,n)}`}var Xs={month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"};function ou(e){return new Date(e).toLocaleString("en-US",Xs)}function iu(e){return new Date(e).toLocaleDateString("en-US",{month:"short",day:"numeric"})}var tt={success:{color:"green",icon:"\u2713",chalkFn:f.green},error:{color:"red",icon:"\u2717",chalkFn:f.red},warning:{color:"yellow",icon:"\u25CB",chalkFn:f.yellow},unknown:{color:"gray",icon:"?",chalkFn:f.gray}};function nt(e){if(!e)return"unknown";let t=e.toLowerCase();return t==="ready"||t==="healthy"||t==="active"||t==="running"?"success":t==="error"||t==="failed"||t==="critical"||t==="stopped"?"error":t==="pending"||t==="starting"||t==="building"||t==="degraded"?"warning":"unknown"}function au(e){return tt[nt(e)].color}function cu(e){return tt[nt(e)].icon}function uu(e,t){return tt[nt(t)].chalkFn(e)}var Zs={resources:{singular:"resource",command:"tdk resource <name>",context:`
6
+ `);return o!==-1&&(t=rn(t,s,r,o)),r+t+s};Object.defineProperties(ae.prototype,{...ie,level:Cs});var Ls=ae(),Hc=ae({level:ln?ln.level:0});var f=Ls;import{Command as Ga}from"commander";import{existsSync as Bs}from"node:fs";var we="docs/agent-hosts.md",ze=`WebContainers cannot run TDK: there is no Docker daemon or Tilt. Run \`tdk up\` on a machine with Docker. See ${we}.`,mn=`Docker is not reachable from this Dev Container. Mount the host Docker socket (-v /var/run/docker.sock:/var/run/docker.sock) or add the docker-outside-of-docker feature to devcontainer.json, then retry. Docker-in-docker is not supported. See ${we}.`;function Us(){return{env:process.env,versions:process.versions,platform:process.platform,fileExists:Bs}}function hn(e=Us()){let{env:t,versions:n,platform:r,fileExists:s}=e;return n.webcontainer?{kind:"webcontainer",canUp:!1}:t.CODESPACES==="true"?{kind:"codespaces",canUp:!0}:t.REMOTE_CONTAINERS||s("/.dockerenv")&&t.DEVCONTAINER?{kind:"devcontainer",canUp:!0}:r==="win32"?{kind:"native-windows",canUp:t.TDK_ALLOW_NATIVE_WINDOWS==="1"}:r==="linux"&&t.WSL_DISTRO_NAME?{kind:"wsl2",canUp:!0}:{kind:"local",canUp:!0}}function gn(e){return e==="devcontainer"||e==="codespaces"}function P(e){return e==="backend"||e==="mcp"}function ve(e){return e.some(t=>P(t.config?.appType)||t.config?.appType==="frontend"||t.config?.appType==="worker")}var Ye=["TILT_TECH_STACK.star","TILT_RESOURCE_DEFAULTS.star","spec.master"],zc=["backend","frontend","library","sdk","worker","migrator","mcp","bring-your-own"],Xe={backend:["dev","build","start"],worker:["dev","build","start"],migrator:["dev","build","start"],mcp:["dev","build","start"],frontend:["dev","build"],library:["dev","build"],sdk:["dev","build"],"bring-your-own":[]};var Ze=["monitoring","elk","debezium","golden_image","verdaccio"],Yc={frontend:{base:3e3,min:3e3,max:3999,range:"3000-3999"},backend:{base:4e3,min:4e3,max:4999,range:"4000-4999"},mcp:{base:4e3,min:4e3,max:5999,range:"4000-5999"},"bring-your-own":{base:4e3,min:4e3,max:5999,range:"4000-5999"},worker:{base:6e3,min:6e3,max:6999,range:"6000-6999"},health:{base:5e3,min:5e3,max:5999,range:"5000-5999"},migrator:{base:7e3,min:7e3,max:7999,range:"7000-7999"}},kn={tiltUi:10350,traefik:8080},Qe="https://tdk-landscape.github.io/tdk-website/docs/quickstart/";var yn=["node_modules",".git",".tilt",".tilt-engine","dist","build",".prisma",".turbo","coverage","tmp","temp","__tests__","test","tests",".github",".vscode","docs"],Sn=["Dockerfile","docker-compose.yml","docker-compose.yaml","Tiltfile","vite.config.ts","tsconfig.json","tsconfig.build.json"],Hs={infra:"\u{1F3D7}\uFE0F",core:"\u{1F527}",api:"\u26A1",app:"\u{1F3A8}",orchestrator:"\u2699\uFE0F"};function Xc(e){let t=e.toLowerCase();for(let[n,r]of Object.entries(Hs))if(t.includes(n))return r;return"\u{1F4E6}"}import{existsSync as Vs,readFileSync as Ws}from"node:fs";import{join as Ks,relative as bn,resolve as xn,sep as Gs}from"node:path";var qs=2,Tn=["services/*/*"];function wn(e){return e.split(Gs).filter(Boolean)}function Js(e,t){let n=0,r=0,s=-1,o=0;for(;r<t.length;)if(n<e.length&&e[n]!=="*"&&(e[n]==="?"||e[n]===t[r]))n++,r++;else if(n<e.length&&e[n]==="*")s=n++,o=r;else if(s!==-1)n=s+1,r=++o;else return!1;for(;n<e.length&&e[n]==="*";)n++;return n===e.length}function zs(e,t){return e.length===t.length&&e.every((n,r)=>Js(n,t[r]))}function et(e){let t=Ks(e,".tdk","project.json");if(!Vs(t))return Tn;try{let n=JSON.parse(Ws(t,"utf-8"))?.discovery?.paths;if(Array.isArray(n)&&n.every(r=>typeof r=="string"))return n}catch{}return Tn}function Pe(e,t,n){let r=wn(bn(e,xn(e,t)));return n.some(s=>{let o=wn(bn(e,xn(e,s)));for(let i=0;i<=qs;i++){let a=r.length-i;if(a>0&&zs(o,r.slice(0,a)))return!0}return!1})}function tu(e,t,n,r){let s=et(e);if(Pe(e,t,s))return{path:t};let o=`services/${n}/${r}`;return Pe(e,o,s)?{path:o,adjustedFrom:t}:{path:t}}async function Pn(e,t){let n=[],r=[],s=o=>{o.status==="fulfilled"?n.push(o.value):r.push({code:"INTERNAL",message:o.reason instanceof Error?o.reason.message:String(o.reason)})};for(let o of await Promise.allSettled(e.map(i=>Promise.resolve().then(i))))s(o);for(let o of t)for(let i of await Promise.allSettled([Promise.resolve().then(o)]))s(i);return{checks:n,errors:r}}function vn(e){let t=e.find(n=>n.name==="Container Runtime");return t?t.didPass:null}function W(e,t,n=[],r,s){return{schemaVersion:1,data:{ready:n.length===0&&e.every(o=>o.didPass||o.isSkipped||o.isWarning),inProject:t,checks:e,...s?{host:{...s,containerRuntimeReachable:vn(e),canUp:s.canUp&&vn(e)!==!1}}:{},...r!==void 0?{ports:{http:{requested:r?.requested.ingressHttp??80,chosen:r?.ingressHttp??null,explicit:r?.explicit.ingressHttp??!!process.env.TDK_HTTP_PORT,reason:r?.reason.ingressHttp??"port planning failed"},https:{requested:r?.requested.ingressHttps??443,chosen:r?.ingressHttps??null,explicit:r?.explicit.ingressHttps??!!process.env.TDK_HTTPS_PORT,reason:r?.reason.ingressHttps??"port planning failed"},postgres:{requested:r?.requested.postgres??5432,chosen:r?.postgres??null,explicit:r?.explicit.postgres??!!process.env.TDK_POSTGRES_PORT,reason:r?.reason.postgres??"port planning failed"}}}:{}},errors:n}}function $n(e){return e.errors.length>0?2:e.data.ready?0:1}import{execFileSync as lr,execSync as me}from"node:child_process";import{existsSync as bt,readdirSync as ri,readFileSync as xt}from"node:fs";import{join as z}from"node:path";function Ys(e,t,n){return e===1?t:n||`${t}s`}function S(e,t,n){return`${e} ${Ys(e,t,n)}`}var Xs={month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"};function ou(e){return new Date(e).toLocaleString("en-US",Xs)}function iu(e){return new Date(e).toLocaleDateString("en-US",{month:"short",day:"numeric"})}var tt={success:{color:"green",icon:"\u2713",chalkFn:f.green},error:{color:"red",icon:"\u2717",chalkFn:f.red},warning:{color:"yellow",icon:"\u25CB",chalkFn:f.yellow},unknown:{color:"gray",icon:"?",chalkFn:f.gray}};function nt(e){if(!e)return"unknown";let t=e.toLowerCase();return t==="ready"||t==="healthy"||t==="active"||t==="running"?"success":t==="error"||t==="failed"||t==="critical"||t==="stopped"?"error":t==="pending"||t==="starting"||t==="building"||t==="degraded"?"warning":"unknown"}function au(e){return tt[nt(e)].color}function cu(e){return tt[nt(e)].icon}function uu(e,t){return tt[nt(t)].chalkFn(e)}var Zs={resources:{singular:"resource",command:"tdk resource <name>",context:`
7
7
  To create a resource:`},stacks:{singular:"stack",command:"tdk stack <stack-name>",context:`
8
8
  To create a stack, use:`},services:{singular:"service",command:"tdk resource <name>",context:`
9
9
  To create a service:`},"stack-services":{singular:"service",command:"tdk resource <name> --stack <stack-name>",context:`
10
10
  To add services to this stack:`}};function du(e,t){let n=Zs[e];console.log(t?f.yellow(`No ${n.singular}s found${t}.`):f.yellow(`No ${n.singular}s found.`)),console.log(f.gray(n.context)),console.log(f.gray(` ${n.command}`)),e==="stacks"&&(console.log(f.gray(`
11
11
  Or create a new resource with a stack:`)),console.log(f.gray(" tdk resource <name> --stack <stack-name>")))}function lu(e){console.log(f.yellow(e||"Cancelled."))}function pu(e){console.log(f.blue(`TDK ${e}
12
- `))}function fu(e,t){console.log(f.green(`All ${e} are ${t}!`))}var rt=62;function mu(e="\u2500",t=rt){return e.repeat(t)}function En(e,t=rt-2){let n=Math.max(0,t-e.length),r=Math.floor(n/2),s=n-r;return" ".repeat(r)+e+" ".repeat(s)}function hu(e,t){return e.length>t?`${e.slice(0,t-1)}\u2026`:e.padEnd(t)}function gu(e,t){return e.length<=t?e:`${e.slice(0,t-3)}...`}function ku(e){console.log(f.green(`\u2713 ${e}`))}function yu(e){console.log(f.blue(e))}function Su(e,t=2){console.log(f.gray(`${" ".repeat(t)}${e}`))}function bu(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`}function xu(e,t,n=rt){let r=n-2,s="\u2500".repeat(r);console.log(),console.log(f.cyan(`\u256D${s}\u256E`)),console.log(f.cyan("\u2502")+f.bold.white(En(e,r))+f.cyan("\u2502")),t&&(console.log(f.cyan(`\u251C${s}\u2524`)),console.log(f.cyan("\u2502")+f.gray(En(t,r))+f.cyan("\u2502"))),console.log(f.cyan(`\u2570${s}\u256F`))}import{existsSync as eo}from"node:fs";import{dirname as to,join as no,resolve as _n}from"node:path";import{cwd as ro}from"node:process";var Rn={name:"tdk-cli-internal",private:!0,version:"1.3.135",description:"TDK CLI \u2014 start services on your laptop.",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=ro()){let t=_n(e),n=_n("/");for(;t!==n;){if(eo(no(t,".tdk","project.json")))return t;let r=to(t);if(r===t)break;t=r}return null}var $e=null;function so(){if($e)return $e;let e=Rn;if(!e||typeof e!="object"||Array.isArray(e))throw new Error("Invalid package.json: expected object");let t=e;return $e={name:String(t.name??"@tdk-landscape/tdk-cli-core"),version:String(t.version??"0.0.0"),fullPackage:t},$e}function On(){return so().version}import{readFileSync as oo}from"node:fs";import{join as io}from"node:path";function st(){let e=m();if(e)try{let t=oo(io(e,".tdk","project.json"),"utf-8"),n=JSON.parse(t);if(n?.project?.name)return n.project.name}catch{}return"tdk-project"}function ot(e){let t=st(),n=process.env.TDK_SERVICE_BASE_URL??`http://${t}.localhost${e?`:${e}`:""}`;try{let r=new URL(n.includes("://")?n:`http://${n}`),s=r.hostname,o=r.port||(e?String(e):"");if(s==="localhost"||/^\d+\.\d+\.\d+\.\d+$/.test(s))return{appBase:`${r.protocol}//${s}${o?`:${o}`:""}`,apiBase:`${r.protocol}//${s}${o?`:${o}`:""}`};let i=s.replace(/^(app|api)\./,"");return{appBase:`${r.protocol}//app.${i}${o?`:${o}`:""}`,apiBase:`${r.protocol}//api.${i}${o?`:${o}`:""}`}}catch{return{appBase:`http://app.${t}.localhost`,apiBase:`http://api.${t}.localhost`}}}function ao(e){return`${e.replace(/\/+$/,"")}/health`}function it(e){if(P(e.config?.appType)){let t=e.name.replace(/-api$/,"");return e.config?.apiPath??`/api/${t}`}return e.config?.basePath??`/${e.name}`}function An(e,t){let{appBase:n,apiBase:r}=ot(t);return e.filter(s=>s.config?.appType==="frontend"||P(s.config?.appType)).map(s=>{let o=P(s.config.appType)?r:n;return{name:s.name,appType:s.config.appType,url:`${o}${ao(it(s))}`}})}async function co(e,t){try{let n=await fetch(e.url,{method:"GET",redirect:"manual",signal:AbortSignal.timeout(t)});return{...e,ok:n.ok,status:n.status}}catch(n){let r=n instanceof Error&&n.name==="TimeoutError"?`no response within ${t}ms`:n instanceof Error?n.message:String(n);return{...e,ok:!1,error:r}}}async function Dn(e,t){return Promise.all(e.map(n=>co(n,t)))}import{existsSync as J,readdirSync as nr,readFileSync as rr,statSync as mt}from"node:fs";import{dirname as Jo,join as U}from"node:path";var ce=class{data;options;constructor(t){this.data=new Map,this.options=t}has(t){let n=this.data.get(t);return n?Date.now()-n.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,n){this.data.set(t,{value:n,timestamp:Date.now()})}delete(t){this.data.delete(t)}clear(){this.data.clear()}keys(){let t=[];for(let n of this.data.keys())this.has(n)&&t.push(n);return t}size(){return this.keys().length}};function Cn(e){let t=0;return{isValid(){return Date.now()-t<e},markUpdated(){t=Date.now()},reset(){t=0}}}import{execFileSync as yo,execSync as So}from"node:child_process";import{existsSync as mo}from"node:fs";import{delimiter as ho,extname as go,join as ko}from"node:path";import{delimiter as Iu,extname as uo}from"node:path";function Ee(){return process.platform==="win32"}function lo(e){return e==="linux"?"linux":e==="darwin"?"darwin":e==="win32"?"windows":null}function po(e){return e==="x64"?"amd64":e==="arm64"?"arm64":null}function fo(e,t){let n=lo(e),r=po(t);if(!n||!r||n==="windows"&&r!=="amd64")return null;let s=`tdk-${n}-${r}`;return n==="windows"?`${s}.exe`:s}function Fu(){return fo(process.platform,process.arch)}function Mu(){return Ee()?"tdk.exe":"tdk"}function Nn(e,t=Ee()){return t?uo(e)?[e]:[e,`${e}.exe`,`${e}.cmd`,`${e}.bat`]:[e]}function $(e){let t=process.env.PATH??process.env.Path??"",n=Ee(),r=Nn(e,n);if(n&&!go(e))for(let s of(process.env.PATHEXT??".EXE;.CMD;.BAT;.COM").split(";")){let o=s.toLowerCase();o&&!r.includes(`${e}${o}`)&&r.push(`${e}${o}`)}for(let s of t.split(ho))if(s)for(let o of r){let i=ko(s,o);if(mo(i))return i}return null}var jn=1e4;function In(){let e=!1;if(process.platform==="win32")try{return yo($("docker")??"docker",["ps"],{stdio:"ignore",timeout:jn,windowsHide:!0}),"running"}catch(t){return t.code==="ETIMEDOUT"?"unresponsive":"missing"}for(let t of["docker ps","colima status","podman ps"])try{return So(t,{stdio:"ignore",timeout:jn}),"running"}catch(n){n.code==="ETIMEDOUT"&&(e=!0)}return e?"unresponsive":"missing"}function bo(e,t){let n=Array.from({length:t.length+1},(r,s)=>s);for(let r=1;r<=e.length;r++){let s=[r];for(let o=1;o<=t.length;o++){let i=e[r-1]===t[o-1]?0:1;s[o]=Math.min(s[o-1]+1,n[o]+1,n[o-1]+i)}n=s}return n[t.length]}function xo(e,t){if(e.length!==t.length)return!1;for(let n=0;n<e.length-1;n++)if(e[n]!==t[n]&&e[n]===t[n+1]&&e[n+1]===t[n]&&e.slice(0,n)===t.slice(0,n)&&e.slice(n+2)===t.slice(n+2))return!0;return!1}function Fn(e,t){if(e.length<2||t.length===0||t.includes(e))return;let n=e.toLowerCase(),r,s=Number.POSITIVE_INFINITY;for(let o of t){if(o.length===0)continue;let i=o.toLowerCase(),a=xo(n,i)?1:bo(n,i),c=Math.max(1,Math.min(2,Math.floor(Math.max(n.length,i.length)/3)));a>c||(a<s||a===s&&(r===void 0||o<r))&&(r=o,s=a)}return r}import{spawn as To}from"node:child_process";import{join as wo}from"node:path";function vo(e,t=[],n={}){return new Promise((r,s)=>{let o=[e,...t];n.verbose&&console.log(`Executing: tilt ${o.join(" ")}`);let i=To($("tilt")??"tilt",o,{stdio:n.inheritStdio?"inherit":"pipe",shell:!1,windowsHide:process.platform==="win32",timeout:n.timeoutMs}),a="",c="";n.inheritStdio||(i.stdout?.on("data",u=>{a+=u.toString()}),i.stderr?.on("data",u=>{c+=u.toString()})),i.on("close",u=>{r({exitCode:u??1,stdout:a,stderr:c})}),i.on("error",u=>{s(new Error(`Failed to spawn tilt: ${u.message}`))})})}async function Mn(){try{return(await vo("version",[],{inheritStdio:!1,timeoutMs:1e4})).exitCode===0}catch{return!1}}function Po(){let e=m();if(!e)throw I.notInProject();return wo(e,".tdk",".tdk-out","Tiltfile")}function Ln(e){let t=Po();e.push("-f",t)}function Qu(e,t={}){let n=[];return Ln(n),t.focusTargets&&t.focusTargets.length>0&&n.push("--",`--focus=${t.focusTargets.join(",")}`),n.push(...e),t.verbose&&!t.quiet&&n.push("--verbose"),t.watch&&n.push("--watch"),n}function ed(e={}){let t=[];return Ln(t),e.force&&t.push("--force"),e.focusTargets&&e.focusTargets.length>0&&t.push("--",`--focus=${e.focusTargets.join(",")}`),t}function Bn(e){return e instanceof Error?e.message:String(e)}function cd(e,t){if(process.env.TDK_VERBOSE){let n=t!==void 0?`: ${Bn(t)}`:"";console.warn(f.gray(`${e}${n}`))}}var E=class extends Error{suggestions;exitCode;constructor(t,n=[],r=1){super(t),this.name="TdkError",this.suggestions=n,this.exitCode=r}display(){Ro(this.message,void 0,this.suggestions)}exit(){this.display(),process.exit(this.exitCode)}};function at(e,t,n=!1){let r=new Set;for(let s of e){let o=Fn(s,t);o&&r.add(n?`Did you mean "${o}" for "${s}"?`:`Did you mean "${o}"?`)}return[...r]}var I={tiltNotInstalled:()=>new E("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: ${Qe}`]),dockerNotAvailable:()=>new E("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: ${Qe}`]),dockerNotResponding:()=>new E("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 E(`Stack "${e}" not found`,[...at([e],t),"Run `tdk stacks` to see available stacks","Run `tdk stack` to assign resources to a stack"]),resourceNotFound:(e,t=[])=>new E(`Resource "${e}" not found`,[...at([e],t),"Run `tdk resources` to list all resources","Check the resource name spelling"]),unknownServices:(e,t)=>{let n=at(e,t,e.length>1);return new E(`Unknown service ${e.join(", ")}. Valid names: ${t.join(", ")}`,n,2)},directoryExists:e=>new E(`Directory already exists: ${e}`,["Use `--path` to specify a different location","Remove the existing directory if no longer needed"]),invalidPath:e=>new E(`Invalid path: ${e}`,["Path must be within the project directory",'Path cannot contain special characters like <>:"|?*']),notInProject:()=>new E("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 ud(){let e=m();return e||I.notInProject().exit()}function $o(e){e instanceof E&&e.exit(),console.error(f.red(`Error: ${Bn(e)}`)),process.exit(1)}async function Eo(e,t){try{return await e()}catch(n){return t?.verbose&&n instanceof Error&&n.stack&&console.error(f.gray(n.stack)),$o(n)}}async function dd(e,t){let n=[],r=In();return r==="unresponsive"?n.push(I.dockerNotResponding()):r==="missing"&&n.push(I.dockerNotAvailable()),await Mn()||n.push(I.tiltNotInstalled()),n.length>0&&(console.error(f.red(`
12
+ `))}function fu(e,t){console.log(f.green(`All ${e} are ${t}!`))}var rt=62;function mu(e="\u2500",t=rt){return e.repeat(t)}function En(e,t=rt-2){let n=Math.max(0,t-e.length),r=Math.floor(n/2),s=n-r;return" ".repeat(r)+e+" ".repeat(s)}function hu(e,t){return e.length>t?`${e.slice(0,t-1)}\u2026`:e.padEnd(t)}function gu(e,t){return e.length<=t?e:`${e.slice(0,t-3)}...`}function ku(e){console.log(f.green(`\u2713 ${e}`))}function yu(e){console.log(f.blue(e))}function Su(e,t=2){console.log(f.gray(`${" ".repeat(t)}${e}`))}function bu(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`}function xu(e,t,n=rt){let r=n-2,s="\u2500".repeat(r);console.log(),console.log(f.cyan(`\u256D${s}\u256E`)),console.log(f.cyan("\u2502")+f.bold.white(En(e,r))+f.cyan("\u2502")),t&&(console.log(f.cyan(`\u251C${s}\u2524`)),console.log(f.cyan("\u2502")+f.gray(En(t,r))+f.cyan("\u2502"))),console.log(f.cyan(`\u2570${s}\u256F`))}import{existsSync as eo}from"node:fs";import{dirname as to,join as no,resolve as _n}from"node:path";import{cwd as ro}from"node:process";var Rn={name:"tdk-cli-internal",private:!0,version:"1.3.136",description:"TDK CLI \u2014 start services on your laptop.",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=ro()){let t=_n(e),n=_n("/");for(;t!==n;){if(eo(no(t,".tdk","project.json")))return t;let r=to(t);if(r===t)break;t=r}return null}var $e=null;function so(){if($e)return $e;let e=Rn;if(!e||typeof e!="object"||Array.isArray(e))throw new Error("Invalid package.json: expected object");let t=e;return $e={name:String(t.name??"@tdk-landscape/tdk-cli-core"),version:String(t.version??"0.0.0"),fullPackage:t},$e}function On(){return so().version}import{readFileSync as oo}from"node:fs";import{join as io}from"node:path";function st(){let e=m();if(e)try{let t=oo(io(e,".tdk","project.json"),"utf-8"),n=JSON.parse(t);if(n?.project?.name)return n.project.name}catch{}return"tdk-project"}function ot(e){let t=st(),n=process.env.TDK_SERVICE_BASE_URL??`http://${t}.localhost${e?`:${e}`:""}`;try{let r=new URL(n.includes("://")?n:`http://${n}`),s=r.hostname,o=r.port||(e?String(e):"");if(s==="localhost"||/^\d+\.\d+\.\d+\.\d+$/.test(s))return{appBase:`${r.protocol}//${s}${o?`:${o}`:""}`,apiBase:`${r.protocol}//${s}${o?`:${o}`:""}`};let i=s.replace(/^(app|api)\./,"");return{appBase:`${r.protocol}//app.${i}${o?`:${o}`:""}`,apiBase:`${r.protocol}//api.${i}${o?`:${o}`:""}`}}catch{return{appBase:`http://app.${t}.localhost`,apiBase:`http://api.${t}.localhost`}}}function ao(e){return`${e.replace(/\/+$/,"")}/health`}function it(e){if(P(e.config?.appType)){let t=e.name.replace(/-api$/,"");return e.config?.apiPath??`/api/${t}`}return e.config?.basePath??`/${e.name}`}function An(e,t){let{appBase:n,apiBase:r}=ot(t);return e.filter(s=>s.config?.appType==="frontend"||P(s.config?.appType)).map(s=>{let o=P(s.config.appType)?r:n;return{name:s.name,appType:s.config.appType,url:`${o}${ao(it(s))}`}})}async function co(e,t){try{let n=await fetch(e.url,{method:"GET",redirect:"manual",signal:AbortSignal.timeout(t)});return{...e,ok:n.ok,status:n.status}}catch(n){let r=n instanceof Error&&n.name==="TimeoutError"?`no response within ${t}ms`:n instanceof Error?n.message:String(n);return{...e,ok:!1,error:r}}}async function Dn(e,t){return Promise.all(e.map(n=>co(n,t)))}import{existsSync as J,readdirSync as nr,readFileSync as rr,statSync as mt}from"node:fs";import{dirname as Jo,join as U}from"node:path";var ce=class{data;options;constructor(t){this.data=new Map,this.options=t}has(t){let n=this.data.get(t);return n?Date.now()-n.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,n){this.data.set(t,{value:n,timestamp:Date.now()})}delete(t){this.data.delete(t)}clear(){this.data.clear()}keys(){let t=[];for(let n of this.data.keys())this.has(n)&&t.push(n);return t}size(){return this.keys().length}};function Cn(e){let t=0;return{isValid(){return Date.now()-t<e},markUpdated(){t=Date.now()},reset(){t=0}}}import{execFileSync as yo,execSync as So}from"node:child_process";import{existsSync as mo}from"node:fs";import{delimiter as ho,extname as go,join as ko}from"node:path";import{delimiter as Iu,extname as uo}from"node:path";function Ee(){return process.platform==="win32"}function lo(e){return e==="linux"?"linux":e==="darwin"?"darwin":e==="win32"?"windows":null}function po(e){return e==="x64"?"amd64":e==="arm64"?"arm64":null}function fo(e,t){let n=lo(e),r=po(t);if(!n||!r||n==="windows"&&r!=="amd64")return null;let s=`tdk-${n}-${r}`;return n==="windows"?`${s}.exe`:s}function Fu(){return fo(process.platform,process.arch)}function Mu(){return Ee()?"tdk.exe":"tdk"}function Nn(e,t=Ee()){return t?uo(e)?[e]:[e,`${e}.exe`,`${e}.cmd`,`${e}.bat`]:[e]}function $(e){let t=process.env.PATH??process.env.Path??"",n=Ee(),r=Nn(e,n);if(n&&!go(e))for(let s of(process.env.PATHEXT??".EXE;.CMD;.BAT;.COM").split(";")){let o=s.toLowerCase();o&&!r.includes(`${e}${o}`)&&r.push(`${e}${o}`)}for(let s of t.split(ho))if(s)for(let o of r){let i=ko(s,o);if(mo(i))return i}return null}var jn=1e4;function In(){let e=!1;if(process.platform==="win32")try{return yo($("docker")??"docker",["ps"],{stdio:"ignore",timeout:jn,windowsHide:!0}),"running"}catch(t){return t.code==="ETIMEDOUT"?"unresponsive":"missing"}for(let t of["docker ps","colima status","podman ps"])try{return So(t,{stdio:"ignore",timeout:jn}),"running"}catch(n){n.code==="ETIMEDOUT"&&(e=!0)}return e?"unresponsive":"missing"}function bo(e,t){let n=Array.from({length:t.length+1},(r,s)=>s);for(let r=1;r<=e.length;r++){let s=[r];for(let o=1;o<=t.length;o++){let i=e[r-1]===t[o-1]?0:1;s[o]=Math.min(s[o-1]+1,n[o]+1,n[o-1]+i)}n=s}return n[t.length]}function xo(e,t){if(e.length!==t.length)return!1;for(let n=0;n<e.length-1;n++)if(e[n]!==t[n]&&e[n]===t[n+1]&&e[n+1]===t[n]&&e.slice(0,n)===t.slice(0,n)&&e.slice(n+2)===t.slice(n+2))return!0;return!1}function Fn(e,t){if(e.length<2||t.length===0||t.includes(e))return;let n=e.toLowerCase(),r,s=Number.POSITIVE_INFINITY;for(let o of t){if(o.length===0)continue;let i=o.toLowerCase(),a=xo(n,i)?1:bo(n,i),c=Math.max(1,Math.min(2,Math.floor(Math.max(n.length,i.length)/3)));a>c||(a<s||a===s&&(r===void 0||o<r))&&(r=o,s=a)}return r}import{spawn as To}from"node:child_process";import{join as wo}from"node:path";function vo(e,t=[],n={}){return new Promise((r,s)=>{let o=[e,...t];n.verbose&&console.log(`Executing: tilt ${o.join(" ")}`);let i=To($("tilt")??"tilt",o,{stdio:n.inheritStdio?"inherit":"pipe",shell:!1,windowsHide:process.platform==="win32",timeout:n.timeoutMs}),a="",c="";n.inheritStdio||(i.stdout?.on("data",u=>{a+=u.toString()}),i.stderr?.on("data",u=>{c+=u.toString()})),i.on("close",u=>{r({exitCode:u??1,stdout:a,stderr:c})}),i.on("error",u=>{s(new Error(`Failed to spawn tilt: ${u.message}`))})})}async function Mn(){try{return(await vo("version",[],{inheritStdio:!1,timeoutMs:1e4})).exitCode===0}catch{return!1}}function Po(){let e=m();if(!e)throw I.notInProject();return wo(e,".tdk",".tdk-out","Tiltfile")}function Ln(e){let t=Po();e.push("-f",t)}function Qu(e,t={}){let n=[];return Ln(n),t.focusTargets&&t.focusTargets.length>0&&n.push("--",`--focus=${t.focusTargets.join(",")}`),n.push(...e),t.verbose&&!t.quiet&&n.push("--verbose"),t.watch&&n.push("--watch"),n}function ed(e={}){let t=[];return Ln(t),e.force&&t.push("--force"),e.focusTargets&&e.focusTargets.length>0&&t.push("--",`--focus=${e.focusTargets.join(",")}`),t}function Bn(e){return e instanceof Error?e.message:String(e)}function cd(e,t){if(process.env.TDK_VERBOSE){let n=t!==void 0?`: ${Bn(t)}`:"";console.warn(f.gray(`${e}${n}`))}}var E=class extends Error{suggestions;exitCode;constructor(t,n=[],r=1){super(t),this.name="TdkError",this.suggestions=n,this.exitCode=r}display(){Ro(this.message,void 0,this.suggestions)}exit(){this.display(),process.exit(this.exitCode)}};function at(e,t,n=!1){let r=new Set;for(let s of e){let o=Fn(s,t);o&&r.add(n?`Did you mean "${o}" for "${s}"?`:`Did you mean "${o}"?`)}return[...r]}var I={tiltNotInstalled:()=>new E("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: ${Qe}`]),dockerNotAvailable:()=>new E("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: ${Qe}`]),dockerNotResponding:()=>new E("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 E(`Stack "${e}" not found`,[...at([e],t),"Run `tdk stacks` to see available stacks","Run `tdk stack` to assign resources to a stack"]),resourceNotFound:(e,t=[])=>new E(`Resource "${e}" not found`,[...at([e],t),"Run `tdk resources` to list all resources","Check the resource name spelling"]),unknownServices:(e,t)=>{let n=at(e,t,e.length>1);return new E(`Unknown service ${e.join(", ")}. Valid names: ${t.join(", ")}`,n,2)},directoryExists:e=>new E(`Directory already exists: ${e}`,["Use `--path` to specify a different location","Remove the existing directory if no longer needed"]),invalidPath:e=>new E(`Invalid path: ${e}`,["Path must be within the project directory",'Path cannot contain special characters like <>:"|?*']),notInProject:()=>new E("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 ud(){let e=m();return e||I.notInProject().exit()}function $o(e){e instanceof E&&e.exit(),console.error(f.red(`Error: ${Bn(e)}`)),process.exit(1)}async function Eo(e,t){try{return await e()}catch(n){return t?.verbose&&n instanceof Error&&n.stack&&console.error(f.gray(n.stack)),$o(n)}}async function dd(e,t){let n=[],r=In();return r==="unresponsive"?n.push(I.dockerNotResponding()):r==="missing"&&n.push(I.dockerNotAvailable()),await Mn()||n.push(I.tiltNotInstalled()),n.length>0&&(console.error(f.red(`
13
13
  TDK can't start - missing prerequisites:
14
14
  `)),n.forEach((s,o)=>{o>0&&console.error(""),s.display()}),console.error(f.gray("\nRun `tdk doctor` for a full environment check.")),process.exit(1)),Eo(e,t)}function ld(e,t=1){console.error(f.red(`Error: ${e}`)),process.exit(t)}function Ro(e,t,n){console.error(f.red(`\u274C ${e}`)),t&&console.error(f.gray(` ${t}`)),n&&n.length>0&&(console.error(f.yellow(`
15
15
  \u{1F4A1} Suggestions:`)),n.forEach(r=>{console.error(f.cyan(` \u2192 ${r}`))}))}function pd(e,t){console.error(f.red(`
16
- tilt ${e} failed with exit code ${t}`)),process.exit(t)}import{existsSync as Xn,readFileSync as Zn}from"node:fs";import{copyFileSync as Un,mkdirSync as _o,rmSync as Hn,writeFileSync as Vn}from"node:fs";import{join as q}from"node:path";var Oo=60,Wn=1e3,Kn=1e4,Gn=200,qn=64*1024,Jn=new Set([404,502,503,504]),Ao=new Set(["ECONNREFUSED","ENOTFOUND","EAI_AGAIN","EHOSTUNREACH","ENETUNREACH"]),Do=new Set(["GET","HEAD","OPTIONS"]);function L(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Co(e,t){if(Do.has(t))return!0;if(!L(e))return!1;let n=L(e.cause)?e.cause:void 0,r=e.code??n?.code;return typeof r=="string"&&Ao.has(r)}function ut(e){if(!L(e))return['smoke: must be an object with "via" and "steps"'];let t=[];return e.via!=="proxy"&&t.push('smoke.via: only "proxy" is supported (the check must go through the public URL)'),e.timeoutSeconds!==void 0&&!(typeof e.timeoutSeconds=="number"&&e.timeoutSeconds>0)&&t.push("smoke.timeoutSeconds: must be a number greater than 0"),!Array.isArray(e.steps)||e.steps.length===0?(t.push("smoke.steps: needs at least one step"),t):(e.steps.forEach((n,r)=>{let s=`smoke.steps[${r}]`;if(!L(n)){t.push(`${s}: must be an object`);return}let o=n.path;(typeof o!="string"||!o.startsWith("/")||o.startsWith("//"))&&t.push(`${s}.path: must start with "/" and is appended to the public URL; a full URL or relative path would skip the proxy`),n.expect!==void 0&&!(typeof n.expect=="number"&&Number.isInteger(n.expect)&&n.expect>=100&&n.expect<=599)&&t.push(`${s}.expect: must be an HTTP status between 100 and 599`),n.bodyContains!==void 0&&typeof n.bodyContains!="string"&&t.push(`${s}.bodyContains: must be a string`),n.save!==void 0&&(L(n.save)&&Object.values(n.save).every(a=>typeof a=="string"&&a.startsWith("$."))||t.push(`${s}.save: must map names to paths such as "$.id"`))}),t)}function yd(e,t){let{appBase:n,apiBase:r}=ot(t),s=[];for(let o of e){let i=o.config;if(!i?.smoke)continue;let a=i.appType,c=P(a)||a==="bring-your-own";if(!c&&a!=="frontend"||i.exposeViaProxy===!1)continue;let u=c?r:n,d=i.healthCheckPath||(c&&a!=="bring-your-own"?"/health":void 0);s.push({name:o.name,baseUrl:`${u}${it(o).replace(/\/+$/,"")}`,...d?.startsWith("/")?{readyPath:d}:{},smoke:i.smoke})}return s}function No(e,t){let n=t.replace(/^\$\.?/,"").match(/[^.[\]]+/g)??[],r=e;for(let s of n){if(r==null)return;r=r[s]}return r}function zn(e,t){return e.replace(/\{\{(\w+)\}\}/g,(n,r)=>t[r]??n)}function ct(e,t){return typeof e=="string"?zn(e,t):Array.isArray(e)?e.map(n=>ct(n,t)):L(e)?Object.fromEntries(Object.entries(e).map(([n,r])=>[n,ct(r,t)])):e}function Re(e){let t=e.replace(/\s+/g," ").trim();return t.length>Gn?`${t.slice(0,Gn)}...`:t}function Yn(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"step"}function jo(e,t){let n=Yn(t),r=(e.get(n)??0)+1;return e.set(n,r),r===1?n:`${n}-${r}`}function Io(e,t,n,r,s){try{let o=q(e,Yn(n.service),t);_o(o,{recursive:!0});let i=q(o,"latest.json"),a=q(o,"body.txt");return r===void 0?Hn(a,{force:!0}):Vn(a,r),Vn(i,`${JSON.stringify({...n,bodyPath:r===void 0?null:"body.txt"},null,2)}
16
+ tilt ${e} failed with exit code ${t}`)),process.exit(t)}import{existsSync as Xn,readFileSync as Zn}from"node:fs";import{copyFileSync as Un,mkdirSync as _o,rmSync as Hn,writeFileSync as Vn}from"node:fs";import{join as q}from"node:path";var Oo=60,Wn=1e3,Kn=1e4,Gn=200,qn=64*1024,Jn=new Set([404,502,503,504]),Ao=new Set(["ECONNREFUSED","ENOTFOUND","EAI_AGAIN","EHOSTUNREACH","ENETUNREACH"]),Do=new Set(["GET","HEAD","OPTIONS"]);function L(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Co(e,t){if(Do.has(t))return!0;if(!L(e))return!1;let n=L(e.cause)?e.cause:void 0,r=e.code??n?.code;return typeof r=="string"&&Ao.has(r)}function ut(e){if(!L(e))return['smoke: must be an object with "via" and "steps"'];let t=[];return e.via!=="proxy"&&t.push('smoke.via: only "proxy" is supported (the check must go through the public URL)'),e.timeoutSeconds!==void 0&&!(typeof e.timeoutSeconds=="number"&&e.timeoutSeconds>0)&&t.push("smoke.timeoutSeconds: must be a number greater than 0"),!Array.isArray(e.steps)||e.steps.length===0?(t.push("smoke.steps: needs at least one step"),t):(e.steps.forEach((n,r)=>{let s=`smoke.steps[${r}]`;if(!L(n)){t.push(`${s}: must be an object`);return}let o=n.path;(typeof o!="string"||!o.startsWith("/")||o.startsWith("//"))&&t.push(`${s}.path: must start with "/" and is appended to the public URL; a full URL or relative path would skip the proxy`),n.expect!==void 0&&!(typeof n.expect=="number"&&Number.isInteger(n.expect)&&n.expect>=100&&n.expect<=599)&&t.push(`${s}.expect: must be an HTTP status between 100 and 599`),n.bodyContains!==void 0&&typeof n.bodyContains!="string"&&t.push(`${s}.bodyContains: must be a string`),n.save!==void 0&&(L(n.save)&&Object.values(n.save).every(a=>typeof a=="string"&&a.startsWith("$."))||t.push(`${s}.save: must map names to paths such as "$.id"`))}),t)}function yd(e,t){let{appBase:n,apiBase:r}=ot(t),s=[];for(let o of e){let i=o.config;if(!i?.smoke)continue;let a=i.appType,c=P(a)||a==="bring-your-own";if(!c&&a!=="frontend"||i.exposeViaProxy===!1)continue;let u=c?r:n,d=i.healthCheckPath||(c&&a!=="bring-your-own"?"/health":void 0);s.push({name:o.name,baseUrl:`${u}${it(o).replace(/\/+$/,"")}`,...d?.startsWith("/")?{readyPath:d}:{},smoke:i.smoke})}return s}function No(e,t){let n=t.replace(/^\$\.?/,"").match(/[^.[\]]+/g)??[],r=e;for(let s of n){if(r==null||!Object.hasOwn(r,s))return;r=r[s]}return r}function zn(e,t){return e.replace(/\{\{(\w+)\}\}/g,(n,r)=>t[r]??n)}function ct(e,t){return typeof e=="string"?zn(e,t):Array.isArray(e)?e.map(n=>ct(n,t)):L(e)?Object.fromEntries(Object.entries(e).map(([n,r])=>[n,ct(r,t)])):e}function Re(e){let t=e.replace(/\s+/g," ").trim();return t.length>Gn?`${t.slice(0,Gn)}...`:t}function Yn(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"step"}function jo(e,t){let n=Yn(t),r=(e.get(n)??0)+1;return e.set(n,r),r===1?n:`${n}-${r}`}function Io(e,t,n,r,s){try{let o=q(e,Yn(n.service),t);_o(o,{recursive:!0});let i=q(o,"latest.json"),a=q(o,"body.txt");return r===void 0?Hn(a,{force:!0}):Vn(a,r),Vn(i,`${JSON.stringify({...n,bodyPath:r===void 0?null:"body.txt"},null,2)}
17
17
  `),s&&(Un(i,q(o,"last-success.json")),r===void 0?Hn(q(o,"last-success-body.txt"),{force:!0}):Un(a,q(o,"last-success-body.txt"))),i}catch{return}}function Fo(e){let t=Buffer.from(e,"utf8");if(t.length<=qn)return{body:e,truncated:!1,bytes:t.length};let n=t.subarray(0,qn).toString("utf8").replace(/\uFFFD$/,"");return{body:n,truncated:!0,bytes:Buffer.byteLength(n,"utf8")}}async function Mo(e,t={}){let n=t.fetch??((d,l)=>fetch(d,l)),r=t.now??Date.now,s=t.sleep??(d=>new Promise(l=>setTimeout(l,d))),o=(e.smoke.timeoutSeconds??Oo)*1e3,i=r()+o,a={},c=ut(e.smoke);if(c.length>0)return{name:e.name,ok:!1,failure:`${e.name}: invalid smoke block: ${c.join("; ")}`};if(e.readyPath){let d=`${e.baseUrl}${e.readyPath}`;for(;;){try{let l=await n(d,{method:"GET",signal:AbortSignal.timeout(Kn)});if(await l.text(),!Jn.has(l.status)&&l.status<500)break}catch{}if(r()>=i)break;await s(Wn)}}i=r()+o;let u=new Map;for(let[d,l]of e.smoke.steps.entries()){let h=l.name??`step ${d+1}`,k=(l.method??"GET").toUpperCase(),g=`${e.baseUrl}${zn(l.path,a)}`,p=l.expect??200,y=l.body!==void 0,v,D="",M,Ve;for(;;){M=void 0,Ve=void 0,v=void 0;let C=!1;try{let R=await n(g,{method:k,headers:y?{"content-type":"application/json"}:void 0,body:y?JSON.stringify(ct(l.body,a)):void 0,signal:AbortSignal.timeout(Kn)});v=R.status,D=await R.text()}catch(R){C=Co(R,k),M=R instanceof Error?R.message:String(R);let V=L(R)?R.code??(L(R.cause)?R.cause.code:void 0):void 0;Ve=typeof V=="string"?V:void 0}if(!(M!==void 0&&C||v!==void 0&&v!==p&&Jn.has(v))||r()>=i)break;await s(Wn)}let te=`${e.name}: ${h}: ${k} ${g}`,en;if(t.recordDir){let C=v===void 0?void 0:Fo(D),re=M===void 0&&v===p&&(l.bodyContains===void 0||D.includes(l.bodyContains));en=Io(t.recordDir,jo(u,h),{service:e.name,step:h,method:k,url:g,expectedStatus:p,status:v??null,...M===void 0?{}:{error:Ve??M},truncated:C?.truncated??!1,bodyBytes:C?.bytes??0},C?.body,re)}let ne=C=>({name:e.name,ok:!1,failure:C,recordPath:en});if(M!==void 0)return ne(`${te} never answered (${M})`);if(v!==p)return ne(`${te} returned ${v}, expected ${p}${D?`: ${Re(D)}`:""}`);if(l.bodyContains!==void 0&&!D.includes(l.bodyContains))return ne(`${te} returned ${v} but the body does not contain "${l.bodyContains}": ${Re(D)}`);if(l.save){let C;try{C=JSON.parse(D)}catch{return ne(`${te} returned a body that is not JSON, cannot save: ${Re(D)}`)}for(let[re,R]of Object.entries(l.save)){let V=No(C,R);if(V==null||typeof V=="object")return ne(`${te} response has no ${R} to save as {{${re}}}: ${Re(D)}`);a[re]=String(V)}}}return{name:e.name,ok:!0}}function Sd(e){return`Smoke check failed: ${e.failure}${e.recordPath?` (record: ${e.recordPath})`:""}`}async function bd(e,t={}){return Promise.all(e.map(n=>Mo(n,t)))}var ue=1,vd="https://tdk-landscape.github.io/schema.service.json",Lo={dependencies:"deprecated, use dependsOn (still read for now)",envVars:"deprecated, use params (still read when params is absent)",jwtSecret:"ignored. A secret must not be committed: remove it and set JWT_SECRET in the project .env"},Bo=new Set(["$schema","apiBasePath","apiPath","appName","appType","backendName","basePath","build","buildContext","databaseName","dependencies","dev","dependsOn","dockerfile","enabled","exposeViaProxy","featuresEnabled","framework","healthCheckPath","image","language","name","nats","params","playwright","port","replicas","restart","runtime","sablier","schemaVersion","secrets","smoke","stack","syncs","traefik","type"]),Uo=[{path:["healthCheckPath"],pattern:/^\/[a-z0-9/-]*$/,expected:"a path such as /health"},{path:["traefik","host"],pattern:/^[A-Za-z0-9.-]+$/,expected:"a hostname such as shop.backend.myproject.local"},{path:["traefik","pathPrefix"],pattern:/^\/[a-z0-9/-]*$/,expected:"a path such as /api/v1/shop-management"},{path:["traefik","healthCheck"],pattern:/^\/[a-z0-9/-]*$/,expected:"a path such as /health"},{path:["nats","queueGroup"],pattern:/^[A-Za-z0-9_.-]+$/,expected:"letters, digits, '_', '.' or '-'"},{path:["databaseName"],pattern:/^[A-Za-z0-9_-]+$/,expected:"letters, digits, '_' or '-'"},{path:["stack"],pattern:/^[A-Za-z0-9_-]+$/,expected:"letters, digits, '_' or '-'"},{path:["image"],pattern:/^[A-Za-z0-9._/:@-]+$/,expected:"an image reference such as ghcr.io/acme/app:1.0"}];function _e(e,t){let n=[],r=new Set;for(let{path:s,pattern:o,expected:i}of Uo){let a=e;for(let u of s)a=a&&typeof a=="object"&&!Array.isArray(a)?a[u]:void 0;if(a==null||a==="")continue;let c=`${t}.${s.join(".")}`;(typeof a!="string"||!o.test(a))&&r.add(c),typeof a!="string"?n.push(`${c}: expected a string`):o.test(a)||n.push(`${c}: must be ${i} (no spaces, line breaks or YAML syntax)`)}for(let[s,o]of Ho(e,t))r.has(s)||n.push(`${s}: ${o}`);return n}function dt(e){for(let t=0;t<e.length;t++){let n=e.charCodeAt(t);if(n<32||n===127||n===133||n===8232||n===8233)return!0}return!1}function Ho(e,t){let n=[],r=Object.entries(e).filter(([s])=>s!=="smoke").map(([s,o])=>[o,`${t}.${s}`]);for(let s of Object.keys(e))dt(s)&&n.push([t,"a key contains a line break"]);for(;r.length>0;){let[s,o]=r.pop();if(typeof s=="string")dt(s)&&n.push([o,"must not contain line breaks or control characters"]);else if(Array.isArray(s))for(let[i,a]of s.entries())r.push([a,`${o}[${i}]`]);else if(s&&typeof s=="object")for(let[i,a]of Object.entries(s))dt(i)?n.push([o,"a key contains a line break"]):r.push([a,`${o}.${i}`])}return n.sort(([s],[o])=>s.localeCompare(o))}var Vo=["apiPath","basePath"];function lt(e){if(!e||typeof e!="object"||Array.isArray(e))return[];let t=e;return Vo.filter(n=>n in t&&typeof t[n]!="string")}function pt(e,t){if(!e||typeof e!="object"||Array.isArray(e))return{errors:[`${t}: expected a JSON object`],warnings:[]};let n=e,r=[];for(let a of["appName","appType","stack","schemaVersion"])a in n||r.push(`${t}.${a}: required field is missing`);for(let a of["appName","appType","stack"])a in n&&typeof n[a]!="string"&&r.push(`${t}.${a}: expected a string`);"schemaVersion"in n&&n.schemaVersion!==ue&&r.push(`${t}.schemaVersion: unsupported version ${String(n.schemaVersion)} (supported: ${ue})`);for(let a of lt(n))r.push(`${t}.${a}: expected a string`);let s=n.dev,o=s&&typeof s=="object"&&!Array.isArray(s)?s.liveReload:void 0;if(o!==void 0&&typeof o!="boolean"&&r.push(`${t}.dev.liveReload: expected true or false`),r.push(..._e(n,t)),"smoke"in n)for(let a of ut(n.smoke))r.push(`${t}.${a}`);let i=Object.keys(n).flatMap(a=>{let c=Lo[a];return c?[`${t}.${a}: ${c}`]:Bo.has(a)?[]:[`${t}.${a}: unknown field is preserved`]});return o===!0&&n.language!=="go"&&i.push(`${t}.dev.liveReload: only applies to Go services (language "go"); it is ignored here`),{errors:r,warnings:i,manifest:n}}function Pd(e,t){if(!Xn(e))return[];try{let n=JSON.parse(Zn(e,"utf-8"));return!n||typeof n!="object"||Array.isArray(n)?[]:_e(n,t)}catch{return[]}}function $d(e,t){if(!Xn(e))return{errors:[`${t}: file is missing`],warnings:[]};try{let n=JSON.parse(Zn(e,"utf-8"));return pt(n,t)}catch(n){let r=n instanceof Error?n.message:String(n);return{errors:[`${t}: invalid JSON (${r})`],warnings:[]}}}function Qn(e){if(e.length===0||e.every(n=>n==="unknown"))return"unknown";let t=e.filter(n=>n==="ready").length/e.length;return t>.9?"healthy":t>.5?"degraded":"error"}var Wo=/^[a-z0-9-]+$/;function er(e){return Wo.test(e)}var Ko="Use lowercase letters, numbers, and hyphens only";function tr(e,t){return`${e} "${t}" is not valid. ${Ko}, e.g. "${e==="Resource name"?"my-service":"my-stack"}".`}function Go(e){return e.trim()?er(e)?{valid:!0}:{valid:!1,error:tr("Resource name",e)}:{valid:!1,error:"Resource name is required"}}function qo(e){return e.trim()?er(e)?{valid:!0}:{valid:!1,error:tr("Stack name",e)}:{valid:!1,error:"Stack name is required"}}function Od(e){let t=e==="resource"?Go:qo;return n=>{let r=t(n);return r.valid?!0:r.error??"Invalid name"}}function Ad(e){return ft(Ze,e)?{valid:!0}:{valid:!1,error:`Invalid service. Must be one of: ${Ze.join(", ")}`}}function Dd(e){return Number.isInteger(e)&&e>0&&e<=65535}function Cd(e){return!e.includes("\0")&&!/[<>:"|?*]/.test(e)}function Nd(e,t="_"){return e.replace(/[^a-zA-Z0-9-]/g,t).substring(0,100)}function ft(e,t){return e.includes(t)}var zo="service.json";function yt(e,t=5,n=0){let r=[];if(n>t)return r;let s=nr(e,{withFileTypes:!0});for(let o of s){let i=U(e,o.name);if(o.isDirectory()){if(Yo(o.name))continue;r.push(...yt(i,t,n+1))}else o.isFile()&&o.name===zo&&r.push(i)}return r}function Gd(e){return yt(e)}function Yo(e){return ft(yn,e)||e.startsWith(".")}function Xo(e){if(!e||typeof e!="object")return!1;let t=e,n=typeof t.runtime=="string"||typeof t.appType=="string"||typeof t.type=="string";return typeof t.appName=="string"&&n}var Oe=new Set;var B=class extends Error{reason;constructor(t){super(t),this.reason=t,this.name="InvalidServiceJsonError"}};function ht(e){return e instanceof Error?e.message:String(e)}function Zo(e){let t;try{t=rr(e,"utf-8")}catch(c){throw new B(`could not read file: ${ht(c)}`)}let n;try{n=JSON.parse(t)}catch(c){throw new B(`invalid JSON: ${ht(c)}`)}if(!Xo(n))throw new B("missing required fields (appName, runtime or appType)");let r=lt(n);if(r.length>0)throw new B(r.map(c=>`${c}: expected a string`).join("; "));let s=_e(n,e);if(s.length>0)throw new B(s.join("; "));let o=n;for(let c of pt(n,e).warnings)Oe.has(c)||(Oe.add(c),console.warn(`\u26A0\uFE0F ${c}`));let i={...o,appType:o.appType||o.type},a=Jo(e);return{name:i.appName,path:a,configPath:e,config:i,stack:i.stack,port:i.port,type:i.appType}}function sr(e){let t=yt(e),n=[],r=[];for(let s of t)try{n.push(Zo(s))}catch(o){r.push({path:s,reason:o instanceof B?o.reason:ht(o)})}return{resources:n,problems:r}}function Qo(e){for(let t of e){let n=`skipped ${t.path}: ${t.reason}`;Oe.has(n)||(Oe.add(n),console.warn(`\u26A0\uFE0F ${n}`))}}function b(e){let{resources:t,problems:n}=sr(e);return Qo(n),t}function le(){let e=m();if(!e)throw I.notInProject();return b(e)}function qd(){let e=m();if(!e)throw I.notInProject();let{resources:t,problems:n}=sr(e);if(n.length>0)throw new Error(n.map(r=>`Invalid service.json at ${r.path}: ${r.reason}`).join(`
18
18
  `));return t}function Jd(e){let t=b(e),n=new Set;for(let r of t)r.stack&&n.add(r.stack);return Array.from(n).sort()}function zd(e){let t=e||le(),n=new Set;for(let r of t)r.stack&&n.add(r.stack);return Array.from(n).sort()}function Yd(e=le()){let t=new Map;for(let r of e)if(r.stack){let s=t.get(r.stack);s?s.push(r):t.set(r.stack,[r])}let n=[];for(let[r,s]of t)n.push({name:r,description:S(s.length,"resource"),resources:s,resourceCount:s.length});return n.sort((r,s)=>r.name.localeCompare(s.name))}function Xd(e,t){return(t??le()).some(r=>r.stack===e)}var St=5e3,gt=new ce({ttlMs:St}),kt=new ce({ttlMs:St}),de=Cn(St);function Zd(){gt.clear(),kt.clear(),de.reset()}function ei(e,t){if(e==="Dockerfile"||e.startsWith("docker-compose"))return"docker";if(e==="Tiltfile"||e.endsWith(".star"))return"tilt";if(e==="vite.config.ts"||e==="tsconfig.json"||e==="package.json")return"config";if(e==="schema.prisma"||e.includes("migration"))return"prisma";if(t){let n=t.split(`
19
19
  `).slice(0,10).join(`
20
20
  `);if(n.includes("GENERATED BY TDK")||n.includes("AUTOGENERATED"))return"generated"}return"unknown"}function ti(e){let t=e.configPath;if(de.isValid()){let k=gt.get(t);if(k)return k}let n=e.path,r=mt(e.configPath),s=r.mtime.toISOString(),o=r.mtime.toISOString(),i=ni(n),a=J(U(n,"Dockerfile")),c=J(U(n,"Tiltfile")),u=J(U(n,"docker-compose.yml"))||J(U(n,"docker-compose.yaml")),d=e.config?.appType,l=d||"backend";d||(e.name.includes("frontend")?l="frontend":(e.name.includes("sdk")||e.name.includes("lib")||e.name.includes("infra"))&&(l="library"));let h={name:e.name,stack:e.stack,type:l,port:e.config?.port,createdAt:s,lastModified:o,dependencies:e.config?.dependsOn??[],hasDockerfile:a,hasTiltfile:c,hasDockerCompose:u,autogeneratedFiles:i,status:"unknown"};return gt.set(t,h),de.markUpdated(),h}function ni(e){let t=[];for(let r of Sn){let s=U(e,r);if(J(s)){let o=mt(s),i=rr(s,"utf-8");t.push({name:r,path:s,type:ei(r,i),size:o.size,lastModified:o.mtime.toISOString()})}}let n=U(e,"prisma");if(J(n)){let r=nr(n);for(let s of r)if(s==="schema.prisma"||s.includes("migration")){let o=U(n,s),i=mt(o);t.push({name:`prisma/${s}`,path:o,type:"prisma",size:i.size,lastModified:i.mtime.toISOString()})}}return t.sort((r,s)=>r.name.localeCompare(s.name))}function Qd(e){let t=e.name;if(de.isValid()){let c=kt.get(t);if(c)return c}let n=e.resources.map(c=>ti(c)),r=n.map(c=>new Date(c.createdAt).getTime()),s=Math.min(...r),o=Math.max(...r),i=Qn(n.map(c=>c.status)),a={name:e.name,resourceCount:n.length,createdAt:new Date(s).toISOString(),lastModified:new Date(o).toISOString(),resources:n,overallStatus:i};return kt.set(t,a),de.markUpdated(),a}function or(e,t){return e==="pending"||e==="in_progress"||e==="none"||t==="pending"||t==="none"}var ir="container is running, but its health check is failing";function ar(e){let t=e?.runtimeStatus??"";if(t!=="ok")return t;let n=e?.composeResourceInfo?.healthStatus;return n==="unhealthy"?"error":n==="starting"?"pending":t}var pe=1e4,cr=3e3,si="http://localhost:4873";function pr(e){return`'${e.replace(/'/g,"'\\''")}'`}function fe(e,t,n,r,s){return process.platform==="win32"?lr($(t)??t,n,{...s,windowsHide:!0}):e(r,s)}var oi=[80,443];function ii(e){return e.replace(/-/g,"_")}function ai(e,t){let n=new Set(t),r=[];for(let s of e.split(`
21
- `)){let o=s.trim();if(!o)continue;let i=o.indexOf(" "),a=i>=0?o.slice(0,i):o,c=i>=0?o.slice(i+1):"",u=[];for(let d of n)(new RegExp(`(?:^|[\\s,])(?:\\d[\\d.]*:|\\[::\\]:|::)?${d}->`).test(c)||c.includes(`:${d}->`))&&u.push(d);u.length>0&&r.push({name:a,ports:c,publishedPorts:u})}return r}function fr(e,t){let n=e.toLowerCase(),r=t.toLowerCase();return n===`${r}_traefik`||n.startsWith(`${r}_traefik`)}function ci(e,t){return e.filter(n=>!fr(n.name,t))}function ui(){try{return new Set(le().filter(e=>e.config?.sablier?.enable&&e.config?.sablier?.deferStart).map(e=>e.name))}catch{return new Set}}function di(e,t=new Set){let r=JSON.parse(e).items??[],s=[],o=0,i=0,a=0;for(let c of r){let u=c.metadata?.name??"unknown",d=c.status?.updateStatus??"",l=ar(c.status),h=l==="error"&&c.status?.runtimeStatus==="ok",g=(c.status?.buildHistory?.[0]?.error??"").trim()||(h?ir:"");if(d==="error"||l==="error"){s.push({name:u,updateStatus:d,runtimeStatus:l,error:g.replace(/\s+/g," ").slice(0,800)});continue}if(d==="ok"&&(l==="ok"||l==="not_applicable")){a+=1;continue}u!=="(Tiltfile)"&&or(d,l)&&(t.has(u)?i+=1:o+=1)}return{failures:s,pendingCount:o,deferredCount:i,okCount:a,total:r.length}}var li=/failed to resolve source metadata for docker\.io\/library\/([A-Za-z0-9._-]+-l[1-4](?:-[a-z]+)*)(?::[^\s:]+)?:/i;function Tt(e){let t=e.replace(/\s+/g," ").trim(),n=t.match(/Bind for [^ ]+:(\d+) failed: port is already allocated/i);if(n)return`host port ${n[1]} is already allocated`;if(/port is already allocated/i.test(t))return"a required host port is already allocated";let r=[...t.matchAll(/ConnectionRefused downloading package manifest (@[A-Za-z0-9._/-]+)/gi)].map(a=>a[1]);if(r.length>0){let a=[...new Set(r)],c=a.slice(0,4).join(", "),u=a.length>4?` (+${a.length-4} more)`:"";return`private registry ConnectionRefused for ${c}${u} \u2014 Verdaccio (:4873) is down or unreachable from the build`}let s=t.match(li);if(s)return`base image ${s[1]} was missing when this build started (the golden layers weren't built yet, or golden-layers-build failed) - Tilt does not retry a failed build by itself`;if(/install-deps\.sh/i.test(t)||/bun install(?: --production)?/i.test(t)||/npm (?:ci|install)/i.test(t))return"dependency install failed during ImageBuild \u2014 usually Verdaccio (:4873) unreachable or missing @scoped packages (ConnectionRefused downloading package manifest)";let o=t.match(/No such image:\s*([^\s]+)/i)?.[1]??t.match(/pull access denied for ([^,:\s]+)/i)?.[1]??void 0,i=t.match(/\bup\s+-d\s+--no-build\s+([A-Za-z0-9._-]+)/i)?.[1];if(o||i||/docker compose .*\bup\s+-d\s+--no-build\b/i.test(t)){let a=o??`${i??"service"}:dev`,c=i?` for ${i}`:"";return`compose run failed because image is missing (${a})${c} \u2014 wait for the ImageBuild resource to finish, then re-trigger the *-run-only resource`}return/bun run build/i.test(t)?"ImageBuild failed during `bun run build` (compile/typecheck) \u2014 open the resource logs in Tilt for the TypeScript/build error":(/ImageBuild:/i.test(t)||/^Command "/i.test(t),t.slice(0,220))}function ur(e){return/ConnectionRefused downloading package manifest|Verdaccio|private registry|dependency install failed during ImageBuild|install-deps\.sh|bun install/i.test(e)}function wt(e=m()??process.cwd()){let t=z(e,".tdk","project.json");if(!bt(t))return!1;try{let n=JSON.parse(xt(t,"utf-8"));return n.optional_infra?.verdaccio===!0||Object.values(n.phases??{}).some(r=>(r.enabledStacks??[]).includes("verdaccio"))}catch{return!1}}function mr(e){for(let t of[z(e,".npmrc"),z(e,"package.json")])if(bt(t))try{let n=xt(t,"utf-8");if(/:4873\b/.test(n)||/verdaccio/i.test(n))return!0}catch{}return!1}function pi(e=m()??process.cwd()){return wt(e)||mr(e)}function vt(e=me,t=m()??process.cwd(),n=process.env.VERDACCIO_URL??process.env.NPM_REGISTRY_URL??si,r=!0){if(!r&&!mr(t))return{name:"Private npm registry",didPass:!0,isSkipped:!0,message:"Verdaccio is enabled in the project config but needs a Premium license, so TDK will not start it - skipped"};if(!pi(t))return{name:"Private npm registry",didPass:!0,isSkipped:!0,message:"Private npm registry (Verdaccio) not enabled for this project - skipped"};let s=!1;try{let a=fe(e,"docker",["ps","--format","{{.Names}}"],"docker ps --format '{{.Names}}'",{stdio:"pipe",encoding:"utf-8",timeout:pe});s=/verdaccio/i.test(a)}catch{}let o=!1,i="";try{let a=process.platform==="win32"?lr("curl.exe",["-fsS","-o","NUL","-w","%{http_code}","--max-time","2",n],{stdio:"pipe",encoding:"utf-8",timeout:cr+1e3,windowsHide:!0}).trim():e(`curl -fsS -o /dev/null -w '%{http_code}' --max-time 2 ${pr(n)}`,{stdio:"pipe",encoding:"utf-8",timeout:cr+1e3}).trim();o=/^[23]\d\d$/.test(a),i=`HTTP ${a}`}catch(a){i=a instanceof Error?a.message.slice(0,120):"request failed"}return o?{name:"Private npm registry",didPass:!0,message:`Private npm registry reachable at ${n}${s?" (verdaccio container running)":""}`}:s?{name:"Private npm registry",didPass:!1,message:`Verdaccio container is running but ${n} is not responding (${i}). ImageBuilds that install @scoped packages will fail with ConnectionRefused downloading package manifest.`,fix:"Check `docker logs` for the verdaccio container, confirm port 4873 is published, then re-run `tdk doctor`."}:{name:"Private npm registry",didPass:!1,message:`Private npm registry (Verdaccio) is not reachable at ${n}. Docker ImageBuilds will fail with ConnectionRefused downloading package manifests for @tdk-landscape/* and project-scoped packages.`,fix:"Start the registry with `bun run verdaccio:start` (or `docker compose -f docker-compose.verdaccio.yml up -d`), publish packages with `bun run publish:all` / `scripts/build/publish-to-verdaccio.sh`, then `tilt trigger` failed resources or re-run `tdk up`."}}function Pt(e=me,t=st(),n=oi){let r=ii(t),s="";try{s=fe(e,"docker",["ps","--format","{{.Names}}\\t{{.Ports}}"],"docker ps --format '{{.Names}}\\t{{.Ports}}'",{stdio:"pipe",encoding:"utf-8",timeout:pe})}catch{return{name:"Ingress Ports",didPass:!0,isSkipped:!0,message:"Docker not available - skipped ingress port check"}}let o=ai(s,n),i=ci(o,r);if(i.length===0){let c=o.filter(u=>fr(u.name,r));return c.length>0?{name:"Ingress Ports",didPass:!0,message:`Ingress ports ${n.join("/")} held by this project's Traefik (${c.map(u=>u.name).join(", ")})`}:{name:"Ingress Ports",didPass:!0,message:`Ingress ports ${n.join("/")} are free for Traefik`}}return{name:"Ingress Ports",didPass:!1,message:`Traefik cannot bind ingress ports because another container already owns them:
21
+ `)){let o=s.trim();if(!o)continue;let i=o.indexOf(" "),a=i>=0?o.slice(0,i):o,c=i>=0?o.slice(i+1):"",u=[];for(let d of n)c.split(/[\s,]+/).some(h=>h.startsWith(`${d}->`)||h.includes(`:${d}->`))&&u.push(d);u.length>0&&r.push({name:a,ports:c,publishedPorts:u})}return r}function fr(e,t){let n=e.toLowerCase(),r=t.toLowerCase();return n===`${r}_traefik`||n.startsWith(`${r}_traefik`)}function ci(e,t){return e.filter(n=>!fr(n.name,t))}function ui(){try{return new Set(le().filter(e=>e.config?.sablier?.enable&&e.config?.sablier?.deferStart).map(e=>e.name))}catch{return new Set}}function di(e,t=new Set){let r=JSON.parse(e).items??[],s=[],o=0,i=0,a=0;for(let c of r){let u=c.metadata?.name??"unknown",d=c.status?.updateStatus??"",l=ar(c.status),h=l==="error"&&c.status?.runtimeStatus==="ok",g=(c.status?.buildHistory?.[0]?.error??"").trim()||(h?ir:"");if(d==="error"||l==="error"){s.push({name:u,updateStatus:d,runtimeStatus:l,error:g.replace(/\s+/g," ").slice(0,800)});continue}if(d==="ok"&&(l==="ok"||l==="not_applicable")){a+=1;continue}u!=="(Tiltfile)"&&or(d,l)&&(t.has(u)?i+=1:o+=1)}return{failures:s,pendingCount:o,deferredCount:i,okCount:a,total:r.length}}var li=/failed to resolve source metadata for docker\.io\/library\/([A-Za-z0-9._-]+-l[1-4](?:-[a-z]+)*)(?::[^\s:]+)?:/i;function Tt(e){let t=e.replace(/\s+/g," ").trim(),n=t.match(/Bind for [^ ]+:(\d+) failed: port is already allocated/i);if(n)return`host port ${n[1]} is already allocated`;if(/port is already allocated/i.test(t))return"a required host port is already allocated";let r=[...t.matchAll(/ConnectionRefused downloading package manifest (@[A-Za-z0-9._/-]+)/gi)].map(a=>a[1]);if(r.length>0){let a=[...new Set(r)],c=a.slice(0,4).join(", "),u=a.length>4?` (+${a.length-4} more)`:"";return`private registry ConnectionRefused for ${c}${u} \u2014 Verdaccio (:4873) is down or unreachable from the build`}let s=t.match(li);if(s)return`base image ${s[1]} was missing when this build started (the golden layers weren't built yet, or golden-layers-build failed) - Tilt does not retry a failed build by itself`;if(/install-deps\.sh/i.test(t)||/bun install(?: --production)?/i.test(t)||/npm (?:ci|install)/i.test(t))return"dependency install failed during ImageBuild \u2014 usually Verdaccio (:4873) unreachable or missing @scoped packages (ConnectionRefused downloading package manifest)";let o=t.match(/No such image:\s*([^\s]+)/i)?.[1]??t.match(/pull access denied for ([^,:\s]+)/i)?.[1]??void 0,i=t.match(/\bup\s+-d\s+--no-build\s+([A-Za-z0-9._-]+)/i)?.[1];if(o||i||/docker compose .*\bup\s+-d\s+--no-build\b/i.test(t)){let a=o??`${i??"service"}:dev`,c=i?` for ${i}`:"";return`compose run failed because image is missing (${a})${c} \u2014 wait for the ImageBuild resource to finish, then re-trigger the *-run-only resource`}return/bun run build/i.test(t)?"ImageBuild failed during `bun run build` (compile/typecheck) \u2014 open the resource logs in Tilt for the TypeScript/build error":(/ImageBuild:/i.test(t)||/^Command "/i.test(t),t.slice(0,220))}function ur(e){return/ConnectionRefused downloading package manifest|Verdaccio|private registry|dependency install failed during ImageBuild|install-deps\.sh|bun install/i.test(e)}function wt(e=m()??process.cwd()){let t=z(e,".tdk","project.json");if(!bt(t))return!1;try{let n=JSON.parse(xt(t,"utf-8"));return n.optional_infra?.verdaccio===!0||Object.values(n.phases??{}).some(r=>(r.enabledStacks??[]).includes("verdaccio"))}catch{return!1}}function mr(e){for(let t of[z(e,".npmrc"),z(e,"package.json")])if(bt(t))try{let n=xt(t,"utf-8");if(/:4873\b/.test(n)||/verdaccio/i.test(n))return!0}catch{}return!1}function pi(e=m()??process.cwd()){return wt(e)||mr(e)}function vt(e=me,t=m()??process.cwd(),n=process.env.VERDACCIO_URL??process.env.NPM_REGISTRY_URL??si,r=!0){if(!r&&!mr(t))return{name:"Private npm registry",didPass:!0,isSkipped:!0,message:"Verdaccio is enabled in the project config but needs a Premium license, so TDK will not start it - skipped"};if(!pi(t))return{name:"Private npm registry",didPass:!0,isSkipped:!0,message:"Private npm registry (Verdaccio) not enabled for this project - skipped"};let s=!1;try{let a=fe(e,"docker",["ps","--format","{{.Names}}"],"docker ps --format '{{.Names}}'",{stdio:"pipe",encoding:"utf-8",timeout:pe});s=/verdaccio/i.test(a)}catch{}let o=!1,i="";try{let a=process.platform==="win32"?lr("curl.exe",["-fsS","-o","NUL","-w","%{http_code}","--max-time","2",n],{stdio:"pipe",encoding:"utf-8",timeout:cr+1e3,windowsHide:!0}).trim():e(`curl -fsS -o /dev/null -w '%{http_code}' --max-time 2 ${pr(n)}`,{stdio:"pipe",encoding:"utf-8",timeout:cr+1e3}).trim();o=/^[23]\d\d$/.test(a),i=`HTTP ${a}`}catch(a){i=a instanceof Error?a.message.slice(0,120):"request failed"}return o?{name:"Private npm registry",didPass:!0,message:`Private npm registry reachable at ${n}${s?" (verdaccio container running)":""}`}:s?{name:"Private npm registry",didPass:!1,message:`Verdaccio container is running but ${n} is not responding (${i}). ImageBuilds that install @scoped packages will fail with ConnectionRefused downloading package manifest.`,fix:"Check `docker logs` for the verdaccio container, confirm port 4873 is published, then re-run `tdk doctor`."}:{name:"Private npm registry",didPass:!1,message:`Private npm registry (Verdaccio) is not reachable at ${n}. Docker ImageBuilds will fail with ConnectionRefused downloading package manifests for @tdk-landscape/* and project-scoped packages.`,fix:"Start the registry with `bun run verdaccio:start` (or `docker compose -f docker-compose.verdaccio.yml up -d`), publish packages with `bun run publish:all` / `scripts/build/publish-to-verdaccio.sh`, then `tilt trigger` failed resources or re-run `tdk up`."}}function Pt(e=me,t=st(),n=oi){let r=ii(t),s="";try{s=fe(e,"docker",["ps","--format","{{.Names}}\\t{{.Ports}}"],"docker ps --format '{{.Names}}\\t{{.Ports}}'",{stdio:"pipe",encoding:"utf-8",timeout:pe})}catch{return{name:"Ingress Ports",didPass:!0,isSkipped:!0,message:"Docker not available - skipped ingress port check"}}let o=ai(s,n),i=ci(o,r);if(i.length===0){let c=o.filter(u=>fr(u.name,r));return c.length>0?{name:"Ingress Ports",didPass:!0,message:`Ingress ports ${n.join("/")} held by this project's Traefik (${c.map(u=>u.name).join(", ")})`}:{name:"Ingress Ports",didPass:!0,message:`Ingress ports ${n.join("/")} are free for Traefik`}}return{name:"Ingress Ports",didPass:!1,message:`Traefik cannot bind ingress ports because another container already owns them:
22
22
  ${i.map(c=>{let u=c.publishedPorts.join(", ");return`${c.name} (host ports ${u})`}).join(`
23
23
  `)}`,fix:`Stop the foreign container(s), e.g. \`docker stop ${i[0]?.name}\`, or shut down the other TDK/Tilt project using that Traefik. Then re-run \`tdk up\`.`}}function fi(e){let{status:t}=e;return t===void 0?e.error??"no response":t===404?"HTTP 404: Traefik is answering but has no route for this URL (container not started yet, or not running)":t===502||t===503||t===504?`HTTP ${t}: Traefik found the route but the container isn't answering (still starting, or unhealthy)`:`HTTP ${t}`}function $t(e){let t=e.filter(o=>o.status!==void 0),n=e.filter(o=>!o.ok);if(t.length===0)return{name:"Service Health",didPass:!0,isSkipped:!0,message:`No services responded - skipped ping of ${S(e.length,"service")} (stack may be down, or Traefik never bound :80)`,fix:"If `tdk up` is already running, check Traefik/port 80 in the Tilt UI. Otherwise start with: tdk up"};if(n.length===0)return{name:"Service Health",didPass:!0,message:`All ${S(e.length,"service")} responding on /health`};let r=n.map(o=>`${o.name} (${fi(o)})
24
24
  ${o.url}`).join(`
@@ -253,7 +253,7 @@ mod tests {
253
253
  assert_eq!(body["status"], "ok");
254
254
  }
255
255
  }
256
- `,description:"Generating backend source and smoke test",emoji:"\u{1F4BB}"}]}};var vr="bun",Y={bun:br,python:Tr,go:xr,rust:wr};function Ai(e){let t=(e??vr).trim().toLowerCase(),n=Object.hasOwn(Y,t)?Y[t]:void 0;if(!n){let r=Object.keys(Y).join(", ");throw new E(`Unknown backend language "${e}". Supported languages: ${r}.`,[`Use one of: ${r}`,`Omit --language to use ${vr}`])}return n}function _l(e,t){if(e!=="backend"){if(t!==void 0)throw new E("--language can only be used with --type backend.",["Add --type backend, or drop --language for this resource type"]);return}return Ai(t)}import{exec as Di,execFile as Ci}from"node:child_process";import{promisify as Pr}from"node:util";var Ni=Pr(Di),N=async(e,t)=>{if(process.platform==="win32"){let r=e.match(/(?:[^\s"']+|"[^"]*"|'[^']*')+/g)??[],[s,...o]=r.map(c=>c.startsWith('"')||c.startsWith("'")?c.slice(1,-1):c);if(!s)throw new Error("Command is empty");let i=$(s)??s,{stdout:a}=await Pr(Ci)(i,o,{encoding:"utf-8",timeout:t,windowsHide:!0,shell:!1});return a}let{stdout:n}=await Ni(e,{encoding:"utf-8",timeout:t});return n};function $r(e){let t=e;return t?.code==="ETIMEDOUT"||t?.killed===!0}import{existsSync as ji,readFileSync as Er}from"node:fs";import{join as H}from"node:path";var Ot=["database-management","proxy"];var Rr=["postgres","database-management"],_r=["pre_alpha","alpha","beta","out_of_scope"];function Ii(e){return Rr.includes(e)}function Or(e){try{return JSON.parse(Er(H(e,".tdk","project.json"),"utf-8"))}catch{return}}function X(e){try{return ji(e)?Er(e,"utf-8"):void 0}catch{return}}function Ar(e,t){let n=new RegExp(`${t}\\s*=\\s*\\[([^\\]]*)\\]`),r=e.match(n);if(r)return[...r[1].matchAll(/"([^"]+)"|'([^']+)'/g)].map(s=>s[1]??s[2]??"")}function Dr(e){let t=H(e,".tdk",".tdk-out","Tiltfile"),n=X(t);if(n)return Ar(n,"ALWAYS_ENABLED_INFRA")}function Fi(e){let t=H(e,".tdk",".tdk-out","spec.master"),n=X(t);if(n!==void 0)return/"database-management"\s*:\s*True/.test(n)}function Mi(e){let t=H(e,".tdk",".tdk-out"),n=X(H(t,"Tiltfile")),r=X(H(t,"spec.master")),s=X(H(t,"tdk-cli-ext","discovery","config.star")),o=X(H(t,"tdk-cli-ext","engine","topologies","tilt","config","profiles.star"));if(!n||!r||!s||!o)return!1;let i=r.match(/PRE_ALPHA_RESOURCES\s*=\s*\{([^}]*)\}/)?.[1],a=Ar(s,"CORE_INFRA");return/FOCUS_MODE\s*,\s*FOCUS_ENABLED_ALL\s*,\s*FOCUS_ENABLED_RESOURCES\s*=\s*Config\.apply_focus\(cfg\)/.test(n)&&/if FOCUS_MODE and FOCUS_ENABLED_ALL\s*:/.test(n)&&/"[^"]+"\s*:\s*True|'[^']+'\s*:\s*True/.test(i??"")&&(a?.includes("postgres")??!1)&&/["']postgres["']\s*:\s*["']database-management["']/.test(s)&&/for infra in CORE_INFRA_EXPORT\s*:/.test(o)&&/needed\[INFRA_STACK_MAP_EXPORT\[infra\]\]\s*=\s*True/.test(o)}function Li(e){let t=Or(e);if(!t)return!1;let n=t.phases??{};for(let s of _r){let o=n[s]?.enabledStacks;if(Array.isArray(o)&&o.includes("database-management"))return!0}let r=t.always_enabled_infra??Ot;return Array.isArray(r)&&r.includes("database-management")}function Bi(e){let t=new Set;for(let s of Rr)t.add(s);for(let s of b(e))t.add(s.name),s.stack&&t.add(s.stack);let n=Or(e);if(n){let s=n.phases??{};for(let i of _r){let a=s[i]?.enabledStacks;if(Array.isArray(a))for(let c of a)t.add(c)}let o=n.always_enabled_infra??Ot;if(Array.isArray(o))for(let i of o)t.add(i)}let r=Dr(e);if(Array.isArray(r))for(let s of r)t.add(s);return t}function At(e){let t=Li(e),n=Dr(e),r=Array.isArray(n)&&n.includes("database-management"),s=Fi(e)===!0,o=t||r||s,i=!t&&Mi(e),a=Bi(e),c=[],u=[];for(let h of b(e)){let k=h.config?.dependsOn??[],g=!1;for(let p of k){if(Ii(p)){g=!0;continue}a.has(p)||u.push({resource:h.name,name:p})}g&&c.push(h.name)}let d=o||c.length>0,l=o?"feature":c.length>0?"dependsOn":"none";return{featureOn:o,featureOnFromProjectJson:t,featureOnFromTiltfile:r,featureOnFromSpecMaster:s,focusWouldEnableDatabaseManagement:i,dependsOnUsers:c,willStart:d,reason:l,unknownDependsOnNames:u}}var De=1e4,Ki=/\.(?:[cm]?[jt]sx?|vue)$/,Gi=/(?:\.test\.|\.spec\.|\/tests?\/|\/__tests__\/)/,qi=7,Ji=new Set(["node_modules",".autogenerated","dist","tests","__tests__"]);function jr(e){try{let t=JSON.parse(ge(_(e,".tdk","project.json"),"utf-8"));return typeof t?.project?.name=="string"?t.project.name:void 0}catch{return}}function zi(e){try{let t=JSON.parse(ge(e,"utf-8")).params;return t&&typeof t=="object"?t:{}}catch{return{}}}function Dt(e){try{let t=JSON.parse(ge(_(e,"package.json"),"utf-8"));return t&&typeof t=="object"?t:{}}catch{return{}}}function Cr(e){if(typeof e!="string")return;let t=e.match(/(?:^|[^0-9])(\d+)(?:\.|$)/);return t?Number(t[1]):void 0}function Yi(e){let t=Ne(e);if(t===void 0)return["missing prisma/schema.prisma"];let n=t.replace(/\/\*[\s\S]*?\*\//g,"").replace(/^\s*\/\/.*$/gm,""),r=[],s=n.match(/datasource\s+\w+\s*\{([^}]*)\}/)?.[1]??"";return/provider\s*=\s*["']postgresql["']/.test(s)||r.push("schema provider is not postgresql"),/\b(?:url|directUrl)\s*=/.test(n)&&r.push("schema still declares url/directUrl"),r}function Xi(e){let t=_(e,".autogenerated","prisma.config.autogenerated.ts"),r=[_(e,"prisma.config.ts"),t].find(i=>Ct(i));if(!r)return["missing prisma.config.ts or generated Prisma config"];let o=(Ne(r)??"").match(/datasource\s*:\s*\{([^}]*)\}/)?.[1]??"";return/url\s*:\s*(?:env\(["']DATABASE_URL["']\)|process\.env\.DATABASE_URL)\s*,?/.test(o)?[]:['Prisma config datasource.url is not env("DATABASE_URL")']}function Ir(e=m()??process.cwd()){let t=b(e),n=t.filter(o=>o.config?.featuresEnabled?.includes("prisma")),r=[],s=t.filter(o=>o.config?.appType==="migrator");for(let o of t){let i=o.config?.features;Array.isArray(i)&&i.includes("prisma")&&!o.config?.featuresEnabled?.includes("prisma")&&r.push(`${o.name}: use featuresEnabled, not features, for Prisma`)}if(n.length===0)return r.length===0?{name:"Prisma 7 consistency",didPass:!0,isSkipped:!0,message:"No resources enable Prisma; Prisma consistency checks were skipped"}:{name:"Prisma 7 consistency",didPass:!1,message:`${S(r.length,"Prisma consistency error")}:
256
+ `,description:"Generating backend source and smoke test",emoji:"\u{1F4BB}"}]}};var vr="bun",Y={bun:br,python:Tr,go:xr,rust:wr};function Ai(e){let t=(e??vr).trim().toLowerCase(),n=Object.hasOwn(Y,t)?Y[t]:void 0;if(!n){let r=Object.keys(Y).join(", ");throw new E(`Unknown backend language "${e}". Supported languages: ${r}.`,[`Use one of: ${r}`,`Omit --language to use ${vr}`])}return n}function _l(e,t){if(e!=="backend"){if(t!==void 0)throw new E("--language can only be used with --type backend.",["Add --type backend, or drop --language for this resource type"]);return}return Ai(t)}import{exec as Di,execFile as Ci}from"node:child_process";import{promisify as Pr}from"node:util";var Ni=Pr(Di),N=async(e,t)=>{if(process.platform==="win32"){let r=e.match(/(?:[^\s"']+|"[^"]*"|'[^']*')+/g)??[],[s,...o]=r.map(c=>c.startsWith('"')||c.startsWith("'")?c.slice(1,-1):c);if(!s)throw new Error("Command is empty");let i=$(s)??s,{stdout:a}=await Pr(Ci)(i,o,{encoding:"utf-8",timeout:t,windowsHide:!0,shell:!1});return a}let{stdout:n}=await Ni(e,{encoding:"utf-8",timeout:t});return n};function $r(e){let t=e;return t?.code==="ETIMEDOUT"||t?.killed===!0}import{existsSync as ji,readFileSync as Er}from"node:fs";import{join as H}from"node:path";var Ot=["database-management","proxy"];var Rr=["postgres","database-management"],_r=["pre_alpha","alpha","beta","out_of_scope"];function Ii(e){return Rr.includes(e)}function Or(e){try{return JSON.parse(Er(H(e,".tdk","project.json"),"utf-8"))}catch{return}}function X(e){try{return ji(e)?Er(e,"utf-8"):void 0}catch{return}}function Ar(e,t){let n=s=>{let o=s;for(;o<e.length&&/\s/.test(e[o]);)o+=1;return o},r=0;for(;;){let s=e.indexOf(t,r);if(s===-1)return;let o=n(s+t.length);if(e[o]==="="&&(o=n(o+1),e[o]==="[")){let i=e.indexOf("]",o+1);return i===-1?void 0:[...e.slice(o+1,i).matchAll(/"([^"]+)"|'([^']+)'/g)].map(a=>a[1]??a[2]??"")}r=s+t.length}}function Dr(e){let t=H(e,".tdk",".tdk-out","Tiltfile"),n=X(t);if(n)return Ar(n,"ALWAYS_ENABLED_INFRA")}function Fi(e){let t=H(e,".tdk",".tdk-out","spec.master"),n=X(t);if(n!==void 0)return/"database-management"\s*:\s*True/.test(n)}function Mi(e){let t=H(e,".tdk",".tdk-out"),n=X(H(t,"Tiltfile")),r=X(H(t,"spec.master")),s=X(H(t,"tdk-cli-ext","discovery","config.star")),o=X(H(t,"tdk-cli-ext","engine","topologies","tilt","config","profiles.star"));if(!n||!r||!s||!o)return!1;let i=r.match(/PRE_ALPHA_RESOURCES\s*=\s*\{([^}]*)\}/)?.[1],a=Ar(s,"CORE_INFRA");return/FOCUS_MODE\s*,\s*FOCUS_ENABLED_ALL\s*,\s*FOCUS_ENABLED_RESOURCES\s*=\s*Config\.apply_focus\(cfg\)/.test(n)&&/if FOCUS_MODE and FOCUS_ENABLED_ALL\s*:/.test(n)&&/"[^"]+"\s*:\s*True|'[^']+'\s*:\s*True/.test(i??"")&&(a?.includes("postgres")??!1)&&/["']postgres["']\s*:\s*["']database-management["']/.test(s)&&/for infra in CORE_INFRA_EXPORT\s*:/.test(o)&&/needed\[INFRA_STACK_MAP_EXPORT\[infra\]\]\s*=\s*True/.test(o)}function Li(e){let t=Or(e);if(!t)return!1;let n=t.phases??{};for(let s of _r){let o=n[s]?.enabledStacks;if(Array.isArray(o)&&o.includes("database-management"))return!0}let r=t.always_enabled_infra??Ot;return Array.isArray(r)&&r.includes("database-management")}function Bi(e){let t=new Set;for(let s of Rr)t.add(s);for(let s of b(e))t.add(s.name),s.stack&&t.add(s.stack);let n=Or(e);if(n){let s=n.phases??{};for(let i of _r){let a=s[i]?.enabledStacks;if(Array.isArray(a))for(let c of a)t.add(c)}let o=n.always_enabled_infra??Ot;if(Array.isArray(o))for(let i of o)t.add(i)}let r=Dr(e);if(Array.isArray(r))for(let s of r)t.add(s);return t}function At(e){let t=Li(e),n=Dr(e),r=Array.isArray(n)&&n.includes("database-management"),s=Fi(e)===!0,o=t||r||s,i=!t&&Mi(e),a=Bi(e),c=[],u=[];for(let h of b(e)){let k=h.config?.dependsOn??[],g=!1;for(let p of k){if(Ii(p)){g=!0;continue}a.has(p)||u.push({resource:h.name,name:p})}g&&c.push(h.name)}let d=o||c.length>0,l=o?"feature":c.length>0?"dependsOn":"none";return{featureOn:o,featureOnFromProjectJson:t,featureOnFromTiltfile:r,featureOnFromSpecMaster:s,focusWouldEnableDatabaseManagement:i,dependsOnUsers:c,willStart:d,reason:l,unknownDependsOnNames:u}}var De=1e4,Ki=/\.(?:[cm]?[jt]sx?|vue)$/,Gi=/(?:\.test\.|\.spec\.|\/tests?\/|\/__tests__\/)/,qi=7,Ji=new Set(["node_modules",".autogenerated","dist","tests","__tests__"]);function jr(e){try{let t=JSON.parse(ge(_(e,".tdk","project.json"),"utf-8"));return typeof t?.project?.name=="string"?t.project.name:void 0}catch{return}}function zi(e){try{let t=JSON.parse(ge(e,"utf-8")).params;return t&&typeof t=="object"?t:{}}catch{return{}}}function Dt(e){try{let t=JSON.parse(ge(_(e,"package.json"),"utf-8"));return t&&typeof t=="object"?t:{}}catch{return{}}}function Cr(e){if(typeof e!="string")return;let t=e.match(/(?:^|[^0-9])(\d+)(?:\.|$)/);return t?Number(t[1]):void 0}function Yi(e){let t=Ne(e);if(t===void 0)return["missing prisma/schema.prisma"];let n=t.replace(/\/\*[\s\S]*?\*\//g,"").replace(/^\s*\/\/.*$/gm,""),r=[],s=n.match(/datasource\s+\w+\s*\{([^}]*)\}/)?.[1]??"";return/provider\s*=\s*["']postgresql["']/.test(s)||r.push("schema provider is not postgresql"),/\b(?:url|directUrl)\s*=/.test(n)&&r.push("schema still declares url/directUrl"),r}function Xi(e){let t=_(e,".autogenerated","prisma.config.autogenerated.ts"),r=[_(e,"prisma.config.ts"),t].find(i=>Ct(i));if(!r)return["missing prisma.config.ts or generated Prisma config"];let o=(Ne(r)??"").match(/datasource\s*:\s*\{([^}]*)\}/)?.[1]??"";return/url\s*:\s*(?:env\(["']DATABASE_URL["']\)|process\.env\.DATABASE_URL)\s*,?/.test(o)?[]:['Prisma config datasource.url is not env("DATABASE_URL")']}function Ir(e=m()??process.cwd()){let t=b(e),n=t.filter(o=>o.config?.featuresEnabled?.includes("prisma")),r=[],s=t.filter(o=>o.config?.appType==="migrator");for(let o of t){let i=o.config?.features;Array.isArray(i)&&i.includes("prisma")&&!o.config?.featuresEnabled?.includes("prisma")&&r.push(`${o.name}: use featuresEnabled, not features, for Prisma`)}if(n.length===0)return r.length===0?{name:"Prisma 7 consistency",didPass:!0,isSkipped:!0,message:"No resources enable Prisma; Prisma consistency checks were skipped"}:{name:"Prisma 7 consistency",didPass:!1,message:`${S(r.length,"Prisma consistency error")}:
257
257
  ${r.join(`
258
258
  `)}`,fix:"Use featuresEnabled to opt into the validated Prisma 7 shape"};for(let o of n){let i=Dt(o.path).dependencies,c={...Dt(o.path).devDependencies??{},...i??{}},u=Cr(c.prisma),d=Cr(c["@prisma/client"]);if(u===void 0||d===void 0?r.push(`${o.name}: prisma and @prisma/client are required`):(u!==d||u!==qi)&&r.push(`${o.name}: prisma packages must both be major 7`),r.push(...Yi(_(o.path,"prisma","schema.prisma")).map(h=>`${o.name}: ${h}`)),r.push(...Xi(o.path).map(h=>`${o.name}: ${h}`)),(o.config?.appType??o.type)==="migrator")o.config?.dependsOn?.some(k=>k==="postgres"||k==="database-management")||r.push(`${o.name}: migrator must depend on postgres or database-management`);else{o.config?.dependsOn?.some(p=>s.some(y=>y.name===p))||r.push(`${o.name}: API must depend on its Prisma migrator`);let k=Dt(o.path).scripts;Object.entries(k??{}).some(([p,y])=>Kr.has(p)&&typeof y=="string"&&/prisma\s+migrate/.test(y))&&r.push(`${o.name}: API start script must not run prisma migrate`);let g=_(o.path,o.config?.dockerfile??"Dockerfile");Ae(g,!0)&&r.push(`${o.name}: API image/startup must not run Prisma migrations`)}}return n.length>0&&!At(e).willStart&&r.push("shared platform Postgres will not start for the Prisma resources"),r.length===0?{name:"Prisma 7 consistency",didPass:!0,message:"Prisma resources use the validated Prisma 7 shape"}:{name:"Prisma 7 consistency",didPass:!1,message:`${S(r.length,"Prisma consistency error")}:
259
259
  ${r.join(`
@@ -277,7 +277,7 @@ mod tests {
277
277
  `)||d.endsWith("\r")?"":`
278
278
  `;d+=h+l.join(`
279
279
  `)}return Yr(t,d),s.map(l=>l.name)}function ap(e){let t=Ft(e,".env");return It(t)?!1:(Qr(t,ns(),{mode:384}),!0)}import{execFileSync as Ra}from"node:child_process";import{existsSync as _a,mkdirSync as Oa,readFileSync as os,writeFileSync as Aa}from"node:fs";import{join as ye}from"node:path";import{createServer as va}from"node:net";import{connect as wa}from"node:net";function ss(e,t=500){return new Promise(n=>{let r=wa({port:e,host:"127.0.0.1"}),s=o=>{r.destroy(),n(o)};r.setTimeout(t,()=>s(!1)),r.once("connect",()=>s(!0)),r.once("error",()=>s(!1))})}var Pa={ingressHttp:{start:8080,end:8180},ingressHttps:{start:8443,end:8543},postgres:{start:15432,end:15532}},Ie={ingressHttp:"TDK_HTTP_PORT",ingressHttps:"TDK_HTTPS_PORT",postgres:"TDK_POSTGRES_PORT"},$a={ingressHttp:80,ingressHttps:443,postgres:5432};async function Mt(e){return await ss(e)?!1:new Promise(t=>{let n=va();n.once("error",()=>t(!1)),n.listen(e,"127.0.0.1",()=>n.close(()=>t(!0)))})}function Ea(e,t){let n=Number(t);if(!Number.isInteger(n)||n<1||n>65535)throw new Error(`${e} must be an integer between 1 and 65535 (received ${JSON.stringify(t)})`);return n}async function ke(e={}){let t=e.env??process.env,n=e.isAvailable??Mt,r={ingressHttp:!1,ingressHttps:!1,postgres:!1},s={ingressHttp:"",ingressHttps:"",postgres:""},o={explicit:r},i=new Set;for(let a of["ingressHttp","ingressHttps","postgres"]){let c=t[Ie[a]],u=c!==void 0&&c.trim()!=="",d=e.ranges?.[a]??Pa[a],l=u?[Ea(Ie[a],c)]:Array.from({length:d.end-d.start+1},(k,g)=>d.start+g),h;for(let k of l)if(!i.has(k)){if(await n(k)){h=k;break}if(u)throw new Error(`${Ie[a]}=${k} is already in use. Choose a free host port and retry.`)}if(h===void 0)throw new Error(`No available host port in ${d.start}-${d.end} for ${a}. Set ${Ie[a]} to a free port and retry.`);i.add(h),o[a]=h,r[a]=u,s[a]=u?"explicit override":`selected from fallback range ${d.start}-${d.end}`}return{...o,requested:{...$a},reason:s}}function fp(e){return`Host ports: HTTP ${e.ingressHttp}, HTTPS ${e.ingressHttps}, Postgres ${e.postgres}`}var is=ye(".tdk",".tdk-out","host-ports.json");function Da(e,t,n){return e.split(`
280
- `).some(r=>{let[s="",o=""]=r.split("|"),i=s.toLowerCase(),a=t.toLowerCase();return(i.startsWith(`${a}_`)||i.startsWith(`${a}-`))&&new RegExp(`:${n}->`).test(o)})}function Ca(e){let t=ye(e,is);if(!_a(t))return null;try{let n=JSON.parse(os(t,"utf-8"));if(!n||typeof n!="object")return null;let r=n;return!Number.isInteger(r.ingressHttp)||!Number.isInteger(r.ingressHttps)||!Number.isInteger(r.postgres)||!r.requested||!r.explicit||!r.reason?null:r}catch{return null}}function Sp(e,t){let n=ye(e,is);Oa(ye(e,".tdk",".tdk-out"),{recursive:!0}),Aa(n,`${JSON.stringify(t,null,2)}
280
+ `).some(r=>{let[s="",o=""]=r.split("|"),i=s.toLowerCase(),a=t.toLowerCase();return(i.startsWith(`${a}_`)||i.startsWith(`${a}-`))&&o.includes(`:${n}->`)})}function Ca(e){let t=ye(e,is);if(!_a(t))return null;try{let n=JSON.parse(os(t,"utf-8"));if(!n||typeof n!="object")return null;let r=n;return!Number.isInteger(r.ingressHttp)||!Number.isInteger(r.ingressHttps)||!Number.isInteger(r.postgres)||!r.requested||!r.explicit||!r.reason?null:r}catch{return null}}function Sp(e,t){let n=ye(e,is);Oa(ye(e,".tdk",".tdk-out"),{recursive:!0}),Aa(n,`${JSON.stringify(t,null,2)}
281
281
  `,{encoding:"utf-8",mode:384})}function bp(e){process.env.TDK_HTTP_PORT=String(e.ingressHttp),process.env.TDK_HTTPS_PORT=String(e.ingressHttps),process.env.TDK_POSTGRES_PORT=String(e.postgres)}async function Fe(e,t={}){let n=Ca(e),r=["TDK_HTTP_PORT","TDK_HTTPS_PORT","TDK_POSTGRES_PORT"].some(c=>process.env[c]);if(t.inspectDocker===!1&&n&&!r)return n;let s="";try{let c=JSON.parse(os(ye(e,".tdk","project.json"),"utf-8"));s=String(c?.project?.name??"tdk-project").replace(/-/g,"_").toLowerCase()}catch{s="tdk_project"}let o="";if(t.inspectDocker!==!1)try{o=Ra("docker",["ps","--format","{{.Names}}|{{.Ports}}"],{encoding:"utf-8",timeout:5e3})}catch{}let i=c=>Da(o,s,c),a=async c=>await Mt(c)||i(c);if(n&&!r){for(let c of[n.ingressHttp,n.ingressHttps,n.postgres])if(!await a(c))return ke({isAvailable:a});return n}return ke({isAvailable:a})}import{existsSync as Na,readFileSync as ja}from"node:fs";import{join as Ia}from"node:path";var Fa="[REDACTED]",Se=class extends Error{path;constructor(t,n){super(`Could not read ${t}: ${n}`),this.path=t,this.name="EnvUnreadableError"}},Ma=8;function as(e){let t=Ia(e,".env");if(!Na(t))return[];let n;try{n=ja(t,"utf-8")}catch(s){throw new Se(t,s instanceof Error?s.message:String(s))}let r=[...Q(n).values()].filter(s=>s.length>=Ma);return[...new Set(r)].sort((s,o)=>o.length-s.length)}function Lt(e,t){let n=e;for(let r of t)n=n.split(r).join(Fa);return n}function Me(e,t){return t.length===0?e:typeof e=="string"?Lt(e,t):Array.isArray(e)?e.map(n=>Me(n,t)):e!==null&&typeof e=="object"?Object.fromEntries(Object.entries(e).map(([n,r])=>[n,Me(r,t)])):e}import{relative as La}from"node:path";function Le(e,t){return La(e,t.configPath)||t.configPath}function cs(e){let t=e.config?.dependsOn;return t===void 0?[]:Array.isArray(t)&&t.every(n=>typeof n=="string")?t:null}function Ba(e){let t=new Set(e.map(a=>a.name)),n=new Map(e.map(a=>[a.name,(cs(a)??[]).filter(c=>t.has(c))])),r=new Map,s=new Map,o=[],i=a=>{s.set(a,"visiting"),o.push(a);for(let c of n.get(a)??[])if(s.get(c)==="visiting"){let u=o.slice(o.indexOf(c)),d=u.indexOf([...u].sort()[0]??c),l=[...u.slice(d),...u.slice(0,d)];r.set(l.join(">"),[...l,l[0]??c])}else s.has(c)||i(c);o.pop(),s.set(a,"done")};for(let a of[...n.keys()].sort())s.has(a)||i(a);return[...r.values()]}function Bt(e=m()??process.cwd()){let t=b(e).flatMap(n=>cs(n)===null?[`${Le(e,n)} dependsOn ${JSON.stringify(n.config?.dependsOn)}: expected an array of service names`]:[]);return t.length===0?{name:"dependsOn",didPass:!0,message:"Every dependsOn is a list of service names"}:{name:"dependsOn",didPass:!1,message:`${S(t.length,"invalid dependsOn","invalid dependsOn")}:
282
282
  ${t.join(`
283
283
  `)}`,fix:'Write "dependsOn" as an array of service names, for example ["postgres", "api"]'}}function Ut(e=m()??process.cwd()){let t=b(e),n=new Map(t.map(o=>[o.name,o])),r=Ba(t);if(r.length===0)return{name:"Circular dependencies",didPass:!0,message:"No service depends on itself through dependsOn"};let s=r.map(o=>{let i=n.get(o[0]??""),a=o[1]??"";return`${i?Le(e,i):o[0]} dependsOn "${a}": circular dependency ${o.join(" -> ")}`});return{name:"Circular dependencies",didPass:!1,message:`${r.length} ${r.length===1?"circular dependency":"circular dependencies"}:
@@ -304,7 +304,7 @@ Fix: ${o.fix}`:""}`).join(`
304
304
  `)}`,fix:`Add to each service's package.json devDependencies: ${s.join(", ")}`}}function zt(e){try{return JSON.parse(ee(e,"utf-8"))}catch{return null}}function mc(e){let n=zt(e)?.compilerOptions;return n?.allowSyntheticDefaultImports===!0||n?.esModuleInterop===!0}function hc(){let e=m()??process.cwd(),t=b(e).filter(r=>r.config?.appType==="frontend");if(t.length===0)return{name:"Frontend Docker Preflight",didPass:!0,isSkipped:!0,message:"No frontend services to check"};let n=[];for(let r of t){O(w(r.path,"public"))||n.push(`${r.name}: no public/ folder, but the Docker build copies it. Create it: mkdir -p ${Kt(Gt(e,w(r.path,"public")))} && touch ${Kt(Gt(e,w(r.path,"public",".gitkeep")))}`);let s=w(r.path,".autogenerated","Dockerfile.app.autogenerated"),o=w(r.path,".autogenerated","tsconfig.docker.autogenerated.json");if(O(s)){let i=ee(s,"utf-8"),a=/\bEXPOSE\s+80\b/.test(i),c=r.config?.stack,u=c?w(e,"services",c,".autogenerated","docker-compose.app.autogenerated.yml"):"";if(a&&u&&O(u)){let d=ee(u,"utf-8"),l=r.name.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),h=new RegExp(`traefik\\.http\\.services\\.${l}\\.loadbalancer\\.server\\.port=(\\d+)`),g=d.match(h)?.[1];g&&g!=="80"&&n.push(`${r.name}: nginx runtime exposes 80, but generated Traefik routes to ${g}`)}}if(O(o)&&!mc(o)){let i=w(r.path,"src","main.tsx");if(O(i)){let a=ee(i,"utf-8"),c=[/import\s+\w+\s+from\s+["']react["']/,/import\s+\w+\s+from\s+["']react-dom\/client["']/].filter(u=>u.test(a)).map(u=>u.source.includes("react-dom")?"react-dom/client":"react");c.length>0&&n.push(`${r.name}: Docker tsconfig does not allow synthetic default imports, but src/main.tsx default-imports ${c.join(" and ")}`)}}}return n.length===0?{name:"Frontend Docker Preflight",didPass:!0,message:`${S(t.length,"frontend")} ${t.length===1?"has":"have"} compatible Docker build/routing metadata`}:{name:"Frontend Docker Preflight",didPass:!1,message:`Frontend Docker metadata has issues that will make \`tdk up\` fail or route 404:
305
305
  ${n.join(`
306
306
  `)}`,fix:'Regenerate with a current TDK (`tdk config regenerate`) and ensure frontend nginx runtimes route to port 80. For React entrypoints, prefer named imports: `import { StrictMode } from "react"` and `import { createRoot } from "react-dom/client"`.'}}var gc=90,kc=80;function yc(e){return e.split(`
307
- `).map(t=>t.trim()).filter(Boolean).map(t=>{let[n,r,s]=t.split(",");return{name:n??"unknown",memPct:Number.parseFloat((r??"").replace("%","")),cpuPct:Number.parseFloat((s??"").replace("%",""))}}).filter(t=>Number.isFinite(t.memPct)&&Number.isFinite(t.cpuPct))}function Sc(){let e;try{e=Wa($("docker")??"docker",["stats","--no-stream","--format","{{.Name}},{{.MemPerc}},{{.CPUPerc}}"],{stdio:"pipe",encoding:"utf-8",timeout:F,windowsHide:process.platform==="win32"})}catch(s){return{name:"Container Resource Health",didPass:!0,isSkipped:!0,message:ks(s)?"Docker not responding - skipped container resource check":"Docker not running - skipped container resource check"}}let t=yc(e);if(t.length===0)return{name:"Container Resource Health",didPass:!0,isSkipped:!0,message:"No running containers to check"};let n=t.filter(s=>s.memPct>=gc&&s.cpuPct>=kc);if(n.length===0)return{name:"Container Resource Health",didPass:!0,message:`${S(t.length,"container")} within normal resource usage`};let r=n.map(s=>`${s.name} (mem ${s.memPct.toFixed(0)}%, cpu ${s.cpuPct.toFixed(0)}%)`).join(`
307
+ `).map(t=>t.trim()).filter(Boolean).map(t=>{let[n,r,s]=t.split(",");return{name:n??"unknown",memPct:Number.parseFloat((r??"").replace(/%/g,"")),cpuPct:Number.parseFloat((s??"").replace(/%/g,""))}}).filter(t=>Number.isFinite(t.memPct)&&Number.isFinite(t.cpuPct))}function Sc(){let e;try{e=Wa($("docker")??"docker",["stats","--no-stream","--format","{{.Name}},{{.MemPerc}},{{.CPUPerc}}"],{stdio:"pipe",encoding:"utf-8",timeout:F,windowsHide:process.platform==="win32"})}catch(s){return{name:"Container Resource Health",didPass:!0,isSkipped:!0,message:ks(s)?"Docker not responding - skipped container resource check":"Docker not running - skipped container resource check"}}let t=yc(e);if(t.length===0)return{name:"Container Resource Health",didPass:!0,isSkipped:!0,message:"No running containers to check"};let n=t.filter(s=>s.memPct>=gc&&s.cpuPct>=kc);if(n.length===0)return{name:"Container Resource Health",didPass:!0,message:`${S(t.length,"container")} within normal resource usage`};let r=n.map(s=>`${s.name} (mem ${s.memPct.toFixed(0)}%, cpu ${s.cpuPct.toFixed(0)}%)`).join(`
308
308
  `);return{name:"Container Resource Health",didPass:!1,message:`${S(n.length,"container")} pinned near its memory limit while burning CPU -- likely stuck in a boot-time retry/fetch loop, not a normal crash:
309
309
  ${r}`,fix:"Check the container's boot logs for a network fetch loop (e.g. `bunx <pkg>` re-downloading a CLI on every start instead of using one already installed): docker logs <container>. If a Prisma auto-migration is the cause, set AUTO_MIGRATE=false in the project's .env as a temporary unblock."}}var bc=5e3;async function xc(e,t){let n=m()??process.cwd(),r=An(b(n),t);return r.length===0?{name:"Service Health",didPass:!0,isSkipped:!0,message:"No routable services to ping"}:$t(await Dn(r,e))}var Tc=new Ga("doctor").description("Check environment readiness for TDK").option("--json","Output a versioned JSON readiness report",!1).exitOverride(e=>{e.exitCode===0&&process.exit(0),Tc.opts().json&&console.log(JSON.stringify(W([],!1,[{code:"USAGE",message:e.message}]))),process.exit(2)}).option("--no-ping","Skip pinging running services' /health endpoints").option("--strict","Fail warnings such as a WSL project under /mnt/c").option("--ping-timeout <ms>","Per-service ping timeout in milliseconds",String(bc)).action(async e=>{let t=Number(e.pingTimeout);if(!/^\d+$/.test(e.pingTimeout)||!Number.isSafeInteger(t)||t<=0){let p="--ping-timeout must be a positive integer number of milliseconds";e.json&&console.log(JSON.stringify(W([],!1,[{code:"USAGE",message:p}]))),console.error(p),process.exit(2);return}e.json||console.log("TDK doctor checks your local Docker + Tilt development environment; it does not check cluster deployments.");let n=hn();if(process.platform==="win32"){if(e.json){let p=null;try{p=await ke()}catch{}console.log(JSON.stringify(W([{name:"Native Windows support",didPass:!1,message:fs,fix:"Use WSL2 Ubuntu with Docker Desktop integration. Guide: docs/wsl2.md"}],!!m(),[],p,{...n,canUp:!1})))}console.error(fs),process.exit(1);return}if(n.kind==="webcontainer"){let p=W([{name:"Host",didPass:!1,message:ze,fix:`Use a machine with Docker. Guide: ${we}`}],!!m(),[],void 0,n);e.json&&console.log(JSON.stringify(p)),console.error(ze),process.exit(1);return}e.json||(console.log(`
310
310
  ${f.bold("\u{1F50D} TDK Doctor")}
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import{createRequire as __tdkRequire}from'node:module';const require=__tdkRequire(import.meta.url);
3
- import{$ as Jy,$a as nB,A as Gm,Aa as G1,B as fA,Ba as L1,C as KA,Ca as j1,D as dg,Da as PC,E as Lm,Ea as Ky,F as I1,Fa as z1,G as y1,Ga as F1,H as Hu,Ha as J1,I as di,Ia as K1,J as pn,Ja as Y1,K as on,Ka as q1,L as Za,La as V1,M as xn,Ma as X1,N as FC,Na as Z1,O as Uo,Oa as WC,P as JC,Pa as $C,Q as Jn,Qa as ns,R as Q1,Ra as eB,S as S1,Sa as tB,T as jm,Ta as P1,U as gg,Ua as Jm,V as v1,Va as Yy,W as zm,Wa as W1,X as pg,Xa as $1,Y as Gu,Ya as eD,Z as KC,Za as tD,_ as YC,_a as nD,a as R,aa as D1,ab as aD,b as GC,ba as mg,bb as oD,c as bl,ca as Zo,cb as qy,d as jy,da as Po,db as Vy,e as Ia,ea as nt,eb as iD,f as Tl,fa as R1,fb as AD,g as u1,ga as b1,gb as lD,h as zy,ha as T1,hb as rD,i as f1,ia as N1,j as ic,ja as qC,k as vn,ka as Eg,kb as sD,l as sr,la as w1,lb as cD,m as jC,ma as VC,n as Fy,na as XC,o as zC,oa as x1,p as d1,pa as _1,q as g1,qa as Fm,r as p1,ra as U1,s as uA,sa as M1,t as Hm,ta as ZC,u as m1,ua as YA,v as E1,va as O1,w as h1,wa as k1,x as C1,xa as H1,y as es,ya as ts,z as B1,za as hg}from"./chunk-M4T3FXXB.js";import{a as r1,c as LC,d as s1,e as c1}from"./chunk-OBQS5CYC.js";import{a as fg,b as ka,c as Yw,d as st}from"./chunk-6EA4DGCY.js";var ZR=ka(hB=>{"use strict";var PU=Symbol.for("react.transitional.element"),WU=Symbol.for("react.fragment");function XR(n,i,l){var s=null;if(l!==void 0&&(s=""+l),i.key!==void 0&&(s=""+i.key),"key"in i){l={};for(var u in i)u!=="key"&&(l[u]=i[u])}else l=i;return i=l.ref,{$$typeof:PU,type:n,key:s,ref:i!==void 0?i:null,props:l}}hB.Fragment=WU;hB.jsx=XR;hB.jsxs=XR});var s2=ka(Dt=>{"use strict";var TQ=Symbol.for("react.transitional.element"),$U=Symbol.for("react.portal"),eM=Symbol.for("react.fragment"),tM=Symbol.for("react.strict_mode"),nM=Symbol.for("react.profiler"),aM=Symbol.for("react.consumer"),oM=Symbol.for("react.context"),iM=Symbol.for("react.forward_ref"),AM=Symbol.for("react.suspense"),lM=Symbol.for("react.memo"),t2=Symbol.for("react.lazy"),rM=Symbol.for("react.activity"),sM=Symbol.for("react.view_transition"),PR=Symbol.iterator;function cM(n){return n===null||typeof n!="object"?null:(n=PR&&n[PR]||n["@@iterator"],typeof n=="function"?n:null)}var n2={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},a2=Object.assign,o2={};function bg(n,i,l){this.props=n,this.context=i,this.refs=o2,this.updater=l||n2}bg.prototype.isReactComponent={};bg.prototype.setState=function(n,i){if(typeof n!="object"&&typeof n!="function"&&n!=null)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,n,i,"setState")};bg.prototype.forceUpdate=function(n){this.updater.enqueueForceUpdate(this,n,"forceUpdate")};function i2(){}i2.prototype=bg.prototype;function NQ(n,i,l){this.props=n,this.context=i,this.refs=o2,this.updater=l||n2}var wQ=NQ.prototype=new i2;wQ.constructor=NQ;a2(wQ,bg.prototype);wQ.isPureReactComponent=!0;var WR=Array.isArray;function bQ(){}var Kn={H:null,A:null,T:null,S:null},A2=Object.prototype.hasOwnProperty;function xQ(n,i,l){var s=l.ref;return{$$typeof:TQ,type:n,key:i,ref:s!==void 0?s:null,props:l}}function uM(n,i){return xQ(n.type,i,n.props)}function _Q(n){return typeof n=="object"&&n!==null&&n.$$typeof===TQ}function fM(n){var i={"=":"=0",":":"=2"};return"$"+n.replace(/[=:]/g,function(l){return i[l]})}var $R=/\/+/g;function RQ(n,i){return typeof n=="object"&&n!==null&&n.key!=null?fM(""+n.key):i.toString(36)}function dM(n){switch(n.status){case"fulfilled":return n.value;case"rejected":throw n.reason;default:switch(typeof n.status=="string"?n.then(bQ,bQ):(n.status="pending",n.then(function(i){n.status==="pending"&&(n.status="fulfilled",n.value=i)},function(i){n.status==="pending"&&(n.status="rejected",n.reason=i)})),n.status){case"fulfilled":return n.value;case"rejected":throw n.reason}}throw n}function Rg(n,i,l,s,u){var p=typeof n;(p==="undefined"||p==="boolean")&&(n=null);var E=!1;if(n===null)E=!0;else switch(p){case"bigint":case"string":case"number":E=!0;break;case"object":switch(n.$$typeof){case TQ:case $U:E=!0;break;case t2:return E=n._init,Rg(E(n._payload),i,l,s,u)}}if(E)return u=u(n),E=s===""?"."+RQ(n,0):s,WR(u)?(l="",E!=null&&(l=E.replace($R,"$&/")+"/"),Rg(u,i,l,"",function(S){return S})):u!=null&&(_Q(u)&&(u=uM(u,l+(u.key==null||n&&n.key===u.key?"":(""+u.key).replace($R,"$&/")+"/")+E)),i.push(u)),1;E=0;var B=s===""?".":s+":";if(WR(n))for(var I=0;I<n.length;I++)s=n[I],p=B+RQ(s,I),E+=Rg(s,i,l,p,u);else if(I=cM(n),typeof I=="function")for(n=I.call(n),I=0;!(s=n.next()).done;)s=s.value,p=B+RQ(s,I++),E+=Rg(s,i,l,p,u);else if(p==="object"){if(typeof n.then=="function")return Rg(dM(n),i,l,s,u);throw i=String(n),Error("Objects are not valid as a React child (found: "+(i==="[object Object]"?"object with keys {"+Object.keys(n).join(", ")+"}":i)+"). If you meant to render a collection of children, use an array instead.")}return E}function CB(n,i,l){if(n==null)return n;var s=[],u=0;return Rg(n,s,"","",function(p){return i.call(l,p,u++)}),s}function gM(n){if(n._status===-1){var i=n._result,l=i();l.then(function(s){(n._status===0||n._status===-1)&&(n._status=1,n._result=s,l.status===void 0&&(l.status="fulfilled",l.value=s))},function(s){(n._status===0||n._status===-1)&&(n._status=2,n._result=s,l.status===void 0&&(l.status="rejected",l.reason=s))}),n._status===-1&&(n._status=0,n._result=l)}if(n._status===1)return n._result.default;throw n._result}var e2=typeof reportError=="function"?reportError:function(n){if(typeof window=="object"&&typeof window.ErrorEvent=="function"){var i=new window.ErrorEvent("error",{bubbles:!0,cancelable:!0,message:typeof n=="object"&&n!==null&&typeof n.message=="string"?String(n.message):String(n),error:n});if(!window.dispatchEvent(i))return}else if(typeof process=="object"&&typeof process.emit=="function"){process.emit("uncaughtException",n);return}console.error(n)};function l2(n){var i=Kn.T,l={};l.types=i!==null?i.types:null,Kn.T=l;try{var s=n(),u=Kn.S;u!==null&&u(l,s),typeof s=="object"&&s!==null&&typeof s.then=="function"&&s.then(bQ,e2)}catch(p){e2(p)}finally{i!==null&&l.types!==null&&(i.types=l.types),Kn.T=i}}function r2(n){var i=Kn.T;if(i!==null){var l=i.types;l===null?i.types=[n]:l.indexOf(n)===-1&&l.push(n)}else l2(r2.bind(null,n))}var pM={map:CB,forEach:function(n,i,l){CB(n,function(){i.apply(this,arguments)},l)},count:function(n){var i=0;return CB(n,function(){i++}),i},toArray:function(n){return CB(n,function(i){return i})||[]},only:function(n){if(!_Q(n))throw Error("React.Children.only expected to receive a single React element child.");return n}};Dt.Activity=rM;Dt.Children=pM;Dt.Component=bg;Dt.Fragment=eM;Dt.Profiler=nM;Dt.PureComponent=NQ;Dt.StrictMode=tM;Dt.Suspense=AM;Dt.ViewTransition=sM;Dt.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE=Kn;Dt.__COMPILER_RUNTIME={__proto__:null,c:function(n){return Kn.H.useMemoCache(n)}};Dt.addTransitionType=r2;Dt.cache=function(n){return function(){return n.apply(null,arguments)}};Dt.cacheSignal=function(){return null};Dt.cloneElement=function(n,i,l){if(n==null)throw Error("The argument must be a React element, but you passed "+n+".");var s=a2({},n.props),u=n.key;if(i!=null)for(p in i.key!==void 0&&(u=""+i.key),i)!A2.call(i,p)||p==="key"||p==="__self"||p==="__source"||p==="ref"&&i.ref===void 0||(s[p]=i[p]);var p=arguments.length-2;if(p===1)s.children=l;else if(1<p){for(var E=Array(p),B=0;B<p;B++)E[B]=arguments[B+2];s.children=E}return xQ(n.type,u,s)};Dt.createContext=function(n){return n={$$typeof:oM,_currentValue:n,_currentValue2:n,_threadCount:0,Provider:null,Consumer:null},n.Provider=n,n.Consumer={$$typeof:aM,_context:n},n};Dt.createElement=function(n,i,l){var s,u={},p=null;if(i!=null)for(s in i.key!==void 0&&(p=""+i.key),i)A2.call(i,s)&&s!=="key"&&s!=="__self"&&s!=="__source"&&(u[s]=i[s]);var E=arguments.length-2;if(E===1)u.children=l;else if(1<E){for(var B=Array(E),I=0;I<E;I++)B[I]=arguments[I+2];u.children=B}if(n&&n.defaultProps)for(s in E=n.defaultProps,E)u[s]===void 0&&(u[s]=E[s]);return xQ(n,p,u)};Dt.createRef=function(){return{current:null}};Dt.forwardRef=function(n){return{$$typeof:iM,render:n}};Dt.isValidElement=_Q;Dt.lazy=function(n){return{$$typeof:t2,_payload:{_status:-1,_result:n},_init:gM}};Dt.memo=function(n,i){return{$$typeof:lM,type:n,compare:i===void 0?null:i}};Dt.startTransition=l2;Dt.unstable_useCacheRefresh=function(){return Kn.H.useCacheRefresh()};Dt.use=function(n){return Kn.H.use(n)};Dt.useActionState=function(n,i,l){return Kn.H.useActionState(n,i,l)};Dt.useCallback=function(n,i){return Kn.H.useCallback(n,i)};Dt.useContext=function(n){return Kn.H.useContext(n)};Dt.useDebugValue=function(){};Dt.useDeferredValue=function(n,i){return Kn.H.useDeferredValue(n,i)};Dt.useEffect=function(n,i){return Kn.H.useEffect(n,i)};Dt.useEffectEvent=function(n){return Kn.H.useEffectEvent(n)};Dt.useId=function(){return Kn.H.useId()};Dt.useImperativeHandle=function(n,i,l){return Kn.H.useImperativeHandle(n,i,l)};Dt.useInsertionEffect=function(n,i){return Kn.H.useInsertionEffect(n,i)};Dt.useLayoutEffect=function(n,i){return Kn.H.useLayoutEffect(n,i)};Dt.useMemo=function(n,i){return Kn.H.useMemo(n,i)};Dt.useOptimistic=function(n,i){return Kn.H.useOptimistic(n,i)};Dt.useReducer=function(n,i,l){return Kn.H.useReducer(n,i,l)};Dt.useRef=function(n){return Kn.H.useRef(n)};Dt.useState=function(n){return Kn.H.useState(n)};Dt.useSyncExternalStore=function(n,i,l){return Kn.H.useSyncExternalStore(n,i,l)};Dt.useTransition=function(){return Kn.H.useTransition()};Dt.version="19.3.0"});var c2=ka((yt,BB)=>{"use strict";process.env.NODE_ENV!=="production"&&(function(){function n(y,U){Object.defineProperty(s.prototype,y,{get:function(){console.warn("%s(...) is deprecated in plain JavaScript React classes. %s",U[0],U[1])}})}function i(y){return y===null||typeof y!="object"?null:(y=Wa&&y[Wa]||y["@@iterator"],typeof y=="function"?y:null)}function l(y,U){y=(y=y.constructor)&&(y.displayName||y.name)||"ReactClass";var ue=y+"."+U;St[ue]||(console.error("Can't call %s on a component that is not yet mounted. This is a no-op, but it might indicate a bug in your application. Instead, assign to `this.state` directly or define a `state = {};` class property with the desired state in the %s component.",U,y),St[ue]=!0)}function s(y,U,ue){this.props=y,this.context=U,this.refs=en,this.updater=ue||Ft}function u(){}function p(y,U,ue){this.props=y,this.context=U,this.refs=en,this.updater=ue||Ft}function E(){}function B(y){return""+y}function I(y){try{B(y);var U=!1}catch{U=!0}if(U){U=console;var ue=U.error,re=typeof Symbol=="function"&&Symbol.toStringTag&&y[Symbol.toStringTag]||y.constructor.name||"Object";return ue.call(U,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",re),B(y)}}function S(y){if(y==null)return null;if(typeof y=="function")return y.$$typeof===Pn?null:y.displayName||y.name||null;if(typeof y=="string")return y;switch(y){case Qt:return"Fragment";case Te:return"Profiler";case J:return"StrictMode";case ct:return"Suspense";case qe:return"SuspenseList";case mn:return"Activity";case Ga:return"ViewTransition"}if(typeof y=="object")switch(typeof y.tag=="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),y.$$typeof){case bt:return"Portal";case Pe:return y.displayName||"Context";case Le:return(y._context.displayName||"Context")+".Consumer";case We:var U=y.render;return y=y.displayName,y||(y=U.displayName||U.name||"",y=y!==""?"ForwardRef("+y+")":"ForwardRef"),y;case He:return U=y.displayName||null,U!==null?U:S(y.type)||"Memo";case $e:U=y._payload,y=y._init;try{return S(y(U))}catch{}}return null}function N(y){if(y===Qt)return"<>";if(typeof y=="object"&&y!==null&&y.$$typeof===$e)return"<...>";try{var U=S(y);return U?"<"+U+">":"<...>"}catch{return"<...>"}}function w(){var y=Ve.A;return y===null?null:y.getOwner()}function T(){return Error("react-stack-top-frame")}function x(y){if(Wt.call(y,"key")){var U=Object.getOwnPropertyDescriptor(y,"key").get;if(U&&U.isReactWarning)return!1}return y.key!==void 0}function z(y,U){function ue(){On||(On=!0,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",U))}ue.isReactWarning=!0,Object.defineProperty(y,"key",{get:ue,configurable:!0})}function F(){var y=S(this.type);return Na[y]||(Na[y]=!0,console.error("Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.")),y=this.props.ref,y!==void 0?y:null}function M(y,U,ue,re,ce,ut){var xe=ue.ref;return y={$$typeof:Me,type:y,key:U,props:ue,_owner:re},(xe!==void 0?xe:null)!==null?Object.defineProperty(y,"ref",{enumerable:!1,get:F}):Object.defineProperty(y,"ref",{enumerable:!1,value:null}),y._store={},Object.defineProperty(y._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(y,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(y,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:ce}),Object.defineProperty(y,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:ut}),Object.freeze&&(Object.freeze(y.props),Object.freeze(y)),y}function Ae(y,U){return U=M(y.type,U,y.props,y._owner,y._debugStack,y._debugTask),y._store&&(U._store.validated=y._store.validated),U}function he(y){Re(y)?y._store&&(y._store.validated=1):typeof y=="object"&&y!==null&&y.$$typeof===$e&&(y._payload.status==="fulfilled"?Re(y._payload.value)&&y._payload.value._store&&(y._payload.value._store.validated=1):y._store&&(y._store.validated=1))}function Re(y){return typeof y=="object"&&y!==null&&y.$$typeof===Me}function Ie(y){var U={"=":"=0",":":"=2"};return"$"+y.replace(/[=:]/g,function(ue){return U[ue]})}function Ge(y,U){return typeof y=="object"&&y!==null&&y.key!=null?(I(y.key),Ie(""+y.key)):U.toString(36)}function Oe(y){switch(y.status){case"fulfilled":return y.value;case"rejected":throw y.reason;default:switch(typeof y.status=="string"?y.then(E,E):(y.status="pending",y.then(function(U){y.status==="pending"&&(y.status="fulfilled",y.value=U)},function(U){y.status==="pending"&&(y.status="rejected",y.reason=U)})),y.status){case"fulfilled":return y.value;case"rejected":throw y.reason}}throw y}function be(y,U,ue,re,ce){var ut=typeof y;(ut==="undefined"||ut==="boolean")&&(y=null);var xe=!1;if(y===null)xe=!0;else switch(ut){case"bigint":case"string":case"number":xe=!0;break;case"object":switch(y.$$typeof){case Me:case bt:xe=!0;break;case $e:return xe=y._init,be(xe(y._payload),U,ue,re,ce)}}if(xe){xe=y,ce=ce(xe);var Xe=re===""?"."+Ge(xe,0):re;return ua(ce)?(ue="",Xe!=null&&(ue=Xe.replace(Qo,"$&/")+"/"),be(ce,U,ue,"",function(Wn){return Wn})):ce!=null&&(Re(ce)&&(ce.key!=null&&(xe&&xe.key===ce.key||I(ce.key)),ue=Ae(ce,ue+(ce.key==null||xe&&xe.key===ce.key?"":(""+ce.key).replace(Qo,"$&/")+"/")+Xe),re!==""&&xe!=null&&Re(xe)&&xe.key==null&&xe._store&&!xe._store.validated&&(ue._store.validated=2),ce=ue),U.push(ce)),1}if(xe=0,Xe=re===""?".":re+":",ua(y))for(var _t=0;_t<y.length;_t++)re=y[_t],ut=Xe+Ge(re,_t),xe+=be(re,U,ue,ut,ce);else if(_t=i(y),typeof _t=="function")for(_t===y.entries&&(qt||console.warn("Using Maps as children is not supported. Use an array of keyed ReactElements instead."),qt=!0),y=_t.call(y),_t=0;!(re=y.next()).done;)re=re.value,ut=Xe+Ge(re,_t++),xe+=be(re,U,ue,ut,ce);else if(ut==="object"){if(typeof y.then=="function")return be(Oe(y),U,ue,re,ce);throw U=String(y),Error("Objects are not valid as a React child (found: "+(U==="[object Object]"?"object with keys {"+Object.keys(y).join(", ")+"}":U)+"). If you meant to render a collection of children, use an array instead.")}return xe}function ze(y,U,ue){if(y==null)return y;var re=[],ce=0;return be(y,re,"","",function(ut){return U.call(ue,ut,ce++)}),re}function Qe(y){if(y._status===-1){var U=null,ue=null,re=y._ioInfo;re!=null&&(re.start=re.end=performance.now(),re.value=new Promise(function(xe,Xe){U=xe,ue=Xe})),re=y._result;var ce=re();if(ce.then(function(xe){if(y._status===0||y._status===-1){y._status=1,y._result=xe;var Xe=y._ioInfo;if(Xe!=null){Xe.end=performance.now();var _t=xe?.default;U(_t),Xe.value.status="fulfilled",Xe.value.value=_t}ce.status===void 0&&(ce.status="fulfilled",ce.value=xe)}},function(xe){if(y._status===0||y._status===-1){y._status=2,y._result=xe;var Xe=y._ioInfo;Xe!=null&&(Xe.end=performance.now(),Xe.value.then(E,E),ue(xe),Xe.value.status="rejected",Xe.value.reason=xe),ce.status===void 0&&(ce.status="rejected",ce.reason=xe)}}),re=y._ioInfo,re!=null){var ut=ce.displayName;typeof ut=="string"&&(re.name=ut)}y._status===-1&&(y._status=0,y._result=ce)}if(y._status===1)return re=y._result,re===void 0&&console.error(`lazy: Expected the result of a dynamic import() call. Instead received: %s
3
+ import{$ as Jy,$a as nB,A as Gm,Aa as G1,B as fA,Ba as L1,C as KA,Ca as j1,D as dg,Da as PC,E as Lm,Ea as Ky,F as I1,Fa as z1,G as y1,Ga as F1,H as Hu,Ha as J1,I as di,Ia as K1,J as pn,Ja as Y1,K as on,Ka as q1,L as Za,La as V1,M as xn,Ma as X1,N as FC,Na as Z1,O as Uo,Oa as WC,P as JC,Pa as $C,Q as Jn,Qa as ns,R as Q1,Ra as eB,S as S1,Sa as tB,T as jm,Ta as P1,U as gg,Ua as Jm,V as v1,Va as Yy,W as zm,Wa as W1,X as pg,Xa as $1,Y as Gu,Ya as eD,Z as KC,Za as tD,_ as YC,_a as nD,a as R,aa as D1,ab as aD,b as GC,ba as mg,bb as oD,c as bl,ca as Zo,cb as qy,d as jy,da as Po,db as Vy,e as Ia,ea as nt,eb as iD,f as Tl,fa as R1,fb as AD,g as u1,ga as b1,gb as lD,h as zy,ha as T1,hb as rD,i as f1,ia as N1,j as ic,ja as qC,k as vn,ka as Eg,kb as sD,l as sr,la as w1,lb as cD,m as jC,ma as VC,n as Fy,na as XC,o as zC,oa as x1,p as d1,pa as _1,q as g1,qa as Fm,r as p1,ra as U1,s as uA,sa as M1,t as Hm,ta as ZC,u as m1,ua as YA,v as E1,va as O1,w as h1,wa as k1,x as C1,xa as H1,y as es,ya as ts,z as B1,za as hg}from"./chunk-I63IBPUZ.js";import{a as r1,c as LC,d as s1,e as c1}from"./chunk-OBQS5CYC.js";import{a as fg,b as ka,c as Yw,d as st}from"./chunk-6EA4DGCY.js";var ZR=ka(hB=>{"use strict";var PU=Symbol.for("react.transitional.element"),WU=Symbol.for("react.fragment");function XR(n,i,l){var s=null;if(l!==void 0&&(s=""+l),i.key!==void 0&&(s=""+i.key),"key"in i){l={};for(var u in i)u!=="key"&&(l[u]=i[u])}else l=i;return i=l.ref,{$$typeof:PU,type:n,key:s,ref:i!==void 0?i:null,props:l}}hB.Fragment=WU;hB.jsx=XR;hB.jsxs=XR});var s2=ka(Dt=>{"use strict";var TQ=Symbol.for("react.transitional.element"),$U=Symbol.for("react.portal"),eM=Symbol.for("react.fragment"),tM=Symbol.for("react.strict_mode"),nM=Symbol.for("react.profiler"),aM=Symbol.for("react.consumer"),oM=Symbol.for("react.context"),iM=Symbol.for("react.forward_ref"),AM=Symbol.for("react.suspense"),lM=Symbol.for("react.memo"),t2=Symbol.for("react.lazy"),rM=Symbol.for("react.activity"),sM=Symbol.for("react.view_transition"),PR=Symbol.iterator;function cM(n){return n===null||typeof n!="object"?null:(n=PR&&n[PR]||n["@@iterator"],typeof n=="function"?n:null)}var n2={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},a2=Object.assign,o2={};function bg(n,i,l){this.props=n,this.context=i,this.refs=o2,this.updater=l||n2}bg.prototype.isReactComponent={};bg.prototype.setState=function(n,i){if(typeof n!="object"&&typeof n!="function"&&n!=null)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,n,i,"setState")};bg.prototype.forceUpdate=function(n){this.updater.enqueueForceUpdate(this,n,"forceUpdate")};function i2(){}i2.prototype=bg.prototype;function NQ(n,i,l){this.props=n,this.context=i,this.refs=o2,this.updater=l||n2}var wQ=NQ.prototype=new i2;wQ.constructor=NQ;a2(wQ,bg.prototype);wQ.isPureReactComponent=!0;var WR=Array.isArray;function bQ(){}var Kn={H:null,A:null,T:null,S:null},A2=Object.prototype.hasOwnProperty;function xQ(n,i,l){var s=l.ref;return{$$typeof:TQ,type:n,key:i,ref:s!==void 0?s:null,props:l}}function uM(n,i){return xQ(n.type,i,n.props)}function _Q(n){return typeof n=="object"&&n!==null&&n.$$typeof===TQ}function fM(n){var i={"=":"=0",":":"=2"};return"$"+n.replace(/[=:]/g,function(l){return i[l]})}var $R=/\/+/g;function RQ(n,i){return typeof n=="object"&&n!==null&&n.key!=null?fM(""+n.key):i.toString(36)}function dM(n){switch(n.status){case"fulfilled":return n.value;case"rejected":throw n.reason;default:switch(typeof n.status=="string"?n.then(bQ,bQ):(n.status="pending",n.then(function(i){n.status==="pending"&&(n.status="fulfilled",n.value=i)},function(i){n.status==="pending"&&(n.status="rejected",n.reason=i)})),n.status){case"fulfilled":return n.value;case"rejected":throw n.reason}}throw n}function Rg(n,i,l,s,u){var p=typeof n;(p==="undefined"||p==="boolean")&&(n=null);var E=!1;if(n===null)E=!0;else switch(p){case"bigint":case"string":case"number":E=!0;break;case"object":switch(n.$$typeof){case TQ:case $U:E=!0;break;case t2:return E=n._init,Rg(E(n._payload),i,l,s,u)}}if(E)return u=u(n),E=s===""?"."+RQ(n,0):s,WR(u)?(l="",E!=null&&(l=E.replace($R,"$&/")+"/"),Rg(u,i,l,"",function(S){return S})):u!=null&&(_Q(u)&&(u=uM(u,l+(u.key==null||n&&n.key===u.key?"":(""+u.key).replace($R,"$&/")+"/")+E)),i.push(u)),1;E=0;var B=s===""?".":s+":";if(WR(n))for(var I=0;I<n.length;I++)s=n[I],p=B+RQ(s,I),E+=Rg(s,i,l,p,u);else if(I=cM(n),typeof I=="function")for(n=I.call(n),I=0;!(s=n.next()).done;)s=s.value,p=B+RQ(s,I++),E+=Rg(s,i,l,p,u);else if(p==="object"){if(typeof n.then=="function")return Rg(dM(n),i,l,s,u);throw i=String(n),Error("Objects are not valid as a React child (found: "+(i==="[object Object]"?"object with keys {"+Object.keys(n).join(", ")+"}":i)+"). If you meant to render a collection of children, use an array instead.")}return E}function CB(n,i,l){if(n==null)return n;var s=[],u=0;return Rg(n,s,"","",function(p){return i.call(l,p,u++)}),s}function gM(n){if(n._status===-1){var i=n._result,l=i();l.then(function(s){(n._status===0||n._status===-1)&&(n._status=1,n._result=s,l.status===void 0&&(l.status="fulfilled",l.value=s))},function(s){(n._status===0||n._status===-1)&&(n._status=2,n._result=s,l.status===void 0&&(l.status="rejected",l.reason=s))}),n._status===-1&&(n._status=0,n._result=l)}if(n._status===1)return n._result.default;throw n._result}var e2=typeof reportError=="function"?reportError:function(n){if(typeof window=="object"&&typeof window.ErrorEvent=="function"){var i=new window.ErrorEvent("error",{bubbles:!0,cancelable:!0,message:typeof n=="object"&&n!==null&&typeof n.message=="string"?String(n.message):String(n),error:n});if(!window.dispatchEvent(i))return}else if(typeof process=="object"&&typeof process.emit=="function"){process.emit("uncaughtException",n);return}console.error(n)};function l2(n){var i=Kn.T,l={};l.types=i!==null?i.types:null,Kn.T=l;try{var s=n(),u=Kn.S;u!==null&&u(l,s),typeof s=="object"&&s!==null&&typeof s.then=="function"&&s.then(bQ,e2)}catch(p){e2(p)}finally{i!==null&&l.types!==null&&(i.types=l.types),Kn.T=i}}function r2(n){var i=Kn.T;if(i!==null){var l=i.types;l===null?i.types=[n]:l.indexOf(n)===-1&&l.push(n)}else l2(r2.bind(null,n))}var pM={map:CB,forEach:function(n,i,l){CB(n,function(){i.apply(this,arguments)},l)},count:function(n){var i=0;return CB(n,function(){i++}),i},toArray:function(n){return CB(n,function(i){return i})||[]},only:function(n){if(!_Q(n))throw Error("React.Children.only expected to receive a single React element child.");return n}};Dt.Activity=rM;Dt.Children=pM;Dt.Component=bg;Dt.Fragment=eM;Dt.Profiler=nM;Dt.PureComponent=NQ;Dt.StrictMode=tM;Dt.Suspense=AM;Dt.ViewTransition=sM;Dt.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE=Kn;Dt.__COMPILER_RUNTIME={__proto__:null,c:function(n){return Kn.H.useMemoCache(n)}};Dt.addTransitionType=r2;Dt.cache=function(n){return function(){return n.apply(null,arguments)}};Dt.cacheSignal=function(){return null};Dt.cloneElement=function(n,i,l){if(n==null)throw Error("The argument must be a React element, but you passed "+n+".");var s=a2({},n.props),u=n.key;if(i!=null)for(p in i.key!==void 0&&(u=""+i.key),i)!A2.call(i,p)||p==="key"||p==="__self"||p==="__source"||p==="ref"&&i.ref===void 0||(s[p]=i[p]);var p=arguments.length-2;if(p===1)s.children=l;else if(1<p){for(var E=Array(p),B=0;B<p;B++)E[B]=arguments[B+2];s.children=E}return xQ(n.type,u,s)};Dt.createContext=function(n){return n={$$typeof:oM,_currentValue:n,_currentValue2:n,_threadCount:0,Provider:null,Consumer:null},n.Provider=n,n.Consumer={$$typeof:aM,_context:n},n};Dt.createElement=function(n,i,l){var s,u={},p=null;if(i!=null)for(s in i.key!==void 0&&(p=""+i.key),i)A2.call(i,s)&&s!=="key"&&s!=="__self"&&s!=="__source"&&(u[s]=i[s]);var E=arguments.length-2;if(E===1)u.children=l;else if(1<E){for(var B=Array(E),I=0;I<E;I++)B[I]=arguments[I+2];u.children=B}if(n&&n.defaultProps)for(s in E=n.defaultProps,E)u[s]===void 0&&(u[s]=E[s]);return xQ(n,p,u)};Dt.createRef=function(){return{current:null}};Dt.forwardRef=function(n){return{$$typeof:iM,render:n}};Dt.isValidElement=_Q;Dt.lazy=function(n){return{$$typeof:t2,_payload:{_status:-1,_result:n},_init:gM}};Dt.memo=function(n,i){return{$$typeof:lM,type:n,compare:i===void 0?null:i}};Dt.startTransition=l2;Dt.unstable_useCacheRefresh=function(){return Kn.H.useCacheRefresh()};Dt.use=function(n){return Kn.H.use(n)};Dt.useActionState=function(n,i,l){return Kn.H.useActionState(n,i,l)};Dt.useCallback=function(n,i){return Kn.H.useCallback(n,i)};Dt.useContext=function(n){return Kn.H.useContext(n)};Dt.useDebugValue=function(){};Dt.useDeferredValue=function(n,i){return Kn.H.useDeferredValue(n,i)};Dt.useEffect=function(n,i){return Kn.H.useEffect(n,i)};Dt.useEffectEvent=function(n){return Kn.H.useEffectEvent(n)};Dt.useId=function(){return Kn.H.useId()};Dt.useImperativeHandle=function(n,i,l){return Kn.H.useImperativeHandle(n,i,l)};Dt.useInsertionEffect=function(n,i){return Kn.H.useInsertionEffect(n,i)};Dt.useLayoutEffect=function(n,i){return Kn.H.useLayoutEffect(n,i)};Dt.useMemo=function(n,i){return Kn.H.useMemo(n,i)};Dt.useOptimistic=function(n,i){return Kn.H.useOptimistic(n,i)};Dt.useReducer=function(n,i,l){return Kn.H.useReducer(n,i,l)};Dt.useRef=function(n){return Kn.H.useRef(n)};Dt.useState=function(n){return Kn.H.useState(n)};Dt.useSyncExternalStore=function(n,i,l){return Kn.H.useSyncExternalStore(n,i,l)};Dt.useTransition=function(){return Kn.H.useTransition()};Dt.version="19.3.0"});var c2=ka((yt,BB)=>{"use strict";process.env.NODE_ENV!=="production"&&(function(){function n(y,U){Object.defineProperty(s.prototype,y,{get:function(){console.warn("%s(...) is deprecated in plain JavaScript React classes. %s",U[0],U[1])}})}function i(y){return y===null||typeof y!="object"?null:(y=Wa&&y[Wa]||y["@@iterator"],typeof y=="function"?y:null)}function l(y,U){y=(y=y.constructor)&&(y.displayName||y.name)||"ReactClass";var ue=y+"."+U;St[ue]||(console.error("Can't call %s on a component that is not yet mounted. This is a no-op, but it might indicate a bug in your application. Instead, assign to `this.state` directly or define a `state = {};` class property with the desired state in the %s component.",U,y),St[ue]=!0)}function s(y,U,ue){this.props=y,this.context=U,this.refs=en,this.updater=ue||Ft}function u(){}function p(y,U,ue){this.props=y,this.context=U,this.refs=en,this.updater=ue||Ft}function E(){}function B(y){return""+y}function I(y){try{B(y);var U=!1}catch{U=!0}if(U){U=console;var ue=U.error,re=typeof Symbol=="function"&&Symbol.toStringTag&&y[Symbol.toStringTag]||y.constructor.name||"Object";return ue.call(U,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",re),B(y)}}function S(y){if(y==null)return null;if(typeof y=="function")return y.$$typeof===Pn?null:y.displayName||y.name||null;if(typeof y=="string")return y;switch(y){case Qt:return"Fragment";case Te:return"Profiler";case J:return"StrictMode";case ct:return"Suspense";case qe:return"SuspenseList";case mn:return"Activity";case Ga:return"ViewTransition"}if(typeof y=="object")switch(typeof y.tag=="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),y.$$typeof){case bt:return"Portal";case Pe:return y.displayName||"Context";case Le:return(y._context.displayName||"Context")+".Consumer";case We:var U=y.render;return y=y.displayName,y||(y=U.displayName||U.name||"",y=y!==""?"ForwardRef("+y+")":"ForwardRef"),y;case He:return U=y.displayName||null,U!==null?U:S(y.type)||"Memo";case $e:U=y._payload,y=y._init;try{return S(y(U))}catch{}}return null}function N(y){if(y===Qt)return"<>";if(typeof y=="object"&&y!==null&&y.$$typeof===$e)return"<...>";try{var U=S(y);return U?"<"+U+">":"<...>"}catch{return"<...>"}}function w(){var y=Ve.A;return y===null?null:y.getOwner()}function T(){return Error("react-stack-top-frame")}function x(y){if(Wt.call(y,"key")){var U=Object.getOwnPropertyDescriptor(y,"key").get;if(U&&U.isReactWarning)return!1}return y.key!==void 0}function z(y,U){function ue(){On||(On=!0,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",U))}ue.isReactWarning=!0,Object.defineProperty(y,"key",{get:ue,configurable:!0})}function F(){var y=S(this.type);return Na[y]||(Na[y]=!0,console.error("Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.")),y=this.props.ref,y!==void 0?y:null}function M(y,U,ue,re,ce,ut){var xe=ue.ref;return y={$$typeof:Me,type:y,key:U,props:ue,_owner:re},(xe!==void 0?xe:null)!==null?Object.defineProperty(y,"ref",{enumerable:!1,get:F}):Object.defineProperty(y,"ref",{enumerable:!1,value:null}),y._store={},Object.defineProperty(y._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(y,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(y,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:ce}),Object.defineProperty(y,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:ut}),Object.freeze&&(Object.freeze(y.props),Object.freeze(y)),y}function Ae(y,U){return U=M(y.type,U,y.props,y._owner,y._debugStack,y._debugTask),y._store&&(U._store.validated=y._store.validated),U}function he(y){Re(y)?y._store&&(y._store.validated=1):typeof y=="object"&&y!==null&&y.$$typeof===$e&&(y._payload.status==="fulfilled"?Re(y._payload.value)&&y._payload.value._store&&(y._payload.value._store.validated=1):y._store&&(y._store.validated=1))}function Re(y){return typeof y=="object"&&y!==null&&y.$$typeof===Me}function Ie(y){var U={"=":"=0",":":"=2"};return"$"+y.replace(/[=:]/g,function(ue){return U[ue]})}function Ge(y,U){return typeof y=="object"&&y!==null&&y.key!=null?(I(y.key),Ie(""+y.key)):U.toString(36)}function Oe(y){switch(y.status){case"fulfilled":return y.value;case"rejected":throw y.reason;default:switch(typeof y.status=="string"?y.then(E,E):(y.status="pending",y.then(function(U){y.status==="pending"&&(y.status="fulfilled",y.value=U)},function(U){y.status==="pending"&&(y.status="rejected",y.reason=U)})),y.status){case"fulfilled":return y.value;case"rejected":throw y.reason}}throw y}function be(y,U,ue,re,ce){var ut=typeof y;(ut==="undefined"||ut==="boolean")&&(y=null);var xe=!1;if(y===null)xe=!0;else switch(ut){case"bigint":case"string":case"number":xe=!0;break;case"object":switch(y.$$typeof){case Me:case bt:xe=!0;break;case $e:return xe=y._init,be(xe(y._payload),U,ue,re,ce)}}if(xe){xe=y,ce=ce(xe);var Xe=re===""?"."+Ge(xe,0):re;return ua(ce)?(ue="",Xe!=null&&(ue=Xe.replace(Qo,"$&/")+"/"),be(ce,U,ue,"",function(Wn){return Wn})):ce!=null&&(Re(ce)&&(ce.key!=null&&(xe&&xe.key===ce.key||I(ce.key)),ue=Ae(ce,ue+(ce.key==null||xe&&xe.key===ce.key?"":(""+ce.key).replace(Qo,"$&/")+"/")+Xe),re!==""&&xe!=null&&Re(xe)&&xe.key==null&&xe._store&&!xe._store.validated&&(ue._store.validated=2),ce=ue),U.push(ce)),1}if(xe=0,Xe=re===""?".":re+":",ua(y))for(var _t=0;_t<y.length;_t++)re=y[_t],ut=Xe+Ge(re,_t),xe+=be(re,U,ue,ut,ce);else if(_t=i(y),typeof _t=="function")for(_t===y.entries&&(qt||console.warn("Using Maps as children is not supported. Use an array of keyed ReactElements instead."),qt=!0),y=_t.call(y),_t=0;!(re=y.next()).done;)re=re.value,ut=Xe+Ge(re,_t++),xe+=be(re,U,ue,ut,ce);else if(ut==="object"){if(typeof y.then=="function")return be(Oe(y),U,ue,re,ce);throw U=String(y),Error("Objects are not valid as a React child (found: "+(U==="[object Object]"?"object with keys {"+Object.keys(y).join(", ")+"}":U)+"). If you meant to render a collection of children, use an array instead.")}return xe}function ze(y,U,ue){if(y==null)return y;var re=[],ce=0;return be(y,re,"","",function(ut){return U.call(ue,ut,ce++)}),re}function Qe(y){if(y._status===-1){var U=null,ue=null,re=y._ioInfo;re!=null&&(re.start=re.end=performance.now(),re.value=new Promise(function(xe,Xe){U=xe,ue=Xe})),re=y._result;var ce=re();if(ce.then(function(xe){if(y._status===0||y._status===-1){y._status=1,y._result=xe;var Xe=y._ioInfo;if(Xe!=null){Xe.end=performance.now();var _t=xe?.default;U(_t),Xe.value.status="fulfilled",Xe.value.value=_t}ce.status===void 0&&(ce.status="fulfilled",ce.value=xe)}},function(xe){if(y._status===0||y._status===-1){y._status=2,y._result=xe;var Xe=y._ioInfo;Xe!=null&&(Xe.end=performance.now(),Xe.value.then(E,E),ue(xe),Xe.value.status="rejected",Xe.value.reason=xe),ce.status===void 0&&(ce.status="rejected",ce.reason=xe)}}),re=y._ioInfo,re!=null){var ut=ce.displayName;typeof ut=="string"&&(re.name=ut)}y._status===-1&&(y._status=0,y._result=ce)}if(y._status===1)return re=y._result,re===void 0&&console.error(`lazy: Expected the result of a dynamic import() call. Instead received: %s
4
4
 
5
5
  Your code should look like:
6
6
  const MyComponent = lazy(() => import('./MyComponent'))
@@ -489,7 +489,7 @@ autoload -U compinit && compinit`;break}case"fish":{N=cr(S,".config","fish","com
489
489
  `:`# TDK (generated files and secrets)
490
490
  `}${u.join(`
491
491
  `)}
492
- `),u}import{existsSync as Cx,lstatSync as Bx}from"node:fs";import{isAbsolute as mD,normalize as AB,relative as Ix,sep as ED}from"node:path";function yx(n){let i=AB(n).split(ED).join("/");return mD(n)||i===".."||i.startsWith("../")?!1:i.split("/").includes(".autogenerated")||i.startsWith(".tdk/.tdk-out/")||i==="shared-platform-engineering/docker-templates"||i.startsWith("shared-platform-engineering/docker-templates/")||i.startsWith("product_autogenerated_resource_manifests/")||i.startsWith("product_autogenerated_services_list/")?!0:i==="Tiltfile"||/^TILT_[^/]+\.star$/.test(i)||i===".tiltignore"||i==="package.json"||i==="services/platform/database-management/docker-compose.yml"}function Lu(n,i){let l=mD(i)?AB(i):AB(`${n}/${i}`),s=Ix(n,l).split(ED).join("/");if(!yx(s))throw new Error(`Refusing to write outside TDK's generated-file allowlist: ${s}`);let u=n;for(let p of s.split("/"))if(u=AB(`${u}/${p}`),Cx(u)&&Bx(u).isSymbolicLink())throw new Error(`Refusing to write through a symbolic link in generated path: ${s}`);return l}var Qx={"database-management":{name:"database-management",description:"Generate and load the stack-level PostgreSQL docker-compose file",generatedFiles:["services/platform/database-management/docker-compose.yml"]}};function hD(n,i){return Qx[i]?["pre_alpha","alpha","beta"].some(l=>n[l]?.enabledStacks?.includes(i)):!1}var vx=Sx(new URL("../dist/generator/template-engine.js",import.meta.url).href),tQ=Ze.dirname(vx);function zu(n){let i=[Ze.join(tQ,"..","..","templates"),Ze.join(tQ,"..","templates"),Ze.join(tQ,"..","..","..","templates"),Ze.join(process.cwd(),"node_modules","@tdk-landscape","tdk-cli-core","templates"),Ze.join(Ze.dirname(process.execPath),"tdk-cli","cli","templates")],l=[];for(let s of i){let u=Ze.join(s,n);l.push(u);try{return It.readFileSync(u,"utf-8")}catch{}}throw new Error(`Failed to load template ${n} from any of these paths: ${l.join(", ")}`)}var nQ=null;function Dx(){return nQ||(nQ={".tiltignore":zu(".tiltignore.hbs"),"TILT_RESOURCE_DEFAULTS.star":zu("TILT_RESOURCE_DEFAULTS.star.hbs"),"TILT_TECH_STACK.star":zu("TILT_TECH_STACK.star.hbs"),Tiltfile:zu("Tiltfile.hbs"),"spec.master":zu("spec.master.hbs")}),nQ}var Rx={proxy:"Traefik reverse proxy",verdaccio:"Private npm registry","database-management":"PostgreSQL database"},bx={monitoring:"Signoz, SkyWalking (RAM intensive)",elk:"Elasticsearch/Logstash/Kibana",debezium:"CDC with Kafka/Zookeeper",golden_image:"Golden image rebuild (one-time)",verdaccio:"Premium local npm registry"},BD=["TILT_TECH_STACK.star","TILT_RESOURCE_DEFAULTS.star","spec.master","Tiltfile",".tiltignore"],Cg=class{templatesDir;constructor(i){let l=fg("node:url").fileURLToPath(new URL("../dist/generator",import.meta.url))||Ze.dirname(new URL(new URL("../dist/generator/template-engine.js",import.meta.url).href).pathname);this.templatesDir=i||Ze.join(l,"..","..","templates"),this.registerHelpers()}formatStarlarkValue(i){return i==null?"None":typeof i=="string"?`"${i.replace(/"/g,'\\"')}"`:typeof i=="boolean"?i?"True":"False":typeof i=="number"?String(i):Array.isArray(i)?`[${i.map(s=>this.formatStarlarkValue(s)).join(", ")}]`:typeof i=="object"?`{${Object.entries(i).map(([s,u])=>`"${s}": ${this.formatStarlarkValue(u)}`).join(", ")}}`:String(i)}registerHelpers(){ju.registerHelper("starlark",i=>new ju.SafeString(this.formatStarlarkValue(i))),ju.registerHelper("starlarkArray",i=>{if(!Array.isArray(i))return new ju.SafeString("[]");let l=i.map(s=>this.formatStarlarkValue(s));return new ju.SafeString(`[${l.join(", ")}]`)}),ju.registerHelper("json",i=>JSON.stringify(i))}buildContext(i){return{version:ki.version,tech:ki.tech,ports:ki.ports,health:ki.health,naming:ki.naming,traefik:ki.traefik,filewatchIgnores:[...ki.filewatchIgnores],serviceTypes:ki.serviceTypes,paths:ki.paths,discovery:{scanIntervalSeconds:ki.discovery.scanIntervalSeconds,maxManifestsPerRoot:ki.discovery.maxManifestsPerRoot,paths:i.discovery.paths},docker:ki.docker,runtime:ki.runtime,project:i.project,phases:Tx(i.phases),alwaysEnabledInfra:i.always_enabled_infra??[...f1],optionalInfra:i.optional_infra,serviceDescriptions:Rx,infraDescriptions:bx}}loadTemplate(i){let l=Ze.join(this.templatesDir,`${i}.hbs`),s=It.existsSync(l)?It.readFileSync(l,"utf-8"):Dx()[i];if(!s)throw new Error(`Template not found: ${l}`);return ju.compile(s)}generateTechStack(i){return this.loadTemplate("TILT_TECH_STACK.star")(i)}generateServiceDefaults(i){return this.loadTemplate("TILT_RESOURCE_DEFAULTS.star")(i)}generateSpecMaster(i){return this.loadTemplate("spec.master")(i)}generateTiltfile(i){return this.loadTemplate("Tiltfile")(i)}generateTiltIgnore(i){return this.loadTemplate(".tiltignore")(i)}generateAll(i){let l=this.buildContext(i);return{"TILT_TECH_STACK.star":this.generateTechStack(l),"TILT_RESOURCE_DEFAULTS.star":this.generateServiceDefaults(l),"spec.master":this.generateSpecMaster(l),Tiltfile:this.generateTiltfile(l),".tiltignore":this.generateTiltIgnore(l)}}};function Tx(n){let i={...n};for(let l of Object.keys(i))i[l]={...i[l],enabledStacks:Array.from(new Set(i[l].enabledStacks))};return i}function Nx(n){return n.replace(/-/g,"_")}function wx(n){let i=Nx(n.project.name||"tdk_project");return`###############################################################################
492
+ `),u}import{existsSync as Cx,lstatSync as Bx}from"node:fs";import{isAbsolute as mD,normalize as AB,relative as Ix,sep as ED}from"node:path";function yx(n){let i=AB(n).split(ED).join("/");return mD(n)||i===".."||i.startsWith("../")?!1:i.split("/").includes(".autogenerated")||i.startsWith(".tdk/.tdk-out/")||i==="shared-platform-engineering/docker-templates"||i.startsWith("shared-platform-engineering/docker-templates/")||i.startsWith("product_autogenerated_resource_manifests/")||i.startsWith("product_autogenerated_services_list/")?!0:i==="Tiltfile"||/^TILT_[^/]+\.star$/.test(i)||i===".tiltignore"||i==="package.json"||i==="services/platform/database-management/docker-compose.yml"}function Lu(n,i){let l=mD(i)?AB(i):AB(`${n}/${i}`),s=Ix(n,l).split(ED).join("/");if(!yx(s))throw new Error(`Refusing to write outside TDK's generated-file allowlist: ${s}`);let u=n;for(let p of s.split("/"))if(u=AB(`${u}/${p}`),Cx(u)&&Bx(u).isSymbolicLink())throw new Error(`Refusing to write through a symbolic link in generated path: ${s}`);return l}var Qx={"database-management":{name:"database-management",description:"Generate and load the stack-level PostgreSQL docker-compose file",generatedFiles:["services/platform/database-management/docker-compose.yml"]}};function hD(n,i){return Qx[i]?["pre_alpha","alpha","beta"].some(l=>n[l]?.enabledStacks?.includes(i)):!1}var vx=Sx(new URL("../dist/generator/template-engine.js",import.meta.url).href),tQ=Ze.dirname(vx);function zu(n){let i=[Ze.join(tQ,"..","..","templates"),Ze.join(tQ,"..","templates"),Ze.join(tQ,"..","..","..","templates"),Ze.join(process.cwd(),"node_modules","@tdk-landscape","tdk-cli-core","templates"),Ze.join(Ze.dirname(process.execPath),"tdk-cli","cli","templates")],l=[];for(let s of i){let u=Ze.join(s,n);l.push(u);try{return It.readFileSync(u,"utf-8")}catch{}}throw new Error(`Failed to load template ${n} from any of these paths: ${l.join(", ")}`)}var nQ=null;function Dx(){return nQ||(nQ={".tiltignore":zu(".tiltignore.hbs"),"TILT_RESOURCE_DEFAULTS.star":zu("TILT_RESOURCE_DEFAULTS.star.hbs"),"TILT_TECH_STACK.star":zu("TILT_TECH_STACK.star.hbs"),Tiltfile:zu("Tiltfile.hbs"),"spec.master":zu("spec.master.hbs")}),nQ}var Rx={proxy:"Traefik reverse proxy",verdaccio:"Private npm registry","database-management":"PostgreSQL database"},bx={monitoring:"Signoz, SkyWalking (RAM intensive)",elk:"Elasticsearch/Logstash/Kibana",debezium:"CDC with Kafka/Zookeeper",golden_image:"Golden image rebuild (one-time)",verdaccio:"Premium local npm registry"},BD=["TILT_TECH_STACK.star","TILT_RESOURCE_DEFAULTS.star","spec.master","Tiltfile",".tiltignore"],Cg=class{templatesDir;constructor(i){let l=fg("node:url").fileURLToPath(new URL("../dist/generator",import.meta.url))||Ze.dirname(new URL(new URL("../dist/generator/template-engine.js",import.meta.url).href).pathname);this.templatesDir=i||Ze.join(l,"..","..","templates"),this.registerHelpers()}quoteStarlarkString(i){return`"${i.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`}formatStarlarkValue(i){return i==null?"None":typeof i=="string"?this.quoteStarlarkString(i):typeof i=="boolean"?i?"True":"False":typeof i=="number"?String(i):Array.isArray(i)?`[${i.map(s=>this.formatStarlarkValue(s)).join(", ")}]`:typeof i=="object"?`{${Object.entries(i).map(([s,u])=>`${this.quoteStarlarkString(s)}: ${this.formatStarlarkValue(u)}`).join(", ")}}`:String(i)}registerHelpers(){ju.registerHelper("starlark",i=>new ju.SafeString(this.formatStarlarkValue(i))),ju.registerHelper("starlarkArray",i=>{if(!Array.isArray(i))return new ju.SafeString("[]");let l=i.map(s=>this.formatStarlarkValue(s));return new ju.SafeString(`[${l.join(", ")}]`)}),ju.registerHelper("json",i=>JSON.stringify(i))}buildContext(i){return{version:ki.version,tech:ki.tech,ports:ki.ports,health:ki.health,naming:ki.naming,traefik:ki.traefik,filewatchIgnores:[...ki.filewatchIgnores],serviceTypes:ki.serviceTypes,paths:ki.paths,discovery:{scanIntervalSeconds:ki.discovery.scanIntervalSeconds,maxManifestsPerRoot:ki.discovery.maxManifestsPerRoot,paths:i.discovery.paths},docker:ki.docker,runtime:ki.runtime,project:i.project,phases:Tx(i.phases),alwaysEnabledInfra:i.always_enabled_infra??[...f1],optionalInfra:i.optional_infra,serviceDescriptions:Rx,infraDescriptions:bx}}loadTemplate(i){let l=Ze.join(this.templatesDir,`${i}.hbs`),s=It.existsSync(l)?It.readFileSync(l,"utf-8"):Dx()[i];if(!s)throw new Error(`Template not found: ${l}`);return ju.compile(s)}generateTechStack(i){return this.loadTemplate("TILT_TECH_STACK.star")(i)}generateServiceDefaults(i){return this.loadTemplate("TILT_RESOURCE_DEFAULTS.star")(i)}generateSpecMaster(i){return this.loadTemplate("spec.master")(i)}generateTiltfile(i){return this.loadTemplate("Tiltfile")(i)}generateTiltIgnore(i){return this.loadTemplate(".tiltignore")(i)}generateAll(i){let l=this.buildContext(i);return{"TILT_TECH_STACK.star":this.generateTechStack(l),"TILT_RESOURCE_DEFAULTS.star":this.generateServiceDefaults(l),"spec.master":this.generateSpecMaster(l),Tiltfile:this.generateTiltfile(l),".tiltignore":this.generateTiltIgnore(l)}}};function Tx(n){let i={...n};for(let l of Object.keys(i))i[l]={...i[l],enabledStacks:Array.from(new Set(i[l].enabledStacks))};return i}function Nx(n){return n.replace(/-/g,"_")}function wx(n){let i=Nx(n.project.name||"tdk_project");return`###############################################################################
493
493
  # SYSTEM-GENERATED - DO NOT EDIT
494
494
  # Stack feature: database-management
495
495
  # Source: .tdk/project.json phases.*.enabledStacks includes "database-management"
@@ -607,7 +607,7 @@ Available templates:`));for(let[p,E]of Object.entries(dB))console.log(` ${R.cya
607
607
  `,0),nt(`Source: ${l.bundledPath?"bundled TDK example":l.repo}`,0),nt(`Destination: ${u}
608
608
  `,0);try{if(l.bundledPath){let p=gB(AU(lU(new URL("../dist/commands/project.js",import.meta.url).href)),"../../../");nU(gB(p,l.bundledPath),u,{recursive:!0});let E=iU(u).replace(/-/g,"_");for(let B of["services/platform/messaging/docker-compose.yml","services/shop/orders-api/service.json","services/shop/orders-api/src/index.ts","services/shop/orders-worker/service.json","services/shop/orders-worker/src/index.ts"]){let I=Dg(u,B),S=fQ(I,"utf-8");oU(I,S.replaceAll("tdk_example",E))}}else tU("git",["clone",l.repo,u],{stdio:"inherit"})}catch{Uo(l.bundledPath?"Bundled example copy failed. Reinstall the TDK CLI package and try again.":"git clone failed. Check you have git installed and network access.")}console.log(R.green(`
609
609
  \u2705 Cloned "${n}" into ${s}/`)),nt(`
610
- Next steps:`,0),nt(`1. cd ${s}`),nt("2. tdk doctor # check Docker/Tilt are ready"),nt("3. tdk up # start the stack")}var Pm={version:"1.0",project:{name:"",version:"1.0.0"},phases:{pre_alpha:{name:"Pre-Alpha",description:"Core infrastructure and MVP services",enabledStacks:cU()},alpha:{name:"Alpha",description:"Essential business services",enabledStacks:[]},beta:{name:"Beta",description:"Extended features",enabledStacks:[]},out_of_scope:{name:"Out of Scope",description:"Future releases",enabledStacks:[]}},optional_infra:{monitoring:!1,elk:!1,debezium:!1,golden_image:!0,verdaccio:!1},discovery:{paths:["services/*/*"]},overrides:{}},cR=new rU("project").description("Initialize or validate project-level master configuration").argument("[template]",`Clone a starter example instead of a blank project (${Object.keys(dB).join(", ")})`).option("--path <dir>","Directory to clone the template into (default: the template's repo name)").option("--check","Check if master configs exist and are in sync").option("--force","Overwrite existing configuration (dangerous)").option("--yes","Non-interactive mode (use defaults)").option("--config-file <path>","Load project config from existing JSON file").action(async(n,i)=>{let{assertMachineReadyOrExit:l}=await import("./cold-preflight-DQVK4J7J.js");if(await l(),n){await xn(async()=>uU(n,i.path));return}await xn(async()=>{let s=vn();s||(s=rR(),Po(`\u{1F680} Initializing new TDK project...
610
+ Next steps:`,0),nt(`1. cd ${s}`),nt("2. tdk doctor # check Docker/Tilt are ready"),nt("3. tdk up # start the stack")}var Pm={version:"1.0",project:{name:"",version:"1.0.0"},phases:{pre_alpha:{name:"Pre-Alpha",description:"Core infrastructure and MVP services",enabledStacks:cU()},alpha:{name:"Alpha",description:"Essential business services",enabledStacks:[]},beta:{name:"Beta",description:"Extended features",enabledStacks:[]},out_of_scope:{name:"Out of Scope",description:"Future releases",enabledStacks:[]}},optional_infra:{monitoring:!1,elk:!1,debezium:!1,golden_image:!0,verdaccio:!1},discovery:{paths:["services/*/*"]},overrides:{}},cR=new rU("project").description("Initialize or validate project-level master configuration").argument("[template]",`Clone a starter example instead of a blank project (${Object.keys(dB).join(", ")})`).option("--path <dir>","Directory to clone the template into (default: the template's repo name)").option("--check","Check if master configs exist and are in sync").option("--force","Overwrite existing configuration (dangerous)").option("--yes","Non-interactive mode (use defaults)").option("--config-file <path>","Load project config from existing JSON file").action(async(n,i)=>{let{assertMachineReadyOrExit:l}=await import("./cold-preflight-NXFER2W6.js");if(await l(),n){await xn(async()=>uU(n,i.path));return}await xn(async()=>{let s=vn();s||(s=rR(),Po(`\u{1F680} Initializing new TDK project...
611
611
  `),nt(`Location: ${s}
612
612
  `,0));let u=Dg(s,".tdk"),p=Dg(u,"project.json");if(i.check){let x=bl.every(F=>Ac(Dg(s,".tdk",".tdk-out",F))),z=Ac(p);if(x&&z){let F=Hi(s);Zo("Project configuration is valid"),nt(`Project: ${F.project.name}`,3),nt(`Phases: ${Object.keys(F.phases).join(", ")}`,3),process.exit(0)}else{if(console.log(R.yellow("\u26A0\uFE0F Project configuration incomplete:")),z||nt(".tdk/project.json (not found)",3),!x)for(let F of bl.filter(M=>!Ac(Dg(s,".tdk/.tdk-out",M))))nt(`.tdk/.tdk-out/${F} (not found)`,3);nt("Run `tdk project` to create them."),process.exit(1)}}Gu("Project Configuration"),nt(`Project root: ${s}
613
613
  `,0),Ac(u)||(pD(u),Zo("Created: .tdk/ directory"));let E=Ac(p);if(E&&!i.force){Zo(".tdk/project.json exists");let x=JSON.parse(fQ(p,"utf-8")),z=Hi(s),F=dQ(s),M=gQ(z,F);if((M.length>0||!x.phases)&&as(p,z),M.length>0&&nt(`Auto-enabled discovered service stacks: ${M.join(", ")}`,0),Po(`
@@ -1416,7 +1416,7 @@ Read about how to prevent this error on https://github.com/vadimdemedes/ink/#isr
1416
1416
  `)}`,B="Upgrade tdk to a version that supports these files. Changing schemaVersion by hand is not a fix";i.onInvalid?.(`${E}
1417
1417
  Fix: ${B}`),console.error(R.red(`\u2717 ${E}`)),console.error(R.gray(` Fix: ${B}`)),l(1)}import{execFileSync as X4}from"node:child_process";var ow=(n,i)=>X4(n,i,{encoding:"utf-8",stdio:"pipe",windowsHide:!0});function Z4(n,i=process.platform,l=ow){if(!Number.isInteger(n)||n<1||n>65535)return[];if(i==="win32"){let u=`$port=${n}; Get-NetTCPConnection -LocalPort $port -State Listen -ErrorAction SilentlyContinue | ForEach-Object { $p=Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue; if ($p -and $p.ProcessName -eq 'tilt') { $_.OwningProcess } } | Sort-Object -Unique`;try{return l("powershell.exe",["-NoProfile","-Command",u]).split(/\s+/).map(Number).filter(p=>Number.isInteger(p)&&p>0)}catch{throw new Error(`Unable to inspect Tilt listeners on port ${n} with PowerShell.`)}}let s;try{s=l("lsof",["-nP","-t",`-iTCP:${n}`,"-sTCP:LISTEN"]).split(/\s+/).map(Number).filter(u=>Number.isInteger(u)&&u>0)}catch(u){let p=u,E=p.stderr?.toString().trim();if(p?.status===1&&!E)return[];throw new Error(`Unable to inspect listeners on port ${n}. Install lsof or resolve the lsof error before using --force.`,{cause:p})}return s.filter(u=>{try{return l("ps",["-p",String(u),"-o","comm="]).trim().split(/[\\/]/).at(-1)==="tilt"}catch(p){throw new Error(`Unable to identify the process listening on port ${n}.`,{cause:p})}})}function TI(n,i=process.platform,l=ow){let s=Z4(n,i,l);for(let u of s)i==="win32"?l("taskkill.exe",["/PID",String(u),"/F"]):l("kill",["-TERM",String(u)]);return s}function iw(n){if(n===void 0||n==="")return{ok:!0,port:void 0};let i=Number(n);return!/^[0-9]+$/.test(n)||!VC(i)?{ok:!1,message:`Invalid TILT_PORT "${n}": expected an integer from 1 to 65535.`}:{ok:!0,port:i}}function Aw(n){return n.runningPorts.length===0||n.force?{action:"start"}:n.only?{action:"only-blocked",ports:n.runningPorts}:{action:"already-running",ports:n.runningPorts}}async function lw(n){if(n.configuredPort!==void 0)return{port:n.configuredPort,autoSwitched:!1};if(n.force)return{port:n.basePort,autoSwitched:!1};let i=await n.findAvailablePort(n.basePort,10);return i&&i!==n.basePort?{port:i,autoSwitched:!0}:{port:n.basePort,autoSwitched:!1}}async function rw(n,i){n.force&&(n.quiet||i.log(`Force flag set - stopping Tilt on port ${n.port} if running...`),i.stop(n.port),await i.wait(2e3))}function sw(n,i){let l=new Set(i.map(s=>s.name));return n.filter(s=>!l.has(s))}function cw(n,i){let l=new Map(i.map(p=>[p.name,p])),s=new Set,u=p=>{if(!(s.has(p)||!l.has(p))){s.add(p);for(let E of l.get(p)?.config?.dependsOn??[])u(E)}};for(let p of n)u(p);return{selected:i.filter(p=>s.has(p.name)),dependencies:i.map(p=>p.name).filter(p=>s.has(p)&&!n.includes(p))}}function uw(n,i=[]){return["TDK is up.",`Tilt UI: http://localhost:${n}`,"App URLs:",...i.length>0?i.slice(0,5).map(l=>` ${l}`):[" run: tdk networks"],"Stop: tdk down"]}function e3(n,i){return n!=="win32"||i==="1"?null:"Landscape startup needs Ubuntu on WSL2. Native Windows is inspect-only."}async function t3(n=Y1(),i=n3){return n.kind==="webcontainer"?J1:q1(n.kind)&&!await i()?K1:null}async function n3(){let{execFile:n}=await import("node:child_process");return new Promise(i=>{n("docker",["ps"],{timeout:1e4},l=>i(!l))})}var a3=2;function o3(n){let i;try{({handEdited:i}=lB(n))}catch(l){if(l instanceof Km)return null;throw l}return i.length===0?null:["Generated files were edited by hand and no longer match service.json:",...i.map(l=>` ${l}`),"Run `tdk config regenerate` to discard the edits, or bypass with `tdk up --ignore-drift`."]}function i3(n,i,l=process.exit){if(i.ignoreDrift){console.warn(R.yellow("Warning: --ignore-drift set; generated files were not checked."));return}let s=o3(n);if(s){i.onDrift?.(s.join(`
1418
1418
  `));for(let u of s)console.error(R.red(u));l(a3)}}function A3(n,i,l=sr(),s=process.exit){if(i.ignoreVersion){console.warn(R.yellow("Warning: --ignore-version set; minTdkVersion was not checked."));return}let u=lD(n,l);u.status==="none"||u.status==="ok"||(i.onFail?.(`${u.message}
1419
- ${u.fix}`),console.error(R.red(u.message)),console.error(R.red(u.fix)),s(1))}function l3(n,i=3e4){return new Promise(l=>{let s=Date.now()+i,u=()=>{let p=P4({host:"127.0.0.1",port:n}),E=!1,B=I=>{E||(E=!0,p.destroy(),I||Date.now()>=s?l(I):setTimeout(u,250))};p.once("connect",()=>B(!0)),p.once("error",()=>B(!1))};u()})}var fw=new $4("up").description("Start all services (optionally filtered by stack)").alias("deploy").argument("[stack-name]","Name of the stack to start (optional - runs all if omitted)").option("-v, --verbose","Enable verbose output",!1).option("-q, --quiet","Suppress non-essential output",!1).option("--dry-run","Show what would be started without starting",!1).option("-f, --force","Kill existing Tilt process before starting",!1).option("--ignore-drift","Start even if generated files differ from service.json",!1).option("--ignore-version","Start even if this tdk is older than minTdkVersion in .tdk/project.json",!1).option("--only <services...>","Start only these services plus what the Tiltfile enables for them (their dependsOn services and shared infrastructure). With a stack, names must belong to that stack; dependencies may cross stacks").option("--json","Print one JSON object on stdout when the stack is ready or the command fails; implies --quiet",!1).action(async(n,i)=>{let l=i.json?fB("UP_FAILED","tdk up"):void 0;i.json&&(i.quiet=!0);let s=iw(process.env.TILT_PORT);s.ok||(l?.({ok:!1},[{code:"INVALID_TILT_PORT",message:s.message}]),Uo(s.message));let u=s.port,p=vn();p&&A3(p,{ignoreVersion:i.ignoreVersion,onFail:N=>l?.({ok:!1},[{code:"TDK_VERSION_TOO_OLD",message:N}])});let E=i.dryRun?null:await t3();E&&(l?.({ok:!1},[{code:"HOST_UNSUPPORTED",message:E}]),Uo(E));let B=e3(process.platform,process.env.TDK_ALLOW_NATIVE_WINDOWS);B&&Uo(B);let I=vn();if(I&&aw(I,{onInvalid:N=>l?.({ok:!1},[{code:"INVALID_SCHEMA_VERSION",message:N}])}),!i.dryRun){let{assertMachineReadyOrExit:N}=await import("./cold-preflight-DQVK4J7J.js");await N()}let S=async()=>{let N=i.dryRun?Za():vn(),w=N??process.cwd(),T=O1(),x,z=[];if((!i.only||n)&&(x=ts(T),z=x.map(J=>J.name)),i.only){if(n&&!hg(n)){let Le=on.stackNotFound(n,z);l?.({ok:!1},[cB(Le).error]),Le.exit()}let J=n?T.filter(Le=>Le.stack===n):T,Te=sw(i.only,J);if(Te.length>0){let Le=J.map(We=>We.name),Pe=on.unknownServices(Te,Le);l?.({ok:!1},[{code:"UNKNOWN_SERVICE",message:Pe.message,...Pe.suggestions.length>0?{suggestions:Pe.suggestions}:{}}]),Pe.exit()}}N&&i3(N,{ignoreDrift:i.ignoreDrift,onDrift:J=>l?.({ok:!1},[{code:"DRIFT_DETECTED",message:J}])}),N&&AD(N,{onInvalid:J=>l?.({ok:!1},[{code:"INVALID_SERVICE_CONFIG",message:J}])}),N&&!l&&!i.quiet&&iD(N);let F=await nB(w,{inspectDocker:!i.dryRun});if(!i.dryRun){if(N){let Le=Jm(w);Le.length>0&&!i.quiet&&console.log(R.gray(`Added ${Le.join(", ")} to .env (generated; existing values unchanged)`))}let J=oQ(w);J.length>0&&i.verbose&&!i.quiet&&console.log(R.gray(`Refreshed runtime assets: ${J.join(", ")}`));let Te=sR(w);Te.length>0&&!i.quiet&&console.log(R.gray(`Added ${Te.join(", ")} to the pre_alpha phase in .tdk/project.json`))}let M,Ae,he=[];if(n){if(M=T.filter(J=>J.stack===n),M.length===0){let J=on.stackNotFound(n,z);l?.({ok:!1},[cB(J).error]),J.exit()}he=M.map(J=>J.name),Ae=`stack "${n}"`}else{M=T;let J=x??ts(T);Ae=`all stacks (${Jn(J.length,"stack")}, ${Jn(M.length,"service")})`}let Re=[];if(i.only){let J=cw(i.only,YA());M=J.selected,Re=J.dependencies,he=M.map(Te=>Te.name),Ae=`${Jn(i.only.length,"requested service")}${Re.length>0?` plus ${Re.join(", ")}`:""}`}i.verbose&&!i.quiet&&console.log(R.gray(`Found ${Jn(M.length,"service")} in ${Ae}`));let Ie=M.map(J=>J.name);if(!i.quiet){console.log(R.blue(`${i.dryRun?"Would start":"Starting"} ${Jn(Ie.length,"service")} from ${Ae}...`)),Ie.forEach(We=>{console.log(R.gray(` - ${We}`))});let{appBase:J,apiBase:Te}=jC(F.ingressHttp),Le=M.filter(We=>We.config?.appType==="frontend"),Pe=M.filter(We=>ic(We.config?.appType));Le.length>0&&(console.log(R.blue(`
1419
+ ${u.fix}`),console.error(R.red(u.message)),console.error(R.red(u.fix)),s(1))}function l3(n,i=3e4){return new Promise(l=>{let s=Date.now()+i,u=()=>{let p=P4({host:"127.0.0.1",port:n}),E=!1,B=I=>{E||(E=!0,p.destroy(),I||Date.now()>=s?l(I):setTimeout(u,250))};p.once("connect",()=>B(!0)),p.once("error",()=>B(!1))};u()})}var fw=new $4("up").description("Start all services (optionally filtered by stack)").alias("deploy").argument("[stack-name]","Name of the stack to start (optional - runs all if omitted)").option("-v, --verbose","Enable verbose output",!1).option("-q, --quiet","Suppress non-essential output",!1).option("--dry-run","Show what would be started without starting",!1).option("-f, --force","Kill existing Tilt process before starting",!1).option("--ignore-drift","Start even if generated files differ from service.json",!1).option("--ignore-version","Start even if this tdk is older than minTdkVersion in .tdk/project.json",!1).option("--only <services...>","Start only these services plus what the Tiltfile enables for them (their dependsOn services and shared infrastructure). With a stack, names must belong to that stack; dependencies may cross stacks").option("--json","Print one JSON object on stdout when the stack is ready or the command fails; implies --quiet",!1).action(async(n,i)=>{let l=i.json?fB("UP_FAILED","tdk up"):void 0;i.json&&(i.quiet=!0);let s=iw(process.env.TILT_PORT);s.ok||(l?.({ok:!1},[{code:"INVALID_TILT_PORT",message:s.message}]),Uo(s.message));let u=s.port,p=vn();p&&A3(p,{ignoreVersion:i.ignoreVersion,onFail:N=>l?.({ok:!1},[{code:"TDK_VERSION_TOO_OLD",message:N}])});let E=i.dryRun?null:await t3();E&&(l?.({ok:!1},[{code:"HOST_UNSUPPORTED",message:E}]),Uo(E));let B=e3(process.platform,process.env.TDK_ALLOW_NATIVE_WINDOWS);B&&Uo(B);let I=vn();if(I&&aw(I,{onInvalid:N=>l?.({ok:!1},[{code:"INVALID_SCHEMA_VERSION",message:N}])}),!i.dryRun){let{assertMachineReadyOrExit:N}=await import("./cold-preflight-NXFER2W6.js");await N()}let S=async()=>{let N=i.dryRun?Za():vn(),w=N??process.cwd(),T=O1(),x,z=[];if((!i.only||n)&&(x=ts(T),z=x.map(J=>J.name)),i.only){if(n&&!hg(n)){let Le=on.stackNotFound(n,z);l?.({ok:!1},[cB(Le).error]),Le.exit()}let J=n?T.filter(Le=>Le.stack===n):T,Te=sw(i.only,J);if(Te.length>0){let Le=J.map(We=>We.name),Pe=on.unknownServices(Te,Le);l?.({ok:!1},[{code:"UNKNOWN_SERVICE",message:Pe.message,...Pe.suggestions.length>0?{suggestions:Pe.suggestions}:{}}]),Pe.exit()}}N&&i3(N,{ignoreDrift:i.ignoreDrift,onDrift:J=>l?.({ok:!1},[{code:"DRIFT_DETECTED",message:J}])}),N&&AD(N,{onInvalid:J=>l?.({ok:!1},[{code:"INVALID_SERVICE_CONFIG",message:J}])}),N&&!l&&!i.quiet&&iD(N);let F=await nB(w,{inspectDocker:!i.dryRun});if(!i.dryRun){if(N){let Le=Jm(w);Le.length>0&&!i.quiet&&console.log(R.gray(`Added ${Le.join(", ")} to .env (generated; existing values unchanged)`))}let J=oQ(w);J.length>0&&i.verbose&&!i.quiet&&console.log(R.gray(`Refreshed runtime assets: ${J.join(", ")}`));let Te=sR(w);Te.length>0&&!i.quiet&&console.log(R.gray(`Added ${Te.join(", ")} to the pre_alpha phase in .tdk/project.json`))}let M,Ae,he=[];if(n){if(M=T.filter(J=>J.stack===n),M.length===0){let J=on.stackNotFound(n,z);l?.({ok:!1},[cB(J).error]),J.exit()}he=M.map(J=>J.name),Ae=`stack "${n}"`}else{M=T;let J=x??ts(T);Ae=`all stacks (${Jn(J.length,"stack")}, ${Jn(M.length,"service")})`}let Re=[];if(i.only){let J=cw(i.only,YA());M=J.selected,Re=J.dependencies,he=M.map(Te=>Te.name),Ae=`${Jn(i.only.length,"requested service")}${Re.length>0?` plus ${Re.join(", ")}`:""}`}i.verbose&&!i.quiet&&console.log(R.gray(`Found ${Jn(M.length,"service")} in ${Ae}`));let Ie=M.map(J=>J.name);if(!i.quiet){console.log(R.blue(`${i.dryRun?"Would start":"Starting"} ${Jn(Ie.length,"service")} from ${Ae}...`)),Ie.forEach(We=>{console.log(R.gray(` - ${We}`))});let{appBase:J,apiBase:Te}=jC(F.ingressHttp),Le=M.filter(We=>We.config?.appType==="frontend"),Pe=M.filter(We=>ic(We.config?.appType));Le.length>0&&(console.log(R.blue(`
1420
1420
  \u{1F30D} Frontend URLs:`)),Le.forEach(We=>{let ct=We.config?.basePath??`/${We.name}`;console.log(R.gray(` - ${We.name}: ${J}${R.cyan(Fy(ct))}`))})),Pe.length>0&&(console.log(R.blue(`
1421
1421
  \u{1F527} Backend API URLs:`)),Pe.forEach(We=>{let ct=We.name.replace(/-api$/,""),qe=We.config?.apiPath??`/api/${ct}`,He=We.config?.sablier,$e=He?.enable&&He?.deferStart?R.dim(" (deferred \u2014 starts on first request)"):"";console.log(R.gray(` - ${We.name}: ${Te}${R.cyan(Fy(qe))}${$e}`))}))}let Ge=i.only??(n?[n]:void 0),Oe=I1(he,{verbose:i.verbose,quiet:i.quiet,force:i.force,focusTargets:Ge}),be=Ge?`tilt up ${Oe.join(" ")}`:"tilt up";if(!i.quiet){console.log(R.blue($1(F)));for(let J of nw(F))console.log(R.yellow(J));console.log(R.gray("Override with TDK_HTTP_PORT, TDK_HTTPS_PORT, or TDK_POSTGRES_PORT."))}if(l&&i.dryRun){l({ok:!0,dryRun:!0,stack:n??null,services:Ie,...i.only?{requested:i.only,declaredDependencies:Re}:{},command:be});return}if(sB(i,"not starting services",be))return;nD(F),tD(w,F);let ze=Tl.tiltUi,Qe=u??ze,Ye=i.only?[...new Set([ze,Qe])]:[Qe],At=[];for(let J of Ye)await lc(J)!==null&&At.push(J);let ke=Aw({runningPorts:At,force:i.force,only:!!i.only});if(ke.action==="already-running"){let J=`Environment is already running on port ${ke.ports.join(", ")}.`;l?.({ok:!0,alreadyRunning:!0,tiltUrl:`http://localhost:${ke.ports[0]}`}),i.quiet||console.log(R.green(J));return}if(ke.action==="only-blocked"){let J=`A Tilt is already running on port ${ke.ports.join(", ")}. --only cannot change a running stack's services: run \`tdk down\` first, or pass --force to replace it.`;l?.({ok:!1},[{code:"TILT_ALREADY_RUNNING",message:J}]),Uo(J)}if(i.only)for(let J of At)TI(J);let kt=await lw({configuredPort:u,force:i.force,basePort:ze,findAvailablePort:oR}),at=kt.port;kt.autoSwitched&&!i.quiet&&(console.log(R.yellow(`\u26A0\uFE0F Port ${ze} is already in use`)),console.log(R.blue(`\u{1F504} Auto-switching to port ${at}
1422
1422
  `))),process.env.TILT_PORT=at.toString(),await rw({force:i.force,quiet:i.quiet,port:at},{stop:TI,log:J=>console.log(R.yellow(J)),wait:J=>new Promise(Te=>setTimeout(Te,J))}),i.quiet||(console.log(R.gray(`
@@ -1,2 +1,2 @@
1
1
  import{createRequire as __tdkRequire}from'node:module';const require=__tdkRequire(import.meta.url);
2
- import{ib as a,jb as b,kb as c,lb as d,mb as e}from"./chunk-M4T3FXXB.js";import"./chunk-OBQS5CYC.js";import"./chunk-6EA4DGCY.js";export{e as assertMachineReadyOrExit,d as formatColdPreflight,a as nodeTooOld,b as requireVerifiedDockerVersions,c as runColdPreflight};
2
+ import{ib as a,jb as b,kb as c,lb as d,mb as e}from"./chunk-I63IBPUZ.js";import"./chunk-OBQS5CYC.js";import"./chunk-6EA4DGCY.js";export{e as assertMachineReadyOrExit,d as formatColdPreflight,a as nodeTooOld,b as requireVerifiedDockerVersions,c as runColdPreflight};
package/cli/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "tdk-cli-internal",
3
3
  "private": true,
4
- "version": "1.3.135",
4
+ "version": "1.3.136",
5
5
  "description": "TDK CLI — start services on your laptop.",
6
6
  "keywords": [
7
7
  "tdk",
@@ -57,7 +57,7 @@ def generate_golden_dockerfile():
57
57
  # =============================================================================
58
58
  # L1: OS BASE + RUNTIME ENVIRONMENT
59
59
  # =============================================================================
60
- FROM oven/bun:1.3.11-alpine AS l1_golden
60
+ FROM oven/bun:1.3.11-alpine@sha256:7ed9f74c326d1c260abe247ac423ccbf5ac92af62bb442d515d1f92f21e8ea9b AS l1_golden
61
61
 
62
62
  LABEL layer="l1" \
63
63
  description="OS base with runtime environment" \
@@ -194,7 +194,7 @@ WORKDIR /app
194
194
  # =============================================================================
195
195
  # L4-BACKEND-NODE: BACKEND PRODUCTION RUNTIME (NODE.JS - LIGHTWEIGHT!)
196
196
  # =============================================================================
197
- FROM node:22-alpine AS l4_backend_node
197
+ FROM node:22-alpine@sha256:0a7108bf6c7bf5de370ffb1a3ed6be93d405b43ff159f681a8d18c0e2bc2e402 AS l4_backend_node
198
198
 
199
199
  LABEL layer="l4-backend-node" \
200
200
  description="Backend production runtime (Node.js - lightweight)" \
@@ -227,7 +227,7 @@ FROM l4_backend_bun AS l4_backend_golden
227
227
  # =============================================================================
228
228
  # L4-FRONTEND: FRONTEND PRODUCTION RUNTIME
229
229
  # =============================================================================
230
- FROM nginx:1.27-alpine AS l4_frontend_golden
230
+ FROM nginx:1.27-alpine@sha256:65645c7bb6a0661892a8b03b89d0743208a18dd2f3f17a54ef4b76fb8e2f2a10 AS l4_frontend_golden
231
231
 
232
232
  LABEL layer="l4-frontend" \
233
233
  description="Frontend production runtime with Nginx" \
@@ -28,7 +28,7 @@ _HEALTHCHECK = """HEALTHCHECK --interval=10s --timeout=5s --retries=3 \\
28
28
  """
29
29
 
30
30
  _PYTHON = """# Generated by TDK for a Python backend. Do not edit; change service.json instead.
31
- FROM python:3.12-slim AS base
31
+ FROM python:3.12-slim@sha256:05cda9777409a9c3ffddd94a4c476b79f0769a0b4857f0c7ed9226b6800b0d6f AS base
32
32
 
33
33
  WORKDIR /app/{res_path}
34
34
 
@@ -52,7 +52,7 @@ CMD ["sh", "-c", "uvicorn main:app --app-dir src --host 0.0.0.0 --port ${{PORT:-
52
52
  """
53
53
 
54
54
  _GO = """# Generated by TDK for a Go backend. Do not edit; change service.json instead.
55
- FROM golang:1.23-bookworm AS build
55
+ FROM golang:1.23-bookworm@sha256:167053a2bb901972bf2c1611f8f52c44d5fe7e762e5cab213708d82c421614db AS build
56
56
  # The official image pins GOTOOLCHAIN=local, so a go.mod that needs a newer Go (Gin 1.12 needs 1.25) stops with "requires go >= 1.25".
57
57
  # `auto` lets Go fetch the toolchain go.mod asks for; a go.mod at or below the image's Go downloads nothing.
58
58
  ENV GOTOOLCHAIN=auto
@@ -68,7 +68,7 @@ RUN CGO_ENABLED=0 go build -o /out/app .
68
68
  FROM build AS test
69
69
  RUN go test ./...
70
70
  {go_development}
71
- FROM debian:bookworm-slim AS production
71
+ FROM debian:bookworm-slim@sha256:7c7b2c966bc9ee8cedfeef67e0e279108992c77681fa595db4a9d65c06ccc587 AS production
72
72
 
73
73
  {curl}
74
74
  COPY --from=build /out/app /usr/local/bin/app
@@ -82,7 +82,7 @@ CMD ["app"]
82
82
  _RUST = """# Generated by TDK for a Rust backend. Do not edit; change service.json instead.
83
83
  # BuildKit cache mounts keep the registry and the target directory between builds, so a rebuild after a
84
84
  # source change recompiles only the crate itself, not every dependency.
85
- FROM rust:1-slim-bookworm AS build
85
+ FROM rust:1-slim-bookworm@sha256:2c3a22f0a5533ea2dd5a16627bc841228151faa2d4de2644ac9987e4a2f1f2fa AS build
86
86
 
87
87
  WORKDIR /app/{res_path}
88
88
 
@@ -96,7 +96,7 @@ RUN --mount=type=cache,target=/usr/local/cargo/registry \\
96
96
  --mount=type=cache,target=/app/{res_path}/target \\
97
97
  cargo test
98
98
 
99
- FROM debian:bookworm-slim AS production
99
+ FROM debian:bookworm-slim@sha256:7c7b2c966bc9ee8cedfeef67e0e279108992c77681fa595db4a9d65c06ccc587 AS production
100
100
 
101
101
  {curl}
102
102
  COPY --from=build /out/app /usr/local/bin/app
@@ -183,7 +183,7 @@ done
183
183
  # source edit recompiles incrementally. `go.mod`, `go.sum` and the Dockerfile still rebuild the image. The heredoc needs BuildKit's
184
184
  # Dockerfile frontend 1.4 (Docker Engine 23+).
185
185
  _GO_DEVELOPMENT = """
186
- FROM golang:1.23-bookworm AS development
186
+ FROM golang:1.23-bookworm@sha256:167053a2bb901972bf2c1611f8f52c44d5fe7e762e5cab213708d82c421614db AS development
187
187
  ENV GOTOOLCHAIN=auto
188
188
  WORKDIR /app/{res_path}
189
189
  COPY {res_path}/go.* ./
@@ -195,7 +195,8 @@ ENV GOFLAGS=-buildvcs=false CGO_ENABLED=0
195
195
  # Same flags as the watcher's builds (and CGO off like the production stage), so the primed binary and cache match every later one.
196
196
  RUN go build -ldflags='-s -w' -o /tmp/app .
197
197
  COPY --chmod=755 <<'TDK_GO_DEV_WATCH' /usr/local/bin/tdk-go-watch
198
- {watch_script}TDK_GO_DEV_WATCH
198
+ {watch_script}
199
+ TDK_GO_DEV_WATCH
199
200
  EXPOSE {port}
200
201
  CMD ["tdk-go-watch"]
201
202
  """
@@ -207,7 +208,7 @@ def generate_language_dockerfile(res_path, language, port = BASE_PORT_BACKEND, d
207
208
  fail("No Dockerfile generator for backend language '{}'".format(language))
208
209
  go_development = ""
209
210
  if dev and language == "go":
210
- go_development = _GO_DEVELOPMENT.format(res_path = res_path, port = port, watch_script = _GO_DEV_WATCH)
211
+ go_development = _GO_DEVELOPMENT.format(res_path = res_path, port = port, watch_script = _GO_DEV_WATCH.rstrip("\n"))
211
212
  return template.format(
212
213
  res_path = res_path,
213
214
  port = port,
@@ -71,9 +71,13 @@
71
71
  {title}
72
72
  </h1>
73
73
  <nav class="nav">
74
+ <!-- nosemgrep: html.security.plaintext-http-link.plaintext-http-link -- localhost dev tools; each listens on loopback over HTTP -->
74
75
  <a href="http://localhost:9765" class="{active_browser}" id="filesLink" data-available="{files_available}">📁 Files</a>
76
+ <!-- nosemgrep: html.security.plaintext-http-link.plaintext-http-link -- localhost dev tools; each listens on loopback over HTTP -->
75
77
  <a href="http://localhost:9766" class="{active_viewer}" id="viewerLink" data-available="{viewer_available}">👁️ Code</a>
78
+ <!-- nosemgrep: html.security.plaintext-http-link.plaintext-http-link -- localhost dev tools; each listens on loopback over HTTP -->
76
79
  <a href="http://localhost:9767" class="{active_inspector}">⚙️ Configs</a>
80
+ <!-- nosemgrep: html.security.plaintext-http-link.plaintext-http-link -- localhost dev tools; each listens on loopback over HTTP -->
77
81
  <a href="http://localhost:9768" class="{active_terminal}" id="terminalLink" data-available="{terminal_available}">💻 Terminal</a>
78
82
  </nav>
79
83
  <button class="theme-toggle" id="themeToggle" title="Toggle theme">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tdk-landscape/tdk-cli-core",
3
- "version": "1.3.135",
3
+ "version": "1.3.136",
4
4
  "description": "TDK CLI — start services on your laptop.",
5
5
  "homepage": "https://tdk-landscape.github.io/tdk-website",
6
6
  "repository": {