infra-kit 0.1.133 → 0.3.0

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.
Files changed (63) hide show
  1. package/dist/{boot-YCABHUPP.js → boot-MTVHM4N7.js} +2 -2
  2. package/dist/{chunk-RXEMP3VI.js → chunk-4MRYIYJP.js} +3 -3
  3. package/dist/chunk-4MRYIYJP.js.map +7 -0
  4. package/dist/chunk-E2NWNNC6.js +2 -0
  5. package/dist/chunk-E2NWNNC6.js.map +7 -0
  6. package/dist/{chunk-3OMHS5RE.js → chunk-E2SEBLGJ.js} +2 -2
  7. package/dist/chunk-KZP2SY37.js +4 -0
  8. package/dist/chunk-KZP2SY37.js.map +7 -0
  9. package/dist/chunk-NC2TIQ3M.js +4 -0
  10. package/dist/chunk-NC2TIQ3M.js.map +7 -0
  11. package/dist/chunk-RLZ5IB2E.js +238 -0
  12. package/dist/chunk-RLZ5IB2E.js.map +7 -0
  13. package/dist/chunk-TI33V5G2.js +6 -0
  14. package/dist/chunk-TI33V5G2.js.map +7 -0
  15. package/dist/{chunk-FAR2L74S.js → chunk-TPVXMJ7N.js} +1 -1
  16. package/dist/cli.js +10 -8
  17. package/dist/cli.js.map +4 -4
  18. package/dist/dev-server.js +23 -20
  19. package/dist/dev-server.js.map +4 -4
  20. package/dist/dev-wizard-run-5HQOGE3R.js +2 -0
  21. package/dist/dev-wizard-run-5HQOGE3R.js.map +7 -0
  22. package/dist/mcp.js +1 -1
  23. package/dist/mcp.js.map +3 -3
  24. package/dist/persistent-ink-dev-ui-KOI44ZVT.js +2 -0
  25. package/dist/persistent-ink-dev-ui-KOI44ZVT.js.map +7 -0
  26. package/dist/safe-stderr-HXDR2DNJ.js +2 -0
  27. package/dist/update-check.js +1 -1
  28. package/package.json +3 -14
  29. package/dist/chunk-6EPRH34O.js +0 -2
  30. package/dist/chunk-6EPRH34O.js.map +0 -7
  31. package/dist/chunk-6FDGBQGX.js +0 -2
  32. package/dist/chunk-6FDGBQGX.js.map +0 -7
  33. package/dist/chunk-JD5T4VCB.js +0 -6
  34. package/dist/chunk-JD5T4VCB.js.map +0 -7
  35. package/dist/chunk-LTKR3F4N.js +0 -2
  36. package/dist/chunk-LTKR3F4N.js.map +0 -7
  37. package/dist/chunk-RSF5XAQJ.js +0 -4
  38. package/dist/chunk-RSF5XAQJ.js.map +0 -7
  39. package/dist/chunk-RXEMP3VI.js.map +0 -7
  40. package/dist/chunk-V37MZDFR.js +0 -3
  41. package/dist/chunk-V37MZDFR.js.map +0 -7
  42. package/dist/chunk-WSO6DN6Q.js +0 -220
  43. package/dist/chunk-WSO6DN6Q.js.map +0 -7
  44. package/dist/chunk-Z6KTUVIC.js +0 -2
  45. package/dist/chunk-Z6KTUVIC.js.map +0 -7
  46. package/dist/dev-wizard-run-TNA5YI7P.js +0 -2
  47. package/dist/dev-wizard-run-TNA5YI7P.js.map +0 -7
  48. package/dist/entry/index.d.ts +0 -4
  49. package/dist/entry/vite.d.ts +0 -2
  50. package/dist/index.js +0 -2
  51. package/dist/lib/package-config/package-config-schema.d.ts +0 -35
  52. package/dist/lib/package-config/package-config.d.ts +0 -99
  53. package/dist/lib/release-slug/release-slug.d.ts +0 -43
  54. package/dist/lib/vendor/config-schema.d.ts +0 -58
  55. package/dist/lib/vite/vite.d.ts +0 -168
  56. package/dist/persistent-ink-dev-ui-FUJQDFNY.js +0 -8
  57. package/dist/persistent-ink-dev-ui-FUJQDFNY.js.map +0 -7
  58. package/dist/vite.js +0 -2
  59. package/dist/vite.js.map +0 -7
  60. /package/dist/{boot-YCABHUPP.js.map → boot-MTVHM4N7.js.map} +0 -0
  61. /package/dist/{chunk-3OMHS5RE.js.map → chunk-E2SEBLGJ.js.map} +0 -0
  62. /package/dist/{chunk-FAR2L74S.js.map → chunk-TPVXMJ7N.js.map} +0 -0
  63. /package/dist/{index.js.map → safe-stderr-HXDR2DNJ.js.map} +0 -0
