@gjsify/cli 0.33.0 → 0.35.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.gjs.mjs +4 -4
- package/lib/commands/affected.js +31 -4
- package/lib/commands/foreach.d.ts +1 -0
- package/lib/commands/foreach.js +30 -1
- package/package.json +17 -17
package/dist/cli.gjs.mjs
CHANGED
|
@@ -863,7 +863,7 @@ if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
|
|
863
863
|
# are installed in the same directory
|
|
864
864
|
$exe=".exe"
|
|
865
865
|
}
|
|
866
|
-
`});function usingSelfShim(){return FN}function needsSelfShim(n){if(n.gjs)return!0;let a=ys(n.workspaceRoot,n.selfEntry);return a===``||a.startsWith(`..`)||_s(a)}function ensureGjsifyShimOnPath(){if(PN)return;PN=!0;let n=process.env.GJSIFY_SHIM_DIR;if(n&&existsSync(vs(n,`gjsify`))){FN=!0,(process.env.PATH??``).split(Ds).includes(n)||(process.env.PATH=n+Ds+(process.env.PATH??``));return}let a=isGjs(),S=fileURLToPath(a?import.meta.url:new URL(`../index.js`,import.meta.url));if(!needsSelfShim({gjs:a,selfEntry:S,workspaceRoot:findWorkspaceRoot(process.cwd())??process.cwd()}))return;let C=mkdtempSync(vs(tmpdir(),`gjsify-shim-`)),N=vs(C,`gjsify`),F=a?process.env.GJS_CONSOLE||`gjs`:`node`,I=a?[`-m`]:[];if(writeFileSync(N,`#!/bin/sh\nexec "${F}" ${I.length>0?`${I.join(` `)} `:``}"${S}" "$@"\n`,{mode:493}),chmodSync(N,493),!a&&process.platform===`win32`){let{cmd:n,ps1:a}=buildLauncherShims({interpreter:F,interpreterArgs:I,target:S});writeFileSync(`${N}.cmd`,n),writeFileSync(`${N}.ps1`,a)}FN=!0,process.env.GJSIFY_SHIM_DIR=C,process.env.PATH=C+Ds+(process.env.PATH??``)}var PN,FN,IN=__esmMin(()=>{Dl(),Cm(),ks(),an(),Rm(),NN(),ev(),PN=!1,FN=!1});function editDistance(n,a){if(n===a)return 0;if(n.length===0)return a.length;if(a.length===0)return n.length;let S=Array.from({length:a.length+1},(n,a)=>a),C=Array.from({length:a.length+1},()=>0);for(let N=1;N<=n.length;N++){C[0]=N;for(let F=1;F<=a.length;F++){let I=n[N-1]===a[F-1]?0:1;C[F]=Math.min(S[F]+1,C[F-1]+1,S[F-1]+I)}[S,C]=[C,S]}return S[a.length]}function suggestClosest(n,a){if(a.length===0)return;let S=n.toLowerCase(),C=Math.max(2,Math.floor(n.length/3)),N,F=1/0;for(let n of a){let a=editDistance(S,n.toLowerCase());a<F&&(F=a,N=n)}return N!==void 0&&F<=C?N:void 0}var LN=__esmMin(()=>{});function collectTransitiveClosure(n,a,S){let C=new Map;for(let n of a)C.set(n.name,n);let N=new Set,F=[],I=[n];for(;I.length>0;){let n=I.pop();if(N.has(n.name))continue;N.add(n.name),F.push(n);let a=n.manifest,H=[a.dependencies,S?a.devDependencies:void 0,a.optionalDependencies];for(let n of H)if(n)for(let[a,S]of Object.entries(n)){if(typeof S!=`string`||!S.startsWith(`workspace:`))continue;let n=C.get(a);n&&(N.has(n.name)||I.push(n))}}return F}async function runOne$1(n,a,S,C,N,F){if(F&&F.tryRestore(n))return;let I=F?.snapshotOutputs(n),H=C===`gjsify`?[`run`,a,...S]:[`run`,a,...S.length>0?[`--`,...S]:[]];N&&he.error(`[${n.name}] $ ${C} ${H.join(` `)}`);let{code:W}=await spawnToCompletion(C,H,{completion:`exit`,cwd:n.location,color:!0});if(W!==0)throw Error(`${C} ${H.join(` `)} exited with code ${W}`);F&&I&&F.storeAfterSuccess(n,I)}function detectPackageManager$1(){if(isGjs()||usingSelfShim())return`gjsify`;let n=process.env.npm_config_user_agent??``;return n.startsWith(`yarn/`)?`yarn`:n.startsWith(`gjsify/`)?`gjsify`:`npm`}var RN,zN=__esmMin(()=>{ge(),xN(),Q_(),ev(),ON(),Rm(),IN(),LN(),RN={command:`workspace <name> <script> [args..]`,description:"Run a workspace script. Both `workspace <name> <script>` and the yarn spelling `workspace <name> run <script>` work.",builder:n=>n.positional(`name`,{description:"Workspace name (matches package.json `name` field).",type:`string`,demandOption:!0}).positional(`script`,{description:`Script name to run inside that workspace.`,type:`string`,demandOption:!0}).positional(`args`,{description:`Extra arguments forwarded to the script.`,type:`string`,array:!0}).option(`with-dependencies`,{description:"Pre-build the target workspace's transitive workspace dependencies in topological order before running the script in the target. Deps that don't declare the script are skipped (--if-present behaviour). Replaces manual `gjsify workspace A build && gjsify workspace B build && …` chains.",type:`boolean`,alias:[`d`,`t`,`topological`],default:!1}).option(`include-dev`,{description:"When --with-dependencies is set, also walk devDependencies (production deps only by default — matches `gjsify foreach -t`).",type:`boolean`,default:!1}).option(`continue-on-error`,{description:`When --with-dependencies is set, keep running remaining deps after one fails (default: stop on first failure).`,type:`boolean`,default:!1}).option(`verbose`,{description:`Echo every spawned command before running it.`,type:`boolean`,alias:`v`,default:!1}).option(`cached`,{description:`Content-hash build cache (ADR 0006): skip the script for a workspace whose inputs (src/**, package.json, tsconfig*.json, transitive workspace deps, toolchain versions) are unchanged and restore its stored outputs instead; on miss run it and store the output dirs it modified. Also applies to the deps run via --with-dependencies. Default from GJSIFY_BUILD_CACHE=1.`,type:`boolean`}),handler:async n=>{let a=findWorkspaceRoot(process.cwd())??process.cwd(),S=discoverWorkspaces(a),C=S.find(a=>a.name===n.name);if(!C){let C=suggestClosest(n.name,S.map(n=>n.name)),N=C?` — did you mean "${C}"?`:``;return he.error(`gjsify workspace: no workspace named "${n.name}"${N} (discovered ${S.length} workspace(s) under ${a})`),process.exit(1)}let N=detectPackageManager$1(),F=n.verbose===!0,I=n[`with-dependencies`]===!0,H=n[`continue-on-error`]===!0,W=n.script,K=n.args??[];W===`run`&&K.length>0&&([W,...K]=K);let q=C.manifest.scripts??{};if(typeof q[W]!=`string`){let a=suggestClosest(W,Object.keys(q));return he.error(`gjsify workspace: workspace "${n.name}" has no script "${W}"`+(a?` — did you mean "${a}"?`:``)),process.exit(1)}let Y;Y=I?topologicalSort(buildDependencyGraph(collectTransitiveClosure(C,S,n[`include-dev`]===!0),{includeDev:n[`include-dev`]===!0})):[C];let X=n.cached??buildCacheEnabledByEnv()?new BuildCacheRunner({root:a,workspaces:S,script:W,args:K,targets:Y.map(n=>n.name)}):void 0,te=[];for(let n of Y){if(typeof(n.manifest.scripts??{})[W]!=`string`){F&&he.error(`[${n.name}] (no "${W}" script — skipping)`);continue}try{await runOne$1(n,W,K,N,F,X)}catch(a){let S=a instanceof Error?a:Error(String(a));if(he.error(`[${n.name}] ${S.message}`),!H)return process.exit(1);te.push({workspace:n.name,error:S})}}return te.length>0?(he.error(`gjsify workspace: ${te.length} workspace(s) failed: ${te.map(n=>n.workspace).join(`, `)}`),process.exit(1)):process.exit(0)}},__name$1(runOne$1,`runOne`),__name$1(detectPackageManager$1,`detectPackageManager`)});async function runCheck(n,a){let S=[],C=detectPackageManager$1();if(C===`gjsify`&&readPackageJson$2(vs(n.location,`package.json`))?.scripts?.check===void 0)return 0;let N=C===`gjsify`?[`run`,`check`]:[`run`,`check`,`--if-present`];try{let{code:F}=await spawnToCompletion(C,N,{completion:`exit`,cwd:n.location,stdio:a===null?`inherit`:`pipe`,onSpawn:n=>{let C=!process.stdout.isTTY;if(a!==null&&n.stdout&&n.stderr){let N=`[${a}] `;S.push(prefixLines(n.stdout,process.stdout,N,C)),S.push(prefixLines(n.stderr,process.stderr,N,C))}}});for(let n of S)n();return F??1}catch{for(let n of S)n();return 1}}var BN,VN=__esmMin(()=>{ge(),mN(),xN(),$_(),ks(),Cm(),Q_(),ev(),zN(),BN={command:`check`,description:"Run `npm run check` (TypeScript type-check) across the current workspace. In a workspace root: walks every package with a `check` script (excludes @girs/*; honours --include/--exclude). In a single package: runs the local `check` script directly. Symmetric peer of `gjsify format` / `lint` / `fix`. (Legacy system-dep `gjsify check` is now `gjsify system-check` — see #254.)",builder:n=>n.option(`include`,{description:`Only run in workspaces matching these glob patterns (repeatable).`,type:`string`,array:!0}).option(`exclude`,{description:`Skip workspaces matching these glob patterns (repeatable). Always excludes @girs/*.`,type:`string`,array:!0}).option(`parallel`,{description:`Run workspace checks in parallel (default). Use --no-parallel to run them sequentially with full per-workspace output.`,type:`boolean`,alias:`p`,default:!0}).option(`jobs`,{description:`Max parallel workers (when --parallel). Default: os.cpus().length.`,type:`number`,alias:`j`}).option(`verbose`,{description:`Log the per-workspace command before spawning.`,type:`boolean`,default:!1}),handler:async n=>{let a=process.cwd(),S=findWorkspaceRoot(a);if(S&&a!==S&&readPackageJson$2(vs(a,`package.json`))?.scripts?.check){n.verbose&&he.log(`[check] cwd=${a} → npm run check`);let{code:S}=await spawnToCompletion(detectPackageManager$1(),[`run`,`check`],{cwd:a,completion:`exit`});return process.exit(S??1)}if(!S)return he.error("gjsify check: no workspace root found from cwd. Run inside a workspace (or a package within one) with `npm run check` defined."),process.exit(1);let C=discoverWorkspaces(S),N=[`@girs/*`,...n.exclude??[]],F=filterWorkspaces(C,{include:n.include,exclude:N}).filter(n=>n.manifest.scripts?.check!==void 0);if(F.length===0)return he.error("gjsify check: no workspaces with a `check` script found."),process.exit(1);if(n.verbose&&he.log(`[check] root=${S} workspaces=${F.length} parallel=${n.parallel?`yes`:`no`}`),!n.parallel){let a=0,S=0;for(let C of F){n.verbose&&he.log(`[check] → ${C.name}`);let N=await runCheck(C,null);N!==0&&(S++,a===0&&(a=N))}return a!==0&&he.error(`gjsify check: failures in ${S} workspace(s)`),process.exit(a)}let I=n.jobs??Math.max(1,cpus().length),H=[],W=0,K=[];for(let n=0;n<I;n++)K.push((async()=>{for(;;){let n=W++;if(n>=F.length)return;let a=F[n],S=await runCheck(a,a.name);S!==0&&H.push({name:a.name,code:S})}})());if(await Promise.all(K),H.length>0){he.error(`\ngjsify check: ${H.length} of ${F.length} workspace(s) failed:`);for(let n of H)he.error(` ✗ ${n.name} (exit ${n.code})`);return process.exit(1)}n.verbose&&he.log(`\ngjsify check: ${F.length} workspace(s) green.`),process.exit(0)}}});function manifestPath(){let n=xs(fileURLToPath(import.meta.url)),a=[vs(n,`..`,`..`,`showcases.json`),vs(n,`..`,`showcases.json`)];return a.find(n=>existsSync(n))??a[0]}function discoverShowcases(){let n=manifestPath();if(!existsSync(n))return[];let a;try{a=JSON.parse(readFileSync(n,`utf-8`))}catch{return[]}if(!Array.isArray(a.showcases))return[];let S=a.showcases.map(n=>({name:n.name,packageName:n.package,category:n.category,description:n.description??``}));return S.sort((n,a)=>n.category.localeCompare(a.category)||n.name.localeCompare(a.name)),S}function findShowcase(n){return discoverShowcases().find(a=>a.name===n)}var HN=__esmMin(()=>{Dl(),ks(),an()});function parseSpec$1(n){if(!n)throw Error(`dlx: empty package spec`);if(n.startsWith(`./`)||n.startsWith(`../`)||_s(n)||existsSync(n))return{kind:`local`,path:hs(n)};let a=n,S,C=n.lastIndexOf(`@`);if(C>0&&(a=n.slice(0,C),S=n.slice(C+1)),!UN.test(a))throw Error(`dlx: invalid package name "${a}"`);return{kind:`registry`,name:a,version:S,spec:n}}var UN,WN=__esmMin(()=>{Dl(),ks(),UN=/^(?:@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/,__name$1(parseSpec$1,`parseSpec`)});function resolveGjsEntry(n,a){let S=vs(n,`package.json`);if(!existsSync(S))throw Error(`dlx: no package.json found at ${n}`);let C=JSON.parse(readFileSync(S,`utf-8`)),N=C.gjsify?.bin,F=C.gjsify?.main,I=C.main,H,W=null,K=!1;if(a!==null){if(!N||!N[a]){let S=N?Object.keys(N).join(`, `):`(none)`;throw Error(`dlx: package "${C.name??n}" has no GJS bin named "${a}" — known: ${S}`)}H=N[a],W=a}else if(N&&Object.keys(N).length===1){let n=Object.keys(N)[0];H=N[n],W=n}else F?H=F:I&&(H=I,K=!0);if(N&&Object.keys(N).length>1&&a===null){let a=Object.keys(N).join(`, `);throw Error(`dlx: package "${C.name??n}" defines multiple GJS bins — pass one of: ${a}`)}if(!H)throw Error(`dlx: package "${C.name??n}" has no GJS entry — set \`gjsify.main\` (or \`gjsify.bin\`) in its package.json`);let q=hs(n,H);if(!existsSync(q))throw Error(`dlx: GJS entry not found: ${q}`);return{bundlePath:q,binName:W,fromFallback:K}}function resolveNodeEntry(n){let a=vs(n,`package.json`);if(!existsSync(a))throw Error(`no package.json found at ${n}`);let S=JSON.parse(readFileSync(a,`utf-8`)),C=S.gjsify?.example?.node;if(C){let a=hs(n,C);if(!existsSync(a))throw Error(`declared node entry not found: ${a} (gjsify.example.node)`);return a}let N=S.gjsify?.main??(S.gjsify?.bin?Object.values(S.gjsify.bin)[0]:void 0)??S.main;if(!N)throw Error(`package "${S.name??n}" has no entry to derive a node bundle from — set \`gjsify.example.node\` to its \`--app node\` bundle path.`);let F=N.replace(/\.gjs\.(js|mjs|cjs)$/,``).replace(/\.(js|mjs|cjs)$/,``),I=[`${F}.node.mjs`,`${F}.node.js`,`${F}.node.cjs`];for(let a of I){let S=hs(n,a);if(existsSync(S))return S}throw Error(`package "${S.name??n}" has no \`--app node\` bundle — looked for ${I.join(`, `)}.\n Build one (e.g. \`gjsify build src/app.ts --app node --outfile dist/app.node.mjs\`) or set \`gjsify.example.node\` to its path.`)}var GN=__esmMin(()=>{Dl(),ks()});function lexCompare(n,a){return n<a?-1:+(n>a)}function createCacheKey(n){let a=[...n.packages].sort(lexCompare),S=Object.entries(n.registries??{}).sort(([n],[a])=>lexCompare(n,a)),C=JSON.stringify([a,S]);return createHash(`sha256`).update(C).digest(`hex`)}function dlxCacheRoot(){let n=process.env.XDG_CACHE_HOME,a=vs(n&&n.length>0?n:vs(homedir(),`.cache`),`gjsify`,`dlx`);return mkdirSync(a,{recursive:!0}),a}function cacheDirFor(n){let a=vs(dlxCacheRoot(),n);return mkdirSync(a,{recursive:!0}),a}function makePrepareDir(n){let a=vs(n,`${Date.now().toString(16)}-${process.pid.toString(16)}`);return mkdirSync(a,{recursive:!0}),a}function getValidCachedPkg(n,a=qN){let S=vs(n,`pkg`),C;try{C=lstatSync(S)}catch(n){if(n.code===`ENOENT`)return;throw n}if(!C.isSymbolicLink())return;let N;try{N=realpathSync(S)}catch{return}return Date.now()-C.mtime.getTime()<=a*KN?N:void 0}function symlinkSwap(n,a,S={}){let C=S.junctions??dirLinksAreJunctions(),N=vs(n,`pkg`),F=vs(n,`pkg.tmp-${Date.now().toString(16)}-${process.pid.toString(16)}`);linkDirSync(F,a);try{C&&rmSync(N,{force:!0,recursive:!1,maxRetries:10,retryDelay:100}),renameSync(F,N)}catch(n){let S=n.code;if(S===`EBUSY`||S===`EPERM`||S===`EEXIST`||S===`EACCES`){rmSync(F,{force:!0});try{return realpathSync(N)}catch{return realpathSync(a)}}throw n}return realpathSync(N)}function resolveInstalledPkgDir(n,a){return hs(n,`node_modules`,a)}var KN,qN,JN=__esmMin(()=>{So(),Dl(),Cm(),ks(),wN(),KN=6e4,qN=1440*7});function makeProgressReporter(n={}){if(n.enabled===!1)return XN;let a=n.stream??process.stderr,S=!!a.isTTY;return n.enabled??!0?S?makeTtyReporter(a):makePlainReporter(a):XN}function makeTtyReporter(n){let a=0,S=``;function render(C,N=!1){let F=Date.now();!N&&F-a<33&&C===S||(a=F,S=C,n.write(`\r\x1B[2K`+C))}function clearLine(){n.write(`\r\x1B[2K`),S=``}return{beginPhase(a,S){render(formatBar(a,0,S,void 0,n.columns??80),!0)},update(a){render(formatBar(a.phase,a.current,a.total,a.name,n.columns??80))},endPhase(a){let S=YN[a];clearLine(),n.write(`gjsify install: ${S} done\n`)}}}function makePlainReporter(n){let a=0,S=0;return{beginPhase(C,N){a=Date.now(),S=0,n.write(`gjsify install: ${YN[C]} ${N} package(s)\n`)},update(C){let N=Date.now();if(N-a<ZN||C.current<=S)return;a=N,S=C.current;let F=C.total>0?Math.round(C.current/C.total*100):0;n.write(`gjsify install: ${YN[C.phase]} ${C.current}/${C.total} (${F}%)\n`)},endPhase(a){n.write(`gjsify install: ${YN[a]} done\n`)}}}function formatBar(n,a,S,C,N){let F=YN[n],I=S>0?Math.min(1,a/S):0,H=`${a}/${S}`,W=`gjsify install: ${F} `,K=` ${H}`+(C?` ${C}`:``),q=Math.max(8,Math.min(40,N-W.length-K.length-4)),Y=Math.round(I*q),X=`█`.repeat(Y)+`░`.repeat(q-Y),te=`${W}[${X}]${K}`;if(te.length>N){let n=te.length-N+1,a=C&&C.length>n?C.slice(0,C.length-n-1)+`…`:``;te=`${W}[${X}] ${H}${a?` `+a:``}`}return te}var YN,XN,ZN,QN=__esmMin(()=>{YN={resolve:`resolving`,download:`downloading`,extract:`extracting`,link:`linking bins`},XN={update(){},beginPhase(){},endPhase(){}},ZN=5e3});function parse(n){try{return new SemVer(n)}catch{return null}}function compare(n,a){let S=n instanceof SemVer?n:new SemVer(n),C=a instanceof SemVer?a:new SemVer(a);return S.compare(C)}function satisfies(n,a){let S=a instanceof tP?a:new tP(a),C=n instanceof SemVer?n:parse(String(n));return C?S.test(C):!1}function maxSatisfying(n,a){let S=a instanceof tP?a:new tP(a),C=null;for(let a of n){let n=parse(a);!n||!S.test(n)||(C===null||n.compare(C)>0)&&(C=n)}return C?C.version:null}function testComparator(n,a){if(n.semver===null)return!0;let S=a.compare(n.semver);switch(n.operator){case``:case`=`:return S===0;case`<`:return S<0;case`<=`:return S<=0;case`>`:return S>0;case`>=`:return S>=0}}function formatComparator(n){return n.semver===null?`*`:`${n.operator}${n.semver.version}`}function parseRangePart(n){let a=n.trim();if(a===``||a===`*`||a.toLowerCase()===`latest`)return[{operator:`>=`,semver:new SemVer(`0.0.0`)}];let S=a.match(/^\s*(\S+)\s+-\s+(\S+)\s*$/);if(S)return hyphenRange(S[1],S[2]);let C=a.replace(/(<=|>=|<|>|=)\s+(?=\S)/g,`$1`).split(/\s+/),N=[];for(let n of C)N.push(...parseSimple(n));return N}function parseSimple(n){if(n===`*`||n===``||n.toLowerCase()===`latest`)return[{operator:`>=`,semver:new SemVer(`0.0.0`)}];if(n.startsWith(`^`))return caretRange(n.slice(1));if(n.startsWith(`~`))return tildeRange(n.slice(1).replace(/^>/,``));let a=n.match(/^(<=|>=|<|>|=)\s*(.+)$/);if(a){let n=a[1];return primitiveRange(n,a[2])}return partialRange(n)}function parsePartial(n){let a=n.trim().replace(/^v/,``);if(a===``||a===`*`)return{major:null,minor:null,patch:null,pre:``,build:``};let S=``,C=``,N=a,F=N.indexOf(`+`);F>=0&&(C=N.slice(F+1),N=N.slice(0,F));let I=N.indexOf(`-`);I>=0&&(S=N.slice(I+1),N=N.slice(0,I));let H=N.split(`.`),xr=a=>{if(a===void 0||a===``||a===`x`||a===`X`||a===`*`)return null;if(!/^\d+$/.test(a))throw TypeError(`Invalid partial version: ${n}`);return Number(a)};return{major:xr(H[0]),minor:xr(H[1]),patch:xr(H[2]),pre:S,build:C}}function partialToVersion(n){return`${n.major??0}.${n.minor??0}.${n.patch??0}${n.pre?`-${n.pre}`:``}${n.build?`+${n.build}`:``}`}function partialRange(n){let a=parsePartial(n);return a.major===null?[{operator:`>=`,semver:new SemVer(`0.0.0`)}]:a.minor===null?[{operator:`>=`,semver:new SemVer(`${a.major}.0.0`)},{operator:`<`,semver:new SemVer(`${a.major+1}.0.0`)}]:a.patch===null?[{operator:`>=`,semver:new SemVer(`${a.major}.${a.minor}.0`)},{operator:`<`,semver:new SemVer(`${a.major}.${a.minor+1}.0`)}]:[{operator:`=`,semver:new SemVer(partialToVersion(a))}]}function caretRange(n){let a=parsePartial(n);if(a.major===null)return[{operator:`>=`,semver:new SemVer(`0.0.0`)}];let S=`${a.major}.${a.minor??0}.${a.patch??0}${a.pre?`-${a.pre}`:``}`,C;return C=a.major>0||a.minor===null?`${a.major+1}.0.0`:a.minor>0||a.patch===null?`0.${a.minor+1}.0`:`0.0.${a.patch+1}`,[{operator:`>=`,semver:new SemVer(S)},{operator:`<`,semver:new SemVer(C)}]}function tildeRange(n){let a=parsePartial(n);if(a.major===null)return[{operator:`>=`,semver:new SemVer(`0.0.0`)}];let S=`${a.major}.${a.minor??0}.${a.patch??0}${a.pre?`-${a.pre}`:``}`,C=a.minor===null?`${a.major+1}.0.0`:`${a.major}.${a.minor+1}.0`;return[{operator:`>=`,semver:new SemVer(S)},{operator:`<`,semver:new SemVer(C)}]}function primitiveRange(n,a){let S=parsePartial(a);return S.major===null?[{operator:`>=`,semver:new SemVer(`0.0.0`)}]:n===`=`||n===``?partialRange(a):n===`>`?S.minor===null?[{operator:`>=`,semver:new SemVer(`${S.major+1}.0.0`)}]:S.patch===null?[{operator:`>=`,semver:new SemVer(`${S.major}.${S.minor+1}.0`)}]:[{operator:`>`,semver:new SemVer(partialToVersion(S))}]:n===`<`?S.minor===null?[{operator:`<`,semver:new SemVer(`${S.major}.0.0`)}]:S.patch===null?[{operator:`<`,semver:new SemVer(`${S.major}.${S.minor}.0`)}]:[{operator:`<`,semver:new SemVer(partialToVersion(S))}]:n===`>=`?[{operator:`>=`,semver:new SemVer(partialToVersion(S))}]:S.minor===null?[{operator:`<`,semver:new SemVer(`${S.major+1}.0.0`)}]:S.patch===null?[{operator:`<`,semver:new SemVer(`${S.major}.${S.minor+1}.0`)}]:[{operator:`<=`,semver:new SemVer(partialToVersion(S))}]}function hyphenRange(n,a){let S=parsePartial(n),C=parsePartial(a),N=S.major===null?{operator:`>=`,semver:new SemVer(`0.0.0`)}:{operator:`>=`,semver:new SemVer(`${S.major}.${S.minor??0}.${S.patch??0}${S.pre?`-${S.pre}`:``}`)},F;return F=C.major===null?{operator:`>=`,semver:new SemVer(`0.0.0`)}:C.minor===null?{operator:`<`,semver:new SemVer(`${C.major+1}.0.0`)}:C.patch===null?{operator:`<`,semver:new SemVer(`${C.major}.${C.minor+1}.0`)}:{operator:`<=`,semver:new SemVer(`${C.major}.${C.minor}.${C.patch}${C.pre?`-${C.pre}`:``}`)},[N,F]}var $N,eP,SemVer,tP,nP=__esmMin(()=>{$N=/^(0|[1-9]\d*)$/,eP=/^(\d+)\.(\d+)\.(\d+)(?:-((?:[0-9A-Za-z-]+)(?:\.[0-9A-Za-z-]+)*))?(?:\+([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?$/,SemVer=class{major;minor;patch;prerelease;build;version;constructor(n){let a=String(n).trim().replace(/^v/,``),S=eP.exec(a);if(!S)throw TypeError(`Invalid Version: ${n}`);this.major=Number(S[1]),this.minor=Number(S[2]),this.patch=Number(S[3]),this.prerelease=S[4]?S[4].split(`.`).map(n=>$N.test(n)?Number(n):n):[],this.build=S[5]?S[5].split(`.`):[],this.version=`${this.major}.${this.minor}.${this.patch}`+(this.prerelease.length?`-${this.prerelease.join(`.`)}`:``)+(this.build.length?`+${this.build.join(`.`)}`:``)}compare(n){return this.major===n.major?this.minor===n.minor?this.patch===n.patch?this.comparePre(n):this.patch<n.patch?-1:1:this.minor<n.minor?-1:1:this.major<n.major?-1:1}comparePre(n){let a=this.prerelease,S=n.prerelease;if(a.length===0&&S.length===0)return 0;if(a.length===0)return 1;if(S.length===0)return-1;for(let n=0;;n++){let C=a[n],N=S[n];if(C===void 0&&N===void 0)return 0;if(N===void 0)return 1;if(C===void 0)return-1;if(C===N)continue;let F=typeof C==`number`,I=typeof N==`number`;return F&&!I?-1:!F&&I?1:C<N?-1:1}}toString(){return this.version}},tP=class Range{raw;set;constructor(n){if(n instanceof Range){this.raw=n.raw,this.set=n.set;return}this.raw=String(n).trim();let a=this.raw.split(/\s*\|\|\s*/),S=[];for(let n of a){let a=parseRangePart(n);if(a.length===0)throw TypeError(`Invalid range: ${this.raw}`);S.push(a)}if(S.length===0)throw TypeError(`Invalid range: ${this.raw}`);this.set=S}test(n){let a=n instanceof SemVer?n:parse(String(n));if(!a)return!1;for(let n of this.set)if(n.every(n=>testComparator(n,a))){if(a.prerelease.length>0&&!n.some(n=>n.semver!==null&&n.semver.prerelease.length>0&&n.semver.major===a.major&&n.semver.minor===a.minor&&n.semver.patch===a.patch))continue;return!0}return!1}format(){return this.set.map(n=>n.map(formatComparator).join(` `)).join(` || `)}toString(){return this.format()}}});function buildHeaders(n,a){let S={"user-agent":`gjsify-install/0.33.0`,"accept-encoding":a.acceptEncoding??`identity`};if(a.npmrc){let C=resolveAuthForUrl(n,a.npmrc);C&&(S.authorization=C)}if(a.headers)for(let[n,C]of Object.entries(a.headers))S[n.toLowerCase()]=C;return S}function resolveAuthForUrl(n,a){let S=pathPrefixes(new URL(n));for(let n of S){let S=a.authTokens[n];if(S)return`Bearer ${S}`;let C=a.basicAuth[n];if(C)return`Basic ${btoa(`${C.username}:${C.password}`)}`}return null}function pathPrefixes(n){let a=n.pathname.split(`/`).filter(Boolean),S=[];for(let C=a.length;C>=0;C--){let N=a.slice(0,C).join(`/`);S.push(N?`//${n.host}/${N}`:`//${n.host}`)}return S}var rP=__esmMin(()=>{}),PackageNotFoundError,IntegrityError,RegistryTimeoutError,iP=__esmMin(()=>{PackageNotFoundError=class extends Error{name;url;constructor(n,a){super(`Package not found in registry: ${n} (${a})`),this.name=n,this.url=a,this.name=`PackageNotFoundError`}},IntegrityError=class extends Error{url;integrity;constructor(n,a){super(`Tarball integrity mismatch for ${n} (expected ${a})`),this.url=n,this.integrity=a,this.name=`IntegrityError`}},RegistryTimeoutError=class extends Error{url;timeoutMs;attempts;constructor(n,a,S){let C=Math.round(a/100)/10,N=Math.round(a*S/100)/10;super(`@gjsify/npm-registry: GET ${n} timed out after ${C}s × ${S} attempt(s) (total ~${N}s). This usually means the registry CDN is slow or unreachable.`),this.url=n,this.timeoutMs=a,this.attempts=S,this.name=`RegistryTimeoutError`}}});function registryFor(n,a){if(a&&n.startsWith(`@`)){let S=n.slice(0,n.indexOf(`/`)),C=a.scopes[S];if(C)return ensureTrailingSlash$1(C)}return a?.registry?ensureTrailingSlash$1(a.registry):aP}function parseNpmrc(n){let a={registry:aP,scopes:{},authTokens:{},basicAuth:{}},S=n.split(/\r?\n/),C={};for(let n of S){let S=n.replace(/^\s+|\s+$/g,``);if(!S||S.startsWith(`#`)||S.startsWith(`;`))continue;let N=S.indexOf(`=`);if(N<0)continue;let F=S.slice(0,N).trim(),I=expandEnv(stripQuotes(S.slice(N+1).trim()));if(F===`registry`){a.registry=ensureTrailingSlash$1(I);continue}let H=F.match(/^(@[^:]+):registry$/);if(H){a.scopes[H[1]]=ensureTrailingSlash$1(I);continue}let W=F.match(/^\/\/(.+):_authToken$/);if(W){a.authTokens[normalizeAuthHost(W[1])]=I;continue}let K=F.match(/^\/\/(.+):username$/);if(K){(C[normalizeAuthHost(K[1])]??={}).user=I;continue}let q=F.match(/^\/\/(.+):_password$/);if(q){let n=base64Decode(I);(C[normalizeAuthHost(q[1])]??={}).pass=n;continue}}for(let[n,S]of Object.entries(C))S.user&&S.pass!==void 0&&(a.basicAuth[n]={username:S.user,password:S.pass});return a}function normalizeAuthHost(n){return`//${n.replace(/\/+$/,``)}`}function ensureTrailingSlash$1(n){return n.endsWith(`/`)?n:n+`/`}function stripQuotes(n){return n.startsWith(`"`)&&n.endsWith(`"`)||n.startsWith(`'`)&&n.endsWith(`'`)?n.slice(1,-1):n}function expandEnv(n){return n.replace(/\$\{([A-Z0-9_]+)\}/gi,(n,a)=>globalThis.process?.env?.[a]??``)}function base64Decode(n){return atob(n)}var aP,oP=__esmMin(()=>{aP=`https://registry.npmjs.org/`,__name$1(ensureTrailingSlash$1,`ensureTrailingSlash`)});async function fetchWithRetry(n,a,S){let C=S.fetch??globalThis.fetch;if(!C)throw Error(`@gjsify/npm-registry: globalThis.fetch is missing`);let N=Math.max(0,S.retries??3),F=Math.max(0,S.retryDelayMs??250),I=Math.max(0,S.timeoutMs??3e4),H=S.retryNotFound??!1,W=0,K,q=0;for(;;){if(a.signal?.aborted)throw signalAbortError(a.signal);let Y=I>0?new AbortController:null,X=Y===null?null:setTimeout(()=>Y.abort(Error(`@gjsify/npm-registry: per-request timeout ${I}ms`)),I),te=composeSignals(a.signal,Y?.signal);try{let S=await C(n,{...a,signal:te}),F=isRetryableStatus(S.status)||H&&S.status===404;if(S.ok||!F||W>=N)return S;try{await S.arrayBuffer()}catch{}K=Error(`HTTP ${S.status} ${S.statusText}`)}catch(S){let C=Y!==null&&Y.signal.aborted,F=a.signal?.aborted===!0;if(C&&!F){if(q++,W>=N)throw new RegistryTimeoutError(n,I,q);K=S}else if(F)throw signalAbortError(a.signal);else{if(!isRetryableError(S)||W>=N)throw S;K=S}}finally{X!==null&&clearTimeout(X)}let ne=Math.min(F*2**W,8e3);S.onRetry?.({attempt:W+1,error:K,delayMs:ne}),await delay$1(ne,a.signal),W++}}function composeSignals(n,a){return n?a?AbortSignal.any([n,a]):n:a}function isRetryableStatus(n){return n===408||n===425||n===429||n===500||n===502||n===503||n===504||n===521||n===522||n===524||n===525}function isRetryableError(n){if(n&&typeof n==`object`&&`name`in n&&n.name===`AbortError`)return!1;if(n instanceof TypeError)return!0;if(n&&typeof n==`object`&&`name`in n){let a=n.name;if(a===`FetchError`)return!0;if(a===`AbortError`)return!1}let a=n?.cause;if(a&&typeof a==`object`&&`code`in a){let n=a.code;if(typeof n==`string`)return n===`ECONNRESET`||n===`ECONNREFUSED`||n===`ENETUNREACH`||n===`ENOTFOUND`||n===`ETIMEDOUT`||n===`EAI_AGAIN`||n===`UND_ERR_SOCKET`||n===`UND_ERR_CONNECT_TIMEOUT`}return!1}function delay$1(n,a){return n<=0?Promise.resolve():new Promise((S,C)=>{let N=setTimeout(()=>{a?.removeEventListener?.(`abort`,onAbort),S()},n),onAbort=()=>{clearTimeout(N),C(signalAbortError(a))};if(a?.aborted){clearTimeout(N),C(signalAbortError(a));return}a?.addEventListener?.(`abort`,onAbort,{once:!0})})}function signalAbortError(n){let a=n&&`reason`in n?n.reason:void 0;if(a instanceof Error)return a;let S=Error(`Aborted`);return S.name=`AbortError`,S}var sP=__esmMin(()=>{iP(),__name$1(delay$1,`delay`)});async function verifyIntegrity(n,a){let S=a.trim().split(/\s+/);for(let a of S){let S=a.indexOf(`-`);if(S<0)continue;let C=a.slice(0,S).toLowerCase(),N=a.slice(S+1),F=globalThis.crypto?.subtle;if(!F)throw Error(`@gjsify/npm-registry: globalThis.crypto.subtle is missing`);let I=subriToWebCryptoAlgo(C);if(!I)continue;let H=await F.digest(I,dataAsArrayBuffer(n));if(bytesToBase64(new Uint8Array(H))===N)return!0}return!1}function subriToWebCryptoAlgo(n){switch(n){case`sha1`:return`SHA-1`;case`sha256`:return`SHA-256`;case`sha384`:return`SHA-384`;case`sha512`:return`SHA-512`;default:return null}}function dataAsArrayBuffer(n){if(n.byteOffset===0&&n.byteLength===n.buffer.byteLength)return n.buffer;let a=new Uint8Array(n.byteLength);return a.set(n),a.buffer}function bytesToBase64(n){let a=``;for(let S=0;S<n.length;S++)a+=String.fromCharCode(n[S]);return btoa(a)}var cP=__esmMin(()=>{});function assertPackument(n,a){if(!a||typeof a!=`object`)throw TypeError(`registry: ${n} packument is not an object`);let S=a;if(typeof S.name!=`string`)throw TypeError(`registry: ${n} packument missing string name`);if(!S.versions||typeof S.versions!=`object`)throw TypeError(`registry: ${n} packument missing versions map`)}function packumentUrl(n,a){let S=ensureTrailingSlash$1(a);if(n.startsWith(`@`)){let a=n.indexOf(`/`);if(a<0)throw TypeError(`Invalid scoped package name: ${n}`);let C=n.slice(0,a),N=n.slice(a+1);return`${S}${encodeURIComponent(C)}/${encodeURIComponent(N)}`}return`${S}${encodeURIComponent(n)}`}async function fetchPackumentConditional(n,a={}){let S=packumentUrl(n,a.registry??registryFor(n,a.npmrc)),C=buildHeaders(S,{...a,acceptEncoding:`gzip`});C.accept??=a.fullMetadata?`application/json`:`application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*`,a.ifNoneMatch&&(C[`if-none-match`]=a.ifNoneMatch);let N=await fetchWithRetry(S,{headers:C,signal:a.signal},{fetch:a.fetch,retries:a.retries,retryDelayMs:a.retryDelayMs,timeoutMs:a.timeoutMs,onRetry:a.onRetry});if(N.status===304){try{await N.arrayBuffer()}catch{}return{status:`not-modified`,etag:a.ifNoneMatch}}if(!N.ok)throw N.status===404||N.status===406?new PackageNotFoundError(n,S):Error(`registry GET ${S} -> ${N.status} ${N.statusText}`);let F=N.headers.get(`etag`)??void 0,I=await decodeJsonBody(N);return assertPackument(n,I),{status:`fresh`,packument:I,etag:F}}async function decodeJsonBody(n){return n.json()}async function fetchPackument(n,a={}){let S=await fetchPackumentConditional(n,a);if(!S.packument)throw Error(`registry: ${n} returned 304 Not Modified to an unconditional request`);return S.packument}var lP=__esmMin(()=>{rP(),iP(),oP(),sP()});async function fetchTarball(n,a={}){let S=buildHeaders(n,{...a,acceptEncoding:`identity`});S.accept??=`application/octet-stream`;let C=await fetchWithRetry(n,{headers:S,signal:a.signal},{fetch:a.fetch,retries:a.retries,retryDelayMs:a.retryDelayMs,timeoutMs:a.timeoutMs,onRetry:a.onRetry,retryNotFound:a.retryNotFound??!0});if(!C.ok)throw Error(`tarball GET ${n} -> ${C.status} ${C.statusText}`);let N=new Uint8Array(await C.arrayBuffer());if(a.integrity&&!await verifyIntegrity(N,a.integrity))throw new IntegrityError(n,a.integrity);return N}var uP=__esmMin(()=>{rP(),iP(),sP(),cP()});async function whoami(n,a){let S=`${ensureTrailingSlash$1(n)}-/whoami`,C=buildHeaders(S,{npmrc:a});C.accept=`application/json`;let N=globalThis.fetch;if(!N)throw Error(`@gjsify/npm-registry: globalThis.fetch is missing`);let F=await N(S,{method:`GET`,headers:C});if(!F.ok)throw Error(`whoami GET ${S} -> ${F.status} ${F.statusText}`);let I=await F.json();if(I&&typeof I==`object`&&`username`in I){let n=I.username;if(typeof n==`string`&&n.length>0)return{username:n}}return{}}var dP=__esmMin(()=>{rP(),oP()}),fP=__esmMin(()=>{rP(),oP(),lP(),uP(),dP()});function parseTar(n){let a=[],S=null,C=null,N=null,F=0;for(;F+512<=n.length;){let I=n.subarray(F,F+512);if(allZeros(I)){let a=n.subarray(F+512,F+2*512);if(a.length===512&&allZeros(a))break;F+=512;continue}if(!validateChecksum(I))throw new TarParseError(`Bad header checksum at offset ${F} — file is not a valid tar archive`);let H=readString(I,0,100),W=parseOctal(I,100,8),K=parseOctal(I,124,12),q=parseOctal(I,136,12),Y=String.fromCharCode(I[156]||0),X=readString(I,157,100),te=readString(I,257,6),ne=readString(I,345,155),re=readString(I,265,32),ie=readString(I,297,32);F+=512;let ae=n.subarray(F,F+K);if(F+=alignToBlock(K),Y===`x`){S=parsePaxRecords(ae);continue}if(Y===`g`)continue;if(Y===`L`){C=bytesToString(ae).replace(/\0+$/,``);continue}if(Y===`K`){N=bytesToString(ae).replace(/\0+$/,``);continue}let oe=H;te===`ustar`&&ne!==``&&(oe=`${ne}/${H}`),C!==null&&(oe=C,C=null);let Z=X;if(N!==null&&(Z=N,N=null),S!==null){let C=S.get(`path`);C!==void 0&&(oe=C);let N=S.get(`linkpath`);N!==void 0&&(Z=N);let I=S.get(`size`);if(I!==void 0){let C=Number(I);if(Number.isFinite(C)){let N=F-alignToBlock(K),I=n.subarray(N,N+C);F=N+alignToBlock(C),S=null,a.push(buildEntry(oe,Z,Y,W,q,re,ie,I));continue}}S=null}a.push(buildEntry(oe,Z,Y,W,q,re,ie,ae))}return a}function buildEntry(n,a,S,C,N,F,I,H){return{name:n,linkname:a,type:typeflagToType(S,n),mode:C,mtime:N,body:H,uname:F,gname:I}}function typeflagToType(n,a){switch(n){case`0`:case`\0`:case``:return a.endsWith(`/`)?`directory`:`file`;case`1`:return`hardlink`;case`2`:return`symlink`;case`5`:return`directory`;case`x`:return`pax-header`;case`g`:return`pax-global`;case`L`:return`gnu-longname`;case`K`:return`gnu-longlink`;default:return`unknown`}}function parsePaxRecords(n){let a=new Map,S=0;for(;S<n.length;){let C=S;for(;C<n.length&&n[C]!==32;)C++;if(C>=n.length)break;let N=bytesToString(n.subarray(S,C)),F=Number(N);if(!Number.isFinite(F)||F<=0)break;let I=S+F;if(I>n.length)break;let H=bytesToString(n.subarray(C+1,I-1)),W=H.indexOf(`=`);if(W>0){let n=H.slice(0,W),S=H.slice(W+1);a.set(n,S)}S=I}return a}function readString(n,a,S){let C=a,N=a+S;for(;C<N&&n[C]!==0;)C++;return bytesToString(n.subarray(a,C))}function bytesToString(n){return new TextDecoder(`utf-8`,{fatal:!1}).decode(n)}function parseOctal(n,a,S){if(S>0&&n[a]&128){let C=n[a]&127;for(let N=1;N<S;N++)C=C*256+n[a+N];return C}let C=``;for(let N=0;N<S;N++){let S=n[a+N];S===0||S===32||(C+=String.fromCharCode(S))}return C===``?0:parseInt(C,8)}function alignToBlock(n){return Math.ceil(n/512)*512}function allZeros(n){for(let a=0;a<n.length;a++)if(n[a]!==0)return!1;return!0}function validateChecksum(n){let a=parseOctal(n,148,8),S=0,C=0;for(let a=0;a<512;a++){let N=a>=148&&a<156?32:n[a];S+=N,C+=N>127?N-256:N}return a===S||a===C}var TarParseError,pP=__esmMin(()=>{TarParseError=class extends Error{constructor(n){super(n),this.name=`TarParseError`}}});function createTarball(n){let a=[];for(let S of n){if(`directory`in S&&S.directory===!0){a.push(buildHeader(ensureTrailingSlash(S.name),0,`5`,S.mode??493,S.mtime??0));continue}let n=S,C=typeof n.body==`string`?new TextEncoder().encode(n.body):n.body,N=n.mode??defaultFileMode(C);a.push(buildHeader(n.name,C.byteLength,`0`,N,n.mtime??0)),a.push(C);let F=padTo512(C.byteLength);F>0&&a.push(new Uint8Array(F))}return a.push(new Uint8Array(512*2)),concatChunks(a)}function buildHeader(n,a,S,C,N){let{prefix:F,basename:I}=splitPathForUstar(n),H=new Uint8Array(512);writeAscii(H,I,0,100),writeOctal(H,C&4095,100,7),H[107]=0,writeOctal(H,0,108,7),H[115]=0,writeOctal(H,0,116,7),H[123]=0,writeOctal(H,a,124,11),H[135]=0,writeOctal(H,N,136,11),H[147]=0;for(let n=148;n<156;n++)H[n]=32;H[156]=S.charCodeAt(0),writeAscii(H,`ustar\0`,257,6),writeAscii(H,`00`,263,2),F&&writeAscii(H,F,345,155);let W=0;for(let n=0;n<512;n++)W+=H[n];return writeAscii(H,W.toString(8).padStart(6,`0`),148,6),H[154]=0,H[155]=32,H}function splitPathForUstar(n){if(n.length<=100)return{prefix:``,basename:n};if(n.length>255)throw Error(`createTarball: path too long (${n.length} > 255 chars): ${n}`);for(let a=Math.min(n.length-1,155);a>0;a--)if(n[a]===`/`&&n.length-a-1<=100)return{prefix:n.slice(0,a),basename:n.slice(a+1)};throw Error(`createTarball: cannot split path into ustar prefix+basename (basename slot is 100 chars): ${n}`)}function writeAscii(n,a,S,C){let N=new TextEncoder().encode(a);if(N.length>C)throw Error(`createTarball: field too long (${N.length} > ${C}): "${a}"`);n.set(N,S)}function writeOctal(n,a,S,C){writeAscii(n,a.toString(8).padStart(C,`0`),S,C)}function padTo512(n){let a=n%512;return a===0?0:512-a}function ensureTrailingSlash(n){return n.endsWith(`/`)?n:`${n}/`}function defaultFileMode(n){return n.length>=2&&n[0]===35&&n[1]===33?493:420}function concatChunks(n){let a=0;for(let S of n)a+=S.byteLength;let S=new Uint8Array(a),C=0;for(let a of n)S.set(a,C),C+=a.byteLength;return S}var mP=__esmMin(()=>{});async function extractTarball(n,a,S={}){let C=n instanceof Uint8Array?n:new Uint8Array(n),N=parseTar(S.gzip??(C.length>=2&&C[0]===31&&C[1]===139)?await gunzip(C):C);mkdirSync(a,{recursive:!0});let F=S.strip??1,I=S.preventEscape??!0,H={files:[],directories:[],symlinks:[],skipped:0};for(let n of N){let C=stripComponents(n.name,F);if(C===null||C===``){H.skipped++;continue}let N=hs(a,C);if(I&&!isInside$1(N,a))throw Error(`tar: refusing to extract ${n.name} outside ${a} (resolved=${N})`);if(S.filter&&!S.filter(n,N)){H.skipped++;continue}if(n.type===`directory`){mkdirSync(N,{recursive:!0}),H.directories.push(N);continue}if(n.type===`file`){mkdirSync(xs(N),{recursive:!0}),writeFileSync(N,n.body);let a=S.chmod?.(n,N)??n.mode&511;if(a>0)try{chmodSync(N,a)}catch{}H.files.push(N);continue}if(n.type===`symlink`){mkdirSync(xs(N),{recursive:!0});try{symlinkSync(n.linkname,N),H.symlinks.push(N)}catch{writeFileSync(N,n.linkname),H.files.push(N)}continue}H.skipped++}return H}async function gunzip(n){let a=globalThis.DecompressionStream;if(typeof a!=`function`)throw Error(`@gjsify/tar: globalThis.DecompressionStream is not available — import '@gjsify/compression-streams/register' on GJS to register it`);return drainStream(new Blob([new Uint8Array(n)]).stream().pipeThrough(new a(`gzip`)))}async function gzip(n){let a=globalThis.CompressionStream;if(typeof a!=`function`)throw Error(`@gjsify/tar: globalThis.CompressionStream is not available — import '@gjsify/compression-streams/register' on GJS to register it`);return drainStream(new Blob([new Uint8Array(n)]).stream().pipeThrough(new a(`gzip`)))}async function drainStream(n){let a=[],S=0,C=n.getReader();for(;;){let{value:n,done:N}=await C.read();if(N)break;let F=n instanceof Uint8Array?n:new Uint8Array(n);a.push(F),S+=F.length}let N=new Uint8Array(S),F=0;for(let n of a)N.set(n,F),F+=n.length;return N}function stripComponents(n,a){if(a<=0)return n;let S=n.split(`/`).filter(n=>n!==``);return S.length<=a?null:S.slice(a).join(`/`)}function isInside$1(n,a){let S=ys(a,n);return S!==``&&!S.startsWith(`..`)&&!_s(S)}var hP=__esmMin(()=>{pP(),Dl(),ks(),__name$1(isInside$1,`isInside`)}),gP=__exportAll$4({BLOCK_SIZE:()=>512,TarParseError:()=>TarParseError,createTarball:()=>createTarball,extractTarball:()=>extractTarball,gunzip:()=>gunzip,gzip:()=>gzip,parseTar:()=>parseTar}),_P=__esmMin(()=>{pP(),mP(),hP()});function gjsifyCacheRoot(n,a){let S=process.env.XDG_CACHE_HOME;return vs(S&&S.length>0?S:vs(homedir(),`.cache`),`gjsify`,n,a)}function atomicWrite(n,a){try{atomicWriteStrict(n,a)}catch{}}function atomicWriteStrict(n,a){mkdirSync(vs(n,`..`),{recursive:!0});let S=`${n}.tmp.${process.pid}`;writeFileSync(S,a),renameSync(S,n)}function readCacheFile(n){if(!existsSync(n))return null;try{let a=readFileSync(n);return a.length===0?null:a}catch{return null}}var vP=__esmMin(()=>{Dl(),Cm(),ks()});function staleMs(){let n=process.env.GJSIFY_INSTALL_LOCK_STALE_MS;if(n!==void 0){let a=Number(n);if(Number.isFinite(a)&&a>0)return a}return xP}function lockingDisabled(){let n=process.env.GJSIFY_INSTALL_LOCK;if(n===void 0)return!1;let a=n.trim();return a===`0`||a===`false`}function isPidAlive(n){if(existsSync(`/proc/self`))return existsSync(`/proc/${n}`);try{return process.kill(n,0),!0}catch(n){return n.code===`EPERM`}}function mtimeMs(n){try{return statSync(n).mtimeMs}catch{return null}}function assessLock(n){let a=vs(n,bP),S=null;try{S=JSON.parse(readFileSync(a,`utf-8`))}catch{S=null}let C=Date.now();if(S&&typeof S.pid==`number`){if(!isPidAlive(S.pid))return{stale:!0,reason:`owner pid ${S.pid} is gone`,ownerPid:S.pid};let n=typeof S.startedAt==`number`?S.startedAt:mtimeMs(a);return n!==null&&C-n>staleMs()?{stale:!0,reason:`owner pid ${S.pid} exceeded the ${staleMs()}ms staleness budget`,ownerPid:S.pid}:{stale:!1,ownerPid:S.pid}}let N=mtimeMs(n);return N===null?{stale:!1}:C-N>SP?{stale:!0,reason:`no owner recorded within the acquire grace period`}:{stale:!1}}function stealStaleLock(n){let a=`${n}.stale-${process.pid}-${++EP}`;try{renameSync(n,a)}catch{return!1}try{rmSync(a,{recursive:!0,force:!0})}catch{}return!0}function abortErr(n){let a=n&&`reason`in n?n.reason:void 0;if(a instanceof Error)return a;let S=Error(`Aborted`);return S.name=`AbortError`,S}function delay(n,a){return n<=0?Promise.resolve():new Promise((S,C)=>{let onAbort=()=>{clearTimeout(N),C(abortErr(a))},N=setTimeout(()=>{a?.removeEventListener?.(`abort`,onAbort),S()},n);if(a?.aborted){clearTimeout(N),C(abortErr(a));return}a?.addEventListener?.(`abort`,onAbort,{once:!0})})}function makeHandle(n){let a=!1;return{release(){if(a)return;a=!0;let S=TP.get(n);if(S&&(S.count--,!(S.count>0))){TP.delete(n);try{let a=JSON.parse(readFileSync(vs(n,bP),`utf-8`));if(a.nonce!==void 0&&a.nonce!==S.nonce)return}catch{}try{rmSync(n,{recursive:!0,force:!0})}catch{}}}}}async function acquireInstallLock(n,a={}){if(lockingDisabled())return{release(){}};let S;try{S=realpathSync(n)}catch{S=hs(n)}let C=vs(S,`node_modules`,yP),N=TP.get(C);if(N)return N.count++,makeHandle(C);mkdirSync(xs(C),{recursive:!0});let F=`${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`,I=CP,H=!1;for(;;){if(a.signal?.aborted)throw abortErr(a.signal);try{return mkdirSync(C),writeFileSync(vs(C,bP),JSON.stringify({pid:process.pid,nonce:F,startedAt:Date.now()})),TP.set(C,{count:1,nonce:F}),makeHandle(C)}catch(n){if(n.code!==`EEXIST`)throw n}let n=assessLock(C);if(n.stale){stealStaleLock(C)&&he.warn(`gjsify install: removed stale install lock (${n.reason}) — ${C}`);continue}if(!H){H=!0;let a=n.ownerPid===void 0?``:` (pid ${n.ownerPid})`;he.warn(`gjsify install: waiting for a concurrent install${a} to release ${C} …`)}await delay(I,a.signal),I=Math.min(Math.round(I*1.6),wP)}}var yP,bP,xP,SP,CP,wP,TP,EP,DP=__esmMin(()=>{ge(),Dl(),ks(),yP=`.gjsify-install-lock`,bP=`owner.json`,xP=35*6e4,SP=15e3,CP=150,wP=1e3,TP=new Map,EP=0});function cacheRoot$1(){return gjsifyCacheRoot(`tarballs`,OP)}function parseSri$1(n){if(!n)return null;let a=n.indexOf(`-`);if(a<=0||a===n.length-1)return null;let S=n.slice(0,a),C=n.slice(a+1).replace(/=+$/,``),N=qe.from(C,`base64`).toString(`hex`);return N.length<4?null:{algorithm:S,hex:N}}function pathFor$2(n){let a=parseSri$1(n);if(!a)return null;let S=a.hex.slice(0,2);return vs(cacheRoot$1(),a.algorithm,S,`${a.hex}.tgz`)}function getCachedTarball(n){let a=pathFor$2(n);return a?readCacheFile(a):null}function putCachedTarball(n,a){let S=pathFor$2(n);S&&(existsSync(S)||atomicWrite(S,a))}function npmCacacheContentDir(){let n=process.env.GJSIFY_NPM_CACHE;if(n!==void 0){let a=n.trim();return a===``||a===`0`||a===`false`?null:vs(a.endsWith(`_cacache`)?a:vs(a,`_cacache`),`content-v2`)}let a=process.env.npm_config_cache;return vs(a&&a.length>0?a:vs(homedir(),`.npm`),`_cacache`,`content-v2`)}function npmCachePathFor(n){let a=npmCacacheContentDir();if(!a)return null;let S=parseSri$1(n);return S?vs(a,S.algorithm,S.hex.slice(0,2),S.hex.slice(2,4),S.hex.slice(4)):null}function getForeignCachedTarball(n){let a=npmCachePathFor(n);return a?readCacheFile(a):null}var OP,kP=__esmMin(()=>{nt(),Dl(),Cm(),ks(),vP(),OP=`v1`,__name$1(cacheRoot$1,`cacheRoot`),__name$1(parseSri$1,`parseSri`),__name$1(pathFor$2,`pathFor`)});function isEnabled(){let n=process.env.GJSIFY_PACKUMENT_CACHE;if(n===void 0)return!0;let a=n.trim();return!(a===`0`||a===`false`||a===``)}function cacheRoot(){return gjsifyCacheRoot(`metadata`,AP)}function shardFor(n){let a=2166136261;for(let S=0;S<n.length;S++)a^=n.charCodeAt(S),a=Math.imul(a,16777619);return(a>>>0&255).toString(16).padStart(2,`0`)}function encodePart(n){return encodeURIComponent(n).replace(/\*/g,`%2A`)}function packumentCacheKey(n,a,S){return`${S},${encodePart(n)},${encodePart(a)}`}function pathFor$1(n,a,S){if(!isEnabled())return null;let C=packumentCacheKey(n,a,S);return vs(cacheRoot(),shardFor(C),`${C}.json`)}function getCachedPackument(n,a,S=`corgi`){let C=pathFor$1(n,a,S);if(!C)return null;let N=readCacheFile(C);if(!N)return null;try{let n=JSON.parse(N.toString(`utf-8`));return typeof n.etag!=`string`||!n.etag||!n.packument||typeof n.packument!=`object`?null:{etag:n.etag,packument:n.packument}}catch{return null}}function putCachedPackument(n,a,S,C,N=`corgi`){if(!S)return;let F=pathFor$1(n,a,N);F&&atomicWrite(F,JSON.stringify({etag:S,packument:C}))}var AP,jP=__esmMin(()=>{ks(),vP(),AP=`v3`,__name$1(pathFor$1,`pathFor`)});function parseNodeMajor(n){return Number.parseInt(String(n).split(`.`,1)[0]??``,10)}function nativeBackendNodeError(n,a){if(!a)return null;let S=parseNodeMajor(n);return!Number.isFinite(S)||S>=24?null:`gjsify install (native backend) requires Node ≥ 24, but this is Node ${n}. Its prebuilt native modules are ABI-locked to Node 24 and crash on older majors. Use Node 24 (nvm/asdf locally, actions/setup-node in CI), or run with --backend npm.`}function onRealNode(){return gjsSystemVersion()===void 0?isNode():!1}function assertNativeBackendNodeVersion(){let n=nativeBackendNodeError(process.versions.node,onRealNode());if(n)throw Error(n)}var MP=__esmMin(()=>{Rm()});function checkList(n,a){let S=typeof a==`string`?[a]:a;if(S.length===1&&S[0]===`any`)return!0;let C=0,N=!1;for(let a of S){let S=a.charAt(0)===`!`,F=S?a.slice(1):a;if(S){if(C++,n===F)return!1}else N||=n===F}return N||C===S.length}function checkPlatform(n,a){let S=n.os?checkList(a.os,n.os):!0,C=n.cpu?checkList(a.cpu,n.cpu):!0,N=n.libc?checkList(a.libc,n.libc):!0;return n.libc&&!a.libc&&(N=!1),{ok:S&&C&&N,current:{os:a.os,cpu:a.cpu,libc:a.libc},required:{os:n.os,cpu:n.cpu,libc:n.libc}}}function declaresPlatform(n){return!!(n.os||n.cpu||n.libc)}function badPlatformError(n,a){let S=Error(`Unsupported platform for ${n}: wanted ${JSON.stringify(a.required)} (current: ${JSON.stringify(a.current)})`);return S.code=`EBADPLATFORM`,S.pkgid=n,S.current=a.current,S.required=a.required,S}function isMuslSharedObject(n){return n.includes(`libc.musl-`)||n.includes(`ld-musl-`)}function libcFromLddFile(n){let a=n.readTextFile(NP);if(a!==null)return a.includes(`musl`)?`musl`:a.includes(`GNU C Library`)?`glibc`:null}function libcFromReportData(n){return n.glibcVersionRuntime?`glibc`:Array.isArray(n.sharedObjects)&&n.sharedObjects.some(n=>isMuslSharedObject(String(n)))?`musl`:null}function libcFromLoaderScan(n,a=PP){let S=!1;for(let C of a){let a=n.listDir(C);if(a)for(let n of a){if(n.startsWith(`ld-linux`))return`glibc`;n.startsWith(`ld-musl-`)&&(S=!0)}}return S?`musl`:null}function detectLibc(n,a){if(n!==`linux`)return;let S=libcFromLddFile(a);if(S!==void 0)return S??void 0;let C=a.diagnosticReport();return C===null?libcFromLoaderScan(a)??void 0:libcFromReportData(C)??void 0}function defaultLibcProbeHost(){return{readTextFile(n){try{return readFileSync(n,`utf-8`)}catch{return null}},listDir(n){try{return readdirSync(n)}catch{return null}},diagnosticReport(){let n=process.report;if(!n||typeof n.getReport!=`function`)return null;let a=n.excludeNetwork;n.excludeNetwork=!0;try{let a=n.getReport();return{glibcVersionRuntime:a.header?.glibcVersionRuntime,sharedObjects:a.sharedObjects}}finally{n.excludeNetwork=a}}}}function hostLibc(n,a=defaultLibcProbeHost()){return IP||=(FP=detectLibc(n,a),!0),FP}function readPlatformOverrides(n){let pick=a=>{let S=n[a];if(typeof S!=`string`)return;let C=S.trim();return C===``?void 0:C},a={},S=pick(`npm_config_os`),C=pick(`npm_config_cpu`),N=pick(`npm_config_libc`);return S!==void 0&&(a.os=S),C!==void 0&&(a.cpu=C),N!==void 0&&(a.libc=N),a}function readPlatformForce(n){let a=n.npm_config_force;if(typeof a!=`string`)return!1;let S=a.trim().toLowerCase();return S===`true`||S===`1`}function resolveHostPlatform(n={}){let a=readPlatformOverrides(n.env??process.env),S=a.os??n.platform??process.platform;return{os:S,cpu:a.cpu??n.arch??process.arch,libc:a.libc??(S===`linux`?hostLibc(S,n.probe??defaultLibcProbeHost()):void 0)}}function describePlatformTarget(n){return`${n.os}-${n.cpu}${n.libc?`-${n.libc}`:``}`}var NP,PP,FP,IP,LP=__esmMin(()=>{Dl(),NP=`/usr/bin/ldd`,PP=[`/lib`,`/lib64`,`/usr/lib`],IP=!1}),RP=__exportAll$4({applyPlatformFilter:()=>applyPlatformFilter,computeOptionalFlags:()=>computeOptionalFlags,installPackagesNative:()=>installPackagesNative,parseSpec:()=>parseSpec,pickVersion:()=>pickVersion,requiredDepEntries:()=>requiredDepEntries,warnMissingNativeBuilds:()=>warnMissingNativeBuilds,writeBinEntry:()=>writeBinEntry});async function installPackagesNative(n){if(assertNativeBackendNodeVersion(),n.specs.length===0)throw Error(`installPackagesNative: empty specs list`);mkdirSync(n.prefix,{recursive:!0});let a=await loadNpmrc$1(n),S=makeLogger(n.verbose??!1),C=await acquireInstallLock(n.prefix,{signal:n.signal});try{return await installPackagesNativeLocked(n,a,S)}finally{C.release()}}async function installPackagesNativeLocked(n,a,S){let C=n.progress,N=vs(n.prefix,BP),F=readLockfile(N),I=resolveHostPlatform(),H=readPlatformForce(process.env);S(`install: platform target %s%s`,describePlatformTarget(I),H?` (--force: checks bypassed)`:``);let W,K=!1,q=new Set;if(n.frozen){if(!F)throw Error(`install: --immutable requires ${BP} at ${n.prefix} — none found. Run \`gjsify install\` (without --immutable) to generate one and commit it.`);let a=describeLockfileDrift(F,n.specs);if(a)throw Error(`install: --immutable but ${N} is stale.\n${a}\nRe-run \`gjsify install\` (without --immutable) to refresh the lockfile.`);S(`install: --immutable, using lockfile (%d package(s))`,Object.keys(F.packages).length),W=lockfileToNodes(F)}else if(!n.refreshLockfile&&F&&F.lockfileVersion===VP&&lockfileMatchesRequest(F,n.specs))S(`install: using lockfile (%d package(s))`,Object.keys(F.packages).length),W=lockfileToNodes(F);else{let N=!n.refreshLockfile&&F?buildPreferredVersions(F):void 0;S(`install: resolving %d top-level spec(s) → %s%s`,n.specs.length,n.prefix,N?` (preserving ${N.size} locked name(s))`:``);let I=await resolveDeps(n.specs,a,S,n.overrides,n.skipDeps,n.signal,C,N,n.workspaceNames,n.specOrigins,n.optionalSpecs);W=I.nodes,q=I.skippedEdges,K=!0}if(computeOptionalFlags(W,requiredTopLevelNames(n.specs,n.optionalSpecs),S),assertRequiredEdgesResolved(W,q),K&&n.lockfile&&(writeLockfile(N,n.specs,W),S(`install: wrote %s (%d entries)`,BP,W.length)),n.workspaceNames&&n.workspaceNames.size>0){let a=W.length;W=W.filter(a=>!n.workspaceNames.has(a.name));let C=a-W.length;C>0&&S(`install: %d workspace-provided package(s) symlinked, not fetched`,C)}let Y=applyPlatformFilter(W,I,H,S);return S(`install: downloading %d tarball(s)`,Y.length),await downloadAndExtractAll(Y,n.prefix,a,S,n.signal,C),await linkBins(Y,n.prefix,S),warnMissingNativeBuilds(Y,n.prefix,S),S(`install: done`),topLevelResolutions(n.specs,W)}function errMsg(n){return n instanceof Error?n.message:String(n)}function applyPlatformFilter(n,a,S,C){let N=[],F=0;for(let I of n){let n=I.platform;if(!n||!declaresPlatform(n)){N.push(I);continue}let H=checkPlatform(n,a);if(H.ok){N.push(I);continue}let W=`${I.name}@${I.version}`;if(!I.optional){if(S){C(`platform-forced: %s (required, incompatible, installed anyway via --force)`,W),N.push(I);continue}throw badPlatformError(W,H)}I.inert=!0,F++,C(`platform-skip: %s (%s) current=%s required=%s`,W,I.installPath,JSON.stringify(H.current),JSON.stringify(H.required))}return F>0&&C(`install: %d optional package(s) inert — not installable on %s`,F,describePlatformTarget(a)),N}function warnMissingNativeBuilds(n,a,S){let C=process.platform,N=process.arch,F=[`preinstall`,`install`,`postinstall`];for(let I of n){let n=vs(a,I.installPath),H;try{H=JSON.parse(readFileSync(vs(n,`package.json`),`utf8`))?.scripts}catch{continue}if(!H||typeof H!=`object`)continue;let W=F.find(n=>typeof H[n]==`string`);if(W===void 0)continue;let K=!1;try{let a=vs(n,`prebuilds`);for(let n of readdirSync(a))if(n.startsWith(`${C}-`)&&readdirSync(vs(a,n)).length>0){K=!0;break}}catch{}if(!K)try{K=readdirSync(vs(n,`build`,`Release`)).some(n=>n.endsWith(`.node`)||n.endsWith(`.so`))}catch{}K||S("install: WARNING — %s declares a native `%s` build script but ships no %s-%s prebuild, and gjsify install does not run build scripts (node-free). It will not load until built: run `node-gyp rebuild` in %s, or use a version that ships a %s-%s prebuild.",I.name,W,C,N,I.installPath,C,N)}}function topLevelResolutions(n,a){let S=new Map;for(let n of a)n.installPath===`node_modules/${n.name}`&&S.set(n.name,n);let C=[];for(let a of n){let n=parseSpecName(a),N=S.get(n);N&&C.push({name:N.name,version:N.version})}return C}function parseSpecName(n){if(n.startsWith(`@`)){let a=n.indexOf(`/`);if(a===-1)return n;let S=n.indexOf(`@`,a+1);return S===-1?n:n.slice(0,S)}let a=n.indexOf(`@`);return a===-1?n:n.slice(0,a)}async function resolveDeps(n,a,S,C,N,F,I,H,W,K,q){I?.beginPhase(`resolve`,n.length);let applyOverride=(n,a)=>{if(!C)return a;let N=C[n];return typeof N!=`string`||N.length===0||N===a?a:(S(`install: override %s %s → %s`,n,a,N),N)},Y=new Map,fetchPkg=n=>{let C=Y.get(n);if(C)return C;let N=fetchPackumentWithDiskCache(n,a,S,F,`full`);return Y.set(n,N),N},X=new Map,te=new Map,ne=new Set,re=new Map,ie=n.map(parseSpec).map(n=>{let a=applyOverride(n.name,n.range),S=re.get(n.name);S||(S=new Map,re.set(n.name,S));let C=S.get(a);C||(C=new Set,S.set(a,C));for(let a of K?.get(`${n.name}@${n.range}`)??[])C.add(a);return{from:null,name:n.name,range:a,required:!q?.has(n.name)}});for(;ie.length>0;){let n=ie.splice(0,ie.length),a=[],C=new Set;for(let S of n)Y.has(S.name)||C.has(S.name)||(C.add(S.name),a.push(S.name));await prefetchPackuments(a,fetchPkg,F);for(let a=0;a<n.length;a++){let C=n[a];if(W?.has(C.name))continue;let F=findVisible(C.from,C.name,X);if(F&&satisfiesRange(F.version,C.range))continue;let K=null;try{let F=await fetchPkg(C.name),W=preferredVersionFor(H?.get(C.name),C.range);if(K=pickVersion(F,C.range,W),!K)throw Error(`No version of ${C.name} satisfies ${C.range}`);let q=F.versions[K];if(!q)throw Error(`Packument for ${C.name} promised ${K} but no entry exists`);let Y=decidePlacement(C.from,C.name,K,te),ne={name:C.name,version:K,tarballUrl:q.dist.tarball,integrity:q.dist.integrity,installPath:Y,dependencies:q.dependencies??{},optionalDependencies:q.optionalDependencies??{},bin:q.bin,platform:platformDeclarationOf(q),optional:!C.required};if(X.set(Y,ne),Y===`node_modules/${C.name}`&&te.set(C.name,ne),S(`resolve: %s@%s ← %s (at %s)`,C.name,K,C.range,Y),I?.update({phase:`resolve`,current:X.size,total:X.size+(n.length-a-1)+ie.length,name:`${C.name}@${K}`}),!N){for(let[n,a]of requiredDepEntries(ne))ie.push({from:Y,name:n,range:applyOverride(n,a),required:!ne.optional});for(let[n,a]of Object.entries(ne.optionalDependencies))ie.push({from:Y,name:n,range:applyOverride(n,a),required:!1})}}catch(n){if(!C.required){ne.add(edgeKey(C.from,C.name)),S(`resolve: optional dep %s@%s skipped (%s)`,C.name,C.range,errMsg(n));continue}throw n}}}return I?.endPhase(`resolve`),emitTopLevelConflictWarnings(re,te),{nodes:Array.from(X.values()),skippedEdges:ne}}function platformDeclarationOf(n){let a={os:n.os,cpu:n.cpu,libc:n.libc};return declaresPlatform(a)?a:void 0}function edgeKey(n,a){return`${n??``}\n${a}`}function parseEdgeKey(n){let a=n.indexOf(`
|
|
866
|
+
`});function usingSelfShim(){return FN}function needsSelfShim(n){if(n.gjs)return!0;let a=ys(n.workspaceRoot,n.selfEntry);return a===``||a.startsWith(`..`)||_s(a)}function ensureGjsifyShimOnPath(){if(PN)return;PN=!0;let n=process.env.GJSIFY_SHIM_DIR;if(n&&existsSync(vs(n,`gjsify`))){FN=!0,(process.env.PATH??``).split(Ds).includes(n)||(process.env.PATH=n+Ds+(process.env.PATH??``));return}let a=isGjs(),S=fileURLToPath(a?import.meta.url:new URL(`../index.js`,import.meta.url));if(!needsSelfShim({gjs:a,selfEntry:S,workspaceRoot:findWorkspaceRoot(process.cwd())??process.cwd()}))return;let C=mkdtempSync(vs(tmpdir(),`gjsify-shim-`)),N=vs(C,`gjsify`),F=a?process.env.GJS_CONSOLE||`gjs`:`node`,I=a?[`-m`]:[];if(writeFileSync(N,`#!/bin/sh\nexec "${F}" ${I.length>0?`${I.join(` `)} `:``}"${S}" "$@"\n`,{mode:493}),chmodSync(N,493),!a&&process.platform===`win32`){let{cmd:n,ps1:a}=buildLauncherShims({interpreter:F,interpreterArgs:I,target:S});writeFileSync(`${N}.cmd`,n),writeFileSync(`${N}.ps1`,a)}FN=!0,process.env.GJSIFY_SHIM_DIR=C,process.env.PATH=C+Ds+(process.env.PATH??``)}var PN,FN,IN=__esmMin(()=>{Dl(),Cm(),ks(),an(),Rm(),NN(),ev(),PN=!1,FN=!1});function editDistance(n,a){if(n===a)return 0;if(n.length===0)return a.length;if(a.length===0)return n.length;let S=Array.from({length:a.length+1},(n,a)=>a),C=Array.from({length:a.length+1},()=>0);for(let N=1;N<=n.length;N++){C[0]=N;for(let F=1;F<=a.length;F++){let I=n[N-1]===a[F-1]?0:1;C[F]=Math.min(S[F]+1,C[F-1]+1,S[F-1]+I)}[S,C]=[C,S]}return S[a.length]}function suggestClosest(n,a){if(a.length===0)return;let S=n.toLowerCase(),C=Math.max(2,Math.floor(n.length/3)),N,F=1/0;for(let n of a){let a=editDistance(S,n.toLowerCase());a<F&&(F=a,N=n)}return N!==void 0&&F<=C?N:void 0}var LN=__esmMin(()=>{});function collectTransitiveClosure(n,a,S){let C=new Map;for(let n of a)C.set(n.name,n);let N=new Set,F=[],I=[n];for(;I.length>0;){let n=I.pop();if(N.has(n.name))continue;N.add(n.name),F.push(n);let a=n.manifest,H=[a.dependencies,S?a.devDependencies:void 0,a.optionalDependencies];for(let n of H)if(n)for(let[a,S]of Object.entries(n)){if(typeof S!=`string`||!S.startsWith(`workspace:`))continue;let n=C.get(a);n&&(N.has(n.name)||I.push(n))}}return F}async function runOne$1(n,a,S,C,N,F){if(F&&F.tryRestore(n))return;let I=F?.snapshotOutputs(n),H=C===`gjsify`?[`run`,a,...S]:[`run`,a,...S.length>0?[`--`,...S]:[]];N&&he.error(`[${n.name}] $ ${C} ${H.join(` `)}`);let{code:W}=await spawnToCompletion(C,H,{completion:`exit`,cwd:n.location,color:!0});if(W!==0)throw Error(`${C} ${H.join(` `)} exited with code ${W}`);F&&I&&F.storeAfterSuccess(n,I)}function detectPackageManager$1(){if(isGjs()||usingSelfShim())return`gjsify`;let n=process.env.npm_config_user_agent??``;return n.startsWith(`yarn/`)?`yarn`:n.startsWith(`gjsify/`)?`gjsify`:`npm`}var RN,zN=__esmMin(()=>{ge(),xN(),Q_(),ev(),ON(),Rm(),IN(),LN(),RN={command:`workspace <name> <script> [args..]`,description:"Run a workspace script. Both `workspace <name> <script>` and the yarn spelling `workspace <name> run <script>` work.",builder:n=>n.positional(`name`,{description:"Workspace name (matches package.json `name` field).",type:`string`,demandOption:!0}).positional(`script`,{description:`Script name to run inside that workspace.`,type:`string`,demandOption:!0}).positional(`args`,{description:`Extra arguments forwarded to the script.`,type:`string`,array:!0}).option(`with-dependencies`,{description:"Pre-build the target workspace's transitive workspace dependencies in topological order before running the script in the target. Deps that don't declare the script are skipped (--if-present behaviour). Replaces manual `gjsify workspace A build && gjsify workspace B build && …` chains.",type:`boolean`,alias:[`d`,`t`,`topological`],default:!1}).option(`include-dev`,{description:"When --with-dependencies is set, also walk devDependencies (production deps only by default — matches `gjsify foreach -t`).",type:`boolean`,default:!1}).option(`continue-on-error`,{description:`When --with-dependencies is set, keep running remaining deps after one fails (default: stop on first failure).`,type:`boolean`,default:!1}).option(`verbose`,{description:`Echo every spawned command before running it.`,type:`boolean`,alias:`v`,default:!1}).option(`cached`,{description:`Content-hash build cache (ADR 0006): skip the script for a workspace whose inputs (src/**, package.json, tsconfig*.json, transitive workspace deps, toolchain versions) are unchanged and restore its stored outputs instead; on miss run it and store the output dirs it modified. Also applies to the deps run via --with-dependencies. Default from GJSIFY_BUILD_CACHE=1.`,type:`boolean`}),handler:async n=>{let a=findWorkspaceRoot(process.cwd())??process.cwd(),S=discoverWorkspaces(a),C=S.find(a=>a.name===n.name);if(!C){let C=suggestClosest(n.name,S.map(n=>n.name)),N=C?` — did you mean "${C}"?`:``;return he.error(`gjsify workspace: no workspace named "${n.name}"${N} (discovered ${S.length} workspace(s) under ${a})`),process.exit(1)}let N=detectPackageManager$1(),F=n.verbose===!0,I=n[`with-dependencies`]===!0,H=n[`continue-on-error`]===!0,W=n.script,K=n.args??[];W===`run`&&K.length>0&&([W,...K]=K);let q=C.manifest.scripts??{};if(typeof q[W]!=`string`){let a=suggestClosest(W,Object.keys(q));return he.error(`gjsify workspace: workspace "${n.name}" has no script "${W}"`+(a?` — did you mean "${a}"?`:``)),process.exit(1)}let Y;Y=I?topologicalSort(buildDependencyGraph(collectTransitiveClosure(C,S,n[`include-dev`]===!0),{includeDev:n[`include-dev`]===!0})):[C];let X=n.cached??buildCacheEnabledByEnv()?new BuildCacheRunner({root:a,workspaces:S,script:W,args:K,targets:Y.map(n=>n.name)}):void 0,te=[];for(let n of Y){if(typeof(n.manifest.scripts??{})[W]!=`string`){F&&he.error(`[${n.name}] (no "${W}" script — skipping)`);continue}try{await runOne$1(n,W,K,N,F,X)}catch(a){let S=a instanceof Error?a:Error(String(a));if(he.error(`[${n.name}] ${S.message}`),!H)return process.exit(1);te.push({workspace:n.name,error:S})}}return te.length>0?(he.error(`gjsify workspace: ${te.length} workspace(s) failed: ${te.map(n=>n.workspace).join(`, `)}`),process.exit(1)):process.exit(0)}},__name$1(runOne$1,`runOne`),__name$1(detectPackageManager$1,`detectPackageManager`)});async function runCheck(n,a){let S=[],C=detectPackageManager$1();if(C===`gjsify`&&readPackageJson$2(vs(n.location,`package.json`))?.scripts?.check===void 0)return 0;let N=C===`gjsify`?[`run`,`check`]:[`run`,`check`,`--if-present`];try{let{code:F}=await spawnToCompletion(C,N,{completion:`exit`,cwd:n.location,stdio:a===null?`inherit`:`pipe`,onSpawn:n=>{let C=!process.stdout.isTTY;if(a!==null&&n.stdout&&n.stderr){let N=`[${a}] `;S.push(prefixLines(n.stdout,process.stdout,N,C)),S.push(prefixLines(n.stderr,process.stderr,N,C))}}});for(let n of S)n();return F??1}catch{for(let n of S)n();return 1}}var BN,VN=__esmMin(()=>{ge(),mN(),xN(),$_(),ks(),Cm(),Q_(),ev(),zN(),BN={command:`check`,description:"Run `npm run check` (TypeScript type-check) across the current workspace. In a workspace root: walks every package with a `check` script (excludes @girs/*; honours --include/--exclude). In a single package: runs the local `check` script directly. Symmetric peer of `gjsify format` / `lint` / `fix`. (Legacy system-dep `gjsify check` is now `gjsify system-check` — see #254.)",builder:n=>n.option(`include`,{description:`Only run in workspaces matching these glob patterns (repeatable).`,type:`string`,array:!0}).option(`exclude`,{description:`Skip workspaces matching these glob patterns (repeatable). Always excludes @girs/*.`,type:`string`,array:!0}).option(`parallel`,{description:`Run workspace checks in parallel (default). Use --no-parallel to run them sequentially with full per-workspace output.`,type:`boolean`,alias:`p`,default:!0}).option(`jobs`,{description:`Max parallel workers (when --parallel). Default: os.cpus().length.`,type:`number`,alias:`j`}).option(`verbose`,{description:`Log the per-workspace command before spawning.`,type:`boolean`,default:!1}),handler:async n=>{let a=process.cwd(),S=findWorkspaceRoot(a);if(S&&a!==S&&readPackageJson$2(vs(a,`package.json`))?.scripts?.check){n.verbose&&he.log(`[check] cwd=${a} → npm run check`);let{code:S}=await spawnToCompletion(detectPackageManager$1(),[`run`,`check`],{cwd:a,completion:`exit`});return process.exit(S??1)}if(!S)return he.error("gjsify check: no workspace root found from cwd. Run inside a workspace (or a package within one) with `npm run check` defined."),process.exit(1);let C=discoverWorkspaces(S),N=[`@girs/*`,...n.exclude??[]],F=filterWorkspaces(C,{include:n.include,exclude:N}).filter(n=>n.manifest.scripts?.check!==void 0);if(F.length===0)return he.error("gjsify check: no workspaces with a `check` script found."),process.exit(1);if(n.verbose&&he.log(`[check] root=${S} workspaces=${F.length} parallel=${n.parallel?`yes`:`no`}`),!n.parallel){let a=0,S=0;for(let C of F){n.verbose&&he.log(`[check] → ${C.name}`);let N=await runCheck(C,null);N!==0&&(S++,a===0&&(a=N))}return a!==0&&he.error(`gjsify check: failures in ${S} workspace(s)`),process.exit(a)}let I=n.jobs??Math.max(1,cpus().length),H=[],W=0,K=[];for(let n=0;n<I;n++)K.push((async()=>{for(;;){let n=W++;if(n>=F.length)return;let a=F[n],S=await runCheck(a,a.name);S!==0&&H.push({name:a.name,code:S})}})());if(await Promise.all(K),H.length>0){he.error(`\ngjsify check: ${H.length} of ${F.length} workspace(s) failed:`);for(let n of H)he.error(` ✗ ${n.name} (exit ${n.code})`);return process.exit(1)}n.verbose&&he.log(`\ngjsify check: ${F.length} workspace(s) green.`),process.exit(0)}}});function manifestPath(){let n=xs(fileURLToPath(import.meta.url)),a=[vs(n,`..`,`..`,`showcases.json`),vs(n,`..`,`showcases.json`)];return a.find(n=>existsSync(n))??a[0]}function discoverShowcases(){let n=manifestPath();if(!existsSync(n))return[];let a;try{a=JSON.parse(readFileSync(n,`utf-8`))}catch{return[]}if(!Array.isArray(a.showcases))return[];let S=a.showcases.map(n=>({name:n.name,packageName:n.package,category:n.category,description:n.description??``}));return S.sort((n,a)=>n.category.localeCompare(a.category)||n.name.localeCompare(a.name)),S}function findShowcase(n){return discoverShowcases().find(a=>a.name===n)}var HN=__esmMin(()=>{Dl(),ks(),an()});function parseSpec$1(n){if(!n)throw Error(`dlx: empty package spec`);if(n.startsWith(`./`)||n.startsWith(`../`)||_s(n)||existsSync(n))return{kind:`local`,path:hs(n)};let a=n,S,C=n.lastIndexOf(`@`);if(C>0&&(a=n.slice(0,C),S=n.slice(C+1)),!UN.test(a))throw Error(`dlx: invalid package name "${a}"`);return{kind:`registry`,name:a,version:S,spec:n}}var UN,WN=__esmMin(()=>{Dl(),ks(),UN=/^(?:@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/,__name$1(parseSpec$1,`parseSpec`)});function resolveGjsEntry(n,a){let S=vs(n,`package.json`);if(!existsSync(S))throw Error(`dlx: no package.json found at ${n}`);let C=JSON.parse(readFileSync(S,`utf-8`)),N=C.gjsify?.bin,F=C.gjsify?.main,I=C.main,H,W=null,K=!1;if(a!==null){if(!N||!N[a]){let S=N?Object.keys(N).join(`, `):`(none)`;throw Error(`dlx: package "${C.name??n}" has no GJS bin named "${a}" — known: ${S}`)}H=N[a],W=a}else if(N&&Object.keys(N).length===1){let n=Object.keys(N)[0];H=N[n],W=n}else F?H=F:I&&(H=I,K=!0);if(N&&Object.keys(N).length>1&&a===null){let a=Object.keys(N).join(`, `);throw Error(`dlx: package "${C.name??n}" defines multiple GJS bins — pass one of: ${a}`)}if(!H)throw Error(`dlx: package "${C.name??n}" has no GJS entry — set \`gjsify.main\` (or \`gjsify.bin\`) in its package.json`);let q=hs(n,H);if(!existsSync(q))throw Error(`dlx: GJS entry not found: ${q}`);return{bundlePath:q,binName:W,fromFallback:K}}function resolveNodeEntry(n){let a=vs(n,`package.json`);if(!existsSync(a))throw Error(`no package.json found at ${n}`);let S=JSON.parse(readFileSync(a,`utf-8`)),C=S.gjsify?.example?.node;if(C){let a=hs(n,C);if(!existsSync(a))throw Error(`declared node entry not found: ${a} (gjsify.example.node)`);return a}let N=S.gjsify?.main??(S.gjsify?.bin?Object.values(S.gjsify.bin)[0]:void 0)??S.main;if(!N)throw Error(`package "${S.name??n}" has no entry to derive a node bundle from — set \`gjsify.example.node\` to its \`--app node\` bundle path.`);let F=N.replace(/\.gjs\.(js|mjs|cjs)$/,``).replace(/\.(js|mjs|cjs)$/,``),I=[`${F}.node.mjs`,`${F}.node.js`,`${F}.node.cjs`];for(let a of I){let S=hs(n,a);if(existsSync(S))return S}throw Error(`package "${S.name??n}" has no \`--app node\` bundle — looked for ${I.join(`, `)}.\n Build one (e.g. \`gjsify build src/app.ts --app node --outfile dist/app.node.mjs\`) or set \`gjsify.example.node\` to its path.`)}var GN=__esmMin(()=>{Dl(),ks()});function lexCompare(n,a){return n<a?-1:+(n>a)}function createCacheKey(n){let a=[...n.packages].sort(lexCompare),S=Object.entries(n.registries??{}).sort(([n],[a])=>lexCompare(n,a)),C=JSON.stringify([a,S]);return createHash(`sha256`).update(C).digest(`hex`)}function dlxCacheRoot(){let n=process.env.XDG_CACHE_HOME,a=vs(n&&n.length>0?n:vs(homedir(),`.cache`),`gjsify`,`dlx`);return mkdirSync(a,{recursive:!0}),a}function cacheDirFor(n){let a=vs(dlxCacheRoot(),n);return mkdirSync(a,{recursive:!0}),a}function makePrepareDir(n){let a=vs(n,`${Date.now().toString(16)}-${process.pid.toString(16)}`);return mkdirSync(a,{recursive:!0}),a}function getValidCachedPkg(n,a=qN){let S=vs(n,`pkg`),C;try{C=lstatSync(S)}catch(n){if(n.code===`ENOENT`)return;throw n}if(!C.isSymbolicLink())return;let N;try{N=realpathSync(S)}catch{return}return Date.now()-C.mtime.getTime()<=a*KN?N:void 0}function symlinkSwap(n,a,S={}){let C=S.junctions??dirLinksAreJunctions(),N=vs(n,`pkg`),F=vs(n,`pkg.tmp-${Date.now().toString(16)}-${process.pid.toString(16)}`);linkDirSync(F,a);try{C&&rmSync(N,{force:!0,recursive:!1,maxRetries:10,retryDelay:100}),renameSync(F,N)}catch(n){let S=n.code;if(S===`EBUSY`||S===`EPERM`||S===`EEXIST`||S===`EACCES`){rmSync(F,{force:!0});try{return realpathSync(N)}catch{return realpathSync(a)}}throw n}return realpathSync(N)}function resolveInstalledPkgDir(n,a){return hs(n,`node_modules`,a)}var KN,qN,JN=__esmMin(()=>{So(),Dl(),Cm(),ks(),wN(),KN=6e4,qN=1440*7});function makeProgressReporter(n={}){if(n.enabled===!1)return XN;let a=n.stream??process.stderr,S=!!a.isTTY;return n.enabled??!0?S?makeTtyReporter(a):makePlainReporter(a):XN}function makeTtyReporter(n){let a=0,S=``;function render(C,N=!1){let F=Date.now();!N&&F-a<33&&C===S||(a=F,S=C,n.write(`\r\x1B[2K`+C))}function clearLine(){n.write(`\r\x1B[2K`),S=``}return{beginPhase(a,S){render(formatBar(a,0,S,void 0,n.columns??80),!0)},update(a){render(formatBar(a.phase,a.current,a.total,a.name,n.columns??80))},endPhase(a){let S=YN[a];clearLine(),n.write(`gjsify install: ${S} done\n`)}}}function makePlainReporter(n){let a=0,S=0;return{beginPhase(C,N){a=Date.now(),S=0,n.write(`gjsify install: ${YN[C]} ${N} package(s)\n`)},update(C){let N=Date.now();if(N-a<ZN||C.current<=S)return;a=N,S=C.current;let F=C.total>0?Math.round(C.current/C.total*100):0;n.write(`gjsify install: ${YN[C.phase]} ${C.current}/${C.total} (${F}%)\n`)},endPhase(a){n.write(`gjsify install: ${YN[a]} done\n`)}}}function formatBar(n,a,S,C,N){let F=YN[n],I=S>0?Math.min(1,a/S):0,H=`${a}/${S}`,W=`gjsify install: ${F} `,K=` ${H}`+(C?` ${C}`:``),q=Math.max(8,Math.min(40,N-W.length-K.length-4)),Y=Math.round(I*q),X=`█`.repeat(Y)+`░`.repeat(q-Y),te=`${W}[${X}]${K}`;if(te.length>N){let n=te.length-N+1,a=C&&C.length>n?C.slice(0,C.length-n-1)+`…`:``;te=`${W}[${X}] ${H}${a?` `+a:``}`}return te}var YN,XN,ZN,QN=__esmMin(()=>{YN={resolve:`resolving`,download:`downloading`,extract:`extracting`,link:`linking bins`},XN={update(){},beginPhase(){},endPhase(){}},ZN=5e3});function parse(n){try{return new SemVer(n)}catch{return null}}function compare(n,a){let S=n instanceof SemVer?n:new SemVer(n),C=a instanceof SemVer?a:new SemVer(a);return S.compare(C)}function satisfies(n,a){let S=a instanceof tP?a:new tP(a),C=n instanceof SemVer?n:parse(String(n));return C?S.test(C):!1}function maxSatisfying(n,a){let S=a instanceof tP?a:new tP(a),C=null;for(let a of n){let n=parse(a);!n||!S.test(n)||(C===null||n.compare(C)>0)&&(C=n)}return C?C.version:null}function testComparator(n,a){if(n.semver===null)return!0;let S=a.compare(n.semver);switch(n.operator){case``:case`=`:return S===0;case`<`:return S<0;case`<=`:return S<=0;case`>`:return S>0;case`>=`:return S>=0}}function formatComparator(n){return n.semver===null?`*`:`${n.operator}${n.semver.version}`}function parseRangePart(n){let a=n.trim();if(a===``||a===`*`||a.toLowerCase()===`latest`)return[{operator:`>=`,semver:new SemVer(`0.0.0`)}];let S=a.match(/^\s*(\S+)\s+-\s+(\S+)\s*$/);if(S)return hyphenRange(S[1],S[2]);let C=a.replace(/(<=|>=|<|>|=)\s+(?=\S)/g,`$1`).split(/\s+/),N=[];for(let n of C)N.push(...parseSimple(n));return N}function parseSimple(n){if(n===`*`||n===``||n.toLowerCase()===`latest`)return[{operator:`>=`,semver:new SemVer(`0.0.0`)}];if(n.startsWith(`^`))return caretRange(n.slice(1));if(n.startsWith(`~`))return tildeRange(n.slice(1).replace(/^>/,``));let a=n.match(/^(<=|>=|<|>|=)\s*(.+)$/);if(a){let n=a[1];return primitiveRange(n,a[2])}return partialRange(n)}function parsePartial(n){let a=n.trim().replace(/^v/,``);if(a===``||a===`*`)return{major:null,minor:null,patch:null,pre:``,build:``};let S=``,C=``,N=a,F=N.indexOf(`+`);F>=0&&(C=N.slice(F+1),N=N.slice(0,F));let I=N.indexOf(`-`);I>=0&&(S=N.slice(I+1),N=N.slice(0,I));let H=N.split(`.`),xr=a=>{if(a===void 0||a===``||a===`x`||a===`X`||a===`*`)return null;if(!/^\d+$/.test(a))throw TypeError(`Invalid partial version: ${n}`);return Number(a)};return{major:xr(H[0]),minor:xr(H[1]),patch:xr(H[2]),pre:S,build:C}}function partialToVersion(n){return`${n.major??0}.${n.minor??0}.${n.patch??0}${n.pre?`-${n.pre}`:``}${n.build?`+${n.build}`:``}`}function partialRange(n){let a=parsePartial(n);return a.major===null?[{operator:`>=`,semver:new SemVer(`0.0.0`)}]:a.minor===null?[{operator:`>=`,semver:new SemVer(`${a.major}.0.0`)},{operator:`<`,semver:new SemVer(`${a.major+1}.0.0`)}]:a.patch===null?[{operator:`>=`,semver:new SemVer(`${a.major}.${a.minor}.0`)},{operator:`<`,semver:new SemVer(`${a.major}.${a.minor+1}.0`)}]:[{operator:`=`,semver:new SemVer(partialToVersion(a))}]}function caretRange(n){let a=parsePartial(n);if(a.major===null)return[{operator:`>=`,semver:new SemVer(`0.0.0`)}];let S=`${a.major}.${a.minor??0}.${a.patch??0}${a.pre?`-${a.pre}`:``}`,C;return C=a.major>0||a.minor===null?`${a.major+1}.0.0`:a.minor>0||a.patch===null?`0.${a.minor+1}.0`:`0.0.${a.patch+1}`,[{operator:`>=`,semver:new SemVer(S)},{operator:`<`,semver:new SemVer(C)}]}function tildeRange(n){let a=parsePartial(n);if(a.major===null)return[{operator:`>=`,semver:new SemVer(`0.0.0`)}];let S=`${a.major}.${a.minor??0}.${a.patch??0}${a.pre?`-${a.pre}`:``}`,C=a.minor===null?`${a.major+1}.0.0`:`${a.major}.${a.minor+1}.0`;return[{operator:`>=`,semver:new SemVer(S)},{operator:`<`,semver:new SemVer(C)}]}function primitiveRange(n,a){let S=parsePartial(a);return S.major===null?[{operator:`>=`,semver:new SemVer(`0.0.0`)}]:n===`=`||n===``?partialRange(a):n===`>`?S.minor===null?[{operator:`>=`,semver:new SemVer(`${S.major+1}.0.0`)}]:S.patch===null?[{operator:`>=`,semver:new SemVer(`${S.major}.${S.minor+1}.0`)}]:[{operator:`>`,semver:new SemVer(partialToVersion(S))}]:n===`<`?S.minor===null?[{operator:`<`,semver:new SemVer(`${S.major}.0.0`)}]:S.patch===null?[{operator:`<`,semver:new SemVer(`${S.major}.${S.minor}.0`)}]:[{operator:`<`,semver:new SemVer(partialToVersion(S))}]:n===`>=`?[{operator:`>=`,semver:new SemVer(partialToVersion(S))}]:S.minor===null?[{operator:`<`,semver:new SemVer(`${S.major+1}.0.0`)}]:S.patch===null?[{operator:`<`,semver:new SemVer(`${S.major}.${S.minor+1}.0`)}]:[{operator:`<=`,semver:new SemVer(partialToVersion(S))}]}function hyphenRange(n,a){let S=parsePartial(n),C=parsePartial(a),N=S.major===null?{operator:`>=`,semver:new SemVer(`0.0.0`)}:{operator:`>=`,semver:new SemVer(`${S.major}.${S.minor??0}.${S.patch??0}${S.pre?`-${S.pre}`:``}`)},F;return F=C.major===null?{operator:`>=`,semver:new SemVer(`0.0.0`)}:C.minor===null?{operator:`<`,semver:new SemVer(`${C.major+1}.0.0`)}:C.patch===null?{operator:`<`,semver:new SemVer(`${C.major}.${C.minor+1}.0`)}:{operator:`<=`,semver:new SemVer(`${C.major}.${C.minor}.${C.patch}${C.pre?`-${C.pre}`:``}`)},[N,F]}var $N,eP,SemVer,tP,nP=__esmMin(()=>{$N=/^(0|[1-9]\d*)$/,eP=/^(\d+)\.(\d+)\.(\d+)(?:-((?:[0-9A-Za-z-]+)(?:\.[0-9A-Za-z-]+)*))?(?:\+([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?$/,SemVer=class{major;minor;patch;prerelease;build;version;constructor(n){let a=String(n).trim().replace(/^v/,``),S=eP.exec(a);if(!S)throw TypeError(`Invalid Version: ${n}`);this.major=Number(S[1]),this.minor=Number(S[2]),this.patch=Number(S[3]),this.prerelease=S[4]?S[4].split(`.`).map(n=>$N.test(n)?Number(n):n):[],this.build=S[5]?S[5].split(`.`):[],this.version=`${this.major}.${this.minor}.${this.patch}`+(this.prerelease.length?`-${this.prerelease.join(`.`)}`:``)+(this.build.length?`+${this.build.join(`.`)}`:``)}compare(n){return this.major===n.major?this.minor===n.minor?this.patch===n.patch?this.comparePre(n):this.patch<n.patch?-1:1:this.minor<n.minor?-1:1:this.major<n.major?-1:1}comparePre(n){let a=this.prerelease,S=n.prerelease;if(a.length===0&&S.length===0)return 0;if(a.length===0)return 1;if(S.length===0)return-1;for(let n=0;;n++){let C=a[n],N=S[n];if(C===void 0&&N===void 0)return 0;if(N===void 0)return 1;if(C===void 0)return-1;if(C===N)continue;let F=typeof C==`number`,I=typeof N==`number`;return F&&!I?-1:!F&&I?1:C<N?-1:1}}toString(){return this.version}},tP=class Range{raw;set;constructor(n){if(n instanceof Range){this.raw=n.raw,this.set=n.set;return}this.raw=String(n).trim();let a=this.raw.split(/\s*\|\|\s*/),S=[];for(let n of a){let a=parseRangePart(n);if(a.length===0)throw TypeError(`Invalid range: ${this.raw}`);S.push(a)}if(S.length===0)throw TypeError(`Invalid range: ${this.raw}`);this.set=S}test(n){let a=n instanceof SemVer?n:parse(String(n));if(!a)return!1;for(let n of this.set)if(n.every(n=>testComparator(n,a))){if(a.prerelease.length>0&&!n.some(n=>n.semver!==null&&n.semver.prerelease.length>0&&n.semver.major===a.major&&n.semver.minor===a.minor&&n.semver.patch===a.patch))continue;return!0}return!1}format(){return this.set.map(n=>n.map(formatComparator).join(` `)).join(` || `)}toString(){return this.format()}}});function buildHeaders(n,a){let S={"user-agent":`gjsify-install/0.35.0`,"accept-encoding":a.acceptEncoding??`identity`};if(a.npmrc){let C=resolveAuthForUrl(n,a.npmrc);C&&(S.authorization=C)}if(a.headers)for(let[n,C]of Object.entries(a.headers))S[n.toLowerCase()]=C;return S}function resolveAuthForUrl(n,a){let S=pathPrefixes(new URL(n));for(let n of S){let S=a.authTokens[n];if(S)return`Bearer ${S}`;let C=a.basicAuth[n];if(C)return`Basic ${btoa(`${C.username}:${C.password}`)}`}return null}function pathPrefixes(n){let a=n.pathname.split(`/`).filter(Boolean),S=[];for(let C=a.length;C>=0;C--){let N=a.slice(0,C).join(`/`);S.push(N?`//${n.host}/${N}`:`//${n.host}`)}return S}var rP=__esmMin(()=>{}),PackageNotFoundError,IntegrityError,RegistryTimeoutError,iP=__esmMin(()=>{PackageNotFoundError=class extends Error{name;url;constructor(n,a){super(`Package not found in registry: ${n} (${a})`),this.name=n,this.url=a,this.name=`PackageNotFoundError`}},IntegrityError=class extends Error{url;integrity;constructor(n,a){super(`Tarball integrity mismatch for ${n} (expected ${a})`),this.url=n,this.integrity=a,this.name=`IntegrityError`}},RegistryTimeoutError=class extends Error{url;timeoutMs;attempts;constructor(n,a,S){let C=Math.round(a/100)/10,N=Math.round(a*S/100)/10;super(`@gjsify/npm-registry: GET ${n} timed out after ${C}s × ${S} attempt(s) (total ~${N}s). This usually means the registry CDN is slow or unreachable.`),this.url=n,this.timeoutMs=a,this.attempts=S,this.name=`RegistryTimeoutError`}}});function registryFor(n,a){if(a&&n.startsWith(`@`)){let S=n.slice(0,n.indexOf(`/`)),C=a.scopes[S];if(C)return ensureTrailingSlash$1(C)}return a?.registry?ensureTrailingSlash$1(a.registry):aP}function parseNpmrc(n){let a={registry:aP,scopes:{},authTokens:{},basicAuth:{}},S=n.split(/\r?\n/),C={};for(let n of S){let S=n.replace(/^\s+|\s+$/g,``);if(!S||S.startsWith(`#`)||S.startsWith(`;`))continue;let N=S.indexOf(`=`);if(N<0)continue;let F=S.slice(0,N).trim(),I=expandEnv(stripQuotes(S.slice(N+1).trim()));if(F===`registry`){a.registry=ensureTrailingSlash$1(I);continue}let H=F.match(/^(@[^:]+):registry$/);if(H){a.scopes[H[1]]=ensureTrailingSlash$1(I);continue}let W=F.match(/^\/\/(.+):_authToken$/);if(W){a.authTokens[normalizeAuthHost(W[1])]=I;continue}let K=F.match(/^\/\/(.+):username$/);if(K){(C[normalizeAuthHost(K[1])]??={}).user=I;continue}let q=F.match(/^\/\/(.+):_password$/);if(q){let n=base64Decode(I);(C[normalizeAuthHost(q[1])]??={}).pass=n;continue}}for(let[n,S]of Object.entries(C))S.user&&S.pass!==void 0&&(a.basicAuth[n]={username:S.user,password:S.pass});return a}function normalizeAuthHost(n){return`//${n.replace(/\/+$/,``)}`}function ensureTrailingSlash$1(n){return n.endsWith(`/`)?n:n+`/`}function stripQuotes(n){return n.startsWith(`"`)&&n.endsWith(`"`)||n.startsWith(`'`)&&n.endsWith(`'`)?n.slice(1,-1):n}function expandEnv(n){return n.replace(/\$\{([A-Z0-9_]+)\}/gi,(n,a)=>globalThis.process?.env?.[a]??``)}function base64Decode(n){return atob(n)}var aP,oP=__esmMin(()=>{aP=`https://registry.npmjs.org/`,__name$1(ensureTrailingSlash$1,`ensureTrailingSlash`)});async function fetchWithRetry(n,a,S){let C=S.fetch??globalThis.fetch;if(!C)throw Error(`@gjsify/npm-registry: globalThis.fetch is missing`);let N=Math.max(0,S.retries??3),F=Math.max(0,S.retryDelayMs??250),I=Math.max(0,S.timeoutMs??3e4),H=S.retryNotFound??!1,W=0,K,q=0;for(;;){if(a.signal?.aborted)throw signalAbortError(a.signal);let Y=I>0?new AbortController:null,X=Y===null?null:setTimeout(()=>Y.abort(Error(`@gjsify/npm-registry: per-request timeout ${I}ms`)),I),te=composeSignals(a.signal,Y?.signal);try{let S=await C(n,{...a,signal:te}),F=isRetryableStatus(S.status)||H&&S.status===404;if(S.ok||!F||W>=N)return S;try{await S.arrayBuffer()}catch{}K=Error(`HTTP ${S.status} ${S.statusText}`)}catch(S){let C=Y!==null&&Y.signal.aborted,F=a.signal?.aborted===!0;if(C&&!F){if(q++,W>=N)throw new RegistryTimeoutError(n,I,q);K=S}else if(F)throw signalAbortError(a.signal);else{if(!isRetryableError(S)||W>=N)throw S;K=S}}finally{X!==null&&clearTimeout(X)}let ne=Math.min(F*2**W,8e3);S.onRetry?.({attempt:W+1,error:K,delayMs:ne}),await delay$1(ne,a.signal),W++}}function composeSignals(n,a){return n?a?AbortSignal.any([n,a]):n:a}function isRetryableStatus(n){return n===408||n===425||n===429||n===500||n===502||n===503||n===504||n===521||n===522||n===524||n===525}function isRetryableError(n){if(n&&typeof n==`object`&&`name`in n&&n.name===`AbortError`)return!1;if(n instanceof TypeError)return!0;if(n&&typeof n==`object`&&`name`in n){let a=n.name;if(a===`FetchError`)return!0;if(a===`AbortError`)return!1}let a=n?.cause;if(a&&typeof a==`object`&&`code`in a){let n=a.code;if(typeof n==`string`)return n===`ECONNRESET`||n===`ECONNREFUSED`||n===`ENETUNREACH`||n===`ENOTFOUND`||n===`ETIMEDOUT`||n===`EAI_AGAIN`||n===`UND_ERR_SOCKET`||n===`UND_ERR_CONNECT_TIMEOUT`}return!1}function delay$1(n,a){return n<=0?Promise.resolve():new Promise((S,C)=>{let N=setTimeout(()=>{a?.removeEventListener?.(`abort`,onAbort),S()},n),onAbort=()=>{clearTimeout(N),C(signalAbortError(a))};if(a?.aborted){clearTimeout(N),C(signalAbortError(a));return}a?.addEventListener?.(`abort`,onAbort,{once:!0})})}function signalAbortError(n){let a=n&&`reason`in n?n.reason:void 0;if(a instanceof Error)return a;let S=Error(`Aborted`);return S.name=`AbortError`,S}var sP=__esmMin(()=>{iP(),__name$1(delay$1,`delay`)});async function verifyIntegrity(n,a){let S=a.trim().split(/\s+/);for(let a of S){let S=a.indexOf(`-`);if(S<0)continue;let C=a.slice(0,S).toLowerCase(),N=a.slice(S+1),F=globalThis.crypto?.subtle;if(!F)throw Error(`@gjsify/npm-registry: globalThis.crypto.subtle is missing`);let I=subriToWebCryptoAlgo(C);if(!I)continue;let H=await F.digest(I,dataAsArrayBuffer(n));if(bytesToBase64(new Uint8Array(H))===N)return!0}return!1}function subriToWebCryptoAlgo(n){switch(n){case`sha1`:return`SHA-1`;case`sha256`:return`SHA-256`;case`sha384`:return`SHA-384`;case`sha512`:return`SHA-512`;default:return null}}function dataAsArrayBuffer(n){if(n.byteOffset===0&&n.byteLength===n.buffer.byteLength)return n.buffer;let a=new Uint8Array(n.byteLength);return a.set(n),a.buffer}function bytesToBase64(n){let a=``;for(let S=0;S<n.length;S++)a+=String.fromCharCode(n[S]);return btoa(a)}var cP=__esmMin(()=>{});function assertPackument(n,a){if(!a||typeof a!=`object`)throw TypeError(`registry: ${n} packument is not an object`);let S=a;if(typeof S.name!=`string`)throw TypeError(`registry: ${n} packument missing string name`);if(!S.versions||typeof S.versions!=`object`)throw TypeError(`registry: ${n} packument missing versions map`)}function packumentUrl(n,a){let S=ensureTrailingSlash$1(a);if(n.startsWith(`@`)){let a=n.indexOf(`/`);if(a<0)throw TypeError(`Invalid scoped package name: ${n}`);let C=n.slice(0,a),N=n.slice(a+1);return`${S}${encodeURIComponent(C)}/${encodeURIComponent(N)}`}return`${S}${encodeURIComponent(n)}`}async function fetchPackumentConditional(n,a={}){let S=packumentUrl(n,a.registry??registryFor(n,a.npmrc)),C=buildHeaders(S,{...a,acceptEncoding:`gzip`});C.accept??=a.fullMetadata?`application/json`:`application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*`,a.ifNoneMatch&&(C[`if-none-match`]=a.ifNoneMatch);let N=await fetchWithRetry(S,{headers:C,signal:a.signal},{fetch:a.fetch,retries:a.retries,retryDelayMs:a.retryDelayMs,timeoutMs:a.timeoutMs,onRetry:a.onRetry});if(N.status===304){try{await N.arrayBuffer()}catch{}return{status:`not-modified`,etag:a.ifNoneMatch}}if(!N.ok)throw N.status===404||N.status===406?new PackageNotFoundError(n,S):Error(`registry GET ${S} -> ${N.status} ${N.statusText}`);let F=N.headers.get(`etag`)??void 0,I=await decodeJsonBody(N);return assertPackument(n,I),{status:`fresh`,packument:I,etag:F}}async function decodeJsonBody(n){return n.json()}async function fetchPackument(n,a={}){let S=await fetchPackumentConditional(n,a);if(!S.packument)throw Error(`registry: ${n} returned 304 Not Modified to an unconditional request`);return S.packument}var lP=__esmMin(()=>{rP(),iP(),oP(),sP()});async function fetchTarball(n,a={}){let S=buildHeaders(n,{...a,acceptEncoding:`identity`});S.accept??=`application/octet-stream`;let C=await fetchWithRetry(n,{headers:S,signal:a.signal},{fetch:a.fetch,retries:a.retries,retryDelayMs:a.retryDelayMs,timeoutMs:a.timeoutMs,onRetry:a.onRetry,retryNotFound:a.retryNotFound??!0});if(!C.ok)throw Error(`tarball GET ${n} -> ${C.status} ${C.statusText}`);let N=new Uint8Array(await C.arrayBuffer());if(a.integrity&&!await verifyIntegrity(N,a.integrity))throw new IntegrityError(n,a.integrity);return N}var uP=__esmMin(()=>{rP(),iP(),sP(),cP()});async function whoami(n,a){let S=`${ensureTrailingSlash$1(n)}-/whoami`,C=buildHeaders(S,{npmrc:a});C.accept=`application/json`;let N=globalThis.fetch;if(!N)throw Error(`@gjsify/npm-registry: globalThis.fetch is missing`);let F=await N(S,{method:`GET`,headers:C});if(!F.ok)throw Error(`whoami GET ${S} -> ${F.status} ${F.statusText}`);let I=await F.json();if(I&&typeof I==`object`&&`username`in I){let n=I.username;if(typeof n==`string`&&n.length>0)return{username:n}}return{}}var dP=__esmMin(()=>{rP(),oP()}),fP=__esmMin(()=>{rP(),oP(),lP(),uP(),dP()});function parseTar(n){let a=[],S=null,C=null,N=null,F=0;for(;F+512<=n.length;){let I=n.subarray(F,F+512);if(allZeros(I)){let a=n.subarray(F+512,F+2*512);if(a.length===512&&allZeros(a))break;F+=512;continue}if(!validateChecksum(I))throw new TarParseError(`Bad header checksum at offset ${F} — file is not a valid tar archive`);let H=readString(I,0,100),W=parseOctal(I,100,8),K=parseOctal(I,124,12),q=parseOctal(I,136,12),Y=String.fromCharCode(I[156]||0),X=readString(I,157,100),te=readString(I,257,6),ne=readString(I,345,155),re=readString(I,265,32),ie=readString(I,297,32);F+=512;let ae=n.subarray(F,F+K);if(F+=alignToBlock(K),Y===`x`){S=parsePaxRecords(ae);continue}if(Y===`g`)continue;if(Y===`L`){C=bytesToString(ae).replace(/\0+$/,``);continue}if(Y===`K`){N=bytesToString(ae).replace(/\0+$/,``);continue}let oe=H;te===`ustar`&&ne!==``&&(oe=`${ne}/${H}`),C!==null&&(oe=C,C=null);let Z=X;if(N!==null&&(Z=N,N=null),S!==null){let C=S.get(`path`);C!==void 0&&(oe=C);let N=S.get(`linkpath`);N!==void 0&&(Z=N);let I=S.get(`size`);if(I!==void 0){let C=Number(I);if(Number.isFinite(C)){let N=F-alignToBlock(K),I=n.subarray(N,N+C);F=N+alignToBlock(C),S=null,a.push(buildEntry(oe,Z,Y,W,q,re,ie,I));continue}}S=null}a.push(buildEntry(oe,Z,Y,W,q,re,ie,ae))}return a}function buildEntry(n,a,S,C,N,F,I,H){return{name:n,linkname:a,type:typeflagToType(S,n),mode:C,mtime:N,body:H,uname:F,gname:I}}function typeflagToType(n,a){switch(n){case`0`:case`\0`:case``:return a.endsWith(`/`)?`directory`:`file`;case`1`:return`hardlink`;case`2`:return`symlink`;case`5`:return`directory`;case`x`:return`pax-header`;case`g`:return`pax-global`;case`L`:return`gnu-longname`;case`K`:return`gnu-longlink`;default:return`unknown`}}function parsePaxRecords(n){let a=new Map,S=0;for(;S<n.length;){let C=S;for(;C<n.length&&n[C]!==32;)C++;if(C>=n.length)break;let N=bytesToString(n.subarray(S,C)),F=Number(N);if(!Number.isFinite(F)||F<=0)break;let I=S+F;if(I>n.length)break;let H=bytesToString(n.subarray(C+1,I-1)),W=H.indexOf(`=`);if(W>0){let n=H.slice(0,W),S=H.slice(W+1);a.set(n,S)}S=I}return a}function readString(n,a,S){let C=a,N=a+S;for(;C<N&&n[C]!==0;)C++;return bytesToString(n.subarray(a,C))}function bytesToString(n){return new TextDecoder(`utf-8`,{fatal:!1}).decode(n)}function parseOctal(n,a,S){if(S>0&&n[a]&128){let C=n[a]&127;for(let N=1;N<S;N++)C=C*256+n[a+N];return C}let C=``;for(let N=0;N<S;N++){let S=n[a+N];S===0||S===32||(C+=String.fromCharCode(S))}return C===``?0:parseInt(C,8)}function alignToBlock(n){return Math.ceil(n/512)*512}function allZeros(n){for(let a=0;a<n.length;a++)if(n[a]!==0)return!1;return!0}function validateChecksum(n){let a=parseOctal(n,148,8),S=0,C=0;for(let a=0;a<512;a++){let N=a>=148&&a<156?32:n[a];S+=N,C+=N>127?N-256:N}return a===S||a===C}var TarParseError,pP=__esmMin(()=>{TarParseError=class extends Error{constructor(n){super(n),this.name=`TarParseError`}}});function createTarball(n){let a=[];for(let S of n){if(`directory`in S&&S.directory===!0){a.push(buildHeader(ensureTrailingSlash(S.name),0,`5`,S.mode??493,S.mtime??0));continue}let n=S,C=typeof n.body==`string`?new TextEncoder().encode(n.body):n.body,N=n.mode??defaultFileMode(C);a.push(buildHeader(n.name,C.byteLength,`0`,N,n.mtime??0)),a.push(C);let F=padTo512(C.byteLength);F>0&&a.push(new Uint8Array(F))}return a.push(new Uint8Array(512*2)),concatChunks(a)}function buildHeader(n,a,S,C,N){let{prefix:F,basename:I}=splitPathForUstar(n),H=new Uint8Array(512);writeAscii(H,I,0,100),writeOctal(H,C&4095,100,7),H[107]=0,writeOctal(H,0,108,7),H[115]=0,writeOctal(H,0,116,7),H[123]=0,writeOctal(H,a,124,11),H[135]=0,writeOctal(H,N,136,11),H[147]=0;for(let n=148;n<156;n++)H[n]=32;H[156]=S.charCodeAt(0),writeAscii(H,`ustar\0`,257,6),writeAscii(H,`00`,263,2),F&&writeAscii(H,F,345,155);let W=0;for(let n=0;n<512;n++)W+=H[n];return writeAscii(H,W.toString(8).padStart(6,`0`),148,6),H[154]=0,H[155]=32,H}function splitPathForUstar(n){if(n.length<=100)return{prefix:``,basename:n};if(n.length>255)throw Error(`createTarball: path too long (${n.length} > 255 chars): ${n}`);for(let a=Math.min(n.length-1,155);a>0;a--)if(n[a]===`/`&&n.length-a-1<=100)return{prefix:n.slice(0,a),basename:n.slice(a+1)};throw Error(`createTarball: cannot split path into ustar prefix+basename (basename slot is 100 chars): ${n}`)}function writeAscii(n,a,S,C){let N=new TextEncoder().encode(a);if(N.length>C)throw Error(`createTarball: field too long (${N.length} > ${C}): "${a}"`);n.set(N,S)}function writeOctal(n,a,S,C){writeAscii(n,a.toString(8).padStart(C,`0`),S,C)}function padTo512(n){let a=n%512;return a===0?0:512-a}function ensureTrailingSlash(n){return n.endsWith(`/`)?n:`${n}/`}function defaultFileMode(n){return n.length>=2&&n[0]===35&&n[1]===33?493:420}function concatChunks(n){let a=0;for(let S of n)a+=S.byteLength;let S=new Uint8Array(a),C=0;for(let a of n)S.set(a,C),C+=a.byteLength;return S}var mP=__esmMin(()=>{});async function extractTarball(n,a,S={}){let C=n instanceof Uint8Array?n:new Uint8Array(n),N=parseTar(S.gzip??(C.length>=2&&C[0]===31&&C[1]===139)?await gunzip(C):C);mkdirSync(a,{recursive:!0});let F=S.strip??1,I=S.preventEscape??!0,H={files:[],directories:[],symlinks:[],skipped:0};for(let n of N){let C=stripComponents(n.name,F);if(C===null||C===``){H.skipped++;continue}let N=hs(a,C);if(I&&!isInside$1(N,a))throw Error(`tar: refusing to extract ${n.name} outside ${a} (resolved=${N})`);if(S.filter&&!S.filter(n,N)){H.skipped++;continue}if(n.type===`directory`){mkdirSync(N,{recursive:!0}),H.directories.push(N);continue}if(n.type===`file`){mkdirSync(xs(N),{recursive:!0}),writeFileSync(N,n.body);let a=S.chmod?.(n,N)??n.mode&511;if(a>0)try{chmodSync(N,a)}catch{}H.files.push(N);continue}if(n.type===`symlink`){mkdirSync(xs(N),{recursive:!0});try{symlinkSync(n.linkname,N),H.symlinks.push(N)}catch{writeFileSync(N,n.linkname),H.files.push(N)}continue}H.skipped++}return H}async function gunzip(n){let a=globalThis.DecompressionStream;if(typeof a!=`function`)throw Error(`@gjsify/tar: globalThis.DecompressionStream is not available — import '@gjsify/compression-streams/register' on GJS to register it`);return drainStream(new Blob([new Uint8Array(n)]).stream().pipeThrough(new a(`gzip`)))}async function gzip(n){let a=globalThis.CompressionStream;if(typeof a!=`function`)throw Error(`@gjsify/tar: globalThis.CompressionStream is not available — import '@gjsify/compression-streams/register' on GJS to register it`);return drainStream(new Blob([new Uint8Array(n)]).stream().pipeThrough(new a(`gzip`)))}async function drainStream(n){let a=[],S=0,C=n.getReader();for(;;){let{value:n,done:N}=await C.read();if(N)break;let F=n instanceof Uint8Array?n:new Uint8Array(n);a.push(F),S+=F.length}let N=new Uint8Array(S),F=0;for(let n of a)N.set(n,F),F+=n.length;return N}function stripComponents(n,a){if(a<=0)return n;let S=n.split(`/`).filter(n=>n!==``);return S.length<=a?null:S.slice(a).join(`/`)}function isInside$1(n,a){let S=ys(a,n);return S!==``&&!S.startsWith(`..`)&&!_s(S)}var hP=__esmMin(()=>{pP(),Dl(),ks(),__name$1(isInside$1,`isInside`)}),gP=__exportAll$4({BLOCK_SIZE:()=>512,TarParseError:()=>TarParseError,createTarball:()=>createTarball,extractTarball:()=>extractTarball,gunzip:()=>gunzip,gzip:()=>gzip,parseTar:()=>parseTar}),_P=__esmMin(()=>{pP(),mP(),hP()});function gjsifyCacheRoot(n,a){let S=process.env.XDG_CACHE_HOME;return vs(S&&S.length>0?S:vs(homedir(),`.cache`),`gjsify`,n,a)}function atomicWrite(n,a){try{atomicWriteStrict(n,a)}catch{}}function atomicWriteStrict(n,a){mkdirSync(vs(n,`..`),{recursive:!0});let S=`${n}.tmp.${process.pid}`;writeFileSync(S,a),renameSync(S,n)}function readCacheFile(n){if(!existsSync(n))return null;try{let a=readFileSync(n);return a.length===0?null:a}catch{return null}}var vP=__esmMin(()=>{Dl(),Cm(),ks()});function staleMs(){let n=process.env.GJSIFY_INSTALL_LOCK_STALE_MS;if(n!==void 0){let a=Number(n);if(Number.isFinite(a)&&a>0)return a}return xP}function lockingDisabled(){let n=process.env.GJSIFY_INSTALL_LOCK;if(n===void 0)return!1;let a=n.trim();return a===`0`||a===`false`}function isPidAlive(n){if(existsSync(`/proc/self`))return existsSync(`/proc/${n}`);try{return process.kill(n,0),!0}catch(n){return n.code===`EPERM`}}function mtimeMs(n){try{return statSync(n).mtimeMs}catch{return null}}function assessLock(n){let a=vs(n,bP),S=null;try{S=JSON.parse(readFileSync(a,`utf-8`))}catch{S=null}let C=Date.now();if(S&&typeof S.pid==`number`){if(!isPidAlive(S.pid))return{stale:!0,reason:`owner pid ${S.pid} is gone`,ownerPid:S.pid};let n=typeof S.startedAt==`number`?S.startedAt:mtimeMs(a);return n!==null&&C-n>staleMs()?{stale:!0,reason:`owner pid ${S.pid} exceeded the ${staleMs()}ms staleness budget`,ownerPid:S.pid}:{stale:!1,ownerPid:S.pid}}let N=mtimeMs(n);return N===null?{stale:!1}:C-N>SP?{stale:!0,reason:`no owner recorded within the acquire grace period`}:{stale:!1}}function stealStaleLock(n){let a=`${n}.stale-${process.pid}-${++EP}`;try{renameSync(n,a)}catch{return!1}try{rmSync(a,{recursive:!0,force:!0})}catch{}return!0}function abortErr(n){let a=n&&`reason`in n?n.reason:void 0;if(a instanceof Error)return a;let S=Error(`Aborted`);return S.name=`AbortError`,S}function delay(n,a){return n<=0?Promise.resolve():new Promise((S,C)=>{let onAbort=()=>{clearTimeout(N),C(abortErr(a))},N=setTimeout(()=>{a?.removeEventListener?.(`abort`,onAbort),S()},n);if(a?.aborted){clearTimeout(N),C(abortErr(a));return}a?.addEventListener?.(`abort`,onAbort,{once:!0})})}function makeHandle(n){let a=!1;return{release(){if(a)return;a=!0;let S=TP.get(n);if(S&&(S.count--,!(S.count>0))){TP.delete(n);try{let a=JSON.parse(readFileSync(vs(n,bP),`utf-8`));if(a.nonce!==void 0&&a.nonce!==S.nonce)return}catch{}try{rmSync(n,{recursive:!0,force:!0})}catch{}}}}}async function acquireInstallLock(n,a={}){if(lockingDisabled())return{release(){}};let S;try{S=realpathSync(n)}catch{S=hs(n)}let C=vs(S,`node_modules`,yP),N=TP.get(C);if(N)return N.count++,makeHandle(C);mkdirSync(xs(C),{recursive:!0});let F=`${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`,I=CP,H=!1;for(;;){if(a.signal?.aborted)throw abortErr(a.signal);try{return mkdirSync(C),writeFileSync(vs(C,bP),JSON.stringify({pid:process.pid,nonce:F,startedAt:Date.now()})),TP.set(C,{count:1,nonce:F}),makeHandle(C)}catch(n){if(n.code!==`EEXIST`)throw n}let n=assessLock(C);if(n.stale){stealStaleLock(C)&&he.warn(`gjsify install: removed stale install lock (${n.reason}) — ${C}`);continue}if(!H){H=!0;let a=n.ownerPid===void 0?``:` (pid ${n.ownerPid})`;he.warn(`gjsify install: waiting for a concurrent install${a} to release ${C} …`)}await delay(I,a.signal),I=Math.min(Math.round(I*1.6),wP)}}var yP,bP,xP,SP,CP,wP,TP,EP,DP=__esmMin(()=>{ge(),Dl(),ks(),yP=`.gjsify-install-lock`,bP=`owner.json`,xP=35*6e4,SP=15e3,CP=150,wP=1e3,TP=new Map,EP=0});function cacheRoot$1(){return gjsifyCacheRoot(`tarballs`,OP)}function parseSri$1(n){if(!n)return null;let a=n.indexOf(`-`);if(a<=0||a===n.length-1)return null;let S=n.slice(0,a),C=n.slice(a+1).replace(/=+$/,``),N=qe.from(C,`base64`).toString(`hex`);return N.length<4?null:{algorithm:S,hex:N}}function pathFor$2(n){let a=parseSri$1(n);if(!a)return null;let S=a.hex.slice(0,2);return vs(cacheRoot$1(),a.algorithm,S,`${a.hex}.tgz`)}function getCachedTarball(n){let a=pathFor$2(n);return a?readCacheFile(a):null}function putCachedTarball(n,a){let S=pathFor$2(n);S&&(existsSync(S)||atomicWrite(S,a))}function npmCacacheContentDir(){let n=process.env.GJSIFY_NPM_CACHE;if(n!==void 0){let a=n.trim();return a===``||a===`0`||a===`false`?null:vs(a.endsWith(`_cacache`)?a:vs(a,`_cacache`),`content-v2`)}let a=process.env.npm_config_cache;return vs(a&&a.length>0?a:vs(homedir(),`.npm`),`_cacache`,`content-v2`)}function npmCachePathFor(n){let a=npmCacacheContentDir();if(!a)return null;let S=parseSri$1(n);return S?vs(a,S.algorithm,S.hex.slice(0,2),S.hex.slice(2,4),S.hex.slice(4)):null}function getForeignCachedTarball(n){let a=npmCachePathFor(n);return a?readCacheFile(a):null}var OP,kP=__esmMin(()=>{nt(),Dl(),Cm(),ks(),vP(),OP=`v1`,__name$1(cacheRoot$1,`cacheRoot`),__name$1(parseSri$1,`parseSri`),__name$1(pathFor$2,`pathFor`)});function isEnabled(){let n=process.env.GJSIFY_PACKUMENT_CACHE;if(n===void 0)return!0;let a=n.trim();return!(a===`0`||a===`false`||a===``)}function cacheRoot(){return gjsifyCacheRoot(`metadata`,AP)}function shardFor(n){let a=2166136261;for(let S=0;S<n.length;S++)a^=n.charCodeAt(S),a=Math.imul(a,16777619);return(a>>>0&255).toString(16).padStart(2,`0`)}function encodePart(n){return encodeURIComponent(n).replace(/\*/g,`%2A`)}function packumentCacheKey(n,a,S){return`${S},${encodePart(n)},${encodePart(a)}`}function pathFor$1(n,a,S){if(!isEnabled())return null;let C=packumentCacheKey(n,a,S);return vs(cacheRoot(),shardFor(C),`${C}.json`)}function getCachedPackument(n,a,S=`corgi`){let C=pathFor$1(n,a,S);if(!C)return null;let N=readCacheFile(C);if(!N)return null;try{let n=JSON.parse(N.toString(`utf-8`));return typeof n.etag!=`string`||!n.etag||!n.packument||typeof n.packument!=`object`?null:{etag:n.etag,packument:n.packument}}catch{return null}}function putCachedPackument(n,a,S,C,N=`corgi`){if(!S)return;let F=pathFor$1(n,a,N);F&&atomicWrite(F,JSON.stringify({etag:S,packument:C}))}var AP,jP=__esmMin(()=>{ks(),vP(),AP=`v3`,__name$1(pathFor$1,`pathFor`)});function parseNodeMajor(n){return Number.parseInt(String(n).split(`.`,1)[0]??``,10)}function nativeBackendNodeError(n,a){if(!a)return null;let S=parseNodeMajor(n);return!Number.isFinite(S)||S>=24?null:`gjsify install (native backend) requires Node ≥ 24, but this is Node ${n}. Its prebuilt native modules are ABI-locked to Node 24 and crash on older majors. Use Node 24 (nvm/asdf locally, actions/setup-node in CI), or run with --backend npm.`}function onRealNode(){return gjsSystemVersion()===void 0?isNode():!1}function assertNativeBackendNodeVersion(){let n=nativeBackendNodeError(process.versions.node,onRealNode());if(n)throw Error(n)}var MP=__esmMin(()=>{Rm()});function checkList(n,a){let S=typeof a==`string`?[a]:a;if(S.length===1&&S[0]===`any`)return!0;let C=0,N=!1;for(let a of S){let S=a.charAt(0)===`!`,F=S?a.slice(1):a;if(S){if(C++,n===F)return!1}else N||=n===F}return N||C===S.length}function checkPlatform(n,a){let S=n.os?checkList(a.os,n.os):!0,C=n.cpu?checkList(a.cpu,n.cpu):!0,N=n.libc?checkList(a.libc,n.libc):!0;return n.libc&&!a.libc&&(N=!1),{ok:S&&C&&N,current:{os:a.os,cpu:a.cpu,libc:a.libc},required:{os:n.os,cpu:n.cpu,libc:n.libc}}}function declaresPlatform(n){return!!(n.os||n.cpu||n.libc)}function badPlatformError(n,a){let S=Error(`Unsupported platform for ${n}: wanted ${JSON.stringify(a.required)} (current: ${JSON.stringify(a.current)})`);return S.code=`EBADPLATFORM`,S.pkgid=n,S.current=a.current,S.required=a.required,S}function isMuslSharedObject(n){return n.includes(`libc.musl-`)||n.includes(`ld-musl-`)}function libcFromLddFile(n){let a=n.readTextFile(NP);if(a!==null)return a.includes(`musl`)?`musl`:a.includes(`GNU C Library`)?`glibc`:null}function libcFromReportData(n){return n.glibcVersionRuntime?`glibc`:Array.isArray(n.sharedObjects)&&n.sharedObjects.some(n=>isMuslSharedObject(String(n)))?`musl`:null}function libcFromLoaderScan(n,a=PP){let S=!1;for(let C of a){let a=n.listDir(C);if(a)for(let n of a){if(n.startsWith(`ld-linux`))return`glibc`;n.startsWith(`ld-musl-`)&&(S=!0)}}return S?`musl`:null}function detectLibc(n,a){if(n!==`linux`)return;let S=libcFromLddFile(a);if(S!==void 0)return S??void 0;let C=a.diagnosticReport();return C===null?libcFromLoaderScan(a)??void 0:libcFromReportData(C)??void 0}function defaultLibcProbeHost(){return{readTextFile(n){try{return readFileSync(n,`utf-8`)}catch{return null}},listDir(n){try{return readdirSync(n)}catch{return null}},diagnosticReport(){let n=process.report;if(!n||typeof n.getReport!=`function`)return null;let a=n.excludeNetwork;n.excludeNetwork=!0;try{let a=n.getReport();return{glibcVersionRuntime:a.header?.glibcVersionRuntime,sharedObjects:a.sharedObjects}}finally{n.excludeNetwork=a}}}}function hostLibc(n,a=defaultLibcProbeHost()){return IP||=(FP=detectLibc(n,a),!0),FP}function readPlatformOverrides(n){let pick=a=>{let S=n[a];if(typeof S!=`string`)return;let C=S.trim();return C===``?void 0:C},a={},S=pick(`npm_config_os`),C=pick(`npm_config_cpu`),N=pick(`npm_config_libc`);return S!==void 0&&(a.os=S),C!==void 0&&(a.cpu=C),N!==void 0&&(a.libc=N),a}function readPlatformForce(n){let a=n.npm_config_force;if(typeof a!=`string`)return!1;let S=a.trim().toLowerCase();return S===`true`||S===`1`}function resolveHostPlatform(n={}){let a=readPlatformOverrides(n.env??process.env),S=a.os??n.platform??process.platform;return{os:S,cpu:a.cpu??n.arch??process.arch,libc:a.libc??(S===`linux`?hostLibc(S,n.probe??defaultLibcProbeHost()):void 0)}}function describePlatformTarget(n){return`${n.os}-${n.cpu}${n.libc?`-${n.libc}`:``}`}var NP,PP,FP,IP,LP=__esmMin(()=>{Dl(),NP=`/usr/bin/ldd`,PP=[`/lib`,`/lib64`,`/usr/lib`],IP=!1}),RP=__exportAll$4({applyPlatformFilter:()=>applyPlatformFilter,computeOptionalFlags:()=>computeOptionalFlags,installPackagesNative:()=>installPackagesNative,parseSpec:()=>parseSpec,pickVersion:()=>pickVersion,requiredDepEntries:()=>requiredDepEntries,warnMissingNativeBuilds:()=>warnMissingNativeBuilds,writeBinEntry:()=>writeBinEntry});async function installPackagesNative(n){if(assertNativeBackendNodeVersion(),n.specs.length===0)throw Error(`installPackagesNative: empty specs list`);mkdirSync(n.prefix,{recursive:!0});let a=await loadNpmrc$1(n),S=makeLogger(n.verbose??!1),C=await acquireInstallLock(n.prefix,{signal:n.signal});try{return await installPackagesNativeLocked(n,a,S)}finally{C.release()}}async function installPackagesNativeLocked(n,a,S){let C=n.progress,N=vs(n.prefix,BP),F=readLockfile(N),I=resolveHostPlatform(),H=readPlatformForce(process.env);S(`install: platform target %s%s`,describePlatformTarget(I),H?` (--force: checks bypassed)`:``);let W,K=!1,q=new Set;if(n.frozen){if(!F)throw Error(`install: --immutable requires ${BP} at ${n.prefix} — none found. Run \`gjsify install\` (without --immutable) to generate one and commit it.`);let a=describeLockfileDrift(F,n.specs);if(a)throw Error(`install: --immutable but ${N} is stale.\n${a}\nRe-run \`gjsify install\` (without --immutable) to refresh the lockfile.`);S(`install: --immutable, using lockfile (%d package(s))`,Object.keys(F.packages).length),W=lockfileToNodes(F)}else if(!n.refreshLockfile&&F&&F.lockfileVersion===VP&&lockfileMatchesRequest(F,n.specs))S(`install: using lockfile (%d package(s))`,Object.keys(F.packages).length),W=lockfileToNodes(F);else{let N=!n.refreshLockfile&&F?buildPreferredVersions(F):void 0;S(`install: resolving %d top-level spec(s) → %s%s`,n.specs.length,n.prefix,N?` (preserving ${N.size} locked name(s))`:``);let I=await resolveDeps(n.specs,a,S,n.overrides,n.skipDeps,n.signal,C,N,n.workspaceNames,n.specOrigins,n.optionalSpecs);W=I.nodes,q=I.skippedEdges,K=!0}if(computeOptionalFlags(W,requiredTopLevelNames(n.specs,n.optionalSpecs),S),assertRequiredEdgesResolved(W,q),K&&n.lockfile&&(writeLockfile(N,n.specs,W),S(`install: wrote %s (%d entries)`,BP,W.length)),n.workspaceNames&&n.workspaceNames.size>0){let a=W.length;W=W.filter(a=>!n.workspaceNames.has(a.name));let C=a-W.length;C>0&&S(`install: %d workspace-provided package(s) symlinked, not fetched`,C)}let Y=applyPlatformFilter(W,I,H,S);return S(`install: downloading %d tarball(s)`,Y.length),await downloadAndExtractAll(Y,n.prefix,a,S,n.signal,C),await linkBins(Y,n.prefix,S),warnMissingNativeBuilds(Y,n.prefix,S),S(`install: done`),topLevelResolutions(n.specs,W)}function errMsg(n){return n instanceof Error?n.message:String(n)}function applyPlatformFilter(n,a,S,C){let N=[],F=0;for(let I of n){let n=I.platform;if(!n||!declaresPlatform(n)){N.push(I);continue}let H=checkPlatform(n,a);if(H.ok){N.push(I);continue}let W=`${I.name}@${I.version}`;if(!I.optional){if(S){C(`platform-forced: %s (required, incompatible, installed anyway via --force)`,W),N.push(I);continue}throw badPlatformError(W,H)}I.inert=!0,F++,C(`platform-skip: %s (%s) current=%s required=%s`,W,I.installPath,JSON.stringify(H.current),JSON.stringify(H.required))}return F>0&&C(`install: %d optional package(s) inert — not installable on %s`,F,describePlatformTarget(a)),N}function warnMissingNativeBuilds(n,a,S){let C=process.platform,N=process.arch,F=[`preinstall`,`install`,`postinstall`];for(let I of n){let n=vs(a,I.installPath),H;try{H=JSON.parse(readFileSync(vs(n,`package.json`),`utf8`))?.scripts}catch{continue}if(!H||typeof H!=`object`)continue;let W=F.find(n=>typeof H[n]==`string`);if(W===void 0)continue;let K=!1;try{let a=vs(n,`prebuilds`);for(let n of readdirSync(a))if(n.startsWith(`${C}-`)&&readdirSync(vs(a,n)).length>0){K=!0;break}}catch{}if(!K)try{K=readdirSync(vs(n,`build`,`Release`)).some(n=>n.endsWith(`.node`)||n.endsWith(`.so`))}catch{}K||S("install: WARNING — %s declares a native `%s` build script but ships no %s-%s prebuild, and gjsify install does not run build scripts (node-free). It will not load until built: run `node-gyp rebuild` in %s, or use a version that ships a %s-%s prebuild.",I.name,W,C,N,I.installPath,C,N)}}function topLevelResolutions(n,a){let S=new Map;for(let n of a)n.installPath===`node_modules/${n.name}`&&S.set(n.name,n);let C=[];for(let a of n){let n=parseSpecName(a),N=S.get(n);N&&C.push({name:N.name,version:N.version})}return C}function parseSpecName(n){if(n.startsWith(`@`)){let a=n.indexOf(`/`);if(a===-1)return n;let S=n.indexOf(`@`,a+1);return S===-1?n:n.slice(0,S)}let a=n.indexOf(`@`);return a===-1?n:n.slice(0,a)}async function resolveDeps(n,a,S,C,N,F,I,H,W,K,q){I?.beginPhase(`resolve`,n.length);let applyOverride=(n,a)=>{if(!C)return a;let N=C[n];return typeof N!=`string`||N.length===0||N===a?a:(S(`install: override %s %s → %s`,n,a,N),N)},Y=new Map,fetchPkg=n=>{let C=Y.get(n);if(C)return C;let N=fetchPackumentWithDiskCache(n,a,S,F,`full`);return Y.set(n,N),N},X=new Map,te=new Map,ne=new Set,re=new Map,ie=n.map(parseSpec).map(n=>{let a=applyOverride(n.name,n.range),S=re.get(n.name);S||(S=new Map,re.set(n.name,S));let C=S.get(a);C||(C=new Set,S.set(a,C));for(let a of K?.get(`${n.name}@${n.range}`)??[])C.add(a);return{from:null,name:n.name,range:a,required:!q?.has(n.name)}});for(;ie.length>0;){let n=ie.splice(0,ie.length),a=[],C=new Set;for(let S of n)Y.has(S.name)||C.has(S.name)||(C.add(S.name),a.push(S.name));await prefetchPackuments(a,fetchPkg,F);for(let a=0;a<n.length;a++){let C=n[a];if(W?.has(C.name))continue;let F=findVisible(C.from,C.name,X);if(F&&satisfiesRange(F.version,C.range))continue;let K=null;try{let F=await fetchPkg(C.name),W=preferredVersionFor(H?.get(C.name),C.range);if(K=pickVersion(F,C.range,W),!K)throw Error(`No version of ${C.name} satisfies ${C.range}`);let q=F.versions[K];if(!q)throw Error(`Packument for ${C.name} promised ${K} but no entry exists`);let Y=decidePlacement(C.from,C.name,K,te),ne={name:C.name,version:K,tarballUrl:q.dist.tarball,integrity:q.dist.integrity,installPath:Y,dependencies:q.dependencies??{},optionalDependencies:q.optionalDependencies??{},bin:q.bin,platform:platformDeclarationOf(q),optional:!C.required};if(X.set(Y,ne),Y===`node_modules/${C.name}`&&te.set(C.name,ne),S(`resolve: %s@%s ← %s (at %s)`,C.name,K,C.range,Y),I?.update({phase:`resolve`,current:X.size,total:X.size+(n.length-a-1)+ie.length,name:`${C.name}@${K}`}),!N){for(let[n,a]of requiredDepEntries(ne))ie.push({from:Y,name:n,range:applyOverride(n,a),required:!ne.optional});for(let[n,a]of Object.entries(ne.optionalDependencies))ie.push({from:Y,name:n,range:applyOverride(n,a),required:!1})}}catch(n){if(!C.required){ne.add(edgeKey(C.from,C.name)),S(`resolve: optional dep %s@%s skipped (%s)`,C.name,C.range,errMsg(n));continue}throw n}}}return I?.endPhase(`resolve`),emitTopLevelConflictWarnings(re,te),{nodes:Array.from(X.values()),skippedEdges:ne}}function platformDeclarationOf(n){let a={os:n.os,cpu:n.cpu,libc:n.libc};return declaresPlatform(a)?a:void 0}function edgeKey(n,a){return`${n??``}\n${a}`}function parseEdgeKey(n){let a=n.indexOf(`
|
|
867
867
|
`),S=n.slice(0,a);return{from:S===``?null:S,name:n.slice(a+1)}}function requiredTopLevelNames(n,a){let S=new Set;for(let C of n){let n=parseSpecName(C);a?.has(n)||S.add(n)}return S}function requiredDepEntries(n){let a=[];for(let[S,C]of Object.entries(n.dependencies))S in n.optionalDependencies||a.push([S,C]);return a}function computeOptionalFlags(n,a,S){let C=new Map;for(let a of n)C.set(a.installPath,a);let N=new Set,F=[],enter=n=>{N.has(n.installPath)||(N.add(n.installPath),F.push(n.installPath))};for(let n of a){let a=C.get(`node_modules/${n}`);a&&enter(a)}for(;F.length>0;){let n=F.pop();if(n===void 0)break;let a=C.get(n);if(a)for(let[S]of requiredDepEntries(a)){let a=findVisible(n,S,C);a&&enter(a)}}let I=0;for(let a of n){let n=!N.has(a.installPath);(a.optional??!1)!==n&&I++,a.optional=n}S(`install: optionality fixpoint — %d of %d node(s) reachable only via optional edges%s`,n.length-N.size,n.length,I>0?`; corrected ${I} incoming flag(s)`:``)}function assertRequiredEdgesResolved(n,a){if(a.size===0)return;let S=new Map;for(let a of n)S.set(a.installPath,a);for(let n of a){let{from:a,name:C}=parseEdgeKey(n);if(a===null)continue;let N=S.get(a);if(N&&!N.optional&&!(C in N.optionalDependencies))throw Error(`install: required dependency ${C} of ${N.name}@${N.version} (${N.installPath}) could not be resolved.\nThe failure was tolerated during the walk because ${N.name} looked optional at that point, but the final dependency graph makes it required — so ${C} is required too and the tree would be incomplete.\nRe-run with --verbose and look for the "resolve: optional dep ${C}@… skipped (…)" line for the underlying cause.`)}}function emitTopLevelConflictWarnings(n,a){for(let[S,C]of n){if(C.size<2)continue;let n=a.get(S);if(!n)continue;let describe=(n,a)=>a.size>0?`${n} (requested by ${[...a].join(`, `)})`:n,N=[],F=[];for(let[a,S]of C){let C;try{C=satisfies(n.version,new tP(a))}catch{continue}(C?N:F).push(describe(a,S))}F.length!==0&&he.warn(`[gjsify] warning: version conflict for ${S}: installed ${n.version} at ${n.installPath} — does NOT satisfy ${F.join(`, `)}`+(N.length>0?`; satisfies ${N.join(`, `)}`:``)+`. One hoisted copy serves all requesters until the per-workspace dedup pass lands (Phase D.8).`)}}async function fetchPackumentWithDiskCache(n,a,S,C,N=`corgi`){let F=registryFor(n,a),I=N===`full`,H=getCachedPackument(F,n,N),onRetry=({attempt:a,error:C,delayMs:F})=>{S(`packument %s (%s): retry %d after %dms (%s)`,n,N,a,F,errMsg(C))},W=await fetchPackumentConditional(n,{npmrc:a,signal:C,ifNoneMatch:H?.etag,fullMetadata:I,onRetry});return W.status===`not-modified`&&H?(S(`packument-cache-hit: %s (%s, 304, etag %s)`,n,N,H.etag),H.packument):W.status===`fresh`&&W.packument?(W.etag&&putCachedPackument(F,n,W.etag,W.packument,N),W.packument):fetchPackument(n,{npmrc:a,signal:C,fullMetadata:I,onRetry})}async function prefetchPackuments(n,a,S){if(n.length===0)return;let C=0,N=Math.max(1,Math.min(zP,n.length)),worker=async()=>{for(;C<n.length;){if(S?.aborted)return;let N=n[C++];try{await a(N)}catch{}}};await Promise.all(Array.from({length:N},()=>worker()))}function findVisible(n,a,S){let C=[];if(n!==null){C.push(`${n}/node_modules/${a}`);let S=n;for(;;){let n=S.lastIndexOf(`/node_modules/`);if(n<0||(S=S.slice(0,n),C.push(`${S}/node_modules/${a}`),S===``))break}}C.push(`node_modules/${a}`);for(let n of C){let a=S.get(n);if(a)return a}return null}function decidePlacement(n,a,S,C){let N=C.get(a);return!N||N.version===S||n===null?`node_modules/${a}`:`${n}/node_modules/${a}`}function satisfiesRange(n,a){try{return satisfies(n,new tP(a))}catch{return!1}}function readLockfile(n){if(!existsSync(n))return null;try{let a=JSON.parse(readFileSync(n,`utf-8`));return!HP.has(a.lockfileVersion)||!a.packages||typeof a.packages!=`object`?null:a}catch{return null}}function writeLockfile(n,a,S){let C={},N=[...S].sort((n,a)=>n.installPath<a.installPath?-1:+(n.installPath>a.installPath));for(let n of N)C[n.installPath]={version:n.version,resolved:n.tarballUrl,integrity:n.integrity,dependencies:Object.keys(n.dependencies).length>0?n.dependencies:void 0,optionalDependencies:Object.keys(n.optionalDependencies).length>0?n.optionalDependencies:void 0,bin:n.bin,os:n.platform?.os,cpu:n.platform?.cpu,libc:n.platform?.libc,optional:n.optional?!0:void 0};let F={lockfileVersion:VP,requested:[...a],packages:C};atomicWriteStrict(n,JSON.stringify(F,null,2)+`
|
|
868
868
|
`)}function buildPreferredVersions(n){let a=new Map;for(let[S,C]of Object.entries(n.packages)){let n=nameFromInstallPath(S),N=a.get(n);N||(N=new Set,a.set(n,N)),N.add(C.version)}return a}function preferredVersionFor(n,a){if(!n||n.size===0)return;let S;for(let C of n)satisfiesRange(C,a)&&(S===void 0||new SemVer(C).compare(new SemVer(S))>0)&&(S=C);return S}function lockfileToNodes(n){return Object.entries(n.packages).map(([n,a])=>{let S={os:a.os,cpu:a.cpu,libc:a.libc};return{name:nameFromInstallPath(n),version:a.version,tarballUrl:a.resolved,integrity:a.integrity,installPath:n,dependencies:a.dependencies??{},optionalDependencies:a.optionalDependencies??{},bin:a.bin,platform:declaresPlatform(S)?S:void 0,optional:a.optional===!0}})}function nameFromInstallPath(n){let a=n.lastIndexOf(`/node_modules/`);return a<0?n.replace(/^node_modules\//,``):n.slice(a+14)}function lockfileMatchesRequest(n,a){if(n.requested.length!==a.length)return!1;let S=[...n.requested].sort(),C=[...a].sort();return S.every((n,a)=>n===C[a])}function describeLockfileDrift(n,a){let S=new Set(n.requested),C=new Set(a),N=[],F=[];for(let n of C)S.has(n)||N.push(n);for(let n of S)C.has(n)||F.push(n);if(N.length===0&&F.length===0)return null;let I=[];return N.length>0&&I.push(` + ${N.sort().join(`
|
|
869
869
|
+ `)}`),F.length>0&&I.push(` - ${F.sort().join(`
|
|
@@ -918,11 +918,11 @@ jobs:
|
|
|
918
918
|
gjsify install ${ZF}\n Under Node the npm \`rolldown\` engine is used instead and this does not apply.`);return}let F=readCliVersionFrom(vs(C,`node_modules`,`@gjsify`,`cli`,`package.json`))??`latest`;he.log(`\n${ZF} is missing and this host can run gjs, so \`gjsify build\` would have no\n bundler engine (there is no npm \`rolldown\` fallback under GJS). Installing the GJS engine set at\n ${F}, in lockstep with the CLI.`),await(S.installFn??installGjsEnginePackages)(C,F,{verbose:n.verbose})}async function runPostInstallChecks(n){he.log(`
|
|
919
919
|
--- gjsify post-install checks ---`);let a=runMinimalChecks(),S=a.filter(n=>!n.found&&n.severity===`required`);if(S.length>0){he.warn(`Missing required system dependencies:
|
|
920
920
|
`);for(let n of S)he.warn(` ✗ ${n.name}`);let n=buildInstallCommand(detectPackageManager$2(),S);n&&he.warn(`\nInstall with:\n ${n}`)}else he.log(`System dependencies OK.`);await ensureProjectGjsEngine(n,a.find(n=>n.id===`gjs`)?.found??!1);let C=detectNativePackages(process.cwd());if(C.length>0){he.log(`\nDetected ${C.length} @gjsify/* package(s) with native prebuilds:`);for(let n of C)he.log(` • ${n.name}`);he.log("\nUse `gjsify run <bundle>` to launch with LD_LIBRARY_PATH/GI_TYPELIB_PATH set.")}maybeInstallGitHooks()}function maybeInstallGitHooks(){let n=process.cwd(),a=vs(n,`scripts`,`install-git-hooks.mjs`);if(existsSync(a)&&existsSync(vs(n,`.git`)))try{let S=spawnSync(nodeBinary(),[a,`--quiet`],{cwd:n,stdio:`inherit`,env:process.env});S.status!==0&&he.warn(`[gjsify install] scripts/install-git-hooks.mjs exited ${S.status} — git hooks may not be active.`)}catch(n){he.warn(`[gjsify install] git hook installation skipped: ${n instanceof Error?n.message:String(n)}`)}}var eI,tI,nI,rI,iI=__esmMin(()=>{ge(),Dl(),ks(),an(),lh(),YF(),Q_(),sv(),yv(),NN(),qP(),vP(),DP(),iN(),xN(),ev(),$F(),sN(),eI=process.platform===`win32`?`junction`:void 0,tI=18e5,nI={command:`install [packages..]`,description:`Install npm dependencies in the current project (or globally with -g), then run gjsify-aware post-checks.`,builder:n=>n.positional(`packages`,{description:`Optional package specs. With none, runs a full project install.`,type:`string`,array:!0}).option(`global`,{description:`Install into the user-global XDG location and symlink bins into ~/.local/bin.`,type:`boolean`,alias:`g`,default:!1}).option(`save-dev`,{type:`boolean`,alias:`D`}).option(`save-peer`,{type:`boolean`}).option(`save-optional`,{type:`boolean`,alias:`O`}).option(`immutable`,{description:`CI mode: install strictly from gjsify-lock.json, fail if the lockfile is missing or stale. Equivalent to yarn --immutable / npm ci --frozen-lockfile.`,type:`boolean`,default:!1}).option(`refresh-lockfile`,{description:`Re-resolve every dependency to the newest version satisfying its range and rewrite the lockfile (bumps in-range transitive deps). Without it, a resolve preserves versions already pinned in the lockfile and only resolves new/changed deps — the npm/yarn/pnpm default. Mirrors yarn install --mode=update-lockfile.`,type:`boolean`,default:!1}).option(`verbose`,{description:`Verbose install logging.`,type:`boolean`,default:!1}).option(`quiet`,{description:`Silence the progress bar.`,type:`boolean`,default:!1}).option(`progress`,{description:`Show a TTY-aware progress bar for resolve / download / extract phases. Auto-enabled when stderr is a TTY (override with --no-progress). Implicitly off under --verbose (per-package log lines replace the bar) or --quiet.`,type:`boolean`,default:!0}).option(`backend`,{description:"Install backend. `native` (default) routes through `@gjsify/{semver,npm-registry,tar}` — no Node/npm at runtime. `npm` shells out to `npm install` as an escape hatch for cases the native backend does not yet model (Yarn PnP repos, lifecycle scripts). Overrides `GJSIFY_INSTALL_BACKEND` if both are set.",type:`string`,choices:[`native`,`npm`]}).option(`timeout`,{description:`Overall install wall-clock timeout in ms (default 1800000 = 30 min). On timeout, all in-flight registry fetches are aborted and the install exits non-zero with a clear "install timed out — likely a registry slowdown" message. Per-request timeouts in @gjsify/npm-registry (default 30s) still apply within this budget. Set to 0 to disable the overall budget.`,type:`number`,default:tI}).option(`os`,{description:"Resolve/install for this OS instead of the running one (npm config key `os`, e.g. darwin, win32, linux). Affects which packages pass the os/cpu/libc compatibility check; the lockfile stays platform-independent either way.",type:`string`}).option(`cpu`,{description:"Resolve/install for this CPU architecture instead of the running one (npm config key `cpu`, e.g. x64, arm64).",type:`string`}).option(`libc`,{description:"Resolve/install for this libc family instead of probing the host (npm config key `libc`: glibc or musl). Only meaningful with --os=linux. A package declaring a libc is incompatible when the target libc is unknown.",type:`string`}).option(`force`,{description:"Install a REQUIRED dependency even when its os/cpu/libc excludes the target, instead of failing with EBADPLATFORM (npm config key `force`). Incompatible OPTIONAL dependencies stay skipped — npm ignores --force for those too, and a binary that cannot load is not worth downloading.",type:`boolean`,default:!1}),handler:async n=>{if(applyPlatformConfigFromFlags(n),n.immutable){if(n.packages&&n.packages.length>0)return he.error(`gjsify install --immutable does not accept package arguments. Remove the package names or drop --immutable.`),process.exit(1);if(n.global)return he.error(`gjsify install --immutable is incompatible with --global.`),process.exit(1);if(n[`refresh-lockfile`])return he.error(`gjsify install --immutable is incompatible with --refresh-lockfile (--immutable forbids rewriting the lockfile). Drop one.`),process.exit(1)}if(n.global){if(!n.packages||n.packages.length===0)return he.error(`gjsify install --global requires at least one <pkg> argument.`),process.exit(1);for(let a of[`save-dev`,`save-peer`,`save-optional`])n[a]&&he.warn(`gjsify install --global ignores --${a}: global installs do not modify a project package.json.`);await installGlobalAndLink(n.packages,{verbose:n.verbose});return}if(warnOnCliVersionSkew(process.cwd()),(n.backend??process.env.GJSIFY_INSTALL_BACKEND??`native`)===`npm`){await projectInstallViaNpm(n),await runPostInstallChecks(n);return}let a=n.timeout>0?n.timeout:0,S=a>0?new AbortController:null,C=S===null?null:setTimeout(()=>S.abort(Error(`install-overall-timeout`)),a),N=a>0?setTimeout(()=>{let n=Math.round(a/100)/10;he.error(`gjsify install: the ${n}s budget elapsed and the abort did not unwind within 10s — forcing exit. That means one of two things, and this timer cannot distinguish them: the install was still WORKING (a cold tree here extracts several GB, and extraction blocks the loop in multi-second synchronous stretches), or a step genuinely wedged. Re-running tells you which, and is safe: extraction is idempotent, every package already on disk is skipped, so a second run finishes the remainder in a fraction of the time. A re-run that makes NO further progress is a real wedge — file an issue.`),forceExit(1)},a+1e4):null;N?.unref?.();try{await projectInstallNative(n,S?.signal),await runPostInstallChecks(n)}catch(n){if(S!==null&&S.signal.aborted&&isAbortedFromOverallTimeout(n)){let n=Math.round(a/100)/10;return he.error(`gjsify install: timed out after ${n}s — likely a registry slowdown or a wedged extract.\nRe-run, or override with --timeout <ms> (set --timeout 0 to disable the overall budget).`),process.exit(1)}throw n}finally{C!==null&&clearTimeout(C),N!==null&&clearTimeout(N)}}},rI=`@gjsify/cli`});function readDirectChildren(n){let a;try{a=readdirSync(`/proc/${n}/task`)}catch{return null}let S=[],C=!1;for(let N of a)try{let a=readFileSync(`/proc/${n}/task/${N}/children`,`utf-8`);C=!0;for(let n of a.trim().split(/\s+/)){let a=Number(n);Number.isInteger(a)&&a>0&&S.push(a)}}catch{}return C?S:null}function buildPpidMap(){let n=new Map,a=[];try{a=readdirSync(`/proc`)}catch{return n}for(let S of a){let a=Number(S);if(!(!Number.isInteger(a)||a<=0))try{let S=readFileSync(`/proc/${a}/stat`,`utf-8`),C=S.slice(S.lastIndexOf(`)`)+2).split(` `),N=Number(C[1]);if(!Number.isInteger(N)||N<=0)continue;let F=n.get(N);F?F.push(a):n.set(N,[a])}catch{}}return n}function collectDescendants(n){let a=[],S=new Set([n]),C=[n],N=null;for(;C.length>0;){let n=C.shift(),F=readDirectChildren(n);F===null&&(N??=buildPpidMap(),F=N.get(n)??[]);for(let n of F)S.has(n)||(S.add(n),a.push(n),C.push(n))}return a}function signalTree(n,a,S){for(let n=a.length-1;n>=0;n--)try{process.kill(a[n],S)}catch{}try{n.kill(S)}catch{}}function killActiveChildren(){let n=new Map;for(let a of aI){let S=a.pid?collectDescendants(a.pid):[];n.set(a,S),signalTree(a,S,`SIGTERM`)}setTimeout(()=>{for(let a of aI){let S=new Set(a.pid?collectDescendants(a.pid):[]);for(let C of n.get(a)??[])S.add(C);signalTree(a,[...S],`SIGKILL`)}},oI).unref?.()}function assertEveryIncludeMatches(n,a){if(!a||a.length===0)return;let S=a.filter(a=>filterWorkspaces(n,{include:[a]}).length===0);if(S.length===0)return;let C=[`gjsify foreach: --include matched no workspace (${S.length} of ${a.length} pattern(s)):`];for(let a of S){C.push(` ${JSON.stringify(a)}`);let S=stripSurroundingQuotes(a);if(S!==a&&filterWorkspaces(n,{include:[S]}).length>0){C.push(` → matches as ${JSON.stringify(S)}: the QUOTES are part of the value. A shell expansion`," is not re-scanned for quoting, so a pre-quoted filter spliced through `sh -c` arrives with",` the quotes attached. Pass the bare name and let word splitting do the work.`);continue}let N=n.map(n=>n.name).filter(n=>n.toLowerCase().includes(S.replace(/\*/g,``).toLowerCase())).slice(0,3);N.length>0&&C.push(` → did you mean: ${N.join(`, `)}?`)}throw C.push(` ${n.length} workspace(s) discovered. Refusing to run: a filter that selects nothing would`,` otherwise exit 0 and look exactly like a successful run over the whole set.`),he.error(C.join(`
|
|
921
|
-
`)),process.exit(1),Error(`gjsify foreach: --include matched no workspace`)}function stripSurroundingQuotes(n){return n.length>=2&&(n[0]===`'`||n[0]===`"`)&&n[n.length-1]===n[0]?n.slice(1,-1):n}async function runSequential(n,a,S,C,N,F){for(let I of n)await runOne(I,a,S,!1,C,N,F)}async function runParallel(n,a,S,C,N,F,I){let H=0,W=[];for(let K=0;K<C;K++)W.push((async()=>{for(;H<n.length;)await runOne(n[H++],a,S,!0,N,F,I)})());await Promise.all(W)}async function runTopologicalParallel(n,a,S,C,N,F,I,H){let W=new Set(n.map(n=>n.name)),K=new Map;for(let a of n){let n=new Set,S=a.manifest;for(let a of[S.dependencies,F?S.devDependencies:void 0,S.optionalDependencies])if(a)for(let[S,C]of Object.entries(a))typeof C==`string`&&C.startsWith(`workspace:`)&&W.has(S)&&n.add(S);K.set(a.name,n)}let q=new Map(n.map(n=>[n.name,n])),Y=n.length,X=new Set,te=0,ne=!process.stdout.isTTY||N,re=new Map,ie=Number(process.env.GJSIFY_FOREACH_STALL_MINUTES??`20`),ae=(Number.isFinite(ie)&&ie>0?ie:20)*6e4;return new Promise((n,F)=>{let W=null,ie=Date.now(),describeInflight=()=>[...re.entries()].map(([n,a])=>`${n} (${Math.round((Date.now()-a)/1e3)}s)`).join(`, `),failFast=n=>{W||(W=n,killActiveChildren(),setTimeout(()=>settle(),sI).unref?.())},oe=setInterval(()=>{let n=Date.now()-ie;n<3e5||re.size===0||(he.error(`[gjsify foreach] WARNING: no workspace completed for ${Math.round(n/6e4)}min — in-flight: ${describeInflight()}`),n>=ae&&failFast(Error(`gjsify foreach: stalled — no workspace completed for ${Math.round(n/6e4)}min (override via GJSIFY_FOREACH_STALL_MINUTES); killed in-flight: ${describeInflight()}`)))},6e4);oe.unref?.();let settle=()=>{clearInterval(oe),W?F(W):n()},pump=()=>{if(!W){for(;te<C;){let n=[...K.entries()].filter(([,n])=>[...n].every(n=>X.has(n))).map(([n])=>n);if(n.length===0)break;let C=n.sort()[0];K.delete(C),te++,re.set(C,Date.now()),ne&&he.error(`[gjsify foreach] start ${C} (${X.size}/${Y} done, ${te} in flight)`),runOne(q.get(C),a,S,!0,N,I,H).then(()=>{X.add(C)}).catch(n=>{failFast(n instanceof Error?n:Error(String(n)))}).finally(()=>{te--,re.delete(C),ie=Date.now(),W?te===0&&settle():K.size===0&&te===0?settle():pump()})}K.size>0&&te===0&&!W&&(clearInterval(oe),F(Error(`gjsify foreach --topological: stuck — workspaces ${[...K.keys()].join(`, `)} have unsatisfied deps in the selected set`)))}};pump()})}async function runOne(n,a,S,C,N,F,I){if(F){N&&he.error(`[${n.name}] $ ${a} ${S.join(` `)}`),await spawnPrefixed(a,S,n.location,C?`[${n.name}] `:null);return}if(I&&I.tryRestore(n))return;let H=I?.snapshotOutputs(n),W=detectPackageManager(),K=W===`gjsify`?[`run`,a,...S]:[`run`,a,...S.length>0?[`--`,...S]:[]];N&&he.error(`[${n.name}] $ ${W} ${K.join(` `)}`),await spawnPrefixed(W,K,n.location,C?`[${n.name}] `:null),I&&H&&I.storeAfterSuccess(n,H)}function detectPackageManager(){if(isGjs())return`gjsify`;let n=process.env.npm_config_user_agent??``;return n.startsWith(`yarn/`)?`yarn`:n.startsWith(`gjsify/`)?`gjsify`:`npm`}async function spawnPrefixed(n,a,S,C){let N=null,F=[];try{let I=await spawnToCompletion(n,a,{completion:`exit`,cwd:S,stdio:C?`pipe`:`inherit`,color:!0,onSpawn:n=>{N=n,aI.add(n);let a=!process.stdout.isTTY;C&&n.stdout&&n.stderr&&(F.push(prefixLines(n.stdout,process.stdout,C,a)),F.push(prefixLines(n.stderr,process.stderr,C,a)))}});for(let n of F)n();if(I.code!==0)throw Error(`${n} ${a.join(` `)} exited with code ${I.code}`)}finally{N&&aI.delete(N)}}var aI,oI,sI,cI,lI=__esmMin(()=>{ge(),xN(),Dl(),Cm(),Q_(),ev(),mN(),ON(),Rm(),aI=new Set,oI=5e3,sI=15e3,cI={command:`foreach [script] [args..]`,description:"Run a workspace script across all (or filtered) workspaces. Drop-in for `yarn workspaces foreach`: -A/--all, -p/--parallel, -t/--topological, --include, --exclude, --no-private. Pass --exec to run an arbitrary command instead of a script.",builder:n=>n.positional(`script`,{description:"Script name to run in each workspace (`run <name>`-equivalent). With --exec, the command to run instead.",type:`string`}).positional(`args`,{description:`Extra arguments forwarded to each child invocation.`,type:`string`,array:!0}).option(`all`,{description:"Include workspaces declared as `private: true`.",type:`boolean`,alias:`A`,default:!1}).option(`parallel`,{description:`Run workspaces in parallel (capped by --jobs).`,type:`boolean`,alias:`p`,default:!1}).option(`topological`,{description:`Wait for each workspace's deps to finish before starting it (production deps only).`,type:`boolean`,alias:`t`,default:!1}).option(`topological-dev`,{description:`Like --topological but also respects devDependencies (often cyclic — use sparingly).`,type:`boolean`,default:!1}).option(`include`,{description:`Glob pattern to include workspaces by name (repeatable). A pattern that matches NO discovered workspace is a hard error — a filter selecting nothing is a typo or a caller-side quoting bug, never an intent.`,type:`string`,array:!0}).option(`exclude`,{description:`Glob pattern to exclude workspaces by name (repeatable).`,type:`string`,array:!0}).option(`private`,{description:`Include private workspaces (default true). Pass --no-private to skip them.`,type:`boolean`,default:!0}).option(`verbose`,{description:`Echo every spawned command before running it.`,type:`boolean`,alias:`v`,default:!1}).option(`jobs`,{description:`Maximum concurrent workspaces in --parallel mode (default: cpu count).`,type:`number`,alias:`j`}).option(`exec`,{description:"Treat <script> [args..] as an arbitrary command (yarn `workspaces foreach exec`-equivalent) instead of a package.json script lookup. Workspace filtering by script presence is skipped. Use `-- <cmd> <args...>` to pass flags to the command without yargs intercepting them.",type:`boolean`,default:!1}).option(`cached`,{description:`Content-hash build cache (ADR 0006): skip a workspace whose inputs (src/**, package.json, tsconfig*.json, transitive workspace deps, toolchain versions) are unchanged and restore its stored outputs instead; on miss run the script and store the output dirs it modified. Script mode only. Default from GJSIFY_BUILD_CACHE=1.`,type:`boolean`}).option(`shard`,{description:`Run only a deterministic slice "<index>/<total>" (1-based) of the matched workspaces, e.g. --shard 2/4. For fanning a long run across parallel CI jobs. Partitions by sorted name (round-robin) so the shards are disjoint and their union is the full set; order-independent, so safe for tests but NOT for ordered builds.`,type:`string`}).parserConfiguration({"populate--":!0}),handler:async n=>{let a=findWorkspaceRoot(process.cwd())??process.cwd(),S=discoverWorkspaces(a),C=n.exec===!0,N=n.script,F=n.args??[];if(!C){let a=(n[`--`]??[]).filter(n=>typeof n==`string`);a.length>0&&(F=[...F,...a])}if(C){let a=(n[`--`]??[]).filter(n=>typeof n==`string`);if(a.length>0&&(N?F=[...F,...a]:(N=a[0],F=[...F,...a.slice(1)])),!N)return he.error("gjsify foreach --exec: missing command. Pass it after `--`, e.g. `gjsify foreach --exec -- npm publish --tag latest`."),process.exit(1)}assertEveryIncludeMatches(S,n.include);let I=filterWorkspaces(S,{include:n.include,exclude:n.exclude,noPrivate:n.private===!1});if(!C){if(!N)return he.error(`gjsify foreach: missing <script> positional. Pass --exec to run an arbitrary command instead.`),process.exit(1);let n=N;I=I.filter(a=>typeof(a.manifest.scripts??{})[n]==`string`)}if(typeof n.shard==`string`&&n.shard.length>0){let a=/^\s*(\d+)\s*\/\s*(\d+)\s*$/.exec(n.shard);if(!a)return he.error(`gjsify foreach: invalid --shard "${n.shard}" — expected "<index>/<total>" (1-based), e.g. 2/4.`),process.exit(1);let S=Number(a[1]),C=Number(a[2]);if(C<1||S<1||S>C)return he.error(`gjsify foreach: invalid --shard "${n.shard}" — need 1 <= index <= total and total >= 1.`),process.exit(1);if(C>1){let n=[...I].sort((n,a)=>n.name<a.name?-1:+(n.name>a.name));I=n.filter((n,a)=>a%C===S-1),he.log(`gjsify foreach: shard ${S}/${C} → ${I.length} of ${n.length} workspace(s)`)}}if(I.length===0){he.log(`gjsify foreach: no workspaces match (${C?`exec`:`script`}="${N}", include=${JSON.stringify(n.include??[])}, exclude=${JSON.stringify(n.exclude??[])})`);return}(n.topological||n[`topological-dev`])&&(I=topologicalSort(buildDependencyGraph(I,{includeDev:n[`topological-dev`]===!0})));let H=n.verbose===!0,W=N,K=n.cached??buildCacheEnabledByEnv();if(n.cached===!0&&C)return he.error(`gjsify foreach: --cached only applies to script mode, not --exec.`),process.exit(1);let q=K&&!C?new BuildCacheRunner({root:a,workspaces:S,script:W,args:F,targets:I.map(n=>n.name)}):void 0;try{if(n.parallel&&!n.topological&&!n[`topological-dev`]){let a=n.jobs&&n.jobs>0?n.jobs:cpus().length;await runParallel(I,W,F,a,H,C,q)}else if(n.parallel){let a=n.jobs&&n.jobs>0?n.jobs:cpus().length;await runTopologicalParallel(I,W,F,a,H,n[`topological-dev`]===!0,C,q)}else await runSequential(I,W,F,H,C,q)}catch(n){return killActiveChildren(),he.error(n.message),process.exit(1)}process.exit(0)}}});async function runLifecycleScript(n,a,S,C={}){let N=(a.scripts??{})[S];if(typeof N!=`string`){if(C.optional!==!1)return!1;throw Error(`gjsify lifecycle-script: no "${S}" in ${n}/package.json`)}let F=findWorkspaceRoot(n),I=[vs(n,`node_modules`,`.bin`)];F&&F!==n&&I.push(vs(F,`node_modules`,`.bin`));let H=process.env.FORCE_COLOR!==void 0||process.env.NO_COLOR!==void 0?{}:{FORCE_COLOR:`1`},W={...process.env,...H,PATH:[...I,process.env.PATH??``].filter(Boolean).join(Ds),npm_lifecycle_event:S,npm_package_name:a.name??``,npm_package_version:a.version??``,...C.env};if(C.stdio===`ignore`)throw Error(`gjsify lifecycle-script: stdio "ignore" is not supported — see utils/spawn.ts`);let K=await spawnToCompletion(N,[],{completion:`return`,cwd:n,env:W,shell:!0,stdio:C.stdio===`inherit-stderr`?`inherit-stderr`:C.stdio===`pipe`?`pipe`:`inherit`});if(K.code!==0)throw Error(`gjsify lifecycle-script: "${S}" in ${n} exited with ${describeExit(K)}`);return!0}var uI=__esmMin(()=>{ks(),xN(),ev()});async function packWorkspace(n,a={}){let S=vs(n,`package.json`);if(!existsSync(S))throw Error(`gjsify pack: no package.json at ${n}`);let C=readFileSync(S,`utf-8`),N=JSON.parse(C),F=typeof N.name==`string`?N.name:``,I=typeof N.version==`string`?N.version:`0.0.0`;if(!F)throw Error(`gjsify pack: package.json at ${n} has no "name"`);let H=a.lifecycleScripts??[`prepack`];for(let S of H)await runLifecycleScript(n,N,S,{optional:!0,stdio:a.lifecycleStdio});let W=readFileSync(S,`utf-8`),K=W===C?N:JSON.parse(W),q=a.skipWorkspaceRewrite?K:rewriteWorkspaceDeps(K,n),Y=JSON.stringify(q,null,indentOf(W))+`
|
|
921
|
+
`)),process.exit(1),Error(`gjsify foreach: --include matched no workspace`)}function stripSurroundingQuotes(n){return n.length>=2&&(n[0]===`'`||n[0]===`"`)&&n[n.length-1]===n[0]?n.slice(1,-1):n}async function runSequential(n,a,S,C,N,F){for(let I of n)await runOne(I,a,S,!1,C,N,F)}async function runParallel(n,a,S,C,N,F,I){let H=0,W=[];for(let K=0;K<C;K++)W.push((async()=>{for(;H<n.length;)await runOne(n[H++],a,S,!0,N,F,I)})());await Promise.all(W)}async function runTopologicalParallel(n,a,S,C,N,F,I,H){let W=new Set(n.map(n=>n.name)),K=new Map;for(let a of n){let n=new Set,S=a.manifest;for(let a of[S.dependencies,F?S.devDependencies:void 0,S.optionalDependencies])if(a)for(let[S,C]of Object.entries(a))typeof C==`string`&&C.startsWith(`workspace:`)&&W.has(S)&&n.add(S);K.set(a.name,n)}let q=new Map(n.map(n=>[n.name,n])),Y=n.length,X=new Set,te=0,ne=!process.stdout.isTTY||N,re=new Map,ie=Number(process.env.GJSIFY_FOREACH_STALL_MINUTES??`20`),ae=(Number.isFinite(ie)&&ie>0?ie:20)*6e4;return new Promise((n,F)=>{let W=null,ie=Date.now(),describeInflight=()=>[...re.entries()].map(([n,a])=>`${n} (${Math.round((Date.now()-a)/1e3)}s)`).join(`, `),failFast=n=>{W||(W=n,killActiveChildren(),setTimeout(()=>settle(),sI).unref?.())},oe=setInterval(()=>{let n=Date.now()-ie;n<3e5||re.size===0||(he.error(`[gjsify foreach] WARNING: no workspace completed for ${Math.round(n/6e4)}min — in-flight: ${describeInflight()}`),n>=ae&&failFast(Error(`gjsify foreach: stalled — no workspace completed for ${Math.round(n/6e4)}min (override via GJSIFY_FOREACH_STALL_MINUTES); killed in-flight: ${describeInflight()}`)))},6e4);oe.unref?.();let settle=()=>{clearInterval(oe),W?F(W):n()},pump=()=>{if(!W){for(;te<C;){let n=[...K.entries()].filter(([,n])=>[...n].every(n=>X.has(n))).map(([n])=>n);if(n.length===0)break;let C=n.sort()[0];K.delete(C),te++,re.set(C,Date.now()),ne&&he.error(`[gjsify foreach] start ${C} (${X.size}/${Y} done, ${te} in flight)`),runOne(q.get(C),a,S,!0,N,I,H).then(()=>{X.add(C)}).catch(n=>{failFast(n instanceof Error?n:Error(String(n)))}).finally(()=>{te--,re.delete(C),ie=Date.now(),W?te===0&&settle():K.size===0&&te===0?settle():pump()})}K.size>0&&te===0&&!W&&(clearInterval(oe),F(Error(`gjsify foreach --topological: stuck — workspaces ${[...K.keys()].join(`, `)} have unsatisfied deps in the selected set`)))}};pump()})}async function runOne(n,a,S,C,N,F,I){if(F){N&&he.error(`[${n.name}] $ ${a} ${S.join(` `)}`),await spawnPrefixed(a,S,n.location,C?`[${n.name}] `:null);return}if(I&&I.tryRestore(n))return;let H=I?.snapshotOutputs(n),W=detectPackageManager(),K=W===`gjsify`?[`run`,a,...S]:[`run`,a,...S.length>0?[`--`,...S]:[]];N&&he.error(`[${n.name}] $ ${W} ${K.join(` `)}`),await spawnPrefixed(W,K,n.location,C?`[${n.name}] `:null),I&&H&&I.storeAfterSuccess(n,H)}function detectPackageManager(){if(isGjs())return`gjsify`;let n=process.env.npm_config_user_agent??``;return n.startsWith(`yarn/`)?`yarn`:n.startsWith(`gjsify/`)?`gjsify`:`npm`}async function spawnPrefixed(n,a,S,C){let N=null,F=[];try{let I=await spawnToCompletion(n,a,{completion:`exit`,cwd:S,stdio:C?`pipe`:`inherit`,color:!0,onSpawn:n=>{N=n,aI.add(n);let a=!process.stdout.isTTY;C&&n.stdout&&n.stderr&&(F.push(prefixLines(n.stdout,process.stdout,C,a)),F.push(prefixLines(n.stderr,process.stderr,C,a)))}});for(let n of F)n();if(I.code!==0)throw Error(`${n} ${a.join(` `)} exited with code ${I.code}`)}finally{N&&aI.delete(N)}}var aI,oI,sI,cI,lI=__esmMin(()=>{ge(),xN(),Dl(),Cm(),Q_(),ev(),mN(),ON(),Rm(),aI=new Set,oI=5e3,sI=15e3,cI={command:`foreach [script] [args..]`,description:"Run a workspace script across all (or filtered) workspaces. Drop-in for `yarn workspaces foreach`: -A/--all, -p/--parallel, -t/--topological, --include, --exclude, --no-private. Pass --exec to run an arbitrary command instead of a script.",builder:n=>n.positional(`script`,{description:"Script name to run in each workspace (`run <name>`-equivalent). With --exec, the command to run instead.",type:`string`}).positional(`args`,{description:`Extra arguments forwarded to each child invocation.`,type:`string`,array:!0}).option(`all`,{description:"Include workspaces declared as `private: true`.",type:`boolean`,alias:`A`,default:!1}).option(`parallel`,{description:`Run workspaces in parallel (capped by --jobs).`,type:`boolean`,alias:`p`,default:!1}).option(`topological`,{description:`Wait for each workspace's deps to finish before starting it (production deps only).`,type:`boolean`,alias:`t`,default:!1}).option(`topological-dev`,{description:`Like --topological but also respects devDependencies (often cyclic — use sparingly).`,type:`boolean`,default:!1}).option(`include`,{description:`Glob pattern to include workspaces by name (repeatable). A pattern that matches NO discovered workspace is a hard error — a filter selecting nothing is a typo or a caller-side quoting bug, never an intent.`,type:`string`,array:!0}).option(`exclude`,{description:`Glob pattern to exclude workspaces by name (repeatable).`,type:`string`,array:!0}).option(`with-dependencies`,{description:`Also select everything the filtered set DEPENDS ON (production deps; add --topological-dev for devDependencies). --include only filters and --topological only orders, so neither can say 'and the packages these need'. Excludes are re-applied afterwards.`,type:`boolean`,alias:`d`,default:!1}).option(`private`,{description:`Include private workspaces (default true). Pass --no-private to skip them.`,type:`boolean`,default:!0}).option(`verbose`,{description:`Echo every spawned command before running it.`,type:`boolean`,alias:`v`,default:!1}).option(`jobs`,{description:`Maximum concurrent workspaces in --parallel mode (default: cpu count).`,type:`number`,alias:`j`}).option(`exec`,{description:"Treat <script> [args..] as an arbitrary command (yarn `workspaces foreach exec`-equivalent) instead of a package.json script lookup. Workspace filtering by script presence is skipped. Use `-- <cmd> <args...>` to pass flags to the command without yargs intercepting them.",type:`boolean`,default:!1}).option(`cached`,{description:`Content-hash build cache (ADR 0006): skip a workspace whose inputs (src/**, package.json, tsconfig*.json, transitive workspace deps, toolchain versions) are unchanged and restore its stored outputs instead; on miss run the script and store the output dirs it modified. Script mode only. Default from GJSIFY_BUILD_CACHE=1.`,type:`boolean`}).option(`shard`,{description:`Run only a deterministic slice "<index>/<total>" (1-based) of the matched workspaces, e.g. --shard 2/4. For fanning a long run across parallel CI jobs. Partitions by sorted name (round-robin) so the shards are disjoint and their union is the full set; order-independent, so safe for tests but NOT for ordered builds.`,type:`string`}).parserConfiguration({"populate--":!0}),handler:async n=>{let a=findWorkspaceRoot(process.cwd())??process.cwd(),S=discoverWorkspaces(a),C=n.exec===!0,N=n.script,F=n.args??[];if(!C){let a=(n[`--`]??[]).filter(n=>typeof n==`string`);a.length>0&&(F=[...F,...a])}if(C){let a=(n[`--`]??[]).filter(n=>typeof n==`string`);if(a.length>0&&(N?F=[...F,...a]:(N=a[0],F=[...F,...a.slice(1)])),!N)return he.error("gjsify foreach --exec: missing command. Pass it after `--`, e.g. `gjsify foreach --exec -- npm publish --tag latest`."),process.exit(1)}assertEveryIncludeMatches(S,n.include);let I=filterWorkspaces(S,{include:n.include,exclude:n.exclude,noPrivate:n.private===!1});if(n[`with-dependencies`]===!0){let a=affectedClosure(buildDependencyGraph(S,{includeDev:n[`topological-dev`]===!0}),I.map(n=>n.name));I=filterWorkspaces(S.filter(n=>a.has(n.name)),{exclude:n.exclude,noPrivate:n.private===!1})}if(!C){if(!N)return he.error(`gjsify foreach: missing <script> positional. Pass --exec to run an arbitrary command instead.`),process.exit(1);let n=N;I=I.filter(a=>typeof(a.manifest.scripts??{})[n]==`string`)}if(typeof n.shard==`string`&&n.shard.length>0){let a=/^\s*(\d+)\s*\/\s*(\d+)\s*$/.exec(n.shard);if(!a)return he.error(`gjsify foreach: invalid --shard "${n.shard}" — expected "<index>/<total>" (1-based), e.g. 2/4.`),process.exit(1);let S=Number(a[1]),C=Number(a[2]);if(C<1||S<1||S>C)return he.error(`gjsify foreach: invalid --shard "${n.shard}" — need 1 <= index <= total and total >= 1.`),process.exit(1);if(C>1){let n=[...I].sort((n,a)=>n.name<a.name?-1:+(n.name>a.name));I=n.filter((n,a)=>a%C===S-1),he.log(`gjsify foreach: shard ${S}/${C} → ${I.length} of ${n.length} workspace(s)`)}}if(I.length===0){he.log(`gjsify foreach: no workspaces match (${C?`exec`:`script`}="${N}", include=${JSON.stringify(n.include??[])}, exclude=${JSON.stringify(n.exclude??[])})`);return}(n.topological||n[`topological-dev`])&&(I=topologicalSort(buildDependencyGraph(I,{includeDev:n[`topological-dev`]===!0})));let H=n.verbose===!0,W=N,K=n.cached??buildCacheEnabledByEnv();if(n.cached===!0&&C)return he.error(`gjsify foreach: --cached only applies to script mode, not --exec.`),process.exit(1);let q=K&&!C?new BuildCacheRunner({root:a,workspaces:S,script:W,args:F,targets:I.map(n=>n.name)}):void 0;try{if(n.parallel&&!n.topological&&!n[`topological-dev`]){let a=n.jobs&&n.jobs>0?n.jobs:cpus().length;await runParallel(I,W,F,a,H,C,q)}else if(n.parallel){let a=n.jobs&&n.jobs>0?n.jobs:cpus().length;await runTopologicalParallel(I,W,F,a,H,n[`topological-dev`]===!0,C,q)}else await runSequential(I,W,F,H,C,q)}catch(n){return killActiveChildren(),he.error(n.message),process.exit(1)}process.exit(0)}}});async function runLifecycleScript(n,a,S,C={}){let N=(a.scripts??{})[S];if(typeof N!=`string`){if(C.optional!==!1)return!1;throw Error(`gjsify lifecycle-script: no "${S}" in ${n}/package.json`)}let F=findWorkspaceRoot(n),I=[vs(n,`node_modules`,`.bin`)];F&&F!==n&&I.push(vs(F,`node_modules`,`.bin`));let H=process.env.FORCE_COLOR!==void 0||process.env.NO_COLOR!==void 0?{}:{FORCE_COLOR:`1`},W={...process.env,...H,PATH:[...I,process.env.PATH??``].filter(Boolean).join(Ds),npm_lifecycle_event:S,npm_package_name:a.name??``,npm_package_version:a.version??``,...C.env};if(C.stdio===`ignore`)throw Error(`gjsify lifecycle-script: stdio "ignore" is not supported — see utils/spawn.ts`);let K=await spawnToCompletion(N,[],{completion:`return`,cwd:n,env:W,shell:!0,stdio:C.stdio===`inherit-stderr`?`inherit-stderr`:C.stdio===`pipe`?`pipe`:`inherit`});if(K.code!==0)throw Error(`gjsify lifecycle-script: "${S}" in ${n} exited with ${describeExit(K)}`);return!0}var uI=__esmMin(()=>{ks(),xN(),ev()});async function packWorkspace(n,a={}){let S=vs(n,`package.json`);if(!existsSync(S))throw Error(`gjsify pack: no package.json at ${n}`);let C=readFileSync(S,`utf-8`),N=JSON.parse(C),F=typeof N.name==`string`?N.name:``,I=typeof N.version==`string`?N.version:`0.0.0`;if(!F)throw Error(`gjsify pack: package.json at ${n} has no "name"`);let H=a.lifecycleScripts??[`prepack`];for(let S of H)await runLifecycleScript(n,N,S,{optional:!0,stdio:a.lifecycleStdio});let W=readFileSync(S,`utf-8`),K=W===C?N:JSON.parse(W),q=a.skipWorkspaceRewrite?K:rewriteWorkspaceDeps(K,n),Y=JSON.stringify(q,null,indentOf(W))+`
|
|
922
922
|
`,X=collectPackedFiles(n,K);assertTypeDeclarationsShipped(n,K,X);let te=[{name:`package/`,directory:!0,mode:493}],ne=[],re=0;for(let a of X){let S;S=a===`package.json`?new TextEncoder().encode(Y):new Uint8Array(readFileSync(vs(n,a)));let C=statSync(vs(n,a)).mode&511;te.push({name:`package/${a}`,body:S,mode:C,mtime:0}),ne.push({path:a,size:S.byteLength,mode:C}),re+=S.byteLength}let ie=await gzip(createTarball(te)),ae=`${F.startsWith(`@`)?F.slice(1).replace(`/`,`-`):F}-${I}.tgz`,oe=createHash(`sha1`).update(ie).digest(`hex`),Z=`sha512-${createHash(`sha512`).update(ie).digest(`base64`)}`,se=a.destination?hs(a.destination):n,ce=vs(se,ae);return a.dryRun||(mkdirSync(se,{recursive:!0}),writeFileSync(ce,ie)),{filename:ae,name:F,version:I,size:ie.byteLength,unpackedSize:re,shasum:oe,integrity:Z,entryCount:ne.length,files:ne,absolutePath:a.dryRun?null:ce}}function collectPackedFiles(n,a){let S=forceIncluded(a),C=Array.isArray(a.files)?a.files.filter(n=>typeof n==`string`):null,N=new Set;if(C)for(let a of expandFilesPatterns(n,C))N.add(a);else{let a=loadIgnore(n);for(let S of walkAll(n))a(S)||N.add(S)}for(let a of S)existsSync(vs(n,a))&&N.add(a);return[...N].sort()}function collectTypeDeclarationRefs(n){let a=new Set,add=n=>{if(typeof n!=`string`)return;let S=n.replace(/^\.\//,``);S.includes(`*`)||a.add(S)};for(let a of[`types`,`typings`])add(n[a]);let walk=n=>{if(!(!n||typeof n!=`object`)){if(Array.isArray(n)){for(let a of n)walk(a);return}for(let[a,S]of Object.entries(n))a===`types`||a===`typings`?add(S):walk(S)}};return walk(n.exports),[...a]}function assertTypeDeclarationsShipped(n,a,S){let C=new Set(S),N=collectTypeDeclarationRefs(a).filter(a=>{let S=vs(n,a);return existsSync(S)&&statSync(S).isFile()&&!C.has(a)});if(N.length===0)return;let F=typeof a.name==`string`?a.name:`(unnamed)`,I=Array.isArray(a.files)?JSON.stringify(a.files):`(none)`;throw Error(`gjsify pack: ${F} references TypeScript declaration file(s) via "exports"/"types" that exist on disk but are excluded from the tarball by the "files" allowlist (${I}):\n`+N.map(n=>` - ${n}`).join(`
|
|
923
923
|
`)+`
|
|
924
924
|
Add the missing path(s) to package.json "files" so type resolution isn't silently broken for consumers.`)}function forceIncluded(n){let a=new Set;a.add(`package.json`);for(let n of[`README`,`README.md`,`LICENSE`,`LICENSE.md`,`NOTICE`,`NOTICE.md`])a.add(n);let S=typeof n.main==`string`?n.main:null;S&&a.add(S.replace(/^\.\//,``));let C=n.bin;if(typeof C==`string`)a.add(C.replace(/^\.\//,``));else if(C&&typeof C==`object`)for(let n of Object.values(C))typeof n==`string`&&a.add(n.replace(/^\.\//,``));return[...a]}function walkAll(n,a=``){let S=[],C=a?vs(n,a):n,N;try{N=readdirSync(C,{withFileTypes:!0})}catch{return S}for(let C of N){if(fI.has(C.name)||C.name.startsWith(`.tsbuildinfo`))continue;let N=a?`${a}/${C.name}`:C.name;C.isDirectory()?S.push(...walkAll(n,N)):C.isFile()&&S.push(N)}return S}function expandFilesPatterns(n,a){let S=new Set,C=null;for(let N of a){let a=N.replace(/^\.\//,``).replace(/\/$/,``);if(!a)continue;if(!/[*?[\]]/.test(a)){let C=vs(n,a);if(!existsSync(C))continue;let N=statSync(C);if(N.isDirectory())for(let C of walkAll(n,a))S.add(C);else N.isFile()&&S.add(a);continue}C??=walkAll(n);let F=filesGlobToRegExp(a),I=filesGlobToRegExp(`${a}/**`);for(let n of C)(F.test(n)||I.test(n))&&S.add(n)}return[...S]}function filesGlobToRegExp(n){let a=`^`;for(let S=0;S<n.length;S++){let C=n[S];if(C===`*`)n[S+1]===`*`?(a+=`.*`,S++,n[S+1]===`/`&&S++):a+=`[^/]*`;else if(C===`?`)a+=`[^/]`;else if(C===`[`){let C=S+1,N=`[`;for(n[C]===`!`&&(N+=`^`,C++);C<n.length&&n[C]!==`]`;C++)N+=n[C];C<n.length?(a+=`${N}]`,S=C):a+=`\\[`}else".+^${}()|\\]".includes(C)?a+=`\\${C}`:a+=C}return RegExp(`${a}$`)}function loadIgnore(n){let a=vs(n,`.npmignore`),S=vs(n,`.gitignore`),C=[],N=existsSync(a)?a:existsSync(S)?S:null;if(N){let n=readFileSync(N,`utf-8`).split(`
|
|
925
|
-
`);for(let a of n){let n=a.trim();!n||n.startsWith(`#`)||n.startsWith(`!`)||C.push(globToRegex(n))}}return n=>{for(let a of C)if(a.test(n))return!0;return!1}}function globToRegex(n){let a=n.replace(/^\//,``);return a=a.replace(/[.+^${}()|[\]\\]/g,`\\$&`),a=a.replace(/\*\*/g,`__DOUBLESTAR__`).replace(/\*/g,`[^/]*`).replace(/__DOUBLESTAR__/g,`.*`),a=a.replace(/\?/g,`[^/]`),RegExp(`^${a}($|/)`)}function collectWorkspaceProtocolDeps(n){let a=[];for(let S of pI){let C=n[S];if(C)for(let[n,N]of Object.entries(C))typeof N==`string`&&N.startsWith(`workspace:`)&&a.push(`${S}.${n}`)}return a}function findPackWorkspaceRoot(n){let a=findWorkspaceRoot(n);if(a)return a;let S=n;for(let n=0;n<12;n++){let n=vs(S,`package.json`);if(existsSync(n)&&readPackageJson$2(n)?.workspaces!==void 0)return S;let a=hs(S,`..`);if(a===S)break;S=a}return null}function rewriteWorkspaceDeps(n,a){let S=findPackWorkspaceRoot(a);if(!S){let S=collectWorkspaceProtocolDeps(n);if(S.length>0)throw Error(`gjsify pack: ${String(n.name)} declares workspace: ranges (${S.join(`, `)}) but ${a} is not inside a monorepo (no ancestor package.json declares "workspaces"). A workspace: range cannot be published — replace it with a real npm range, or pack from within the monorepo.`);return n}let C=new Map;for(let n of discoverWorkspaces(S))n.name&&n.version&&C.set(n.name,n.version);let N=JSON.parse(JSON.stringify(n));for(let n of pI){let a=N[n];if(a)for(let[F,I]of Object.entries(a)){if(typeof I!=`string`||!I.startsWith(`workspace:`))continue;let H=C.get(F);if(!H)throw Error(`gjsify pack: ${N.name} declares ${I} on ${F} (${n}) but no sibling workspace with that name exists in the monorepo at ${S}`);let W=I.slice(10);W===`*`||W===``?a[F]=H:W===`^`||W===`~`?a[F]=`${W}${H}`:a[F]=W}}return N}function indentOf(n){let a=n.match(/\n([ \t]+)"/);return a?a[1]:` `}var dI,fI,pI,mI=__esmMin(()=>{Dl(),So(),ks(),_P(),Q_(),ev(),$_(),uI(),dI={command:`pack [path]`,description:`Produce an npm-compatible .tgz tarball for the workspace at <path> (default: cwd). Rewrites workspace:^/~/* deps to resolved versions.`,builder:n=>n.positional(`path`,{description:`Workspace path (default: cwd).`,type:`string`}).option(`pack-destination`,{description:`Directory to write the tarball into. Default: workspace cwd.`,type:`string`}).option(`json`,{description:"Emit pack metadata as JSON on stdout (mirrors `npm pack --json`).",type:`boolean`,default:!1}).option(`dry-run`,{description:`Compute everything but do not write the .tgz.`,type:`boolean`,default:!1}).option(`ignore-scripts`,{description:"Skip the `prepack` lifecycle script before packing. Mirrors `npm pack --ignore-scripts`. Use when scripts are already run by the outer workflow.",type:`boolean`,default:!1}),handler:async n=>{let a=await packWorkspace(hs(n.path??process.cwd()),{destination:n[`pack-destination`],dryRun:n[`dry-run`]===!0,lifecycleScripts:n[`ignore-scripts`]?[]:[`prepack`],lifecycleStdio:n.json?`inherit-stderr`:`inherit`});n.json?process.stdout.write(`${JSON.stringify([a],null,2)}\n`):process.stdout.write(`${a.filename}\n`)}},fI=new Set([`.git`,`.svn`,`.hg`,`.gitignore`,`.gitattributes`,`.npmrc`,`CVS`,`.DS_Store`,`node_modules`,`.npmignore`,`package-lock.json`,`gjsify-lock.json`,`yarn.lock`,`yarn-error.log`,`.yarn`,`.pnp.cjs`,`.pnp.loader.mjs`,`tsconfig.tsbuildinfo`]),pI=[`dependencies`,`devDependencies`,`peerDependencies`,`optionalDependencies`]});function escapePackageName(n){return n.replace(`/`,`%2f`)}function buildPublishHeaders(n,a){let S=buildHeaders(n,{npmrc:a.npmrc});return S[`content-type`]=`application/json`,S[`npm-command`]=`publish`,S[`npm-auth-type`]=a.otp?`legacy`:`web`,S[`user-agent`]=a.userAgent??defaultUserAgent(),a.otp&&(S[`npm-otp`]=a.otp),a.authorization&&(S.authorization=a.authorization),S}function cliVersion(){return hI===void 0&&(hI=`0.
|
|
925
|
+
`);for(let a of n){let n=a.trim();!n||n.startsWith(`#`)||n.startsWith(`!`)||C.push(globToRegex(n))}}return n=>{for(let a of C)if(a.test(n))return!0;return!1}}function globToRegex(n){let a=n.replace(/^\//,``);return a=a.replace(/[.+^${}()|[\]\\]/g,`\\$&`),a=a.replace(/\*\*/g,`__DOUBLESTAR__`).replace(/\*/g,`[^/]*`).replace(/__DOUBLESTAR__/g,`.*`),a=a.replace(/\?/g,`[^/]`),RegExp(`^${a}($|/)`)}function collectWorkspaceProtocolDeps(n){let a=[];for(let S of pI){let C=n[S];if(C)for(let[n,N]of Object.entries(C))typeof N==`string`&&N.startsWith(`workspace:`)&&a.push(`${S}.${n}`)}return a}function findPackWorkspaceRoot(n){let a=findWorkspaceRoot(n);if(a)return a;let S=n;for(let n=0;n<12;n++){let n=vs(S,`package.json`);if(existsSync(n)&&readPackageJson$2(n)?.workspaces!==void 0)return S;let a=hs(S,`..`);if(a===S)break;S=a}return null}function rewriteWorkspaceDeps(n,a){let S=findPackWorkspaceRoot(a);if(!S){let S=collectWorkspaceProtocolDeps(n);if(S.length>0)throw Error(`gjsify pack: ${String(n.name)} declares workspace: ranges (${S.join(`, `)}) but ${a} is not inside a monorepo (no ancestor package.json declares "workspaces"). A workspace: range cannot be published — replace it with a real npm range, or pack from within the monorepo.`);return n}let C=new Map;for(let n of discoverWorkspaces(S))n.name&&n.version&&C.set(n.name,n.version);let N=JSON.parse(JSON.stringify(n));for(let n of pI){let a=N[n];if(a)for(let[F,I]of Object.entries(a)){if(typeof I!=`string`||!I.startsWith(`workspace:`))continue;let H=C.get(F);if(!H)throw Error(`gjsify pack: ${N.name} declares ${I} on ${F} (${n}) but no sibling workspace with that name exists in the monorepo at ${S}`);let W=I.slice(10);W===`*`||W===``?a[F]=H:W===`^`||W===`~`?a[F]=`${W}${H}`:a[F]=W}}return N}function indentOf(n){let a=n.match(/\n([ \t]+)"/);return a?a[1]:` `}var dI,fI,pI,mI=__esmMin(()=>{Dl(),So(),ks(),_P(),Q_(),ev(),$_(),uI(),dI={command:`pack [path]`,description:`Produce an npm-compatible .tgz tarball for the workspace at <path> (default: cwd). Rewrites workspace:^/~/* deps to resolved versions.`,builder:n=>n.positional(`path`,{description:`Workspace path (default: cwd).`,type:`string`}).option(`pack-destination`,{description:`Directory to write the tarball into. Default: workspace cwd.`,type:`string`}).option(`json`,{description:"Emit pack metadata as JSON on stdout (mirrors `npm pack --json`).",type:`boolean`,default:!1}).option(`dry-run`,{description:`Compute everything but do not write the .tgz.`,type:`boolean`,default:!1}).option(`ignore-scripts`,{description:"Skip the `prepack` lifecycle script before packing. Mirrors `npm pack --ignore-scripts`. Use when scripts are already run by the outer workflow.",type:`boolean`,default:!1}),handler:async n=>{let a=await packWorkspace(hs(n.path??process.cwd()),{destination:n[`pack-destination`],dryRun:n[`dry-run`]===!0,lifecycleScripts:n[`ignore-scripts`]?[]:[`prepack`],lifecycleStdio:n.json?`inherit-stderr`:`inherit`});n.json?process.stdout.write(`${JSON.stringify([a],null,2)}\n`):process.stdout.write(`${a.filename}\n`)}},fI=new Set([`.git`,`.svn`,`.hg`,`.gitignore`,`.gitattributes`,`.npmrc`,`CVS`,`.DS_Store`,`node_modules`,`.npmignore`,`package-lock.json`,`gjsify-lock.json`,`yarn.lock`,`yarn-error.log`,`.yarn`,`.pnp.cjs`,`.pnp.loader.mjs`,`tsconfig.tsbuildinfo`]),pI=[`dependencies`,`devDependencies`,`peerDependencies`,`optionalDependencies`]});function escapePackageName(n){return n.replace(`/`,`%2f`)}function buildPublishHeaders(n,a){let S=buildHeaders(n,{npmrc:a.npmrc});return S[`content-type`]=`application/json`,S[`npm-command`]=`publish`,S[`npm-auth-type`]=a.otp?`legacy`:`web`,S[`user-agent`]=a.userAgent??defaultUserAgent(),a.otp&&(S[`npm-otp`]=a.otp),a.authorization&&(S.authorization=a.authorization),S}function cliVersion(){return hI===void 0&&(hI=`0.35.0`),hI}function defaultUserAgent(){let n=globalThis.process,a=n?.arch??`x64`,S=n?.platform??`linux`;return`gjsify-publish/${cliVersion()} (${S} ${a})`}var hI,gI=__esmMin(()=>{Dl(),ks(),fP()});function decodeJwtPayload(n){let a=n.split(`.`);if(a.length!==3)return null;try{let n=a[1].replace(/-/g,`+`).replace(/_/g,`/`),S=typeof atob==`function`?atob(n):Buffer.from(n,`base64`).toString(`binary`);return JSON.parse(S)}catch{return null}}function hasGithubOidcEnv(){return!!(process.env.ACTIONS_ID_TOKEN_REQUEST_URL&&process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN)}async function fetchGithubOidcToken(n,a){let S=process.env.ACTIONS_ID_TOKEN_REQUEST_URL,C=process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN;if(!S||!C)throw new OidcUnavailableError("GitHub Actions OIDC env vars (ACTIONS_ID_TOKEN_REQUEST_{URL,TOKEN}) not set. The calling workflow needs `permissions: id-token: write`.",`no-env`);let N=`${S}${S.includes(`?`)?`&`:`?`}audience=${encodeURIComponent(n)}`;a?.(`gjsify oidc: GET ${N.replace(C,`<bearer>`)}`);let F=await fetch(N,{method:`GET`,headers:{Accept:`application/json`,Authorization:`Bearer ${C}`}});if(!F.ok){let n=await F.text().catch(()=>`<no body>`);throw new OidcUnavailableError(`Failed to fetch GitHub OIDC id_token: ${F.status} ${F.statusText} — ${n.slice(0,200)}`,`fetch-id-token`)}let I=await F.json().catch(()=>({}));if(!I.value)throw new OidcUnavailableError("GitHub OIDC response missing `value` field",`no-id-token`);return I.value}async function exchangeOidcForNpmToken(n){let{packageName:a,registry:S,idToken:C,log:N}=n,F=`${S.endsWith(`/`)?S.slice(0,-1):S}/-/npm/v1/oidc/token/exchange/package/${a.startsWith(`@`)?(()=>{let n=a.indexOf(`/`),S=a.slice(1,n),C=a.slice(n+1);return`@${encodeURIComponent(S)}%2f${encodeURIComponent(C)}`})():encodeURIComponent(a)}`;N?.(`gjsify oidc: POST ${F}`);let I=n.maxRetries??3,H=n.retryBaseMs??1e3;for(let n=0;;n++){let S;try{S=await fetch(F,{method:`POST`,headers:{Authorization:`Bearer ${C}`,"Content-Type":`application/json`,Accept:`application/json`},body:`{}`})}catch(S){if(n<I){let S=Math.min(H*2**n,8e3);N?.(`gjsify oidc: network error for ${a} (attempt ${n+1}/${I+1}), retrying in ${S}ms`),await sleep(S);continue}throw new OidcExchangeError(`npm OIDC token exchange network error for ${a} after ${n+1} attempt(s): ${S instanceof Error?S.message:String(S)}`,0,``,a,decodeJwtPayload(C)??void 0)}let W=await S.text().catch(()=>``);if(!S.ok){if(_I.has(S.status)&&n<I){let C=Math.min(H*2**n,8e3);N?.(`gjsify oidc: transient ${S.status} ${S.statusText} for ${a} (attempt ${n+1}/${I+1}), retrying in ${C}ms`),await sleep(C);continue}throw new OidcExchangeError(`npm OIDC token exchange failed for ${a}: ${S.status} ${S.statusText} — ${W.slice(0,300)}`,S.status,W,a,decodeJwtPayload(C)??void 0)}let K;try{K=JSON.parse(W)}catch{throw new OidcExchangeError(`npm OIDC token exchange returned non-JSON body for ${a}: ${W.slice(0,200)}`,S.status,W,a)}if(!K.token)throw new OidcExchangeError(`npm OIDC token exchange returned no \`token\` field for ${a}`,S.status,W,a);return K.token}}async function getNpmTrustedToken(n){let a=`npm:${new URL(n.registry).hostname}`,S=await fetchGithubOidcToken(a,n.log);return{token:await exchangeOidcForNpmToken({...n,idToken:S}),audience:a}}var _I,sleep,OidcUnavailableError,OidcExchangeError,vI=__esmMin(()=>{_I=new Set([408,425,429,500,502,503,504]),sleep=n=>new Promise(a=>setTimeout(a,n)),OidcUnavailableError=class extends Error{reason;constructor(n,a){super(n),this.reason=a,this.name=`OidcUnavailableError`}},OidcExchangeError=class extends Error{status;body;packageName;claims;constructor(n,a,S,C,N){super(n),this.status=a,this.body=S,this.packageName=C,this.claims=N,this.name=`OidcExchangeError`}}});async function diagnose404(n){let{packageName:a,version:S,registry:C,npmrc:N}=n,F={};try{F=await whoami(C,N)}catch{return{reason:`unknown`,message:formatUnknown(a,S)}}return F.username&&F.username.length>0?{reason:`live-token-404`,username:F.username,message:formatLiveToken404(a,S,F.username)}:{reason:`dead-token`,message:formatDeadToken(a,S)}}function formatDeadToken(n,a){return[`gjsify publish: ${n}@${a} — 404 Not Found`,``,`The npm token in ~/.npmrc appears to be revoked or expired (the /-/whoami probe`,`returned {} instead of {"username": "..."}). The 404 is npm's response to a PUT`,`authenticated with an invalid bearer token.`,``,`To refresh:`,` npm login`,` # or, future: gjsify login (tracked as project_gjsify_login_goal)`,``,`Then verify before publishing:`,` curl -s -H "Authorization: Bearer $(grep registry.npmjs.org ~/.npmrc | sed 's|.*=||')" \\`,` https://registry.npmjs.org/-/whoami`,` # Healthy: {"username":"<you>"}`,` # Dead: {}`].join(`
|
|
926
926
|
`)}function formatLiveToken404(n,a,S){return[`gjsify publish: ${n}@${a} — 404 Not Found`,``,`Authenticated as: ${S}`,``,`Your token authenticates, so this is NOT a dead-token problem. The package`,`${n} is not (yet) on npmjs.com. Two cases:`,``,` 1. First publish of a brand-new scoped package — do the one-time bootstrap`,` (see AGENTS.md > "New @gjsify/* package: first-publish + Trusted`,` Publisher bootstrap"). The npm registry can also 404 *transiently*`,` while provisioning a brand-new package: simply re-run, or do the very`," first publish with `npm publish` (then configure the Trusted Publisher)."," 2. You lack publish access to the scope — verify with `npm access ls-packages`."].join(`
|
|
927
927
|
`)}function formatUnknown(n,a){return`gjsify publish: ${n}@${a} — 404 Not Found`}function is404DiagnosticCandidate(n){let a=n.trim();return!!(a.length===0||/^not found$/i.test(a)||/"error"\s*:\s*"Not Found"/i.test(a))}var yI=__esmMin(()=>{fP()});function isTtyStdin(){let n=process.stdin;return!!n.isTTY&&typeof n.setRawMode==`function`}function applyKey(n,a,S){return a===`\r`||a===`
|
|
928
928
|
`?{buf:n,echo:`
|
|
@@ -952,7 +952,7 @@ Select upgrades: comma- or space-separated indices, `+pL.bold+`a`+pL.reset+` for
|
|
|
952
952
|
`).map(n=>n.trim()).filter(Boolean)}var SL=__esmMin(()=>{Dl()});function classifyAndExpand(n,a){let S=a.map(n=>n.replace(/\\/g,`/`)).filter(n=>n.length>0);if(S.length===0)return{global:!1,reason:`empty-diff`,workspaces:[],runE2E:!1,runIntegration:!1,skipAll:!0};let C=[];for(let n of S)TL.some(a=>a.test(n))||C.push(n);if(C.length===0)return{global:!1,reason:`ignored-only`,workspaces:[],runE2E:!1,runIntegration:!1,skipAll:!0};for(let a of C)for(let S of wL)if(S.test(a))return{global:!0,reason:`global-trigger ${S.source} matched ${a}`,workspaces:n.map(n=>n.name),runE2E:!0,runIntegration:!0,skipAll:!1};let{matched:N,unmatched:F}=workspacesForChangedFiles(n,C),I=new Set(n.map(n=>n.name)),H=new Set,W=new Set,K=!1;for(let a of DL){let S=C.filter(n=>a.match.test(n));if(S.length!==0){for(let n of S)W.add(n);for(let S of a.seeds){if(!I.has(S))return{global:!0,reason:`script-coupling seed ${S} is not a workspace (${a.match.source} → ${a.why}); SCRIPT_COUPLINGS in commands/affected.ts is stale`,workspaces:n.map(n=>n.name),runE2E:!0,runIntegration:!0,skipAll:!1};H.add(S)}a.runE2E&&(K=!0)}}let q=F.filter(n=>!W.has(n));if(q.length>0)return{global:!0,reason:`unmatched files (${q.length}): ${q.slice(0,3).join(`, `)}${q.length>3?`…`:``}`,workspaces:n.map(n=>n.name),runE2E:!0,runIntegration:!0,skipAll:!1};for(let n of H)N.add(n);if(H.size===0&&C.every(n=>EL.some(a=>a.test(n)))&&N.size===1){let n=[...N][0],a=C.some(n=>n.startsWith(`tests/e2e/`)),S=C.some(n=>n.startsWith(`tests/integration/`));return{global:!1,reason:`test-only (${C.length} file(s) in ${n})`,workspaces:[n],runE2E:a,runIntegration:S||isIntegrationWorkspace(n),skipAll:!1}}let Y=affectedClosure(buildReverseDependencyGraph(n,{includeDev:!1}),[...N]),X=buildDependencyGraph(n,{includeDev:!0}),te=!1;for(let[n,a]of X.edges)if(isIntegrationWorkspace(n)){for(let S of a)if(Y.has(S)){Y.add(n),te=!0;break}}let ne=C.some(n=>n.startsWith(`tests/e2e/`))||K;return{global:!1,reason:`closure (${Y.size} ws from ${N.size} seed(s))`+(H.size>0?`, ${H.size} via script-coupling`:``),workspaces:[...Y].sort(),runE2E:ne,runIntegration:te,skipAll:!1}}function isIntegrationWorkspace(n){return n.startsWith(`@gjsify/integration-`)}function runGitDiff(n,a,S){let C=spawnSync(`git`,[`diff`,`--name-only`,`${a}...${S}`],{cwd:n,encoding:`utf8`});if(C.status!==0)throw process.stderr.write(`gjsify affected: git diff failed (${C.status}): ${C.stderr.trim()}\n`),process.exit(2),Error(`gjsify affected: git diff failed (${C.status})`);return C.stdout.split(`
|
|
953
953
|
`).filter(Boolean)}function emit(n,a){if(n===`json`){process.stdout.write(JSON.stringify(a)+`
|
|
954
954
|
`);return}if(n===`globs`){for(let n of a.workspaces)process.stdout.write(`${n}\n`);return}if(n===`github-actions`){let n=a.global?``:a.workspaces.map(n=>`--include ${assertShellSafeWorkspaceName(n)}`).join(` `),S=process.env.GITHUB_OUTPUT,C=[`skip-all=${a.skipAll}`,`global=${a.global}`,`include-args=${n}`,`run-integration=${a.runIntegration}`,`run-e2e=${a.runE2E}`,`reason=${a.reason}`];if(S)for(let n of C)appendFileSync(S,`${n}\n`);else for(let n of C)process.stdout.write(`${n}\n`);return}process.stdout.write(`affected:
|
|
955
|
-
`),process.stdout.write(` reason: ${a.reason}\n`),process.stdout.write(` global: ${a.global}\n`),process.stdout.write(` skip-all: ${a.skipAll}\n`),process.stdout.write(` run-integration: ${a.runIntegration}\n`),process.stdout.write(` run-e2e: ${a.runE2E}\n`),process.stdout.write(` workspaces (${a.workspaces.length}):\n`);for(let n of a.workspaces)process.stdout.write(` - ${n}\n`)}function assertShellSafeWorkspaceName(n){if(OL.test(n))return n;throw process.stderr.write(`gjsify affected: workspace name ${JSON.stringify(n)} is not shell-safe, so it cannot be emitted as an\n \`include-args\` token (the value is consumed by an UNQUOTED $INCLUDE_ARGS expansion — see the\n contract at the top of commands/affected.ts). Rename the workspace, or teach this command a\n transport the consumers can unquote. Refusing to emit a filter that would silently mis-match.\n`),process.exit(2),Error(`gjsify affected: unsafe workspace name ${n}`)}var CL,wL,TL,EL,DL,OL,kL=__esmMin(()=>{lh(),Dl(),SL(),Q_(),ev(),CL={command:`affected`,description:"Classify changed files against the workspace tree and print the set of workspaces affected (seeds + transitive dependents). Designed for CI to gate `gjsify foreach test --include …` so unrelated workspaces are not re-tested on every PR.",builder:n=>n.option(`base`,{description:"Diff base. Default: `origin/main`. Resolved via `git rev-parse`. On a PR set this to `${{ github.event.pull_request.base.sha }}`.",type:`string`}).option(`head`,{description:"Diff head. Default: `HEAD`.",type:`string`,default:`HEAD`}).option(`format`,{description:`Output shape.`,choices:[`text`,`json`,`globs`,`github-actions`],default:`text`}).option(`changed-from-stdin`,{description:"Skip `git diff`. Read a newline-separated list of repo-relative paths from stdin instead. Lets callers — tests, ad-hoc scripts — control the input exactly.",type:`boolean`,default:!1}).option(`cwd`,{description:"Workspace root. Default: discovered from `process.cwd()`.",type:`string`}),handler:async n=>{let a=n.cwd??findWorkspaceRoot(process.cwd())??process.cwd(),S=classifyAndExpand(discoverWorkspaces(a,{includeRoot:!0}),n[`changed-from-stdin`]?readStdinLines():runGitDiff(a,n.base??`origin/main`,n.head??`HEAD`));emit(n.format,S)}},wL=[/^packages\/infra\/workspace\//,/^packages\/infra\/cli\//,/^packages\/infra\/rolldown-plugin-gjsify\//,/^packages\/infra\/resolve-npm\//,/^packages\/gjs\/unit\//,/^\.github\/actions\//,/^gjsify-lock\.json$/,/^package\.json$/,/^tsconfig[^/]*\.json$/,/^\.github\/workflows\/main\.yml$/,/^scripts\/audit-runtimes\.mjs$/],TL=[/\.md$/i,/^refs\//,/^website\//,/^docs\//,/^\.github\/workflows\/(deploy-docs|commitlint|release|release-cut|audit-runtimes|prebuilds|node-gi|napi|cli-cross-platform|build-ci-image|cancel-pr-runs)\.yml$/,/^\.github\/prebuild-toolchain\//,/^scripts\/manifest-conformance\//,/^status\//,/^scripts\/generate-status\.mjs
|
|
955
|
+
`),process.stdout.write(` reason: ${a.reason}\n`),process.stdout.write(` global: ${a.global}\n`),process.stdout.write(` skip-all: ${a.skipAll}\n`),process.stdout.write(` run-integration: ${a.runIntegration}\n`),process.stdout.write(` run-e2e: ${a.runE2E}\n`),process.stdout.write(` workspaces (${a.workspaces.length}):\n`);for(let n of a.workspaces)process.stdout.write(` - ${n}\n`)}function assertShellSafeWorkspaceName(n){if(OL.test(n))return n;throw process.stderr.write(`gjsify affected: workspace name ${JSON.stringify(n)} is not shell-safe, so it cannot be emitted as an\n \`include-args\` token (the value is consumed by an UNQUOTED $INCLUDE_ARGS expansion — see the\n contract at the top of commands/affected.ts). Rename the workspace, or teach this command a\n transport the consumers can unquote. Refusing to emit a filter that would silently mis-match.\n`),process.exit(2),Error(`gjsify affected: unsafe workspace name ${n}`)}var CL,wL,TL,EL,DL,OL,kL=__esmMin(()=>{lh(),Dl(),SL(),Q_(),ev(),CL={command:`affected`,description:"Classify changed files against the workspace tree and print the set of workspaces affected (seeds + transitive dependents). Designed for CI to gate `gjsify foreach test --include …` so unrelated workspaces are not re-tested on every PR.",builder:n=>n.option(`base`,{description:"Diff base. Default: `origin/main`. Resolved via `git rev-parse`. On a PR set this to `${{ github.event.pull_request.base.sha }}`.",type:`string`}).option(`head`,{description:"Diff head. Default: `HEAD`.",type:`string`,default:`HEAD`}).option(`format`,{description:`Output shape.`,choices:[`text`,`json`,`globs`,`github-actions`],default:`text`}).option(`changed-from-stdin`,{description:"Skip `git diff`. Read a newline-separated list of repo-relative paths from stdin instead. Lets callers — tests, ad-hoc scripts — control the input exactly.",type:`boolean`,default:!1}).option(`cwd`,{description:"Workspace root. Default: discovered from `process.cwd()`.",type:`string`}),handler:async n=>{let a=n.cwd??findWorkspaceRoot(process.cwd())??process.cwd(),S=classifyAndExpand(discoverWorkspaces(a,{includeRoot:!0}),n[`changed-from-stdin`]?readStdinLines():runGitDiff(a,n.base??`origin/main`,n.head??`HEAD`));emit(n.format,S)}},wL=[/^packages\/infra\/workspace\//,/^packages\/infra\/cli\//,/^packages\/infra\/rolldown-plugin-gjsify\//,/^packages\/infra\/resolve-npm\//,/^packages\/gjs\/unit\//,/^\.github\/actions\//,/^gjsify-lock\.json$/,/^package\.json$/,/^tsconfig[^/]*\.json$/,/^\.github\/workflows\/main\.yml$/,/^scripts\/audit-runtimes\.mjs$/],TL=[/\.md$/i,/^refs\//,/^website\//,/^docs\//,/^\.github\/workflows\/(deploy-docs|commitlint|release|release-cut|audit-runtimes|prebuilds|node-gi|napi|cli-cross-platform|build-ci-image|cancel-pr-runs)\.yml$/,/^\.github\/prebuild-toolchain\//,/^scripts\/manifest-conformance\//,/^status\//,/^scripts\/generate-status\.mjs$/,/^packages\/node-gi\//,/^packages\/napi\//,/^flatpak\//,/^LICENSE/,/^\.gitignore$/,/^\.gjsify-[^/]*\.md$/,/^STATUS\.md$/,/^CHANGELOG\.md$/,/^AGENTS\.md$/,/^CLAUDE\.md$/,/^README\.md$/],EL=[/\.spec\.[mc]?[tj]sx?$/,/^tests\/(e2e|integration)\//],DL=[{match:/^\.githooks\//,seeds:[],runE2E:!0,why:`tests/e2e/git-hooks-cli-bundle-staleness drives .githooks/pre-commit`},{match:/^templates\//,seeds:[`@gjsify/create-app`],runE2E:!0,why:`@gjsify/create-app build → node scripts/process-template.mjs reads templates/`}],OL=/^[A-Za-z0-9@][A-Za-z0-9@._/-]*$/});function readPackage$2(n){try{return JSON.parse(readFileSync(vs(n,`package.json`),`utf8`))}catch{return{}}}function deriveAppId(n){return n?`org.gjsify.storybook.${n.replace(/^@/,``).replace(/[^a-zA-Z0-9]+/g,`.`).replace(/^\.+|\.+$/g,``)}`:`org.gjsify.Storybook`}function findStoryFiles(n){let a=[];if(!existsSync(n))return a;for(let S of readdirSync(n,{withFileTypes:!0})){if(S.name===`node_modules`||S.name.startsWith(`.`))continue;let C=vs(n,S.name);S.isDirectory()?a.push(...findStoryFiles(C)):/\.story\.(ts|js|mts|mjs)$/.test(S.name)&&a.push(C)}return a}function generateEntry$2(n,a,S){let C=n.map((n,a)=>`import * as m${a} from ${JSON.stringify(n)};`).join(`
|
|
956
956
|
`),N=n.map((n,a)=>`m${a}`).join(`, `),F=S?`\n title: ${JSON.stringify(S)},`:``;return`// Auto-generated by \`gjsify storybook\` — do not edit by hand.
|
|
957
957
|
import { collectStoryModules, runStorybook } from '@gjsify/storybook';
|
|
958
958
|
${C}
|
package/lib/commands/affected.js
CHANGED
|
@@ -247,7 +247,12 @@ const IGNORE = [
|
|
|
247
247
|
/^website\//,
|
|
248
248
|
/^docs\//,
|
|
249
249
|
...OTHER_WORKFLOW_INPUTS,
|
|
250
|
-
|
|
250
|
+
// `.githooks/` WAS here, and that is what let #1095 break its own guard. IGNORE
|
|
251
|
+
// is applied FIRST and wins over everything, so a hook change selected nothing,
|
|
252
|
+
// the e2e tier stayed off, the PR went green and `main` went red on the push
|
|
253
|
+
// run. It is a SCRIPT_COUPLING now instead: no seeds (there is no workspace to
|
|
254
|
+
// rebuild) but `runE2E`, because tests/e2e/git-hooks-cli-bundle-staleness is the
|
|
255
|
+
// only thing that exercises the hook at all.
|
|
251
256
|
// @gjsify/node-gi (the Node-native GObject-Introspection engine, Axis 5) is
|
|
252
257
|
// NOT a gjsify workspace member — the GJS-first install/foreach tooling can't
|
|
253
258
|
// build its node-gyp addon, so the main workflow neither builds nor tests it.
|
|
@@ -263,9 +268,12 @@ const IGNORE = [
|
|
|
263
268
|
// its files map to no workspace and force a conservative full run on every
|
|
264
269
|
// napi PR.
|
|
265
270
|
/^packages\/napi\//,
|
|
266
|
-
// Flatpak build/distribution tooling (SDK-extension manifest + metainfo).
|
|
267
|
-
//
|
|
268
|
-
// `tests/e2e
|
|
271
|
+
// Flatpak build/distribution tooling (SDK-extension manifest + metainfo). No
|
|
272
|
+
// package-test consumers; its own `tests/e2e/flatpak-sdk-extension` runs on
|
|
273
|
+
// `tests/e2e/**` / global triggers. This used to cite `.githooks/` as the
|
|
274
|
+
// precedent — that one has since moved to SCRIPT_COUPLINGS because ignoring it
|
|
275
|
+
// let a change walk past the suite guarding it, so the precedent is now the
|
|
276
|
+
// counter-example. Worth revisiting here for the same reason.
|
|
269
277
|
/^flatpak\//,
|
|
270
278
|
/^LICENSE/,
|
|
271
279
|
/^\.gitignore$/,
|
|
@@ -279,6 +287,25 @@ const IGNORE = [
|
|
|
279
287
|
/** Patterns that suggest a test-only change. */
|
|
280
288
|
const TEST_PATHS = [/\.spec\.[mc]?[tj]sx?$/, /^tests\/(e2e|integration)\//];
|
|
281
289
|
const SCRIPT_COUPLINGS = [
|
|
290
|
+
{
|
|
291
|
+
// `.githooks/pre-commit` is guarded by an e2e suite and reachable from no
|
|
292
|
+
// workspace at all — it is not source, not a dependency, and its consumer is
|
|
293
|
+
// git. So a change to it selected NOTHING, the e2e tier stayed off (it turns
|
|
294
|
+
// on for a `tests/e2e/**` touch), and the PR went green while breaking the
|
|
295
|
+
// very test written to hold the hook: #1095 edited the hook's command line,
|
|
296
|
+
// merged clean, and turned `main` red on the push run.
|
|
297
|
+
//
|
|
298
|
+
// The same shape #1028 left a note about — whoever changes the GUARDED thing
|
|
299
|
+
// walks past the guard — and the reason it repeats is that the guard's
|
|
300
|
+
// trigger names the TEST's path instead of the thing under test.
|
|
301
|
+
//
|
|
302
|
+
// No extra seeds: there is no workspace to rebuild. The whole point is the
|
|
303
|
+
// tier.
|
|
304
|
+
match: /^\.githooks\//,
|
|
305
|
+
seeds: [],
|
|
306
|
+
runE2E: true,
|
|
307
|
+
why: 'tests/e2e/git-hooks-cli-bundle-staleness drives .githooks/pre-commit',
|
|
308
|
+
},
|
|
282
309
|
{
|
|
283
310
|
// `templates/*` ARE workspaces (root `package.json#workspaces` carries
|
|
284
311
|
// a `templates/*` glob), so a template change already seeds its own
|
package/lib/commands/foreach.js
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
import { spawnToCompletion } from '../utils/spawn.js';
|
|
12
12
|
import { readFileSync, readdirSync } from 'node:fs';
|
|
13
13
|
import { cpus } from 'node:os';
|
|
14
|
-
import { buildDependencyGraph, discoverWorkspaces, filterWorkspaces, topologicalSort, } from '@gjsify/workspace';
|
|
14
|
+
import { affectedClosure, buildDependencyGraph, discoverWorkspaces, filterWorkspaces, topologicalSort, } from '@gjsify/workspace';
|
|
15
15
|
import { findWorkspaceRoot } from '../utils/workspace-root.js';
|
|
16
16
|
import { prefixLines } from '../utils/prefixed-output.js';
|
|
17
17
|
import { BuildCacheRunner, buildCacheEnabledByEnv } from '../utils/build-cache.js';
|
|
@@ -218,6 +218,12 @@ export const foreachCommand = {
|
|
|
218
218
|
description: 'Glob pattern to exclude workspaces by name (repeatable).',
|
|
219
219
|
type: 'string',
|
|
220
220
|
array: true,
|
|
221
|
+
})
|
|
222
|
+
.option('with-dependencies', {
|
|
223
|
+
description: "Also select everything the filtered set DEPENDS ON (production deps; add --topological-dev for devDependencies). --include only filters and --topological only orders, so neither can say 'and the packages these need'. Excludes are re-applied afterwards.",
|
|
224
|
+
type: 'boolean',
|
|
225
|
+
alias: 'd',
|
|
226
|
+
default: false,
|
|
221
227
|
})
|
|
222
228
|
.option('private', {
|
|
223
229
|
// Yargs auto-negates `--no-private` to `private=false`, so the
|
|
@@ -305,6 +311,29 @@ export const foreachCommand = {
|
|
|
305
311
|
exclude: args.exclude,
|
|
306
312
|
noPrivate: args.private === false,
|
|
307
313
|
});
|
|
314
|
+
// `--with-dependencies` — the third thing a selection can mean, and the
|
|
315
|
+
// one that had no spelling. `--include` FILTERS and `--topological` only
|
|
316
|
+
// ORDERS what was already selected, so "and everything these need" was
|
|
317
|
+
// inexpressible, and CI's selective build simply assumed every
|
|
318
|
+
// dependency's restored `lib/` was current. A build cache can be
|
|
319
|
+
// complete without being current: caches are branch-scoped, so ONE
|
|
320
|
+
// cancelled build on `main` left later PRs compiling against pre-merge
|
|
321
|
+
// outputs, failing with compiler errors that named a package the PR
|
|
322
|
+
// never touched (#1080). No warmth probe can see that — a stale archive
|
|
323
|
+
// is perfectly complete — so freshness has to come from the selection.
|
|
324
|
+
//
|
|
325
|
+
// AFTER the filter, not before: expanding the unfiltered set would walk
|
|
326
|
+
// out through the very packages the caller excluded (CI excludes
|
|
327
|
+
// `@gjsify/website`, which prod-depends every showcase — expanding first
|
|
328
|
+
// pulled in 56 extra packages and undid selective CI). Excludes are then
|
|
329
|
+
// re-applied, because a dependency may be something the caller took out
|
|
330
|
+
// on purpose and expansion must not smuggle it back in.
|
|
331
|
+
if (args['with-dependencies'] === true) {
|
|
332
|
+
const includeDev = args['topological-dev'] === true;
|
|
333
|
+
const forward = buildDependencyGraph(allWorkspaces, { includeDev });
|
|
334
|
+
const closure = affectedClosure(forward, selected.map((ws) => ws.name));
|
|
335
|
+
selected = filterWorkspaces(allWorkspaces.filter((ws) => closure.has(ws.name)), { exclude: args.exclude, noPrivate: args.private === false });
|
|
336
|
+
}
|
|
308
337
|
// In script mode, only run on workspaces that actually have the
|
|
309
338
|
// requested script — yarn does this too, otherwise every project
|
|
310
339
|
// that doesn't declare `<script>` would fail and force the user to
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gjsify/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.35.0",
|
|
4
4
|
"description": "CLI for Gjsify",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -134,19 +134,19 @@
|
|
|
134
134
|
"cli"
|
|
135
135
|
],
|
|
136
136
|
"dependencies": {
|
|
137
|
-
"@gjsify/buffer": "^0.
|
|
138
|
-
"@gjsify/create-app": "^0.
|
|
139
|
-
"@gjsify/node-globals": "^0.
|
|
140
|
-
"@gjsify/node-polyfills": "^0.
|
|
141
|
-
"@gjsify/npm-registry": "^0.
|
|
142
|
-
"@gjsify/resolve-npm": "^0.
|
|
143
|
-
"@gjsify/rolldown-plugin-gjsify": "^0.
|
|
144
|
-
"@gjsify/rolldown-plugin-pnp": "^0.
|
|
145
|
-
"@gjsify/semver": "^0.
|
|
146
|
-
"@gjsify/tar": "^0.
|
|
147
|
-
"@gjsify/tsc": "^0.
|
|
148
|
-
"@gjsify/web-polyfills": "^0.
|
|
149
|
-
"@gjsify/workspace": "^0.
|
|
137
|
+
"@gjsify/buffer": "^0.35.0",
|
|
138
|
+
"@gjsify/create-app": "^0.35.0",
|
|
139
|
+
"@gjsify/node-globals": "^0.35.0",
|
|
140
|
+
"@gjsify/node-polyfills": "^0.35.0",
|
|
141
|
+
"@gjsify/npm-registry": "^0.35.0",
|
|
142
|
+
"@gjsify/resolve-npm": "^0.35.0",
|
|
143
|
+
"@gjsify/rolldown-plugin-gjsify": "^0.35.0",
|
|
144
|
+
"@gjsify/rolldown-plugin-pnp": "^0.35.0",
|
|
145
|
+
"@gjsify/semver": "^0.35.0",
|
|
146
|
+
"@gjsify/tar": "^0.35.0",
|
|
147
|
+
"@gjsify/tsc": "^0.35.0",
|
|
148
|
+
"@gjsify/web-polyfills": "^0.35.0",
|
|
149
|
+
"@gjsify/workspace": "^0.35.0",
|
|
150
150
|
"cosmiconfig": "^9.0.2",
|
|
151
151
|
"get-tsconfig": "^4.14.0",
|
|
152
152
|
"pkg-types": "^2.3.1",
|
|
@@ -154,13 +154,13 @@
|
|
|
154
154
|
"yargs": "^18.0.0"
|
|
155
155
|
},
|
|
156
156
|
"devDependencies": {
|
|
157
|
-
"@gjsify/unit": "^0.
|
|
157
|
+
"@gjsify/unit": "^0.35.0",
|
|
158
158
|
"@types/yargs": "^17.0.35",
|
|
159
159
|
"typescript": "^6.0.3"
|
|
160
160
|
},
|
|
161
161
|
"peerDependencies": {
|
|
162
|
-
"@gjsify/oxfmt-native": "^0.
|
|
163
|
-
"@gjsify/rolldown-native": "^0.
|
|
162
|
+
"@gjsify/oxfmt-native": "^0.35.0",
|
|
163
|
+
"@gjsify/rolldown-native": "^0.35.0"
|
|
164
164
|
},
|
|
165
165
|
"peerDependenciesMeta": {
|
|
166
166
|
"@gjsify/oxfmt-native": {
|