infra-kit 0.7.9 → 0.7.12

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,4 +1,4 @@
1
- import{a as Ue,b as L,c as M,d as Fe,e as H,k as Me,l as He,m as Be,p as je}from"./chunk-KXQQUBGV.js";import{$ as Ce,K as T,L as Ae,R as ne,U as C,V as U,W as Re,X as Ee,Y as F,Z as Te,_ as $,aa as $e,ba as Le,ca as Ne,da as Ie,ea as Oe,fa as _e}from"./chunk-63VNUKUS.js";import{c as te,k as re,o as ke,r as xe}from"./chunk-LDF2KOGN.js";import"./chunk-MFAFQVTW.js";import"./chunk-HHWP3YXW.js";import{d as Pe,f as ee,o as De}from"./chunk-NFIFWIO6.js";import{a as N,b as We}from"./chunk-VDBJ73LS.js";import{Command as Fn}from"commander";import P from"node:process";import{pathToFileURL as Mn}from"node:url";import*as Ve from"node:path";import qt from"node:process";var Jt=r=>({pane:{surfaces:[{type:"terminal",command:r}]}}),ie=(r,e)=>{if(r.length===1)return Jt(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:[ie(n,e+1),ie(i,e+1)]}},Ge=r=>{if(r.length===0)throw new Error("buildCmuxLayout: at least one command is required");return ie(r,0)};var zt=(r,e)=>r.map(({app:t,targets:n})=>`pnpm exec infra-kit dev ${n&&n.length>0?`--target=${n.join(",")}`:`--app=${t}`}${e?" --watch":""}`),Yt=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},Xt=(r,e)=>{let t=U(r);return e?t.filter(n=>e.includes(n.name)):t},Qt=(r,e)=>{T.info(`\u{1F9E9} Opened cmux dev workspace ${e} with ${r.length} pane(s):`);for(let t of r)T.info(` \u2022 ${t.name} (infra-kit dev --app=${t.name})`)},Zt=r=>{H({onSignal:async e=>{T.info(`
1
+ import{a as Ue,b as L,c as M,d as Fe,e as H,k as Me,l as He,m as Be,p as je}from"./chunk-T2WBH6YO.js";import{$ as Ce,K as T,L as Ae,R as ne,U as C,V as U,W as Re,X as Ee,Y as F,Z as Te,_ as $,aa as $e,ba as Le,ca as Ne,da as Ie,ea as Oe,fa as _e}from"./chunk-5FYZAIFC.js";import{c as te,k as re,o as ke,r as xe}from"./chunk-6OFUVD7F.js";import"./chunk-MFAFQVTW.js";import"./chunk-HHWP3YXW.js";import{d as Pe,f as ee,p as De}from"./chunk-75URROMU.js";import{a as N,b as We}from"./chunk-VDBJ73LS.js";import{Command as Fn}from"commander";import P from"node:process";import{pathToFileURL as Mn}from"node:url";import*as Ve from"node:path";import qt from"node:process";var Jt=r=>({pane:{surfaces:[{type:"terminal",command:r}]}}),ie=(r,e)=>{if(r.length===1)return Jt(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:[ie(n,e+1),ie(i,e+1)]}},Ge=r=>{if(r.length===0)throw new Error("buildCmuxLayout: at least one command is required");return ie(r,0)};var zt=(r,e)=>r.map(({app:t,targets:n})=>`pnpm exec infra-kit dev ${n&&n.length>0?`--target=${n.join(",")}`:`--app=${t}`}${e?" --watch":""}`),Yt=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},Xt=(r,e)=>{let t=U(r);return e?t.filter(n=>e.includes(n.name)):t},Qt=(r,e)=>{T.info(`\u{1F9E9} Opened cmux dev workspace ${e} with ${r.length} pane(s):`);for(let t of r)T.info(` \u2022 ${t.name} (infra-kit dev --app=${t.name})`)},Zt=r=>{H({onSignal:async e=>{T.info(`
2
2
  Received ${e}, closing cmux dev workspace ${r}...`),await Be(r)}})},Ke=async r=>{let e=C(qt.cwd()),t=Xt(e,F(r.include));if(t.length===0){T.warn("No API apps found to run");return}let n=Yt(r.presetDef),i=zt(t.map(u=>({app:u.name,targets:n.get(u.name)})),r.watch??!1),s=Ge(i),o=`${Ve.basename(e)} dev`,a=await He({cwd:e,title:o,layout:s});Qt(t,a),Zt(a);let l=setInterval(()=>{l.refresh()},2**30);await new Promise(()=>{})};import se from"node:process";var oe=r=>{try{se.stderr.write(r)}catch{}},I=(r,e,t=!0)=>{let n=e instanceof Error?`${e.message}
3
3
  ${e.stack??"(no stack)"}`:String(e);return`
4
4
  \u26A0\uFE0F ${r}: ${n}
@@ -34,5 +34,5 @@ Reinstalling restarts it (still the only step that needs root):
34
34
  `);let l=n(()=>{e(),t(we)},i);a.shutdown().finally(()=>{l(),t(we)}).catch(()=>{})}},Vn=["SIGINT","SIGTERM"],Kn=({forceReap:r=L,exit:e=i=>{P.exit(i)},register:t=(i,s)=>{P.on(i,s)},unregister:n=(i,s)=>{P.off(i,s)}}={})=>{let i=new Map;for(let s of Vn){let o=()=>{Vt(r,e,Fe(s))};i.set(s,o),t(s,o)}return{remove:()=>{for(let[s,o]of i)n(s,o)}}},be=async r=>{let e=jn(r);if(e.cmux){if(await Me()){await Ke(e);return}P.stdout.write(`cmux not available; falling back to single-terminal dev
35
35
  `)}let t=null,n=Wn(),i=Gn({getRunner:()=>t,setTimer:n}),s=ot({onDeath:(l,u)=>{i(`stdio unwritable: ${l} ${u.code}`)}}),o=Kn();try{t=await Bt({...e,onExitRequest:l=>{P.exit(l)}})}finally{o.remove()}let a=t;Je({onFault:(l,u)=>{a.reportFault(I(l,u))},isTerminalDead:s.isDead,fileFault:(l,u)=>{a.fileFault(I(l,u,!1))},onFatal:i}),H({onSignal:async l=>{le(`
36
36
  Received ${l}, shutting down dev-server...
37
- `),await a.shutdown()},describeStall:()=>a.shutdownStage,fileReport:l=>{a.fileFault(l)},setTimer:n})},Jn=(r,e,t)=>!r.preset&&!r.app&&!r.self&&!r.cmux&&!r.watch&&!r.verbose&&!r.routes&&e&&!t,qn=(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}),Is=async(r,e,t)=>{if(Jn(r,e,t)){let{runDevWizard:n}=await import("./dev-wizard-run-MCUYV6IN.js"),i=Promise.all([import("./persistent-ink-dev-ui-P65EJCC6.js"),import("./safe-stderr-ECYA6DRR.js")]).catch(()=>{}),s;try{s=await n()}catch(o){if(je(o))return;throw o}if(s==null)return;await i,await be({...qn(s,r),tty:e,json:t});return}await be({...Wt(r),tty:e,json:t})},zn=async r=>{let e=new Fn;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 be(Wt({...e.opts(),preset:e.args[0]}))};import.meta.url===Mn(P.argv[1]??"").href&&zn(P.argv).catch(r=>{console.error(r instanceof Error?r.message:String(r)),P.exit(1)});export{Gn as createFatalHandler,Wn as createSharedDeadlineTimer,Kn as installBootSignalGuard,be as runDevServer,Is as runDevServerCli,Jn as shouldRunWizard,Wt as toDevServerOptions};
37
+ `),await a.shutdown()},describeStall:()=>a.shutdownStage,fileReport:l=>{a.fileFault(l)},setTimer:n})},Jn=(r,e,t)=>!r.preset&&!r.app&&!r.self&&!r.cmux&&!r.watch&&!r.verbose&&!r.routes&&e&&!t,qn=(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}),Is=async(r,e,t)=>{if(Jn(r,e,t)){let{runDevWizard:n}=await import("./dev-wizard-run-DRBMPH2O.js"),i=Promise.all([import("./persistent-ink-dev-ui-P65EJCC6.js"),import("./safe-stderr-ECYA6DRR.js")]).catch(()=>{}),s;try{s=await n()}catch(o){if(je(o))return;throw o}if(s==null)return;await i,await be({...qn(s,r),tty:e,json:t});return}await be({...Wt(r),tty:e,json:t})},zn=async r=>{let e=new Fn;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 be(Wt({...e.opts(),preset:e.args[0]}))};import.meta.url===Mn(P.argv[1]??"").href&&zn(P.argv).catch(r=>{console.error(r instanceof Error?r.message:String(r)),P.exit(1)});export{Gn as createFatalHandler,Wn as createSharedDeadlineTimer,Kn as installBootSignalGuard,be as runDevServer,Is as runDevServerCli,Jn as shouldRunWizard,Wt as toDevServerOptions};
38
38
  //# sourceMappingURL=dev-server.js.map