@@ -1,27 +1,30 @@
1
- import{d as M,h as ae,l as ue,m as ce,n as de,q as he}from"./chunk-RSF5XAQJ.js";import{A as ee,B as S,C as re,D as te,E as ne,G as ie,H as oe,K as se,Q as O,v as b,w as P,x as R,y as Z,z as C}from"./chunk-V37MZDFR.js";import"./chunk-6FU2TRU5.js";import{d as le,m as pe}from"./chunk-CHETBZ6M.js";import{a as _,b as F,c as k}from"./chunk-LTKR3F4N.js";import{b as j,c as ge}from"./chunk-JD5T4VCB.js";import{Command as at}from"commander";import w from"node:process";import{pathToFileURL as lt}from"node:url";import*as Pe from"node:path";import ur from"node:process";var Ke=t=>({pane:{surfaces:[{type:"terminal",command:t}]}}),H=(t,e)=>{if(t.length===1)return Ke(t[0]);let r=Math.ceil(t.length/2),n=t.slice(0,r),i=t.slice(r);return{direction:e%2===0?"horizontal":"vertical",split:Math.round(r/t.length*100)/100,children:[H(n,e+1),H(i,e+1)]}},me=t=>{if(t.length===0)throw new Error("buildCmuxLayout: at least one command is required");return H(t,0)};import{constants as nr}from"node:os";import V from"node:process";import{execFileSync as ze}from"node:child_process";import D from"node:process";var qe=5e3,Ye=100,Xe=2e3,Qe="/bin/ps",Ze=t=>t.split(`
2
- `).flatMap(e=>{let[r,n,i]=e.trim().split(/\s+/);if(r==null||n==null||i==null)return[];let o=Number(r),s=Number(n),a=Number(i);return!Number.isInteger(o)||!Number.isInteger(s)||!Number.isInteger(a)?[]:[{pid:o,ppid:s,pgid:a}]}),er=(t,e,r)=>{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([t]),o=new Set([t]),s=[t];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!==r)},W=()=>{try{return Ze(ze(Qe,["-eo","pid=,ppid=,pgid="],{encoding:"utf8",maxBuffer:8<<20}))}catch{return[]}},rr=(t,e,r)=>r.some(n=>n.pid===t&&n.ppid===e),B=(t,e)=>{let r=e.find(n=>n.pid===D.pid)?.pgid;return er(t,e,r)},ve=t=>{try{return D.kill(-t,0),!0}catch{return!1}},G=(t,e)=>{for(let r of t)try{D.kill(-r,e)}catch{}},ye=()=>{G(B(D.pid,W()),"SIGKILL")},tr=async t=>new Promise(e=>{setTimeout(e,t)}),fe=async(t,e)=>{let r=Date.now()+e,n=t;for(;n.length>0&&Date.now()<r&&(n=n.filter(ve),n.length!==0);)await tr(Ye);return n};function T(t,e=qe,r){t.unref();let n=!1,i=o=>{n||r?.(o)};return t.on("exit",(o,s)=>{i(`exited unexpectedly (code=${o??"null"}, signal=${s??"null"})`)}),t.on("error",o=>{i(`failed to spawn: ${o.message}`)}),{kill:async()=>{n=!0;let o=t.pid;if(o==null||t.exitCode!==null||t.signalCode!==null)return;let s=W();if(s.length>0&&!rr(o,D.pid,s))return;let a=B(o,s);G(a,"SIGTERM");let l=await fe(a,e);if(l.length===0)return;let u=B(o,W()),d=[...new Set([...l,...u])].filter(ve);G(d,"SIGKILL"),await fe(d,Xe)}}}var ir=["SIGINT","SIGTERM","SIGHUP"],or=nr.signals,sr=2,we=t=>128+(or[t]??sr),ar=t=>{V.exit(t)},lr=(t,e)=>{V.on(t,e)},be=t=>{try{V.stderr.write(t)}catch{}},pr=(t,e)=>{let r=e instanceof Error?`${e.message}
3
- ${e.stack??"(no stack)"}`:String(e);be(`
1
+ import{b as J,e as K,i as be,m as Se,n as Pe,o as De,r as Ae}from"./chunk-NC2TIQ3M.js";import"./chunk-6FU2TRU5.js";import{b as q,c as xe}from"./chunk-TI33V5G2.js";import{A as ce,B as L,C as de,D as he,E as ge,G as fe,H as me,K as ve,Q as V,v as T,w as $,x as _,y as ue,z as F}from"./chunk-KZP2SY37.js";import{d as we,m as ye}from"./chunk-CHETBZ6M.js";import{Command as Zt}from"commander";import U from"node:process";import{pathToFileURL as en}from"node:url";import*as Me from"node:path";import Ur from"node:process";var wr=t=>({pane:{surfaces:[{type:"terminal",command:t}]}}),z=(t,e)=>{if(t.length===1)return wr(t[0]);let r=Math.ceil(t.length/2),n=t.slice(0,r),i=t.slice(r);return{direction:e%2===0?"horizontal":"vertical",split:Math.round(r/t.length*100)/100,children:[z(n,e+1),z(i,e+1)]}},Ee=t=>{if(t.length===0)throw new Error("buildCmuxLayout: at least one command is required");return z(t,0)};import{constants as Cr}from"node:os";import Q from"node:process";import{execFile as yr,execFileSync as br}from"node:child_process";import x from"node:process";var Sr=5e3,Pr=100,Dr=2e3,Ce="/bin/ps",Ar=1e3,Te=["-eo","pid=,ppid=,pgid=,lstart="],$e=8<<20,Le=t=>t.split(`
2
+ `).flatMap(e=>{let[r,n,i,...o]=e.trim().split(/\s+/);if(r==null||n==null||i==null)return[];let s=Number(r),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(" ")}]}),Ie=t=>{let e=new Map;for(let r of t)r.pid===r.pgid&&e.set(r.pgid,r.lstart);return e},xr=(t,e,r)=>{let n=Ie(e);return Ne(t,e,r).flatMap(i=>{let o=n.get(i);return o==null||o===""?[]:[{pgid:i,leaderStart:o}]})},Re=(t,e)=>{let r=Ie(e);return t.flatMap(({pgid:n,leaderStart:i})=>{if(r.get(n)!==i)return[];try{x.kill(-n,"SIGKILL")}catch{return[]}return[n]})},Ne=(t,e,r)=>{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([t]),o=new Set([t]),s=[t];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!==r)},I=()=>{try{return Le(br(Ce,[...Te],{encoding:"utf8",maxBuffer:$e}))}catch{return[]}},Er=async()=>new Promise(t=>{yr(Ce,[...Te],{encoding:"utf8",maxBuffer:$e},(e,r)=>{t(e?[]:Le(r))})}),Rr=(t,e,r)=>r.some(n=>n.pid===t&&n.ppid===e),X=(t,e)=>{let r=e.find(n=>n.pid===x.pid)?.pgid;return Ne(t,e,r)},Oe=t=>{try{return x.kill(-t,0),!0}catch{return!1}},Y=(t,e)=>{for(let r of t)try{x.kill(-r,e)}catch{}},Ue=()=>{Y(X(x.pid,I()),"SIGKILL")},kr=async t=>new Promise(e=>{setTimeout(e,t)}),ke=async(t,e)=>{let r=Date.now()+e,n=t;for(;n.length>0&&Date.now()<r&&(n=n.filter(Oe),n.length!==0);)await kr(Pr);return n};function M(t,e=Sr,r){t.unref();let n=!1,i=!1,o=[],s=null,a=()=>{s&&clearInterval(s),s=null},l=async()=>{let u=t.pid;if(u==null||i||n)return;let h=await Er();if(h.length===0||i||n)return;let p=h.find(g=>g.pid===x.pid)?.pgid,c=xr(u,h,p);c.length>0&&(o=c)};l(),s=setInterval(()=>{l()},Ar),s.unref();let d=u=>{n||r?.(u)};return t.on("exit",(u,h)=>{i=!0,a(),n||Re(o,I()),d(`exited unexpectedly (code=${u??"null"}, signal=${h??"null"})`)}),t.on("error",u=>{d(`failed to spawn: ${u.message}`)}),{kill:async()=>{n=!0,a();let u=t.pid;if(u==null)return;if(t.exitCode!==null||t.signalCode!==null){Re(o,I());return}let h=I();if(h.length>0&&!Rr(u,x.pid,h))return;let p=X(u,h);Y(p,"SIGTERM");let c=await ke(p,e);if(c.length===0)return;let g=X(u,I()),w=[...new Set([...c,...g])].filter(Oe);Y(w,"SIGKILL"),await ke(w,Dr)}}}var Tr=["SIGINT","SIGTERM","SIGHUP"],$r=Cr.signals,Lr=2,_e=t=>128+($r[t]??Lr),Ir=t=>{Q.exit(t)},Nr=(t,e)=>{Q.on(t,e)},Fe=t=>{try{Q.stderr.write(t)}catch{}},Or=(t,e)=>{let r=e instanceof Error?`${e.message}
3
+ ${e.stack??"(no stack)"}`:String(e);Fe(`
4
4
  \u2717 Teardown failed while handling ${t}: ${r}
5
- `)},$=({onSignal:t,exit:e=ar,register:r=lr,forceReap:n=ye})=>{let i=null,o=s=>{if(i!==null){if(s!==i)return;be(`
5
+ `)},W=({onSignal:t,exit:e=Ir,register:r=Nr,forceReap:n=Ue})=>{let i=null,o=s=>{if(i!==null){if(s!==i)return;Fe(`
6
6
  \u26A0 Received ${s} again \u2014 force-quitting.
7
- `),n(),e(we(s));return}i=s,(async()=>{try{await t(s)}catch(a){pr(s,a)}finally{e(we(s))}})()};for(let s of ir)r(s,()=>o(s))};var cr=(t,e)=>t.map(({app:r,targets:n})=>`pnpm exec infra-kit dev ${n&&n.length>0?`--target=${n.join(",")}`:`--app=${r}`}${e?" --watch":""}`),dr=t=>{let e=new Map;for(let r of Object.keys(t?.apps??{})){let n=r.split("/")[0];n===void 0||n==="*"||e.set(n,[...e.get(n)??[],r])}return e},hr=(t,e)=>{let r=R(t);return e?r.filter(n=>e.includes(n.name)):r},gr=(t,e)=>{b.info(`\u{1F9E9} Opened cmux dev workspace ${e} with ${t.length} pane(s):`);for(let r of t)b.info(` \u2022 ${r.name} (infra-kit dev --app=${r.name})`)},mr=t=>{$({onSignal:async e=>{b.info(`
8
- Received ${e}, closing cmux dev workspace ${t}...`),await de(t)}})},Se=async t=>{let e=P(ur.cwd()),r=hr(e,C(t.include));if(r.length===0){b.warn("No API apps found to run");return}let n=dr(t.presetDef),i=cr(r.map(u=>({app:u.name,targets:n.get(u.name)})),t.watch??!1),o=me(i),s=`${Pe.basename(e)} dev`,a=await ce({cwd:e,title:s,layout:o});gr(r,a),mr(a);let l=setInterval(()=>{l.refresh()},2**30);await new Promise(()=>{})};import De from"node:process";var fr=t=>{try{De.stderr.write(t)}catch{}},vr=(t,e)=>{let r=e instanceof Error?`${e.message}
9
- ${e.stack??"(no stack)"}`:String(e);fr(`
7
+ `),n(),e(_e(s));return}i=s,(async()=>{try{await t(s)}catch(a){Or(s,a)}finally{e(_e(s))}})()};for(let s of Tr)r(s,()=>o(s))};var _r=(t,e)=>t.map(({app:r,targets:n})=>`pnpm exec infra-kit dev ${n&&n.length>0?`--target=${n.join(",")}`:`--app=${r}`}${e?" --watch":""}`),Fr=t=>{let e=new Map;for(let r of Object.keys(t?.apps??{})){let n=r.split("/")[0];n===void 0||n==="*"||e.set(n,[...e.get(n)??[],r])}return e},Mr=(t,e)=>{let r=_(t);return e?r.filter(n=>e.includes(n.name)):r},Wr=(t,e)=>{T.info(`\u{1F9E9} Opened cmux dev workspace ${e} with ${t.length} pane(s):`);for(let r of t)T.info(` \u2022 ${r.name} (infra-kit dev --app=${r.name})`)},jr=t=>{W({onSignal:async e=>{T.info(`
8
+ Received ${e}, closing cmux dev workspace ${t}...`),await De(t)}})},We=async t=>{let e=$(Ur.cwd()),r=Mr(e,F(t.include));if(r.length===0){T.warn("No API apps found to run");return}let n=Fr(t.presetDef),i=_r(r.map(d=>({app:d.name,targets:n.get(d.name)})),t.watch??!1),o=Ee(i),s=`${Me.basename(e)} dev`,a=await Pe({cwd:e,title:s,layout:o});Wr(r,a),jr(a);let l=setInterval(()=>{l.refresh()},2**30);await new Promise(()=>{})};import je from"node:process";var Hr=t=>{try{je.stderr.write(t)}catch{}},Z=(t,e)=>{let r=e instanceof Error?`${e.message}
9
+ ${e.stack??"(no stack)"}`:String(e);return`
10
10
  \u26A0\uFE0F ${t}: ${r}
11
11
  dev-server kept alive (likely a bug in a handler's async path); restart if it misbehaves.
12
- `)},yr=(t,e)=>{De.on(t,e)},xe=({onFault:t=vr,register:e=yr}={})=>{let r=n=>i=>{t(n,i)};e("uncaughtException",r("uncaughtException")),e("unhandledRejection",r("unhandledRejection"))};import Vr from"chokidar";import{exec as Jr,execFileSync as Kr}from"node:child_process";import*as c from"node:fs";import zr from"node:net";import qr from"node:os";import*as h from"node:path";import g from"node:process";import Yr from"node:util";import{execFile as wr}from"node:child_process";import*as Ae from"node:fs";import*as L from"node:path";import{promisify as br}from"node:util";var Pr=br(wr),Sr=t=>{try{let e=JSON.parse(Ae.readFileSync(L.join(t,"package.json"),"utf-8"));return typeof e.name=="string"?e.name:void 0}catch{return}},Dr=t=>async e=>{let{stdout:r}=await Pr("pnpm",["exec","turbo","run","build","--dry=json",`--filter=...${e}`],{cwd:t,maxBuffer:33554432}),i=(JSON.parse(r).tasks??[]).map(o=>o.package).filter(o=>typeof o=="string");return[...new Set(i)]},xr=t=>{let e=new Map,r=new Map;for(let n of S(t)){let i=Sr(L.dirname(n));i!==void 0&&(e.set(n,i),r.set(i,n))}return{packageNameByDir:e,dirByName:r}},Ee=async(t,e,r=Dr(t))=>{let{packageNameByDir:n,dirByName:i}=xr(t),o=new Map,s=await Promise.all(e.map(async a=>({app:a,closure:await r(a.packageName)})));for(let{app:a,closure:l}of s)for(let u of l){let d=i.get(u);if(d===void 0)continue;let v=o.get(d)??new Set;v.add(a.name),o.set(d,v)}return{dependentsByPackageDir:o,packageNameByDir:n}},Re=t=>`__pkg__:${t}`,Ce=(t,e,r)=>{if(e===null||r===void 0)return null;let n=e.dependentsByPackageDir.get(r)??new Set;return t.filter(i=>i.watchDeps&&n.has(i.name))};var Ar="/api/v1";function ke(t){if(t==null||t==="")return;let e=parseInt(t.trim().replace(/^["']|["']$/g,""),10);return Number.isNaN(e)?void 0:e}function Te(t,e,r){let i=`${t.replace(/-/g,"_").toUpperCase()}_PORT`,o=ke(e[i]);if(o!=null)return o;let s=ke(e.PORT);return s??r[t]?.port??void 0}function $e(t,e){return e[t]?.prefixUrl??Ar}function Le(t){let e=t.map(i=>i.port),r=e.filter((i,o)=>e.indexOf(i)!==o),n=t.filter(i=>r.includes(i.port));return{duplicatePorts:r,conflictingApps:n}}import{Logger as Er}from"@aws-lambda-powertools/logger";import Rr from"fastify";import*as Ne from"node:fs";import*as x from"node:path";import J from"node:process";import{pathToFileURL as Cr}from"node:url";import{parse as kr}from"yaml";var Tr=t=>t?.code==="EADDRINUSE",$r=3e4,Lr=()=>{let t=Number.parseInt(J.env.DEV_SERVER_TIMEOUT_MS??"",10);return Number.isNaN(t)?$r:t},Ie=()=>J.env.DEV_SERVER_REQUEST_LOG==="1",I=class{constructor(e){this.serverConfig=e;this.importCacheBust=`${Date.now()}`,this.logger=new Er({serviceName:"LocalServer",logLevel:"DEBUG"}),this.serverConfig.prefixUrl=this.serverConfig.prefixUrl??"",this.server=Rr({logger:!1}),this.server.addHook("onRequest",async(n,i)=>{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 r=this.serverConfig.onRequestLog;(Ie()||r)&&this.server.addHook("onResponse",async(n,i)=>{let o=Math.round(i.elapsedTime),s=n.url.split("?")[0]??n.url;r?.({method:n.method,path:s,status:i.statusCode,ms:o}),Ie()&&J.stdout.write(`${n.method} ${n.url} \u2192 ${i.statusCode} ${o}ms
13
- `)})}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(r){if(!Tr(r))throw r}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,r)=>r.code(200).send({status:"ok",app:this.serverConfig.appName??null,port:this.serverConfig.port})})}loadRoutes(){let e=x.join(this.serverConfig.controllersPath,"serverless.yml"),r=Ne.readFileSync(e,"utf8"),n=kr(r),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,r){let n=e.path.toString();n=n.replaceAll("{",":").replaceAll("}","");let i=x.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=(r.handler??"").split("."),d=u[0]??"",v=u[1]??"",p=x.join(this.serverConfig.controllersPath,`${d}.js`),m=Cr(p);m.searchParams.set("v",this.importCacheBust);let y=await import(m.href);this.controllers[a]={action:y,handler:v};let N=this.logger.createChild({serviceName:"RequestLogger"});this.server.route({method:s,url:i,handler:async(A,X)=>{let E=this.controllers[a];if(!E)throw new Error(`No controller for ${a}`);let Q=E.action[E.handler];if(!Q)throw new Error(`No handler ${E.handler} for ${i}`);let U=await Q(this.getEventObj(A.body,A.query,A.params,A.headers,s,i),this.getContext(),N),Je=JSON.parse(U.body);return X.headers(U.headers??{}),X.code(U?.statusCode??500).send(Je)}})}getEventObj(e,r,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:r??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(),r=Lr(),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,r-(Date.now()-e)),done:(i,o)=>{},fail:i=>{},succeed:i=>{}}}};import{spawn as Ir}from"node:child_process";import*as Ue from"node:fs";var Nr=(t,e)=>[...t.map(r=>`--filter=...${r}`),...e.map(r=>`--filter=${r}^...`)],Oe=({depInclusive:t,depClosure:e,cwd:r,logFile:n,onUnexpectedExit:i})=>{let o=Nr(t,e),s=Ue.openSync(n,"a"),a=Ir("pnpm",["exec","turbo","watch","build",...o,"--continue=dependencies-successful","--env-mode=loose"],{cwd:r,detached:!0,stdio:["ignore",s,s]});return T(a,void 0,i)};import{spawn as Ur}from"node:child_process";import Or from"node:process";var _r=/\u001B\][\s\S]*?(?:\u0007|\u001B\\)/g,Fr=/\u001B\[[0-9;?]*[\u0020-\u002F]*[\u0040-\u007E]/g,Mr=/[\u0000-\u0008\u000B-\u001F\u007F]/g,jr=t=>t.replace(_r,"").replace(Fr,"").replace(Mr,""),Hr=/^([^\s:]+):dev:[ \t]?/,Wr=t=>/^cache (?:bypass|hit|miss)/.test(t)||t.startsWith("$ "),Br=t=>{let e=jr(t).trimEnd(),r=Hr.exec(e);if(r==null)return null;let n=e.slice(r[0].length);return n.trim()===""||Wr(n.trim())?null:{pkg:r[1],text:n}},Gr=64*1024,_e=(t,e)=>{if(t==null)return;let r="",n=i=>{let o=Br(i);o!=null&&e.onLine?.(o)};t.setEncoding("utf-8"),t.on("data",i=>{e.appendLog?.(i),r+=i;let o=r.split(`
14
- `);r=o.pop()??"";for(let s of o)n(s);r.length>Gr&&(n(r),r="")}),t.on("end",()=>{r!==""&&(n(r),r="")}),t.on("error",i=>{e.appendLog?.(`[infra-kit] ui dev stream error: ${i.message}
15
- `)})},Fe=({packageNames:t,cwd:e,concurrency:r,env:n,appendLog:i,onLine:o,onUnexpectedExit:s})=>{let a=t.map(u=>`--filter=${u}`),l=Ur("pnpm",["exec","turbo","run","dev",...a,`--concurrency=${r}`,"--env-mode=loose","--only","--output-logs=new-only","--no-update-notifier","--ui=stream"],{cwd:e,detached:!0,stdio:["ignore","pipe","pipe"],env:{...Or.env,...n}});return _e(l.stdout,{appendLog:i,onLine:o}),_e(l.stderr,{appendLog:i,onLine:o}),T(l,void 0,s)};var f=He();function He(){return h.join(pe(),g.env[le]??"no-session","logs.txt")}function Xr(){f=He(),c.mkdirSync(h.dirname(f),{recursive:!0}),c.writeFileSync(f,`=== Dev Server Started: ${new Date().toISOString()} ===
16
-
17
- `)}function Me(t){let e=qr.homedir();return t===e||t.startsWith(`${e}${h.sep}`)?`~${t.slice(e.length)}`:t}function je(t){return t.map(e=>e.packageName).join(", ")}var Qr=Yr.promisify(Jr),Zr=async(t,e)=>{try{let{stderr:r}=await Qr(t);r&&e&&e(` (build) ${r.trim()}`,"debug"),r&&!e&&console.error("stderr:",r)}catch(r){let n=r;throw e&&(n.stdout||n.stderr)&&(n.stdout&&e(` stdout: ${n.stdout.trim()}`,"error"),n.stderr&&e(` stderr: ${n.stderr.trim()}`,"error")),r}};function We(t){c.appendFileSync(f,t)}var et=()=>new Promise((t,e)=>{let r=zr.createServer();r.unref(),r.on("error",e),r.listen(0,"127.0.0.1",()=>{let n=r.address(),i=typeof n=="object"&&n!==null?n.port:0;r.close(()=>t(i))})}),rt=async t=>{try{return(await fetch(t,{signal:AbortSignal.timeout(1500)})).ok}catch{return!1}},K="0.1.132",tt=(t,e)=>{let r=o=>o.split(".").map(s=>Number.parseInt(s,10)||0),n=r(t),i=r(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},nt=t=>{let e=[h.join(t,"package.json")];try{for(let r of c.readdirSync(h.join(t,"apps"),{withFileTypes:!0}))if(r.isDirectory())for(let n of["api","ui"])e.push(h.join(t,"apps",r.name,n,"package.json"))}catch{}return e.some(r=>{try{let n=JSON.parse(c.readFileSync(r,"utf-8"));return["dependencies","devDependencies"].some(i=>n[i]?.["infra-kit"]!=null)}catch{return!1}})},it=t=>{let e=h.join(t,"node_modules","infra-kit");if(!c.existsSync(e)){if(!nt(t))return;throw new Error("infra-kit dev: this repo depends on infra-kit but node_modules/infra-kit is missing, so the `infra-kit/vite` helper version cannot be verified. Run `pnpm install`.")}try{let n=c.realpathSync(e),i=c.realpathSync(t);if(n.startsWith(i+h.sep)&&!n.includes(`${h.sep}node_modules${h.sep}`))return}catch{}let r;try{let n=JSON.parse(c.readFileSync(h.join(e,"package.json"),"utf-8"));if(typeof n.version!="string")throw new Error("no version field");r=n.version}catch{throw new Error("infra-kit dev: could not read the version of the pinned `infra-kit/vite` helper (node_modules/infra-kit/package.json). Refusing to start rather than risk proxying plain HTTP at a TLS listener. Run `pnpm install`.")}if(tt(r,K))throw new Error(`infra-kit dev: this repo pins infra-kit ${r}, but dev URLs are now HTTPS and the \`infra-kit/vite\` helper only understands them from ${K}. An older helper would proxy plain HTTP at a TLS listener \u2014 silently. Bump the dependency:
18
- pnpm add -D infra-kit@^${K}`)},z=t=>{try{let e=Kr("git",["rev-parse","--abbrev-ref","HEAD"],{cwd:t,encoding:"utf-8"}).trim(),r=F(e);return r===""?k:r}catch{return k}},ot=t=>{let r=(t instanceof Error?t.message:String(t)).split(`
19
- `)[0]?.trim()??"";return r===""?"unknown error (see the log)":r},q=class t{monorepoRoot;devContextDir;appServers=[];watchDebounceTimers=new Map;watcher=null;static WATCH_DEBOUNCE_MS=400;restartWorkChain=Promise.resolve();static PORT_RELEASE_DELAY_MS=200;livenessTimer=null;livenessFailures=new Map;static LIVENESS_INTERVAL_MS=5e3;static LIVENESS_FAILURE_THRESHOLD=2;options;runBuild;turboWatchFactory;turboWatch=null;uiDevFactory;uiDev=null;uiLogStream=null;dryRunner;failedApps=[];renderer;healthProbe;proxy;proxyPort=se;registeredAliases=new Set;uiPortMap={};shuttingDown=!1;closureMap=null;closureBuild=Promise.resolve();constructor(e={},r=Zr,n=Oe,i=Fe,o,s,a=rt,l=ae()){this.options=e,this.runBuild=r,this.turboWatchFactory=n,this.uiDevFactory=i,this.dryRunner=o,this.proxy=l,Xr(),this.renderer=s??new ge({appendLog:We,verbose:this.options.verbose??!1}),this.healthProbe=a,this.devContextDir=h.join(g.cwd(),".infra-kit","dev-context"),this.monorepoRoot=P(g.cwd()),(g.env.DOPPLER_PROJECT!=null||g.env.DOPPLER_ENVIRONMENT!=null)&&this.renderer.log("\u{1F510} Doppler env detected (DOPPLER_PROJECT / DOPPLER_ENVIRONMENT)","debug")}discoverApiApps(e){return R(this.monorepoRoot).map(r=>({...r,preferredPort:this.resolvePreferredPort(r.name,e),prefixUrl:this.resolvePrefixUrl(r.name,e),watchDeps:!0}))}async loadDevConfig(){try{return(await O()).dev??{}}catch{return{}}}normalizeAppInclude(){return C(this.options.include)}resolvePreferredPort(e,r){return Te(e,g.env,r)}resolvePrefixUrl(e,r){return $e(e,r)}async loadDevPresets(){try{return(await O()).devServersPresets??{}}catch{return{}}}resolvePresetDef(e){if(this.options.presetDef!=null)return this.options.presetDef;let r=this.options.preset;if(r==null)return{};let n=e[r];if(!n){let i=Object.keys(e);throw new Error(`Unknown dev preset "${r}". Available: ${i.length>0?i.join(", "):"(none defined in devServersPresets)"}`)}return n}async start(){let e=Date.now(),r=this.normalizeAppInclude(),n=this.options.watch??!1,i=await this.loadDevConfig();g.env.POWERTOOLS_DEV??="true",g.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}=await this.resolveRunPlan(i,r);if(o.length===0&&s.length===0){this.renderer.log("\u26A0\uFE0F No API or UI apps to run for this preset","warn");return}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} Handler logs (AWS Powertools, logger.info/debug, etc.) \u2192 this terminal. Runner-only file: ${f}`));let u=oe({preset:this.options.preset,running:[...o.map(d=>`${d.name}/api`),...s.map(d=>`${d.name}/ui`)],discovered:[...a.map(d=>`${d.name}/api`),...l.map(d=>`${d.name}/ui`)]});if(await this.printReady(o,s,e,u),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.appServers.length>0&&this.startLivenessMonitor()}async resolveRunPlan(e,r){let n=this.discoverApiApps(e),i=Z(this.monorepoRoot),o=ie(this.resolvePresetDef(await this.loadDevPresets()),{api:n.map(p=>p.name),ui:i.map(p=>p.name)});o.unmatched.length>0&&this.renderer.log(`\u26A0\uFE0F Preset targets not found (skipped): ${o.unmatched.join(", ")}`,"warn");let s=new Set(o.targets.filter(p=>p.part==="api").map(p=>p.app)),a=new Set(o.targets.filter(p=>p.part==="ui").map(p=>p.app)),l=p=>!r||r.includes(p),u=new Map(o.targets.filter(p=>p.part==="api").map(p=>[p.app,p.watchDeps])),d=n.filter(p=>s.has(p.name)&&l(p.name)).map(p=>({...p,watchDeps:u.get(p.name)??p.watchDeps})),v=i.filter(p=>a.has(p.name)&&l(p.name));return{apps:d,uiApps:v,apiAppsAll:n,uiAppsAll:i}}async bringUpProxy(e){it(P(g.cwd())),await this.ensureProxy(),e.length>0&&this.assertNoPortConflicts(e)}async buildAll(e,r,n){let i=[e.length>0?`building ${je(e)}`:"",r.length>0?`warming ${je(r)}`:""].filter(Boolean).join(" \xB7 ");this.renderer.bootStep(i),e.length>0&&await this.buildApps(e,n),r.length>0&&await this.buildUiApps(r)}armWatch(e,r,n){n&&(this.appServers.length>0||r.length>0)&&(this.setupWatch(e,r),this.closureBuild=this.buildClosureMapSafe(e).then(i=>{this.closureMap=i}))}async buildUiApps(e){let r=e.map(n=>`--filter=${n.packageName}^...`).join(" ");try{await this.runBuild(`pnpm exec turbo run build ${r} --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 r=e.map(s=>s.name).join(", ");this.renderer.narrate(`\u{1F3A8} Starting ${e.length} UI dev server(s) via \`turbo run dev\`: ${r}`),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=g.env.NODE_EXTRA_CA_CERTS==null&&c.existsSync(M())?{NODE_EXTRA_CA_CERTS:M()}:void 0,o=new Map(e.map(s=>[s.packageName,`${s.name}/ui`]));this.uiLogStream=c.createWriteStream(f,{flags:"a"}),this.uiLogStream.on("error",()=>{this.uiLogStream=null}),this.uiDev=this.uiDevFactory({packageNames:e.map(s=>s.packageName),cwd:g.cwd(),concurrency:Math.max(e.length+4,12),env:n||i?{...n,...i}:void 0,appendLog:s=>{this.uiLogStream?.write(s)},onLine:({pkg:s,text:a})=>{this.renderer.event({tag:o.get(s)??`${s}/ui`,text:a})},onUnexpectedExit:s=>{this.reportEngineDeath("UI dev engine (`turbo run dev`)","frontends stopped reloading",s)}})}formatAppList(e){return e.map(r=>`${r.name}:${r.port}`).join(", ")}assertNoPortConflicts(e){let r=e.filter(o=>o.preferredPort!=null).map(o=>({name:o.name,port:o.preferredPort})),{duplicatePorts:n,conflictingApps:i}=Le(r);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,r){let i=`pnpm exec turbo run build ${e.map(o=>`--filter=${o.packageName}`).join(" ")} --env-mode=loose --output-logs=errors-only --no-update-notifier${r?" --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 r=>{try{let n=await this.startOneApp(r);n&&this.appServers.push({app:r,...n})}catch(n){this.renderer.log(`\u274C Failed to start ${r.name}: ${String(n)}`,"error"),this.failedApps.push({app:r,reason:ot(n)})}}))}async ensureProxy(){if(!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`.");if(!await this.proxy.isProxyServing(this.proxyPort,!0))throw new Error(`infra-kit dev: no portless daemon is serving HTTPS on :${this.proxyPort}, so no dev URL can resolve. Install it once (this is the only step that needs root):
20
- sudo portless service install
12
+ `},Br=(t,e)=>{Hr(Z(t,e))},Gr=(t,e)=>{je.on(t,e)},He=({onFault:t=Br,register:e=Gr}={})=>{let r=n=>i=>{t(n,i)};e("uncaughtException",r("uncaughtException")),e("unhandledRejection",r("unhandledRejection"))};import{DEFAULT_RELEASE_SLUG as ur,DEV_CONTEXT_WIRE_VERSION as Rt,slugifyHostLabel as kt,slugifyRelease as Ct}from"@slip-stream-kit/config/internal";import Tt from"chokidar";import{exec as $t,execFileSync as Lt}from"node:child_process";import*as f from"node:fs";import It from"node:net";import Nt from"node:os";import*as m from"node:path";import v from"node:process";import Ot from"node:util";import{execFile as Vr}from"node:child_process";import*as Be from"node:fs";import*as j from"node:path";import{promisify as Jr}from"node:util";var Kr=Jr(Vr),qr=t=>{try{let e=JSON.parse(Be.readFileSync(j.join(t,"package.json"),"utf-8"));return typeof e.name=="string"?e.name:void 0}catch{return}},zr=t=>async e=>{let{stdout:r}=await Kr("pnpm",["exec","turbo","run","build","--dry=json",`--filter=...${e}`],{cwd:t,maxBuffer:33554432}),i=(JSON.parse(r).tasks??[]).map(o=>o.package).filter(o=>typeof o=="string");return[...new Set(i)]},Xr=t=>{let e=new Map,r=new Map;for(let n of L(t)){let i=qr(j.dirname(n));i!==void 0&&(e.set(n,i),r.set(i,n))}return{packageNameByDir:e,dirByName:r}},Ge=async(t,e,r=zr(t))=>{let{packageNameByDir:n,dirByName:i}=Xr(t),o=new Map,s=await Promise.all(e.map(async a=>({app:a,closure:await r(a.packageName)})));for(let{app:a,closure:l}of s)for(let d of l){let u=i.get(d);if(u===void 0)continue;let h=o.get(u)??new Set;h.add(a.name),o.set(u,h)}return{dependentsByPackageDir:o,packageNameByDir:n}},Ve=t=>`__pkg__:${t}`,Je=(t,e,r)=>{if(e===null||r===void 0)return null;let n=e.dependentsByPackageDir.get(r)??new Set;return t.filter(i=>i.watchDeps&&n.has(i.name))};import{AsyncLocalStorage as Yr}from"node:async_hooks";var ee=new Yr,Ke=(t,e)=>ee.run(t,e),qe=t=>{ee.enterWith(t)},re=()=>ee.getStore();import b from"node:fs";import k from"node:path";import S from"node:process";var Qr=Object.getPrototypeOf(S.stdout).write,N=t=>Qr.call(S.stdout,t),Xe=t=>Object.getPrototypeOf(S.stderr).write.call(S.stderr,t);var Ye=()=>new Proxy(S.stdout,{get(t,e,r){if(e==="write")return i=>N(String(i));let n=Reflect.get(t,e,r);return typeof n=="function"?n.bind(t):n}}),ze=()=>({errors:0,warns:0,lastErrorAt:null}),Qe=t=>{let e=t.split(/\W+/).filter(r=>r!=="").join("-");return e===""?null:e},Zr=()=>{let t=S.env[we]??"",e=Qe(t)??"no-session";return k.join(ye(),e,"dev",String(S.pid))},et=t=>`${Qe(t)??"unnamed"}.log`,rt=10080*60*1e3,tt=t=>{let e=Number(t);if(!Number.isInteger(e)||e<=0)return!1;try{return S.kill(e,0),!0}catch(r){return r.code==="EPERM"}},nt=(t,e)=>{let r;try{r=b.readdirSync(t,{withFileTypes:!0})}catch{return}for(let n of r){if(!n.isDirectory()||tt(n.name))continue;let i=k.join(t,n.name);try{e-b.statSync(i).mtimeMs>rt&&b.rmSync(i,{recursive:!0,force:!0})}catch{}}},H=class{dir;fds=new Map;counters=new Map;closed=!1;constructor(e=Zr()){this.dir=e,b.mkdirSync(this.dir,{recursive:!0}),nt(k.dirname(this.dir),Date.now()),this.linkLatest()}linkLatest(){let e=k.join(k.dirname(this.dir),"latest");try{b.rmSync(e,{force:!0}),b.symlinkSync(this.dir,e,"dir")}catch{}}pathFor(e){return k.join(this.dir,et(e))}fdFor(e){let r=this.fds.get(e);if(r!=null)return r;try{let n=b.openSync(this.pathFor(e),"a");return this.fds.set(e,n),n}catch{return null}}write(e,r,n={}){if(this.closed)return;let i=this.counters.get(e)??ze();n.level==="error"?(i.errors+=1,i.lastErrorAt=Date.now()):n.level==="warn"&&(i.warns+=1),this.counters.set(e,i);let o=this.fdFor(e);if(o!=null)try{b.writeSync(o,r.endsWith(`
13
+ `)?r:`${r}
14
+ `)}catch{}}statsFor(e){return this.counters.get(e)??ze()}services(){return[...this.fds.keys()]}close(){if(!this.closed){this.closed=!0;for(let e of this.fds.values())try{b.closeSync(e)}catch{}this.fds.clear()}}};import te from"node:process";import it from"node:util";var ne={log:"info",info:"info",debug:"debug",trace:"debug",warn:"warn",error:"error"},Ze=({sink:t,fallbackService:e,currentService:r,terminalWrite:n=N,stderrWrite:i=Xe})=>{let o=!1,s=!0,a=()=>r()??e,l=(c,g)=>{t.write(a(),c,{level:g}),o||n(c.endsWith(`
15
+ `)?c:`${c}
16
+ `)},d={};for(let c of Object.keys(ne))d[c]=console[c],console[c]=(...g)=>{if(!s){d[c](...g);return}l(it.format(...g),ne[c])};let u=(c,g,w)=>{let G=c.write.bind(c),y="",P=()=>{y!==""&&(t.write(a(),y,{level:g}),y="")};return c.write=((D,...A)=>{if(!s||typeof D!="string")return G(D,...A);o||w(D),y+=D;let C=y.split(`
17
+ `);y=C.pop()??"";for(let R of C)R!==""&&t.write(a(),R,{level:g});y.length>8192&&P();let E=A.find(R=>typeof R=="function");return typeof E=="function"&&te.nextTick(E),!0}),()=>{P(),Reflect.deleteProperty(c,"write")}},h=u(te.stdout,"info",n),p=u(te.stderr,"warn",i);return{suppressTerminal:()=>{o=!0},uninstall:()=>{if(s){s=!1,h(),p();for(let c of Object.keys(ne))console[c]=d[c]}}}};var ot="/api/v1";function er(t){if(t==null||t==="")return;let e=parseInt(t.trim().replace(/^["']|["']$/g,""),10);return Number.isNaN(e)?void 0:e}function rr(t,e,r){let i=`${t.replace(/-/g,"_").toUpperCase()}_PORT`,o=er(e[i]);if(o!=null)return o;let s=er(e.PORT);return s??r[t]?.port??void 0}function tr(t,e){return e[t]?.prefixUrl??ot}function nr(t){let e=t.map(i=>i.port),r=e.filter((i,o)=>e.indexOf(i)!==o),n=t.filter(i=>r.includes(i.port));return{duplicatePorts:r,conflictingApps:n}}import{Logger as st}from"@aws-lambda-powertools/logger";import at from"fastify";import*as or from"node:fs";import*as O from"node:path";import ie from"node:process";import{pathToFileURL as lt}from"node:url";import{parse as pt}from"yaml";var ut=t=>t?.code==="EADDRINUSE",ct=3e4,dt=()=>{let t=Number.parseInt(ie.env.DEV_SERVER_TIMEOUT_MS??"",10);return Number.isNaN(t)?ct:t},ir=()=>ie.env.DEV_SERVER_REQUEST_LOG==="1",B=class{constructor(e){this.serverConfig=e;this.importCacheBust=`${Date.now()}`,this.logger=new st({serviceName:"LocalServer",logLevel:"DEBUG"}),this.serverConfig.prefixUrl=this.serverConfig.prefixUrl??"",this.server=at({logger:!1}),this.server.addHook("onRequest",async(n,i)=>{let o=this.serverConfig.serviceTag;o!=null&&qe(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 r=this.serverConfig.onRequestLog;(ir()||r)&&this.server.addHook("onResponse",async(n,i)=>{let o=Math.round(i.elapsedTime),s=n.url.split("?")[0]??n.url;r?.({method:n.method,path:s,status:i.statusCode,ms:o}),ir()&&ie.stdout.write(`${n.method} ${n.url} \u2192 ${i.statusCode} ${o}ms
18
+ `)})}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(r){if(!ut(r))throw r}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,r)=>r.code(200).send({status:"ok",app:this.serverConfig.appName??null,port:this.serverConfig.port})})}loadRoutes(){let e=O.join(this.serverConfig.controllersPath,"serverless.yml"),r=or.readFileSync(e,"utf8"),n=pt(r),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,r){let n=e.path.toString();n=n.replaceAll("{",":").replaceAll("}","");let i=O.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 d=(r.handler??"").split("."),u=d[0]??"",h=d[1]??"",p=O.join(this.serverConfig.controllersPath,`${u}.js`),c=lt(p);c.searchParams.set("v",this.importCacheBust);let g=this.serverConfig.serviceTag,w=async()=>await import(c.href),G=g==null?await w():await Ke(g,w);this.controllers[a]={action:G,handler:h};let y=this.logger.createChild({serviceName:"RequestLogger"});this.server.route({method:s,url:i,handler:async(P,D)=>{let A=this.controllers[a];if(!A)throw new Error(`No controller for ${a}`);let C=A.action[A.handler];if(!C)throw new Error(`No handler ${A.handler} for ${i}`);let E=await C(this.getEventObj(P.body,P.query,P.params,P.headers,s,i),this.getContext(),y),R=JSON.parse(E.body);return D.headers(E.headers??{}),D.code(E?.statusCode??500).send(R)}})}getEventObj(e,r,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:r??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(),r=dt(),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,r-(Date.now()-e)),done:(i,o)=>{},fail:i=>{},succeed:i=>{}}}};import{spawn as ht}from"node:child_process";import*as sr from"node:fs";var gt=(t,e)=>[...t.map(r=>`--filter=...${r}`),...e.map(r=>`--filter=${r}^...`)],ar=({depInclusive:t,depClosure:e,cwd:r,logFile:n,onUnexpectedExit:i})=>{let o=gt(t,e),s=sr.openSync(n,"a"),a=ht("pnpm",["exec","turbo","watch","build",...o,"--continue=dependencies-successful","--env-mode=loose"],{cwd:r,detached:!0,stdio:["ignore",s,s]});return M(a,void 0,i)};import{spawn as ft}from"node:child_process";import mt from"node:process";var vt=[/^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],wt=t=>vt.some(e=>e.test(t))?"error":"info",yt=/\u001B\][\s\S]*?(?:\u0007|\u001B\\)/g,bt=/\u001B\[[0-9;?]*[\u0020-\u002F]*[\u0040-\u007E]/g,St=/[\u0000-\u0008\u000B-\u001F\u007F]/g,Pt=t=>t.replace(yt,"").replace(bt,"").replace(St,""),Dt=/^([^\s:]+):dev:[ \t]?/,At=t=>/^cache (?:bypass|hit|miss)/.test(t)||t.startsWith("$ "),xt=t=>{let e=Pt(t).trimEnd(),r=Dt.exec(e);if(r==null)return null;let n=e.slice(r[0].length);return n.trim()===""||At(n.trim())?null:{pkg:r[1],text:n,level:wt(n)}},Et=64*1024,lr=(t,e)=>{if(t==null)return;let r="",n=i=>{let o=xt(i);o!=null&&e.onLine?.(o)};t.setEncoding("utf-8"),t.on("data",i=>{e.appendLog?.(i),r+=i;let o=r.split(`
19
+ `);r=o.pop()??"";for(let s of o)n(s);r.length>Et&&(n(r),r="")}),t.on("end",()=>{r!==""&&(n(r),r="")}),t.on("error",i=>{e.appendLog?.(`[infra-kit] ui dev stream error: ${i.message}
20
+ `)})},pr=({packageNames:t,cwd:e,concurrency:r,env:n,appendLog:i,onLine:o,onUnexpectedExit:s})=>{let a=t.map(d=>`--filter=${d}`),l=ft("pnpm",["exec","turbo","run","dev",...a,`--concurrency=${r}`,"--env-mode=loose","--only","--output-logs=new-only","--no-update-notifier","--ui=stream"],{cwd:e,detached:!0,stdio:["ignore","pipe","pipe"],env:{...mt.env,...n}});return lr(l.stdout,{appendLog:i,onLine:o}),lr(l.stderr,{appendLog:i,onLine:o}),M(l,void 0,s)};var ae="runner",Ut="turbo",_t="watch";function oe(t){let e=Nt.homedir();return t===e||t.startsWith(`${e}${m.sep}`)?`~${t.slice(e.length)}`:t}function cr(t){return t.map(e=>e.packageName).join(", ")}var Ft=Ot.promisify($t),Mt=async(t,e)=>{try{let{stderr:r}=await Ft(t);r&&e&&e(` (build) ${r.trim()}`,"debug"),r&&!e&&console.error("stderr:",r)}catch(r){let n=r;throw e&&(n.stdout||n.stderr)&&(n.stdout&&e(` stdout: ${n.stdout.trim()}`,"error"),n.stderr&&e(` stderr: ${n.stderr.trim()}`,"error")),r}},dr=null;function hr(t){dr?.write(ae,t)}var Wt=()=>new Promise((t,e)=>{let r=It.createServer();r.unref(),r.on("error",e),r.listen(0,"127.0.0.1",()=>{let n=r.address(),i=typeof n=="object"&&n!==null?n.port:0;r.close(()=>t(i))})}),jt=async t=>{try{return(await fetch(t,{signal:AbortSignal.timeout(1500)})).ok}catch{return!1}},Ht=[{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"}],Bt=(t,e)=>{let r=o=>o.split(".").map(s=>Number.parseInt(s,10)||0),n=r(t),i=r(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},Gt=t=>{let e=[t];try{for(let r of f.readdirSync(m.join(t,"apps"),{withFileTypes:!0}))if(r.isDirectory())for(let n of["api","ui"])e.push(m.join(t,"apps",r.name,n))}catch{}return e},Vt=(t,e)=>{try{let r=JSON.parse(f.readFileSync(m.join(t,"package.json"),"utf-8"));return["dependencies","devDependencies"].some(n=>r[n]?.[e]!=null)}catch{return!1}},Jt=(t,e,r)=>{let n=r.split("/"),i=e;for(;;){let o=m.join(i,"node_modules",...n);if(f.existsSync(o))return o;let s=m.dirname(i);if(i===t||s===i)return;i=s}},Kt=(t,e)=>{try{let r=f.realpathSync(e),n=f.realpathSync(t);return r.startsWith(n+m.sep)&&!r.includes(`${m.sep}node_modules${m.sep}`)}catch{return!1}},qt=t=>{try{return f.realpathSync(t)}catch{return t}},zt=(t,e,r,n)=>{if(Kt(t,n))return;let i;try{let o=JSON.parse(f.readFileSync(m.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(Bt(i,r))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 ${r}. An older helper would proxy plain HTTP at a TLS listener \u2014 silently. Bump the dependency:
21
+ pnpm add -D ${e}@^${r}`)},Xt=t=>{let e=Gt(t);for(let{name:r,floor:n}of Ht){let i=e.filter(s=>Vt(s,r)),o=new Map;for(let s of[...i,t]){let a=Jt(t,s,r);a&&o.set(qt(a),a)}if(o.size===0){if(i.length===0)continue;throw new Error(`infra-kit dev: ${i[0]}/package.json depends on ${r} but it does not resolve from there, so the \`infraKitDev\` helper version cannot be verified. Run \`pnpm install\`.`)}for(let s of o.values())zt(t,r,n,s)}},se=t=>{try{let e=Lt("git",["rev-parse","--abbrev-ref","HEAD"],{cwd:t,encoding:"utf-8"}).trim(),r=Ct(e);return r===""?ur:r}catch{return ur}},Yt=t=>{let r=(t instanceof Error?t.message:String(t)).split(`
22
+ `)[0]?.trim()??"";return r===""?"unknown error (see the log)":r},le=class t{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;livenessFailures=new Map;static LIVENESS_INTERVAL_MS=5e3;static LIVENESS_FAILURE_THRESHOLD=2;options;runBuild;turboWatchFactory;turboWatch=null;uiDevFactory;uiDev=null;sink;intercept;dryRunner;failedApps=[];renderer;healthProbe;proxy;proxyPort=ve;registeredAliases=new Set;uiPortMap={};shuttingDown=!1;closureMap=null;closureBuild=Promise.resolve();constructor(e={},r=Mt,n=ar,i=pr,o,s,a=jt,l=be()){this.options=e,this.runBuild=r,this.turboWatchFactory=n,this.uiDevFactory=i,this.dryRunner=o,this.proxy=l,this.sink=new H,dr=this.sink,this.intercept=gr(this.options)?Ze({sink:this.sink,fallbackService:ae,currentService:re}):null,this.renderer=s??new xe({appendLog:hr,verbose:this.options.verbose??!1}),this.healthProbe=a,this.devContextDir=m.join(v.cwd(),".infra-kit","dev-context"),this.monorepoRoot=$(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 _(this.monorepoRoot).map(r=>({...r,preferredPort:this.resolvePreferredPort(r.name,e),prefixUrl:this.resolvePrefixUrl(r.name,e),watchDeps:!0}))}async loadDevConfig(){try{return(await V()).dev??{}}catch{return{}}}normalizeAppInclude(){return F(this.options.include)}resolvePreferredPort(e,r){return rr(e,v.env,r)}resolvePrefixUrl(e,r){return tr(e,r)}async loadDevPresets(){try{return(await V()).devServersPresets??{}}catch{return{}}}resolvePresetDef(e){if(this.options.presetDef!=null)return this.options.presetDef;let r=this.options.preset;if(r==null)return{};let n=e[r];if(!n){let i=Object.keys(e);throw new Error(`Unknown dev preset "${r}". Available: ${i.length>0?i.join(", "):"(none defined in devServersPresets)"}`)}return n}async start(){let e=Date.now(),r=this.normalizeAppInclude(),n=this.options.watch??!1,i=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:o,uiApps:s,apiAppsAll:a,uiAppsAll:l}=await this.resolveRunPlan(i,r);if(o.length===0&&s.length===0){this.renderer.log("\u26A0\uFE0F No API or UI apps to run for this preset","warn");return}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 ${oe(this.sink.dir)} (one file per service)`));let d=me({preset:this.options.preset,running:[...o.map(u=>`${u.name}/api`),...s.map(u=>`${u.name}/ui`)],discovered:[...a.map(u=>`${u.name}/api`),...l.map(u=>`${u.name}/ui`)]});if(await this.printReady(o,s,e,d),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,r){let n=this.discoverApiApps(e),i=ue(this.monorepoRoot),o=fe(this.resolvePresetDef(await this.loadDevPresets()),{api:n.map(p=>p.name),ui:i.map(p=>p.name)});o.unmatched.length>0&&this.renderer.log(`\u26A0\uFE0F Preset targets not found (skipped): ${o.unmatched.join(", ")}`,"warn");let s=new Set(o.targets.filter(p=>p.part==="api").map(p=>p.app)),a=new Set(o.targets.filter(p=>p.part==="ui").map(p=>p.app)),l=p=>!r||r.includes(p),d=new Map(o.targets.filter(p=>p.part==="api").map(p=>[p.app,p.watchDeps])),u=n.filter(p=>s.has(p.name)&&l(p.name)).map(p=>({...p,watchDeps:d.get(p.name)??p.watchDeps})),h=i.filter(p=>a.has(p.name)&&l(p.name));return{apps:u,uiApps:h,apiAppsAll:n,uiAppsAll:i}}async bringUpProxy(e){Xt($(v.cwd())),await this.ensureProxy(),e.length>0&&this.assertNoPortConflicts(e)}async buildAll(e,r,n){let i=[e.length>0?`building ${cr(e)}`:"",r.length>0?`warming ${cr(r)}`:""].filter(Boolean).join(" \xB7 ");this.renderer.bootStep(i),e.length>0&&await this.buildApps(e,n),r.length>0&&await this.buildUiApps(r)}armWatch(e,r,n){n&&(this.appServers.length>0||r.length>0)&&(this.setupWatch(e,r),this.closureBuild=this.buildClosureMapSafe(e).then(i=>{this.closureMap=i}))}async buildUiApps(e){let r=e.map(n=>`--filter=${n.packageName}^...`).join(" ");try{await this.runBuild(`pnpm exec turbo run build ${r} --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 r=e.map(s=>s.name).join(", ");this.renderer.narrate(`\u{1F3A8} Starting ${e.length} UI dev server(s) via \`turbo run dev\`: ${r}`),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=v.env.NODE_EXTRA_CA_CERTS==null&&f.existsSync(K())?{NODE_EXTRA_CA_CERTS:K()}:void 0,o=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||i?{...n,...i}:void 0,appendLog:s=>{this.sink.write(Ut,s)},onLine:({pkg:s,text:a,level:l})=>{let d=o.get(s)??`${s}/ui`;this.sink.write(d,a,{level:l})},onUnexpectedExit:s=>{this.reportEngineDeath("UI dev engine (`turbo run dev`)","frontends stopped reloading",s)}})}formatAppList(e){return e.map(r=>`${r.name}:${r.port}`).join(", ")}assertNoPortConflicts(e){let r=e.filter(o=>o.preferredPort!=null).map(o=>({name:o.name,port:o.preferredPort})),{duplicatePorts:n,conflictingApps:i}=nr(r);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,r){let i=`pnpm exec turbo run build ${e.map(o=>`--filter=${o.packageName}`).join(" ")} --env-mode=loose --output-logs=errors-only --no-update-notifier${r?" --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 r=>{try{let n=await this.startOneApp(r);n&&this.appServers.push({app:r,...n,startedAt:Date.now(),restarts:0})}catch(n){this.renderer.log(`\u274C Failed to start ${r.name}: ${String(n)}`,"error"),this.failedApps.push({app:r,reason:Yt(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`.");if(!await this.proxy.isProxyServing(this.proxyPort,!0))throw new Error(`infra-kit dev: no portless daemon is serving HTTPS on :${this.proxyPort}, so no dev URL can resolve. Install it once (this is the only step that needs root):
23
+ ${J(["service","install"],{sudo:!0,bin:e})}
21
24
  Then trust its local CA (no sudo needed):
22
- portless trust
23
- \`infra-kit doctor\` checks both.`)}async registerAppAlias(e,r,n){let i=z(r),o=_(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 r=new I({controllersPath:e.path,prefixUrl:e.prefixUrl,port:e.preferredPort,appName:e.name,onRequestLog:({method:o,path:s,status:a,ms:l})=>{s!=="/__health"&&this.renderer.event({tag:`${e.name}/api`,text:`${o} ${s} ${a} ${l}ms`})}}),n=await r.start(),i;try{i=await this.registerAppAlias(e.packageName,e.path,n)}catch(o){throw await r.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:r,boundPort:n,alias:i}}writeDevContextFragment(e,r,n){let i={package:e.packageName,port:r,pid:g.pid,writtenAt:Date.now(),release:z(e.path),alias:n,origin:`https://${n}`},o=h.join(this.devContextDir,`${e.name}.json`),s=h.join(this.devContextDir,`${e.name}.json.${g.pid}.tmp`);c.mkdirSync(this.devContextDir,{recursive:!0}),c.writeFileSync(s,JSON.stringify(i,null,2)),c.renameSync(s,o)}removeDevContextFragment(e){c.rmSync(h.join(this.devContextDir,`${e.name}.json`),{force:!0})}scheduleRestartWork(e){let r=this.restartWorkChain.then(()=>e(),()=>e());return this.restartWorkChain=r.catch(()=>{}),r}async delayPortRelease(){await new Promise(e=>setTimeout(e,t.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(r=>({idx:this.appServers.findIndex(n=>n.app.name===r.name),app:r})).filter(r=>r.idx>=0)}async runRestart(e){let r=this.resolveRestartTargets(e);if(r.length===0)return;let n=r.length===1?r[0].app.name:`${r.length} apps`;this.renderer.log(`\u{1F504} Restarting ${n}...`),await Promise.all(r.map(async({idx:a})=>{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(r.map(async({idx:a,app:l})=>{try{let u=await this.startOneApp(l);if(u){let d={app:l,...u};return this.appServers[a]=d,{app:l,entry:d}}return{app:l,entry:null}}catch(u){return this.renderer.log(`\u274C Failed to restart ${l.name}: ${String(u)}`,"error"),{app:l,entry:null}}})),o=await Promise.all(i.map(async({app:a,entry:l})=>{let u=l?await this.healthProbe(t.healthUrl(l.boundPort)):!1;return{label:`${l?`${a.name}:${l.boundPort}`:a.name} ${u?"\u25CF up":"\u25CF down"}`,healthy:u}})),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 Ee(this.monorepoRoot,e,this.dryRunner)}catch(r){return this.renderer.log(`\u26A0\uFE0F Dependency-closure map unavailable (${String(r)}); package changes restart all apps`,"warn"),null}}reportEngineDeath(e,r,n){this.shuttingDown||this.renderer.log(`\u26A0\uFE0F ${e} ${n} \u2014 ${r}. Restart \`infra-kit dev\`.`,"warn")}setupWatch(e,r){this.turboWatch=this.turboWatchFactory({depInclusive:e.map(l=>l.packageName),depClosure:r.map(l=>l.packageName),cwd:g.cwd(),logFile:f,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=re(e),i=S(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=g.env.DEV_SERVER_CHOKIDAR_POLL==="1",a=Vr.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,r,n,i){this.renderer.log(`\u{1F440} dist change detected: ${e}`,"debug");let o=te(e,n,i);if(o.kind==="package"){let a=Ce(r,this.closureMap,o.packageDir);if(a===null){this.scheduleDebounced("__packages__",()=>this.restart(r));return}a.length>0&&o.packageDir!==void 0&&this.scheduleDebounced(Re(o.packageDir),()=>this.restart(a));return}let s=r.find(a=>h.join(a.path,"dist")===o.app);s&&this.scheduleDebounced(s.name,()=>this.restart([s]))}scheduleDebounced(e,r){if(this.shuttingDown)return;let n=this.watchDebounceTimers.get(e);n&&clearTimeout(n);let i=setTimeout(()=>{this.watchDebounceTimers.delete(e),!this.shuttingDown&&r().catch(o=>{this.renderer.log(`Restart error (${e}): ${String(o)}`,"error")})},t.WATCH_DEBOUNCE_MS);this.watchDebounceTimers.set(e,i)}static healthUrl(e){return`http://127.0.0.1:${e}/__health`}startLivenessMonitor(){this.scheduleLivenessTick()}scheduleLivenessTick(){let e=this.options.livenessIntervalMs??t.LIVENESS_INTERVAL_MS;this.livenessTimer=setTimeout(()=>{this.livenessTick().finally(()=>{this.shuttingDown||this.scheduleLivenessTick()}).catch(()=>{})},e),this.livenessTimer.unref()}async livenessTick(){this.shuttingDown||await Promise.all(this.appServers.map(async({app:e,boundPort:r})=>{let n=await this.healthProbe(t.healthUrl(r));if(this.shuttingDown)return;let i=this.livenessFailures.get(e.name)??0;if(n){i>=t.LIVENESS_FAILURE_THRESHOLD&&this.renderer.log(`\u2705 ${e.name}/api recovered`),this.livenessFailures.set(e.name,0);return}let o=i+1;this.livenessFailures.set(e.name,o),o===t.LIVENESS_FAILURE_THRESHOLD&&this.renderer.log(`\u26A0\uFE0F ${e.name}/api unhealthy (/__health not responding)`,"warn")}))}async printReady(e,r,n,i){let o=Date.now()-n,s=await Promise.all(this.appServers.map(({boundPort:m})=>this.healthProbe(t.healthUrl(m)))),a=this.appServers.map(({app:m,alias:y},N)=>({tag:`${m.name}/api`,url:j({prefixUrl:m.prefixUrl,alias:y}),healthy:s[N]??null}));this.uiPortMap={};let l=[],u=[];for(let m of r){let y=await this.assignUiPort(m);y!=null?l.push({tag:`${m.name}/ui`,url:j({prefixUrl:"",alias:y.alias}),healthy:null}):u.push({tag:`${m.name}/ui`})}let d=this.options.watch??!1,v=e.length+r.length,p=S(this.monorepoRoot).length;this.renderer.ready({target:i,watch:d,hasUiChild:r.length>0,release:z(g.cwd()),elapsedMs:o,endpoints:[...a,...l],uiRefs:u,failed:this.failedApps.map(({app:m,reason:y})=>({tag:`${m.name}/api`,reason:y})),watchSummary:`${v} app${v===1?"":"s"} \xB7 ${p} package${p===1?"":"s"}`,logPath:Me(f),logHref:f})}async assignUiPort(e){if(!e.managedPort)return null;let r;try{r=await et()}catch{return null}let n=await this.registerAppAlias(e.packageName,e.path,r);return this.uiPortMap[e.packageName]={port:r,alias:n},{port:r,alias:n}}printRouteDump(){if(this.appServers.length!==0){this.renderer.log("\u{1F5FA}\uFE0F Registered routes:");for(let{app:e,server:r}of this.appServers){let n=r.getRegisteredRoutes();this.renderer.log(` ${e.name} (${n.length}): ${n.length>0?n.join(", "):"(none)"}`)}}}async shutdown(){this.shuttingDown=!0,this.renderer.dispose(),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&&(await this.watcher.close(),this.watcher=null),await this.restartWorkChain,await this.closureBuild,await Promise.all([...this.registeredAliases].map(e=>this.proxy.removeAlias(e))),this.registeredAliases.clear(),this.turboWatch&&(await this.turboWatch.kill(),this.turboWatch=null),this.uiDev&&(await this.uiDev.kill(),this.uiDev=null),this.uiLogStream&&(this.uiLogStream.end(),this.uiLogStream=null);for(let{app:e,server:r}of this.appServers){try{await r.close()}catch{}this.removeDevContextFragment(e)}this.renderer.log(`\u2713 dev stopped \xB7 logs \u2192 ${Me(f)}`)}},st=async t=>{if(!(t.tty??!!g.stdout.isTTY)||t.json)return;let{PersistentInkDevUi:r}=await import("./persistent-ink-dev-ui-FUJQDFNY.js");return new r({appendLog:We,verbose:t.verbose??!1})};async function Be(t={}){let e=await st(t),r=new q(t,void 0,void 0,void 0,void 0,e);try{await r.start()}catch(n){throw await r.shutdown().catch(()=>{}),n}return r}var pt=t=>{if(t!=null){for(let e of t)if(ne(e)!==null)throw new Error(`infra-kit dev: invalid --target "${e}" (expected "<app>/api" or "<app>/ui").`);return{apps:Object.fromEntries(t.map(e=>[e,{}]))}}},Ge=t=>{if(t==null)return null;let e=t.split(",").map(r=>r.trim()).filter(Boolean);return e.length>0?e:null},Ve=t=>({watch:t.watch??!1,include:Ge(t.app),preset:t.preset,presetDef:pt(Ge(t.target)),cmux:t.cmux??!1,self:t.self??!1,verbose:t.verbose??!1,routes:t.routes??!1}),ut=t=>!t.self||t.include?t:{...t,include:[ee(w.cwd())]},Y=async t=>{let e=ut(t);if(e.cmux){if(await ue()){await Se(e);return}w.stdout.write(`cmux not available; falling back to single-terminal dev
24
- `)}let r=await Be(e);xe(),$({onSignal:async n=>{w.stdout.write(`
25
+ ${J(["trust"],{bin:e})}
26
+ \`infra-kit doctor\` checks both.`)}async registerAppAlias(e,r,n){let i=se(r),o=kt(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 r=new B({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 d=`${e.name}/api`,u=`${o} ${s} ${a} ${l}ms`;this.sink.write(d,u,{level:a>=500?"error":"info"});let h=this.reqTimes.get(d);h?h.push(Date.now()):this.reqTimes.set(d,[Date.now()])}}),n=await r.start(),i;try{i=await this.registerAppAlias(e.packageName,e.path,n)}catch(o){throw await r.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:r,boundPort:n,alias:i}}writeDevContextFragment(e,r,n){let i={v:Rt,package:e.packageName,port:r,pid:v.pid,writtenAt:Date.now(),release:se(e.path),alias:n,origin:`https://${n}`},o=m.join(this.devContextDir,`${e.name}.json`),s=m.join(this.devContextDir,`${e.name}.json.${v.pid}.tmp`);f.mkdirSync(this.devContextDir,{recursive:!0}),f.writeFileSync(s,JSON.stringify(i,null,2)),f.renameSync(s,o)}removeDevContextFragment(e){f.rmSync(m.join(this.devContextDir,`${e.name}.json`),{force:!0})}scheduleRestartWork(e){let r=this.restartWorkChain.then(()=>e(),()=>e());return this.restartWorkChain=r.catch(()=>{}),r}async delayPortRelease(){await new Promise(e=>setTimeout(e,t.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(r=>({idx:this.appServers.findIndex(n=>n.app.name===r.name),app:r})).filter(r=>r.idx>=0)}async runRestart(e){let r=this.resolveRestartTargets(e);if(r.length===0)return;let n=r.length===1?r[0].app.name:`${r.length} apps`;this.renderer.log(`\u{1F504} Restarting ${n}...`),await Promise.all(r.map(async({idx:a})=>{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(r.map(async({idx:a,app:l})=>{try{let d=await this.startOneApp(l);if(d){let u=this.appServers[a],h={app:l,...d,startedAt:Date.now(),restarts:(u?.restarts??0)+1};return this.appServers[a]=h,{app:l,entry:h}}return{app:l,entry:null}}catch(d){return this.renderer.log(`\u274C Failed to restart ${l.name}: ${String(d)}`,"error"),{app:l,entry:null}}})),o=await Promise.all(i.map(async({app:a,entry:l})=>{let d=l?await this.healthProbe(t.healthUrl(l.boundPort)):!1;return{label:`${l?`${a.name}:${l.boundPort}`:a.name} ${d?"\u25CF up":"\u25CF down"}`,healthy:d}})),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 Ge(this.monorepoRoot,e,this.dryRunner)}catch(r){return this.renderer.log(`\u26A0\uFE0F Dependency-closure map unavailable (${String(r)}); package changes restart all apps`,"warn"),null}}reportEngineDeath(e,r,n){this.shuttingDown||this.renderer.log(`\u26A0\uFE0F ${e} ${n} \u2014 ${r}. Restart \`infra-kit dev\`.`,"warn")}setupWatch(e,r){this.turboWatch=this.turboWatchFactory({depInclusive:e.map(l=>l.packageName),depClosure:r.map(l=>l.packageName),cwd:v.cwd(),logFile:this.sink.pathFor(_t),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=v.env.DEV_SERVER_CHOKIDAR_POLL==="1",a=Tt.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,r,n,i){this.renderer.log(`\u{1F440} dist change detected: ${e}`,"debug");let o=he(e,n,i);if(o.kind==="package"){let a=Je(r,this.closureMap,o.packageDir);if(a===null){this.scheduleDebounced("__packages__",()=>this.restart(r));return}a.length>0&&o.packageDir!==void 0&&this.scheduleDebounced(Ve(o.packageDir),()=>this.restart(a));return}let s=r.find(a=>m.join(a.path,"dist")===o.app);s&&this.scheduleDebounced(s.name,()=>this.restart([s]))}scheduleDebounced(e,r){if(this.shuttingDown)return;let n=this.watchDebounceTimers.get(e);n&&clearTimeout(n);let i=setTimeout(()=>{this.watchDebounceTimers.delete(e),!this.shuttingDown&&r().catch(o=>{this.renderer.log(`Restart error (${e}): ${String(o)}`,"error")})},t.WATCH_DEBOUNCE_MS);this.watchDebounceTimers.set(e,i)}static healthUrl(e){return`http://127.0.0.1:${e}/__health`}startLivenessMonitor(){this.scheduleLivenessTick()}scheduleLivenessTick(){let e=this.options.livenessIntervalMs??t.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 r=Date.now(),n=new Map(this.appServers.map(i=>[`${i.app.name}/api`,i]));this.pruneRequestWindow(r),this.renderer.refresh?.({...e,sessionUptimeMs:r-this.readyAt,uiRefs:e.uiRefs.map(i=>({...i,errors:this.sink.statsFor(i.tag).errors})),endpoints:e.endpoints.map(i=>{let o=n.get(i.tag);return{...i,healthy:o?(this.livenessFailures.get(o.app.name)??0)===0:i.healthy,uptimeMs:o?r-o.startedAt:void 0,restarts:o?.restarts,rpm:(this.reqTimes.get(i.tag)??[]).length,errors:this.sink.statsFor(i.tag).errors}})})}pruneRequestWindow(e){let r=e-6e4;for(let[n,i]of this.reqTimes)this.reqTimes.set(n,i.filter(o=>o>r))}async livenessTick(){this.shuttingDown||(await Promise.all(this.appServers.map(async({app:e,boundPort:r})=>{let n=await this.healthProbe(t.healthUrl(r));if(this.shuttingDown)return;let i=this.livenessFailures.get(e.name)??0;if(n){i>=t.LIVENESS_FAILURE_THRESHOLD&&this.renderer.log(`\u2705 ${e.name}/api recovered`),this.livenessFailures.set(e.name,0);return}let o=i+1;this.livenessFailures.set(e.name,o),o===t.LIVENESS_FAILURE_THRESHOLD&&this.renderer.log(`\u26A0\uFE0F ${e.name}/api unhealthy (/__health not responding)`,"warn")})),this.refreshStatus())}async printReady(e,r,n,i){let o=Date.now()-n,s=await Promise.all(this.appServers.map(({boundPort:c})=>this.healthProbe(t.healthUrl(c)))),a=this.appServers.map(({app:c,alias:g},w)=>({tag:`${c.name}/api`,url:q({prefixUrl:c.prefixUrl,alias:g}),healthy:s[w]??null}));this.uiPortMap={};let l=[],d=[];for(let c of r){let g=await this.assignUiPort(c);g!=null?l.push({tag:`${c.name}/ui`,url:q({prefixUrl:"",alias:g.alias}),healthy:null}):d.push({tag:`${c.name}/ui`})}let u=this.options.watch??!1,h=e.length+r.length,p=L(this.monorepoRoot).length;this.intercept?.suppressTerminal(),this.lastSummary={target:i,watch:u,release:se(v.cwd()),elapsedMs:o,endpoints:[...a,...l],uiRefs:d,failed:this.failedApps.map(({app:c,reason:g})=>({tag:`${c.name}/api`,reason:g})),watchSummary:`${h} app${h===1?"":"s"} \xB7 ${p} package${p===1?"":"s"}`,logPath:oe(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 r;try{r=await Wt()}catch{return null}let n=await this.registerAppAlias(e.packageName,e.path,r);return this.uiPortMap[e.packageName]={port:r,alias:n},{port:r,alias:n}}printRouteDump(){if(this.appServers.length!==0){this.renderer.log("\u{1F5FA}\uFE0F Registered routes:");for(let{app:e,server:r}of this.appServers){let n=r.getRegisteredRoutes();this.renderer.log(` ${e.name} (${n.length}): ${n.length>0?n.join(", "):"(none)"}`)}}}reportFault(e){this.sink.write(re()??ae,e,{level:"error"}),this.renderer.log(e,"error")}async shutdown(){this.shuttingDown=!0,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&&(await this.watcher.close(),this.watcher=null),await this.restartWorkChain,await this.closureBuild,await Promise.all([...this.registeredAliases].map(e=>this.proxy.removeAlias(e))),this.registeredAliases.clear(),this.turboWatch&&(await this.turboWatch.kill(),this.turboWatch=null),this.uiDev&&(await this.uiDev.kill(),this.uiDev=null);for(let{app:e,server:r}of this.appServers){try{await r.close()}catch{}this.removeDevContextFragment(e)}this.intercept?.uninstall(),this.renderer.log(`\u2713 dev stopped \xB7 logs \u2192 ${oe(this.sink.dir)}`),this.sink.close()}},gr=t=>(t.tty??!!v.stdout.isTTY)&&!t.json,Qt=async t=>{if(!gr(t))return;let{PersistentInkDevUi:e}=await import("./persistent-ink-dev-ui-KOI44ZVT.js"),{createSafeStream:r}=await import("./safe-stderr-HXDR2DNJ.js");return new e({appendLog:hr,verbose:t.verbose??!1,stdout:r(Ye())})};async function fr(t={}){let e=await Qt(t),r=new le(t,void 0,void 0,void 0,void 0,e);try{await r.start()}catch(n){throw await r.shutdown().catch(()=>{}),n}return r}var rn=t=>{if(t!=null){for(let e of t)if(ge(e)!==null)throw new Error(`infra-kit dev: invalid --target "${e}" (expected "<app>/api" or "<app>/ui").`);return{apps:Object.fromEntries(t.map(e=>[e,{}]))}}},mr=t=>{if(t==null)return null;let e=t.split(",").map(r=>r.trim()).filter(Boolean);return e.length>0?e:null},vr=t=>({watch:t.watch??!1,include:mr(t.app),preset:t.preset,presetDef:rn(mr(t.target)),cmux:t.cmux??!1,self:t.self??!1,verbose:t.verbose??!1,routes:t.routes??!1}),tn=t=>!t.self||t.include?t:{...t,include:[ce(U.cwd())]},pe=async t=>{let e=tn(t);if(e.cmux){if(await Se()){await We(e);return}U.stdout.write(`cmux not available; falling back to single-terminal dev
27
+ `)}let r=await fr(e);He({onFault:(n,i)=>{r.reportFault(Z(n,i))}}),W({onSignal:async n=>{N(`
25
28
  Received ${n}, shutting down dev-server...
26
- `),await r.shutdown()}})},ct=(t,e,r)=>!t.preset&&!t.app&&!t.self&&!t.cmux&&!t.watch&&!t.verbose&&!t.routes&&e&&!r,dt=t=>({watch:t.watch,cmux:t.cmux,include:t.include??null,preset:t.preset,presetDef:t.presetDef,self:!1,verbose:!1,routes:!1}),Cn=async(t,e,r)=>{if(ct(t,e,r)){let{runDevWizard:n}=await import("./dev-wizard-run-TNA5YI7P.js"),i;try{i=await n()}catch(o){if(he(o))return;throw o}if(i==null)return;await Y({...dt(i),tty:e,json:r});return}await Y({...Ve(t),tty:e,json:r})},ht=async t=>{let e=new at;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(t),await Y(Ve({...e.opts(),preset:e.args[0]}))};import.meta.url===lt(w.argv[1]??"").href&&ht(w.argv).catch(t=>{console.error(t instanceof Error?t.message:String(t)),w.exit(1)});export{Y as runDevServer,Cn as runDevServerCli,ct as shouldRunWizard,Ve as toDevServerOptions};
29
+ `),await r.shutdown()}})},nn=(t,e,r)=>!t.preset&&!t.app&&!t.self&&!t.cmux&&!t.watch&&!t.verbose&&!t.routes&&e&&!r,on=t=>({watch:t.watch,cmux:t.cmux,include:t.include??null,preset:t.preset,presetDef:t.presetDef,self:!1,verbose:!1,routes:!1}),Ii=async(t,e,r)=>{if(nn(t,e,r)){let{runDevWizard:n}=await import("./dev-wizard-run-5HQOGE3R.js"),i;try{i=await n()}catch(o){if(Ae(o))return;throw o}if(i==null)return;await pe({...on(i),tty:e,json:r});return}await pe({...vr(t),tty:e,json:r})},sn=async t=>{let e=new Zt;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(t),await pe(vr({...e.opts(),preset:e.args[0]}))};import.meta.url===en(U.argv[1]??"").href&&sn(U.argv).catch(t=>{console.error(t instanceof Error?t.message:String(t)),U.exit(1)});export{pe as runDevServer,Ii as runDevServerCli,nn as shouldRunWizard,vr as toDevServerOptions};
27
30
  //# sourceMappingURL=dev-server.js.map