infra-kit 0.3.6 → 0.3.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/boot-HP5ORQEX.js +2 -0
  2. package/dist/boot-HP5ORQEX.js.map +7 -0
  3. package/dist/{chunk-T74NOBEP.js → chunk-3LPUAYWA.js} +2 -2
  4. package/dist/{chunk-T74NOBEP.js.map → chunk-3LPUAYWA.js.map} +1 -1
  5. package/dist/chunk-7DL27USH.js +7 -0
  6. package/dist/{chunk-GZNE5CBQ.js.map → chunk-7DL27USH.js.map} +3 -3
  7. package/dist/chunk-KAWDTA5H.js +2 -0
  8. package/dist/chunk-KAWDTA5H.js.map +7 -0
  9. package/dist/{chunk-A7FAXZGI.js → chunk-LKKKDB6V.js} +1 -1
  10. package/dist/{chunk-A7FAXZGI.js.map → chunk-LKKKDB6V.js.map} +1 -1
  11. package/dist/chunk-PZU6BLQR.js +4 -0
  12. package/dist/{chunk-IVWPZEMC.js.map → chunk-PZU6BLQR.js.map} +3 -3
  13. package/dist/chunk-RDRJX6TT.js +232 -0
  14. package/dist/chunk-RDRJX6TT.js.map +7 -0
  15. package/dist/chunk-X46DP23W.js +2 -0
  16. package/dist/chunk-X46DP23W.js.map +7 -0
  17. package/dist/chunk-XTRPE4SX.js +2 -0
  18. package/dist/chunk-XTRPE4SX.js.map +7 -0
  19. package/dist/cli.js +8 -8
  20. package/dist/cli.js.map +3 -3
  21. package/dist/dev-server.js +3 -3
  22. package/dist/dev-server.js.map +2 -2
  23. package/dist/dev-wizard-run-KIOSJM4D.js +2 -0
  24. package/dist/dev-wizard-run-KIOSJM4D.js.map +7 -0
  25. package/dist/mcp.js +1 -1
  26. package/dist/mcp.js.map +1 -1
  27. package/dist/update-check.js +1 -1
  28. package/package.json +1 -1
  29. package/dist/boot-FHXCA53R.js +0 -2
  30. package/dist/boot-FHXCA53R.js.map +0 -7
  31. package/dist/chunk-3G6O7MCC.js +0 -231
  32. package/dist/chunk-3G6O7MCC.js.map +0 -7
  33. package/dist/chunk-EX66ZFV5.js +0 -2
  34. package/dist/chunk-EX66ZFV5.js.map +0 -7
  35. package/dist/chunk-GZNE5CBQ.js +0 -7
  36. package/dist/chunk-IVWPZEMC.js +0 -4
  37. package/dist/chunk-S45AAYXO.js +0 -4
  38. package/dist/chunk-S45AAYXO.js.map +0 -7
  39. package/dist/dev-wizard-run-5ST3BJ4L.js +0 -2
  40. package/dist/dev-wizard-run-5ST3BJ4L.js.map +0 -7
@@ -1,2 +1,2 @@
1
1
  var r=t=>Object.fromEntries(Object.entries(t).filter(([e])=>!e.startsWith("npm_")&&e!=="PNPM_SCRIPT_SRC_DIR")),o=/^npm_config_(?:prefix|registry)$/i,a=t=>{let e=r(t);for(let[n,s]of Object.entries(t))o.test(n)&&(e[n]=s);return e};export{r as a,a as b};