@@ -1,2 +1,2 @@
1
- import{f as C,i as f,k as g}from"./chunk-YKCY657C.js";import{K as u,R as y,U as k,V as x,X as v,fa as w}from"./chunk-63VNUKUS.js";import"./chunk-MFAFQVTW.js";import{f as b}from"./chunk-NFIFWIO6.js";import"./chunk-QWVLAZ6N.js";import O from"@inquirer/checkbox";import _ from"@inquirer/confirm";import j,{Separator as I}from"@inquirer/select";import{loadDev as K}from"@slip-stream-kit/config/internal";import U from"node:path";import m from"node:process";var W=e=>e.split("/")[0],A=e=>new Map(e.apps.map(r=>[r.name,r])),D=e=>e.localCapable&&e.cloudCapable,N=(e,r,t)=>D(r)?t[`${e} ${r.path}`]??(r.cloudCapable?"cloud":"local"):r.localCapable?"local":"cloud",$=(e,r,t)=>{let a=new Set,o=new Map;for(let n of e){let s=r.get(W(n));for(let c of s?.backends??[]){o.set(c.packageName,c.ownerApp);for(let l of c.routes)N(n,l,t)==="local"&&a.add(c.packageName)}}return{localPkgs:a,ownerByPkg:o}},B=(e,r)=>{let t={},a=!1;for(let o of e?.backends??[]){let n=r.has(o.packageName);for(let s of o.routes){let c=s.localCapable&&n?"local":"cloud";t[s.path]=c,c==="cloud"&&(a=!0)}}return{overrides:t,anyCloud:a}},z=(e,r)=>{let t=A(r),a=e.targets.filter(p=>p.endsWith("/ui")),o=e.targets.filter(p=>p.endsWith("/api")),{localPkgs:n,ownerByPkg:s}=$(a,t,e.sources),c={},l=!1;for(let p of a){let{overrides:d,anyCloud:i}=B(t.get(W(p)),n);i&&(l=!0),c[p]=Object.keys(d).length>0?{proxy:d}:{}}for(let p of o)c[p]??={};for(let p of n){let d=s.get(p);d!=null&&(c[`${d}/api`]??={})}return{presetDef:{apps:c,cmux:e.cmux},anyCloudRoute:l,targetKeys:Object.keys(c).sort()}},M=(e,r)=>{let t=[`--target=${e.targetKeys.join(",")}`];return r.watch&&t.push("--watch"),r.cmux&&t.push("--cmux"),{flags:t.join(" ")}};var h={output:m.stderr,clearPromptOnDone:!0},q={select:e=>g(r=>j({message:e.message,choices:e.choices,default:e.default},r),h),checkbox:e=>g(r=>O({message:e.message,choices:e.choices},r),h),confirm:e=>g(r=>_({message:e.message,default:e.default},r),h)},E=(e,r)=>{let t=new Map;for(let[a,o]of Object.entries(e)){let n={path:a,localCapable:o.from.includes("local"),cloudCapable:o.from.includes("cloud"),default:o.default},s=t.get(o.packageName);s?(s.routes.push(n),s.localCapable=s.localCapable||n.localCapable,s.cloudCapable=s.cloudCapable||n.cloudCapable):t.set(o.packageName,{packageName:o.packageName,routes:[n],localCapable:n.localCapable,cloudCapable:n.cloudCapable,ownerApp:r.get(o.packageName)})}return[...t.values()]},T=async(e,r,t)=>{try{let a=(await K(e))?.proxy?.routes;return a?E(a,t):[]}catch(a){return u.warn(`\u26A0\uFE0F Skipping ${r}: its dev config failed to load \u2014 ${a instanceof Error?a.message:String(a)}`),[]}},V=async e=>{let r=x(e),t=v(e),a=await y(),o=new Map(r.map(i=>[i.packageName,i.name])),n=new Map(r.map(i=>[i.name,i.packageName])),s=new Set(t.map(i=>i.name)),c=new Set(r.map(i=>i.name)),l=[...new Set([...c,...s])].sort(),p=await Promise.all(l.map(async i=>{let P=s.has(i);return{name:i,hasApi:c.has(i),hasUi:P,apiPackage:n.get(i),backends:P?await T(U.join(e,"apps",i,"ui"),i,o):[]}})),d=await C();return{apps:p,presets:Object.keys(a.devServersPresets??{}),environments:Object.keys(d?.envs??{}).sort()}},F=e=>{let r=[];for(let t of e.apps){if(t.hasUi){let a=t.backends.flatMap(n=>n.routes.map(s=>s.path)),o=a.length>0?`frontend \u2014 proxies ${[...a].sort().join(", ")}`:"frontend";r.push({name:`${t.name}/ui`,value:`${t.name}/ui`,description:o})}t.hasApi&&!t.hasUi&&r.push({name:`${t.name}/api`,value:`${t.name}/api`,description:"backend"})}return r},L=e=>{let r={api:e.apps.filter(o=>o.hasApi).map(o=>o.name),ui:e.apps.filter(o=>o.hasUi).map(o=>o.name)},t={},a=new Map;for(let o of e.apps){o.apiPackage!=null&&(t[o.name]=o.apiPackage);for(let n of o.backends)for(let s of n.routes)a.set(`${o.name} ${s.path}`,n.packageName)}return{discovered:r,apiPkgByApp:t,routePkg:(o,n)=>a.get(`${o} ${n}`)}},X=(e,r)=>w({__wizard__:e},L(r)).map(t=>t.message),Z="INFRA_KIT_DEV_WIZARD_CMUX",H=()=>m.env[Z]==="1",G=async(e,r,t)=>{let a=new Map(r.apps.map(n=>[n.name,n])),o={};for(let n of t){let s=a.get(n.split("/")[0]);for(let c of s?.backends??[])for(let l of c.routes){if(!l.localCapable||!l.cloudCapable)continue;let p=await e.select({message:`\u{1F500} ${n} ${l.path} \u2192 local or cloud?`,choices:[{name:"local (this machine)",value:"local"},{name:"cloud",value:"cloud"}],default:l.default??"local"});o[`${n} ${l.path}`]=p}}return o},J=(e,r,t)=>e.apps.find(a=>a.name===r)?.backends.flatMap(a=>a.routes).find(a=>a.path===t),Q=(e,r)=>{let t=[];for(let[a,o]of Object.entries(e.presetDef.apps??{})){if(!a.endsWith("/ui")||!o.proxy)continue;let n=a.split("/")[0];for(let[s,c]of Object.entries(o.proxy)){let l=J(r,n,s),p=l&&l.localCapable&&l.cloudCapable?"":" (only option)";t.push(` ${a} ${s} \u2192 ${c}${p}`)}}if(t.length!==0){u.info("Resolved routes:");for(let a of[...t].sort())u.info(a)}},R=async(e,r)=>{if(r.apps.length===0)return u.warn("No apps discovered to run."),null;let t=await e.checkbox({message:"\u{1F4E6} Which packages?",choices:F(r)});if(t.length===0)return u.warn("No packages selected."),null;let a=t.filter(i=>i.endsWith("/ui")),o=await G(e,r,a),n=await e.confirm({message:"\u{1F440} Rebuild & restart on save (watch)?",default:!1}),s=H()?await e.confirm({message:"\u{1F9E9} Run each app in its own cmux pane?",default:!1}):!1,c={targets:t,sources:o,watch:n,cmux:s},l=z(c,r);if(l.anyCloudRoute){if(r.environments.length===0)return u.warn("\u2601\uFE0F This selection routes to a cloud environment, but no environment token is loaded."),u.warn(" Run `infra-kit env-load` to add one, then re-run the wizard."),null;c.env=await e.select({message:"\u2601\uFE0F Point cloud routes at which environment?",choices:r.environments.map(i=>({name:i,value:i}))}),m.env[b]=c.env}let p=X(l.presetDef,r);if(p.length>0){u.warn("\u26A0\uFE0F Proxy audit found issues with this selection:");for(let i of p)u.warn(` \u2022 ${i}`);return null}Q(l,r),Y(l,c);let d=l.targetKeys.filter(i=>i.endsWith("/api")).map(i=>i.split("/")[0]);return s&&d.length>0?{include:d,presetDef:l.presetDef,watch:n,cmux:!0}:(s&&u.info("\u2139\uFE0F cmux needs at least one local backend (panes are backend-only) \u2014 running in-process instead."),{presetDef:l.presetDef,watch:n,cmux:!1})},Y=(e,r)=>{f.setInteractive();let t=M(e,r);f.addOption(t.flags,!0),f.print(),u.info("\u2139\uFE0F Prefer a short name? Save this selection as a devPreset and run `infra-kit dev <name>`.")},ee=async(e,r)=>{let t=await e.confirm({message:"\u{1F440} Rebuild & restart on save (watch)?",default:!1});return f.setInteractive(),f.addOption(r,!0),t&&f.addOption("--watch",!0),f.print(),{preset:r,watch:t,cmux:!1}},S=" manual",re=async(e,r)=>{if(r.presets.length===0)return R(e,r);let t=await e.select({message:"\u{1F680} Start from a preset, or configure manually?",choices:[...r.presets.map(a=>({name:a,value:a})),new I(" "),{name:"Manual (custom)\u2026",value:S}]});return t===S?R(e,r):ee(e,t)},be=async(e=q,r=k(m.cwd()))=>re(e,await V(r));export{S as MANUAL_CHOICE,Z as WIZARD_CMUX_VAR,X as auditManualPlan,q as defaultPrompts,V as gatherWizardModel,T as loadBackends,be as runDevWizard,re as runWizardFlow};
2
- //# sourceMappingURL=dev-wizard-run-MCUYV6IN.js.map
1
+ import{f as C,i as f,k as g}from"./chunk-GFKYWEPW.js";import{K as u,R as y,U as k,V as x,X as v,fa as w}from"./chunk-5FYZAIFC.js";import"./chunk-MFAFQVTW.js";import{f as b}from"./chunk-75URROMU.js";import"./chunk-QWVLAZ6N.js";import O from"@inquirer/checkbox";import _ from"@inquirer/confirm";import j,{Separator as I}from"@inquirer/select";import{loadDev as K}from"@slip-stream-kit/config/internal";import U from"node:path";import m from"node:process";var W=e=>e.split("/")[0],A=e=>new Map(e.apps.map(r=>[r.name,r])),D=e=>e.localCapable&&e.cloudCapable,N=(e,r,t)=>D(r)?t[`${e} ${r.path}`]??(r.cloudCapable?"cloud":"local"):r.localCapable?"local":"cloud",$=(e,r,t)=>{let a=new Set,o=new Map;for(let n of e){let s=r.get(W(n));for(let c of s?.backends??[]){o.set(c.packageName,c.ownerApp);for(let l of c.routes)N(n,l,t)==="local"&&a.add(c.packageName)}}return{localPkgs:a,ownerByPkg:o}},B=(e,r)=>{let t={},a=!1;for(let o of e?.backends??[]){let n=r.has(o.packageName);for(let s of o.routes){let c=s.localCapable&&n?"local":"cloud";t[s.path]=c,c==="cloud"&&(a=!0)}}return{overrides:t,anyCloud:a}},z=(e,r)=>{let t=A(r),a=e.targets.filter(p=>p.endsWith("/ui")),o=e.targets.filter(p=>p.endsWith("/api")),{localPkgs:n,ownerByPkg:s}=$(a,t,e.sources),c={},l=!1;for(let p of a){let{overrides:d,anyCloud:i}=B(t.get(W(p)),n);i&&(l=!0),c[p]=Object.keys(d).length>0?{proxy:d}:{}}for(let p of o)c[p]??={};for(let p of n){let d=s.get(p);d!=null&&(c[`${d}/api`]??={})}return{presetDef:{apps:c,cmux:e.cmux},anyCloudRoute:l,targetKeys:Object.keys(c).sort()}},M=(e,r)=>{let t=[`--target=${e.targetKeys.join(",")}`];return r.watch&&t.push("--watch"),r.cmux&&t.push("--cmux"),{flags:t.join(" ")}};var h={output:m.stderr,clearPromptOnDone:!0},q={select:e=>g(r=>j({message:e.message,choices:e.choices,default:e.default},r),h),checkbox:e=>g(r=>O({message:e.message,choices:e.choices},r),h),confirm:e=>g(r=>_({message:e.message,default:e.default},r),h)},E=(e,r)=>{let t=new Map;for(let[a,o]of Object.entries(e)){let n={path:a,localCapable:o.from.includes("local"),cloudCapable:o.from.includes("cloud"),default:o.default},s=t.get(o.packageName);s?(s.routes.push(n),s.localCapable=s.localCapable||n.localCapable,s.cloudCapable=s.cloudCapable||n.cloudCapable):t.set(o.packageName,{packageName:o.packageName,routes:[n],localCapable:n.localCapable,cloudCapable:n.cloudCapable,ownerApp:r.get(o.packageName)})}return[...t.values()]},T=async(e,r,t)=>{try{let a=(await K(e))?.proxy?.routes;return a?E(a,t):[]}catch(a){return u.warn(`\u26A0\uFE0F Skipping ${r}: its dev config failed to load \u2014 ${a instanceof Error?a.message:String(a)}`),[]}},V=async e=>{let r=x(e),t=v(e),a=await y(),o=new Map(r.map(i=>[i.packageName,i.name])),n=new Map(r.map(i=>[i.name,i.packageName])),s=new Set(t.map(i=>i.name)),c=new Set(r.map(i=>i.name)),l=[...new Set([...c,...s])].sort(),p=await Promise.all(l.map(async i=>{let P=s.has(i);return{name:i,hasApi:c.has(i),hasUi:P,apiPackage:n.get(i),backends:P?await T(U.join(e,"apps",i,"ui"),i,o):[]}})),d=await C();return{apps:p,presets:Object.keys(a.devServersPresets??{}),environments:Object.keys(d?.envs??{}).sort()}},F=e=>{let r=[];for(let t of e.apps){if(t.hasUi){let a=t.backends.flatMap(n=>n.routes.map(s=>s.path)),o=a.length>0?`frontend \u2014 proxies ${[...a].sort().join(", ")}`:"frontend";r.push({name:`${t.name}/ui`,value:`${t.name}/ui`,description:o})}t.hasApi&&!t.hasUi&&r.push({name:`${t.name}/api`,value:`${t.name}/api`,description:"backend"})}return r},L=e=>{let r={api:e.apps.filter(o=>o.hasApi).map(o=>o.name),ui:e.apps.filter(o=>o.hasUi).map(o=>o.name)},t={},a=new Map;for(let o of e.apps){o.apiPackage!=null&&(t[o.name]=o.apiPackage);for(let n of o.backends)for(let s of n.routes)a.set(`${o.name} ${s.path}`,n.packageName)}return{discovered:r,apiPkgByApp:t,routePkg:(o,n)=>a.get(`${o} ${n}`)}},X=(e,r)=>w({__wizard__:e},L(r)).map(t=>t.message),Z="INFRA_KIT_DEV_WIZARD_CMUX",H=()=>m.env[Z]==="1",G=async(e,r,t)=>{let a=new Map(r.apps.map(n=>[n.name,n])),o={};for(let n of t){let s=a.get(n.split("/")[0]);for(let c of s?.backends??[])for(let l of c.routes){if(!l.localCapable||!l.cloudCapable)continue;let p=await e.select({message:`\u{1F500} ${n} ${l.path} \u2192 local or cloud?`,choices:[{name:"local (this machine)",value:"local"},{name:"cloud",value:"cloud"}],default:l.default??"local"});o[`${n} ${l.path}`]=p}}return o},J=(e,r,t)=>e.apps.find(a=>a.name===r)?.backends.flatMap(a=>a.routes).find(a=>a.path===t),Q=(e,r)=>{let t=[];for(let[a,o]of Object.entries(e.presetDef.apps??{})){if(!a.endsWith("/ui")||!o.proxy)continue;let n=a.split("/")[0];for(let[s,c]of Object.entries(o.proxy)){let l=J(r,n,s),p=l&&l.localCapable&&l.cloudCapable?"":" (only option)";t.push(` ${a} ${s} \u2192 ${c}${p}`)}}if(t.length!==0){u.info("Resolved routes:");for(let a of[...t].sort())u.info(a)}},R=async(e,r)=>{if(r.apps.length===0)return u.warn("No apps discovered to run."),null;let t=await e.checkbox({message:"\u{1F4E6} Which packages?",choices:F(r)});if(t.length===0)return u.warn("No packages selected."),null;let a=t.filter(i=>i.endsWith("/ui")),o=await G(e,r,a),n=await e.confirm({message:"\u{1F440} Rebuild & restart on save (watch)?",default:!1}),s=H()?await e.confirm({message:"\u{1F9E9} Run each app in its own cmux pane?",default:!1}):!1,c={targets:t,sources:o,watch:n,cmux:s},l=z(c,r);if(l.anyCloudRoute){if(r.environments.length===0)return u.warn("\u2601\uFE0F This selection routes to a cloud environment, but no environment token is loaded."),u.warn(" Run `infra-kit env-load` to add one, then re-run the wizard."),null;c.env=await e.select({message:"\u2601\uFE0F Point cloud routes at which environment?",choices:r.environments.map(i=>({name:i,value:i}))}),m.env[b]=c.env}let p=X(l.presetDef,r);if(p.length>0){u.warn("\u26A0\uFE0F Proxy audit found issues with this selection:");for(let i of p)u.warn(` \u2022 ${i}`);return null}Q(l,r),Y(l,c);let d=l.targetKeys.filter(i=>i.endsWith("/api")).map(i=>i.split("/")[0]);return s&&d.length>0?{include:d,presetDef:l.presetDef,watch:n,cmux:!0}:(s&&u.info("\u2139\uFE0F cmux needs at least one local backend (panes are backend-only) \u2014 running in-process instead."),{presetDef:l.presetDef,watch:n,cmux:!1})},Y=(e,r)=>{f.setInteractive();let t=M(e,r);f.addOption(t.flags,!0),f.print(),u.info("\u2139\uFE0F Prefer a short name? Save this selection as a devPreset and run `infra-kit dev <name>`.")},ee=async(e,r)=>{let t=await e.confirm({message:"\u{1F440} Rebuild & restart on save (watch)?",default:!1});return f.setInteractive(),f.addOption(r,!0),t&&f.addOption("--watch",!0),f.print(),{preset:r,watch:t,cmux:!1}},S=" manual",re=async(e,r)=>{if(r.presets.length===0)return R(e,r);let t=await e.select({message:"\u{1F680} Start from a preset, or configure manually?",choices:[...r.presets.map(a=>({name:a,value:a})),new I(" "),{name:"Manual (custom)\u2026",value:S}]});return t===S?R(e,r):ee(e,t)},be=async(e=q,r=k(m.cwd()))=>re(e,await V(r));export{S as MANUAL_CHOICE,Z as WIZARD_CMUX_VAR,X as auditManualPlan,q as defaultPrompts,V as gatherWizardModel,T as loadBackends,be as runDevWizard,re as runWizardFlow};
2
+ //# sourceMappingURL=dev-wizard-run-DRBMPH2O.js.map
package/dist/mcp-proxy.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{u as G}from"./chunk-LDF2KOGN.js";import{a as M}from"./chunk-MFAFQVTW.js";import"./chunk-HHWP3YXW.js";import{a as W,d as H,n as T,o as E,s as K}from"./chunk-NFIFWIO6.js";import m from"node:process";var ve=/^[a-z][a-z0-9-]*$/,ye=/^[A-Z_]\w*$/i,Pe=(e,n,r)=>n==="--name"?e.name!==null?"--name given twice":ve.test(r)?(e.name=r,null):`--name "${r}" must be lowercase letters, digits and hyphens`:n==="--env"||n==="--unset"?ye.test(r)?M.has(r)?`${n} "${r}" is process plumbing, not a credential`:(n==="--env"?e.env.push(r):e.unset.push(r),null):`${n} "${r}" is not an environment-variable name`:`unknown flag ${n}`,Se=(e,n)=>{let r=0;for(;r<e.length;){let o=e[r];if(o==="--")return{separator:r};if(!o.startsWith("--"))return{problem:`missing "--" before the upstream command (saw "${o}")`};let a=e[r+1];if(a===void 0||a.startsWith("--"))return{problem:`${o} needs a value`};let p=Pe(n,o,a);if(p!==null)return{problem:p};r+=2}return{problem:'missing "--" before the upstream command'}},Q=e=>{let n={name:null,env:[],unset:[]},r=Se(e,n);if("problem"in r)return{ok:!1,problem:r.problem};if(n.name===null)return{ok:!1,problem:"missing --name"};if(n.env.length===0)return{ok:!1,problem:"missing --env (at least one variable to read)"};let o=e[r.separator+1];return o===void 0||o.length===0?{ok:!1,problem:'missing upstream command after "--"'}:{ok:!0,spec:{name:n.name,command:o,args:e.slice(r.separator+2),env:n.env,unset:n.unset}}};import{spawnSync as xe}from"node:child_process";import C from"node:fs";import x from"node:path";import O from"node:process";var Y=e=>x.join(E(),"mcp-proxy",e),be=e=>e.replaceAll(/[^\w.-]/g,"_").slice(0,64),Z=(e,n)=>x.join(n,`profile-${be(e)}.json`),A=(e,n)=>{let r=x.isAbsolute(e)?[e]:(n??O.env.PATH??"").split(x.delimiter).map(o=>x.join(o,e));for(let o of r)try{let a=C.statSync(o);return`stat-${a.size}-${Math.trunc(a.mtimeMs)}`}catch{}return"unknown"},X=(e,n=["--version"],r)=>{try{let o=xe(e,[...n],{encoding:"utf8",timeout:5e3,env:r==null?O.env:{...O.env,PATH:r}});if(o.status!==0)return A(e,r);let a=`${o.stdout}`.trim().split(`
2
+ import{u as G}from"./chunk-6OFUVD7F.js";import{a as M}from"./chunk-MFAFQVTW.js";import"./chunk-HHWP3YXW.js";import{a as W,d as H,n as T,p as E,t as K}from"./chunk-75URROMU.js";import m from"node:process";var ve=/^[a-z][a-z0-9-]*$/,ye=/^[A-Z_]\w*$/i,Pe=(e,n,r)=>n==="--name"?e.name!==null?"--name given twice":ve.test(r)?(e.name=r,null):`--name "${r}" must be lowercase letters, digits and hyphens`:n==="--env"||n==="--unset"?ye.test(r)?M.has(r)?`${n} "${r}" is process plumbing, not a credential`:(n==="--env"?e.env.push(r):e.unset.push(r),null):`${n} "${r}" is not an environment-variable name`:`unknown flag ${n}`,Se=(e,n)=>{let r=0;for(;r<e.length;){let o=e[r];if(o==="--")return{separator:r};if(!o.startsWith("--"))return{problem:`missing "--" before the upstream command (saw "${o}")`};let a=e[r+1];if(a===void 0||a.startsWith("--"))return{problem:`${o} needs a value`};let p=Pe(n,o,a);if(p!==null)return{problem:p};r+=2}return{problem:'missing "--" before the upstream command'}},Q=e=>{let n={name:null,env:[],unset:[]},r=Se(e,n);if("problem"in r)return{ok:!1,problem:r.problem};if(n.name===null)return{ok:!1,problem:"missing --name"};if(n.env.length===0)return{ok:!1,problem:"missing --env (at least one variable to read)"};let o=e[r.separator+1];return o===void 0||o.length===0?{ok:!1,problem:'missing upstream command after "--"'}:{ok:!0,spec:{name:n.name,command:o,args:e.slice(r.separator+2),env:n.env,unset:n.unset}}};import{spawnSync as xe}from"node:child_process";import C from"node:fs";import x from"node:path";import O from"node:process";var Y=e=>x.join(E(),"mcp-proxy",e),be=e=>e.replaceAll(/[^\w.-]/g,"_").slice(0,64),Z=(e,n)=>x.join(n,`profile-${be(e)}.json`),A=(e,n)=>{let r=x.isAbsolute(e)?[e]:(n??O.env.PATH??"").split(x.delimiter).map(o=>x.join(o,e));for(let o of r)try{let a=C.statSync(o);return`stat-${a.size}-${Math.trunc(a.mtimeMs)}`}catch{}return"unknown"},X=(e,n=["--version"],r)=>{try{let o=xe(e,[...n],{encoding:"utf8",timeout:5e3,env:r==null?O.env:{...O.env,PATH:r}});if(o.status!==0)return A(e,r);let a=`${o.stdout}`.trim().split(`
3
3
  `)[0]?.trim()??"";return a.length>0?a:A(e,r)}catch{return A(e,r)}},ee=(e,n)=>{try{let r=JSON.parse(C.readFileSync(Z(e,n),"utf8"));return r.version!==e||!Array.isArray(r.tools)?null:{version:e,protocolVersion:typeof r.protocolVersion=="string"?r.protocolVersion:"",capabilities:r.capabilities??{},tools:r.tools}}catch{return null}},re=(e,n)=>{try{return C.mkdirSync(n,{recursive:!0}),K(Z(e.version,n),`${JSON.stringify(e)}
4
4
  `,384),!0}catch{return!1}};import we from"node:path";import L from"node:process";var Ee="no-session",Me="IK_MCP_ENV_FILE",Re=()=>{let e=L.env[H];return e!=null&&e.length>0?e:Ee},R=()=>{let e=L.env[Me];return e!=null&&e.length>0?e:we.join(E(),Re(),W)},$e=(e,n)=>{let r=e[n];if(r!=null&&r.length>0)return r;let o=L.env[n];return o!=null&&o.length>0?o:""},ne=(e,n=R())=>{let r=T(n),o={};for(let a of e){let p=$e(r,a);if(p.length===0)return null;o[a]=p}return o},te=(e,n=R())=>{let r=new Set(e);return Object.keys(T(n)).filter(o=>!r.has(o))};var $=(e,n)=>{let r="";e.setEncoding("utf8"),e.on("data",o=>{r+=o;let a=r.indexOf(`
5
5
  `);for(;a!==-1;){let p=r.slice(0,a);r=r.slice(a+1);let f=p.endsWith("\r")?p.slice(0,-1):p;f.trim().length>0&&n(f),a=r.indexOf(`
package/dist/mcp.js CHANGED
@@ -1,3 +1,3 @@
1
- import{W as M,a as F,d as h,ha as $,ka as j,t as _}from"./chunk-MFNMFVI6.js";import{i as O}from"./chunk-YKCY657C.js";import"./chunk-KXQQUBGV.js";import{I as w,J as E,K as s,R as N,c as A}from"./chunk-63VNUKUS.js";import"./chunk-LDF2KOGN.js";import"./chunk-MFAFQVTW.js";import{l as I}from"./chunk-DFZ5WUIM.js";import"./chunk-HHWP3YXW.js";import"./chunk-NFIFWIO6.js";import"./chunk-QWVLAZ6N.js";import{serveStdio as Ge}from"@modelcontextprotocol/server/stdio";import g from"node:process";import{setTimeout as Ue}from"node:timers/promises";import f from"node:process";var q=e=>{f.on("uncaughtException",o=>{e.fatal({err:o,msg:"Uncaught Exception"}),e.error(`Uncaught Exception! Check ${w}. Shutting down...`),e.flush(),f.exit(1)}),f.on("unhandledRejection",(o,r)=>{e.fatal({reason:o,promise:r,msg:"Unhandled Rejection"}),e.error(`Unhandled Rejection! Check ${w}. Shutting down...`),e.flush(),f.exit(1)})};import{McpServer as qe}from"@modelcontextprotocol/server";var ae="infra-kit://config",ce="infra-kit://dev-context",ue="infra-kit://workflow/session",de=["This procedure moved to the `/infra-kit:session` skill; update the plugin.","Meanwhile: no token \u2192 call `env-load` without `config`; the human's pick is the load.","On a tool error or a refused result naming `config`, call `env-list` and list every row in prose, then ask."].join(`
2
- `),me={loadConfig:N,readDevContext:()=>h()},R=(e,o)=>({contents:[{uri:e,mimeType:"application/json",text:JSON.stringify(o,null,2)}]}),G=async(e,o=me)=>{e.registerResource("infra-kit-config",ae,{title:"infra-kit config",description:"The merged infra-kit.json configuration (all override layers applied). Read-only.",mimeType:"application/json"},async r=>{try{return R(r.toString(),await o.loadConfig())}catch(n){return R(r.toString(),{error:n instanceof Error?n.message:String(n)})}}),e.registerResource("infra-kit-dev-context",ce,{title:"infra-kit dev context",description:"What `infra-kit dev` last wrote: backends currently up, their ports/origins, and fragment freshness. Read-only and advisory (no liveness probe). No active session resolves to an empty payload.",mimeType:"application/json"},r=>R(r.toString(),o.readDevContext())),e.registerResource("infra-kit-workflow-session",ue,{title:"session procedure (moved)",description:"Retired: the session procedure now lives in the /infra-kit:session plugin skill. Update the plugin.",mimeType:"text/markdown"},r=>({contents:[{uri:r.toString(),mimeType:"text/markdown",text:de}]}))};import{CLIENT_CAPABILITIES_META_KEY as Me}from"@modelcontextprotocol/server";import{z as D}from"zod";import{createRequestStateCodec as le}from"@modelcontextprotocol/server";import{randomBytes as fe}from"node:crypto";var pe=new Set(["confirm","confirmToken"]),ge=600,U=e=>({toolName:e}),k=e=>{if(Array.isArray(e))return e.map(k);if(e!==null&&typeof e=="object"){let o=e;return Object.fromEntries(Object.keys(o).sort().map(r=>[r,k(o[r])]))}return e},x=e=>JSON.stringify(k(e)),c=e=>typeof e!="object"||e===null?{}:Object.fromEntries(Object.entries(e).filter(([o])=>!pe.has(o))),H=(e={})=>{let o=le({key:e.key??fe(32),ttlSeconds:e.ttlSeconds??ge,bind:r=>r.toolName});return{mint:(r,n)=>o.mint(r,U(n)),verify:(r,n)=>o.verify(r,U(n))}},L,K=()=>(L??=H(),L),Ce=e=>{if(typeof e!="object"||e===null)return;let{confirmToken:o}=e;return typeof o=="string"?o:void 0},ye=new Set(["malformed","mac","expired","bind"]),we=e=>{let o=e instanceof Error?e.message:"";return ye.has(o)?o:"malformed"},z=async(e,o,r)=>e.mint({args:x(c(r))},o),B=async(e,o,r)=>{let n=Ce(r);if(n===void 0)return{ok:!1,reason:"absent"};let t;try{t=await e.verify(n,o)}catch(i){return{ok:!1,reason:we(i)}}return t.args!==x(c(r))?{ok:!1,reason:"mismatch"}:{ok:!0}};import{acceptedContent as he,inputRequired as W,inputResponse as Re}from"@modelcontextprotocol/server";var T="args",V=3e3,Z=e=>{let o=Re(e,T);return o.kind==="elicit"?o.action:"missing"},ke=async(e,o)=>new Promise(r=>{let n=setTimeout(()=>{r(null)},o);e.then(t=>{clearTimeout(n),r(t)},()=>{clearTimeout(n),r(null)})}),X=async(e,o,r)=>{try{return await ke(e.buildRequestedSchema(o),r)}catch{return null}},Y=async(e,o,r)=>{let n=await X(e,o,r);if(n===null)return null;try{return W({inputRequests:{[T]:W.elicit({message:e.message,requestedSchema:n})}})}catch{return null}},v=async(e,o,r,n)=>{let t=await X(e,o,n);if(t===null)return null;let i;try{i=he(r,T,t)}catch{return null}if(i===void 0)return null;try{return e.toArgs(i,o)}catch{return null}},J=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),S=(e,o)=>{if(!J(e))return!1;if(!J(o))return!0;for(let[r,n]of Object.entries(e)){if(!(r in o))return!0;let t=o[r];if(Array.isArray(n)&&(!Array.isArray(t)||t.length!==n.length))return!0}return!1};var xe=e=>typeof e=="object"&&e!==null&&e.confirm===!0,Te=e=>e.gated&&!e.confirmed&&e.responses===void 0&&e.canForm&&e.hasProvider&&e.formable?"form":e.gated&&!e.confirmed&&e.responses!==void 0&&!e.accepted?"declined":e.gated&&!e.confirmed&&(e.responses===void 0||e.accepted)?"gate":e.gated&&e.confirmed?"verify":!e.gated&&e.responses===void 0&&e.canForm&&e.hasProvider&&e.formable?"form":!e.gated&&e.responses!==void 0&&e.hasProvider&&!e.accepted?"declined":!e.gated&&e.responses!==void 0&&e.hasProvider&&e.accepted?"run-form":"run",p=e=>({content:F(JSON.stringify(e,null,2)),structuredContent:e,isError:!0}),ve="The values you submitted in the form could NOT be applied and were DISCARDED \u2014 they failed validation or narrowed the arguments \u2014 so the arguments shown above are the ORIGINAL ones, not your selection.",Se="This tool does not prompt for its arguments; you are being asked to approve the values shown above.",be=async(e,o,r,n)=>{let t=c(r),i=await z(e,o,r),d=[n.formDiscarded?ve:void 0,`${o} mutates external state and is gated. It was NOT executed. Re-call ${o} with the same arguments plus "confirm": true and this "confirmToken" to execute.`,n.hasProvider?void 0:Se].filter(C=>C!==void 0).join(" ");return p({status:"confirmation_required",tool:o,resolvedArgs:t,confirmToken:i,formDiscarded:n.formDiscarded,message:d})},De=(e,o)=>p({status:"form_declined",tool:e,action:o,message:`${e} was NOT executed: the argument form came back as "${o}". No confirmation is pending \u2014 call ${e} again to start over.`}),Pe={validation:"failed validation",narrowed:"narrowed the arguments"},Q=(e,o)=>p({status:"form_discarded",tool:e,reason:o,message:`${e} was NOT executed: the values you submitted in the form ${Pe[o]} and were DISCARDED. No confirmation is pending \u2014 call ${e} again to start over.`}),Ae={absent:'no "confirmToken" was supplied',malformed:'the "confirmToken" is malformed',mac:'the "confirmToken" was not issued by this server',expired:'the "confirmToken" has expired',bind:'the "confirmToken" was issued for a different tool',mismatch:'the arguments differ from the ones the "confirmToken" was issued for'},Ee=(e,o)=>p({status:"confirmation_refused",tool:e,reason:o,message:`${e} was NOT executed: ${Ae[o]}. Call ${e} again WITHOUT "confirm" to receive a fresh gate, then re-call with the same arguments plus "confirm": true and the returned "confirmToken".`}),ee=e=>{try{return e()}catch{return!1}},Fe=async(e,o,r,n)=>{let t=e.formProvider;if(t===void 0||n!=="accept")return{params:o,formDiscarded:!1};let i=await v(t,o,r,e.formDeadlineMs);return i===null?(s.info({msg:`Tool execution form discarded (validation): ${e.toolName}`}),{params:o,formDiscarded:!0}):S(c(o),i)?(s.info({msg:`Tool execution form discarded (narrowed): ${e.toolName}`}),{params:o,formDiscarded:!0}):{params:i,formDiscarded:!1}},u=e=>({kind:"stop",result:e}),l=e=>({kind:"run",params:e}),oe=async(e,o,r,n)=>{let t=await Fe(e,o,r,n);return s.info({msg:`Tool execution gated (awaiting confirm): ${e.toolName}`}),await be(e.codec,e.toolName,t.params,{formDiscarded:t.formDiscarded,hasProvider:e.formProvider!==void 0})},Ie=async(e,o,r,n,t)=>{let i=e.formProvider===void 0?null:await Y(e.formProvider,o,e.formDeadlineMs);return i!==null?(s.info({msg:`Tool execution form requested: ${e.toolName}`}),u(i)):(s.info({msg:`Tool execution form unavailable: ${e.toolName}`}),t?u(await oe(e,o,r,n)):l(o))},Ne=async(e,o,r)=>{let n=e.formProvider;if(n===void 0)return l(o);let t=await v(n,o,r,e.formDeadlineMs);return t===null?(s.info({msg:`Tool execution form discarded (validation): ${e.toolName}`}),u(Q(e.toolName,"validation"))):S(c(o),t)?(s.info({msg:`Tool execution form discarded (narrowed): ${e.toolName}`}),u(Q(e.toolName,"narrowed"))):(s.info({msg:`Tool execution form accepted: ${e.toolName}`}),l(t))},Oe=async(e,o)=>{let r=await B(e.codec,e.toolName,o);return r.ok?l(o):(s.info({msg:`Tool execution refused (${r.reason}): ${e.toolName}`}),u(Ee(e.toolName,r.reason)))},_e=async(e,o,r)=>{let n=r?.mcpReq?.inputResponses,t=Z(n),i=e.requiresHumanConfirm===!0,d=Te({gated:i,confirmed:xe(o),responses:n,canForm:ee(()=>e.getClientCapabilities?.(r)?.elicitation?.form!==void 0),hasProvider:e.formProvider!==void 0,formable:ee(()=>e.formProvider?.isFormable(o)===!0),accepted:t==="accept"});switch(d){case"run":return l(o);case"declined":return s.info({msg:`Tool execution form declined (${t}): ${e.toolName}`}),u(De(e.toolName,t));case"verify":return await Oe(e,o);case"run-form":return await Ne(e,o,n);case"form":return await Ie(e,o,n,t,i);case"gate":return u(await oe(e,o,n,t));default:return M(d)}},b=({toolName:e,handler:o,requiresHumanConfirm:r,formProvider:n,getClientCapabilities:t,confirmCodec:i,formDeadlineMs:d})=>{let C={toolName:e,codec:i??K(),requiresHumanConfirm:r,formProvider:n,getClientCapabilities:t,formDeadlineMs:d??V};return async(y,P)=>{s.info({msg:`Tool execution started: ${e}`,params:y,sessionId:P?.sessionId});try{await _(),O.reset();let m=await _e(C,y,P);if(m.kind==="stop")return m.result;let se=await o({...m.params,confirmedCommand:!0});return s.info({msg:`Tool execution successful: ${e}`}),se}catch(m){throw s.error({err:m,params:y,msg:`Tool execution failed: ${e}`}),m}}};var re=async e=>{for(let o of $())e.registerTool(o.name,{title:o.title,description:o.description,inputSchema:D.object(o.requiresHumanConfirm===!0?$e(o.inputSchema):o.inputSchema),outputSchema:D.object(o.outputSchema),annotations:o.annotations,_meta:o.meta},je(b({toolName:o.name,handler:o.handler,requiresHumanConfirm:o.requiresHumanConfirm,formProvider:o.formProvider,getClientCapabilities:r=>r?.mcpReq?.envelope?.[Me]??e.server.getClientCapabilities()})))},$e=e=>({...e,confirmToken:D.string().optional().describe("Round-2 only: the token returned by the round-1 gate, proving the arguments are unchanged.")}),je=e=>(o,r)=>e(o,r);async function ne(){A.enabled=!0;let e=new qe({name:"infra-kit",version:I.version},{capabilities:{resources:{listChanged:!0},tools:{}}});return await G(e),await re(e),e}j();var a=E(),Le=async()=>{try{return await ne()}catch(e){a.error({err:e,msg:"Failed to create MCP server"}),a.flush(),g.exit(1)}};q(a);var He=Ge(Le,{onerror:e=>{a.error({err:e,msg:"MCP stdio entry error"}),a.flush()}});a.info({msg:"MCP stdio entry started."});var te=!1,ie=async e=>{if(!te){te=!0,a.info({msg:`Received ${e}. Shutting down...`});try{await Promise.race([He.close(),Ue(1500)])}catch(o){a.error({err:o,msg:"MCP stdio close failed during shutdown"})}a.flush(),g.exit(0)}};g.on("SIGINT",()=>{ie("SIGINT")});g.on("SIGTERM",()=>{ie("SIGTERM")});
1
+ import{U as W,X as J,a as U,d as w,ia as X,la as Z,t as B}from"./chunk-R6AYBYV6.js";import{i as z}from"./chunk-GFKYWEPW.js";import"./chunk-T2WBH6YO.js";import{I as R,J as q,K as s,R as V,c as G}from"./chunk-5FYZAIFC.js";import"./chunk-6OFUVD7F.js";import{a as K}from"./chunk-MFAFQVTW.js";import{l as H}from"./chunk-UNAV7SP4.js";import"./chunk-HHWP3YXW.js";import{a as N,b as M,d as h,l as $,n as j,o as S,q as L}from"./chunk-75URROMU.js";import"./chunk-QWVLAZ6N.js";import{serveStdio as gn}from"@modelcontextprotocol/server/stdio";import v from"node:process";import{setTimeout as Cn}from"node:timers/promises";import p from"node:process";var Y=e=>{p.on("uncaughtException",n=>{e.fatal({err:n,msg:"Uncaught Exception"}),e.error(`Uncaught Exception! Check ${R}. Shutting down...`),e.flush(),p.exit(1)}),p.on("unhandledRejection",(n,o)=>{e.fatal({reason:n,promise:o,msg:"Unhandled Rejection"}),e.error(`Unhandled Rejection! Check ${R}. Shutting down...`),e.flush(),p.exit(1)})};import{McpServer as pn}from"@modelcontextprotocol/server";var De="infra-kit://config",Ae="infra-kit://dev-context",Pe="infra-kit://workflow/session",Fe=["This procedure moved to the `/infra-kit:session` skill; update the plugin.","Meanwhile: no token \u2192 call `env-load` without `config`; the human's pick is the load.","On a tool error or a refused result naming `config`, call `env-list` and list every row in prose, then ask."].join(`
2
+ `),_e={loadConfig:V,readDevContext:()=>w()},x=(e,n)=>({contents:[{uri:e,mimeType:"application/json",text:JSON.stringify(n,null,2)}]}),Q=async(e,n=_e)=>{e.registerResource("infra-kit-config",De,{title:"infra-kit config",description:"The merged infra-kit.json configuration (all override layers applied). Read-only.",mimeType:"application/json"},async o=>{try{return x(o.toString(),await n.loadConfig())}catch(r){return x(o.toString(),{error:r instanceof Error?r.message:String(r)})}}),e.registerResource("infra-kit-dev-context",Ae,{title:"infra-kit dev context",description:"What `infra-kit dev` last wrote: backends currently up, their ports/origins, and fragment freshness. Read-only and advisory (no liveness probe). No active session resolves to an empty payload.",mimeType:"application/json"},o=>x(o.toString(),n.readDevContext())),e.registerResource("infra-kit-workflow-session",Pe,{title:"session procedure (moved)",description:"Retired: the session procedure now lives in the /infra-kit:session plugin skill. Update the plugin.",mimeType:"text/markdown"},o=>({contents:[{uri:o.toString(),mimeType:"text/markdown",text:Fe}]}))};import{CLIENT_CAPABILITIES_META_KEY as dn}from"@modelcontextprotocol/server";import{z as O}from"zod";import{createRequestStateCodec as Oe}from"@modelcontextprotocol/server";import{randomBytes as Ie}from"node:crypto";var Ne=new Set(["confirm","confirmToken"]),Me=600,ee=e=>({toolName:e}),T=e=>{if(Array.isArray(e))return e.map(T);if(e!==null&&typeof e=="object"){let n=e;return Object.fromEntries(Object.keys(n).sort().map(o=>[o,T(n[o])]))}return e},E=e=>JSON.stringify(T(e)),c=e=>typeof e!="object"||e===null?{}:Object.fromEntries(Object.entries(e).filter(([n])=>!Ne.has(n))),oe=(e={})=>{let n=Oe({key:e.key??Ie(32),ttlSeconds:e.ttlSeconds??Me,bind:o=>o.toolName});return{mint:(o,r)=>n.mint(o,ee(r)),verify:(o,r)=>n.verify(o,ee(r))}},ne,re=()=>(ne??=oe(),ne),$e=e=>{if(typeof e!="object"||e===null)return;let{confirmToken:n}=e;return typeof n=="string"?n:void 0},je=new Set(["malformed","mac","expired","bind"]),Le=e=>{let n=e instanceof Error?e.message:"";return je.has(n)?n:"malformed"},te=async(e,n,o)=>e.mint({args:E(c(o))},n),ie=async(e,n,o)=>{let r=$e(o);if(r===void 0)return{ok:!1,reason:"absent"};let t;try{t=await e.verify(r,n)}catch(i){return{ok:!1,reason:Le(i)}}return t.args!==E(c(o))?{ok:!1,reason:"mismatch"}:{ok:!0}};import Ge from"node:fs";import se from"node:path";import m from"node:process";var de=new Set([...K,h,"XDG_CACHE_HOME","CLAUDE_PROJECT_DIR","CLAUDE_PLUGIN_ROOT"]),me=null,g=new Set,b=null,ae=!1;var ce=e=>{try{return Ge.statSync(e)}catch{return null}},qe=()=>{if(ae)return null;try{return L()}catch{return ae=!0,s.warn(`session-env: ${h} unset \u2014 no overlay`),null}},Ue=e=>{let n=se.join(e,N),o=se.join(e,M),r=ce(n),t=ce(o);return r&&!(t&&t.mtimeMs>r.mtimeMs)?{kind:"load",file:n,signature:`load:${r.ino}:${r.mtimeMs}:${r.size}`}:t?{kind:"clear",file:o,signature:`clear:${t.ino}:${t.mtimeMs}`}:{kind:"none",signature:"none"}},He=e=>e.kind==="load"?{kind:"load",vars:j(e.file),unset:S(e.file),signature:e.signature}:e.kind==="clear"?{kind:"clear",unset:S(e.file),signature:e.signature}:e;var Ke=()=>{let e=qe();if(e===null)return{kind:"no-session"};let n=Ue(e);return n.signature===b?null:He(n)},Ve=()=>{for(let e of g){let n=me[e];n===void 0?delete m.env[e]:m.env[e]=n}g.clear()},le=(e,n,o)=>{if(de.has(n)){e.skipped.push(n);return}m.env[n]=o,g.add(n),e.set.push(n)},ue=(e,n)=>{if(de.has(n)){e.skipped.push(n);return}delete m.env[n],g.add(n),e.unset.push(n)},ze=e=>{let n={set:[],unset:[],skipped:[]};if(e.kind==="load"){for(let[o,r]of Object.entries(e.vars))le(n,o,r);for(let o of e.unset)ue(n,o)}if(e.kind==="clear"){for(let o of e.unset)ue(n,o);le(n,$,"1")}return n},Be=e=>e.kind==="load"?`load, ${Object.keys(e.vars).length} vars`:e.kind,D=(e=Ke())=>{if(me??={...m.env},e===null||e.kind==="no-session"||e.signature===b)return{set:[],unset:[],changed:!1};Ve();let{set:n,unset:o,skipped:r}=ze(e);return b=e.signature,r.length>0&&s.warn(`session-env: skipped protected names [${r.join(", ")}]`),s.info(`session-env applied: set [${n.join(", ")}] unset [${o.join(", ")}] (${Be(e)})`),{set:n,unset:o,changed:!0}};import{acceptedContent as We,inputRequired as fe,inputResponse as Je}from"@modelcontextprotocol/server";var A="args",ge=3e3,Ce=e=>{let n=Je(e,A);return n.kind==="elicit"?n.action:"missing"},ve=async(e,n,o)=>{try{return await W(e.buildRequestedSchema(n),o)}catch{return null}},ye=async(e,n,o)=>{let r=await ve(e,n,o);if(r===null)return null;try{return fe({inputRequests:{[A]:fe.elicit({message:e.message,requestedSchema:r})}})}catch{return null}},P=async(e,n,o,r)=>{let t=await ve(e,n,r);if(t===null)return null;let i;try{i=We(o,A,t)}catch{return null}if(i===void 0)return null;try{return e.toArgs(i,n)}catch{return null}},pe=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),F=(e,n)=>{if(!pe(e))return!1;if(!pe(n))return!0;for(let[o,r]of Object.entries(e)){if(!(o in n))return!0;let t=n[o];if(Array.isArray(r)&&(!Array.isArray(t)||t.length!==r.length))return!0}return!1};var Xe=e=>typeof e=="object"&&e!==null&&e.confirm===!0,Ze=e=>e.gated&&!e.confirmed&&e.responses===void 0&&e.canForm&&e.hasProvider&&e.formable?"form":e.gated&&!e.confirmed&&e.responses!==void 0&&!e.accepted?"declined":e.gated&&!e.confirmed&&(e.responses===void 0||e.accepted)?"gate":e.gated&&e.confirmed?"verify":!e.gated&&e.responses===void 0&&e.canForm&&e.hasProvider&&e.formable?"form":!e.gated&&e.responses!==void 0&&e.hasProvider&&!e.accepted?"declined":!e.gated&&e.responses!==void 0&&e.hasProvider&&e.accepted?"run-form":"run",C=e=>({content:U(JSON.stringify(e,null,2)),structuredContent:e,isError:!0}),Ye="The values you submitted in the form could NOT be applied and were DISCARDED \u2014 they failed validation or narrowed the arguments \u2014 so the arguments shown above are the ORIGINAL ones, not your selection.",Qe="This tool does not prompt for its arguments; you are being asked to approve the values shown above.",en=async(e,n,o,r)=>{let t=c(o),i=await te(e,n,o),u=[r.formDiscarded?Ye:void 0,`${n} mutates external state and is gated. It was NOT executed. Re-call ${n} with the same arguments plus "confirm": true and this "confirmToken" to execute.`,r.hasProvider?void 0:Qe].filter(y=>y!==void 0).join(" ");return C({status:"confirmation_required",tool:n,resolvedArgs:t,confirmToken:i,formDiscarded:r.formDiscarded,message:u})},nn=(e,n)=>C({status:"form_declined",tool:e,action:n,message:`${e} was NOT executed: the argument form came back as "${n}". No confirmation is pending \u2014 call ${e} again to start over.`}),on={validation:"failed validation",narrowed:"narrowed the arguments"},ke=(e,n)=>C({status:"form_discarded",tool:e,reason:n,message:`${e} was NOT executed: the values you submitted in the form ${on[n]} and were DISCARDED. No confirmation is pending \u2014 call ${e} again to start over.`}),rn={absent:'no "confirmToken" was supplied',malformed:'the "confirmToken" is malformed',mac:'the "confirmToken" was not issued by this server',expired:'the "confirmToken" has expired',bind:'the "confirmToken" was issued for a different tool',mismatch:'the arguments differ from the ones the "confirmToken" was issued for'},tn=(e,n)=>C({status:"confirmation_refused",tool:e,reason:n,message:`${e} was NOT executed: ${rn[n]}. Call ${e} again WITHOUT "confirm" to receive a fresh gate, then re-call with the same arguments plus "confirm": true and the returned "confirmToken".`}),he=e=>{try{return e()}catch{return!1}},sn=async(e,n,o,r)=>{let t=e.formProvider;if(t===void 0||r!=="accept")return{params:n,formDiscarded:!1};let i=await P(t,n,o,e.formDeadlineMs);return i===null?(s.info({msg:`Tool execution form discarded (validation): ${e.toolName}`}),{params:n,formDiscarded:!0}):F(c(n),i)?(s.info({msg:`Tool execution form discarded (narrowed): ${e.toolName}`}),{params:n,formDiscarded:!0}):{params:i,formDiscarded:!1}},l=e=>({kind:"stop",result:e}),f=e=>({kind:"run",params:e}),Se=async(e,n,o,r)=>{let t=await sn(e,n,o,r);return s.info({msg:`Tool execution gated (awaiting confirm): ${e.toolName}`}),await en(e.codec,e.toolName,t.params,{formDiscarded:t.formDiscarded,hasProvider:e.formProvider!==void 0})},an=async(e,n,o,r,t)=>{let i=e.formProvider===void 0?null:await ye(e.formProvider,n,e.formDeadlineMs);return i!==null?(s.info({msg:`Tool execution form requested: ${e.toolName}`}),l(i)):(s.info({msg:`Tool execution form unavailable: ${e.toolName}`}),t?l(await Se(e,n,o,r)):f(n))},cn=async(e,n,o)=>{let r=e.formProvider;if(r===void 0)return f(n);let t=await P(r,n,o,e.formDeadlineMs);return t===null?(s.info({msg:`Tool execution form discarded (validation): ${e.toolName}`}),l(ke(e.toolName,"validation"))):F(c(n),t)?(s.info({msg:`Tool execution form discarded (narrowed): ${e.toolName}`}),l(ke(e.toolName,"narrowed"))):(s.info({msg:`Tool execution form accepted: ${e.toolName}`}),f(t))},ln=async(e,n)=>{let o=await ie(e.codec,e.toolName,n);return o.ok?f(n):(s.info({msg:`Tool execution refused (${o.reason}): ${e.toolName}`}),l(tn(e.toolName,o.reason)))},un=async(e,n,o)=>{let r=o?.mcpReq?.inputResponses,t=Ce(r),i=e.requiresHumanConfirm===!0,u=Ze({gated:i,confirmed:Xe(n),responses:r,canForm:he(()=>e.getClientCapabilities?.(o)?.elicitation?.form!==void 0),hasProvider:e.formProvider!==void 0,formable:he(()=>e.formProvider?.isFormable(n)===!0),accepted:t==="accept"});switch(u){case"run":return f(n);case"declined":return s.info({msg:`Tool execution form declined (${t}): ${e.toolName}`}),l(nn(e.toolName,t));case"verify":return await ln(e,n);case"run-form":return await cn(e,n,r);case"form":return await an(e,n,r,t,i);case"gate":return l(await Se(e,n,r,t));default:return J(u)}},_=({toolName:e,handler:n,requiresHumanConfirm:o,formProvider:r,getClientCapabilities:t,confirmCodec:i,formDeadlineMs:u,applySessionEnv:y=D})=>{let Ee={toolName:e,codec:i??re(),requiresHumanConfirm:o,formProvider:r,getClientCapabilities:t,formDeadlineMs:u??ge};return async(k,I)=>{s.info({msg:`Tool execution started: ${e}`,params:k,sessionId:I?.sessionId});try{await B(),z.reset(),y();let d=await un(Ee,k,I);if(d.kind==="stop")return d.result;let be=await n({...d.params,confirmedCommand:!0});return s.info({msg:`Tool execution successful: ${e}`}),be}catch(d){throw s.error({err:d,params:k,msg:`Tool execution failed: ${e}`}),d}}};var Re=async e=>{for(let n of X())e.registerTool(n.name,{title:n.title,description:n.description,inputSchema:O.object(n.requiresHumanConfirm===!0?mn(n.inputSchema):n.inputSchema),outputSchema:O.object(n.outputSchema),annotations:n.annotations,_meta:n.meta},fn(_({toolName:n.name,handler:n.handler,requiresHumanConfirm:n.requiresHumanConfirm,formProvider:n.formProvider,getClientCapabilities:o=>o?.mcpReq?.envelope?.[dn]??e.server.getClientCapabilities()})))},mn=e=>({...e,confirmToken:O.string().optional().describe("Round-2 only: the token returned by the round-1 gate, proving the arguments are unchanged.")}),fn=e=>(n,o)=>e(n,o);async function we(){G.enabled=!0;let e=new pn({name:"infra-kit",version:H.version},{capabilities:{resources:{listChanged:!0},tools:{}}});return await Q(e),await Re(e),e}Z();var a=q(),vn=async()=>{try{return await we()}catch(e){a.error({err:e,msg:"Failed to create MCP server"}),a.flush(),v.exit(1)}};Y(a);var yn=gn(vn,{onerror:e=>{a.error({err:e,msg:"MCP stdio entry error"}),a.flush()}});a.info({msg:"MCP stdio entry started."});var xe=!1,Te=async e=>{if(!xe){xe=!0,a.info({msg:`Received ${e}. Shutting down...`});try{await Promise.race([yn.close(),Cn(1500)])}catch(n){a.error({err:n,msg:"MCP stdio close failed during shutdown"})}a.flush(),v.exit(0)}};v.on("SIGINT",()=>{Te("SIGINT")});v.on("SIGTERM",()=>{Te("SIGTERM")});
3
3
  //# sourceMappingURL=mcp.js.map