infra-kit 0.7.8 → 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,8 +1,8 @@
1
- import{a as G}from"./chunk-MFAFQVTW.js";import{e as A}from"./chunk-NFIFWIO6.js";import q from"node:process";import $ from"pino";import ke from"pino-pretty";var V="/tmp/mcp-infra-kit.log",B=["token","*.token","serviceToken","*.serviceToken","DOPPLER_TOKEN","*.DOPPLER_TOKEN","INFRA_KIT_ENV_TOKEN","*.INFRA_KIT_ENV_TOKEN"],Jt=()=>{let e=q.argv.includes("--debug")?"debug":"info",t=$({level:e,redact:B},$.destination({dest:V}));return t.info(`Logger initialized with level: ${e}. Logging to: ${V}`),t},xe=()=>{let e=q.argv.includes("--debug")?"debug":"info",t=["time","pid","hostname"];return e==="debug"&&t.push("level"),$({level:e,redact:B},ke({destination:2,ignore:t.join(","),colorize:!0}))},Yt=xe();import W from"node:fs/promises";import pe from"node:os";import R from"node:path";import He from"node:process";import{z as s}from"zod";import x from"node:path";import Q from"node:process";import{$ as f}from"zx";var w=e=>{let t=new Set,r=e;for(;r!==null&&typeof r=="object"&&!t.has(r);){t.add(r);let{stderr:n,stderrExcerpt:o}=r;if(typeof n=="string"&&n.length>0)return n;if(typeof o=="string"&&o.length>0)return o;r=r.cause}},we=(e,t)=>{let r=t.stderrExcerpt??w(e),n=[`failed to ${t.operation}`];return r&&n.push(`stderr: ${r.slice(0,200).trim()}`),t.remediation&&n.push(`try: ${t.remediation}`),n.join(" \u2014 ")},d=class extends Error{operation;remediation;stderrExcerpt;constructor(t,r){super(we(t,r),{cause:t}),this.name="OperationError",this.operation=r.operation,this.remediation=r.remediation,this.stderrExcerpt=r.stderrExcerpt??w(t)}};var U={enabled:!1},P=()=>U.enabled;var Pe=/^v?(\d+)\.(\d+)\.(\d+)$/,be=/^(\d+)\.(\d+)\.(\d+)$/,Re=/^[a-z0-9]+(?:-[a-z0-9]+)*$/,C="release/",D="release/v",H="refs/heads/",Ee="next";var X=new Set(["dev","main","next","hotfix","regular","release"]),v=class extends Error{constructor(t){super(t),this.name="InvalidReleaseNameError"}},k=class extends Error{constructor(t){super(t),this.name="InvalidReleaseRefError"}},Y=e=>e.startsWith(H)?e.slice(H.length):e,Z=(e,t,r)=>({kind:"version",semver:{major:e,minor:t,patch:r},raw:`${e}.${t}.${r}`}),T=e=>{if(e.length===0)throw new v('Release name is empty. Provide a kebab-case name like "checkout-redesign".');if(e.length>50)throw new v(`Release name "${e}" is ${e.length} characters; the maximum is 50.`);if(!Re.test(e))throw new v(`Release name "${e}" is not kebab-case. Use lowercase letters, digits, and single hyphens, e.g. "checkout-redesign".`);if(X.has(e))throw new v(`Release name "${e}" is reserved. Reserved names: ${[...X].join(", ")}.`)},N=e=>{let t=Y(e.trim());if(!t.startsWith(C))return null;if(t.startsWith(D)){let n=t.slice(D.length),o=be.exec(n);if(o)return Z(Number(o[1]),Number(o[2]),Number(o[3]))}let r=t.slice(C.length);try{T(r)}catch{return null}return{kind:"name",name:r,raw:r}},Se=e=>{let t=e.trim();if(Y(t).startsWith(C)){let o=N(t);if(!o)throw new k(`"${e}" looks like a release branch but is not a valid release/v<semver> or release/<name> ref.`);return o}let n=Pe.exec(t);if(n)return Z(Number(n[1]),Number(n[2]),Number(n[3]));if(t.toLowerCase()===Ee)throw new k('The "next" token must be resolved to a concrete version (via computeNextVersion) before parsing a release ref.');try{T(t)}catch(o){let i=o instanceof Error?o.message:String(o);throw new k(`Cannot parse "${e}" as a release ref: ${i}`)}return{kind:"name",name:t,raw:t}},Ce=e=>e.kind==="version"?`${D}${e.raw}`:`${C}${e.name}`,je=(e,t)=>{let r=t==="hotfix"?"Hotfix":"Release";return e.kind==="version"?`${r} v${e.raw}`:`${r} ${e.name}`},Ie=e=>e.kind==="version"?`Release v${e.raw} (RC)`:`Release ${e.name} (RC)`,Ae=e=>e.kind==="version"?`v${e.raw}`:e.name,$e=e=>e.raw,_=e=>e==null?!1:N(e)!==null,J=e=>{if(e===void 0)return null;let t=e instanceof Date?e.getTime():new Date(e).getTime();return Number.isNaN(t)?null:t},De=(e,t,r)=>{if(e.kind==="version"&&t.kind==="version")return e.semver.major!==t.semver.major?e.semver.major-t.semver.major:e.semver.minor!==t.semver.minor?e.semver.minor-t.semver.minor:e.semver.patch-t.semver.patch;if(e.kind==="version")return-1;if(t.kind==="version")return 1;let n=J(r?.a),o=J(r?.b);return n!==null&&o!==null&&n!==o?n-o:e.name<t.name?-1:e.name>t.name?1:0};var ee=async e=>{let t=await f({cwd:e})`git worktree list --porcelain`,r=[],n=null;for(let o of t.stdout.split(`
1
+ import{a as G}from"./chunk-MFAFQVTW.js";import{e as A}from"./chunk-75URROMU.js";import q from"node:process";import $ from"pino";import ke from"pino-pretty";var V="/tmp/mcp-infra-kit.log",B=["token","*.token","serviceToken","*.serviceToken","DOPPLER_TOKEN","*.DOPPLER_TOKEN","INFRA_KIT_ENV_TOKEN","*.INFRA_KIT_ENV_TOKEN"],Jt=()=>{let e=q.argv.includes("--debug")?"debug":"info",t=$({level:e,redact:B},$.destination({dest:V}));return t.info(`Logger initialized with level: ${e}. Logging to: ${V}`),t},xe=()=>{let e=q.argv.includes("--debug")?"debug":"info",t=["time","pid","hostname"];return e==="debug"&&t.push("level"),$({level:e,redact:B},ke({destination:2,ignore:t.join(","),colorize:!0}))},Yt=xe();import W from"node:fs/promises";import pe from"node:os";import R from"node:path";import He from"node:process";import{z as s}from"zod";import x from"node:path";import Q from"node:process";import{$ as f}from"zx";var w=e=>{let t=new Set,r=e;for(;r!==null&&typeof r=="object"&&!t.has(r);){t.add(r);let{stderr:n,stderrExcerpt:o}=r;if(typeof n=="string"&&n.length>0)return n;if(typeof o=="string"&&o.length>0)return o;r=r.cause}},we=(e,t)=>{let r=t.stderrExcerpt??w(e),n=[`failed to ${t.operation}`];return r&&n.push(`stderr: ${r.slice(0,200).trim()}`),t.remediation&&n.push(`try: ${t.remediation}`),n.join(" \u2014 ")},d=class extends Error{operation;remediation;stderrExcerpt;constructor(t,r){super(we(t,r),{cause:t}),this.name="OperationError",this.operation=r.operation,this.remediation=r.remediation,this.stderrExcerpt=r.stderrExcerpt??w(t)}};var U={enabled:!1},P=()=>U.enabled;var Pe=/^v?(\d+)\.(\d+)\.(\d+)$/,be=/^(\d+)\.(\d+)\.(\d+)$/,Re=/^[a-z0-9]+(?:-[a-z0-9]+)*$/,C="release/",D="release/v",H="refs/heads/",Ee="next";var X=new Set(["dev","main","next","hotfix","regular","release"]),v=class extends Error{constructor(t){super(t),this.name="InvalidReleaseNameError"}},k=class extends Error{constructor(t){super(t),this.name="InvalidReleaseRefError"}},Y=e=>e.startsWith(H)?e.slice(H.length):e,Z=(e,t,r)=>({kind:"version",semver:{major:e,minor:t,patch:r},raw:`${e}.${t}.${r}`}),T=e=>{if(e.length===0)throw new v('Release name is empty. Provide a kebab-case name like "checkout-redesign".');if(e.length>50)throw new v(`Release name "${e}" is ${e.length} characters; the maximum is 50.`);if(!Re.test(e))throw new v(`Release name "${e}" is not kebab-case. Use lowercase letters, digits, and single hyphens, e.g. "checkout-redesign".`);if(X.has(e))throw new v(`Release name "${e}" is reserved. Reserved names: ${[...X].join(", ")}.`)},N=e=>{let t=Y(e.trim());if(!t.startsWith(C))return null;if(t.startsWith(D)){let n=t.slice(D.length),o=be.exec(n);if(o)return Z(Number(o[1]),Number(o[2]),Number(o[3]))}let r=t.slice(C.length);try{T(r)}catch{return null}return{kind:"name",name:r,raw:r}},Se=e=>{let t=e.trim();if(Y(t).startsWith(C)){let o=N(t);if(!o)throw new k(`"${e}" looks like a release branch but is not a valid release/v<semver> or release/<name> ref.`);return o}let n=Pe.exec(t);if(n)return Z(Number(n[1]),Number(n[2]),Number(n[3]));if(t.toLowerCase()===Ee)throw new k('The "next" token must be resolved to a concrete version (via computeNextVersion) before parsing a release ref.');try{T(t)}catch(o){let i=o instanceof Error?o.message:String(o);throw new k(`Cannot parse "${e}" as a release ref: ${i}`)}return{kind:"name",name:t,raw:t}},Ce=e=>e.kind==="version"?`${D}${e.raw}`:`${C}${e.name}`,je=(e,t)=>{let r=t==="hotfix"?"Hotfix":"Release";return e.kind==="version"?`${r} v${e.raw}`:`${r} ${e.name}`},Ie=e=>e.kind==="version"?`Release v${e.raw} (RC)`:`Release ${e.name} (RC)`,Ae=e=>e.kind==="version"?`v${e.raw}`:e.name,$e=e=>e.raw,_=e=>e==null?!1:N(e)!==null,J=e=>{if(e===void 0)return null;let t=e instanceof Date?e.getTime():new Date(e).getTime();return Number.isNaN(t)?null:t},De=(e,t,r)=>{if(e.kind==="version"&&t.kind==="version")return e.semver.major!==t.semver.major?e.semver.major-t.semver.major:e.semver.minor!==t.semver.minor?e.semver.minor-t.semver.minor:e.semver.patch-t.semver.patch;if(e.kind==="version")return-1;if(t.kind==="version")return 1;let n=J(r?.a),o=J(r?.b);return n!==null&&o!==null&&n!==o?n-o:e.name<t.name?-1:e.name>t.name?1:0};var ee=async e=>{let t=await f({cwd:e})`git worktree list --porcelain`,r=[],n=null;for(let o of t.stdout.split(`
2
2
  `)){if(o.startsWith("worktree ")){n&&r.push(n),n={path:o.slice(9),branch:null,detached:!1,bare:!1,prunable:!1,locked:!1};continue}n&&(o.startsWith("branch ")?n.branch=o.slice(7).replace(/^refs\/heads\//,""):o==="detached"?n.detached=!0:o==="bare"?n.bare=!0:o==="locked"||o.startsWith("locked ")?n.locked=!0:(o==="prunable"||o.startsWith("prunable "))&&(n.prunable=!0))}return n&&r.push(n),r},Te=async e=>{let t=await ee(Q.cwd()),r=n=>e==="release"?_(n):n.startsWith("feature/");return t.map(n=>n.branch).filter(n=>n!==null&&r(n))},Ne=e=>{let t=w(e);return t&&/not a git repository/i.test(t)?"not a git repository":void 0},_e=({hasStderr:e})=>{if(P())return"the infra-kit MCP server resolves its project from the working directory it was launched in; the operator must relaunch the server with its working directory set to an infra-kit project repo";let t="run infra-kit from inside an infra-kit project repo (or one of its git worktrees)";return e?`${t}; if you are already in one, the stderr in this message is the real cause`:t},b=async()=>{try{return(await f({quiet:!0})`git rev-parse --show-toplevel`).stdout.trim()}catch(e){let t=Ne(e)??w(e);throw new d(e,{operation:`resolve the project root from ${Q.cwd()}`,stderrExcerpt:t,remediation:_e({hasStderr:t!==void 0})})}},L=async e=>{let t=e??await b(),r=(await f({cwd:t,quiet:!0})`git rev-parse --git-common-dir`).stdout.trim(),n=x.resolve(t,r);return n.includes(`${x.sep}.git${x.sep}modules${x.sep}`)?t:x.dirname(n)},te=async()=>(await f`git rev-parse --abbrev-ref HEAD`).stdout.trim(),re=async()=>(await f`git status --porcelain`).stdout.split(`
3
3
  `).map(t=>t.trimEnd()).filter(t=>t.trim().length>0),Le=async()=>(await re()).length===0,Me=async()=>{let e=await b(),[t,r]=await Promise.all([f({cwd:e})`git rev-parse --absolute-git-dir`,f({cwd:e})`git rev-parse --git-common-dir`]),n=t.stdout.trim(),o=x.resolve(e,r.stdout.trim());return n!==o};var Oe=async e=>(await f`git branch --list ${e}`).stdout.trim().length>0,Ke=async e=>{(await f`git branch --list ${e}`).stdout.trim().length!==0&&await te()!==e&&await f`git branch -D ${e}`},We=async e=>{(await f`git ls-remote --heads origin ${e}`).stdout.trim().length!==0&&await f`git push origin --delete ${e}`};import{$ as j}from"zx";var Fe=async(e,t)=>{let r=`${t}^{commit}`;try{return(await j({cwd:e,quiet:!0})`git rev-parse --verify --quiet ${r}`).stdout.trim()||null}catch{return null}},ze=async(e,t,r)=>{try{return await j({cwd:e,quiet:!0})`git merge-base --is-ancestor ${t} ${r}`,!0}catch(n){if(n.exitCode===1)return!1;throw new d(n,{operation:`test whether ${t} is contained in ${r}`,remediation:"both refs must exist \u2014 verify them with rev-parse first"})}},Ge=async(e,t)=>{let n=(await j({cwd:e,quiet:!0})`git ls-remote --heads origin ${t}`).stdout.trim().split(`
4
4
  `)[0];return n?n.split(/\s+/)[0]??null:null},Ve=async(e,t)=>{let r=t.map(n=>`${n.sha}:refs/heads/${n.branch}`);if(r.length===0)return{refspecs:r,pushed:!1};try{return await j({cwd:e,quiet:!0})`git push --atomic origin ${r}`,{refspecs:r,pushed:!0}}catch(n){return{refspecs:r,pushed:!1,stderr:n.stderr}}};import ne from"node:path";import M from"node:process";import{$ as m}from"zx";var oe=async e=>{let t=e??M.cwd(),r=(await m({cwd:t,quiet:!0})`git rev-parse --git-common-dir`).stdout.trim(),n=M.env.INFRA_KIT_SESSION||String(M.pid);return ne.join(ne.resolve(t,r),"infra-kit",`merge-dev-${n}`)},O=async e=>{try{return await m({cwd:e,quiet:!0})`git rev-parse -q --verify MERGE_HEAD`,!0}catch{return!1}},qe=async e=>{if(await O(e))throw new d(void 0,{operation:"reuse the scratch worktree",stderrExcerpt:"a merge is still in progress in the scratch worktree",remediation:"this is an infra-kit bug \u2014 the previous branch iteration did not clean up"});let t=(await m({cwd:e,quiet:!0})`git status --porcelain`).stdout.trim();if(t.length>0)throw new d(void 0,{operation:"reuse the scratch worktree",stderrExcerpt:`scratch worktree is dirty: ${t.split(`
5
5
  `)[0]}`,remediation:"this is an infra-kit bug \u2014 the previous branch iteration did not clean up"})},Be=async e=>{let t=async r=>{try{await r()}catch{}};await O(e)&&await t(()=>m({cwd:e,quiet:!0})`git merge --abort`),await t(()=>m({cwd:e,quiet:!0})`git reset --hard`),await t(()=>m({cwd:e,quiet:!0})`git clean -fd`)},Ue=async(e,t)=>{let{cwd:r,anchor:n="origin/dev"}=e,o=await oe(r),i=async()=>{await m({cwd:r,quiet:!0})`git worktree add --detach ${o} ${n}`};try{await i()}catch(u){try{await m({cwd:r,quiet:!0})`git worktree prune`,await i()}catch{throw new d(u,{operation:"create the scratch worktree for the merge",remediation:`remove any stale checkout at ${o}, then retry`})}}let c={path:o,remove:async()=>{try{await m({cwd:r,quiet:!0})`git worktree remove --force ${o}`}catch{}}};try{return await t(c)}finally{await c.remove()}};var se="infra-kit.json";var Xe="infra-kit.json",Je="projects",Ye=s.object({provider:s.literal("doppler"),config:s.object({name:s.string().min(1)})}),Ze=s.discriminatedUnion("provider",[Ye]),Qe=s.object({workspaceConfigPath:s.string().min(1)}),et=s.object({provider:s.literal("cursor"),config:Qe}),tt=s.object({}),rt=s.object({provider:s.literal("zed"),config:tt}),ie=s.discriminatedUnion("provider",[et,rt]),nt=s.union([ie,s.array(ie).min(1)]),ot=s.object({provider:s.literal("jira"),config:s.object({baseUrl:s.string().url(),projectId:s.number().int().positive()})}),st=s.discriminatedUnion("provider",[ot]),it=["two-columns","three-pane"],at=s.object({layout:s.enum(it).optional()}),ct=s.object({openInGithubDesktop:s.boolean().optional(),openInCmux:s.boolean().optional(),cmux:at.optional()}),pt=s.object({port:s.number().int().positive().optional(),prefixUrl:s.string().min(1).optional()}).strict(),ut=s.record(s.string().min(1),pt),lt=s.enum(["local","cloud"]),ft=s.object({watchDeps:s.boolean().optional(),proxy:s.record(s.string().min(1),lt).optional()}).strict(),dt=s.object({apps:s.record(s.string().min(1),ft).optional(),cmux:s.boolean().optional()}).strict(),mt=s.record(s.string().min(1),dt),gt=s.object({port:s.number().int().positive().optional()}).strict(),ht=s.object({trigger:s.enum(["shell-startup","cli-invocation"]),config:s.string().min(1)}).strict(),yt=s.enum(["disallow","allow","cli-only"]),ae=s.string().regex(/^[A-Z_]\w*$/i,"must be a POSIX environment-variable name"),vt=s.object({command:s.string().min(1),args:s.array(s.string()).default([]),env:s.array(ae).min(1),unset:s.array(ae).default([])}).strict().superRefine((e,t)=>{for(let r of e.env)G.has(r)&&t.addIssue({code:"custom",path:["env"],message:`"${r}" is process plumbing the proxy never strips or injects \u2014 it cannot be a credential name`})}),kt=s.record(s.string().regex(/^[a-z][a-z0-9-]*$/,"must be lowercase letters, digits and hyphens, starting with a letter").refine(e=>!e.includes("infra-kit"),{message:'"infra-kit" is reserved for the infra-kit MCP server itself'}),vt),F=s.object({envManagement:Ze,ide:nt.optional(),taskManager:st.optional(),worktrees:ct.optional(),envAutoLoad:ht.optional(),dev:ut.optional(),devServersPresets:mt.optional(),devProxy:gt.optional(),protectedEnvs:yt.optional(),mcp:kt.optional()}).strict(),xt=443,ue=F.superRefine((e,t)=>{if(!Array.isArray(e.ide))return;let r=new Set;for(let n of e.ide){if(r.has(n.provider)){t.addIssue({code:"custom",message:"each IDE provider may appear at most once",path:["ide"]});return}r.add(n.provider)}}),le=F.partial(),wt=e=>{let t=e.ide;return t?Array.isArray(t)?t:[t]:[]},Pt="two-columns",bt=e=>e.worktrees?.cmux?.layout??Pt,g=null,E=null,fe=()=>`${He.cwd()} ${pe.homedir()}`,de=async()=>{let e=fe();if(E&&E.key===e)return E.value;let t=await b(),r=await L(t),n=R.basename(r),o=R.join(pe.homedir(),A),i={main:R.join(t,se),userGlobal:R.join(o,Xe),userProject:R.join(o,Je,n,se),projectName:n};return E={key:e,value:i},i},Rt=async()=>{let e=fe(),t=await de(),r;try{r=await W.stat(t.main)}catch{g=null;let h=t.main.replace(/\.json$/,".yml");throw await K(h)?new Error(`infra-kit.json not found at ${t.main}. A legacy infra-kit.yml exists \u2014 run \`infra-kit setup --skip-tools\` to convert it.`):new Error(P()?`infra-kit.json not found at ${t.main} \u2014 the directory the infra-kit MCP server was launched in is not an infra-kit project. The operator must relaunch the server with its working directory set to an infra-kit project repo.`:`infra-kit.json not found at ${t.main} \u2014 this git repo is not an infra-kit project. Run \`infra-kit setup --skip-tools\` here to create it, cd into an infra-kit project repo, or check out a branch that has infra-kit.json.`)}let[n,o]=await Promise.all([K(t.userGlobal),K(t.userProject)]),i={main:Number(r.mtimeMs),userGlobal:n?Number(n.mtimeMs):null,userProject:o?Number(o.mtimeMs):null};if(g&&g.key===e&&jt(g.mtimes,i))return g.value;let c=[{label:"infra-kit.json",path:t.main,required:!0},{label:"~/.infra-kit/infra-kit.json",path:t.userGlobal,required:!1},{label:`~/.infra-kit/projects/${t.projectName}/infra-kit.json`,path:t.userProject,required:!1}],u={};for(let h of c){let y=await It(h);y!==null&&(u={...u,...y})}let l=ue.safeParse(u);if(!l.success)throw new Error(`Invalid merged infra-kit config: ${s.prettifyError(l.error)}`);return g={key:e,mtimes:i,value:l.data},l.data},Et=()=>{g=null},St=()=>{g=null,E=null},K=async e=>{try{return await W.stat(e)}catch{return null}},Ct=async e=>{try{return await W.readFile(e,"utf-8")}catch{return null}},jt=(e,t)=>{let r=Object.keys(e);return r.length!==Object.keys(t).length?!1:r.every(n=>e[n]===t[n])},It=async e=>{let t=await Ct(e.path);if(t===null){if(e.required)throw new Error(`${e.label} not found at ${e.path}`);return null}let r;try{r=t.trim()===""?{}:JSON.parse(t)}catch(o){throw new Error(`Invalid JSON in ${e.label} at ${e.path}: ${o.message}`)}if(ce(r)&&"envTokens"in r)throw new Error($t(e));if(!e.required&&ce(r)&&"mcp"in r)throw new Error(At(e));let n=le.safeParse(r);if(!n.success)throw new Error(`Invalid ${e.label} at ${e.path}: ${s.prettifyError(n.error)}`);return n.data},At=e=>[`"mcp" is not allowed in ${e.label} (${e.path}): it feeds the committed .mcp.json, so a per-machine copy would replace the project's servers for everyone.`,"Move the block to the project infra-kit.json and run `infra-kit setup`.","For a machine-only override of one server (e.g. a local fork), use Claude Code directly:"," claude mcp add --scope local <name> -- ik-mcp --name <name> --env <VAR> ... -- <command> <args>","(local scope shadows the project entry by name; `claude mcp list` will show a same-name conflict warning, which is expected)."].join(`
6
6
  `),ce=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),$t=e=>[`Refusing to load ${e.label} \u2014 \`envTokens\` is not a config key.`,"A service token in a config file can be committed, backed up by your editor, or shared."," 1. REVOKE the token in Doppler now \u2014 treat it as compromised.",` 2. Remove the \`envTokens\` key from ${e.path}.`," 3. Re-add it privately: `infra-kit env-token-set <env>`"," (it is written to ~/.infra-kit/projects/<repo>/tokens.json, mode 0600, never to the repo)."].join(`
7
7
  `);import*as p from"node:fs";import*as a from"node:path";function Dt(e){let t=e;for(let r=0;r<10;r++){let n=a.join(t,"pnpm-workspace.yaml");if(p.existsSync(n))return t;t=a.dirname(t)}throw new Error("Could not find monorepo root (pnpm-workspace.yaml)")}function ge(e,t){let r=a.join(e,"package.json");if(!p.existsSync(r))return t;try{let n=JSON.parse(p.readFileSync(r,"utf-8"));return typeof n.name=="string"?n.name:t}catch{return t}}function Or(e){let t=a.join(e,"apps"),r=[];if(!p.existsSync(t))throw new Error(`Apps directory not found: ${t}`);let n=p.readdirSync(t,{withFileTypes:!0}).filter(o=>o.isDirectory()).map(o=>o.name);for(let o of n){let i=a.join(t,o,"api"),c=a.join(i,"serverless.yml");p.existsSync(c)&&r.push({name:o,packageName:ge(i,o),path:i})}return r}var he=["vite.config.ts","vite.config.mts","vite.config.cts","vite.config.js","vite.config.mjs","vite.config.cjs"],Tt=["@slip-stream-kit/vite","@slip-stream-kit/config/vite","infra-kit/vite"];function Nt(e){for(let t of he){let r=a.join(e,t);if(p.existsSync(r))try{let n=p.readFileSync(r,"utf-8");return Tt.some(o=>n.includes(o))}catch{return!1}}return!1}function Kr(e){for(let t of he){let r=a.join(e,t);if(p.existsSync(r))try{return p.readFileSync(r,"utf-8").includes("infraKit(")}catch{return!1}}return!1}function _t(e){let t=a.join(e,"package.json");if(!p.existsSync(t))return!1;try{let r=JSON.parse(p.readFileSync(t,"utf-8"));return typeof r.scripts?.dev=="string"&&r.scripts.dev.length>0}catch{return!1}}function Wr(e){let t=a.join(e,"apps"),r=[];if(!p.existsSync(t))return r;let n=p.readdirSync(t,{withFileTypes:!0}).filter(o=>o.isDirectory()).map(o=>o.name);for(let o of n){let i=a.join(t,o,"ui");p.existsSync(i)&&_t(i)&&r.push({name:o,packageName:ge(i,o),path:i,managedPort:Nt(i)})}return r}function Fr(e){let t=e?.filter(Boolean)??[];return t.length>0?t:null}function zr(e){let t=Dt(e),r=a.relative(a.join(t,"apps"),e),n=r.split(a.sep)[0];if(r===""||r.startsWith("..")||a.isAbsolute(r)||!n)throw new Error(`--self: not inside an apps/<app> directory (cwd: ${e}). Run from an app folder or use --app=<name>.`);return n}var Lt=new Set(["api","ui"]),me=e=>{let t=a.join(e,"dist");return p.existsSync(t)&&p.statSync(t).isDirectory()?t:void 0},z=e=>p.existsSync(e)?p.readdirSync(e,{withFileTypes:!0}).filter(t=>t.isDirectory()).map(t=>t.name):[];function Gr(e){let t=[];for(let n of z(a.join(e,"packages"))){let o=me(a.join(e,"packages",n));o!==void 0&&t.push(o)}let r=a.join(e,"apps");for(let n of z(r))for(let o of z(a.join(r,n))){if(Lt.has(o))continue;let i=a.join(r,n,o);if(!p.existsSync(a.join(i,"package.json")))continue;let c=me(i);c!==void 0&&t.push(c)}return t}function Vr(e){return e.map(t=>a.join(t.path,"dist")).filter(t=>p.existsSync(t))}function qr(e,t,r){let n=a.normalize(e),o=r.find(c=>n.startsWith(a.normalize(c)));return o?{kind:"package",packageDir:o}:{kind:"app",app:t.find(c=>n.startsWith(a.normalize(c)))}}var Mt={"*/api":{},"*/ui":{}},ve=e=>{let t=e.split("/"),[r,n]=t;return t.length!==2||!r?`devServersPresets: invalid target "${e}" (expected "<app>/api" or "<app>/ui")`:n!=="api"&&n!=="ui"?`devServersPresets: invalid target part "${n}" in "${e}" (expected "api" or "ui")`:null},Ot=e=>{let t=ve(e);if(t)throw new Error(t);let[r,n]=e.split("/");return{appGlob:r,part:n}},Ur=e=>{let t=[];for(let[r,n]of Object.entries(e))for(let o of Object.keys(n.apps??{})){let i=ve(o);i&&t.push({preset:r,key:o,message:`preset "${r}": ${i}`})}return t},Kt=(e,t)=>t==="api"?e.api:e.ui,Wt=e=>[...new Set([...e.api,...e.ui])].sort(),ye=(e,t)=>`${e}/${t}`,Ft=e=>e?0:1,zt=(e,t)=>t.watchDeps===void 0?e??{watchDeps:!0,rank:t.rank,explicitValue:!1}:!e||!e.explicitValue?{watchDeps:t.watchDeps,rank:t.rank,explicitValue:!0}:t.rank>e.rank?{watchDeps:t.watchDeps,rank:t.rank,explicitValue:!0}:e,Gt=(e,t,r)=>{let{app:n,part:o,watchDeps:i,isGlob:c}=r;if(!Kt(t,o).includes(n)){c||e.unmatched.push(ye(n,o));return}let u=ye(n,o),l=zt(e.targets.get(u),{watchDeps:i,rank:Ft(c)});e.targets.set(u,{app:n,part:o,...l})},Vt=(e,t)=>{let r=Object.entries(e.apps??Mt),n={targets:new Map,proxy:{},unmatched:[]};for(let[c,u]of r){let{appGlob:l,part:h}=Ot(c),y=l==="*",S=y?Wt(t):[l];for(let I of S)Gt(n,t,{app:I,part:h,watchDeps:u.watchDeps,isGlob:y}),u.proxy&&(n.proxy[I]={...n.proxy[I]??{},...u.proxy})}let o=[...n.targets.values()].map(({app:c,part:u,watchDeps:l})=>({app:c,part:u,watchDeps:l})),i=[...new Set(o.filter(c=>c.part==="api").map(c=>c.app))];return{targets:o,cmux:e.cmux??!1,proxy:n.proxy,localApps:i,unmatched:n.unmatched}},Hr=e=>{if(e.preset!=null)return e.preset;if(e.running.length===0)return"nothing";let t=new Set(e.running);return e.discovered.every(n=>t.has(n))?"*":[...t].sort().join(" + ")},qt=(e,t)=>Object.keys(e).find(r=>e[r]===t),Bt=({preset:e,app:t,route:r,launchedPkgs:n,ctx:o})=>{let i=o.routePkg(t,r);if(i===void 0)return{preset:e,app:t,route:r,kind:"unknown-route",message:`preset "${e}": proxy override "${r}" on "${t}" names a route not declared in ${t}'s infra-kit.config.ts dev.proxy.routes`};if(n.has(i))return null;let c=qt(o.apiPkgByApp,i),u=c?`add "${c}/api" to the preset`:`launch the api whose package is "${i}"`;return{preset:e,app:t,route:r,pkg:i,kind:"backend-not-launched",message:`preset "${e}": proxy override "${r}" \u2192 "local" requires backend "${i}" to run locally, but the preset does not launch it \u2014 ${u}, or set "${r}" to "cloud"`}},Xr=(e,t)=>{let r=[];for(let[n,o]of Object.entries(e)){let i=Vt(o,t.discovered),c=new Set(i.localApps.map(u=>t.apiPkgByApp[u]).filter(u=>u!==void 0));for(let[u,l]of Object.entries(i.proxy))for(let[h,y]of Object.entries(l)){if(y!=="local")continue;let S=Bt({preset:n,app:u,route:h,launchedPkgs:c,ctx:t});S&&r.push(S)}}return r};export{w as a,d as b,U as c,P as d,v as e,T as f,N as g,Se as h,Ce as i,je as j,Ie as k,Ae as l,$e as m,_ as n,De as o,ee as p,Te as q,b as r,L as s,te as t,re as u,Le as v,Me as w,Oe as x,Ke as y,We as z,Fe as A,ze as B,Ge as C,Ve as D,O as E,qe as F,Be as G,Ue as H,V as I,Jt as J,Yt as K,xt as L,ue as M,le as N,wt as O,bt as P,de as Q,Rt as R,Et as S,St as T,Dt as U,Or as V,Kr as W,Wr as X,Fr as Y,zr as Z,Gr as _,Vr as $,qr as aa,ve as ba,Ur as ca,Vt as da,Hr as ea,Xr as fa};