2
- //# sourceMappingURL=chunk-A7FAXZGI.js.map
2
+ //# sourceMappingURL=chunk-LKKKDB6V.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/lib/pm-env/pm-env.ts"],
4
- "sourcesContent": ["/**\n * `env` minus every package-manager marker a spawned child could mistake for a throwaway install.\n *\n * Any child we launch through `node <bin>` (the portless driver, self-update, the mcp launcher) inherits\n * our env, and a tool that sniffs those markers will conclude it was run via `npx`/`pnpm dlx` and refuse\n * to work. portless is the motivating case; its guard (cli.js `main()`) is:\n *\n * isNpx = npm_command === 'exec' && !npm_lifecycle_event\n * isPnpmDlx = !!PNPM_SCRIPT_SRC_DIR && !npm_lifecycle_event\n * if ((isNpx || isPnpmDlx) && !isLocallyInstalled()) \u2192 abort\n *\n * `isLocallyInstalled()` walks up from the CHILD's cwd, so in a consumer repo (where portless is a\n * transitive dep of infra-kit, absent from the root `node_modules`) it is false and the guard is live.\n * `pnpm exec infra-kit dev` exports `npm_command=exec` with no lifecycle event \u2192 `isNpx` \u2192 every\n * portless call exits 1 \u2192 `isAvailable()` is false \u2192 `ensureProxy` aborts the whole dev boot with\n * \"portless is not installed\", on a machine where it plainly is.\n *\n * `PNPM_SCRIPT_SRC_DIR` must be dropped ALONGSIDE the `npm_*` block, not left behind: it is set by\n * `pnpm run <script>`, where `npm_lifecycle_event` is what suppresses `isPnpmDlx`. Stripping only\n * `npm_*` removes that suppressor and *creates* an abort for the script-style invocation that\n * previously worked. Both markers go, or neither is safe.\n *\n * The result makes the child look exactly like a direct `node <pkg>/dist/cli.js` run \u2014 which it is.\n */\nexport const withoutPackageManagerEnv = (env: NodeJS.ProcessEnv): NodeJS.ProcessEnv => {\n return Object.fromEntries(\n Object.entries(env).filter(([key]) => {\n return !key.startsWith('npm_') && key !== 'PNPM_SCRIPT_SRC_DIR'\n }),\n )\n}\n\n/**\n * npm's own configuration \u2014 as opposed to the npx/dlx *markers* above. Case-insensitive because npm reads\n * `npm_config_*` case-insensitively (its parser matches `/^npm_config_/i`) and real environments export\n * both forms: shells write the lowercase name, Dockerfiles and CI images overwhelmingly write the\n * uppercase one.\n */\nconst NPM_CONFIG_TO_PRESERVE = /^npm_config_(?:prefix|registry)$/i\n\n/**\n * The env for spawning a package-manager INSTALL: npx/dlx markers stripped, but npm's own config kept.\n *\n * {@link withoutPackageManagerEnv} is deliberately a blunt `npm_*` prefix filter, and it is the right tool\n * for the portless driver \u2014 but it is the WRONG tool for spawning an install, because it also drops the two\n * variables that tell the package manager *where* and *from where* to install:\n *\n * - `npm_config_prefix` is the npm matcher's ONLY signal (see `install-manager.ts`). Strip it and we\n * detect a global install rooted at prefix P, then run the install with P erased \u2014 so it lands in the\n * DEFAULT prefix instead. That is either a permanent EACCES, or a second global copy that is not the\n * one on PATH. Nothing notices: the install exits 0, we report `installed`, the version on PATH never\n * moves, and the whole cycle repeats every 24h forever. `export npm_config_prefix=~/.npm-global` is\n * npm's own documented EACCES workaround, so this is a mainstream layout, not an exotic one.\n * - `npm_config_registry` is what the update CHECK already used to pick a registry. Dropping it here\n * means we decide against a corporate mirror and then install from somewhere else.\n *\n * Preserving these cannot re-arm the dlx guard: that guard reads `npm_command`, `npm_lifecycle_event`, and\n * `PNPM_SCRIPT_SRC_DIR` \u2014 none of which are npm *config*, and all of which remain stripped.\n *\n * @example\n * packageManagerInstallEnv({ npm_command: 'exec', npm_config_prefix: '/p', PATH: '/bin' })\n * // => { npm_config_prefix: '/p', PATH: '/bin' }\n */\nexport const packageManagerInstallEnv = (env: NodeJS.ProcessEnv): NodeJS.ProcessEnv => {\n const sanitised = withoutPackageManagerEnv(env)\n\n for (const [key, value] of Object.entries(env)) {\n if (NPM_CONFIG_TO_PRESERVE.test(key)) sanitised[key] = value\n }\n\n return sanitised\n}\n"],
4
+ "sourcesContent": ["/**\n * `env` minus every package-manager marker a spawned child could mistake for a throwaway install.\n *\n * Any child we launch through `node <bin>` (the portless driver, self-update, the mcp launcher) inherits\n * our env, and a tool that sniffs those markers will conclude it was run via `npx`/`pnpm dlx` and refuse\n * to work. portless is the motivating case; its guard (cli.js `main()`) is:\n *\n * isNpx = npm_command === 'exec' && !npm_lifecycle_event\n * isPnpmDlx = !!PNPM_SCRIPT_SRC_DIR && !npm_lifecycle_event\n * if ((isNpx || isPnpmDlx) && !isLocallyInstalled()) \u2192 abort\n *\n * `isLocallyInstalled()` walks up from the CHILD's cwd, so in a consumer repo (where portless is a\n * transitive dep of infra-kit, absent from the root `node_modules`) it is false and the guard is live.\n * `pnpm exec infra-kit dev` exports `npm_command=exec` with no lifecycle event \u2192 `isNpx` \u2192 every\n * portless call exits 1 \u2192 `isAvailable()` is false \u2192 `ensureProxy` aborts the whole dev boot with\n * \"portless is not installed\", on a machine where it plainly is.\n *\n * `PNPM_SCRIPT_SRC_DIR` must be dropped ALONGSIDE the `npm_*` block, not left behind: it is set by\n * `pnpm run <script>`, where `npm_lifecycle_event` is what suppresses `isPnpmDlx`. Stripping only\n * `npm_*` removes that suppressor and *creates* an abort for the script-style invocation that\n * previously worked. Both markers go, or neither is safe.\n *\n * The result makes the child look exactly like a direct `node <pkg>/dist/cli.js` run \u2014 which it is.\n */\nexport const withoutPackageManagerEnv = (env: NodeJS.ProcessEnv): NodeJS.ProcessEnv => {\n return Object.fromEntries(\n Object.entries(env).filter(([key]) => {\n return !key.startsWith('npm_') && key !== 'PNPM_SCRIPT_SRC_DIR'\n }),\n )\n}\n\n/**\n * npm's own configuration \u2014 as opposed to the npx/dlx *markers* above. Case-insensitive because npm reads\n * `npm_config_*` case-insensitively (its parser matches `/^npm_config_/i`) and real environments export\n * both forms: shells write the lowercase name, Dockerfiles and CI images overwhelmingly write the\n * uppercase one.\n */\nconst NPM_CONFIG_TO_PRESERVE = /^npm_config_(?:prefix|registry)$/i\n\n/**\n * The env for spawning a package-manager INSTALL: npx/dlx markers stripped, but npm's own config kept.\n *\n * {@link withoutPackageManagerEnv} is deliberately a blunt `npm_*` prefix filter, and it is the right tool\n * for the portless driver \u2014 but it is the WRONG tool for spawning an install, because it also drops the two\n * variables that tell the package manager *where* and *from where* to install:\n *\n * - `npm_config_prefix` is the npm matcher's ONLY signal (see `install-manager.ts`). Strip it and we\n * detect a global install rooted at prefix P, then run the install with P erased \u2014 so it lands in the\n * DEFAULT prefix instead. That is either a permanent EACCES, or a second global copy that is not the\n * one on PATH. Nothing notices: the install exits 0, we report `installed`, the version on PATH never\n * moves, and the whole cycle repeats every window forever. `export npm_config_prefix=~/.npm-global` is\n * npm's own documented EACCES workaround, so this is a mainstream layout, not an exotic one.\n * - `npm_config_registry` is what the update CHECK already used to pick a registry. Dropping it here\n * means we decide against a corporate mirror and then install from somewhere else.\n *\n * Preserving these cannot re-arm the dlx guard: that guard reads `npm_command`, `npm_lifecycle_event`, and\n * `PNPM_SCRIPT_SRC_DIR` \u2014 none of which are npm *config*, and all of which remain stripped.\n *\n * @example\n * packageManagerInstallEnv({ npm_command: 'exec', npm_config_prefix: '/p', PATH: '/bin' })\n * // => { npm_config_prefix: '/p', PATH: '/bin' }\n */\nexport const packageManagerInstallEnv = (env: NodeJS.ProcessEnv): NodeJS.ProcessEnv => {\n const sanitised = withoutPackageManagerEnv(env)\n\n for (const [key, value] of Object.entries(env)) {\n if (NPM_CONFIG_TO_PRESERVE.test(key)) sanitised[key] = value\n }\n\n return sanitised\n}\n"],
5
5
  "mappings": "AAwBO,IAAMA,EAA4BC,GAChC,OAAO,YACZ,OAAO,QAAQA,CAAG,EAAE,OAAO,CAAC,CAACC,CAAG,IACvB,CAACA,EAAI,WAAW,MAAM,GAAKA,IAAQ,qBAC3C,CACH,EASIC,EAAyB,oCAyBlBC,EAA4BH,GAA8C,CACrF,IAAMI,EAAYL,EAAyBC,CAAG,EAE9C,OAAW,CAACC,EAAKI,CAAK,IAAK,OAAO,QAAQL,CAAG,EACvCE,EAAuB,KAAKD,CAAG,IAAGG,EAAUH,CAAG,EAAII,GAGzD,OAAOD,CACT",
