infra-kit 0.3.12 → 0.3.13

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.
@@ -1,46 +1,46 @@
1
- import{a as $e,c as N,f as te,j as Ne,p as Ue,q as _e,r as Fe,u as Me}from"./chunk-ADCSGQAU.js";import"./chunk-LKKKDB6V.js";import{b as I,c as He}from"./chunk-RVTI3AL2.js";import{B as C,C as $,D as M,E as Se,F as Pe,G as H,H as xe,I as L,J as De,K as Ae,L as Re,M as ke,N as Ee,O as Te,P as Ce,R as Le,X as ee}from"./chunk-DWZSB6O6.js";import{d as Ie,e as re,m as Oe}from"./chunk-CHETBZ6M.js";import{Command as Vn}from"commander";import D from"node:process";import{pathToFileURL as Jn}from"node:url";import*as Qe from"node:path";import ur from"node:process";var Bt=r=>({pane:{surfaces:[{type:"terminal",command:r}]}}),ne=(r,e)=>{if(r.length===1)return Bt(r[0]);let t=Math.ceil(r.length/2),n=r.slice(0,t),i=r.slice(t);return{direction:e%2===0?"horizontal":"vertical",split:Math.round(t/r.length*100)/100,children:[ne(n,e+1),ne(i,e+1)]}},je=r=>{if(r.length===0)throw new Error("buildCmuxLayout: at least one command is required");return ne(r,0)};import{constants as Zt}from"node:os";import B from"node:process";import{execFile as Wt,execFileSync as Gt}from"node:child_process";import A from"node:process";var Vt=5e3,Jt=100,Be=2e3,Ge="/bin/ps",Kt=1e3,Ve=["-eo","pid=,ppid=,pgid=,lstart="],Je=8<<20,Ke=r=>r.split(`
2
- `).flatMap(e=>{let[t,n,i,...o]=e.trim().split(/\s+/);if(t==null||n==null||i==null)return[];let s=Number(t),a=Number(n),l=Number(i);return!Number.isInteger(s)||!Number.isInteger(a)||!Number.isInteger(l)?[]:[{pid:s,ppid:a,pgid:l,lstart:o.join(" ")}]}),qe=r=>{let e=new Map;for(let t of r)t.pid===t.pgid&&e.set(t.pgid,t.lstart);return e},qt=(r,e,t)=>{let n=qe(e);return Xe(r,e,t).flatMap(i=>{let o=n.get(i);return o==null||o===""?[]:[{pgid:i,leaderStart:o}]})},ze=(r,e)=>{let t=qe(e);return r.flatMap(({pgid:n,leaderStart:i})=>t.get(n)===i?[n]:[])},We=(r,e)=>ze(r,e).flatMap(t=>{try{A.kill(-t,"SIGKILL")}catch{return[]}return[t]}),Xe=(r,e,t)=>{let n=new Map;for(let a of e){let l=n.get(a.ppid);l?l.push(a):n.set(a.ppid,[a])}let i=new Set([r]),o=new Set([r]),s=[r];for(let a=0;a<s.length;a+=1)for(let l of n.get(s[a]??-1)??[])o.has(l.pid)||(o.add(l.pid),i.add(l.pgid),s.push(l.pid));return[...i].filter(a=>a>1&&a!==t)},oe=()=>{try{return Ke(Gt(Ge,[...Ve],{encoding:"utf8",maxBuffer:Je}))}catch{return[]}},zt=async()=>new Promise(r=>{Wt(Ge,[...Ve],{encoding:"utf8",maxBuffer:Je},(e,t)=>{r(e?[]:Ke(t))})}),Xt=(r,e,t)=>t.some(n=>n.pid===r&&n.ppid===e),se=(r,e)=>{let t=e.find(n=>n.pid===A.pid)?.pgid;return Xe(r,e,t)},Ye=r=>{try{return A.kill(-r,0),!0}catch{return!1}},ae=(r,e)=>{for(let t of r)try{A.kill(-t,e)}catch{}},E=new Set,Yt=(r,e,t)=>{let n=se(r,e),i=t.flatMap(o=>ze(o,e));return[...new Set([...n,...i])]},R=()=>{let r=oe(),e=[...E].map(t=>t());ae(Yt(A.pid,r,e),"SIGKILL")},Qt=async r=>new Promise(e=>{setTimeout(e,r)}),ie=async(r,e)=>{let t=Date.now()+e,n=r;for(;n.length>0&&Date.now()<t&&(n=n.filter(Ye),n.length!==0);)await Qt(Jt);return n};function j(r,e=Vt,t,n=oe){r.unref();let i=!1,o=!1,s=[],a=null,l=()=>s;E.add(l);let u=()=>{a&&clearInterval(a),a=null},c=async()=>{await ie(s.map(p=>p.pgid),Be),E.delete(l)},g=p=>{let f=r.pid;if(f==null||o||i||p.length===0)return;let d=p.find(b=>b.pid===A.pid)?.pgid,S=qt(f,p,d);S.length>0&&(s=S)},m=async()=>{r.pid==null||o||i||g(await zt())};g(oe()),a=setInterval(()=>{m()},Kt),a.unref();let h=p=>{i||t?.(p)};return r.on("exit",(p,f)=>{o=!0,u(),i||(We(s,n()),c()),h(`exited unexpectedly (code=${p??"null"}, signal=${f??"null"})`)}),r.on("error",p=>{h(`failed to spawn: ${p.message}`)}),{kill:async()=>{i=!0,u();let p=r.pid;if(p==null){E.delete(l);return}if(r.exitCode!==null||r.signalCode!==null){We(s,n()),await c();return}let f=n();if(f.length>0&&!Xt(p,A.pid,f))return;let d=se(p,f);ae(d,"SIGTERM");let S=await ie(d,e);if(S.length===0){E.delete(l);return}let b=se(p,n()),P=[...new Set([...S,...b])].filter(Ye);ae(P,"SIGKILL"),await ie(P,Be),E.delete(l)}}}var er=["SIGINT","SIGTERM","SIGHUP"],tr=Zt.signals,rr=2,O=r=>128+(tr[r]??rr),nr=2e4,ir=r=>{B.exit(r)},or=(r,e)=>{B.on(r,e)},sr=(r,e)=>{B.off(r,e)},ar=(r,e)=>{let t=setTimeout(r,e);return t.unref(),()=>{clearTimeout(t)}},le=r=>{try{B.stderr.write(r)}catch{}},lr=(r,e)=>{let t=e instanceof Error?`${e.message}
3
- ${e.stack??"(no stack)"}`:String(e);le(`
1
+ import{a as Be,c as O,f as se,j as Ge,p as Je,q as Ke,r as qe,u as ze}from"./chunk-SHFPI4QA.js";import"./chunk-LKKKDB6V.js";import{b as _,c as Xe}from"./chunk-RVTI3AL2.js";import{B as N,C as L,D as B,E as $e,F as Ne,G as j,H as Le,I,J as Ie,K as Oe,L as _e,M as Ue,N as Fe,O as Me,P as He,R as je,X as ie}from"./chunk-SSBYKOHY.js";import{d as We,e as ae,m as Ve}from"./chunk-CHETBZ6M.js";import{Command as bo}from"commander";import D from"node:process";import{pathToFileURL as So}from"node:url";import*as lt from"node:path";import Tr from"node:process";var lr=r=>({pane:{surfaces:[{type:"terminal",command:r}]}}),le=(r,e)=>{if(r.length===1)return lr(r[0]);let t=Math.ceil(r.length/2),n=r.slice(0,t),o=r.slice(t);return{direction:e%2===0?"horizontal":"vertical",split:Math.round(t/r.length*100)/100,children:[le(n,e+1),le(o,e+1)]}},Ye=r=>{if(r.length===0)throw new Error("buildCmuxLayout: at least one command is required");return le(r,0)};import{constants as wr}from"node:os";import W from"node:process";import{execFile as ur,execFileSync as dr}from"node:child_process";import A from"node:process";var pr=5e3,cr=100,Qe=2e3,et="/bin/ps",gr=1e3,tt=["-eo","pid=,ppid=,pgid=,lstart="],rt=8<<20,nt=r=>r.split(`
2
+ `).flatMap(e=>{let[t,n,o,...i]=e.trim().split(/\s+/);if(t==null||n==null||o==null)return[];let s=Number(t),a=Number(n),l=Number(o);return!Number.isInteger(s)||!Number.isInteger(a)||!Number.isInteger(l)?[]:[{pid:s,ppid:a,pgid:l,lstart:i.join(" ")}]}),ot=r=>{let e=new Map;for(let t of r)t.pid===t.pgid&&e.set(t.pgid,t.lstart);return e},hr=(r,e,t)=>{let n=ot(e);return st(r,e,t).flatMap(o=>{let i=n.get(o);return i==null||i===""?[]:[{pgid:o,leaderStart:i}]})},it=(r,e)=>{let t=ot(e);return r.flatMap(({pgid:n,leaderStart:o})=>t.get(n)===o?[n]:[])},Ze=(r,e)=>it(r,e).flatMap(t=>{try{A.kill(-t,"SIGKILL")}catch{return[]}return[t]}),st=(r,e,t)=>{let n=new Map;for(let a of e){let l=n.get(a.ppid);l?l.push(a):n.set(a.ppid,[a])}let o=new Set([r]),i=new Set([r]),s=[r];for(let a=0;a<s.length;a+=1)for(let l of n.get(s[a]??-1)??[])i.has(l.pid)||(i.add(l.pid),o.add(l.pgid),s.push(l.pid));return[...o].filter(a=>a>1&&a!==t)},de=()=>{try{return nt(dr(et,[...tt],{encoding:"utf8",maxBuffer:rt}))}catch{return[]}},fr=async()=>new Promise(r=>{ur(et,[...tt],{encoding:"utf8",maxBuffer:rt},(e,t)=>{r(e?[]:nt(t))})}),mr=(r,e,t)=>t.some(n=>n.pid===r&&n.ppid===e),pe=(r,e)=>{let t=e.find(n=>n.pid===A.pid)?.pgid;return st(r,e,t)},at=r=>{try{return A.kill(-r,0),!0}catch{return!1}},ce=(r,e)=>{for(let t of r)try{A.kill(-t,e)}catch{}},T=new Set,vr=(r,e,t)=>{let n=pe(r,e),o=t.flatMap(i=>it(i,e));return[...new Set([...n,...o])]},k=()=>{let r=de(),e=[...T].map(t=>t());ce(vr(A.pid,r,e),"SIGKILL")},yr=async r=>new Promise(e=>{setTimeout(e,r)}),ue=async(r,e)=>{let t=Date.now()+e,n=r;for(;n.length>0&&Date.now()<t&&(n=n.filter(at),n.length!==0);)await yr(cr);return n};function G(r,e=pr,t,n=de){r.unref();let o=!1,i=!1,s=[],a=null,l=()=>s;T.add(l);let u=()=>{a&&clearInterval(a),a=null},c=async()=>{await ue(s.map(d=>d.pgid),Qe),T.delete(l)},f=d=>{let m=r.pid;if(m==null||i||o||d.length===0)return;let b=d.find(S=>S.pid===A.pid)?.pgid,g=hr(m,d,b);g.length>0&&(s=g)},h=async()=>{r.pid==null||i||o||f(await fr())};f(de()),a=setInterval(()=>{h()},gr),a.unref();let p=d=>{o||t?.(d)};return r.on("exit",(d,m)=>{i=!0,u(),o||(Ze(s,n()),c()),p(`exited unexpectedly (code=${d??"null"}, signal=${m??"null"})`)}),r.on("error",d=>{p(`failed to spawn: ${d.message}`)}),{kill:async()=>{o=!0,u();let d=r.pid;if(d==null){T.delete(l);return}if(r.exitCode!==null||r.signalCode!==null){Ze(s,n()),await c();return}let m=n();if(m.length>0&&!mr(d,A.pid,m))return;let b=pe(d,m);ce(b,"SIGTERM");let g=await ue(b,e);if(g.length===0){T.delete(l);return}let S=pe(d,n()),P=[...new Set([...g,...S])].filter(at);ce(P,"SIGKILL"),await ue(P,Qe),T.delete(l)}}}var br=["SIGINT","SIGTERM","SIGHUP"],Sr=wr.signals,Pr=2,U=r=>128+(Sr[r]??Pr),xr=2e4,Dr=r=>{W.exit(r)},Rr=(r,e)=>{W.on(r,e)},Ar=(r,e)=>{W.off(r,e)},kr=(r,e)=>{let t=setTimeout(r,e);return t.unref(),()=>{clearTimeout(t)}},ge=r=>{try{W.stderr.write(r)}catch{}},Er=(r,e)=>{let t=e instanceof Error?`${e.message}
3
+ ${e.stack??"(no stack)"}`:String(e);ge(`
4
4
  \u2717 Teardown failed while handling ${r}: ${t}
5
- `)},W=({onSignal:r,exit:e=ir,register:t=or,unregister:n=sr,forceReap:i=R,teardownDeadlineMs:o=nr,setTimer:s=ar,describeStall:a=()=>"unknown",fileReport:l=()=>{}})=>{let u=null,c=null,g=new Map,m=()=>{for(let[p,f]of g)n(p,f);g.clear()},h=p=>{if(u!==null){if(p!==u)return;le(`
6
- \u26A0 Received ${p} again \u2014 force-quitting.
7
- `),c?.(),i(),m(),e(O(p));return}u=p,c=s(()=>{let f=`
8
- \u26A0 Teardown deadline exceeded at stage=${a()} after ${o}ms \u2014 force-quitting.
9
- `;le(f),l(f),i(),m(),e(O(p))},o),(async()=>{try{await r(p)}catch(f){lr(p,f)}finally{c?.(),m(),e(O(p))}})()};for(let p of er){let f=()=>h(p);g.set(p,f),t(p,f)}return m};var pr=(r,e)=>r.map(({app:t,targets:n})=>`pnpm exec infra-kit dev ${n&&n.length>0?`--target=${n.join(",")}`:`--app=${t}`}${e?" --watch":""}`),cr=r=>{let e=new Map;for(let t of Object.keys(r?.apps??{})){let n=t.split("/")[0];n===void 0||n==="*"||e.set(n,[...e.get(n)??[],t])}return e},dr=(r,e)=>{let t=M(r);return e?t.filter(n=>e.includes(n.name)):t},gr=(r,e)=>{C.info(`\u{1F9E9} Opened cmux dev workspace ${e} with ${r.length} pane(s):`);for(let t of r)C.info(` \u2022 ${t.name} (infra-kit dev --app=${t.name})`)},hr=r=>{W({onSignal:async e=>{C.info(`
10
- Received ${e}, closing cmux dev workspace ${r}...`),await Fe(r)}})},Ze=async r=>{let e=$(ur.cwd()),t=dr(e,H(r.include));if(t.length===0){C.warn("No API apps found to run");return}let n=cr(r.presetDef),i=pr(t.map(u=>({app:u.name,targets:n.get(u.name)})),r.watch??!1),o=je(i),s=`${Qe.basename(e)} dev`,a=await _e({cwd:e,title:s,layout:o});gr(t,a),hr(a);let l=setInterval(()=>{l.refresh()},2**30);await new Promise(()=>{})};import ue from"node:process";var pe=r=>{try{ue.stderr.write(r)}catch{}},U=(r,e,t=!0)=>{let n=e instanceof Error?`${e.message}
5
+ `)},V=({onSignal:r,exit:e=Dr,register:t=Rr,unregister:n=Ar,forceReap:o=k,teardownDeadlineMs:i=xr,setTimer:s=kr,describeStall:a=()=>"unknown",fileReport:l=()=>{}})=>{let u=null,c=null,f=new Map,h=()=>{for(let[d,m]of f)n(d,m);f.clear()},p=d=>{if(u!==null){if(d!==u)return;ge(`
6
+ \u26A0 Received ${d} again \u2014 force-quitting.
7
+ `),c?.(),o(),h(),e(U(d));return}u=d,c=s(()=>{let m=`
8
+ \u26A0 Teardown deadline exceeded at stage=${a()} after ${i}ms \u2014 force-quitting.
9
+ `;ge(m),l(m),o(),h(),e(U(d))},i),(async()=>{try{await r(d)}catch(m){Er(d,m)}finally{c?.(),h(),e(U(d))}})()};for(let d of br){let m=()=>p(d);f.set(d,m),t(d,m)}return h};var Cr=(r,e)=>r.map(({app:t,targets:n})=>`pnpm exec infra-kit dev ${n&&n.length>0?`--target=${n.join(",")}`:`--app=${t}`}${e?" --watch":""}`),$r=r=>{let e=new Map;for(let t of Object.keys(r?.apps??{})){let n=t.split("/")[0];n===void 0||n==="*"||e.set(n,[...e.get(n)??[],t])}return e},Nr=(r,e)=>{let t=B(r);return e?t.filter(n=>e.includes(n.name)):t},Lr=(r,e)=>{N.info(`\u{1F9E9} Opened cmux dev workspace ${e} with ${r.length} pane(s):`);for(let t of r)N.info(` \u2022 ${t.name} (infra-kit dev --app=${t.name})`)},Ir=r=>{V({onSignal:async e=>{N.info(`
10
+ Received ${e}, closing cmux dev workspace ${r}...`),await qe(r)}})},ut=async r=>{let e=L(Tr.cwd()),t=Nr(e,j(r.include));if(t.length===0){N.warn("No API apps found to run");return}let n=$r(r.presetDef),o=Cr(t.map(u=>({app:u.name,targets:n.get(u.name)})),r.watch??!1),i=Ye(o),s=`${lt.basename(e)} dev`,a=await Ke({cwd:e,title:s,layout:i});Lr(t,a),Ir(a);let l=setInterval(()=>{l.refresh()},2**30);await new Promise(()=>{})};import he from"node:process";var fe=r=>{try{he.stderr.write(r)}catch{}},F=(r,e,t=!0)=>{let n=e instanceof Error?`${e.message}
11
11
  ${e.stack??"(no stack)"}`:String(e);return`
12
12
  \u26A0\uFE0F ${r}: ${n}
13
13
  ${t?` dev-server kept alive (likely a bug in a handler's async path); restart if it misbehaves.
14
14
  `:` dev-server is shutting down: its stdio is unwritable, so reporting this fault would loop forever.
15
- `}`},fr=(r,e)=>{pe(U(r,e))},mr=(r,e)=>{pe(U(r,e,!1))},vr=r=>{pe(`
15
+ `}`},Or=(r,e)=>{fe(F(r,e))},_r=(r,e)=>{fe(F(r,e,!1))},Ur=r=>{fe(`
16
16
  \u2717 dev-server exiting: ${r}
17
- `),R(),ue.exit(1)},yr=(r,e)=>{ue.on(r,e)},et=({onFault:r=fr,register:e=yr,isTerminalDead:t=()=>!1,fileFault:n=mr,onFatal:i=vr}={})=>{let o=!0,s=a=>l=>{if(!o){n(a,l);return}if(t()){n(a,l),i(`${a} while stdio is unwritable`);return}r(a,l)};return e("uncaughtException",s("uncaughtException")),e("unhandledRejection",s("unhandledRejection")),{disarm:()=>{o=!1}}};import{DEFAULT_RELEASE_SLUG as Ct,DEV_CONTEXT_WIRE_VERSION as cn,loadDev as dn,slugifyHostLabel as gn,slugifyRelease as hn}from"@slip-stream-kit/config/internal";import fn from"chokidar";import{exec as mn,execFileSync as vn}from"node:child_process";import*as v from"node:fs";import yn from"node:net";import wn from"node:os";import*as w from"node:path";import y from"node:process";import bn from"node:util";import{execFile as wr}from"node:child_process";import*as tt from"node:fs";import*as G from"node:path";import{promisify as br}from"node:util";var Sr=br(wr),Pr=r=>{try{let e=JSON.parse(tt.readFileSync(G.join(r,"package.json"),"utf-8"));return typeof e.name=="string"?e.name:void 0}catch{return}},xr=r=>async e=>{let{stdout:t}=await Sr("pnpm",["exec","turbo","run","build","--dry=json",`--filter=...${e}`],{cwd:r,maxBuffer:33554432}),i=(JSON.parse(t).tasks??[]).map(o=>o.package).filter(o=>typeof o=="string");return[...new Set(i)]},Dr=r=>{let e=new Map,t=new Map;for(let n of L(r)){let i=Pr(G.dirname(n));i!==void 0&&(e.set(n,i),t.set(i,n))}return{packageNameByDir:e,dirByName:t}},rt=async(r,e,t=xr(r))=>{let{packageNameByDir:n,dirByName:i}=Dr(r),o=new Map,s=await Promise.all(e.map(async a=>({app:a,closure:await t(a.packageName)})));for(let{app:a,closure:l}of s)for(let u of l){let c=i.get(u);if(c===void 0)continue;let g=o.get(c)??new Set;g.add(a.name),o.set(c,g)}return{dependentsByPackageDir:o,packageNameByDir:n}};var nt=(r,e,t)=>{if(e===null||t===void 0)return null;let n=e.dependentsByPackageDir.get(t)??new Set;return r.filter(i=>i.watchDeps&&n.has(i.name))};var Ar="this run never launched it",it=(r,e,t)=>{if(!(!t&&r.includes("<env>")))return r.replaceAll("<packageName>",e).replaceAll("<env>",t??"")},ot=r=>r.default??r.from[0]??"cloud",Rr=(r,e,t)=>r==null?void 0:it(r,e,t),st=r=>r.uis.flatMap(e=>Object.entries(e.routes).flatMap(([t,n])=>{let i=kr(e,t,n,r);return i?[i]:[]})),kr=(r,e,t,{wanted:n,running:i,reasons:o,env:s})=>{let{packageName:a}=t,l=n.has(a)||t.pinnedLocal===!0;if(!t.from.includes("local")||!l||i.has(a))return null;let u=ot(t),c=o.get(a),g=u==="cloud"&&r.cloudTemplate!=null?it(r.cloudTemplate,a,s):void 0;return{uiApp:r.app,route:e,packageName:a,fallback:u,apiApp:c?.app,reason:c?.reason??Ar,cloudTarget:g}},at=r=>{let{uis:e,running:t,localOrigin:n,env:i}=r;return e.flatMap(o=>Object.entries(o.routes).sort(([s],[a])=>s.localeCompare(a)).map(([s,a])=>{let l=a.from.includes("local")&&t.has(a.packageName)?"local":ot(a),u=l==="local"?n(a.packageName):Rr(o.cloudTemplate,a.packageName,i);return{uiApp:o.app,route:s,packageName:a.packageName,source:l,target:u}}))},Er=r=>{if(r.fallback==="local")return`would proxy ${r.route} at the local alias for "${r.packageName}", which nothing is serving \u2014 every request will fail`;let e=r.cloudTarget??"the cloud backend";return`would proxy ${r.route} to ${e} instead of your local backend`},lt=r=>r.apiApp!=null,Tr=r=>lt(r)?`fix ${r.apiApp}/api and re-run (or use --watch to retry it on the next save)`:`this run never launched "${r.packageName}" \u2014 drop the --app/--self narrowing, add its api to the preset, or set "${r.route}" to "cloud" if you meant to develop against cloud`,ut=(r,e)=>{let t=r.map(n=>{let i=lt(n)?`${n.apiApp}/api`:`"${n.packageName}"`;return` ${n.uiApp}/ui ${n.route} \u2192 ${n.packageName}: ${n.uiApp}/ui ${Er(n)}.
18
- ${i}: ${n.reason}
19
- \u2192 ${Tr(n)}`});return`infra-kit dev: "${e}" is supposed to serve a backend locally, but it is not running \u2014 refusing to bring the frontend up silently pointed somewhere else.
17
+ `),k(),he.exit(1)},Fr=(r,e)=>{he.on(r,e)},dt=({onFault:r=Or,register:e=Fr,isTerminalDead:t=()=>!1,fileFault:n=_r,onFatal:o=Ur}={})=>{let i=!0,s=a=>l=>{if(!i){n(a,l);return}if(t()){n(a,l),o(`${a} while stdio is unwritable`);return}r(a,l)};return e("uncaughtException",s("uncaughtException")),e("unhandledRejection",s("unhandledRejection")),{disarm:()=>{i=!1}}};import{DEFAULT_RELEASE_SLUG as Yt,DEV_CONTEXT_WIRE_VERSION as Mn,loadDev as Hn,slugifyHostLabel as Bn,slugifyRelease as jn}from"@slip-stream-kit/config/internal";import Gn from"chokidar";import{exec as Wn,execFileSync as Vn}from"node:child_process";import*as y from"node:fs";import Jn from"node:net";import Kn from"node:os";import*as w from"node:path";import v from"node:process";import qn from"node:util";import{execFile as Mr}from"node:child_process";import*as pt from"node:fs";import*as J from"node:path";import{promisify as Hr}from"node:util";var Br=Hr(Mr),jr=r=>{try{let e=JSON.parse(pt.readFileSync(J.join(r,"package.json"),"utf-8"));return typeof e.name=="string"?e.name:void 0}catch{return}},Gr=r=>async e=>{let{stdout:t}=await Br("pnpm",["exec","turbo","run","build","--dry=json",`--filter=...${e}`],{cwd:r,maxBuffer:33554432}),o=(JSON.parse(t).tasks??[]).map(i=>i.package).filter(i=>typeof i=="string");return[...new Set(o)]},Wr=r=>{let e=new Map,t=new Map;for(let n of I(r)){let o=jr(J.dirname(n));o!==void 0&&(e.set(n,o),t.set(o,n))}return{packageNameByDir:e,dirByName:t}},ct=async(r,e,t=Gr(r))=>{let{packageNameByDir:n,dirByName:o}=Wr(r),i=new Map,s=await Promise.all(e.map(async a=>({app:a,closure:await t(a.packageName)})));for(let{app:a,closure:l}of s)for(let u of l){let c=o.get(u);if(c===void 0)continue;let f=i.get(c)??new Set;f.add(a.name),i.set(c,f)}return{dependentsByPackageDir:i,packageNameByDir:n}},gt=(r,e,t)=>{if(e===null||t===void 0)return null;let n=e.dependentsByPackageDir.get(t)??new Set;return r.filter(o=>o.watchDeps&&n.has(o.name))};var Vr="this run never launched it",ht=(r,e,t)=>{if(!(!t&&r.includes("<env>")))return r.replaceAll("<packageName>",e).replaceAll("<env>",t??"")},ft=r=>r.default??r.from[0]??"cloud",Jr=(r,e,t)=>r==null?void 0:ht(r,e,t),mt=r=>r.uis.flatMap(e=>Object.entries(e.routes).flatMap(([t,n])=>{let o=Kr(e,t,n,r);return o?[o]:[]})),Kr=(r,e,t,{wanted:n,running:o,reasons:i,env:s})=>{let{packageName:a}=t,l=n.has(a)||t.pinnedLocal===!0;if(!t.from.includes("local")||!l||o.has(a))return null;let u=ft(t),c=i.get(a),f=u==="cloud"&&r.cloudTemplate!=null?ht(r.cloudTemplate,a,s):void 0;return{uiApp:r.app,route:e,packageName:a,fallback:u,apiApp:c?.app,reason:c?.reason??Vr,cloudTarget:f}},vt=r=>{let{uis:e,running:t,localOrigin:n,env:o}=r;return e.flatMap(i=>Object.entries(i.routes).sort(([s],[a])=>s.localeCompare(a)).map(([s,a])=>{let l=a.from.includes("local")&&t.has(a.packageName)?"local":ft(a),u=l==="local"?n(a.packageName):Jr(i.cloudTemplate,a.packageName,o);return{uiApp:i.app,route:s,packageName:a.packageName,source:l,target:u}}))},qr=r=>{if(r.fallback==="local")return`would proxy ${r.route} at the local alias for "${r.packageName}", which nothing is serving \u2014 every request will fail`;let e=r.cloudTarget??"the cloud backend";return`would proxy ${r.route} to ${e} instead of your local backend`},yt=r=>r.apiApp!=null,zr=r=>yt(r)?`fix ${r.apiApp}/api and re-run (or use --watch to retry it on the next save)`:`this run never launched "${r.packageName}" \u2014 drop the --app/--self narrowing, add its api to the preset, or set "${r.route}" to "cloud" if you meant to develop against cloud`,wt=(r,e)=>{let t=r.map(n=>{let o=yt(n)?`${n.apiApp}/api`:`"${n.packageName}"`;return` ${n.uiApp}/ui ${n.route} \u2192 ${n.packageName}: ${n.uiApp}/ui ${qr(n)}.
18
+ ${o}: ${n.reason}
19
+ \u2192 ${zr(n)}`});return`infra-kit dev: "${e}" is supposed to serve a backend locally, but it is not running \u2014 refusing to bring the frontend up silently pointed somewhere else.
20
20
 
21
21
  ${t.join(`
22
22
 
23
- `)}`};import{AsyncLocalStorage as Cr}from"node:async_hooks";var ce=new Cr,pt=(r,e)=>ce.run(r,e),ct=r=>{ce.enterWith(r)},V=()=>ce.getStore();import{Buffer as ht}from"node:buffer";import x from"node:fs";import T from"node:path";import k from"node:process";import K from"node:process";var $r=new Set(["EAGAIN","EINTR"]),J=!1,dt=()=>J,Lr=(r,e)=>r===K.stdout?"stdout":r===K.stderr||e===1?"stderr":"stdout",gt=({streams:r=[K.stdout,K.stderr],onDeath:e}={})=>{let t=!1,n=[];for(let[i,o]of r.entries()){let s=Lr(o,i),a=l=>{let u=l??new Error("stdio error");u.code!=null&&$r.has(u.code)||(J=!0,!t&&(t=!0,e?.(s,u)))};o.on("error",a),n.push({stream:o,listener:a})}return{isDead:()=>J,uninstall:()=>{for(let{stream:i,listener:o}of n)i.removeListener("error",o);n.length=0,J=!1,t=!1}}};var Nr=()=>Object.getPrototypeOf(k.stdout).write,de=r=>dt()?!0:Nr().call(k.stdout,r);var vt=()=>new Proxy(k.stdout,{get(r,e,t){if(e==="write")return i=>de(String(i));let n=Reflect.get(r,e,t);return typeof n=="function"?n.bind(r):n}}),ft=()=>({errors:0,warns:0,lastErrorAt:null}),yt=r=>{let e=r.split(/\W+/).filter(t=>t!=="").join("-");return e===""?null:e},Ir=()=>{let r=k.env[Ie]??"",e=yt(r)??"no-session";return T.join(Oe(),e,"dev",String(k.pid))},mt=r=>`${yt(r)??"unnamed"}.log`,Or=10080*60*1e3,Ur=r=>{let e=Number(r);if(!Number.isInteger(e)||e<=0)return!1;try{return k.kill(e,0),!0}catch(t){return t.code==="EPERM"}},_r=(r,e)=>{let t;try{t=x.readdirSync(r,{withFileTypes:!0})}catch{return}for(let n of t){if(!n.isDirectory()||Ur(n.name))continue;let i=T.join(r,n.name);try{e-x.statSync(i).mtimeMs>Or&&x.rmSync(i,{recursive:!0,force:!0})}catch{}}},Fr=256*1024*1024,Mr="INFRA_KIT_DEV_LOG_MAX_BYTES",Hr=()=>{let r=Number(k.env[Mr]);return Number.isInteger(r)&&r>0?r:Fr},q=class{dir;fds=new Map;counters=new Map;bytes=new Map;capped=new Set;maxBytes;closed=!1;constructor(e=Ir(),t=Hr()){this.dir=e,this.maxBytes=t,x.mkdirSync(this.dir,{recursive:!0}),_r(T.dirname(this.dir),Date.now()),this.linkLatest()}linkLatest(){let e=T.join(T.dirname(this.dir),"latest");try{x.rmSync(e,{force:!0}),x.symlinkSync(this.dir,e,"dir")}catch{}}pathFor(e){return T.join(this.dir,mt(e))}fdFor(e){let t=this.fds.get(e);if(t!=null)return t;try{let n=x.openSync(this.pathFor(e),"a");this.fds.set(e,n);try{this.bytes.set(e,x.fstatSync(n).size)}catch{this.bytes.set(e,0)}return n}catch{return null}}write(e,t,n={}){if(this.closed)return;let i=this.counters.get(e)??ft();if(n.level==="error"?(i.errors+=1,i.lastErrorAt=Date.now()):n.level==="warn"&&(i.warns+=1),this.counters.set(e,i),this.capped.has(e))return;let o=this.fdFor(e);if(o==null)return;let s=t.endsWith(`
23
+ `)}`};import{AsyncLocalStorage as Xr}from"node:async_hooks";var me=new Xr,bt=(r,e)=>me.run(r,e),St=r=>{me.enterWith(r)},K=()=>me.getStore();import{Buffer as Dt}from"node:buffer";import x from"node:fs";import C from"node:path";import E from"node:process";import z from"node:process";var Yr=new Set(["EAGAIN","EINTR"]),q=!1,Pt=()=>q,Qr=(r,e)=>r===z.stdout?"stdout":r===z.stderr||e===1?"stderr":"stdout",xt=({streams:r=[z.stdout,z.stderr],onDeath:e}={})=>{let t=!1,n=[];for(let[o,i]of r.entries()){let s=Qr(i,o),a=l=>{let u=l??new Error("stdio error");u.code!=null&&Yr.has(u.code)||(q=!0,!t&&(t=!0,e?.(s,u)))};i.on("error",a),n.push({stream:i,listener:a})}return{isDead:()=>q,uninstall:()=>{for(let{stream:o,listener:i}of n)o.removeListener("error",i);n.length=0,q=!1,t=!1}}};var Zr=()=>Object.getPrototypeOf(E.stdout).write,ve=r=>Pt()?!0:Zr().call(E.stdout,r);var kt=()=>new Proxy(E.stdout,{get(r,e,t){if(e==="write")return o=>ve(String(o));let n=Reflect.get(r,e,t);return typeof n=="function"?n.bind(r):n}}),Rt=()=>({errors:0,warns:0,lastErrorAt:null}),Et=r=>{let e=r.split(/\W+/).filter(t=>t!=="").join("-");return e===""?null:e},en=()=>{let r=E.env[We]??"",e=Et(r)??"no-session";return C.join(Ve(),e,"dev",String(E.pid))},At=r=>`${Et(r)??"unnamed"}.log`,tn=10080*60*1e3,rn=r=>{let e=Number(r);if(!Number.isInteger(e)||e<=0)return!1;try{return E.kill(e,0),!0}catch(t){return t.code==="EPERM"}},nn=(r,e)=>{let t;try{t=x.readdirSync(r,{withFileTypes:!0})}catch{return}for(let n of t){if(!n.isDirectory()||rn(n.name))continue;let o=C.join(r,n.name);try{e-x.statSync(o).mtimeMs>tn&&x.rmSync(o,{recursive:!0,force:!0})}catch{}}},on=256*1024*1024,sn="INFRA_KIT_DEV_LOG_MAX_BYTES",an=()=>{let r=Number(E.env[sn]);return Number.isInteger(r)&&r>0?r:on},X=class{dir;fds=new Map;counters=new Map;bytes=new Map;capped=new Set;maxBytes;closed=!1;constructor(e=en(),t=an()){this.dir=e,this.maxBytes=t,x.mkdirSync(this.dir,{recursive:!0}),nn(C.dirname(this.dir),Date.now()),this.linkLatest()}linkLatest(){let e=C.join(C.dirname(this.dir),"latest");try{x.rmSync(e,{force:!0}),x.symlinkSync(this.dir,e,"dir")}catch{}}pathFor(e){return C.join(this.dir,At(e))}fdFor(e){let t=this.fds.get(e);if(t!=null)return t;try{let n=x.openSync(this.pathFor(e),"a");this.fds.set(e,n);try{this.bytes.set(e,x.fstatSync(n).size)}catch{this.bytes.set(e,0)}return n}catch{return null}}write(e,t,n={}){if(this.closed)return;let o=this.counters.get(e)??Rt();if(n.level==="error"?(o.errors+=1,o.lastErrorAt=Date.now()):n.level==="warn"&&(o.warns+=1),this.counters.set(e,o),this.capped.has(e))return;let i=this.fdFor(e);if(i==null)return;let s=t.endsWith(`
24
24
  `)?t:`${t}
25
- `,a=ht.byteLength(s);if((this.bytes.get(e)??0)+a>this.maxBytes){this.capped.add(e),this.writeRaw(o,e,`[capped] ${mt(e)} hit ${this.maxBytes} bytes; further lines dropped (likely a logging loop)
26
- `);return}this.writeRaw(o,e,s)}writeRaw(e,t,n){try{x.writeSync(e,n),this.bytes.set(t,(this.bytes.get(t)??0)+ht.byteLength(n))}catch{}}statsFor(e){return this.counters.get(e)??ft()}services(){return[...this.fds.keys()]}close(){if(!this.closed){this.closed=!0;for(let e of this.fds.values())try{x.closeSync(e)}catch{}this.fds.clear()}}};import ge from"node:process";import jr from"node:util";var he={log:"info",info:"info",debug:"debug",trace:"debug",warn:"warn",error:"error"},wt=({sink:r,fallbackService:e,currentService:t})=>{let n=!0,i=()=>t()??e,o=(c,g)=>{r.write(i(),c,{level:g})},s={};for(let c of Object.keys(he))s[c]=console[c],console[c]=(...g)=>{if(!n){s[c](...g);return}o(jr.format(...g),he[c])};let a=(c,g)=>{let m=c.write.bind(c),h="",p=()=>{h!==""&&(r.write(i(),h,{level:g}),h="")};return c.write=((f,...d)=>{if(!n||typeof f!="string")return m(f,...d);h+=f;let S=h.split(`
27
- `);h=S.pop()??"";for(let P of S)P!==""&&r.write(i(),P,{level:g});h.length>8192&&p();let b=d.find(P=>typeof P=="function");return typeof b=="function"&&ge.nextTick(b),!0}),()=>{p(),Reflect.deleteProperty(c,"write")}},l=a(ge.stdout,"info"),u=a(ge.stderr,"warn");return{uninstall:()=>{if(n){n=!1,l(),u();for(let c of Object.keys(he))console[c]=s[c]}}}};var Br="/api/v1";function bt(r){if(r==null||r==="")return;let e=parseInt(r.trim().replace(/^["']|["']$/g,""),10);return Number.isNaN(e)?void 0:e}function St(r,e,t){let i=`${r.replace(/-/g,"_").toUpperCase()}_PORT`,o=bt(e[i]);if(o!=null)return o;let s=bt(e.PORT);return s??t[r]?.port??void 0}function Pt(r,e){return e[r]?.prefixUrl??Br}function xt(r){let e=r.map(i=>i.port),t=e.filter((i,o)=>e.indexOf(i)!==o),n=r.filter(i=>t.includes(i.port));return{duplicatePorts:t,conflictingApps:n}}import{Logger as Wr}from"@aws-lambda-powertools/logger";import Gr from"fastify";import*as At from"node:fs";import*as _ from"node:path";import fe from"node:process";import{pathToFileURL as Vr}from"node:url";import{parse as Jr}from"yaml";var Kr=r=>r?.code==="EADDRINUSE",qr=3e4,zr=()=>{let r=Number.parseInt(fe.env.DEV_SERVER_TIMEOUT_MS??"",10);return Number.isNaN(r)?qr:r},Dt=()=>fe.env.DEV_SERVER_REQUEST_LOG==="1",z=class{constructor(e){this.serverConfig=e;this.importCacheBust=`${Date.now()}`,this.logger=new Wr({serviceName:"LocalServer",logLevel:"DEBUG"}),this.serverConfig.prefixUrl=this.serverConfig.prefixUrl??"",this.server=Gr({logger:!1}),this.server.addHook("onRequest",async(n,i)=>{let o=this.serverConfig.serviceTag;o!=null&&ct(o),i.header("Access-Control-Allow-Origin","*"),i.header("Access-Control-Allow-Methods","GET, POST, PUT, DELETE, PATCH, OPTIONS"),i.header("Access-Control-Allow-Headers","Content-Type, Authorization, X-Requested-With"),n.method==="OPTIONS"&&i.status(204).send()});let t=this.serverConfig.onRequestLog;(Dt()||t)&&this.server.addHook("onResponse",async(n,i)=>{let o=Math.round(i.elapsedTime),s=n.url.split("?")[0]??n.url;t?.({method:n.method,path:s,status:i.statusCode,ms:o}),Dt()&&fe.stdout.write(`${n.method} ${n.url} \u2192 ${i.statusCode} ${o}ms
28
- `)})}serverConfig;importCacheBust;logger;server;controllers={};registeredRouteKeys=new Set;getRegisteredRoutes(){return[...this.registeredRouteKeys].sort()}async start(){this.registerHealthRoute(),await Promise.all(this.loadRoutes());let e=await this.listenWithFallback();return this.serverConfig.port=e,this.logger.info(`Server listening on http://127.0.0.1:${e}`,{address:`http://127.0.0.1:${e}`}),e}async listenWithFallback(){let e=this.serverConfig.port;if(e!=null)try{return await this.server.listen({port:e,host:"127.0.0.1"}),this.readBoundPort()}catch(t){if(!Kr(t))throw t}return await this.server.listen({port:0,host:"127.0.0.1"}),this.readBoundPort()}readBoundPort(){let e=this.server.server.address();if(e==null||typeof e=="string")throw new Error("Server address unavailable after listen()");return e.port}async close(){let e=this.server.server;typeof e.closeAllConnections=="function"&&e.closeAllConnections(),await this.server.close()}registerHealthRoute(){this.server.route({method:"GET",url:"/__health",handler:(e,t)=>t.code(200).send({status:"ok",app:this.serverConfig.appName??null,port:this.serverConfig.port})})}loadRoutes(){let e=_.join(this.serverConfig.controllersPath,"serverless.yml"),t=At.readFileSync(e,"utf8"),n=Jr(t),i=[];if(!n?.functions)return i;for(let o of Object.values(n.functions))if(o?.events?.length)for(let s of o.events){let a=s?.http;a&&i.push(this.defineRoute(a,o))}return i}async defineRoute(e,t){let n=e.path.toString();n=n.replaceAll("{",":").replaceAll("}","");let i=_.posix.join(this.serverConfig.prefixUrl??"",n);i=i[0]==="/"?i:`/${i}`;let o=["GET","POST","PUT","DELETE","PATCH","HEAD","OPTIONS"],s=String(e.method).toUpperCase();if(!o.includes(s))throw new Error(`Invalid HTTP method: "${e.method}" for URL: ${i}`);let a=`${s} ${i}`;if(this.registeredRouteKeys.has(a))throw new Error(`Duplicate route: ${a}`);this.registeredRouteKeys.add(a);let u=(t.handler??"").split("."),c=u[0]??"",g=u[1]??"",m=_.join(this.serverConfig.controllersPath,`${c}.js`),h=Vr(m);h.searchParams.set("v",this.importCacheBust);let p=this.serverConfig.serviceTag,f=async()=>await import(h.href),d=p==null?await f():await pt(p,f);this.controllers[a]={action:d,handler:g};let S=this.logger.createChild({serviceName:"RequestLogger"});this.server.route({method:s,url:i,handler:async(b,P)=>{let F=this.controllers[a];if(!F)throw new Error(`No controller for ${a}`);let be=F.action[F.handler];if(!be)throw new Error(`No handler ${F.handler} for ${i}`);let Z=await be(this.getEventObj(b.body,b.query,b.params,b.headers,s,i),this.getContext(),S),jt=JSON.parse(Z.body);return P.headers(Z.headers??{}),P.code(Z?.statusCode??500).send(jt)}})}getEventObj(e,t,n,i,o="",s=""){let a={body:e?JSON.stringify(e):null,headers:i??{},multiValueHeaders:{},httpMethod:o,isBase64Encoded:!1,path:s,pathParameters:n??null,queryStringParameters:t??null,multiValueQueryStringParameters:null,stageVariables:null,requestContext:{accountId:"",apiId:"",authorizer:void 0,protocol:"",httpMethod:o,identity:{accessKey:null,accountId:null,apiKey:null,apiKeyId:null,caller:null,clientCert:null,cognitoAuthenticationProvider:null,cognitoAuthenticationType:null,cognitoIdentityId:null,cognitoIdentityPoolId:null,principalOrgId:null,sourceIp:"devIp",user:null,userAgent:null,userArn:null},path:s,stage:"",requestId:"",requestTimeEpoch:0,resourceId:"",resourcePath:s},resource:s};return a.source="aws.events",a}getContext(){let e=Date.now(),t=zr(),n=new Date().toISOString().split("T")[0]??"";return{callbackWaitsForEmptyEventLoop:!1,functionName:"local-dev",functionVersion:"1.0.0",invokedFunctionArn:"arn:aws:lambda:local:000000000000:function:local-dev",memoryLimitInMB:"1024",awsRequestId:`local-${Date.now()}`,logGroupName:"/aws/lambda/local-dev",logStreamName:`${n}/local`,getRemainingTimeInMillis:()=>Math.max(0,t-(Date.now()-e)),done:(i,o)=>{},fail:i=>{},succeed:i=>{}}}};import{spawn as Xr}from"node:child_process";import*as Rt from"node:fs";var Yr=(r,e)=>[...r.map(t=>`--filter=...${t}`),...e.map(t=>`--filter=${t}^...`)],kt=({depInclusive:r,depClosure:e,cwd:t,logFile:n,onUnexpectedExit:i})=>{let o=Yr(r,e),s=Rt.openSync(n,"a"),a=Xr("pnpm",["exec","turbo","watch","build",...o,"--continue=dependencies-successful","--env-mode=loose"],{cwd:t,detached:!0,stdio:["ignore",s,s]});return j(a,void 0,i)};import{spawn as Qr}from"node:child_process";import Zr from"node:process";var en=[/^error\b/i,/^[✘✖×]/,/^\[vite\][^\n]*\berror\b/i,/^\w*Error: /,/\berror TS\d+\b/,/^Failed to (?:resolve|load url|parse|compile)\b/i,/^(?:ENOENT|EADDRINUSE|ECONNREFUSED)\b/,/pre-transform error/i,/\b(?:build|transform|compilation) failed\b/i],tn=r=>en.some(e=>e.test(r))?"error":"info",rn=/\u001B\][\s\S]*?(?:\u0007|\u001B\\)/g,nn=/\u001B\[[0-9;?]*[\u0020-\u002F]*[\u0040-\u007E]/g,on=/[\u0000-\u0008\u000B-\u001F\u007F]/g,sn=r=>r.replace(rn,"").replace(nn,"").replace(on,""),an=/^([^\s:]+):dev:[ \t]?/,ln=r=>/^cache (?:bypass|hit|miss)/.test(r)||r.startsWith("$ "),un=r=>{let e=sn(r).trimEnd(),t=an.exec(e);if(t==null)return null;let n=e.slice(t[0].length);return n.trim()===""||ln(n.trim())?null:{pkg:t[1],text:n,level:tn(n)}},pn=64*1024,Et=(r,e)=>{if(r==null)return;let t="",n=i=>{let o=un(i);o!=null&&e.onLine?.(o)};r.setEncoding("utf-8"),r.on("data",i=>{e.appendLog?.(i),t+=i;let o=t.split(`
29
- `);t=o.pop()??"";for(let s of o)n(s);t.length>pn&&(n(t),t="")}),r.on("end",()=>{t!==""&&(n(t),t="")}),r.on("error",i=>{e.appendLog?.(`[infra-kit] ui dev stream error: ${i.message}
30
- `)})},Tt=({packageNames:r,cwd:e,concurrency:t,env:n,appendLog:i,onLine:o,onUnexpectedExit:s})=>{let a=r.map(u=>`--filter=${u}`),l=Qr("pnpm",["exec","turbo","run","dev",...a,`--concurrency=${t}`,"--env-mode=loose","--only","--output-logs=new-only","--no-update-notifier","--ui=stream"],{cwd:e,detached:!0,stdio:["ignore","pipe","pipe"],env:{...Zr.env,...n}});return Et(l.stdout,{appendLog:i,onLine:o}),Et(l.stderr,{appendLog:i,onLine:o}),j(l,void 0,s)};var Y="runner",Sn="turbo",Pn="watch";function X(r){let e=wn.homedir();return r===e||r.startsWith(`${e}${w.sep}`)?`~${r.slice(e.length)}`:r}function $t(r){return r.map(e=>e.packageName).join(", ")}var xn=bn.promisify(mn),Dn=async(r,e)=>{try{let{stderr:t}=await xn(r,{maxBuffer:33554432});t&&e&&e(` (build) ${t.trim()}`,"debug"),t&&!e&&console.error("stderr:",t)}catch(t){let n=t;throw e&&(n.stdout||n.stderr)&&(n.stdout&&e(` stdout: ${n.stdout.trim()}`,"error"),n.stderr&&e(` stderr: ${n.stderr.trim()}`,"error")),t}},Nt=null;function It(r){Nt?.write(Y,r)}var An=()=>new Promise((r,e)=>{let t=yn.createServer();t.unref(),t.on("error",e),t.listen(0,"127.0.0.1",()=>{let n=t.address(),i=typeof n=="object"&&n!==null?n.port:0;t.close(()=>r(i))})}),Rn=r=>typeof r=="object",Q=async r=>(await r.body?.cancel(),{kind:"foreign",status:r.status,contentType:r.headers.get("content-type")}),kn=(r,e)=>{let t=e.contentType?.split(";")[0]?.trim(),n=t==null||t===""?`${e.status}`:`${e.status} ${t}`;return`port ${r} answered ${n}, not vite's ping \u2014 liveness cannot be verified`},En=1500,Lt={accept:"text/x-vite-ping"},Tn=r=>r.kind==="api"?`http://127.0.0.1:${r.port}/__health`:`http://127.0.0.1:${r.port}/`,Cn=(r,e)=>{try{return new URL(r,e)}catch{return null}},$n=async(r,e)=>{let t=await fetch(r,{signal:e});return t.ok?(await t.body?.cancel(),"ok"):Q(t)},Ln=async(r,e)=>{let t=await fetch(r,{headers:Lt,redirect:"manual",signal:e});if(t.status===204)return"ok";if(t.status<300||t.status>=400)return Q(t);let n=t.headers.get("location"),i=n==null?null:Cn(n,r);if(i==null||i.origin!==new URL(r).origin)return Q(t);await t.body?.cancel();let o=await fetch(i,{headers:Lt,redirect:"manual",signal:e});return o.status!==204?Q(o):(await o.body?.cancel(),"ok")},Nn=async r=>{let e=Tn(r),t=AbortSignal.timeout(En);try{return r.kind==="api"?await $n(e,t):await Ln(e,t)}catch{return"refused"}},In=[{name:"@slip-stream-kit/vite",floor:"0.1.134"},{name:"@slip-stream-kit/config",floor:"0.1.134"},{name:"infra-kit",floor:"0.1.132"}],On=(r,e)=>{let t=o=>o.split(".").map(s=>Number.parseInt(s,10)||0),n=t(r),i=t(e);for(let o=0;o<Math.max(n.length,i.length);o+=1){let s=n[o]??0,a=i[o]??0;if(s!==a)return s<a}return!1},Un=r=>{let e=[r];try{for(let t of v.readdirSync(w.join(r,"apps"),{withFileTypes:!0}))if(t.isDirectory())for(let n of["api","ui"])e.push(w.join(r,"apps",t.name,n))}catch{}return e},_n=(r,e)=>{try{let t=JSON.parse(v.readFileSync(w.join(r,"package.json"),"utf-8"));return["dependencies","devDependencies"].some(n=>t[n]?.[e]!=null)}catch{return!1}},Fn=(r,e,t)=>{let n=t.split("/"),i=e;for(;;){let o=w.join(i,"node_modules",...n);if(v.existsSync(o))return o;let s=w.dirname(i);if(i===r||s===i)return;i=s}},Mn=(r,e)=>{try{let t=v.realpathSync(e),n=v.realpathSync(r);return t.startsWith(n+w.sep)&&!t.includes(`${w.sep}node_modules${w.sep}`)}catch{return!1}},Hn=r=>{try{return v.realpathSync(r)}catch{return r}},jn=(r,e,t,n)=>{if(Mn(r,n))return;let i;try{let o=JSON.parse(v.readFileSync(w.join(n,"package.json"),"utf-8"));if(typeof o.version!="string")throw new Error("no version field");i=o.version}catch{throw new Error(`infra-kit dev: could not read the version of the pinned \`${e}\` helper (${n}). Refusing to start rather than risk proxying plain HTTP at a TLS listener. Run \`pnpm install\`.`)}if(On(i,t))throw new Error(`infra-kit dev: this repo pins ${e} ${i}, but dev URLs are now HTTPS and the \`infraKitDev\` helper only understands them from ${t}. An older helper would proxy plain HTTP at a TLS listener \u2014 silently. Bump the dependency:
31
- pnpm add -D ${e}@^${t}`)},Bn=r=>{let e=Un(r);for(let{name:t,floor:n}of In){let i=e.filter(s=>_n(s,t)),o=new Map;for(let s of[...i,r]){let a=Fn(r,s,t);a&&o.set(Hn(a),a)}if(o.size===0){if(i.length===0)continue;throw new Error(`infra-kit dev: ${i[0]}/package.json depends on ${t} but it does not resolve from there, so the \`infraKitDev\` helper version cannot be verified. Run \`pnpm install\`.`)}for(let s of o.values())jn(r,t,n,s)}},me=r=>{try{let e=vn("git",["rev-parse","--abbrev-ref","HEAD"],{cwd:r,encoding:"utf-8"}).trim(),t=hn(e);return t===""?Ct:t}catch{return Ct}},Wn=r=>{let t=(r instanceof Error?r.message:String(r)).split(`
32
- `)[0]?.trim()??"";return t===""?"unknown error (see the log)":t},ve=class r{monorepoRoot;devContextDir;appServers=[];reqTimes=new Map;lastSummary=null;readyAt=0;watchDebounceTimers=new Map;watcher=null;static WATCH_DEBOUNCE_MS=400;restartWorkChain=Promise.resolve();static PORT_RELEASE_DELAY_MS=200;livenessTimer=null;health=new Map;firstErrorLogged=new Set;uiTagByPackage=new Map;static LIVENESS_INTERVAL_MS=5e3;static LIVENESS_FAILURE_THRESHOLD=2;static NEVER_UP_DOWN_THRESHOLD=6;options;runBuild;turboWatchFactory;turboWatch=null;uiDevFactory;uiDev=null;sink;intercept;dryRunner;failedApps=[];degradedRoutes=[];launchedUis=[];proxyRoutes=[];renderer;healthProbe;proxy;proxyPort=Le;registeredAliases=new Set;uiPortMap={};shuttingDown=!1;closureMap=null;closureBuild=Promise.resolve();teardown=null;stage="idle";constructor(e={},t=Dn,n=kt,i=Tt,o,s,a=Nn,l=Ne(),u){this.options=e,this.runBuild=t,this.turboWatchFactory=n,this.uiDevFactory=i,this.dryRunner=o,this.proxy=l,this.sink=u??new q,Nt=this.sink,this.intercept=Ot(this.options)?wt({sink:this.sink,fallbackService:Y,currentService:V}):null,this.renderer=s??new He({appendLog:It,verbose:this.options.verbose??!1}),this.healthProbe=a,this.devContextDir=w.join(y.cwd(),".infra-kit","dev-context"),this.monorepoRoot=$(y.cwd()),(y.env.DOPPLER_PROJECT!=null||y.env.DOPPLER_ENVIRONMENT!=null)&&this.renderer.log("\u{1F510} Doppler env detected (DOPPLER_PROJECT / DOPPLER_ENVIRONMENT)","debug")}discoverApiApps(e){return M(this.monorepoRoot).map(t=>({...t,preferredPort:this.resolvePreferredPort(t.name,e),prefixUrl:this.resolvePrefixUrl(t.name,e),watchDeps:!0}))}async loadDevConfig(){try{return(await ee()).dev??{}}catch{return{}}}normalizeAppInclude(){return H(this.options.include)}resolvePreferredPort(e,t){return St(e,y.env,t)}resolvePrefixUrl(e,t){return Pt(e,t)}async loadDevPresets(){try{return(await ee()).devServersPresets??{}}catch{return{}}}resolvePresetDef(e){if(this.options.presetDef!=null)return this.options.presetDef;let t=this.options.preset;if(t==null)return{};let n=e[t];if(!n){let i=Object.keys(e);throw new Error(`Unknown dev preset "${t}". Available: ${i.length>0?i.join(", "):"(none defined in devServersPresets)"}`)}return n}assertPresetKeysValid(e){let t=this.options.preset??"dev",n=ke({[t]:e});if(n.length!==0)throw new Error(`infra-kit dev: cannot run this preset \u2014 ${n.map(i=>i.message).join("; ")}`)}async assertPresetProxyLocalityValid(e,t,n,i){let o={[e]:t},{ctx:s,loadErrors:a}=await $e(this.monorepoRoot,o,n,i);if(a.length>0)return;let l=Ce(o,s);if(l.length!==0)throw new Error(`infra-kit dev: cannot run this preset \u2014 ${l.map(u=>u.message).join("; ")}`)}async start(){let e=Date.now(),t=this.normalizeAppInclude(),n=this.options.watch??!1,i=await this.loadDevConfig();y.env.POWERTOOLS_DEV??="true",y.env.LOG_LEVEL??="DEBUG",this.renderer.narrate("\u{1F680} Starting Development Server Runner"),n&&this.renderer.narrate("\u{1F440} Watch mode: will rebuild and restart on file save");let{apps:o,uiApps:s,apiAppsAll:a,uiAppsAll:l,wantedLocalPkgs:u,presetProxy:c}=await this.resolveRunPlan(i,t);if(o.length===0&&s.length===0){this.renderer.log("\u26A0\uFE0F No API or UI apps to run for this preset","warn");return}this.warnUiMissingVitePlugin(s),await this.bringUpProxy(o),await this.buildAll(o,s,n),o.length>0&&(this.renderer.bootStep("starting servers"),await this.startAllApps(o),this.renderer.narrate(this.failedApps.length===0?"\u{1F389} All servers started!":`\u26A0\uFE0F ${this.appServers.length}/${o.length} servers started \u2014 ${this.failedApps.length} failed`),this.renderer.narrate(`\u{1F4DD} Logs \u2192 ${X(this.sink.dir)} (one file per service)`));let g=Te({preset:this.options.preset,running:[...o.map(m=>`${m.name}/api`),...s.map(m=>`${m.name}/ui`)],discovered:[...a.map(m=>`${m.name}/api`),...l.map(m=>`${m.name}/ui`)]});if(this.degradedRoutes=await this.collectDegradedRoutes(s,u,c),this.degradedRoutes.length>0&&!n)throw new Error(ut(this.degradedRoutes,g));if(await this.printReady(o,s,e,g),this.options.routes&&this.printRouteDump(),this.appServers.length===0&&s.length===0&&this.failedApps.length>0)throw new Error(`infra-kit dev: no app started (${this.failedApps.length} of ${o.length} failed). First failure: ${this.failedApps[0]?.reason??"unknown"}`);this.armWatch(o,s,n),s.length>0&&this.startUiDev(s),this.startLivenessMonitor()}async resolveRunPlan(e,t){let n=this.discoverApiApps(e),i=Pe(this.monorepoRoot),o=await this.loadDevPresets(),s=this.resolvePresetDef(o);this.assertPresetKeysValid(s);let a={api:n.map(d=>d.name),ui:i.map(d=>d.name)};this.options.presetDef==null&&this.options.preset!=null&&await this.assertPresetProxyLocalityValid(this.options.preset,s,a,n);let l=Ee(s,a);l.unmatched.length>0&&this.renderer.log(`\u26A0\uFE0F Preset targets not found (skipped): ${l.unmatched.join(", ")}`,"warn");let u=new Set(l.targets.filter(d=>d.part==="api").map(d=>d.app)),c=new Set(l.targets.filter(d=>d.part==="ui").map(d=>d.app)),g=d=>!t||t.includes(d),m=new Map(l.targets.filter(d=>d.part==="api").map(d=>[d.app,d.watchDeps])),h=n.filter(d=>u.has(d.name)&&g(d.name)).map(d=>({...d,watchDeps:m.get(d.name)??d.watchDeps})),p=i.filter(d=>c.has(d.name)&&g(d.name)),f=new Set(n.filter(d=>u.has(d.name)).map(d=>d.packageName));return{apps:h,uiApps:p,apiAppsAll:n,uiAppsAll:i,wantedLocalPkgs:f,presetProxy:l.proxy}}async collectDegradedRoutes(e,t,n){if(e.length===0)return[];let i=[];for(let o of e){let s=await dn(o.path).catch(()=>{});if(!s?.proxy)continue;let a=n[o.name]??{},l=Object.fromEntries(Object.entries(s.proxy.routes).map(([u,c])=>[u,{...c,pinnedLocal:a[u]==="local"}]));i.push({app:o.name,routes:l,cloudTemplate:s.proxy.templates.cloud})}return this.launchedUis=i,st({uis:i,wanted:t,running:new Set(this.appServers.map(({app:o})=>o.packageName)),reasons:new Map(this.failedApps.map(({app:o,reason:s})=>[o.packageName,{app:o.name,reason:s}])),env:y.env[re]})}warnUiMissingVitePlugin(e){for(let t of e)!t.managedPort||Se(t.path)||this.renderer.log(`\u26A0\uFE0F ${t.name}/ui is wired with the infra-kit vite helper directly, not the infraKit() plugin \u2014 its proxy is baked at config load and won't react to backend routing changes. Wire the infraKit() vite plugin (from @slip-stream-kit/vite) instead.`,"warn")}proxiesFor(e){let t=this.proxyRoutes.filter(n=>n.uiApp===e).map(n=>({route:n.route,source:n.source,target:n.target}));return t.length>0?t:void 0}async bringUpProxy(e){Bn($(y.cwd())),await this.ensureProxy(),e.length>0&&this.assertNoPortConflicts(e)}async buildAll(e,t,n){let i=[e.length>0?`building ${$t(e)}`:"",t.length>0?`warming ${$t(t)}`:""].filter(Boolean).join(" \xB7 ");this.renderer.bootStep(i),e.length>0&&await this.buildApps(e,n),t.length>0&&await this.buildUiApps(t)}armWatch(e,t,n){n&&(this.appServers.length>0||t.length>0)&&(this.setupWatch(e,t),this.closureBuild=this.buildClosureMapSafe(e).then(i=>{this.closureMap=i}))}async buildUiApps(e){let t=e.map(n=>`--filter=${n.packageName}^...`).join(" ");try{await this.runBuild(`pnpm exec turbo run build ${t} --env-mode=loose --output-logs=errors-only --no-update-notifier`,this.renderer.logFn),this.renderer.narrate("\u2705 UI deps built")}catch(n){this.renderer.log(`\u26A0\uFE0F UI dep build failed (continuing; vite will report unresolved deps): ${String(n)}`,"warn")}}startUiDev(e){let t=e.map(s=>s.name).join(", ");this.renderer.narrate(`\u{1F3A8} Starting ${e.length} UI dev server(s) via \`turbo run dev\`: ${t}`),this.renderer.narrate(" (framework output is routed into the live tail; full detail in the runner log)");let n=Object.keys(this.uiPortMap).length>0?{INFRA_KIT_UI_PORTS:JSON.stringify(this.uiPortMap)}:void 0,i=y.env.NODE_EXTRA_CA_CERTS==null&&v.existsSync(te())?{NODE_EXTRA_CA_CERTS:te()}:void 0,o=new Map(e.map(s=>[s.packageName,`${s.name}/ui`]));this.uiDev=this.uiDevFactory({packageNames:e.map(s=>s.packageName),cwd:y.cwd(),concurrency:Math.max(e.length+4,12),env:n||i?{...n,...i}:void 0,appendLog:s=>{this.sink.write(Sn,s)},onLine:({pkg:s,text:a,level:l})=>{let u=o.get(s)??`${s}/ui`;this.sink.write(u,a,{level:l})},onUnexpectedExit:s=>{this.markUiEngineDead(),this.reportEngineDeath("UI dev engine (`turbo run dev`)","frontends stopped reloading",s)}})}formatAppList(e){return e.map(t=>`${t.name}:${t.port}`).join(", ")}assertNoPortConflicts(e){let t=e.filter(o=>o.preferredPort!=null).map(o=>({name:o.name,port:o.preferredPort})),{duplicatePorts:n,conflictingApps:i}=xt(t);if(n.length!==0)throw this.renderer.log(`\u26A0\uFE0F Port conflict detected! ${n.join(", ")}`,"error"),this.renderer.log(`Conflicting apps: ${this.formatAppList(i)}`,"error"),this.renderer.log("\n\u{1F4A1} Tip: give each app a distinct port via `{APP}_PORT` env (e.g. `CLIENT_PORT=`,","error"),this.renderer.log(" `SEARCH_ENGINE_PORT=`) or `dev.<app>.port` in infra-kit.json; or run a subset with","error"),this.renderer.log(" `--app=<name>,<name>`.\n","error"),new Error(`Port conflict detected: ${n.join(", ")}`)}async buildApps(e,t){let i=`pnpm exec turbo run build ${e.map(o=>`--filter=${o.packageName}`).join(" ")} --env-mode=loose --output-logs=errors-only --no-update-notifier${t?" --force":""}`;try{await this.runBuild(i,this.renderer.logFn),this.renderer.narrate("\u2705 Build complete")}catch(o){this.renderer.log(`\u274C Build failed: ${String(o)}`,"error"),o instanceof Error&&o.message&&this.renderer.log(` ${o.message}`,"error");let s=o;throw s.stdout&&this.renderer.log(` stdout: ${s.stdout.trim()}`,"error"),s.stderr&&this.renderer.log(` stderr: ${s.stderr.trim()}`,"error"),o}}async startAllApps(e){await Promise.all(e.map(async t=>{try{let n=await this.startOneApp(t);n&&this.appServers.push({app:t,...n,startedAt:Date.now(),restarts:0})}catch(n){this.renderer.log(`\u274C Failed to start ${t.name}: ${String(n)}`,"error"),this.failedApps.push({app:t,reason:Wn(n)})}}))}async ensureProxy(){let e=this.proxy.binPath();if(e==null||!await this.proxy.isAvailable())throw new Error("infra-kit dev: portless is not installed, so no dev URL can resolve. It ships as a dependency of infra-kit \u2014 reinstall with `pnpm install`.");let t=await this.proxy.probeProxy(this.proxyPort,!0);if(t!=="serving")throw t==="not-portless"?new Error(`infra-kit dev: something else is already listening on :${this.proxyPort}, and it is not portless (no \`X-Portless\` header on the wire). Find and stop it, e.g. \`sudo lsof -iTCP:${this.proxyPort} -sTCP:LISTEN\`. Installing or trusting portless will not help while another process holds the port.`):this.proxy.isServiceInstalled()==="no"?new Error(`infra-kit dev: no portless daemon is serving HTTPS on :${this.proxyPort}, and its OS service is not installed yet, so no dev URL can resolve. Install it once (this is the only step that needs root):
33
- ${N(["service","install"],{sudo:!0,bin:e})}
25
+ `,a=Dt.byteLength(s);if((this.bytes.get(e)??0)+a>this.maxBytes){this.capped.add(e),this.writeRaw(i,e,`[capped] ${At(e)} hit ${this.maxBytes} bytes; further lines dropped (likely a logging loop)
26
+ `);return}this.writeRaw(i,e,s)}writeRaw(e,t,n){try{x.writeSync(e,n),this.bytes.set(t,(this.bytes.get(t)??0)+Dt.byteLength(n))}catch{}}statsFor(e){return this.counters.get(e)??Rt()}close(){if(!this.closed){this.closed=!0;for(let e of this.fds.values())try{x.closeSync(e)}catch{}this.fds.clear()}}};import*as Nt from"node:fs";import ln from"node:module";import*as $ from"node:path";import un from"node:process";import{fileURLToPath as Lt}from"node:url";var dn="ikgen",ye=2e9,Tt=null,Ct=!1,$t=new Map,be=r=>{let e=$t.get(r);if(e!==void 0)return e;try{let t=Nt.realpathSync(r);return $t.set(r,t),t}catch{return null}},we=(r,e)=>r===e||r.startsWith(e+$.sep),pn=(r,e)=>{if(!r.startsWith("file:"))return null;let t;try{t=Lt(r)}catch{return null}let n=be(t);if(n===null||!we(n,e.root)||n.includes(`${$.sep}node_modules${$.sep}`)||we(n,e.selfDist))return null;e.busted.add(n);let o=new URL(r);return o.searchParams.set(dn,String(e.generation)),o.href},It=()=>ln.registerHooks,Ot=()=>typeof It()=="function",Se=r=>{if(r==="0"||r?.toLowerCase()==="off")return{stopEnabled:!1,stopBytes:ye};let e=Number(r);return Number.isInteger(e)&&e>0?{stopEnabled:!0,stopBytes:e}:{stopEnabled:!0,stopBytes:ye}},_t=()=>{let r=$.dirname(Lt(import.meta.url));return be(r)??r},Ut=r=>{let e=It();if(typeof e!="function")return null;let t={busted:new Set,generation:0,root:r.root,selfDist:r.selfDist},n=r.stopBytes??ye,o=r.stopEnabled??!0,i=n/2,s=r.warnStrideBytes??n/8,a=r.sampleRss??(()=>un.memoryUsage.rss()),l=0,u=0;return Tt=t,Ct||(Ct=!0,e({resolve:(c,f,h)=>{let p=h(c,f),d=Tt;if(d===null)return p;let m=pn(p.url,d);return m===null?p:{...p,url:m}}})),{bump:()=>(t.generation+=1,t.busted=new Set,t.generation),budgetState:()=>{let c=a();if(o&&c>n){if(l+=1,l>=2)return"stop"}else l=0;return c>=i&&c>=u+s?(u=c,"warn"):"ok"},bustedUnder:c=>{let f=be(c)??c;for(let h of t.busted)if(we(h,f))return!0;return!1},generation:()=>t.generation}};import Pe from"node:process";import cn from"node:util";var xe={log:"info",info:"info",debug:"debug",trace:"debug",warn:"warn",error:"error"},Ft=({sink:r,fallbackService:e,currentService:t})=>{let n=!0,o=()=>t()??e,i=(c,f)=>{r.write(o(),c,{level:f})},s={};for(let c of Object.keys(xe))s[c]=console[c],console[c]=(...f)=>{if(!n){s[c](...f);return}i(cn.format(...f),xe[c])};let a=(c,f)=>{let h=c.write.bind(c),p="",d=()=>{p!==""&&(r.write(o(),p,{level:f}),p="")};return c.write=((m,...b)=>{if(!n||typeof m!="string")return h(m,...b);p+=m;let g=p.split(`
27
+ `);p=g.pop()??"";for(let P of g)P!==""&&r.write(o(),P,{level:f});p.length>8192&&d();let S=b.find(P=>typeof P=="function");return typeof S=="function"&&Pe.nextTick(S),!0}),()=>{d(),Reflect.deleteProperty(c,"write")}},l=a(Pe.stdout,"info"),u=a(Pe.stderr,"warn");return{uninstall:()=>{if(n){n=!1,l(),u();for(let c of Object.keys(xe))console[c]=s[c]}}}};var gn="/api/v1";function Mt(r){if(r==null||r==="")return;let e=parseInt(r.trim().replace(/^["']|["']$/g,""),10);return Number.isNaN(e)?void 0:e}function Ht(r,e,t,n=!0){let i=`${r.replace(/-/g,"_").toUpperCase()}_PORT`,s=Mt(e[i]);if(s!=null)return s;if(n){let a=Mt(e.PORT);if(a!=null)return a}return t[r]?.port??void 0}function Bt(r,e){return e[r]?.prefixUrl??gn}function jt(r){let e=r.map(o=>o.port),t=e.filter((o,i)=>e.indexOf(o)!==i),n=r.filter(o=>t.includes(o.port));return{duplicatePorts:t,conflictingApps:n}}import*as Y from"node:fs";import*as R from"node:path";import{parse as hn}from"yaml";var Gt=new Map;var fn=(r,e)=>{let t=new Set,n;try{n=hn(Y.readFileSync(r,"utf8"))}catch{return t}for(let o of Object.values(n?.functions??{})){let i=o?.handler;if(typeof i!="string")continue;let s=i.split(".")[0]??"";s!==""&&t.add(R.normalize(R.join(e,`${s}.js`)))}return t},mn=r=>{let e=R.join(r,"serverless.yml"),t;try{t=Y.statSync(e).mtimeMs}catch{return new Set}let n=Gt.get(r);if(n&&n.mtimeMs===t)return n.entries;let o=fn(e,r);return Gt.set(r,{entries:o,mtimeMs:t}),o},Wt=(r,e)=>mn(e).has(R.normalize(r)),vn=2,Vt=r=>{let e=r.slice(0,vn).map(n=>R.basename(n)),t=r.length-e.length;return t>0?`${e.join(", ")} (+${t} more)`:e.join(", ")};import{Logger as yn}from"@aws-lambda-powertools/logger";import wn from"fastify";import*as Kt from"node:fs";import*as M from"node:path";import De from"node:process";import{pathToFileURL as bn}from"node:url";import{parse as Sn}from"yaml";var Pn=r=>r?.code==="EADDRINUSE",xn=3e4,Dn=()=>{let r=Number.parseInt(De.env.DEV_SERVER_TIMEOUT_MS??"",10);return Number.isNaN(r)?xn:r},Jt=()=>De.env.DEV_SERVER_REQUEST_LOG==="1",Q=class{constructor(e){this.serverConfig=e;this.importCacheBust=`${Date.now()}`,this.logger=new yn({serviceName:"LocalServer",logLevel:"DEBUG"}),this.serverConfig.prefixUrl=this.serverConfig.prefixUrl??"",this.server=wn({logger:!1}),this.server.addHook("onRequest",async(n,o)=>{let i=this.serverConfig.serviceTag;i!=null&&St(i),o.header("Access-Control-Allow-Origin","*"),o.header("Access-Control-Allow-Methods","GET, POST, PUT, DELETE, PATCH, OPTIONS"),o.header("Access-Control-Allow-Headers","Content-Type, Authorization, X-Requested-With"),n.method==="OPTIONS"&&o.status(204).send()});let t=this.serverConfig.onRequestLog;(Jt()||t)&&this.server.addHook("onResponse",async(n,o)=>{let i=Math.round(o.elapsedTime),s=n.url.split("?")[0]??n.url;t?.({method:n.method,path:s,status:o.statusCode,ms:i}),Jt()&&De.stdout.write(`${n.method} ${n.url} \u2192 ${o.statusCode} ${i}ms
28
+ `)})}serverConfig;importCacheBust;logger;server;controllers={};registeredRouteKeys=new Set;getRegisteredRoutes(){return[...this.registeredRouteKeys].sort()}async start(){this.registerHealthRoute(),await Promise.all(this.loadRoutes());let e=await this.listenWithFallback();return this.serverConfig.port=e,this.logger.info(`Server listening on http://127.0.0.1:${e}`,{address:`http://127.0.0.1:${e}`}),e}async listenWithFallback(){let e=this.serverConfig.port;if(e!=null)try{return await this.server.listen({port:e,host:"127.0.0.1"}),this.readBoundPort()}catch(t){if(!Pn(t))throw t}return await this.server.listen({port:0,host:"127.0.0.1"}),this.readBoundPort()}readBoundPort(){let e=this.server.server.address();if(e==null||typeof e=="string")throw new Error("Server address unavailable after listen()");return e.port}async close(){let e=this.server.server;typeof e.closeAllConnections=="function"&&e.closeAllConnections(),await this.server.close()}registerHealthRoute(){this.server.route({method:"GET",url:"/__health",handler:(e,t)=>t.code(200).send({status:"ok",app:this.serverConfig.appName??null,port:this.serverConfig.port})})}loadRoutes(){let e=M.join(this.serverConfig.controllersPath,"serverless.yml"),t=Kt.readFileSync(e,"utf8"),n=Sn(t),o=[];if(!n?.functions)return o;for(let i of Object.values(n.functions))if(i?.events?.length)for(let s of i.events){let a=s?.http;a&&o.push(this.defineRoute(a,i))}return o}async defineRoute(e,t){let n=e.path.toString();n=n.replaceAll("{",":").replaceAll("}","");let o=M.posix.join(this.serverConfig.prefixUrl??"",n);o=o[0]==="/"?o:`/${o}`;let i=["GET","POST","PUT","DELETE","PATCH","HEAD","OPTIONS"],s=String(e.method).toUpperCase();if(!i.includes(s))throw new Error(`Invalid HTTP method: "${e.method}" for URL: ${o}`);let a=`${s} ${o}`;if(this.registeredRouteKeys.has(a))throw new Error(`Duplicate route: ${a}`);this.registeredRouteKeys.add(a);let u=(t.handler??"").split("."),c=u[0]??"",f=u[1]??"",h=M.join(this.serverConfig.controllersPath,`${c}.js`),p=bn(h);p.searchParams.set("v",this.importCacheBust);let d=this.serverConfig.serviceTag,m=async()=>await import(p.href),b=d==null?await m():await bt(d,m);this.controllers[a]={action:b,handler:f};let g=this.logger.createChild({serviceName:"RequestLogger"});this.server.route({method:s,url:o,handler:async(S,P)=>{let H=this.controllers[a];if(!H)throw new Error(`No controller for ${a}`);let Ce=H.action[H.handler];if(!Ce)throw new Error(`No handler ${H.handler} for ${o}`);let oe=await Ce(this.getEventObj(S.body,S.query,S.params,S.headers,s,o),this.getContext(),g),ar=JSON.parse(oe.body);return P.headers(oe.headers??{}),P.code(oe?.statusCode??500).send(ar)}})}getEventObj(e,t,n,o,i="",s=""){let a={body:e?JSON.stringify(e):null,headers:o??{},multiValueHeaders:{},httpMethod:i,isBase64Encoded:!1,path:s,pathParameters:n??null,queryStringParameters:t??null,multiValueQueryStringParameters:null,stageVariables:null,requestContext:{accountId:"",apiId:"",authorizer:void 0,protocol:"",httpMethod:i,identity:{accessKey:null,accountId:null,apiKey:null,apiKeyId:null,caller:null,clientCert:null,cognitoAuthenticationProvider:null,cognitoAuthenticationType:null,cognitoIdentityId:null,cognitoIdentityPoolId:null,principalOrgId:null,sourceIp:"devIp",user:null,userAgent:null,userArn:null},path:s,stage:"",requestId:"",requestTimeEpoch:0,resourceId:"",resourcePath:s},resource:s};return a.source="aws.events",a}getContext(){let e=Date.now(),t=Dn(),n=new Date().toISOString().split("T")[0]??"";return{callbackWaitsForEmptyEventLoop:!1,functionName:"local-dev",functionVersion:"1.0.0",invokedFunctionArn:"arn:aws:lambda:local:000000000000:function:local-dev",memoryLimitInMB:"1024",awsRequestId:`local-${Date.now()}`,logGroupName:"/aws/lambda/local-dev",logStreamName:`${n}/local`,getRemainingTimeInMillis:()=>Math.max(0,t-(Date.now()-e)),done:(o,i)=>{},fail:o=>{},succeed:o=>{}}}};import{spawn as Rn}from"node:child_process";import*as Z from"node:fs";var An=(r,e)=>[...r.map(t=>`--filter=...${t}`),...e.map(t=>`--filter=${t}^...`)],qt=({depInclusive:r,depClosure:e,cwd:t,logFile:n,onUnexpectedExit:o,openLog:i})=>{let s=An(r,e),a=i?i(n):Z.openSync(n,"a"),l=Rn("pnpm",["exec","turbo","watch","build",...s,"--continue=dependencies-successful","--env-mode=loose"],{cwd:t,detached:!0,stdio:["ignore",a,a]});return Z.closeSync(a),G(l,void 0,o)};import{spawn as kn}from"node:child_process";import En from"node:process";var Tn=[/^error\b/i,/^[✘✖×]/,/^\[vite\][^\n]*\berror\b/i,/^\w*Error: /,/\berror TS\d+\b/,/^Failed to (?:resolve|load url|parse|compile)\b/i,/^(?:ENOENT|EADDRINUSE|ECONNREFUSED)\b/,/pre-transform error/i,/\b(?:build|transform|compilation) failed\b/i],Cn=r=>Tn.some(e=>e.test(r))?"error":"info",$n=/\u001B\][\s\S]*?(?:\u0007|\u001B\\)/g,Nn=/\u001B\[[0-9;?]*[\u0020-\u002F]*[\u0040-\u007E]/g,Ln=/[\u0000-\u0008\u000B-\u001F\u007F]/g,In=r=>r.replace($n,"").replace(Nn,"").replace(Ln,""),On=/^([^\s:]+):dev:[ \t]?/,_n=r=>/^cache (?:bypass|hit|miss)/.test(r)||r.startsWith("$ "),Un=r=>{let e=In(r).trimEnd(),t=On.exec(e);if(t==null)return null;let n=e.slice(t[0].length);return n.trim()===""||_n(n.trim())?null:{pkg:t[1],text:n,level:Cn(n)}},Fn=64*1024,zt=(r,e)=>{if(r==null)return;let t="",n=o=>{let i=Un(o);i!=null&&e.onLine?.(i)};r.setEncoding("utf-8"),r.on("data",o=>{e.appendLog?.(o),t+=o;let i=t.split(`
29
+ `);t=i.pop()??"";for(let s of i)n(s);t.length>Fn&&(n(t),t="")}),r.on("end",()=>{t!==""&&(n(t),t="")}),r.on("error",o=>{e.appendLog?.(`[infra-kit] ui dev stream error: ${o.message}
30
+ `)})},Xt=({packageNames:r,cwd:e,concurrency:t,env:n,appendLog:o,onLine:i,onUnexpectedExit:s})=>{let a=r.map(u=>`--filter=${u}`),l=kn("pnpm",["exec","turbo","run","dev",...a,`--concurrency=${t}`,"--env-mode=loose","--only","--output-logs=new-only","--no-update-notifier","--ui=stream"],{cwd:e,detached:!0,stdio:["ignore","pipe","pipe"],env:{...En.env,...n}});return zt(l.stdout,{appendLog:o,onLine:i}),zt(l.stderr,{appendLog:o,onLine:i}),G(l,void 0,s)};var te="runner",zn="turbo",Xn="watch",Re=r=>`${Math.round(r/1e6)} MB`;function ee(r){let e=Kn.homedir();return r===e||r.startsWith(`${e}${w.sep}`)?`~${r.slice(e.length)}`:r}function Qt(r){return r.map(e=>e.packageName).join(", ")}var Yn=qn.promisify(Wn),Qn=async(r,e)=>{try{let{stderr:t}=await Yn(r,{maxBuffer:33554432});t&&e&&e(` (build) ${t.trim()}`,"debug"),t&&!e&&console.error("stderr:",t)}catch(t){let n=t;throw e&&(n.stdout||n.stderr)&&(n.stdout&&e(` stdout: ${n.stdout.trim()}`,"error"),n.stderr&&e(` stderr: ${n.stderr.trim()}`,"error")),t}},re=null;function er(r){re?.write(te,r)}var Zn=()=>new Promise((r,e)=>{let t=Jn.createServer();t.unref(),t.on("error",e),t.listen(0,"127.0.0.1",()=>{let n=t.address(),o=typeof n=="object"&&n!==null?n.port:0;t.close(()=>r(o))})}),eo=r=>typeof r=="object",ne=async r=>(await r.body?.cancel(),{kind:"foreign",status:r.status,contentType:r.headers.get("content-type")}),to=(r,e)=>{let t=e.contentType?.split(";")[0]?.trim(),n=t==null||t===""?`${e.status}`:`${e.status} ${t}`;return`port ${r} answered ${n}, not vite's ping \u2014 liveness cannot be verified`},ro=1500,Zt={accept:"text/x-vite-ping"},no=r=>r.kind==="api"?`http://127.0.0.1:${r.port}/__health`:`http://127.0.0.1:${r.port}/`,oo=(r,e)=>{try{return new URL(r,e)}catch{return null}},io=async(r,e)=>{let t=await fetch(r,{signal:e});return t.ok?(await t.body?.cancel(),"ok"):ne(t)},so=async(r,e)=>{let t=await fetch(r,{headers:Zt,redirect:"manual",signal:e});if(t.status===204)return"ok";if(t.status<300||t.status>=400)return ne(t);let n=t.headers.get("location"),o=n==null?null:oo(n,r);if(o==null||o.origin!==new URL(r).origin)return ne(t);await t.body?.cancel();let i=await fetch(o,{headers:Zt,redirect:"manual",signal:e});return i.status!==204?ne(i):(await i.body?.cancel(),"ok")},ao=async r=>{let e=no(r),t=AbortSignal.timeout(ro);try{return r.kind==="api"?await io(e,t):await so(e,t)}catch{return"refused"}},lo=[{name:"@slip-stream-kit/vite",floor:"0.1.134"},{name:"@slip-stream-kit/config",floor:"0.1.134"},{name:"infra-kit",floor:"0.1.132"}],uo=(r,e)=>{let t=i=>i.split(".").map(s=>Number.parseInt(s,10)||0),n=t(r),o=t(e);for(let i=0;i<Math.max(n.length,o.length);i+=1){let s=n[i]??0,a=o[i]??0;if(s!==a)return s<a}return!1},po=r=>{let e=[r];try{for(let t of y.readdirSync(w.join(r,"apps"),{withFileTypes:!0}))if(t.isDirectory())for(let n of["api","ui"])e.push(w.join(r,"apps",t.name,n))}catch{}return e},co=(r,e)=>{try{let t=JSON.parse(y.readFileSync(w.join(r,"package.json"),"utf-8"));return["dependencies","devDependencies"].some(n=>t[n]?.[e]!=null)}catch{return!1}},go=(r,e,t)=>{let n=t.split("/"),o=e;for(;;){let i=w.join(o,"node_modules",...n);if(y.existsSync(i))return i;let s=w.dirname(o);if(o===r||s===o)return;o=s}},ho=(r,e)=>{try{let t=y.realpathSync(e),n=y.realpathSync(r);return t.startsWith(n+w.sep)&&!t.includes(`${w.sep}node_modules${w.sep}`)}catch{return!1}},fo=r=>{try{return y.realpathSync(r)}catch{return r}},mo=(r,e,t,n)=>{if(ho(r,n))return;let o;try{let i=JSON.parse(y.readFileSync(w.join(n,"package.json"),"utf-8"));if(typeof i.version!="string")throw new Error("no version field");o=i.version}catch{throw new Error(`infra-kit dev: could not read the version of the pinned \`${e}\` helper (${n}). Refusing to start rather than risk proxying plain HTTP at a TLS listener. Run \`pnpm install\`.`)}if(uo(o,t))throw new Error(`infra-kit dev: this repo pins ${e} ${o}, but dev URLs are now HTTPS and the \`infraKitDev\` helper only understands them from ${t}. An older helper would proxy plain HTTP at a TLS listener \u2014 silently. Bump the dependency:
31
+ pnpm add -D ${e}@^${t}`)},vo=r=>{let e=po(r);for(let{name:t,floor:n}of lo){let o=e.filter(s=>co(s,t)),i=new Map;for(let s of[...o,r]){let a=go(r,s,t);a&&i.set(fo(a),a)}if(i.size===0){if(o.length===0)continue;throw new Error(`infra-kit dev: ${o[0]}/package.json depends on ${t} but it does not resolve from there, so the \`infraKitDev\` helper version cannot be verified. Run \`pnpm install\`.`)}for(let s of i.values())mo(r,t,n,s)}},Ae=r=>{try{let e=Vn("git",["rev-parse","--abbrev-ref","HEAD"],{cwd:r,encoding:"utf-8"}).trim(),t=jn(e);return t===""?Yt:t}catch{return Yt}},yo=r=>{let t=(r instanceof Error?r.message:String(r)).split(`
32
+ `)[0]?.trim()??"";return t===""?"unknown error (see the log)":t},ke=class r{monorepoRoot;devContextDir;appServers=[];reqTimes=new Map;lastSummary=null;readyAt=0;watchDebounceTimers=new Map;pendingChanges=new Map;moduleGeneration=null;watcher=null;static WATCH_DEBOUNCE_MS=400;restartWorkChain=Promise.resolve();static PORT_RELEASE_DELAY_MS=200;livenessTimer=null;health=new Map;firstErrorLogged=new Set;uiTagByPackage=new Map;static LIVENESS_INTERVAL_MS=5e3;static LIVENESS_FAILURE_THRESHOLD=2;static NEVER_UP_DOWN_THRESHOLD=6;options;runBuild;turboWatchFactory;turboWatch=null;uiDevFactory;uiDev=null;sink;intercept;dryRunner;failedApps=[];degradedRoutes=[];launchedUis=[];proxyRoutes=[];renderer;healthProbe;proxy;proxyPort=je;registeredAliases=new Set;uiPortMap={};shuttingDown=!1;closureMap=null;closureBuild=Promise.resolve();teardown=null;stage="idle";constructor(e={},t=Qn,n=qt,o=Xt,i,s,a=ao,l=Ge(),u){this.options=e,this.runBuild=t,this.turboWatchFactory=n,this.uiDevFactory=o,this.dryRunner=i,this.proxy=l,this.sink=u??new X,re=this.sink,this.intercept=tr(this.options)?Ft({sink:this.sink,fallbackService:te,currentService:K}):null,this.renderer=s??new Xe({appendLog:er,verbose:this.options.verbose??!1}),this.healthProbe=a,this.devContextDir=w.join(v.cwd(),".infra-kit","dev-context"),this.monorepoRoot=L(v.cwd()),(v.env.DOPPLER_PROJECT!=null||v.env.DOPPLER_ENVIRONMENT!=null)&&this.renderer.log("\u{1F510} Doppler env detected (DOPPLER_PROJECT / DOPPLER_ENVIRONMENT)","debug")}discoverApiApps(e){return B(this.monorepoRoot).map(t=>({...t,preferredPort:this.resolvePreferredPort(t.name,e),appScopedPort:this.resolvePreferredPort(t.name,e,!1),prefixUrl:this.resolvePrefixUrl(t.name,e),watchDeps:!0}))}async loadDevConfig(){try{return(await ie()).dev??{}}catch{return{}}}normalizeAppInclude(){return j(this.options.include)}resolvePreferredPort(e,t,n=!0){return Ht(e,v.env,t,n)}resolvePrefixUrl(e,t){return Bt(e,t)}async loadDevPresets(){try{return(await ie()).devServersPresets??{}}catch{return{}}}resolvePresetDef(e){if(this.options.presetDef!=null)return this.options.presetDef;let t=this.options.preset;if(t==null)return{};let n=e[t];if(!n){let o=Object.keys(e);throw new Error(`Unknown dev preset "${t}". Available: ${o.length>0?o.join(", "):"(none defined in devServersPresets)"}`)}return n}assertPresetKeysValid(e){let t=this.options.preset??"dev",n=Ue({[t]:e});if(n.length!==0)throw new Error(`infra-kit dev: cannot run this preset \u2014 ${n.map(o=>o.message).join("; ")}`)}async assertPresetProxyLocalityValid(e,t,n,o){let i={[e]:t},{ctx:s,loadErrors:a}=await Be(this.monorepoRoot,i,n,o);if(a.length>0)return;let l=He(i,s);if(l.length!==0)throw new Error(`infra-kit dev: cannot run this preset \u2014 ${l.map(u=>u.message).join("; ")}`)}async start(){let e=Date.now(),t=this.normalizeAppInclude(),n=this.options.watch??!1,o=await this.loadDevConfig();v.env.POWERTOOLS_DEV??="true",v.env.LOG_LEVEL??="DEBUG",this.renderer.narrate("\u{1F680} Starting Development Server Runner"),n&&this.renderer.narrate("\u{1F440} Watch mode: will rebuild and restart on file save");let{apps:i,uiApps:s,apiAppsAll:a,uiAppsAll:l,wantedLocalPkgs:u,presetProxy:c}=await this.resolveRunPlan(o,t);if(i.length===0&&s.length===0){this.renderer.log("\u26A0\uFE0F No API or UI apps to run for this preset","warn");return}this.warnUiMissingVitePlugin(s),n&&this.installModuleGeneration(),await this.bringUpProxy(i),await this.buildAll(i,s,n),i.length>0&&(this.renderer.bootStep("starting servers"),await this.startAllApps(i),this.renderer.narrate(this.failedApps.length===0?"\u{1F389} All servers started!":`\u26A0\uFE0F ${this.appServers.length}/${i.length} servers started \u2014 ${this.failedApps.length} failed`),this.renderer.narrate(`\u{1F4DD} Logs \u2192 ${ee(this.sink.dir)} (one file per service)`));let f=Me({preset:this.options.preset,running:[...i.map(h=>`${h.name}/api`),...s.map(h=>`${h.name}/ui`)],discovered:[...a.map(h=>`${h.name}/api`),...l.map(h=>`${h.name}/ui`)]});if(this.degradedRoutes=await this.collectDegradedRoutes(s,u,c),this.degradedRoutes.length>0&&!n)throw new Error(wt(this.degradedRoutes,f));if(await this.printReady(i,s,e,f),this.options.routes&&this.printRouteDump(),this.appServers.length===0&&s.length===0&&this.failedApps.length>0)throw new Error(`infra-kit dev: no app started (${this.failedApps.length} of ${i.length} failed). First failure: ${this.failedApps[0]?.reason??"unknown"}`);this.armWatch(i,s,n),s.length>0&&this.startUiDev(s),this.startLivenessMonitor()}async resolveRunPlan(e,t){let n=this.discoverApiApps(e),o=Ne(this.monorepoRoot),i=await this.loadDevPresets(),s=this.resolvePresetDef(i);this.assertPresetKeysValid(s);let a={api:n.map(g=>g.name),ui:o.map(g=>g.name)};this.options.presetDef==null&&this.options.preset!=null&&await this.assertPresetProxyLocalityValid(this.options.preset,s,a,n);let l=Fe(s,a);l.unmatched.length>0&&this.renderer.log(`\u26A0\uFE0F Preset targets not found (skipped): ${l.unmatched.join(", ")}`,"warn");let u=new Set(l.targets.filter(g=>g.part==="api").map(g=>g.app)),c=new Set(l.targets.filter(g=>g.part==="ui").map(g=>g.app)),f=g=>!t||t.includes(g),h=new Map(l.targets.filter(g=>g.part==="api").map(g=>[g.app,g.watchDeps])),p=n.filter(g=>u.has(g.name)&&f(g.name)),d=p.map(g=>({...g,watchDeps:h.get(g.name)??g.watchDeps,preferredPort:p.length===1?g.preferredPort:g.appScopedPort})),m=o.filter(g=>c.has(g.name)&&f(g.name)),b=new Set(n.filter(g=>u.has(g.name)).map(g=>g.packageName));return{apps:d,uiApps:m,apiAppsAll:n,uiAppsAll:o,wantedLocalPkgs:b,presetProxy:l.proxy}}async collectDegradedRoutes(e,t,n){if(e.length===0)return[];let o=[];for(let i of e){let s=await Hn(i.path).catch(()=>{});if(!s?.proxy)continue;let a=n[i.name]??{},l=Object.fromEntries(Object.entries(s.proxy.routes).map(([u,c])=>[u,{...c,pinnedLocal:a[u]==="local"}]));o.push({app:i.name,routes:l,cloudTemplate:s.proxy.templates.cloud})}return this.launchedUis=o,mt({uis:o,wanted:t,running:new Set(this.appServers.map(({app:i})=>i.packageName)),reasons:new Map(this.failedApps.map(({app:i,reason:s})=>[i.packageName,{app:i.name,reason:s}])),env:v.env[ae]})}warnUiMissingVitePlugin(e){for(let t of e)!t.managedPort||$e(t.path)||this.renderer.log(`\u26A0\uFE0F ${t.name}/ui is wired with the infra-kit vite helper directly, not the infraKit() plugin \u2014 its proxy is baked at config load and won't react to backend routing changes. Wire the infraKit() vite plugin (from @slip-stream-kit/vite) instead.`,"warn")}proxiesFor(e){let t=this.proxyRoutes.filter(n=>n.uiApp===e).map(n=>({route:n.route,source:n.source,target:n.target}));return t.length>0?t:void 0}async bringUpProxy(e){vo(L(v.cwd())),await this.ensureProxy(),e.length>0&&this.assertNoPortConflicts(e)}async buildAll(e,t,n){let o=[e.length>0?`building ${Qt(e)}`:"",t.length>0?`warming ${Qt(t)}`:""].filter(Boolean).join(" \xB7 ");this.renderer.bootStep(o),e.length>0&&await this.buildApps(e,n),t.length>0&&await this.buildUiApps(t)}armWatch(e,t,n){n&&(this.appServers.length>0||t.length>0)&&(this.setupWatch(e,t),this.closureBuild=this.buildClosureMapSafe(e).then(o=>{this.closureMap=o}))}async buildUiApps(e){let t=e.map(n=>`--filter=${n.packageName}^...`).join(" ");try{await this.runBuild(`pnpm exec turbo run build ${t} --env-mode=loose --output-logs=errors-only --no-update-notifier`,this.renderer.logFn),this.renderer.narrate("\u2705 UI deps built")}catch(n){this.renderer.log(`\u26A0\uFE0F UI dep build failed (continuing; vite will report unresolved deps): ${String(n)}`,"warn")}}startUiDev(e){let t=e.map(s=>s.name).join(", ");this.renderer.narrate(`\u{1F3A8} Starting ${e.length} UI dev server(s) via \`turbo run dev\`: ${t}`),this.renderer.narrate(" (framework output is routed into the live tail; full detail in the runner log)");let n=Object.keys(this.uiPortMap).length>0?{INFRA_KIT_UI_PORTS:JSON.stringify(this.uiPortMap)}:void 0,o=v.env.NODE_EXTRA_CA_CERTS==null&&y.existsSync(se())?{NODE_EXTRA_CA_CERTS:se()}:void 0,i=new Map(e.map(s=>[s.packageName,`${s.name}/ui`]));this.uiDev=this.uiDevFactory({packageNames:e.map(s=>s.packageName),cwd:v.cwd(),concurrency:Math.max(e.length+4,12),env:n||o?{...n,...o}:void 0,appendLog:s=>{this.sink.write(zn,s)},onLine:({pkg:s,text:a,level:l})=>{let u=i.get(s)??`${s}/ui`;this.sink.write(u,a,{level:l})},onUnexpectedExit:s=>{this.markUiEngineDead(),this.reportEngineDeath("UI dev engine (`turbo run dev`)","frontends stopped reloading",s)}})}formatAppList(e){return e.map(t=>`${t.name}:${t.port}`).join(", ")}assertNoPortConflicts(e){let t=e.filter(i=>i.preferredPort!=null).map(i=>({name:i.name,port:i.preferredPort})),{duplicatePorts:n,conflictingApps:o}=jt(t);if(n.length!==0)throw this.renderer.log(`\u26A0\uFE0F Port conflict detected! ${n.join(", ")}`,"error"),this.renderer.log(`Conflicting apps: ${this.formatAppList(o)}`,"error"),this.renderer.log("\n\u{1F4A1} Tip: give each app a distinct port via `{APP}_PORT` env (e.g. `CLIENT_PORT=`,","error"),this.renderer.log(" `SEARCH_ENGINE_PORT=`) or `dev.<app>.port` in infra-kit.json; or run a subset with","error"),this.renderer.log(" `--app=<name>,<name>`.\n","error"),new Error(`Port conflict detected: ${n.join(", ")}`)}async buildApps(e,t){let o=`pnpm exec turbo run build ${e.map(i=>`--filter=${i.packageName}`).join(" ")} --env-mode=loose --output-logs=errors-only --no-update-notifier${t?" --force":""}`;try{await this.runBuild(o,this.renderer.logFn),this.renderer.narrate("\u2705 Build complete")}catch(i){this.renderer.log(`\u274C Build failed: ${String(i)}`,"error"),i instanceof Error&&i.message&&this.renderer.log(` ${i.message}`,"error");let s=i;throw s.stdout&&this.renderer.log(` stdout: ${s.stdout.trim()}`,"error"),s.stderr&&this.renderer.log(` stderr: ${s.stderr.trim()}`,"error"),i}}async startAllApps(e){await Promise.all(e.map(async t=>{try{let n=await this.startOneApp(t);n&&this.appServers.push({app:t,...n,startedAt:Date.now(),restarts:0})}catch(n){this.renderer.log(`\u274C Failed to start ${t.name}: ${String(n)}`,"error"),this.failedApps.push({app:t,reason:yo(n)})}}))}async ensureProxy(){let e=this.proxy.binPath();if(e==null||!await this.proxy.isAvailable())throw new Error("infra-kit dev: portless is not installed, so no dev URL can resolve. It ships as a dependency of infra-kit \u2014 reinstall with `pnpm install`.");let t=await this.proxy.probeProxy(this.proxyPort,!0);if(t!=="serving")throw t==="not-portless"?new Error(`infra-kit dev: something else is already listening on :${this.proxyPort}, and it is not portless (no \`X-Portless\` header on the wire). Find and stop it, e.g. \`sudo lsof -iTCP:${this.proxyPort} -sTCP:LISTEN\`. Installing or trusting portless will not help while another process holds the port.`):this.proxy.isServiceInstalled()==="no"?new Error(`infra-kit dev: no portless daemon is serving HTTPS on :${this.proxyPort}, and its OS service is not installed yet, so no dev URL can resolve. Install it once (this is the only step that needs root):
33
+ ${O(["service","install"],{sudo:!0,bin:e})}
34
34
  Then trust its local CA (no sudo needed):
35
- ${N(["trust"],{bin:e})}
35
+ ${O(["trust"],{bin:e})}
36
36
  \`infra-kit doctor\` checks both.`):new Error(`infra-kit dev: portless's OS service is installed, but no daemon is currently serving HTTPS on :${this.proxyPort} \u2014 it may have crashed or been stopped, so no dev URL can resolve. Check its state:
37
- ${N(["service","status"],{bin:e})}
37
+ ${O(["service","status"],{bin:e})}
38
38
  Reinstalling restarts it (still the only step that needs root):
39
- ${N(["service","install"],{sudo:!0,bin:e})}
40
- \`infra-kit doctor\` checks the daemon and CA trust state.`)}async registerAppAlias(e,t,n){let i=me(t),o=gn(e);if(o==="")throw new Error(`infra-kit dev: package name "${e}" has no letters or digits to build a hostname from.`);let s=`${i}.${o}`;if(!await this.proxy.registerAlias(s,n))throw new Error(`infra-kit dev: portless refused the alias "${s}" \u2192 127.0.0.1:${n}.`);return this.registeredAliases.add(s),`${s}.localhost`}async startOneApp(e){this.renderer.narrate(`\u{1F504} Starting ${e.name}...`);let t=new z({controllersPath:e.path,prefixUrl:e.prefixUrl,port:e.preferredPort,appName:e.name,serviceTag:`${e.name}/api`,onRequestLog:({method:o,path:s,status:a,ms:l})=>{if(s==="/__health")return;let u=`${e.name}/api`,c=`${o} ${s} ${a} ${l}ms`;this.sink.write(u,c,{level:a>=500?"error":"info"});let g=this.reqTimes.get(u);g?g.push(Date.now()):this.reqTimes.set(u,[Date.now()])}}),n=await t.start(),i;try{i=await this.registerAppAlias(e.packageName,e.path,n)}catch(o){throw await t.close().catch(()=>{}),o}try{this.writeDevContextFragment(e,n,i)}catch(o){this.renderer.log(`\u26A0\uFE0F Failed to write dev-context fragment for ${e.name}: ${String(o)}`,"warn")}return this.renderer.narrate(`\u2705 ${e.name} started on port ${n}`),{server:t,boundPort:n,alias:i}}writeDevContextFragment(e,t,n){let i={v:cn,package:e.packageName,port:t,pid:y.pid,writtenAt:Date.now(),release:me(e.path),alias:n,origin:`https://${n}`},o=w.join(this.devContextDir,`${e.name}.json`),s=w.join(this.devContextDir,`${e.name}.json.${y.pid}.tmp`);v.mkdirSync(this.devContextDir,{recursive:!0}),v.writeFileSync(s,JSON.stringify(i,null,2)),v.renameSync(s,o)}removeDevContextFragment(e){v.rmSync(w.join(this.devContextDir,`${e.name}.json`),{force:!0})}scheduleRestartWork(e){let t=this.restartWorkChain.then(()=>e(),()=>e());return this.restartWorkChain=t.catch(()=>{}),t}async delayPortRelease(){await new Promise(e=>setTimeout(e,r.PORT_RELEASE_DELAY_MS))}restart(e){return this.shuttingDown?Promise.resolve():this.scheduleRestartWork(()=>this.shuttingDown?Promise.resolve():this.runRestart(e))}resolveRestartTargets(e){return e.map(t=>({idx:this.appServers.findIndex(n=>n.app.name===t.name),app:t})).filter(t=>t.idx>=0||this.isFailedApp(t.app.name))}isFailedApp(e){return this.failedApps.some(t=>t.app.name===e)}promoteRecoveredApp(e,t){let n={app:e,...t,startedAt:Date.now(),restarts:0},i=`${e.name}/api`;this.healthEntry(i,"api"),this.appServers.push(n);let o=this.failedApps.findIndex(s=>s.app.name===e.name);return o>=0&&this.failedApps.splice(o,1),this.lastSummary&&(this.lastSummary={...this.lastSummary,endpoints:[...this.lastSummary.endpoints,{tag:i,url:I({prefixUrl:e.prefixUrl,alias:t.alias}),health:this.healthOf(i)}],failed:(this.lastSummary.failed??[]).filter(s=>s.tag!==i)}),n}async runRestart(e){let t=this.resolveRestartTargets(e);if(t.length===0)return;let n=t.length===1?t[0].app.name:`${t.length} apps`;this.renderer.log(`\u{1F504} Restarting ${n}...`),await Promise.all(t.map(async({idx:a})=>{if(!(a<0))try{await this.appServers[a].server.close()}catch(l){this.renderer.log(` Close warning: ${String(l)}`,"debug")}})),await this.delayPortRelease();let i=await Promise.all(t.map(async({idx:a,app:l})=>{try{let u=await this.startOneApp(l);if(u){if(a<0){let m=this.promoteRecoveredApp(l,u);return this.renderer.log(`\u2705 ${l.name} recovered \u2014 its routes are served locally again`,"info"),{app:l,entry:m}}let c=this.appServers[a],g={app:l,...u,startedAt:Date.now(),restarts:(c?.restarts??0)+1};return this.appServers[a]=g,{app:l,entry:g}}return{app:l,entry:null}}catch(u){return this.renderer.log(`\u274C Failed to ${a<0?"start":"restart"} ${l.name}: ${String(u)}`,"error"),{app:l,entry:null}}})),o=await Promise.all(i.map(async({app:a,entry:l})=>{let u=`${a.name}/api`;if(l==null)return this.markDown(u,"api"),this.refreshStatus(),{label:`${a.name} \u25CF down`,healthy:!1};let c={tag:u,port:l.boundPort,kind:"api"},g=await this.healthProbe(c);this.recordProbe(c,g),this.refreshStatus();let m=g==="ok";return{label:`${a.name}:${l.boundPort} ${m?"\u25CF up":"\u25CF down"}`,healthy:m}})),s=o.every(a=>a.healthy);this.renderer.log(`${s?"\u2705":"\u26A0\uFE0F "} Restarted ${o.map(a=>a.label).join(", ")}`)}async buildClosureMapSafe(e){try{return await rt(this.monorepoRoot,e,this.dryRunner)}catch(t){return this.renderer.log(`\u26A0\uFE0F Dependency-closure map unavailable (${String(t)}); package changes restart all apps`,"warn"),null}}reportEngineDeath(e,t,n){this.shuttingDown||this.renderer.log(`\u26A0\uFE0F ${e} ${n} \u2014 ${t}. Restart \`infra-kit dev\`.`,"warn")}markUiEngineDead(){if(!this.shuttingDown){for(let{tag:e,kind:t}of this.uiTargets())this.healthEntry(e,t).dead=!0;this.refreshStatus()}}setupWatch(e,t){this.turboWatch=this.turboWatchFactory({depInclusive:e.map(l=>l.packageName),depClosure:t.map(l=>l.packageName),cwd:y.cwd(),logFile:this.sink.pathFor(Pn),onUnexpectedExit:l=>{this.reportEngineDeath("Watch engine (`turbo watch build`)","file saves no longer rebuild",l)}}),this.renderer.narrate("\u{1F440} Watch mode: started `turbo watch build` engine; watching dist output");let n=De(e),i=L(this.monorepoRoot),o=[...n,...i];if(o.length===0){this.renderer.log("\u26A0\uFE0F No app or package dist directories found to watch (were they built?)","warn");return}let s=y.env.DEV_SERVER_CHOKIDAR_POLL==="1",a=fn.watch(o,{ignoreInitial:!0,awaitWriteFinish:{stabilityThreshold:200,pollInterval:100},ignored:l=>l.endsWith(".tsbuildinfo")||l.endsWith(".map"),...s?{usePolling:!0,interval:400}:{}});this.watcher=a,s&&this.renderer.log("\u{1F440} chokidar: usePolling enabled (DEV_SERVER_CHOKIDAR_POLL=1)","debug"),a.on("change",l=>{this.handleDistChange(l,e,n,i)}),this.renderer.narrate(`\u{1F440} Watching ${n.length} app dist + ${i.length} package dist dir(s) for changes...`)}handleDistChange(e,t,n,i){this.renderer.log(`\u{1F440} dist change detected: ${e}`,"debug");let o=Ae(e,n,i);if(o.kind==="package"){let a=nt(t,this.closureMap,o.packageDir);if(a===null){this.scheduleDebounced("__packages__",()=>this.restart(t));return}for(let l of a)this.scheduleDebounced(l.name,()=>this.restart([l]));return}let s=t.find(a=>w.join(a.path,"dist")===o.app);s&&this.scheduleDebounced(s.name,()=>this.restart([s]))}scheduleDebounced(e,t){if(this.shuttingDown)return;let n=this.watchDebounceTimers.get(e);n&&clearTimeout(n);let i=setTimeout(()=>{this.watchDebounceTimers.delete(e),!this.shuttingDown&&t().catch(o=>{this.renderer.log(`Restart error (${e}): ${String(o)}`,"error")})},r.WATCH_DEBOUNCE_MS);this.watchDebounceTimers.set(e,i)}uiHealthEnabled(){return(this.options.uiHealth??!0)&&y.env.INFRA_KIT_NO_UI_HEALTH!=="1"}apiTargets(){return this.appServers.map(({app:e,boundPort:t})=>({tag:`${e.name}/api`,port:t,kind:"api"}))}uiTargets(){return this.uiHealthEnabled()?Object.entries(this.uiPortMap).map(([e,{port:t}])=>({tag:this.uiTagByPackage.get(e)??`${e}/ui`,port:t,kind:"ui"})):[]}healthEntry(e,t){let n=this.health.get(e);if(n)return n;let i={kind:t,failures:0,foreignStreak:0,everUp:!1,dead:!1,unverified:!1};return this.health.set(e,i),i}recordProbe(e,t){let n=this.healthEntry(e.tag,e.kind),i=r.LIVENESS_FAILURE_THRESHOLD;if(t==="ok"){let o=n.failures>=i;n.everUp=!0,n.failures=0,n.foreignStreak=0,n.unverified=!1,o&&this.renderer.log(`\u2705 ${e.tag} recovered`);return}if(Rn(t)&&e.kind==="ui"){n.foreignStreak+=1,n.unverified=n.foreignStreak>=i,n.foreignStreak===i&&this.renderer.log(`\u26A0\uFE0F ${e.tag}: ${kn(e.port,t)}`,"warn");return}if(n.foreignStreak=0,n.failures+=1,e.kind==="ui"&&n.failures>=i&&(n.unverified=!1),n.failures===i){let o=e.kind==="api"?"/__health not responding":"not answering vite's ping";this.renderer.log(`\u26A0\uFE0F ${e.tag} unhealthy (${o})`,"warn")}}markDown(e,t){let n=this.healthEntry(e,t);n.dead=!0,n.failures=r.LIVENESS_FAILURE_THRESHOLD,n.foreignStreak=0,n.unverified=!1}healthOf(e){let t=this.health.get(e);return t==null?"unknown":t.unverified?"unverified":t.everUp?t.failures>=r.LIVENESS_FAILURE_THRESHOLD?"down":"ok":this.neverUpState(t)}neverUpState(e){return e.kind==="api"||e.dead||e.failures>=r.NEVER_UP_DOWN_THRESHOLD?"down":"starting"}startLivenessMonitor(){this.scheduleLivenessTick()}scheduleLivenessTick(){let e=this.options.livenessIntervalMs??r.LIVENESS_INTERVAL_MS;this.livenessTimer=setTimeout(()=>{this.livenessTick().finally(()=>{this.shuttingDown||this.scheduleLivenessTick()}).catch(()=>{})},e),this.livenessTimer.unref()}refreshStatus(){let e=this.lastSummary;if(e==null)return;let t=Date.now(),n=new Map(this.appServers.map(i=>[`${i.app.name}/api`,i]));this.pruneRequestWindow(t),this.renderer.refresh?.({...e,sessionUptimeMs:t-this.readyAt,degraded:this.degradedRows(),uiRefs:e.uiRefs.map(i=>({...i,errors:this.announceFirstError(i.tag)})),endpoints:e.endpoints.map(i=>{let o=n.get(i.tag);return{...i,health:this.healthOf(i.tag),uptimeMs:o?t-o.startedAt:void 0,restarts:o?.restarts,rpm:(this.reqTimes.get(i.tag)??[]).length,errors:this.announceFirstError(i.tag)}})})}announceFirstError(e){let{errors:t}=this.sink.statsFor(e);return t>0&&!this.firstErrorLogged.has(e)&&(this.firstErrorLogged.add(e),this.renderer.log(`\u26A0\uFE0F ${e} reported its first error \u2192 ${X(this.sink.pathFor(e))}`,"warn")),t}degradedRows(){if(this.degradedRoutes.length===0)return[];let e=new Set(this.appServers.map(({app:t})=>t.packageName));return this.degradedRoutes.filter(t=>!e.has(t.packageName)).map(t=>({route:t.route,tag:`${t.uiApp}/ui`,fallback:t.fallback,target:t.cloudTarget}))}pruneRequestWindow(e){let t=e-6e4;for(let[n,i]of this.reqTimes)this.reqTimes.set(n,i.filter(o=>o>t))}async livenessTick(){this.shuttingDown||(await Promise.all([...this.apiTargets(),...this.uiTargets()].map(e=>this.probeOne(e))),this.refreshStatus())}async probeOne(e){let t=await this.healthProbe(e);this.shuttingDown||this.recordProbe(e,t)}async printReady(e,t,n,i){let o=Date.now()-n;await Promise.all(this.apiTargets().map(h=>this.probeOne(h)));let s=this.appServers.map(({app:h,alias:p})=>({tag:`${h.name}/api`,url:I({prefixUrl:h.prefixUrl,alias:p}),health:this.healthOf(`${h.name}/api`)})),a=new Map(this.appServers.map(({app:h,alias:p})=>[h.packageName,I({prefixUrl:h.prefixUrl,alias:p})]));this.proxyRoutes=at({uis:this.launchedUis,running:new Set(this.appServers.map(({app:h})=>h.packageName)),localOrigin:h=>a.get(h),env:y.env[re]}),this.uiPortMap={};let l=[],u=[];for(let h of t){let p=await this.assignUiPort(h),f=`${h.name}/ui`;p!=null?l.push({tag:f,url:I({prefixUrl:"",alias:p.alias}),health:this.seedUiHealth(f),proxies:this.proxiesFor(h.name)}):u.push({tag:f,proxies:this.proxiesFor(h.name)})}let c=this.options.watch??!1,g=e.length+t.length,m=L(this.monorepoRoot).length;this.lastSummary={target:i,watch:c,release:me(y.cwd()),elapsedMs:o,endpoints:[...s,...l],uiRefs:u,failed:this.failedApps.map(({app:h,reason:p})=>({tag:`${h.name}/api`,reason:p})),degraded:this.degradedRows(),watchSummary:`${g} app${g===1?"":"s"} \xB7 ${m} package${m===1?"":"s"}`,logPath:X(this.sink.dir),logHref:this.sink.dir},this.readyAt=Date.now(),this.renderer.ready(this.lastSummary),this.refreshStatus()}async assignUiPort(e){if(!e.managedPort)return null;let t;try{t=await An()}catch{return null}let n=await this.registerAppAlias(e.packageName,e.path,t);return this.uiPortMap[e.packageName]={port:t,alias:n},this.uiTagByPackage.set(e.packageName,`${e.name}/ui`),{port:t,alias:n}}seedUiHealth(e){return this.uiHealthEnabled()?(this.healthEntry(e,"ui"),this.healthOf(e)):"unknown"}printRouteDump(){if(this.appServers.length!==0){this.renderer.log("\u{1F5FA}\uFE0F Registered routes:");for(let{app:e,server:t}of this.appServers){let n=t.getRegisteredRoutes();this.renderer.log(` ${e.name} (${n.length}): ${n.length>0?n.join(", "):"(none)"}`)}}}reportFault(e){this.sink.write(V()??Y,e,{level:"error"}),!this.shuttingDown&&this.renderer.log(e,"error",{tee:!1})}fileFault(e){this.sink.write(V()??Y,e,{level:"error"})}get shutdownStage(){return this.stage}shutdown(){return this.teardown!=null?this.teardown:(this.teardown=this.doShutdown(),this.teardown.catch(()=>{}),this.teardown)}async doShutdown(){this.shuttingDown=!0,this.stage="starting",this.renderer.dispose(),this.intercept?.uninstall(),this.renderer.log("\u{1F6D1} Shutting down all servers...");for(let e of this.watchDebounceTimers.values())clearTimeout(e);this.watchDebounceTimers.clear(),this.livenessTimer&&(clearTimeout(this.livenessTimer),this.livenessTimer=null),this.watcher&&(this.stage="watcher.close",await this.watcher.close(),this.watcher=null),this.stage="restartWorkChain",await this.restartWorkChain,this.stage="closureBuild",await this.closureBuild,this.stage="removeAlias",await Promise.all([...this.registeredAliases].map(e=>this.proxy.removeAlias(e))),this.registeredAliases.clear(),this.turboWatch&&(this.stage="turboWatch.kill",await this.turboWatch.kill(),this.turboWatch=null),this.uiDev&&(this.stage="uiDev.kill",await this.uiDev.kill(),this.uiDev=null);for(let{app:e,server:t}of this.appServers){this.stage=`server.close(${e.name})`;try{await t.close()}catch{}this.removeDevContextFragment(e)}this.intercept?.uninstall(),this.renderer.log(`\u2713 dev stopped \xB7 logs \u2192 ${X(this.sink.dir)}`),this.sink.close(),this.stage="done"}},Ot=r=>(r.tty??!!y.stdout.isTTY)&&!r.json,Gn=async r=>{if(!Ot(r))return;let{PersistentInkDevUi:e}=await import("./persistent-ink-dev-ui-PLLSRSGL.js"),{createSafeStream:t}=await import("./safe-stderr-HXDR2DNJ.js");return new e({appendLog:It,verbose:r.verbose??!1,stdout:t(vt())})};async function Ut(r={}){let e=await Gn(r),t=new ve(r,void 0,void 0,void 0,void 0,e);try{await t.start()}catch(n){throw await t.shutdown().catch(()=>{}),n}return t}var ye=1,Kn=2e4,qn=r=>{if(r!=null){for(let e of r)if(Re(e)!==null)throw new Error(`infra-kit dev: invalid --target "${e}" (expected "<app>/api" or "<app>/ui").`);return{apps:Object.fromEntries(r.map(e=>[e,{}]))}}},_t=r=>{if(r==null)return null;let e=r.split(",").map(t=>t.trim()).filter(Boolean);return e.length>0?e:null},Ft=r=>({watch:r.watch??!1,include:_t(r.app),preset:r.preset,presetDef:qn(_t(r.target)),cmux:r.cmux??!1,self:r.self??!1,verbose:r.verbose??!1,routes:r.routes??!1,uiHealth:r.uiHealth??!0}),zn=r=>!r.self||r.include?r:{...r,include:[xe(D.cwd())]},Mt=(r,e)=>{let t=setTimeout(r,e);return t.unref(),()=>{clearTimeout(t)}},Xn=(r=Mt)=>{let e=!1;return(t,n)=>{if(e)return()=>{};e=!0;let i=r(t,n);return()=>{e=!1,i()}}},Ht=(r,e,t)=>{r(),e(t)},Yn=({getRunner:r,forceReap:e=R,exit:t=o=>{D.exit(o)},setTimer:n=Mt,deadlineMs:i=Kn})=>{let o=!1;return s=>{if(o)return;o=!0;let a=r();if(a==null){Ht(e,t,ye);return}a.fileFault(`
39
+ ${O(["service","install"],{sudo:!0,bin:e})}
40
+ \`infra-kit doctor\` checks the daemon and CA trust state.`)}async registerAppAlias(e,t,n){let o=Ae(t),i=Bn(e);if(i==="")throw new Error(`infra-kit dev: package name "${e}" has no letters or digits to build a hostname from.`);let s=`${o}.${i}`;if(!await this.proxy.registerAlias(s,n))throw new Error(`infra-kit dev: portless refused the alias "${s}" \u2192 127.0.0.1:${n}.`);return this.registeredAliases.add(s),`${s}.localhost`}async startOneApp(e){this.renderer.narrate(`\u{1F504} Starting ${e.name}...`);let t=new Q({controllersPath:e.path,prefixUrl:e.prefixUrl,port:e.preferredPort,appName:e.name,serviceTag:`${e.name}/api`,onRequestLog:({method:i,path:s,status:a,ms:l})=>{if(s==="/__health")return;let u=`${e.name}/api`,c=`${i} ${s} ${a} ${l}ms`;this.sink.write(u,c,{level:a>=500?"error":"info"});let f=this.reqTimes.get(u);f?f.push(Date.now()):this.reqTimes.set(u,[Date.now()])}}),n=await t.start(),o;try{o=await this.registerAppAlias(e.packageName,e.path,n)}catch(i){throw await t.close().catch(()=>{}),i}try{this.writeDevContextFragment(e,n,o)}catch(i){this.renderer.log(`\u26A0\uFE0F Failed to write dev-context fragment for ${e.name}: ${String(i)}`,"warn")}return this.renderer.narrate(`\u2705 ${e.name} started on port ${n}`),{server:t,boundPort:n,alias:o}}writeDevContextFragment(e,t,n){let o={v:Mn,package:e.packageName,port:t,pid:v.pid,writtenAt:Date.now(),release:Ae(e.path),alias:n,origin:`https://${n}`},i=w.join(this.devContextDir,`${e.name}.json`),s=w.join(this.devContextDir,`${e.name}.json.${v.pid}.tmp`);y.mkdirSync(this.devContextDir,{recursive:!0}),y.writeFileSync(s,JSON.stringify(o,null,2)),y.renameSync(s,i)}removeDevContextFragment(e){y.rmSync(w.join(this.devContextDir,`${e.name}.json`),{force:!0})}scheduleRestartWork(e){let t=this.restartWorkChain.then(()=>e(),()=>e());return this.restartWorkChain=t.catch(()=>{}),t}async delayPortRelease(){await new Promise(e=>setTimeout(e,r.PORT_RELEASE_DELAY_MS))}restart(e,t=[]){return this.shuttingDown?Promise.resolve():this.scheduleRestartWork(()=>this.shuttingDown?Promise.resolve():this.runRestart(e,t))}resolveRestartTargets(e){return e.map(t=>({idx:this.appServers.findIndex(n=>n.app.name===t.name),app:t})).filter(t=>t.idx>=0||this.isFailedApp(t.app.name))}isFailedApp(e){return this.failedApps.some(t=>t.app.name===e)}promoteRecoveredApp(e,t){let n={app:e,...t,startedAt:Date.now(),restarts:0},o=`${e.name}/api`;this.healthEntry(o,"api"),this.appServers.push(n);let i=this.failedApps.findIndex(s=>s.app.name===e.name);return i>=0&&this.failedApps.splice(i,1),this.lastSummary&&(this.lastSummary={...this.lastSummary,endpoints:[...this.lastSummary.endpoints,{tag:o,url:_({prefixUrl:e.prefixUrl,alias:t.alias}),health:this.healthOf(o)}],failed:(this.lastSummary.failed??[]).filter(s=>s.tag!==o)}),n}async runRestart(e,t=[]){let n=this.resolveRestartTargets(e);if(n.length===0)return;let o=n.length===1?n[0].app.name:`${n.length} apps`,i=this.moduleGeneration?.budgetState()??"ok";if(i==="stop"){this.reportGenerationBudgetStop(Se(v.env.INFRA_KIT_DEV_STOP_BYTES).stopBytes),this.shutdown().catch(()=>{}).finally(()=>{this.options.onExitRequest?.(1)}).catch(()=>{});return}i==="warn"&&this.reportGenerationBudgetWarn(),this.moduleGeneration?.bump(),this.renderer.log(`\u{1F504} Restarting ${o}...`),await Promise.all(n.map(async({idx:h})=>{if(!(h<0))try{await this.appServers[h].server.close()}catch(p){this.renderer.log(` Close warning: ${String(p)}`,"debug")}})),await this.delayPortRelease();let s=await Promise.all(n.map(async({idx:h,app:p})=>{try{let d=await this.startOneApp(p);if(d){if(h<0){let g=this.promoteRecoveredApp(p,d);return this.renderer.log(`\u2705 ${p.name} recovered \u2014 its routes are served locally again`,"info"),{app:p,entry:g}}let m=this.appServers[h],b={app:p,...d,startedAt:Date.now(),restarts:(m?.restarts??0)+1};return this.appServers[h]=b,{app:p,entry:b}}return{app:p,entry:null}}catch(d){return this.renderer.log(`\u274C Failed to ${h<0?"start":"restart"} ${p.name}: ${String(d)}`,"error"),{app:p,entry:null}}})),a=await Promise.all(s.map(async({app:h,entry:p})=>{let d=`${h.name}/api`;if(p==null)return this.markDown(d,"api"),this.refreshStatus(),{label:`${h.name} \u25CF down`,healthy:!1};let m={tag:d,port:p.boundPort,kind:"api"},b=await this.healthProbe(m);this.recordProbe(m,b),this.refreshStatus();let g=b==="ok";return{label:`${h.name}:${p.boundPort} ${g?"\u25CF up":"\u25CF down"}`,healthy:g}})),l=a.every(h=>h.healthy),u=a.map(h=>h.label).join(", "),f=s.some(h=>h.entry!==null)?this.resolveStaleFiles(t,n):[];if(f.length>0){this.renderer.log(`\u26A0\uFE0F Restarted ${u} \u2014 still serving the OLD ${Vt(f)}. Re-run \`infra-kit dev\` to pick this up.`,"warn");return}this.renderer.log(`${l?"\u2705":"\u26A0\uFE0F "} Restarted ${u}`)}resolveStaleFiles(e,t){let n=this.moduleGeneration;return n?e.filter(o=>!n.bustedUnder(w.dirname(o))):e.filter(o=>!t.some(i=>Wt(o,i.app.path)))}async buildClosureMapSafe(e){try{return await ct(this.monorepoRoot,e,this.dryRunner)}catch(t){return this.renderer.log(`\u26A0\uFE0F Dependency-closure map unavailable (${String(t)}); package changes restart all apps`,"warn"),null}}reportEngineDeath(e,t,n){this.shuttingDown||this.renderer.log(`\u26A0\uFE0F ${e} ${n} \u2014 ${t}. Restart \`infra-kit dev\`.`,"warn")}markUiEngineDead(){if(!this.shuttingDown){for(let{tag:e,kind:t}of this.uiTargets())this.healthEntry(e,t).dead=!0;this.refreshStatus()}}setupWatch(e,t){this.turboWatch=this.turboWatchFactory({depInclusive:e.map(l=>l.packageName),depClosure:t.map(l=>l.packageName),cwd:v.cwd(),logFile:this.sink.pathFor(Xn),onUnexpectedExit:l=>{this.reportEngineDeath("Watch engine (`turbo watch build`)","file saves no longer rebuild",l)}}),this.renderer.narrate("\u{1F440} Watch mode: started `turbo watch build` engine; watching dist output");let n=Ie(e),o=I(this.monorepoRoot),i=[...n,...o];if(i.length===0){this.renderer.log("\u26A0\uFE0F No app or package dist directories found to watch (were they built?)","warn");return}let s=v.env.DEV_SERVER_CHOKIDAR_POLL==="1",a=Gn.watch(i,{ignoreInitial:!0,awaitWriteFinish:{stabilityThreshold:200,pollInterval:100},ignored:l=>l.endsWith(".tsbuildinfo")||l.endsWith(".map"),...s?{usePolling:!0,interval:400}:{}});this.watcher=a,s&&this.renderer.log("\u{1F440} chokidar: usePolling enabled (DEV_SERVER_CHOKIDAR_POLL=1)","debug");for(let l of["add","change","unlink"])a.on(l,u=>{this.handleDistChange(u,e,n,o)});this.renderer.narrate(`\u{1F440} Watching ${n.length} app dist + ${o.length} package dist dir(s) for changes...`),this.renderer.narrate(this.moduleGeneration?"\u{1F440} Watch reloads the whole local graph in place \u2014 shared packages and services included.":"\u{1F440} Watch reloads serverless handler entry files only; other modules need a re-run of `infra-kit dev`.")}handleDistChange(e,t,n,o){this.renderer.log(`\u{1F440} dist change detected: ${e}`,"debug");let i=Oe(e,n,o);if(i.kind==="package"){this.handlePackageDistChange(e,t,i.packageDir);return}let s=t.find(a=>w.join(a.path,"dist")===i.app);s&&(this.markChanged(s.name,e),this.scheduleDebounced(s.name,()=>this.restart([s],this.takeChanged(s.name))))}handlePackageDistChange(e,t,n){let o=gt(t,this.closureMap,n);if(o===null){this.markChanged("__packages__",e),this.scheduleDebounced("__packages__",()=>this.restart(t,this.takeChanged("__packages__")));return}for(let i of o)this.markChanged(i.name,e),this.scheduleDebounced(i.name,()=>this.restart([i],this.takeChanged(i.name)))}markChanged(e,t){let n=this.pendingChanges.get(e);n?n.add(t):this.pendingChanges.set(e,new Set([t]))}installModuleGeneration(){if(v.env.INFRA_KIT_DEV_NO_GENERATION==="1"){this.renderer.log("\u{1F440} Module generation disabled (INFRA_KIT_DEV_NO_GENERATION=1)","debug");return}if(!Ot()){this.renderer.log(`\u26A0\uFE0F This Node (${v.version}) has no \`module.registerHooks\`, so only handler entry files reload in place.`,"warn");return}let e=Se(v.env.INFRA_KIT_DEV_STOP_BYTES);this.moduleGeneration=Ut({root:y.realpathSync(this.monorepoRoot),selfDist:_t(),stopBytes:e.stopBytes,stopEnabled:e.stopEnabled})}reportGenerationBudgetWarn(){let e=this.moduleGeneration?.generation()??0;this.renderer.log(`\u26A0\uFE0F Reload memory ${Re(v.memoryUsage.rss())} after ${e} reload(s). Module records cannot be freed in-process, so this only grows \u2014 re-run \`infra-kit dev\` when convenient.`,"warn")}reportGenerationBudgetStop(e){let t=this.moduleGeneration?.generation()??0;this.renderer.log(`\u26D4 Reload memory ${Re(v.memoryUsage.rss())} exceeds the ${Re(e)} budget after ${t} reload(s) \u2014 stopping. Module records cannot be freed in-process. Re-run \`infra-kit dev\` to continue, or set INFRA_KIT_DEV_STOP_BYTES to raise the budget (or \`off\` to disable the stop).`,"error")}takeChanged(e){let t=this.pendingChanges.get(e);return this.pendingChanges.delete(e),t?[...t]:[]}scheduleDebounced(e,t){if(this.shuttingDown)return;let n=this.watchDebounceTimers.get(e);n&&clearTimeout(n);let o=setTimeout(()=>{this.watchDebounceTimers.delete(e),!this.shuttingDown&&t().catch(i=>{this.renderer.log(`Restart error (${e}): ${String(i)}`,"error")})},r.WATCH_DEBOUNCE_MS);this.watchDebounceTimers.set(e,o)}uiHealthEnabled(){return(this.options.uiHealth??!0)&&v.env.INFRA_KIT_NO_UI_HEALTH!=="1"}apiTargets(){return this.appServers.map(({app:e,boundPort:t})=>({tag:`${e.name}/api`,port:t,kind:"api"}))}uiTargets(){return this.uiHealthEnabled()?Object.entries(this.uiPortMap).map(([e,{port:t}])=>({tag:this.uiTagByPackage.get(e)??`${e}/ui`,port:t,kind:"ui"})):[]}healthEntry(e,t){let n=this.health.get(e);if(n)return n;let o={kind:t,failures:0,foreignStreak:0,everUp:!1,dead:!1,unverified:!1};return this.health.set(e,o),o}recordProbe(e,t){let n=this.healthEntry(e.tag,e.kind),o=r.LIVENESS_FAILURE_THRESHOLD;if(t==="ok"){let i=n.failures>=o;n.everUp=!0,n.failures=0,n.foreignStreak=0,n.unverified=!1,i&&this.renderer.log(`\u2705 ${e.tag} recovered`);return}if(eo(t)&&e.kind==="ui"){n.foreignStreak+=1,n.unverified=n.foreignStreak>=o,n.foreignStreak===o&&this.renderer.log(`\u26A0\uFE0F ${e.tag}: ${to(e.port,t)}`,"warn");return}if(n.foreignStreak=0,n.failures+=1,e.kind==="ui"&&n.failures>=o&&(n.unverified=!1),n.failures===o){let i=e.kind==="api"?"/__health not responding":"not answering vite's ping";this.renderer.log(`\u26A0\uFE0F ${e.tag} unhealthy (${i})`,"warn")}}markDown(e,t){let n=this.healthEntry(e,t);n.dead=!0,n.failures=r.LIVENESS_FAILURE_THRESHOLD,n.foreignStreak=0,n.unverified=!1}healthOf(e){let t=this.health.get(e);return t==null?"unknown":t.unverified?"unverified":t.everUp?t.failures>=r.LIVENESS_FAILURE_THRESHOLD?"down":"ok":this.neverUpState(t)}neverUpState(e){return e.kind==="api"||e.dead||e.failures>=r.NEVER_UP_DOWN_THRESHOLD?"down":"starting"}startLivenessMonitor(){this.scheduleLivenessTick()}scheduleLivenessTick(){let e=this.options.livenessIntervalMs??r.LIVENESS_INTERVAL_MS;this.livenessTimer=setTimeout(()=>{this.livenessTick().finally(()=>{this.shuttingDown||this.scheduleLivenessTick()}).catch(()=>{})},e),this.livenessTimer.unref()}refreshStatus(){let e=this.lastSummary;if(e==null)return;let t=Date.now(),n=new Map(this.appServers.map(o=>[`${o.app.name}/api`,o]));this.pruneRequestWindow(t),this.renderer.refresh?.({...e,sessionUptimeMs:t-this.readyAt,degraded:this.degradedRows(),uiRefs:e.uiRefs.map(o=>({...o,errors:this.announceFirstError(o.tag)})),endpoints:e.endpoints.map(o=>{let i=n.get(o.tag);return{...o,health:this.healthOf(o.tag),uptimeMs:i?t-i.startedAt:void 0,restarts:i?.restarts,rpm:(this.reqTimes.get(o.tag)??[]).length,errors:this.announceFirstError(o.tag)}})})}announceFirstError(e){let{errors:t}=this.sink.statsFor(e);return t>0&&!this.firstErrorLogged.has(e)&&(this.firstErrorLogged.add(e),this.renderer.log(`\u26A0\uFE0F ${e} reported its first error \u2192 ${ee(this.sink.pathFor(e))}`,"warn")),t}degradedRows(){if(this.degradedRoutes.length===0)return[];let e=new Set(this.appServers.map(({app:t})=>t.packageName));return this.degradedRoutes.filter(t=>!e.has(t.packageName)).map(t=>({route:t.route,tag:`${t.uiApp}/ui`,fallback:t.fallback,target:t.cloudTarget}))}pruneRequestWindow(e){let t=e-6e4;for(let[n,o]of this.reqTimes)this.reqTimes.set(n,o.filter(i=>i>t))}async livenessTick(){this.shuttingDown||(await Promise.all([...this.apiTargets(),...this.uiTargets()].map(e=>this.probeOne(e))),this.refreshStatus())}async probeOne(e){let t=await this.healthProbe(e);this.shuttingDown||this.recordProbe(e,t)}async printReady(e,t,n,o){let i=Date.now()-n;await Promise.all(this.apiTargets().map(p=>this.probeOne(p)));let s=this.appServers.map(({app:p,alias:d})=>({tag:`${p.name}/api`,url:_({prefixUrl:p.prefixUrl,alias:d}),health:this.healthOf(`${p.name}/api`)})),a=new Map(this.appServers.map(({app:p,alias:d})=>[p.packageName,_({prefixUrl:p.prefixUrl,alias:d})]));this.proxyRoutes=vt({uis:this.launchedUis,running:new Set(this.appServers.map(({app:p})=>p.packageName)),localOrigin:p=>a.get(p),env:v.env[ae]}),this.uiPortMap={};let l=[],u=[];for(let p of t){let d=await this.assignUiPort(p),m=`${p.name}/ui`;d!=null?l.push({tag:m,url:_({prefixUrl:"",alias:d.alias}),health:this.seedUiHealth(m),proxies:this.proxiesFor(p.name)}):u.push({tag:m,proxies:this.proxiesFor(p.name)})}let c=this.options.watch??!1,f=e.length+t.length,h=I(this.monorepoRoot).length;this.lastSummary={target:o,watch:c,release:Ae(v.cwd()),elapsedMs:i,endpoints:[...s,...l],uiRefs:u,failed:this.failedApps.map(({app:p,reason:d})=>({tag:`${p.name}/api`,reason:d})),degraded:this.degradedRows(),watchSummary:`${f} app${f===1?"":"s"} \xB7 ${h} package${h===1?"":"s"}`,logPath:ee(this.sink.dir),logHref:this.sink.dir},this.readyAt=Date.now(),this.renderer.ready(this.lastSummary),this.refreshStatus()}async assignUiPort(e){if(!e.managedPort)return null;let t;try{t=await Zn()}catch{return null}let n=await this.registerAppAlias(e.packageName,e.path,t);return this.uiPortMap[e.packageName]={port:t,alias:n},this.uiTagByPackage.set(e.packageName,`${e.name}/ui`),{port:t,alias:n}}seedUiHealth(e){return this.uiHealthEnabled()?(this.healthEntry(e,"ui"),this.healthOf(e)):"unknown"}printRouteDump(){if(this.appServers.length!==0){this.renderer.log("\u{1F5FA}\uFE0F Registered routes:");for(let{app:e,server:t}of this.appServers){let n=t.getRegisteredRoutes();this.renderer.log(` ${e.name} (${n.length}): ${n.length>0?n.join(", "):"(none)"}`)}}}reportFault(e){this.sink.write(K()??te,e,{level:"error"}),!this.shuttingDown&&this.renderer.log(e,"error",{tee:!1})}fileFault(e){this.sink.write(K()??te,e,{level:"error"})}get shutdownStage(){return this.stage}shutdown(){return this.teardown!=null?this.teardown:(this.teardown=this.doShutdown(),this.teardown.catch(()=>{}),this.teardown)}async doShutdown(){this.shuttingDown=!0,this.stage="starting",this.renderer.dispose(),this.intercept?.uninstall(),this.renderer.log("\u{1F6D1} Shutting down all servers...");for(let e of this.watchDebounceTimers.values())clearTimeout(e);this.watchDebounceTimers.clear(),this.livenessTimer&&(clearTimeout(this.livenessTimer),this.livenessTimer=null),this.watcher&&(this.stage="watcher.close",await this.watcher.close(),this.watcher=null),this.stage="restartWorkChain",await this.restartWorkChain,this.stage="closureBuild",await this.closureBuild,this.stage="removeAlias",await Promise.all([...this.registeredAliases].map(e=>this.proxy.removeAlias(e))),this.registeredAliases.clear(),this.turboWatch&&(this.stage="turboWatch.kill",await this.turboWatch.kill(),this.turboWatch=null),this.uiDev&&(this.stage="uiDev.kill",await this.uiDev.kill(),this.uiDev=null);for(let{app:e,server:t}of this.appServers){this.stage=`server.close(${e.name})`;try{await t.close()}catch{}this.removeDevContextFragment(e)}this.intercept?.uninstall(),this.renderer.log(`\u2713 dev stopped \xB7 logs \u2192 ${ee(this.sink.dir)}`),this.sink.close(),re===this.sink&&(re=null),this.stage="done"}},tr=r=>(r.tty??!!v.stdout.isTTY)&&!r.json,wo=async r=>{if(!tr(r))return;let{PersistentInkDevUi:e}=await import("./persistent-ink-dev-ui-PLLSRSGL.js"),{createSafeStream:t}=await import("./safe-stderr-HXDR2DNJ.js");return new e({appendLog:er,verbose:r.verbose??!1,stdout:t(kt())})};async function rr(r={}){let e=await wo(r),t=new ke(r,void 0,void 0,void 0,void 0,e);try{await t.start()}catch(n){throw await t.shutdown().catch(()=>{}),n}return t}var Ee=1,Po=2e4,xo=r=>{if(r!=null){for(let e of r)if(_e(e)!==null)throw new Error(`infra-kit dev: invalid --target "${e}" (expected "<app>/api" or "<app>/ui").`);return{apps:Object.fromEntries(r.map(e=>[e,{}]))}}},nr=r=>{if(r==null)return null;let e=r.split(",").map(t=>t.trim()).filter(Boolean);return e.length>0?e:null},or=r=>({watch:r.watch??!1,include:nr(r.app),preset:r.preset,presetDef:xo(nr(r.target)),cmux:r.cmux??!1,self:r.self??!1,verbose:r.verbose??!1,routes:r.routes??!1,uiHealth:r.uiHealth??!0}),Do=r=>!r.self||r.include?r:{...r,include:[Le(D.cwd())]},ir=(r,e)=>{let t=setTimeout(r,e);return t.unref(),()=>{clearTimeout(t)}},Ro=(r=ir)=>{let e=!1;return(t,n)=>{if(e)return()=>{};e=!0;let o=r(t,n);return()=>{e=!1,o()}}},sr=(r,e,t)=>{r(),e(t)},Ao=({getRunner:r,forceReap:e=k,exit:t=i=>{D.exit(i)},setTimer:n=ir,deadlineMs:o=Po})=>{let i=!1;return s=>{if(i)return;i=!0;let a=r();if(a==null){sr(e,t,Ee);return}a.fileFault(`
41
41
  \u2717 dev-server exiting: ${s}
42
- `);let l=n(()=>{e(),t(ye)},i);a.shutdown().finally(()=>{l(),t(ye)}).catch(()=>{})}},Qn=["SIGINT","SIGTERM"],Zn=({forceReap:r=R,exit:e=i=>{D.exit(i)},register:t=(i,o)=>{D.on(i,o)},unregister:n=(i,o)=>{D.off(i,o)}}={})=>{let i=new Map;for(let o of Qn){let s=()=>{Ht(r,e,O(o))};i.set(o,s),t(o,s)}return{remove:()=>{for(let[o,s]of i)n(o,s)}}},we=async r=>{let e=zn(r);if(e.cmux){if(await Ue()){await Ze(e);return}D.stdout.write(`cmux not available; falling back to single-terminal dev
43
- `)}let t=null,n=Xn(),i=Yn({getRunner:()=>t,setTimer:n}),o=gt({onDeath:(l,u)=>{i(`stdio unwritable: ${l} ${u.code}`)}}),s=Zn();try{t=await Ut(e)}finally{s.remove()}let a=t;et({onFault:(l,u)=>{a.reportFault(U(l,u))},isTerminalDead:o.isDead,fileFault:(l,u)=>{a.fileFault(U(l,u,!1))},onFatal:i}),W({onSignal:async l=>{de(`
42
+ `);let l=n(()=>{e(),t(Ee)},o);a.shutdown().finally(()=>{l(),t(Ee)}).catch(()=>{})}},ko=["SIGINT","SIGTERM"],Eo=({forceReap:r=k,exit:e=o=>{D.exit(o)},register:t=(o,i)=>{D.on(o,i)},unregister:n=(o,i)=>{D.off(o,i)}}={})=>{let o=new Map;for(let i of ko){let s=()=>{sr(r,e,U(i))};o.set(i,s),t(i,s)}return{remove:()=>{for(let[i,s]of o)n(i,s)}}},Te=async r=>{let e=Do(r);if(e.cmux){if(await Je()){await ut(e);return}D.stdout.write(`cmux not available; falling back to single-terminal dev
43
+ `)}let t=null,n=Ro(),o=Ao({getRunner:()=>t,setTimer:n}),i=xt({onDeath:(l,u)=>{o(`stdio unwritable: ${l} ${u.code}`)}}),s=Eo();try{t=await rr({...e,onExitRequest:l=>{D.exit(l)}})}finally{s.remove()}let a=t;dt({onFault:(l,u)=>{a.reportFault(F(l,u))},isTerminalDead:i.isDead,fileFault:(l,u)=>{a.fileFault(F(l,u,!1))},onFatal:o}),V({onSignal:async l=>{ve(`
44
44
  Received ${l}, shutting down dev-server...
45
- `),await a.shutdown()},describeStall:()=>a.shutdownStage,fileReport:l=>{a.fileFault(l)},setTimer:n})},ei=(r,e,t)=>!r.preset&&!r.app&&!r.self&&!r.cmux&&!r.watch&&!r.verbose&&!r.routes&&e&&!t,ti=(r,e)=>({watch:r.watch,cmux:r.cmux,include:r.include??null,preset:r.preset,presetDef:r.presetDef,self:!1,verbose:!1,routes:!1,uiHealth:e.uiHealth??!0}),Ho=async(r,e,t)=>{if(ei(r,e,t)){let{runDevWizard:n}=await import("./dev-wizard-run-4SVW4W3I.js"),i=Promise.all([import("./persistent-ink-dev-ui-PLLSRSGL.js"),import("./safe-stderr-HXDR2DNJ.js")]).catch(()=>{}),o;try{o=await n()}catch(s){if(Me(s))return;throw s}if(o==null)return;await i,await we({...ti(o,r),tty:e,json:t});return}await we({...Ft(r),tty:e,json:t})},ri=async r=>{let e=new Vn;e.name("infra-kit-dev-server").description("Run local dev servers for the apps in a named devServersPresets preset (or all apps)").argument("[preset]","Named preset from devServersPresets (omit to run every app)").option("-w, --watch","Rebuild and restart on file save").option("--app <names>","Further narrow to these app folder names (comma-separated)").option("--cmux","Run each app in its own cmux pane (one workspace, N panes; falls back to single terminal if cmux is unavailable)").option("--self","Run only the app of the current directory (infer from cwd; use inside apps/<app>/\u2026)").option("-V, --verbose","Print full boot narration (default: quiet; full detail always in the session log)").option("--routes","Print each app\u2019s registered METHOD /path routes at startup (default: off)"),e.parse(r),await we(Ft({...e.opts(),preset:e.args[0]}))};import.meta.url===Jn(D.argv[1]??"").href&&ri(D.argv).catch(r=>{console.error(r instanceof Error?r.message:String(r)),D.exit(1)});export{Yn as createFatalHandler,Xn as createSharedDeadlineTimer,Zn as installBootSignalGuard,we as runDevServer,Ho as runDevServerCli,ei as shouldRunWizard,Ft as toDevServerOptions};
45
+ `),await a.shutdown()},describeStall:()=>a.shutdownStage,fileReport:l=>{a.fileFault(l)},setTimer:n})},To=(r,e,t)=>!r.preset&&!r.app&&!r.self&&!r.cmux&&!r.watch&&!r.verbose&&!r.routes&&e&&!t,Co=(r,e)=>({watch:r.watch,cmux:r.cmux,include:r.include??null,preset:r.preset,presetDef:r.presetDef,self:!1,verbose:!1,routes:!1,uiHealth:e.uiHealth??!0}),Ps=async(r,e,t)=>{if(To(r,e,t)){let{runDevWizard:n}=await import("./dev-wizard-run-XM5L23UP.js"),o=Promise.all([import("./persistent-ink-dev-ui-PLLSRSGL.js"),import("./safe-stderr-HXDR2DNJ.js")]).catch(()=>{}),i;try{i=await n()}catch(s){if(ze(s))return;throw s}if(i==null)return;await o,await Te({...Co(i,r),tty:e,json:t});return}await Te({...or(r),tty:e,json:t})},$o=async r=>{let e=new bo;e.name("infra-kit-dev-server").description("Run local dev servers for the apps in a named devServersPresets preset (or all apps)").argument("[preset]","Named preset from devServersPresets (omit to run every app)").option("-w, --watch","Rebuild and restart on file save").option("--app <names>","Further narrow to these app folder names (comma-separated)").option("--cmux","Run each app in its own cmux pane (one workspace, N panes; falls back to single terminal if cmux is unavailable)").option("--self","Run only the app of the current directory (infer from cwd; use inside apps/<app>/\u2026)").option("-V, --verbose","Print full boot narration (default: quiet; full detail always in the session log)").option("--routes","Print each app\u2019s registered METHOD /path routes at startup (default: off)"),e.parse(r),await Te(or({...e.opts(),preset:e.args[0]}))};import.meta.url===So(D.argv[1]??"").href&&$o(D.argv).catch(r=>{console.error(r instanceof Error?r.message:String(r)),D.exit(1)});export{Ao as createFatalHandler,Ro as createSharedDeadlineTimer,Eo as installBootSignalGuard,Te as runDevServer,Ps as runDevServerCli,To as shouldRunWizard,or as toDevServerOptions};
46
46
  //# sourceMappingURL=dev-server.js.map