8
- //# sourceMappingURL=chunk-63VNUKUS.js.map
8
+ //# sourceMappingURL=chunk-5FYZAIFC.js.map
@@ -1,2 +1,2 @@
1
- import{j as L,m as I,n as R}from"./chunk-HHWP3YXW.js";import{e as E}from"./chunk-NFIFWIO6.js";import g from"node:fs";import{homedir as ce}from"node:os";import{dirname as v,join as C}from"node:path";import O from"node:process";import{fileURLToPath as ue}from"node:url";import{execFile as j}from"node:child_process";import{createHash as H}from"node:crypto";import{existsSync as _,readFileSync as f}from"node:fs";import G from"node:http";import K from"node:https";import q from"node:net";import{homedir as z}from"node:os";import{dirname as y,join as u}from"node:path";import m from"node:process";import J from"node:tls";import{fileURLToPath as V}from"node:url";import{promisify as $}from"node:util";var U=/^[\w@%+=:,./-]+$/,F="'\\''",A=e=>U.test(e)?e:`'${e.replaceAll("'",F)}'`,P=e=>e.map(A).join(" ");var W=$(j),Q=e=>{let r=JSON.parse(f(e,"utf-8")),t=typeof r.bin=="string"?r.bin:r.bin?.portless;return t==null||t===""?null:t},x=()=>{try{let e=y(V(import.meta.url));for(;;){let r=u(e,"node_modules","portless","package.json");if(_(r)){let n=Q(r);return n==null?null:u(y(r),n)}let t=y(e);if(t===e)return null;e=t}}catch{return null}},h,w=()=>(h===void 0&&(h=x()),h),N=(e,r)=>{let t=[r.execPath??m.execPath,r.bin,...e];return(r.sudo===!0?"sudo ":"")+P(t)},X=1500,S=1500,Y="x-portless",b="127.0.0.1",Z="localhost",ee="sh.portless.proxy",te=`/Library/LaunchDaemons/${ee}.plist`,re="/etc/systemd/system/portless.service",Be="portless",ne=(e=_)=>{try{return m.platform==="darwin"?e(te)?"yes":"no":m.platform==="linux"?e(re)?"yes":"no":"unknown"}catch{return"unknown"}},oe=e=>new Promise(r=>{let t=q.connect({host:b,port:e}),n=o=>{t.destroy(),r(o)};t.setTimeout(S),t.once("connect",()=>{n(!0)}),t.once("timeout",()=>{n(!1)}),t.once("error",()=>{n(!1)})}),se=(e,r)=>new Promise(t=>{let o=(r?K.request:G.request)({host:b,port:e,method:"HEAD",path:"/",timeout:S,...r?{rejectUnauthorized:!1,servername:Z}:{}},s=>{s.resume(),t(s.headers[Y]==="1")});o.on("error",()=>{t(!1)}),o.on("timeout",()=>{o.destroy(),t(!1)}),o.end()}),ie=async(e,{timeoutMs:r})=>{let t=w();if(t==null)throw new Error("portless is not installed (not resolvable from node_modules)");await W(m.execPath,[t,...e],{signal:AbortSignal.timeout(r),encoding:"utf-8",env:R(m.env)})},k=()=>m.env.PORTLESS_STATE_DIR??u(z(),".portless"),ae="ca.pem",le="ca.trusted",T=()=>u(k(),ae),Ue=()=>{try{let e=f(u(k(),le),"utf-8").trim();return e===""?!1:H("sha256").update(f(T())).digest("hex")===e.toLowerCase()}catch{return!1}},Fe=(e,r)=>new Promise(t=>{let n;try{n=f(T())}catch{t({ok:!1,code:"ENOENT"});return}let o=J.connect({host:b,port:e,servername:r,ca:[n],rejectUnauthorized:!0},()=>{let s=o.authorizationError,c=o.authorized;o.destroy(),t(c?{ok:!0}:{ok:!1,code:s?.code??s?.message??"UNKNOWN"})});o.setTimeout(S),o.once("timeout",()=>{o.destroy(),t({ok:!1,code:"ETIMEDOUT"})}),o.once("error",s=>{o.destroy(),t({ok:!1,code:s.code??"UNKNOWN"})})}),je=()=>{try{let e=JSON.parse(f(u(k(),"routes.json"),"utf-8"));return Array.isArray(e)?e.flatMap(r=>{let{hostname:t,port:n}=r??{};return typeof t!="string"||t===""||typeof n!="number"?[]:[{name:t,port:n}]}):[]}catch{return[]}},He=(e={})=>{let r=e.bin===void 0?w():e.bin,t=e.run??ie,n=e.isListening??oe,o=e.isProxyServing??se,s=e.isServiceInstalled??ne,c=e.timeoutMs??X,a=null,l=async i=>{try{return await t(i,{timeoutMs:c}),!0}catch{return!1}},d=async()=>(a??=await l(["--version"]),a);return{binPath:()=>r,isAvailable:d,isProxyServing:async(i,p)=>!await d()||!await n(i)?!1:o(i,p),probeProxy:async(i,p)=>await n(i)?await o(i,p)?"serving":"not-portless":"daemon-down",isServiceInstalled:s,registerAlias:async(i,p)=>await d()?l(["alias",i,String(p)]):!1,removeAlias:async i=>{await d()&&await l(["alias","--remove",i])}}};var D=e=>C(e,E,"portless"),me=(e,r=g.existsSync)=>{let t=C(D(e),"dist","cli.js");return r(t)?t:null},Xe=(e,r)=>N(["service","install"],{sudo:!0,bin:me(r.home,r.exists)??e,execPath:r.execPath}),M=Symbol("absent"),B=Symbol("not-a-symlink"),pe=(e,r)=>{let t=r.lstatSync(e,{throwIfNoEntry:!1});return t===void 0?M:t.isSymbolicLink()?r.readlinkSync(e):B},fe=(e,r,t)=>{let n=`${r}.tmp-${O.pid}`;try{t.unlinkSync(n)}catch{}t.symlinkSync(e,n);try{t.renameSync(n,r)}catch(o){try{t.unlinkSync(n)}catch{}throw o}},de=e=>{let{resolveBin:r,isGlobal:t,home:n,fs:o=g}=e,s=D(n),c=r();if(c===null)return{outcome:"skipped-unresolved",target:null,link:s};let a=v(v(c));if(!t())return{outcome:"skipped-local",target:a,link:s};try{o.mkdirSync(v(s),{recursive:!0});let l=pe(s,o);return l===a?{outcome:"unchanged",target:a,link:s}:l===B?{outcome:"failed",target:a,link:s}:(fe(a,s,o),{outcome:l===M?"created":"repointed",target:a,link:s})}catch{return{outcome:"failed",target:a,link:s}}},ge=()=>{let e=ce();return{resolveBin:x,isGlobal:()=>L({selfRealPath:g.realpathSync(ue(import.meta.url)),env:O.env,realpath:I,home:e,exists:g.existsSync}),home:e}},Ye=(e,r)=>{try{e(de(r??ge()),"portless link")}catch{}};export{P as a,x as b,N as c,ee as d,te as e,re as f,Be as g,oe as h,se as i,k as j,T as k,Ue as l,Fe as m,je as n,He as o,D as p,me as q,Xe as r,de as s,ge as t,Ye as u};
2
- //# sourceMappingURL=chunk-LDF2KOGN.js.map
1
+ import{j as L,m as I,n as R}from"./chunk-HHWP3YXW.js";import{e as E}from"./chunk-75URROMU.js";import g from"node:fs";import{homedir as ce}from"node:os";import{dirname as v,join as C}from"node:path";import O from"node:process";import{fileURLToPath as ue}from"node:url";import{execFile as j}from"node:child_process";import{createHash as H}from"node:crypto";import{existsSync as _,readFileSync as f}from"node:fs";import G from"node:http";import K from"node:https";import q from"node:net";import{homedir as z}from"node:os";import{dirname as y,join as u}from"node:path";import m from"node:process";import J from"node:tls";import{fileURLToPath as V}from"node:url";import{promisify as $}from"node:util";var U=/^[\w@%+=:,./-]+$/,F="'\\''",A=e=>U.test(e)?e:`'${e.replaceAll("'",F)}'`,P=e=>e.map(A).join(" ");var W=$(j),Q=e=>{let r=JSON.parse(f(e,"utf-8")),t=typeof r.bin=="string"?r.bin:r.bin?.portless;return t==null||t===""?null:t},x=()=>{try{let e=y(V(import.meta.url));for(;;){let r=u(e,"node_modules","portless","package.json");if(_(r)){let n=Q(r);return n==null?null:u(y(r),n)}let t=y(e);if(t===e)return null;e=t}}catch{return null}},h,w=()=>(h===void 0&&(h=x()),h),N=(e,r)=>{let t=[r.execPath??m.execPath,r.bin,...e];return(r.sudo===!0?"sudo ":"")+P(t)},X=1500,S=1500,Y="x-portless",b="127.0.0.1",Z="localhost",ee="sh.portless.proxy",te=`/Library/LaunchDaemons/${ee}.plist`,re="/etc/systemd/system/portless.service",Be="portless",ne=(e=_)=>{try{return m.platform==="darwin"?e(te)?"yes":"no":m.platform==="linux"?e(re)?"yes":"no":"unknown"}catch{return"unknown"}},oe=e=>new Promise(r=>{let t=q.connect({host:b,port:e}),n=o=>{t.destroy(),r(o)};t.setTimeout(S),t.once("connect",()=>{n(!0)}),t.once("timeout",()=>{n(!1)}),t.once("error",()=>{n(!1)})}),se=(e,r)=>new Promise(t=>{let o=(r?K.request:G.request)({host:b,port:e,method:"HEAD",path:"/",timeout:S,...r?{rejectUnauthorized:!1,servername:Z}:{}},s=>{s.resume(),t(s.headers[Y]==="1")});o.on("error",()=>{t(!1)}),o.on("timeout",()=>{o.destroy(),t(!1)}),o.end()}),ie=async(e,{timeoutMs:r})=>{let t=w();if(t==null)throw new Error("portless is not installed (not resolvable from node_modules)");await W(m.execPath,[t,...e],{signal:AbortSignal.timeout(r),encoding:"utf-8",env:R(m.env)})},k=()=>m.env.PORTLESS_STATE_DIR??u(z(),".portless"),ae="ca.pem",le="ca.trusted",T=()=>u(k(),ae),Ue=()=>{try{let e=f(u(k(),le),"utf-8").trim();return e===""?!1:H("sha256").update(f(T())).digest("hex")===e.toLowerCase()}catch{return!1}},Fe=(e,r)=>new Promise(t=>{let n;try{n=f(T())}catch{t({ok:!1,code:"ENOENT"});return}let o=J.connect({host:b,port:e,servername:r,ca:[n],rejectUnauthorized:!0},()=>{let s=o.authorizationError,c=o.authorized;o.destroy(),t(c?{ok:!0}:{ok:!1,code:s?.code??s?.message??"UNKNOWN"})});o.setTimeout(S),o.once("timeout",()=>{o.destroy(),t({ok:!1,code:"ETIMEDOUT"})}),o.once("error",s=>{o.destroy(),t({ok:!1,code:s.code??"UNKNOWN"})})}),je=()=>{try{let e=JSON.parse(f(u(k(),"routes.json"),"utf-8"));return Array.isArray(e)?e.flatMap(r=>{let{hostname:t,port:n}=r??{};return typeof t!="string"||t===""||typeof n!="number"?[]:[{name:t,port:n}]}):[]}catch{return[]}},He=(e={})=>{let r=e.bin===void 0?w():e.bin,t=e.run??ie,n=e.isListening??oe,o=e.isProxyServing??se,s=e.isServiceInstalled??ne,c=e.timeoutMs??X,a=null,l=async i=>{try{return await t(i,{timeoutMs:c}),!0}catch{return!1}},d=async()=>(a??=await l(["--version"]),a);return{binPath:()=>r,isAvailable:d,isProxyServing:async(i,p)=>!await d()||!await n(i)?!1:o(i,p),probeProxy:async(i,p)=>await n(i)?await o(i,p)?"serving":"not-portless":"daemon-down",isServiceInstalled:s,registerAlias:async(i,p)=>await d()?l(["alias",i,String(p)]):!1,removeAlias:async i=>{await d()&&await l(["alias","--remove",i])}}};var D=e=>C(e,E,"portless"),me=(e,r=g.existsSync)=>{let t=C(D(e),"dist","cli.js");return r(t)?t:null},Xe=(e,r)=>N(["service","install"],{sudo:!0,bin:me(r.home,r.exists)??e,execPath:r.execPath}),M=Symbol("absent"),B=Symbol("not-a-symlink"),pe=(e,r)=>{let t=r.lstatSync(e,{throwIfNoEntry:!1});return t===void 0?M:t.isSymbolicLink()?r.readlinkSync(e):B},fe=(e,r,t)=>{let n=`${r}.tmp-${O.pid}`;try{t.unlinkSync(n)}catch{}t.symlinkSync(e,n);try{t.renameSync(n,r)}catch(o){try{t.unlinkSync(n)}catch{}throw o}},de=e=>{let{resolveBin:r,isGlobal:t,home:n,fs:o=g}=e,s=D(n),c=r();if(c===null)return{outcome:"skipped-unresolved",target:null,link:s};let a=v(v(c));if(!t())return{outcome:"skipped-local",target:a,link:s};try{o.mkdirSync(v(s),{recursive:!0});let l=pe(s,o);return l===a?{outcome:"unchanged",target:a,link:s}:l===B?{outcome:"failed",target:a,link:s}:(fe(a,s,o),{outcome:l===M?"created":"repointed",target:a,link:s})}catch{return{outcome:"failed",target:a,link:s}}},ge=()=>{let e=ce();return{resolveBin:x,isGlobal:()=>L({selfRealPath:g.realpathSync(ue(import.meta.url)),env:O.env,realpath:I,home:e,exists:g.existsSync}),home:e}},Ye=(e,r)=>{try{e(de(r??ge()),"portless link")}catch{}};export{P as a,x as b,N as c,ee as d,te as e,re as f,Be as g,oe as h,se as i,k as j,T as k,Ue as l,Fe as m,je as n,He as o,D as p,me as q,Xe as r,de as s,ge as t,Ye as u};
2
+ //# sourceMappingURL=chunk-6OFUVD7F.js.map
@@ -0,0 +1,4 @@
1
+ import O from"node:crypto";import R from"node:fs";import C from"node:os";import E from"node:path";import p from"node:process";var x="env-load.sh",S="env-clear.sh",D="projects",K=7200,I="INFRA_KIT_SESSION",L=".infra-kit",f="INFRA_KIT_ENV",d="INFRA_KIT_ENV_CONFIG",v="INFRA_KIT_ENV_PROJECT",W="INFRA_KIT_ENV_PROJECT_ROOT",y="INFRA_KIT_ENV_LOADED_AT",P="INFRA_KIT_ENV_AUTOLOADED",U="INFRA_KIT_ENV_CLEARED",h=/^([A-Z_]\w*)=/i,j=/^unset ([A-Z_]\w*)$/i,c=(t,e)=>{let r=e;for(let n=0;n<t.length;n++){if(!r&&t[n]==="\\"){n++;continue}t[n]==="'"&&(r=!r)}return r},w=t=>{let e=t.startsWith("'")?t.slice(1):t;return(e.endsWith("'")?e.slice(0,-1):e).split("'\\''").join("'")},F=t=>{try{return R.readFileSync(t,"utf-8")}catch{return""}},T=(t,e,r)=>{let n=t.split(`
2
+ `).map(s=>s.endsWith("\r")?s.slice(0,-1):s),o=0,_=!1;for(;o<n.length;){let s=n[o];if(_){_=c(s,_),o+=1;continue}let a=h.exec(s);if(!a){let i=j.exec(s);i&&r?.(i[1]),_=c(s,!1),o+=1;continue}let V=a[1],A=s.slice(a[0].length);if(!A.startsWith("'")){e({name:V,value:A}),_=c(s,!1),o+=1;continue}let m=[A],N=c(A,!1);for(;N&&o+1<n.length;){o+=1;let i=n[o];m.push(i),N=c(i,!0)}e({name:V,value:w(m.join(`
3
+ `))}),_=N,o+=1}},G=t=>{let e=[];return T(F(t),({name:r})=>{e.push(r)}),e},b=t=>{let e={};return T(F(t),({name:r,value:n})=>{e[r]=n}),e},k=t=>{let e=[];return T(F(t),()=>{},r=>{e.push(r)}),e},g=()=>{let t=p.env.XDG_CACHE_HOME,e=t&&t.length>0?t:E.join(C.homedir(),".cache");return E.join(e,"infra-kit")},H=()=>{let t=p.env[I];if(!t)throw new Error(`${I} is not set. Run \`infra-kit setup --skip-tools\` then \`source ~/.zshrc\`.`);return E.join(g(),t)},l=t=>O.createHash("sha256").update(t,"utf8").digest("hex"),u=()=>E.join(g(),D),J=t=>E.join(u(),l(t)),M=(t,e,r)=>{let n=`${t}.tmp.${p.pid}`;R.writeFileSync(n,e,{mode:r});try{R.renameSync(n,t)}catch(o){throw R.rmSync(n,{force:!0}),o}},Q="-worktrees";export{x as a,S as b,K as c,I as d,L as e,f,d as g,v as h,W as i,y as j,P as k,U as l,G as m,b as n,k as o,g as p,H as q,u as r,J as s,M as t,Q as u};
4
+ //# sourceMappingURL=chunk-75URROMU.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/lib/constants/constants.ts"],
4
+ "sourcesContent": ["import crypto from 'node:crypto'\nimport fs from 'node:fs'\nimport os from 'node:os'\nimport path from 'node:path'\nimport process from 'node:process'\n\nexport const ENV_LOAD_FILE = 'env-load.sh'\nexport const ENV_CLEAR_FILE = 'env-clear.sh'\n\n/** Subdir of the cache root holding the project-scoped WARM caches (one dir per\n * project, keyed by {@link warmCacheKey}). Kept in sync with the zsh block in\n * init.ts, which reads `$cache_root/projects/$key/env-load.sh`. */\nexport const WARM_CACHE_SUBDIR = 'projects'\n\n/**\n * Default warm-cache TTL in seconds (2h). Governs BOTH the node-side eviction\n * sweep and the zsh-side source gate (`_INFRA_KIT_WARM_TTL` in the shell block);\n * the two MUST stay equal, so this constant is the single source of truth and the\n * shell default is emitted from it. Short by design: a warm file older than this\n * is never sourced (bounds a revoked/rotated secret served at prompt-0) and is\n * deleted on the next write. The background refresh lands in ~1-2s regardless.\n */\nexport const DEFAULT_WARM_TTL_SECONDS = 2 * 60 * 60\n\nexport const INFRA_KIT_SESSION_VAR = 'INFRA_KIT_SESSION'\n/**\n * Directory under the user's home that holds all machine-local infra-kit config:\n * the runtime `infra-kit.json` merge layer, per-project overrides, the factory\n * registry (`vendor.json`), and the `portless` package link. Single source of\n * truth for `.infra-kit`.\n *\n * Defined HERE, not in `lib/infra-kit-config`, because that module pulls in zod\n * and the `ik-mcp` proxy bundle must stay Node-builtins-only (guarded in\n * `entry/__tests__/dist-shebang.test.ts`); `lib/infra-kit-config` re-exports it\n * for its existing consumers.\n */\nexport const USER_CONFIG_DIR_NAME = '.infra-kit'\n/**\n * The active environment/config NAME (e.g. `dev`, `arthur`), exported plainly so\n * non-shell consumers can read it from `process.env`. Notably `infra-kit/vite`'s\n * `infraKitDev()` reads this to interpolate the `<env>` placeholder in cloud proxy\n * targets. Mirrors {@link INFRA_KIT_ENV_CONFIG_VAR} (same value) but is the stable,\n * purpose-named handle for tooling rather than the shell session-metadata var.\n */\nexport const INFRA_KIT_ENV_VAR = 'INFRA_KIT_ENV'\nexport const INFRA_KIT_ENV_CONFIG_VAR = 'INFRA_KIT_ENV_CONFIG'\nexport const INFRA_KIT_ENV_PROJECT_VAR = 'INFRA_KIT_ENV_PROJECT'\n/**\n * Absolute project root (git top-level) the loaded env belongs to. Lets the shell\n * startup gate tell a same-project subshell (skip) from a NEW project (load), so a\n * different project's secrets are never silently kept after `cd`/new shell.\n */\nexport const INFRA_KIT_ENV_PROJECT_ROOT_VAR = 'INFRA_KIT_ENV_PROJECT_ROOT'\nexport const INFRA_KIT_ENV_LOADED_AT_VAR = 'INFRA_KIT_ENV_LOADED_AT'\n/**\n * Marker exported into env-load.sh ONLY when the load was triggered automatically\n * (see lib/env-autoload). Its presence is the sole signal distinguishing an\n * auto-loaded env from a deliberate manual `env-load`, so auto-load never\n * clobbers a manual choice. A manual load unsets it.\n */\nexport const INFRA_KIT_ENV_AUTOLOADED_VAR = 'INFRA_KIT_ENV_AUTOLOADED'\n/**\n * Suppression sentinel exported by env-clear. While set in a shell, cli-invocation\n * auto-load stays silent (a deliberate clear must not be immediately re-loaded).\n * Lifted by a manual `env-load` or a new shell.\n */\nexport const INFRA_KIT_ENV_CLEARED_VAR = 'INFRA_KIT_ENV_CLEARED'\n\n/**\n * Matches a line of the form `KEY=...` where KEY is an env-var identifier\n * (letter or underscore, then word chars). Capture group 1 is the name. Shared\n * between env-load (validation, var counting) and parseVarNamesFromEnvFile.\n */\nexport const ENV_VAR_LINE_PATTERN = /^([A-Z_]\\w*)=/i\n\n/**\n * The `unset NAME` line env-clear.sh is made of and a manual env-load.sh ends with. Anchored at\n * both ends so a value that merely starts with the word is not a match.\n */\nconst UNSET_LINE_PATTERN = /^unset ([A-Z_]\\w*)$/i\n\n/**\n * Track whether a physical line leaves us inside an open single-quoted value,\n * mirroring how `shellSingleQuote` emits values (`'\u2026'`, with literal quotes as\n * `'\\''`). Outside a quote a backslash escapes the next char; inside a quote a\n * `'` closes it. Lets the parser skip the continuation lines of a multiline value.\n */\nconst advanceSingleQuoteState = (line: string, startInQuote: boolean): boolean => {\n let inQuote = startInQuote\n\n for (let i = 0; i < line.length; i++) {\n if (!inQuote && line[i] === '\\\\') {\n i++\n continue\n }\n\n if (line[i] === \"'\") {\n inQuote = !inQuote\n }\n }\n\n return inQuote\n}\n\n/** One `KEY=value` assignment recovered from an env file, value already unescaped. */\nexport interface EnvAssignment {\n name: string\n value: string\n}\n\n/**\n * Undo {@link shellSingleQuote}: drop the wrapping quotes, then turn each `'\\''`\n * back into a literal `'`. Order matters \u2014 unescaping first would let an embedded\n * `'\\''` be mistaken for the closing quote.\n */\nconst decodeSingleQuoted = (raw: string): string => {\n const withoutOpen = raw.startsWith(\"'\") ? raw.slice(1) : raw\n const body = withoutOpen.endsWith(\"'\") ? withoutOpen.slice(0, -1) : withoutOpen\n\n return body.split(\"'\\\\''\").join(\"'\")\n}\n\n/** File contents, or '' when the path is absent, a directory, or unreadable. */\nconst readEnvFileContent = (filePath: string): string => {\n try {\n return fs.readFileSync(filePath, 'utf-8')\n } catch {\n return ''\n }\n}\n\n/**\n * Walk every assignment in an env-load.sh body, skipping the continuation lines of\n * multiline values. {@link parseVarNamesFromEnvFile}, {@link parseVarsFromEnvFile}\n * and {@link parseUnsetNamesFromEnvFile} all go through here, so they can never\n * disagree about where a value ends \u2014 an `unset X` inside a quoted value is a\n * continuation line to every one of them.\n */\nconst forEachAssignment = (\n content: string,\n visit: (assignment: EnvAssignment) => void,\n visitUnset?: (name: string) => void,\n): void => {\n // A trailing CR is stripped per line: a CRLF file would otherwise hand back values\n // ending in '\\r' \u2014 a token that looks right in a diff and fails every request.\n const lines = content.split('\\n').map((line) => {\n return line.endsWith('\\r') ? line.slice(0, -1) : line\n })\n let index = 0\n let inQuote = false\n\n while (index < lines.length) {\n const line = lines[index]!\n\n // Only a line that starts OUTSIDE a quoted value can be a real assignment;\n // continuation lines of a multiline secret value are skipped.\n if (inQuote) {\n inQuote = advanceSingleQuoteState(line, inQuote)\n index += 1\n continue\n }\n\n const match = ENV_VAR_LINE_PATTERN.exec(line)\n\n if (!match) {\n const unset = UNSET_LINE_PATTERN.exec(line)\n\n if (unset) visitUnset?.(unset[1]!)\n\n inQuote = advanceSingleQuoteState(line, false)\n index += 1\n continue\n }\n\n const name = match[1]!\n const rest = line.slice(match[0].length)\n\n // An unquoted value cannot span lines (`CONNECTION_STRING=host=db;user=admin`).\n if (!rest.startsWith(\"'\")) {\n visit({ name, value: rest })\n inQuote = advanceSingleQuoteState(line, false)\n index += 1\n continue\n }\n\n const parts = [rest]\n let open = advanceSingleQuoteState(rest, false)\n\n while (open && index + 1 < lines.length) {\n index += 1\n const continuation = lines[index]!\n\n parts.push(continuation)\n open = advanceSingleQuoteState(continuation, true)\n }\n\n visit({ name, value: decodeSingleQuoted(parts.join('\\n')) })\n inQuote = open\n index += 1\n }\n}\n\nexport const parseVarNamesFromEnvFile = (filePath: string): string[] => {\n const names: string[] = []\n\n forEachAssignment(readEnvFileContent(filePath), ({ name }) => {\n names.push(name)\n })\n\n return names\n}\n\n/**\n * Same walk as {@link parseVarNamesFromEnvFile}, but keeping the values. Later\n * assignments win, matching what `source`ing the file would do.\n */\nexport const parseVarsFromEnvFile = (filePath: string): Record<string, string> => {\n const vars: Record<string, string> = {}\n\n forEachAssignment(readEnvFileContent(filePath), ({ name, value }) => {\n vars[name] = value\n })\n\n return vars\n}\n\n/**\n * The names the file `unset`s \u2014 everything env-clear.sh does, and the marker lines a\n * manual env-load.sh ends with. Absent file \u2192 `[]`, like its siblings.\n */\nexport const parseUnsetNamesFromEnvFile = (filePath: string): string[] => {\n const names: string[] = []\n\n forEachAssignment(\n readEnvFileContent(filePath),\n () => {},\n (name) => {\n names.push(name)\n },\n )\n\n return names\n}\n\n/**\n * Root cache dir for infra-kit across all sessions. Resolved from\n * $XDG_CACHE_HOME when set, falling back to ~/.cache/infra-kit. Keep in sync\n * with the shell block emitted by `infra-kit setup` (src/commands/init/init.ts).\n */\nexport const getCacheRoot = (): string => {\n const xdg = process.env.XDG_CACHE_HOME\n const base = xdg && xdg.length > 0 ? xdg : path.join(os.homedir(), '.cache')\n\n return path.join(base, 'infra-kit')\n}\n\nexport const getSessionCacheDir = (): string => {\n const session = process.env[INFRA_KIT_SESSION_VAR]\n\n if (!session) {\n throw new Error(\n `${INFRA_KIT_SESSION_VAR} is not set. Run \\`infra-kit setup --skip-tools\\` then \\`source ~/.zshrc\\`.`,\n )\n }\n\n return path.join(getCacheRoot(), session)\n}\n\n/**\n * The warm-cache key for a project: the hex SHA-256 of its CANONICAL (realpath'd)\n * directory. This MUST be byte-identical to the zsh block's\n * `printf %s \"$canon\" | shasum -a 256 | cut -c1-64` \u2014 same input string (no\n * trailing newline), same digest, full 64-hex output \u2014 or a warm file written by\n * node is never found by the shell. The shell passes the already-canonicalized\n * dir via `--project-dir`, so node hashes that VERBATIM (it does not re-resolve).\n */\nexport const warmCacheKey = (canonicalProjectDir: string): string => {\n return crypto.createHash('sha256').update(canonicalProjectDir, 'utf8').digest('hex')\n}\n\n/** Root holding all project-scoped warm caches: `$cacheRoot/projects`. */\nexport const getWarmCacheRoot = (): string => {\n return path.join(getCacheRoot(), WARM_CACHE_SUBDIR)\n}\n\n/** This project's warm-cache dir: `$cacheRoot/projects/<warmCacheKey>`. */\nexport const getProjectWarmCacheDir = (canonicalProjectDir: string): string => {\n return path.join(getWarmCacheRoot(), warmCacheKey(canonicalProjectDir))\n}\n\n/**\n * Write content atomically: write to a pid-suffixed temp file in the same\n * directory, then rename. fs.renameSync is atomic on a single filesystem, so\n * concurrent writers can't produce a half-written secret file.\n */\nexport const atomicWriteFileSync = (filePath: string, content: string, mode: number): void => {\n const tmpPath = `${filePath}.tmp.${process.pid}`\n\n fs.writeFileSync(tmpPath, content, { mode })\n\n try {\n fs.renameSync(tmpPath, filePath)\n } catch (error) {\n fs.rmSync(tmpPath, { force: true })\n throw error\n }\n}\n\nexport const WORKTREES_DIR_SUFFIX = '-worktrees'\n// eslint-disable-next-line sonarjs/publicly-writable-directories\nexport const LOG_FILE_PATH = '/tmp/mcp-infra-kit.log'\n"],
5
+ "mappings": "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",
6
+ "names": ["crypto", "fs", "os", "path", "process", "ENV_LOAD_FILE", "ENV_CLEAR_FILE", "WARM_CACHE_SUBDIR", "DEFAULT_WARM_TTL_SECONDS", "INFRA_KIT_SESSION_VAR", "USER_CONFIG_DIR_NAME", "INFRA_KIT_ENV_VAR", "INFRA_KIT_ENV_CONFIG_VAR", "INFRA_KIT_ENV_PROJECT_VAR", "INFRA_KIT_ENV_PROJECT_ROOT_VAR", "INFRA_KIT_ENV_LOADED_AT_VAR", "INFRA_KIT_ENV_AUTOLOADED_VAR", "INFRA_KIT_ENV_CLEARED_VAR", "ENV_VAR_LINE_PATTERN", "UNSET_LINE_PATTERN", "advanceSingleQuoteState", "line", "startInQuote", "inQuote", "i", "decodeSingleQuoted", "raw", "withoutOpen", "readEnvFileContent", "filePath", "forEachAssignment", "content", "visit", "visitUnset", "lines", "index", "match", "unset", "name", "rest", "parts", "open", "continuation", "parseVarNamesFromEnvFile", "names", "parseVarsFromEnvFile", "vars", "value", "parseUnsetNamesFromEnvFile", "getCacheRoot", "xdg", "base", "getSessionCacheDir", "session", "warmCacheKey", "canonicalProjectDir", "getWarmCacheRoot", "getProjectWarmCacheDir", "atomicWriteFileSync", "mode", "tmpPath", "error", "WORKTREES_DIR_SUFFIX"]
7
+ }
@@ -1,7 +1,7 @@
1
- import{K as f,Q as k,b as y,d as T}from"./chunk-63VNUKUS.js";import{s as O}from"./chunk-NFIFWIO6.js";import{a as S,b as P}from"./chunk-QWVLAZ6N.js";import u from"node:fs/promises";import c from"node:path";import{z as s}from"zod";var i=class extends Error{env;constructor(t,o=null){super(t),this.name="EnvAuthError",this.env=o}},L=e=>e instanceof i;import N from"node:fs/promises";import I from"node:os";var j=async e=>{try{return await N.access(e),!0}catch{return!1}},d=e=>{let t=I.homedir();return e.startsWith(t)?`~${e.slice(t.length)}`:e};var _="tokens.json",h=1,b=384,C=448,A=s.object({version:s.literal(h).default(h),envs:s.record(s.string().min(1),s.string().min(1))}).strict(),g=async()=>{let e=await k();return c.join(c.dirname(e.userProject),_)},v=async()=>{let e=await g(),t;try{t=await u.readFile(e,"utf-8")}catch{return null}let o;try{o=JSON.parse(t)}catch(n){throw new i(`Invalid JSON in the token store at ${d(e)}: ${n.message}
1
+ import{K as f,Q as k,b as y,d as T}from"./chunk-5FYZAIFC.js";import{t as O}from"./chunk-75URROMU.js";import{a as S,b as P}from"./chunk-QWVLAZ6N.js";import u from"node:fs/promises";import c from"node:path";import{z as s}from"zod";var i=class extends Error{env;constructor(t,o=null){super(t),this.name="EnvAuthError",this.env=o}},L=e=>e instanceof i;import N from"node:fs/promises";import I from"node:os";var j=async e=>{try{return await N.access(e),!0}catch{return!1}},d=e=>{let t=I.homedir();return e.startsWith(t)?`~${e.slice(t.length)}`:e};var _="tokens.json",h=1,b=384,C=448,A=s.object({version:s.literal(h).default(h),envs:s.record(s.string().min(1),s.string().min(1))}).strict(),g=async()=>{let e=await k();return c.join(c.dirname(e.userProject),_)},v=async()=>{let e=await g(),t;try{t=await u.readFile(e,"utf-8")}catch{return null}let o;try{o=JSON.parse(t)}catch(n){throw new i(`Invalid JSON in the token store at ${d(e)}: ${n.message}
2
2
  Fix or delete the file, then re-add the token with \`infra-kit env-token-set <env>\`.`)}let r=A.safeParse(o);if(!r.success)throw new i(`Invalid token store at ${d(e)}: ${s.prettifyError(r.error)}
3
3
  Fix or delete the file, then re-add the token with \`infra-kit env-token-set <env>\`.`);return r.data},x=async e=>{let t=await g(),o=c.dirname(t),r=c.dirname(o),n=c.dirname(r);for(let a of[n,r,o])await u.mkdir(a,{recursive:!0,mode:C}),await u.chmod(a,C);O(t,`${JSON.stringify(e,null,2)}
4
4
  `,b),await u.chmod(t,b)},F=async(e,t)=>{let o=await v();await x({version:h,envs:{...o?.envs,[e]:t}})},H=async e=>{let t=await v();if(!t||!(e in t.envs))return;let o={...t.envs};delete o[e],await x({version:h,envs:o})};var M=()=>{let e="",t=[],o=!1;return{start(r){e=r,t=[],o=!1},setInteractive(){o=!0},addOption(r,n){t.push({flag:r,value:n})},formatOptions(){return t.map(r=>typeof r.value=="boolean"?r.value?r.flag:"":Array.isArray(r.value)?`${r.flag} "${r.value.join(", ")}"`:`${r.flag} "${r.value}"`).filter(Boolean).join(" ")},snapshot(){return t.length===0?null:{formattedOptions:this.formatOptions()}},print(){!o||t.length===0||!e||f.info(`\u{1F4DF} Equivalent command:
5
5
  pnpm exec infra-kit ${e} ${this.formatOptions()}
6
6
  `)},reset(){e="",t=[],o=!1}}},w=M();import D from"node:process";var R=27,J=e=>{if(typeof e=="object")return e.value;throw new y(void 0,{operation:"interactive prompt",remediation:e==="unreachable"?"this prompt is declared unreachable under MCP because a required field should block the path \u2014 reaching it means that field was relaxed without updating the call site":"pass the value explicitly instead of relying on the prompt \u2014 MCP runs have no human to answer it",stderrExcerpt:"an interactive prompt was reached under MCP, where stdin carries JSON-RPC"})},$=async(e,t)=>{let o=new AbortController,{whenHeadless:r="refuse",...n}=t??{},a={...n,signal:o.signal};if(T())return J(r);if(!D.stdin.isTTY)return e(a);let m=D.stdin,E=p=>{p.length===1&&p[0]===R&&o.abort()};S();try{let p=e(a);return m.isPaused()&&m.resume(),m.on("data",E),await p}finally{m.removeListener("data",E),P()}};import B from"@inquirer/confirm";import K from"node:process";var l=class extends Error{constructor(t="Operation cancelled by the operator"){super(t),this.name="CommandDeclinedError"}},ue=e=>e instanceof l;var q=async(e,t,o={})=>{let r=e?!0:await $(n=>B({message:t},n),{whenHeadless:"refuse"});if(e||w.setInteractive(),!r){if(o.throwOnDecline)throw new l;f.info("Operation cancelled. Exiting..."),K.exit(0)}};export{i as a,L as b,j as c,d,g as e,v as f,F as g,H as h,w as i,ue as j,$ as k,q as l};
7
- //# sourceMappingURL=chunk-YKCY657C.js.map
7
+ //# sourceMappingURL=chunk-GFKYWEPW.js.map