6
6
  "names": ["withoutPackageManagerEnv", "env", "key", "NPM_CONFIG_TO_PRESERVE", "packageManagerInstallEnv", "sanitised", "value"]
7
7
  }
@@ -0,0 +1,4 @@
1
+ import L from"node:process";import C from"pino";import re from"pino-pretty";var _="/tmp/mcp-infra-kit.log",K=["token","*.token","serviceToken","*.serviceToken","DOPPLER_TOKEN","*.DOPPLER_TOKEN","INFRA_KIT_ENV_TOKEN","*.INFRA_KIT_ENV_TOKEN"],Pt=()=>{let e=L.argv.includes("--debug")?"debug":"info",t=C({level:e,redact:K},C.destination({dest:_}));return t.info(`Logger initialized with level: ${e}. Logging to: ${_}`),t},ne=()=>{let e=L.argv.includes("--debug")?"debug":"info",t=["time","pid","hostname"];return e==="debug"&&t.push("level"),C({level:e,redact:K},re({destination:2,ignore:t.join(","),colorize:!0}))},Rt=ne();import*as p from"node:fs";import*as a from"node:path";function oe(e){let t=e;for(let n=0;n<10;n++){let r=a.join(t,"pnpm-workspace.yaml");if(p.existsSync(r))return t;t=a.dirname(t)}throw new Error("Could not find monorepo root (pnpm-workspace.yaml)")}function M(e,t){let n=a.join(e,"package.json");if(!p.existsSync(n))return t;try{let r=JSON.parse(p.readFileSync(n,"utf-8"));return typeof r.name=="string"?r.name:t}catch{return t}}function Ct(e){let t=a.join(e,"apps"),n=[];if(!p.existsSync(t))throw new Error(`Apps directory not found: ${t}`);let r=p.readdirSync(t,{withFileTypes:!0}).filter(o=>o.isDirectory()).map(o=>o.name);for(let o of r){let i=a.join(t,o,"api"),c=a.join(i,"serverless.yml");p.existsSync(c)&&n.push({name:o,packageName:M(i,o),path:i})}return n}var se=["vite.config.ts","vite.config.mts","vite.config.cts","vite.config.js","vite.config.mjs","vite.config.cjs"],ie=["@slip-stream-kit/vite","@slip-stream-kit/config/vite","infra-kit/vite"];function ae(e){for(let t of se){let n=a.join(e,t);if(p.existsSync(n))try{let r=p.readFileSync(n,"utf-8");return ie.some(o=>r.includes(o))}catch{return!1}}return!1}function ce(e){let t=a.join(e,"package.json");if(!p.existsSync(t))return!1;try{let n=JSON.parse(p.readFileSync(t,"utf-8"));return typeof n.scripts?.dev=="string"&&n.scripts.dev.length>0}catch{return!1}}function St(e){let t=a.join(e,"apps"),n=[];if(!p.existsSync(t))return n;let r=p.readdirSync(t,{withFileTypes:!0}).filter(o=>o.isDirectory()).map(o=>o.name);for(let o of r){let i=a.join(t,o,"ui");p.existsSync(i)&&ce(i)&&n.push({name:o,packageName:M(i,o),path:i,managedPort:ae(i)})}return n}function It(e){let t=e?.filter(Boolean)??[];return t.length>0?t:null}function Et(e){let t=oe(e),n=a.relative(a.join(t,"apps"),e),r=n.split(a.sep)[0];if(n===""||n.startsWith("..")||a.isAbsolute(n)||!r)throw new Error(`--self: not inside an apps/<app> directory (cwd: ${e}). Run from an app folder or use --app=<name>.`);return r}var pe=new Set(["api","ui"]),O=e=>{let t=a.join(e,"dist");return p.existsSync(t)&&p.statSync(t).isDirectory()?t:void 0},S=e=>p.existsSync(e)?p.readdirSync(e,{withFileTypes:!0}).filter(t=>t.isDirectory()).map(t=>t.name):[];function jt(e){let t=[];for(let r of S(a.join(e,"packages"))){let o=O(a.join(e,"packages",r));o!==void 0&&t.push(o)}let n=a.join(e,"apps");for(let r of S(n))for(let o of S(a.join(n,r))){if(pe.has(o))continue;let i=a.join(n,r,o);if(!p.existsSync(a.join(i,"package.json")))continue;let c=O(i);c!==void 0&&t.push(c)}return t}function Dt(e){return e.map(t=>a.join(t.path,"dist")).filter(t=>p.existsSync(t))}function At(e,t,n){let r=a.normalize(e),o=n.find(c=>r.startsWith(a.normalize(c)));return o?{kind:"package",packageDir:o}:{kind:"app",app:t.find(c=>r.startsWith(a.normalize(c)))}}var le={"*/api":{},"*/ui":{}},W=e=>{let t=e.split("/"),[n,r]=t;return t.length!==2||!n?`devServersPresets: invalid target "${e}" (expected "<app>/api" or "<app>/ui")`:r!=="api"&&r!=="ui"?`devServersPresets: invalid target part "${r}" in "${e}" (expected "api" or "ui")`:null},ue=e=>{let t=W(e);if(t)throw new Error(t);let[n,r]=e.split("/");return{appGlob:n,part:r}},Nt=e=>{let t=[];for(let[n,r]of Object.entries(e))for(let o of Object.keys(r.apps??{})){let i=W(o);i&&t.push({preset:n,key:o,message:`preset "${n}": ${i}`})}return t},fe=(e,t)=>t==="api"?e.api:e.ui,ge=e=>[...new Set([...e.api,...e.ui])].sort(),F=(e,t)=>`${e}/${t}`,de=e=>e?0:1,me=(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,he=(e,t,n)=>{let{app:r,part:o,watchDeps:i,isGlob:c}=n;if(!fe(t,o).includes(r)){c||e.unmatched.push(F(r,o));return}let l=F(r,o),u=me(e.targets.get(l),{watchDeps:i,rank:de(c)});e.targets.set(l,{app:r,part:o,...u})},ve=(e,t)=>{let n=Object.entries(e.apps??le),r={targets:new Map,proxy:{},unmatched:[]};for(let[c,l]of n){let{appGlob:u,part:m}=ue(c),b=u==="*",P=b?ge(t):[u];for(let w of P)he(r,t,{app:w,part:m,watchDeps:l.watchDeps,isGlob:b}),l.proxy&&(r.proxy[w]={...r.proxy[w]??{},...l.proxy})}let o=[...r.targets.values()].map(({app:c,part:l,watchDeps:u})=>({app:c,part:l,watchDeps:u})),i=[...new Set(o.filter(c=>c.part==="api").map(c=>c.app))];return{targets:o,cmux:e.cmux??!1,proxy:r.proxy,localApps:i,unmatched:r.unmatched}},Tt=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(r=>t.has(r))?"*":[...t].sort().join(" + ")},ye=(e,t)=>Object.keys(e).find(n=>e[n]===t),xe=({preset:e,app:t,route:n,launchedPkgs:r,ctx:o})=>{let i=o.routePkg(t,n);if(i===void 0)return{preset:e,app:t,route:n,kind:"unknown-route",message:`preset "${e}": proxy override "${n}" on "${t}" names a route not declared in ${t}'s infra-kit.config.ts dev.proxy.routes`};if(r.has(i))return null;let c=ye(o.apiPkgByApp,i),l=c?`add "${c}/api" to the preset`:`launch the api whose package is "${i}"`;return{preset:e,app:t,route:n,pkg:i,kind:"backend-not-launched",message:`preset "${e}": proxy override "${n}" \u2192 "local" requires backend "${i}" to run locally, but the preset does not launch it \u2014 ${l}, or set "${n}" to "cloud"`}},_t=(e,t)=>{let n=[];for(let[r,o]of Object.entries(e)){let i=ve(o,t.discovered),c=new Set(i.localApps.map(l=>t.apiPkgByApp[l]).filter(l=>l!==void 0));for(let[l,u]of Object.entries(i.proxy))for(let[m,b]of Object.entries(u)){if(b!=="local")continue;let P=xe({preset:r,app:l,route:m,launchedPkgs:c,ctx:t});P&&n.push(P)}}return n};import N from"node:fs/promises";import Y from"node:os";import x from"node:path";import Ke from"node:process";import{z as s}from"zod";import v from"node:path";import Ae from"node:process";import{$ as f}from"zx";var ke=/^v?(\d+)\.(\d+)\.(\d+)$/,be=/^(\d+)\.(\d+)\.(\d+)$/,Pe=/^[a-z0-9]+(?:-[a-z0-9]+)*$/,R="release/",I="release/v",G="refs/heads/",Re="next";var B=new Set(["dev","main","next","hotfix","regular","release"]),g=class extends Error{constructor(t){super(t),this.name="InvalidReleaseNameError"}},h=class extends Error{constructor(t){super(t),this.name="InvalidReleaseRefError"}},V=e=>e.startsWith(G)?e.slice(G.length):e,U=(e,t,n)=>({kind:"version",semver:{major:e,minor:t,patch:n},raw:`${e}.${t}.${n}`}),E=e=>{if(e.length===0)throw new g('Release name is empty. Provide a kebab-case name like "checkout-redesign".');if(e.length>50)throw new g(`Release name "${e}" is ${e.length} characters; the maximum is 50.`);if(!Pe.test(e))throw new g(`Release name "${e}" is not kebab-case. Use lowercase letters, digits, and single hyphens, e.g. "checkout-redesign".`);if(B.has(e))throw new g(`Release name "${e}" is reserved. Reserved names: ${[...B].join(", ")}.`)},j=e=>{let t=V(e.trim());if(!t.startsWith(R))return null;if(t.startsWith(I)){let r=t.slice(I.length),o=be.exec(r);if(o)return U(Number(o[1]),Number(o[2]),Number(o[3]))}let n=t.slice(R.length);try{E(n)}catch{return null}return{kind:"name",name:n,raw:n}},we=e=>{let t=e.trim();if(V(t).startsWith(R)){let o=j(t);if(!o)throw new h(`"${e}" looks like a release branch but is not a valid release/v<semver> or release/<name> ref.`);return o}let r=ke.exec(t);if(r)return U(Number(r[1]),Number(r[2]),Number(r[3]));if(t.toLowerCase()===Re)throw new h('The "next" token must be resolved to a concrete version (via computeNextVersion) before parsing a release ref.');try{E(t)}catch(o){let i=o instanceof Error?o.message:String(o);throw new h(`Cannot parse "${e}" as a release ref: ${i}`)}return{kind:"name",name:t,raw:t}},Ce=e=>e.kind==="version"?`${I}${e.raw}`:`${R}${e.name}`,Se=(e,t)=>{let n=t==="hotfix"?"Hotfix":"Release";return e.kind==="version"?`${n} v${e.raw}`:`${n} ${e.name}`},Ie=e=>e.kind==="version"?`Release v${e.raw} (RC)`:`Release ${e.name} (RC)`,Ee=e=>e.kind==="version"?`v${e.raw}`:e.name,je=e=>e.raw,D=e=>e==null?!1:j(e)!==null,z=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,n)=>{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 r=z(n?.a),o=z(n?.b);return r!==null&&o!==null&&r!==o?r-o:e.name<t.name?-1:e.name>t.name?1:0};var H=async e=>{let t=await f({cwd:e})`git worktree list --porcelain`,n=[],r=null;for(let o of t.stdout.split(`
2
+ `)){if(o.startsWith("worktree ")){r&&n.push(r),r={path:o.slice(9),branch:null,detached:!1,bare:!1,prunable:!1,locked:!1};continue}r&&(o.startsWith("branch ")?r.branch=o.slice(7).replace(/^refs\/heads\//,""):o==="detached"?r.detached=!0:o==="bare"?r.bare=!0:o==="locked"||o.startsWith("locked ")?r.locked=!0:(o==="prunable"||o.startsWith("prunable "))&&(r.prunable=!0))}return r&&n.push(r),n},$e=async e=>{let t=await H(Ae.cwd()),n=r=>e==="release"?D(r):r.startsWith("feature/");return t.map(r=>r.branch).filter(r=>r!==null&&n(r))},y=async()=>(await f`git rev-parse --show-toplevel`).stdout.trim(),A=async e=>{let t=e??await y(),n=(await f({cwd:t})`git rev-parse --git-common-dir`).stdout.trim(),r=v.resolve(t,n);return r.includes(`${v.sep}.git${v.sep}modules${v.sep}`)?t:v.dirname(r)},X=async()=>(await f`git rev-parse --abbrev-ref HEAD`).stdout.trim(),Ne=async()=>(await f`git status --porcelain`).stdout.trim().length===0,Te=async()=>{let e=await y(),[t,n]=await Promise.all([f({cwd:e})`git rev-parse --absolute-git-dir`,f({cwd:e})`git rev-parse --git-common-dir`]),r=t.stdout.trim(),o=v.resolve(e,n.stdout.trim());return r!==o};var _e=async e=>{(await f`git branch --list ${e}`).stdout.trim().length!==0&&await X()!==e&&await f`git branch -D ${e}`},Le=async e=>{(await f`git ls-remote --heads origin ${e}`).stdout.trim().length!==0&&await f`git push origin --delete ${e}`};var q="infra-kit.json",Q=".infra-kit",Oe="infra-kit.json",Me="projects",Fe=s.object({provider:s.literal("doppler"),config:s.object({name:s.string().min(1)})}),We=s.discriminatedUnion("provider",[Fe]),Ge=s.object({workspaceConfigPath:s.string().min(1)}),Be=s.object({provider:s.literal("cursor"),config:Ge}),ze=s.object({}),Ve=s.object({provider:s.literal("zed"),config:ze}),J=s.discriminatedUnion("provider",[Be,Ve]),Ue=s.union([J,s.array(J).min(1)]),He=s.object({provider:s.literal("jira"),config:s.object({baseUrl:s.string().url(),projectId:s.number().int().positive()})}),Xe=s.discriminatedUnion("provider",[He]),qe=["two-columns","three-pane"],Je=s.object({layout:s.enum(qe).optional()}),Ye=s.object({openInGithubDesktop:s.boolean().optional(),openInCmux:s.boolean().optional(),cmux:Je.optional()}),Qe=s.object({port:s.number().int().positive().optional(),prefixUrl:s.string().min(1).optional()}).strict(),Ze=s.record(s.string().min(1),Qe),et=s.enum(["local","cloud"]),tt=s.object({watchDeps:s.boolean().optional(),proxy:s.record(s.string().min(1),et).optional()}).strict(),rt=s.object({apps:s.record(s.string().min(1),tt).optional(),cmux:s.boolean().optional()}).strict(),nt=s.record(s.string().min(1),rt),ot=s.object({port:s.number().int().positive().optional()}).strict(),st=s.object({trigger:s.enum(["shell-startup","cli-invocation"]),config:s.string().min(1)}).strict(),T=s.object({envManagement:We,ide:Ue.optional(),taskManager:Xe.optional(),worktrees:Ye.optional(),envAutoLoad:st.optional(),dev:Ze.optional(),devServersPresets:nt.optional(),devProxy:ot.optional()}).strict(),it=443,Z=T.superRefine((e,t)=>{if(!Array.isArray(e.ide))return;let n=new Set;for(let r of e.ide){if(n.has(r.provider)){t.addIssue({code:"custom",message:"each IDE provider may appear at most once",path:["ide"]});return}n.add(r.provider)}}),ee=T.partial(),at=e=>{let t=e.ide;return t?Array.isArray(t)?t:[t]:[]},ct="two-columns",pt=e=>e.worktrees?.cmux?.layout??ct,d=null,k=null,lt=()=>`${Ke.cwd()} ${Y.homedir()}`,te=async()=>{let e=lt();if(k&&k.key===e)return k.value;let t=await y(),n=await A(t),r=x.basename(n),o=x.join(Y.homedir(),Q),i={main:x.join(t,q),userGlobal:x.join(o,Oe),userProject:x.join(o,Me,r,q),projectName:r};return k={key:e,value:i},i},ut=async()=>{let e=await te(),t;try{t=await N.stat(e.main)}catch{d=null;let u=e.main.replace(/\.json$/,".yml");throw await $(u)?new Error(`infra-kit.json not found at ${e.main}. A legacy infra-kit.yml exists \u2014 run \`infra-kit init\` to convert it.`):new Error(`infra-kit.json not found at ${e.main}`)}let[n,r]=await Promise.all([$(e.userGlobal),$(e.userProject)]),o={main:Number(t.mtimeMs),userGlobal:n?Number(n.mtimeMs):null,userProject:r?Number(r.mtimeMs):null};if(d&&mt(d.mtimes,o))return d.value;let i=[{label:"infra-kit.json",path:e.main,required:!0},{label:"~/.infra-kit/infra-kit.json",path:e.userGlobal,required:!1},{label:`~/.infra-kit/projects/${e.projectName}/infra-kit.json`,path:e.userProject,required:!1}],c={};for(let u of i){let m=await ht(u);m!==null&&(c={...c,...m})}let l=Z.safeParse(c);if(!l.success)throw new Error(`Invalid merged infra-kit config: ${s.prettifyError(l.error)}`);return d={mtimes:o,value:l.data},l.data},ft=()=>{d=null},gt=()=>{d=null,k=null},$=async e=>{try{return await N.stat(e)}catch{return null}},dt=async e=>{try{return await N.readFile(e,"utf-8")}catch{return null}},mt=(e,t)=>{let n=Object.keys(e);return n.length!==Object.keys(t).length?!1:n.every(r=>e[r]===t[r])},ht=async e=>{let t=await dt(e.path);if(t===null){if(e.required)throw new Error(`${e.label} not found at ${e.path}`);return null}let n;try{n=t.trim()===""?{}:JSON.parse(t)}catch(o){throw new Error(`Invalid JSON in ${e.label} at ${e.path}: ${o.message}`)}if(vt(n)&&"envTokens"in n)throw new Error(yt(e));let r=ee.safeParse(n);if(!r.success)throw new Error(`Invalid ${e.label} at ${e.path}: ${s.prettifyError(r.error)}`);return r.data},vt=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),yt=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(`
3
+ `);export{g as a,E as b,j as c,we as d,Ce as e,Se as f,Ie as g,Ee as h,je as i,D as j,De as k,H as l,$e as m,y as n,A as o,Ne as p,Te as q,_e as r,Le as s,_ as t,Pt as u,Rt as v,oe as w,Ct as x,St as y,It as z,Et as A,jt as B,Dt as C,At as D,W as E,Nt as F,ve as G,Tt as H,_t as I,Q as J,it as K,Z as L,ee as M,at as N,pt as O,te as P,ut as Q,ft as R,gt as S};
4
+ //# sourceMappingURL=chunk-PZU6BLQR.js.map