@gjsify/cli 0.29.0 → 0.30.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 +20 -13
- package/lib/config.js +1 -1
- package/lib/utils/bin-shim.d.ts +39 -0
- package/lib/utils/bin-shim.js +89 -13
- package/lib/utils/check-system-deps.d.ts +22 -0
- package/lib/utils/check-system-deps.js +38 -4
- package/lib/utils/dlx-cache.js +1 -1
- package/lib/utils/install-backend-native.d.ts +8 -0
- package/lib/utils/install-backend-native.js +8 -2
- package/lib/utils/install-global.js +13 -1
- package/lib/utils/run-lifecycle-script.js +41 -25
- package/lib/utils/spawn.d.ts +17 -1
- package/lib/utils/spawn.js +23 -6
- package/package.json +17 -17
package/dist/cli.gjs.mjs
CHANGED
|
@@ -768,7 +768,7 @@ Add @gjsify/node-gi as a dependency to run the storybook on Node, e.g.:
|
|
|
768
768
|
`)[0]??n)),n}function checkGwebgl(n){return checkNpmPackage(`gwebgl`,`gwebgl (@gjsify/webgl)`,`@gjsify/webgl`,n,`optional`,[`@gjsify/webgl`])}function runRequiredChecks(n){let a=[];return a.push(checkBinary(`blueprint-compiler`,`Blueprint Compiler`,`blueprint-compiler`,[`--version`],`required`)),a.push(checkBinary(`pkg-config`,`pkg-config`,`pkg-config`,[`--version`],`required`)),a.push(checkBinary(`meson`,`Meson`,`meson`,[`--version`],`required`)),a.push(checkPkgConfig(`gtk4`,`GTK4`,`gtk4`,`required`)),a.push(checkPkgConfig(`libadwaita`,`libadwaita`,`libadwaita-1`,`required`)),a.push(checkPkgConfig(`libsoup3`,`libsoup3`,`libsoup-3.0`,`required`)),a.push(checkPkgConfig(`gobject-introspection`,`GObject Introspection`,`gobject-introspection-1.0`,`required`)),a}function runNativeBuildToolchainChecks(){let n=[`@gjsify/http-soup-bridge`,`@gjsify/http2-native`,`@gjsify/lightningcss-native`,`@gjsify/oxfmt-native`,`@gjsify/rolldown-native`,`@gjsify/sab-native`,`@gjsify/terminal-native`,`@gjsify/tls-native`,`@gjsify/webgl`,`@gjsify/webrtc-native`];return[checkBinary(`ninja`,`Ninja`,`ninja`,[`--version`],`optional`,void 0,n),checkBinary(`vala`,`Vala`,`valac`,[`--version`],`optional`,n=>n.replace(/^Vala\s+/i,``),n),checkBinary(`cargo`,`Cargo (Rust)`,`cargo`,[`--version`],`optional`,n=>n.replace(/^cargo\s+/i,``).split(` `)[0]??n,[`@gjsify/lightningcss-native`,`@gjsify/oxfmt-native`,`@gjsify/rolldown-native`])]}function runOptionalChecks(n,a){let S=[];for(let[a,C]of Object.entries(BM)){if(n!==null&&!n.has(a))continue;let N=Object.entries(VM).filter(([,n])=>n.includes(a)).map(([n])=>n);S.push(checkPkgConfig(C.id,C.name,C.pkgName,`optional`,N))}return(n===null||n.has(`gwebgl`))&&S.push(checkGwebgl(a)),S}function buildInstallCommand(n,a){if(n===`unknown`)return null;let S=HM[n],C=[],N=[];for(let n of a){if(n.id===`gwebgl`){N.push(`@gjsify/webgl`);continue}if(n.id===`nodejs`)continue;let a=S[n.id];a&&C.push(a)}let F=[];return C.length>0&&F.push(`${UM[n]} ${C.join(` `)}`),N.length>0&&F.push(`npm install ${N.join(` `)}`),F.length>0?F.join(`
|
|
769
769
|
`):null}function readGirsLibraryVersion(n,a){for(let S of[pathToFileURL(_s(n,`_girs_.js`)).href,import.meta.url]){let n;try{n=bs(createRequire(S).resolve(a))}catch{continue}for(let S=0;S<5;S++){let S=_s(n,`package.json`);if(existsSync(S))try{let n=JSON.parse(readFileSync(S,`utf-8`));if(n.name===a)return n.libraryVersion??null}catch{return null}let C=bs(n);if(C===n)break;n=C}}return null}function majorMinor(n){let a=/^(\d+)\.(\d+)/.exec(n.trim());return a?[Number(a[1]),Number(a[2])]:null}function isDegenerate(n,a){let S=n.trim(),C=a.split(`.`);for(let n=C.length;n<=3;n++)if(S===[...C,...Array(n-C.length).fill(`0`)].join(`.`))return!0;return!1}function checkTypeSkew(n,a={}){let S=a.readDeclared??readGirsLibraryVersion,C=a.readInstalled??(n=>tryExecFile(`pkg-config`,[`--modversion`,n])),N=[];for(let a of WM){let F=S(n,a.typePackage);if(F===null||isDegenerate(F,a.namespaceVersion))continue;let I=C(a.pkgConfig);if(I===null)continue;let H=majorMinor(F),W=majorMinor(I.split(`
|
|
770
770
|
`)[0]??I);!H||!W||H[0]===W[0]&&H[1]===W[1]||N.push({typePackage:a.typePackage,pkgConfig:a.pkgConfig,declared:F,installed:I.split(`
|
|
771
|
-
`)[0]??I,relation:H[0]>W[0]||H[0]===W[0]&&H[1]>W[1]?`ahead`:`behind`})}return N}var BM,VM,HM,UM,WM,GM=__esmMin(()=>{Xm(),Os(),is(),rn(),gl(),__name$1(detectPackageManager$2,`detectPackageManager`),BM={manette:{id:`manette`,name:`libmanette`,pkgName:`manette-0.2`},gstreamer:{id:`gstreamer`,name:`GStreamer`,pkgName:`gstreamer-1.0`},"gst-app":{id:`gst-app`,name:`GStreamer App`,pkgName:`gstreamer-app-1.0`},"gdk-pixbuf":{id:`gdk-pixbuf`,name:`GdkPixbuf`,pkgName:`gdk-pixbuf-2.0`},pango:{id:`pango`,name:`Pango`,pkgName:`pango`},pangocairo:{id:`pangocairo`,name:`PangoCairo`,pkgName:`pangocairo`},webkitgtk:{id:`webkitgtk`,name:`WebKitGTK`,pkgName:`webkitgtk-6.0`},cairo:{id:`cairo`,name:`Cairo`,pkgName:`cairo`},gnutls:{id:`gnutls`,name:`GnuTLS`,pkgName:`gnutls`},nghttp2:{id:`nghttp2`,name:`libnghttp2`,pkgName:`libnghttp2`}},VM={"@gjsify/gamepad":[`manette`],"@gjsify/webaudio":[`gstreamer`,`gst-app`],"@gjsify/iframe":[`webkitgtk`],"@gjsify/canvas2d":[`gdk-pixbuf`,`pango`,`pangocairo`,`cairo`],"@gjsify/canvas2d-core":[`gdk-pixbuf`,`pango`,`pangocairo`,`cairo`],"@gjsify/dom-elements":[`gdk-pixbuf`],"@gjsify/webgl":[`gwebgl`],"@gjsify/tls-native":[`gnutls`],"@gjsify/http2-native":[`nghttp2`]},HM={apt:{gjs:`gjs`,"blueprint-compiler":`blueprint-compiler`,"pkg-config":`pkg-config`,meson:`meson`,ninja:`ninja-build`,vala:`valac`,cargo:`cargo`,gtk4:`libgtk-4-dev`,libadwaita:`libadwaita-1-dev`,libsoup3:`libsoup-3.0-dev`,webkitgtk:`libwebkit2gtk-6.0-dev`,"gobject-introspection":`gobject-introspection libgirepository1.0-dev`,manette:`libmanette-0.2-0 gir1.2-manette-0.2`,gstreamer:`libgstreamer1.0-dev`,"gst-app":`libgstreamer-plugins-base1.0-dev gir1.2-gst-plugins-base-1.0`,"gdk-pixbuf":`libgdk-pixbuf-2.0-dev`,pango:`libpango1.0-dev`,pangocairo:`libpango1.0-dev`,cairo:`libcairo2-dev`,gnutls:`libgnutls28-dev`,nghttp2:`libnghttp2-dev`},dnf:{gjs:`gjs`,"blueprint-compiler":`blueprint-compiler`,"pkg-config":`pkgconf-pkg-config`,meson:`meson`,ninja:`ninja-build`,vala:`vala`,cargo:`cargo`,gtk4:`gtk4-devel`,libadwaita:`libadwaita-devel`,libsoup3:`libsoup3-devel`,webkitgtk:`webkitgtk6.0-devel`,"gobject-introspection":`gobject-introspection-devel`,manette:`libmanette-devel`,gstreamer:`gstreamer1-devel`,"gst-app":`gstreamer1-plugins-base-devel`,"gdk-pixbuf":`gdk-pixbuf2-devel`,pango:`pango-devel`,pangocairo:`pango-devel`,cairo:`cairo-devel`,gnutls:`gnutls-devel`,nghttp2:`libnghttp2-devel`},pacman:{gjs:`gjs`,"blueprint-compiler":`blueprint-compiler`,"pkg-config":`pkgconf`,meson:`meson`,ninja:`ninja`,vala:`vala`,cargo:`rust`,gtk4:`gtk4`,libadwaita:`libadwaita`,libsoup3:`libsoup3`,webkitgtk:`webkitgtk-6.0`,"gobject-introspection":`gobject-introspection`,manette:`libmanette`,gstreamer:`gstreamer`,"gst-app":`gst-plugins-base`,"gdk-pixbuf":`gdk-pixbuf2`,pango:`pango`,pangocairo:`pango`,cairo:`cairo`,gnutls:`gnutls`,nghttp2:`libnghttp2`},zypper:{gjs:`gjs`,"blueprint-compiler":`blueprint-compiler`,"pkg-config":`pkg-config`,meson:`meson`,ninja:`ninja`,vala:`vala`,cargo:`cargo`,gtk4:`gtk4-devel`,libadwaita:`libadwaita-devel`,libsoup3:`libsoup-3_0-devel`,webkitgtk:`webkitgtk6_0-devel`,"gobject-introspection":`gobject-introspection-devel`,manette:`libmanette-0_2-0-devel`,gstreamer:`gstreamer-devel`,"gst-app":`gstreamer-plugins-base-devel`,"gdk-pixbuf":`gdk-pixbuf-devel`,pango:`pango-devel`,pangocairo:`pango-devel`,cairo:`cairo-devel`,gnutls:`libgnutls-devel`,nghttp2:`libnghttp2-devel`},apk:{gjs:`gjs`,"blueprint-compiler":`blueprint-compiler`,"pkg-config":`pkgconf`,meson:`meson`,ninja:`ninja`,vala:`vala`,cargo:`cargo`,gtk4:`gtk4.0-dev`,libadwaita:`libadwaita-dev`,libsoup3:`libsoup3-dev`,webkitgtk:`webkit2gtk-6.0-dev`,"gobject-introspection":`gobject-introspection-dev`,manette:`libmanette-dev`,gstreamer:`gstreamer-dev`,"gst-app":`gst-plugins-base-dev`,"gdk-pixbuf":`gdk-pixbuf-dev`,pango:`pango-dev`,pangocairo:`pango-dev`,cairo:`cairo-dev`,gnutls:`gnutls-dev`,nghttp2:`nghttp2-dev`},brew:{gjs:`gjs`,"blueprint-compiler":`blueprint-compiler`,"pkg-config":`pkgconf`,meson:`meson`,ninja:`ninja`,vala:`vala`,cargo:`rust`,gtk4:`gtk4`,libadwaita:`libadwaita`,libsoup3:`libsoup`,"gobject-introspection":`gobject-introspection`,gstreamer:`gstreamer`,"gst-app":`gst-plugins-base`,"gdk-pixbuf":`gdk-pixbuf`,pango:`pango`,pangocairo:`pango`,cairo:`cairo`,gnutls:`gnutls`,nghttp2:`nghttp2`},unknown:{}},UM={apt:`sudo apt install`,dnf:`sudo dnf install`,pacman:`sudo pacman -S`,zypper:`sudo zypper install`,apk:`sudo apk add`,brew:`brew install`,unknown:``},WM=[{pkgConfig:`gtk4`,typePackage:`@girs/gtk-4.0`,namespaceVersion:`4.0`},{pkgConfig:`libadwaita-1`,typePackage:`@girs/adw-1`,namespaceVersion:`1`},{pkgConfig:`libsoup-3.0`,typePackage:`@girs/soup-3.0`,namespaceVersion:`3.0`},{pkgConfig:`glib-2.0`,typePackage:`@girs/glib-2.0`,namespaceVersion:`2.0`},{pkgConfig:`gobject-2.0`,typePackage:`@girs/gobject-2.0`,namespaceVersion:`2.0`},{pkgConfig:`gio-2.0`,typePackage:`@girs/gio-2.0`,namespaceVersion:`2.0`},{pkgConfig:`gstreamer-1.0`,typePackage:`@girs/gst-1.0`,namespaceVersion:`1.0`},{pkgConfig:`webkitgtk-6.0`,typePackage:`@girs/webkit-6.0`,namespaceVersion:`6.0`},{pkgConfig:`manette-0.2`,typePackage:`@girs/manette-0.2`,namespaceVersion:`0.2`},{pkgConfig:`pango`,typePackage:`@girs/pango-1.0`,namespaceVersion:`1.0`},{pkgConfig:`harfbuzz`,typePackage:`@girs/harfbuzz-0.0`,namespaceVersion:`0.0`}]}),KM,qM=__esmMin(()=>{_e(),GM(),KM={command:`system-check`,description:"Check that required system dependencies (GJS, GTK4, libsoup3, …) are installed. Optional dependencies are detected only when their @gjsify/* package is in your project. (Previously called `gjsify check`; the bare name now runs TypeScript checks across the workspace — see `gjsify check --help`.)",builder:n=>n.option(`json`,{description:`Output results as JSON`,type:`boolean`,default:!1}),handler:async n=>{let a=runAllChecks(process.cwd()),S=detectPackageManager$2(),C=checkTypeSkew(process.cwd()),N=a.filter(n=>!n.found&&n.severity===`required`),F=a.filter(n=>!n.found&&n.severity===`optional`),I=[...N,...F];if(n.json)return ge.log(JSON.stringify({packageManager:S,deps:a,typeSkew:C},null,2)),process.exit(+(N.length>0));ge.log(`System dependency check
|
|
771
|
+
`)[0]??I,relation:H[0]>W[0]||H[0]===W[0]&&H[1]>W[1]?`ahead`:`behind`})}return N}var BM,VM,HM,UM,WM,GM=__esmMin(()=>{Xm(),Os(),is(),rn(),gl(),__name$1(detectPackageManager$2,`detectPackageManager`),BM={manette:{id:`manette`,name:`libmanette`,pkgName:`manette-0.2`},gstreamer:{id:`gstreamer`,name:`GStreamer`,pkgName:`gstreamer-1.0`},"gst-app":{id:`gst-app`,name:`GStreamer App`,pkgName:`gstreamer-app-1.0`},"gdk-pixbuf":{id:`gdk-pixbuf`,name:`GdkPixbuf`,pkgName:`gdk-pixbuf-2.0`},pango:{id:`pango`,name:`Pango`,pkgName:`pango`},pangocairo:{id:`pangocairo`,name:`PangoCairo`,pkgName:`pangocairo`},webkitgtk:{id:`webkitgtk`,name:`WebKitGTK`,pkgName:`webkitgtk-6.0`},cairo:{id:`cairo`,name:`Cairo`,pkgName:`cairo`},gnutls:{id:`gnutls`,name:`GnuTLS`,pkgName:`gnutls`},nghttp2:{id:`nghttp2`,name:`libnghttp2`,pkgName:`libnghttp2`},"json-glib":{id:`json-glib`,name:`JSON-GLib`,pkgName:`json-glib-1.0`},epoxy:{id:`epoxy`,name:`libepoxy`,pkgName:`epoxy`},"gst-webrtc":{id:`gst-webrtc`,name:`GStreamer WebRTC`,pkgName:`gstreamer-webrtc-1.0`}},VM={"@gjsify/gamepad":[`manette`],"@gjsify/webaudio":[`gstreamer`,`gst-app`],"@gjsify/iframe":[`webkitgtk`],"@gjsify/canvas2d":[`gdk-pixbuf`,`pango`,`pangocairo`,`cairo`],"@gjsify/canvas2d-core":[`gdk-pixbuf`,`pango`,`pangocairo`,`cairo`],"@gjsify/dom-elements":[`gdk-pixbuf`],"@gjsify/webgl":[`gwebgl`,`gdk-pixbuf`,`epoxy`],"@gjsify/tls-native":[`gnutls`],"@gjsify/http2-native":[`nghttp2`],"@gjsify/rolldown-native":[`json-glib`],"@gjsify/webrtc-native":[`gstreamer`,`gst-webrtc`]},HM={apt:{gjs:`gjs`,"blueprint-compiler":`blueprint-compiler`,"pkg-config":`pkg-config`,meson:`meson`,ninja:`ninja-build`,vala:`valac`,cargo:`cargo`,gtk4:`libgtk-4-dev`,libadwaita:`libadwaita-1-dev`,libsoup3:`libsoup-3.0-dev`,webkitgtk:`libwebkit2gtk-6.0-dev`,"gobject-introspection":`gobject-introspection libgirepository1.0-dev`,manette:`libmanette-0.2-0 gir1.2-manette-0.2`,gstreamer:`libgstreamer1.0-dev`,"gst-app":`libgstreamer-plugins-base1.0-dev gir1.2-gst-plugins-base-1.0`,"gdk-pixbuf":`libgdk-pixbuf-2.0-dev`,pango:`libpango1.0-dev`,pangocairo:`libpango1.0-dev`,cairo:`libcairo2-dev`,gnutls:`libgnutls28-dev`,nghttp2:`libnghttp2-dev`,"json-glib":`libjson-glib-dev`,epoxy:`libepoxy-dev`},dnf:{gjs:`gjs`,"blueprint-compiler":`blueprint-compiler`,"pkg-config":`pkgconf-pkg-config`,meson:`meson`,ninja:`ninja-build`,vala:`vala`,cargo:`cargo`,gtk4:`gtk4-devel`,libadwaita:`libadwaita-devel`,libsoup3:`libsoup3-devel`,webkitgtk:`webkitgtk6.0-devel`,"gobject-introspection":`gobject-introspection-devel`,manette:`libmanette-devel`,gstreamer:`gstreamer1-devel`,"gst-app":`gstreamer1-plugins-base-devel`,"gdk-pixbuf":`gdk-pixbuf2-devel`,pango:`pango-devel`,pangocairo:`pango-devel`,cairo:`cairo-devel`,gnutls:`gnutls-devel`,nghttp2:`libnghttp2-devel`,"json-glib":`json-glib-devel`,epoxy:`libepoxy-devel`},pacman:{gjs:`gjs`,"blueprint-compiler":`blueprint-compiler`,"pkg-config":`pkgconf`,meson:`meson`,ninja:`ninja`,vala:`vala`,cargo:`rust`,gtk4:`gtk4`,libadwaita:`libadwaita`,libsoup3:`libsoup3`,webkitgtk:`webkitgtk-6.0`,"gobject-introspection":`gobject-introspection`,manette:`libmanette`,gstreamer:`gstreamer`,"gst-app":`gst-plugins-base`,"gdk-pixbuf":`gdk-pixbuf2`,pango:`pango`,pangocairo:`pango`,cairo:`cairo`,gnutls:`gnutls`,nghttp2:`libnghttp2`,"json-glib":`json-glib`,epoxy:`libepoxy`},zypper:{gjs:`gjs`,"blueprint-compiler":`blueprint-compiler`,"pkg-config":`pkg-config`,meson:`meson`,ninja:`ninja`,vala:`vala`,cargo:`cargo`,gtk4:`gtk4-devel`,libadwaita:`libadwaita-devel`,libsoup3:`libsoup-3_0-devel`,webkitgtk:`webkitgtk6_0-devel`,"gobject-introspection":`gobject-introspection-devel`,manette:`libmanette-0_2-0-devel`,gstreamer:`gstreamer-devel`,"gst-app":`gstreamer-plugins-base-devel`,"gdk-pixbuf":`gdk-pixbuf-devel`,pango:`pango-devel`,pangocairo:`pango-devel`,cairo:`cairo-devel`,gnutls:`libgnutls-devel`,nghttp2:`libnghttp2-devel`,"json-glib":`json-glib-devel`,epoxy:`libepoxy-devel`},apk:{gjs:`gjs`,"blueprint-compiler":`blueprint-compiler`,"pkg-config":`pkgconf`,meson:`meson`,ninja:`ninja`,vala:`vala`,cargo:`cargo`,gtk4:`gtk4.0-dev`,libadwaita:`libadwaita-dev`,libsoup3:`libsoup3-dev`,webkitgtk:`webkit2gtk-6.0-dev`,"gobject-introspection":`gobject-introspection-dev`,manette:`libmanette-dev`,gstreamer:`gstreamer-dev`,"gst-app":`gst-plugins-base-dev`,"gdk-pixbuf":`gdk-pixbuf-dev`,pango:`pango-dev`,pangocairo:`pango-dev`,cairo:`cairo-dev`,gnutls:`gnutls-dev`,nghttp2:`nghttp2-dev`,"json-glib":`json-glib-dev`,epoxy:`libepoxy-dev`},brew:{gjs:`gjs`,"blueprint-compiler":`blueprint-compiler`,"pkg-config":`pkgconf`,meson:`meson`,ninja:`ninja`,vala:`vala`,cargo:`rust`,gtk4:`gtk4`,libadwaita:`libadwaita`,libsoup3:`libsoup`,"gobject-introspection":`gobject-introspection`,gstreamer:`gstreamer`,"gst-app":`gst-plugins-base`,"gdk-pixbuf":`gdk-pixbuf`,pango:`pango`,pangocairo:`pango`,cairo:`cairo`,gnutls:`gnutls`,nghttp2:`nghttp2`,"json-glib":`json-glib`,epoxy:`libepoxy`},unknown:{}},UM={apt:`sudo apt install`,dnf:`sudo dnf install`,pacman:`sudo pacman -S`,zypper:`sudo zypper install`,apk:`sudo apk add`,brew:`brew install`,unknown:``},WM=[{pkgConfig:`gtk4`,typePackage:`@girs/gtk-4.0`,namespaceVersion:`4.0`},{pkgConfig:`libadwaita-1`,typePackage:`@girs/adw-1`,namespaceVersion:`1`},{pkgConfig:`libsoup-3.0`,typePackage:`@girs/soup-3.0`,namespaceVersion:`3.0`},{pkgConfig:`glib-2.0`,typePackage:`@girs/glib-2.0`,namespaceVersion:`2.0`},{pkgConfig:`gobject-2.0`,typePackage:`@girs/gobject-2.0`,namespaceVersion:`2.0`},{pkgConfig:`gio-2.0`,typePackage:`@girs/gio-2.0`,namespaceVersion:`2.0`},{pkgConfig:`gstreamer-1.0`,typePackage:`@girs/gst-1.0`,namespaceVersion:`1.0`},{pkgConfig:`webkitgtk-6.0`,typePackage:`@girs/webkit-6.0`,namespaceVersion:`6.0`},{pkgConfig:`manette-0.2`,typePackage:`@girs/manette-0.2`,namespaceVersion:`0.2`},{pkgConfig:`pango`,typePackage:`@girs/pango-1.0`,namespaceVersion:`1.0`},{pkgConfig:`harfbuzz`,typePackage:`@girs/harfbuzz-0.0`,namespaceVersion:`0.0`}]}),KM,qM=__esmMin(()=>{_e(),GM(),KM={command:`system-check`,description:"Check that required system dependencies (GJS, GTK4, libsoup3, …) are installed. Optional dependencies are detected only when their @gjsify/* package is in your project. (Previously called `gjsify check`; the bare name now runs TypeScript checks across the workspace — see `gjsify check --help`.)",builder:n=>n.option(`json`,{description:`Output results as JSON`,type:`boolean`,default:!1}),handler:async n=>{let a=runAllChecks(process.cwd()),S=detectPackageManager$2(),C=checkTypeSkew(process.cwd()),N=a.filter(n=>!n.found&&n.severity===`required`),F=a.filter(n=>!n.found&&n.severity===`optional`),I=[...N,...F];if(n.json)return ge.log(JSON.stringify({packageManager:S,deps:a,typeSkew:C},null,2)),process.exit(+(N.length>0));ge.log(`System dependency check
|
|
772
772
|
`);let H=a.filter(n=>n.severity===`required`),W=a.filter(n=>n.severity===`optional`);if(H.length>0){ge.log(`Required:`);for(let n of H){let a=n.found?`✓`:`✗`,S=n.version?` (${n.version})`:``;ge.log(` ${a} ${n.name}${S}`)}}if(W.length>0){ge.log(`
|
|
773
773
|
Optional:`);for(let n of W){let a=n.found?`✓`:`⚠`,S=n.version?` (${n.version})`:``,C=n.requiredBy&&n.requiredBy.length>0?` — needed by ${n.requiredBy.join(`, `)}`:``;ge.log(` ${a} ${n.name}${S}${C}`)}}if(C.length>0){ge.log(`
|
|
774
774
|
Type/runtime version skew:`);for(let n of C){let a=n.relation===`ahead`?`⚠`:`ℹ`;ge.log(` ${a} ${n.typePackage} describes ${n.declared}, installed ${n.pkgConfig} is ${n.installed}`)}C.some(n=>n.relation===`ahead`)&&ge.log(`
|
|
@@ -780,10 +780,10 @@ Type/runtime version skew:`);for(let n of C){let a=n.relation===`ahead`?`⚠`:`
|
|
|
780
780
|
All dependencies found.`);return}N.length>0&&ge.log(`\nMissing required: ${N.map(n=>n.name).join(`, `)}`),F.length>0&&ge.log(`Missing optional: ${F.map(n=>n.name).join(`, `)}`);let K=buildInstallCommand(S,I);K?ge.log(`\nTo install:\n ${K}`):ge.log(`
|
|
781
781
|
No install command available for your package manager. Install manually.`),process.exit(+(N.length>0))}}});function prefixLines(n,a,S,C){let N=``,F=``,emit=n=>{C?F+=n:a.write(n)};return n.setEncoding(`utf-8`),n.on(`data`,n=>{N+=n;let a;for(;(a=N.indexOf(`
|
|
782
782
|
`))!==-1;)emit(S+N.slice(0,a+1)),N=N.slice(a+1)}),n.on(`end`,()=>{N.length>0&&emit(S+N+`
|
|
783
|
-
`)}),()=>{F.length>0&&(a.write(F),F=``)}}var JM=__esmMin(()=>{});function lookupEnv(n,a){let S=a.toLowerCase();for(let a of Object.keys(n))if(a.toLowerCase()===S&&n[a]!==void 0)return n[a]}function escapeCmdCommand(n){return n.replace(QM,`^$1`)}function escapeCmdArgument(n,a=!1){let S=`${n}`;return S=S.replace(/(?=(\\+?)?)\1"/g,`$1$1\\"`),S=S.replace(/(?=(\\+?)?)\1$/,`$1$1`),S=`"${S}"`,S=S.replace(QM,`^$1`),a&&(S=S.replace(QM,`^$1`)),S}function buildCmdExeInvocation(n,a,S=`cmd.exe`){let C=ZM.test(n);return{cmd:S,args:[`/d`,`/s`,`/c`,`"${[escapeCmdCommand(n),...a.map(n=>escapeCmdArgument(n,C))].join(` `)}"`],windowsVerbatimArguments:!0}}function isBareName(n){return!n.includes(`/`)&&!n.includes(`\\`)&&!/\.[^.]+$/.test(n)}function lookupOnPath(n,a){let S=(lookupEnv(a.env,`PATH`)??``).split(`;`).filter(Boolean),C=(lookupEnv(a.env,`PATHEXT`)??YM).split(`;`).filter(Boolean);for(let N of S)for(let S of C){let C=a.join(N,n+S);if(a.exists(C))return C}}function resolveWin32Command(n,a,S){if(S.platform!==`win32`||!isBareName(n))return;let C=lookupOnPath(n,S);if(C)return XM.test(C)?{cmd:C,args:[...a]}:buildCmdExeInvocation(C,a,lookupEnv(S.env,`COMSPEC`)??`cmd.exe`)}var YM,XM,ZM,QM,$M=__esmMin(()=>{YM=`.COM;.EXE;.BAT;.CMD`,XM=/\.(?:com|exe)$/i,ZM=/node_modules[\\/]\.bin[\\/][^\\/]+\.cmd$/i,QM=/([()\][%!^"`<>&|;, *?])/g});function resolveEnv(n){if(!n.color)return n.env;let a=n.env??process.env,S=process.env.FORCE_COLOR!==void 0||process.env.NO_COLOR!==void 0?{}:{FORCE_COLOR:`1`};return{...a,...S}}function forWin32(n,a,S){return resolveWin32Command(n,a,{platform:process.platform,env:S??process.env,exists:existsSync,join:_s})??{cmd:n,args:[...a]}}function mapSpawnError(n,a){return n.code===`ENOENT`&&a.notFound?a.notFound(n):n}function mustBlock(n){return isGjs()&&n.completion===`return`}function spawnToCompletion(n,a,S){let C=resolveEnv(S);if(mustBlock(S)){let
|
|
783
|
+
`)}),()=>{F.length>0&&(a.write(F),F=``)}}var JM=__esmMin(()=>{});function lookupEnv(n,a){let S=a.toLowerCase();for(let a of Object.keys(n))if(a.toLowerCase()===S&&n[a]!==void 0)return n[a]}function escapeCmdCommand(n){return n.replace(QM,`^$1`)}function escapeCmdArgument(n,a=!1){let S=`${n}`;return S=S.replace(/(?=(\\+?)?)\1"/g,`$1$1\\"`),S=S.replace(/(?=(\\+?)?)\1$/,`$1$1`),S=`"${S}"`,S=S.replace(QM,`^$1`),a&&(S=S.replace(QM,`^$1`)),S}function buildCmdExeInvocation(n,a,S=`cmd.exe`){let C=ZM.test(n);return{cmd:S,args:[`/d`,`/s`,`/c`,`"${[escapeCmdCommand(n),...a.map(n=>escapeCmdArgument(n,C))].join(` `)}"`],windowsVerbatimArguments:!0}}function isBareName(n){return!n.includes(`/`)&&!n.includes(`\\`)&&!/\.[^.]+$/.test(n)}function lookupOnPath(n,a){let S=(lookupEnv(a.env,`PATH`)??``).split(`;`).filter(Boolean),C=(lookupEnv(a.env,`PATHEXT`)??YM).split(`;`).filter(Boolean);for(let N of S)for(let S of C){let C=a.join(N,n+S);if(a.exists(C))return C}}function resolveWin32Command(n,a,S){if(S.platform!==`win32`||!isBareName(n))return;let C=lookupOnPath(n,S);if(C)return XM.test(C)?{cmd:C,args:[...a]}:buildCmdExeInvocation(C,a,lookupEnv(S.env,`COMSPEC`)??`cmd.exe`)}var YM,XM,ZM,QM,$M=__esmMin(()=>{YM=`.COM;.EXE;.BAT;.CMD`,XM=/\.(?:com|exe)$/i,ZM=/node_modules[\\/]\.bin[\\/][^\\/]+\.cmd$/i,QM=/([()\][%!^"`<>&|;, *?])/g});function resolveEnv(n){if(!n.color)return n.env;let a=n.env??process.env,S=process.env.FORCE_COLOR!==void 0||process.env.NO_COLOR!==void 0?{}:{FORCE_COLOR:`1`};return{...a,...S}}function forWin32(n,a,S){return resolveWin32Command(n,a,{platform:process.platform,env:S??process.env,exists:existsSync,join:_s})??{cmd:n,args:[...a]}}function mapSpawnError(n,a){return n.code===`ENOENT`&&a.notFound?a.notFound(n):n}function mustBlock(n){return isGjs()&&n.completion===`return`}function spawnToCompletion(n,a,S){let C=resolveEnv(S),N=S.shell?{cmd:n,args:[...a],windowsVerbatimArguments:!1}:forWin32(n,a,C);if(mustBlock(S)){let n=spawnSync(N.cmd,N.args,{stdio:[`inherit`,`pipe`,`pipe`],cwd:S.cwd,env:C,shell:S.shell,maxBuffer:S.maxBuffer??eN,windowsVerbatimArguments:N.windowsVerbatimArguments});if(n.error)return Promise.reject(mapSpawnError(n.error,S));let a=S.stdio===`inherit-stderr`?process.stderr:process.stdout;return n.stdout&&n.stdout.length>0&&a.write(n.stdout),n.stderr&&n.stderr.length>0&&process.stderr.write(n.stderr),Promise.resolve({code:n.status,signal:n.signal??null})}return new Promise((n,a)=>{let F=N,I={cwd:S.cwd,stdio:S.stdio===`pipe`?[`ignore`,`pipe`,`pipe`]:S.stdio===`inherit-stderr`?[`inherit`,2,2]:`inherit`};S.shell&&(I.shell=!0),C&&(I.env=C),F.windowsVerbatimArguments&&(I.windowsVerbatimArguments=!0);let H=spawn(F.cmd,F.args,I);S.onSpawn?.(H),H.on(`close`,(a,S)=>{n({code:a,signal:S})}),H.on(`error`,n=>{a(mapSpawnError(n,S))})})}function describeExit(n){return n.signal===null?`code ${n.code}`:`signal ${n.signal}`}var eN,tN=__esmMin(()=>{Xm(),gl(),Os(),Tm(),$M(),eN=64*1024*1024});function dirLinkTarget(n,a,S=nN){return S===`junction`?ms(a):vs(bs(n),a)}function linkDirSync(n,a){assertAbsolute(a),symlinkSync(dirLinkTarget(n,a),n,rN)}function replicateLinkSync(n,a){let S=readlinkSync(n);if(!dirLinksAreJunctions()){symlinkSync(S,a);return}let C=ms(bs(n),S),N;try{N=statSync(C).isDirectory()}catch{symlinkSync(S,a);return}N?symlinkSync(C,a,`junction`):symlinkSync(S,a,`file`)}function assertAbsolute(n){if(ms(n)!==n)throw TypeError(`linkDir: target must be an absolute path, got ${JSON.stringify(n)}. Node resolves a Windows junction target against the process CWD rather than the link's own directory, so a relative target silently points somewhere else there.`)}var nN,rN,dirLinksAreJunctions,iN=__esmMin(()=>{gl(),Jc(),Os(),nN=process.platform===`win32`?`junction`:`symlink`,rN=nN===`junction`?`junction`:void 0,dirLinksAreJunctions=()=>nN===`junction`});function buildCacheEnabledByEnv(n=process.env){let a=n.GJSIFY_BUILD_CACHE;return a===void 0?!1:a!==``&&a!==`0`&&a!==`false`}function buildCacheRoot(n){return _s(n,`node_modules`,`.cache`,`gjsify`,`build`)}function sanitizePackageDirName(n){return`${n.replace(/^@/,``).replace(/[^A-Za-z0-9._-]/g,`-`)}-${createHash(`sha256`).update(n).digest(`hex`).slice(0,8)}`}function hashFileStream(n){let a=createHash(`sha256`),S=openSync(n,`r`);try{let n=Buffer.alloc(64*1024);for(;;){let C=readSync(S,n,0,n.length,null);if(C<=0)break;a.update(n.subarray(0,C))}}finally{closeSync(S)}return a.digest(`hex`)}function walkFiles(n,a,S){let C;try{C=readdirSync(n)}catch{return}C.sort();for(let N of C){if(N===`node_modules`)continue;let C=_s(n,N),F=a===``?N:`${a}/${N}`,I;try{I=lstatSync(C)}catch{continue}if(I.isSymbolicLink())try{let n=readlinkSync(C);S.push({rel:F,abs:C,link:n})}catch{}else I.isDirectory()?walkFiles(C,F,S):I.isFile()&&S.push({rel:F,abs:C})}}function hashPackageInputs(n){let a=[],S=_s(n,`package.json`);existsSync(S)&&a.push({rel:`package.json`,abs:S});let C=[];try{C=readdirSync(n)}catch{}for(let S of C.sort())/^tsconfig.*\.json$/.test(S)&&a.push({rel:S,abs:_s(n,S)});let N=_s(n,`src`);existsSync(N)&&walkFiles(N,`src`,a);let F=createHash(`sha256`);F.update(`gjsify-build-cache-inputs/v3
|
|
784
784
|
`);for(let n of a){if(n.link!==void 0){let a;try{a=hashFileStream(n.abs)}catch{a=`link:${n.link}`}F.update(`${n.rel} ${a}\n`);continue}try{F.update(`${n.rel} ${hashFileStream(n.abs)}\n`)}catch{F.update(`${n.rel} unreadable\n`)}}return F.digest(`hex`)}function hashOutputDirs(n,a){let S=createHash(`sha256`);S.update(`gjsify-build-cache-outputs/v3
|
|
785
785
|
`);for(let C of[...a].sort()){let a=_s(n,C);if(!existsSync(a)){S.update(`${C} absent\n`);continue}let N=[];walkFiles(a,C,N);for(let n of N){if(n.link!==void 0){S.update(`${n.rel} link:${n.link}\n`);continue}try{S.update(`${n.rel} ${hashFileStream(n.abs)}\n`)}catch{S.update(`${n.rel} unreadable\n`)}}}return S.digest(`hex`)}function outputUnits(n){let a=[];for(let S of aN){let C=_s(n,S);if(!existsSync(C))continue;let N;try{N=readdirSync(C).filter(n=>n!==`node_modules`&&!isBuildInfo(n))}catch{continue}let F=N.every(n=>{try{return lstatSync(_s(C,n)).isDirectory()}catch{return!1}});if(N.length===0||!F){a.push(S);continue}for(let n of[...N].sort())a.push(`${S}/${n}`)}return a}function signatureOf(n,a){let S=[];walkFiles(_s(n,a),a,S);let C=createHash(`sha256`);for(let n of S){let a=`link`;if(n.link===void 0)try{let S=lstatSync(n.abs);a=`${S.size}:${S.mtimeMs}`}catch{a=`gone`}C.update(`${n.rel} ${a}\n`)}return C.digest(`hex`)}function snapshotOutputDirs(n){let a={};for(let n of aN)a[n]=null;for(let S of outputUnits(n))a[S]=signatureOf(n,S);return a}function modifiedOutputDirs(n,a){let S=[];for(let C of outputUnits(n))signatureOf(n,C)!==(a[C]??null)&&S.push(C);return S.sort()}function composeCacheKey(n){let a=createHash(`sha256`);a.update(`gjsify-build-cache/v3
|
|
786
|
-
`),a.update(`script:${n.script}\n`);for(let S of n.args??[])a.update(`arg:${S}\n`);for(let S of Object.keys(n.toolchain).sort())a.update(`tool:${S}@${n.toolchain[S]}\n`);a.update(`self:${n.ownHash}\n`);let S=n.depHashes instanceof Map?n.depHashes:new Map(Object.entries(n.depHashes));for(let n of[...S.keys()].sort())a.update(`dep:${n} ${S.get(n)}\n`);return a.digest(`hex`).slice(0,32)}function resolveToolchainVersions(n){let a={};for(let S of oN){let C=`none`;try{let a=readFileSync(_s(n,`node_modules`,...S.split(`/`),`package.json`),`utf-8`),N=JSON.parse(a);typeof N.version==`string`&&(C=N.version)}catch{}S===`@gjsify/cli`&&C===`none`&&(C=readOwnCliVersion()??`none`),a[S]=C}return a}function readOwnCliVersion(){try{let n=bs(fileURLToPath(import.meta.url));for(let a=0;a<4;a++){let a=_s(n,`package.json`);if(existsSync(a)){let n=JSON.parse(readFileSync(a,`utf-8`));if(n.name===`@gjsify/cli`&&typeof n.version==`string`)return n.version}n=bs(n)}}catch{}return null}function copyDirRecursive(n,a){mkdirSync(a,{recursive:!0});for(let S of readdirSync(n).sort()){let C=_s(n,S),N=_s(a,S),F=lstatSync(C);if(F.isSymbolicLink())replicateLinkSync(C,N);else if(F.isDirectory())copyDirRecursive(C,N);else if(F.isFile()){copyFileSync(C,N);try{chmodSync(N,F.mode&511)}catch{}}}}function buildCacheEntryDir(n,a,S){return _s(n,sanitizePackageDirName(a),S)}function readCacheEntry(n,a,S){let C=_s(sN(n,a,S),`manifest.json`);try{let N=JSON.parse(readFileSync(C,`utf-8`));if(N.version!==1||N.layout!==`v3`||N.package!==a||N.key!==S||!Array.isArray(N.dirs))return null;for(let C of N.dirs)if(!existsSync(_s(sN(n,a,S),`outputs`,C)))return null;return N}catch{return null}}function storeCacheEntry(n,a,S,C,N){let F=sN(n,a.name,S),I=`${F}.tmp-${process.pid}`;try{rmSync(I,{recursive:!0,force:!0}),mkdirSync(_s(I,`outputs`),{recursive:!0});for(let n of N)copyDirRecursive(_s(a.location,n),_s(I,`outputs`,n));let H=new Date().toISOString(),W={version:1,layout:`v3`,package:a.name,script:C,key:S,dirs:[...N],outputsHash:hashOutputDirs(a.location,N),createdAt:H,usedAt:H};return writeFileSync(_s(I,`manifest.json`),JSON.stringify(W,null,2)),rmSync(F,{recursive:!0,force:!0}),renameSync(I,F),pruneCacheEntries(n,a.name),W}catch{try{rmSync(I,{recursive:!0,force:!0})}catch{}return null}}function restoreCacheEntry(n,a,S){let C=sN(n,a.name,S.key);try{if(S.dirs.length>0&&hashOutputDirs(a.location,S.dirs)===S.outputsHash)return touchManifestUsed(C,S),`up-to-date`;for(let n of S.dirs){let S=_s(a.location,n);rmSync(S,{recursive:!0,force:!0}),copyDirRecursive(_s(C,`outputs`,n),S)}return touchManifestUsed(C,S),S.dirs.length>0?`restored`:`up-to-date`}catch{return null}}function touchManifestUsed(n,a){try{a.usedAt=new Date().toISOString(),writeFileSync(_s(n,`manifest.json`),JSON.stringify(a,null,2))}catch{}}function pruneCacheEntries(n,a,S=2){let C=_s(n,sanitizePackageDirName(a)),N;try{N=readdirSync(C)}catch{return}let F=[];for(let n of N){if(n.includes(`.tmp-`)){try{rmSync(_s(C,n),{recursive:!0,force:!0})}catch{}continue}let a=``;try{let S=JSON.parse(readFileSync(_s(C,n,`manifest.json`),`utf-8`));a=S.usedAt??S.createdAt??``}catch{}F.push({name:n,stamp:a})}if(!(F.length<=S)){F.sort((n,a)=>n.stamp<a.stamp?1:n.stamp>a.stamp?-1:0);for(let n of F.slice(S))try{rmSync(_s(C,n.name),{recursive:!0,force:!0})}catch{}}}function buildCacheOptedOut(n){return n.manifest.gjsify?.buildCache===!1}var aN,oN,isBuildInfo,sN,BuildCacheRunner,cN=__esmMin(()=>{_e(),xo(),gl(),Os(),rn(),R_(),iN(),aN=[`lib`,`dist`,`dist-templates`],oN=[`@gjsify/cli`,`@gjsify/tsc`,`rolldown`,`typescript`],isBuildInfo=n=>n.endsWith(`.tsbuildinfo`),sN=buildCacheEntryDir,BuildCacheRunner=class{options;cacheRoot;graph;toolchain;ownHashes=new Map;closures=new Map;keys=new Map;log;constructor(n){this.options=n,this.cacheRoot=buildCacheRoot(n.root),this.graph=buildDependencyGraph(n.workspaces,{includeDev:!0,includePeer:!0,includeOptional:!0}),this.toolchain=resolveToolchainVersions(n.root),this.log=n.log??(n=>ge.error(n));for(let a of n.targets??[])if(this.graph.byName.has(a)){this.ownHashOf(a);for(let n of this.closureOf(a))this.ownHashOf(n)}}ownHashOf(n){let a=this.ownHashes.get(n);if(a===void 0){let S=this.graph.byName.get(n);a=S?hashPackageInputs(S.location):`unknown-workspace`,this.ownHashes.set(n,a)}return a}closureOf(n){let a=this.closures.get(n);if(a===void 0){let S=new Set,C=[...this.graph.edges.get(n)??[]];for(;C.length>0;){let a=C.shift();if(!(a===n||S.has(a))){S.add(a);for(let N of this.graph.edges.get(a)??[])!S.has(N)&&N!==n&&C.push(N)}}a=[...S].sort(),this.closures.set(n,a)}return a}keyFor(n){let a=this.keys.get(n.name);if(a===void 0){let S=new Map;for(let a of this.closureOf(n.name))S.set(a,this.ownHashOf(a));a=composeCacheKey({script:this.options.script,args:this.options.args,toolchain:this.toolchain,ownHash:this.ownHashOf(n.name),depHashes:S}),this.keys.set(n.name,a)}return a}tryRestore(n){try{if(buildCacheOptedOut(n))return this.log(`[gjsify build-cache] ${n.name}: opted out (gjsify.buildCache=false) — running uncached`),!1;let a=this.keyFor(n),S=readCacheEntry(this.cacheRoot,n.name,a);if(!S||S.script!==this.options.script)return this.log(`[gjsify build-cache] ${n.name}: miss ${a} — running "${this.options.script}"`),!1;let C=restoreCacheEntry(this.cacheRoot,n,S);if(C===null)return this.log(`[gjsify build-cache] ${n.name}: entry ${a} unrestorable — running "${this.options.script}"`),!1;let N=S.dirs.length>0?S.dirs.join(`, `):`no output dirs`;return this.log(`[gjsify build-cache] ${n.name}: hit ${a} — ${C===`restored`?`restored ${N}`:`${N} up to date`} (skipped "${this.options.script}")`),!0}catch(a){return this.log(`[gjsify build-cache] ${n.name}: cache error (${a.message}) — running uncached`),!1}}snapshotOutputs(n){try{return snapshotOutputDirs(n.location)}catch{return{}}}storeAfterSuccess(n,a){try{if(buildCacheOptedOut(n))return;let S=this.keyFor(n),C=modifiedOutputDirs(n.location,a);if(storeCacheEntry(this.cacheRoot,n,S,this.options.script,C)){let a=C.length>0?C.join(`, `):`no output dirs modified`;this.log(`[gjsify build-cache] ${n.name}: stored ${S} (${a})`)}}catch(a){this.log(`[gjsify build-cache] ${n.name}: store failed (${a.message}) — continuing`)}}}});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&&ge.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())return`gjsify`;let n=process.env.npm_config_user_agent??``;return n.startsWith(`yarn/`)?`yarn`:n.startsWith(`gjsify/`)?`gjsify`:`npm`}var uN,dN=__esmMin(()=>{_e(),tN(),R_(),B_(),cN(),Tm(),lN(),uN={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 ge.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 ge.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&&ge.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(ge.error(`[${n.name}] ${S.message}`),!H)return process.exit(1);te.push({workspace:n.name,error:S})}}return te.length>0?(ge.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(_s(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 fN,pN=__esmMin(()=>{_e(),JM(),tN(),z_(),Os(),um(),R_(),B_(),dN(),fN={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(_s(a,`package.json`))?.scripts?.check){n.verbose&&ge.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 ge.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 ge.error("gjsify check: no workspaces with a `check` script found."),process.exit(1);if(n.verbose&&ge.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&&ge.log(`[check] → ${C.name}`);let N=await runCheck(C,null);N!==0&&(S++,a===0&&(a=N))}return a!==0&&ge.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){ge.error(`\ngjsify check: ${H.length} of ${F.length} workspace(s) failed:`);for(let n of H)ge.error(` ✗ ${n.name} (exit ${n.code})`);return process.exit(1)}n.verbose&&ge.log(`\ngjsify check: ${F.length} workspace(s) green.`),process.exit(0)}}});function manifestPath(){let n=bs(fileURLToPath(import.meta.url)),a=[_s(n,`..`,`..`,`showcases.json`),_s(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??``,needsWebgl:!!n.needsWebgl}));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 mN=__esmMin(()=>{gl(),Os(),rn()});function parseSpec$1(n){if(!n)throw Error(`dlx: empty package spec`);if(n.startsWith(`./`)||n.startsWith(`../`)||gs(n)||existsSync(n))return{kind:`local`,path:ms(n)};let a=n,S,C=n.lastIndexOf(`@`);if(C>0&&(a=n.slice(0,C),S=n.slice(C+1)),!hN.test(a))throw Error(`dlx: invalid package name "${a}"`);return{kind:`registry`,name:a,version:S,spec:n}}var hN,gN=__esmMin(()=>{gl(),Os(),hN=/^(?:@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/,__name$1(parseSpec$1,`parseSpec`)});function resolveGjsEntry(n,a){let S=_s(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=ms(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=_s(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=ms(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=ms(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 _N=__esmMin(()=>{gl(),Os()});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=_s(n&&n.length>0?n:_s(homedir(),`.cache`),`gjsify`,`dlx`);return mkdirSync(a,{recursive:!0}),a}function cacheDirFor(n){let a=_s(dlxCacheRoot(),n);return mkdirSync(a,{recursive:!0}),a}function makePrepareDir(n){let a=_s(n,`${Date.now().toString(16)}-${process.pid.toString(16)}`);return mkdirSync(a,{recursive:!0}),a}function getValidCachedPkg(n,a=yN){let S=_s(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*vN?N:void 0}function symlinkSwap(n,a,S={}){let C=S.junctions??dirLinksAreJunctions(),N=_s(n,`pkg`),F=_s(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 ms(n,`node_modules`,a)}var vN,yN,bN=__esmMin(()=>{xo(),gl(),um(),Os(),iN(),vN=6e4,yN=1440*7});function makeProgressReporter(n={}){if(n.enabled===!1)return SN;let a=n.stream??process.stderr,S=!!a.isTTY;return n.enabled??!0?S?makeTtyReporter(a):makePlainReporter(a):SN}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=xN[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: ${xN[C]} ${N} package(s)\n`)},update(C){let N=Date.now();if(N-a<CN||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: ${xN[C.phase]} ${C.current}/${C.total} (${F}%)\n`)},endPhase(a){n.write(`gjsify install: ${xN[a]} done\n`)}}}function formatBar(n,a,S,C,N){let F=xN[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 xN,SN,CN,wN=__esmMin(()=>{xN={resolve:`resolving`,download:`downloading`,extract:`extracting`,link:`linking bins`},SN={update(){},beginPhase(){},endPhase(){}},CN=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 DN?a:new DN(a),C=n instanceof SemVer?n:parse(String(n));return C?S.test(C):!1}function maxSatisfying(n,a){let S=a instanceof DN?a:new DN(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 TN,EN,SemVer,DN,ON=__esmMin(()=>{TN=/^(0|[1-9]\d*)$/,EN=/^(\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=EN.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=>TN.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}},DN=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.29.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 kN=__esmMin(()=>{}),PackageNotFoundError,IntegrityError,RegistryTimeoutError,AN=__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):jN}function parseNpmrc(n){let a={registry:jN,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 jN,MN=__esmMin(()=>{jN=`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 NN=__esmMin(()=>{AN(),__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 PN=__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 FN=__esmMin(()=>{kN(),AN(),MN(),NN()});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 IN=__esmMin(()=>{kN(),AN(),NN(),PN()});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 LN=__esmMin(()=>{kN(),MN()}),RN=__esmMin(()=>{kN(),MN(),FN(),IN(),LN()});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,zN=__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 BN=__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=ms(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(bs(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(bs(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=vs(a,n);return S!==``&&!S.startsWith(`..`)&&!gs(S)}var VN=__esmMin(()=>{zN(),gl(),Os(),__name$1(isInside$1,`isInside`)}),HN=__exportAll$4({BLOCK_SIZE:()=>512,TarParseError:()=>TarParseError,createTarball:()=>createTarball,extractTarball:()=>extractTarball,gunzip:()=>gunzip,gzip:()=>gzip,parseTar:()=>parseTar}),UN=__esmMin(()=>{zN(),BN(),VN()});function gjsifyCacheRoot(n,a){let S=process.env.XDG_CACHE_HOME;return _s(S&&S.length>0?S:_s(homedir(),`.cache`),`gjsify`,n,a)}function atomicWrite(n,a){try{atomicWriteStrict(n,a)}catch{}}function atomicWriteStrict(n,a){mkdirSync(_s(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 WN=__esmMin(()=>{gl(),um(),Os()});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 qN}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=_s(n,KN),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>JN?{stale:!0,reason:`no owner recorded within the acquire grace period`}:{stale:!1}}function stealStaleLock(n){let a=`${n}.stale-${process.pid}-${++QN}`;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=ZN.get(n);if(S&&(S.count--,!(S.count>0))){ZN.delete(n);try{let a=JSON.parse(readFileSync(_s(n,KN),`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=ms(n)}let C=_s(S,`node_modules`,GN),N=ZN.get(C);if(N)return N.count++,makeHandle(C);mkdirSync(bs(C),{recursive:!0});let F=`${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`,I=YN,H=!1;for(;;){if(a.signal?.aborted)throw abortErr(a.signal);try{return mkdirSync(C),writeFileSync(_s(C,KN),JSON.stringify({pid:process.pid,nonce:F,startedAt:Date.now()})),ZN.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)&&ge.warn(`gjsify install: removed stale install lock (${n.reason}) — ${C}`);continue}if(!H){H=!0;let a=n.ownerPid===void 0?``:` (pid ${n.ownerPid})`;ge.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),XN)}}var GN,KN,qN,JN,YN,XN,ZN,QN,$N=__esmMin(()=>{_e(),gl(),Os(),GN=`.gjsify-install-lock`,KN=`owner.json`,qN=35*6e4,JN=15e3,YN=150,XN=1e3,ZN=new Map,QN=0});function cacheRoot$1(){return gjsifyCacheRoot(`tarballs`,eP)}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=Ke.from(C,`base64`).toString(`hex`);return N.length<4?null:{algorithm:S,hex:N}}function pathFor$1(n){let a=parseSri$1(n);if(!a)return null;let S=a.hex.slice(0,2);return _s(cacheRoot$1(),a.algorithm,S,`${a.hex}.tgz`)}function getCachedTarball(n){let a=pathFor$1(n);return a?readCacheFile(a):null}function putCachedTarball(n,a){let S=pathFor$1(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:_s(a.endsWith(`_cacache`)?a:_s(a,`_cacache`),`content-v2`)}let a=process.env.npm_config_cache;return _s(a&&a.length>0?a:_s(homedir(),`.npm`),`_cacache`,`content-v2`)}function npmCachePathFor(n){let a=npmCacacheContentDir();if(!a)return null;let S=parseSri$1(n);return S?_s(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 eP,tP=__esmMin(()=>{tt(),gl(),um(),Os(),WN(),eP=`v1`,__name$1(cacheRoot$1,`cacheRoot`),__name$1(parseSri$1,`parseSri`),__name$1(pathFor$1,`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`,nP)}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(n,a,S){if(!isEnabled())return null;let C=packumentCacheKey(n,a,S);return _s(cacheRoot(),shardFor(C),`${C}.json`)}function getCachedPackument(n,a,S=`corgi`){let C=pathFor(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(n,a,N);F&&atomicWrite(F,JSON.stringify({etag:S,packument:C}))}var nP,rP=__esmMin(()=>{Os(),WN(),nP=`v3`});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 iP=__esmMin(()=>{Tm()});function parseShebang(n){let a=aP.exec(n.trim());return a?{variables:a[1]??``,prog:a[2]??``,args:a[3]??``}:null}function replaceDollarWithPercentPair(n){return n.replace(/\$\{?([^$@#?\- \t{}:]+)\}?/g,(n,a)=>`%${a}%`)}function convertToSetCommands(n){let a=``;for(let S of n.split(` `)){let n=S.indexOf(`=`);if(n<=0)continue;let C=S.slice(0,n).trim(),N=S.slice(n+1).trim();C&&N&&(a+=`@SET ${C}=${replaceDollarWithPercentPair(N)}\r\n`)}return a}function buildCmdShim(n,a){let S=n.split(`\\`).join(`/`),C=S.split(`/`).join(`\\`),N=S,F=a?.prog??``,I=a?.args??``,H=a?.variables??``,W=F?F.split(`\\`).join(`/`):``,K=W?`"${W}$exe"`:``,q=``,Y=``,X=``;F?(q=`"%dp0%\\${F}.exe"`,Y=`"$basedir/${F}"`,X=`"$basedir/${F}$exe"`,C=`"%dp0%\\${C}"`,S=`"$basedir_win/${S}"`,N=`"$basedir/${N}"`):(F=`"%dp0%\\${C}"`,W=`"$basedir/${S}"`,K=W,I=``,C=``,S=``,N=``);let te;if(q){let n=I.trim();te=oP+convertToSetCommands(H)+`\r
|
|
786
|
+
`),a.update(`script:${n.script}\n`);for(let S of n.args??[])a.update(`arg:${S}\n`);for(let S of Object.keys(n.toolchain).sort())a.update(`tool:${S}@${n.toolchain[S]}\n`);a.update(`self:${n.ownHash}\n`);let S=n.depHashes instanceof Map?n.depHashes:new Map(Object.entries(n.depHashes));for(let n of[...S.keys()].sort())a.update(`dep:${n} ${S.get(n)}\n`);return a.digest(`hex`).slice(0,32)}function resolveToolchainVersions(n){let a={};for(let S of oN){let C=`none`;try{let a=readFileSync(_s(n,`node_modules`,...S.split(`/`),`package.json`),`utf-8`),N=JSON.parse(a);typeof N.version==`string`&&(C=N.version)}catch{}S===`@gjsify/cli`&&C===`none`&&(C=readOwnCliVersion()??`none`),a[S]=C}return a}function readOwnCliVersion(){try{let n=bs(fileURLToPath(import.meta.url));for(let a=0;a<4;a++){let a=_s(n,`package.json`);if(existsSync(a)){let n=JSON.parse(readFileSync(a,`utf-8`));if(n.name===`@gjsify/cli`&&typeof n.version==`string`)return n.version}n=bs(n)}}catch{}return null}function copyDirRecursive(n,a){mkdirSync(a,{recursive:!0});for(let S of readdirSync(n).sort()){let C=_s(n,S),N=_s(a,S),F=lstatSync(C);if(F.isSymbolicLink())replicateLinkSync(C,N);else if(F.isDirectory())copyDirRecursive(C,N);else if(F.isFile()){copyFileSync(C,N);try{chmodSync(N,F.mode&511)}catch{}}}}function buildCacheEntryDir(n,a,S){return _s(n,sanitizePackageDirName(a),S)}function readCacheEntry(n,a,S){let C=_s(sN(n,a,S),`manifest.json`);try{let N=JSON.parse(readFileSync(C,`utf-8`));if(N.version!==1||N.layout!==`v3`||N.package!==a||N.key!==S||!Array.isArray(N.dirs))return null;for(let C of N.dirs)if(!existsSync(_s(sN(n,a,S),`outputs`,C)))return null;return N}catch{return null}}function storeCacheEntry(n,a,S,C,N){let F=sN(n,a.name,S),I=`${F}.tmp-${process.pid}`;try{rmSync(I,{recursive:!0,force:!0}),mkdirSync(_s(I,`outputs`),{recursive:!0});for(let n of N)copyDirRecursive(_s(a.location,n),_s(I,`outputs`,n));let H=new Date().toISOString(),W={version:1,layout:`v3`,package:a.name,script:C,key:S,dirs:[...N],outputsHash:hashOutputDirs(a.location,N),createdAt:H,usedAt:H};return writeFileSync(_s(I,`manifest.json`),JSON.stringify(W,null,2)),rmSync(F,{recursive:!0,force:!0}),renameSync(I,F),pruneCacheEntries(n,a.name),W}catch{try{rmSync(I,{recursive:!0,force:!0})}catch{}return null}}function restoreCacheEntry(n,a,S){let C=sN(n,a.name,S.key);try{if(S.dirs.length>0&&hashOutputDirs(a.location,S.dirs)===S.outputsHash)return touchManifestUsed(C,S),`up-to-date`;for(let n of S.dirs){let S=_s(a.location,n);rmSync(S,{recursive:!0,force:!0}),copyDirRecursive(_s(C,`outputs`,n),S)}return touchManifestUsed(C,S),S.dirs.length>0?`restored`:`up-to-date`}catch{return null}}function touchManifestUsed(n,a){try{a.usedAt=new Date().toISOString(),writeFileSync(_s(n,`manifest.json`),JSON.stringify(a,null,2))}catch{}}function pruneCacheEntries(n,a,S=2){let C=_s(n,sanitizePackageDirName(a)),N;try{N=readdirSync(C)}catch{return}let F=[];for(let n of N){if(n.includes(`.tmp-`)){try{rmSync(_s(C,n),{recursive:!0,force:!0})}catch{}continue}let a=``;try{let S=JSON.parse(readFileSync(_s(C,n,`manifest.json`),`utf-8`));a=S.usedAt??S.createdAt??``}catch{}F.push({name:n,stamp:a})}if(!(F.length<=S)){F.sort((n,a)=>n.stamp<a.stamp?1:n.stamp>a.stamp?-1:0);for(let n of F.slice(S))try{rmSync(_s(C,n.name),{recursive:!0,force:!0})}catch{}}}function buildCacheOptedOut(n){return n.manifest.gjsify?.buildCache===!1}var aN,oN,isBuildInfo,sN,BuildCacheRunner,cN=__esmMin(()=>{_e(),xo(),gl(),Os(),rn(),R_(),iN(),aN=[`lib`,`dist`,`dist-templates`],oN=[`@gjsify/cli`,`@gjsify/tsc`,`rolldown`,`typescript`],isBuildInfo=n=>n.endsWith(`.tsbuildinfo`),sN=buildCacheEntryDir,BuildCacheRunner=class{options;cacheRoot;graph;toolchain;ownHashes=new Map;closures=new Map;keys=new Map;log;constructor(n){this.options=n,this.cacheRoot=buildCacheRoot(n.root),this.graph=buildDependencyGraph(n.workspaces,{includeDev:!0,includePeer:!0,includeOptional:!0}),this.toolchain=resolveToolchainVersions(n.root),this.log=n.log??(n=>ge.error(n));for(let a of n.targets??[])if(this.graph.byName.has(a)){this.ownHashOf(a);for(let n of this.closureOf(a))this.ownHashOf(n)}}ownHashOf(n){let a=this.ownHashes.get(n);if(a===void 0){let S=this.graph.byName.get(n);a=S?hashPackageInputs(S.location):`unknown-workspace`,this.ownHashes.set(n,a)}return a}closureOf(n){let a=this.closures.get(n);if(a===void 0){let S=new Set,C=[...this.graph.edges.get(n)??[]];for(;C.length>0;){let a=C.shift();if(!(a===n||S.has(a))){S.add(a);for(let N of this.graph.edges.get(a)??[])!S.has(N)&&N!==n&&C.push(N)}}a=[...S].sort(),this.closures.set(n,a)}return a}keyFor(n){let a=this.keys.get(n.name);if(a===void 0){let S=new Map;for(let a of this.closureOf(n.name))S.set(a,this.ownHashOf(a));a=composeCacheKey({script:this.options.script,args:this.options.args,toolchain:this.toolchain,ownHash:this.ownHashOf(n.name),depHashes:S}),this.keys.set(n.name,a)}return a}tryRestore(n){try{if(buildCacheOptedOut(n))return this.log(`[gjsify build-cache] ${n.name}: opted out (gjsify.buildCache=false) — running uncached`),!1;let a=this.keyFor(n),S=readCacheEntry(this.cacheRoot,n.name,a);if(!S||S.script!==this.options.script)return this.log(`[gjsify build-cache] ${n.name}: miss ${a} — running "${this.options.script}"`),!1;let C=restoreCacheEntry(this.cacheRoot,n,S);if(C===null)return this.log(`[gjsify build-cache] ${n.name}: entry ${a} unrestorable — running "${this.options.script}"`),!1;let N=S.dirs.length>0?S.dirs.join(`, `):`no output dirs`;return this.log(`[gjsify build-cache] ${n.name}: hit ${a} — ${C===`restored`?`restored ${N}`:`${N} up to date`} (skipped "${this.options.script}")`),!0}catch(a){return this.log(`[gjsify build-cache] ${n.name}: cache error (${a.message}) — running uncached`),!1}}snapshotOutputs(n){try{return snapshotOutputDirs(n.location)}catch{return{}}}storeAfterSuccess(n,a){try{if(buildCacheOptedOut(n))return;let S=this.keyFor(n),C=modifiedOutputDirs(n.location,a);if(storeCacheEntry(this.cacheRoot,n,S,this.options.script,C)){let a=C.length>0?C.join(`, `):`no output dirs modified`;this.log(`[gjsify build-cache] ${n.name}: stored ${S} (${a})`)}}catch(a){this.log(`[gjsify build-cache] ${n.name}: store failed (${a.message}) — continuing`)}}}});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&&ge.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())return`gjsify`;let n=process.env.npm_config_user_agent??``;return n.startsWith(`yarn/`)?`yarn`:n.startsWith(`gjsify/`)?`gjsify`:`npm`}var uN,dN=__esmMin(()=>{_e(),tN(),R_(),B_(),cN(),Tm(),lN(),uN={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 ge.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 ge.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&&ge.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(ge.error(`[${n.name}] ${S.message}`),!H)return process.exit(1);te.push({workspace:n.name,error:S})}}return te.length>0?(ge.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(_s(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 fN,pN=__esmMin(()=>{_e(),JM(),tN(),z_(),Os(),um(),R_(),B_(),dN(),fN={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(_s(a,`package.json`))?.scripts?.check){n.verbose&&ge.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 ge.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 ge.error("gjsify check: no workspaces with a `check` script found."),process.exit(1);if(n.verbose&&ge.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&&ge.log(`[check] → ${C.name}`);let N=await runCheck(C,null);N!==0&&(S++,a===0&&(a=N))}return a!==0&&ge.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){ge.error(`\ngjsify check: ${H.length} of ${F.length} workspace(s) failed:`);for(let n of H)ge.error(` ✗ ${n.name} (exit ${n.code})`);return process.exit(1)}n.verbose&&ge.log(`\ngjsify check: ${F.length} workspace(s) green.`),process.exit(0)}}});function manifestPath(){let n=bs(fileURLToPath(import.meta.url)),a=[_s(n,`..`,`..`,`showcases.json`),_s(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??``,needsWebgl:!!n.needsWebgl}));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 mN=__esmMin(()=>{gl(),Os(),rn()});function parseSpec$1(n){if(!n)throw Error(`dlx: empty package spec`);if(n.startsWith(`./`)||n.startsWith(`../`)||gs(n)||existsSync(n))return{kind:`local`,path:ms(n)};let a=n,S,C=n.lastIndexOf(`@`);if(C>0&&(a=n.slice(0,C),S=n.slice(C+1)),!hN.test(a))throw Error(`dlx: invalid package name "${a}"`);return{kind:`registry`,name:a,version:S,spec:n}}var hN,gN=__esmMin(()=>{gl(),Os(),hN=/^(?:@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/,__name$1(parseSpec$1,`parseSpec`)});function resolveGjsEntry(n,a){let S=_s(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=ms(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=_s(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=ms(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=ms(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 _N=__esmMin(()=>{gl(),Os()});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=_s(n&&n.length>0?n:_s(homedir(),`.cache`),`gjsify`,`dlx`);return mkdirSync(a,{recursive:!0}),a}function cacheDirFor(n){let a=_s(dlxCacheRoot(),n);return mkdirSync(a,{recursive:!0}),a}function makePrepareDir(n){let a=_s(n,`${Date.now().toString(16)}-${process.pid.toString(16)}`);return mkdirSync(a,{recursive:!0}),a}function getValidCachedPkg(n,a=yN){let S=_s(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*vN?N:void 0}function symlinkSwap(n,a,S={}){let C=S.junctions??dirLinksAreJunctions(),N=_s(n,`pkg`),F=_s(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 ms(n,`node_modules`,a)}var vN,yN,bN=__esmMin(()=>{xo(),gl(),um(),Os(),iN(),vN=6e4,yN=1440*7});function makeProgressReporter(n={}){if(n.enabled===!1)return SN;let a=n.stream??process.stderr,S=!!a.isTTY;return n.enabled??!0?S?makeTtyReporter(a):makePlainReporter(a):SN}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=xN[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: ${xN[C]} ${N} package(s)\n`)},update(C){let N=Date.now();if(N-a<CN||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: ${xN[C.phase]} ${C.current}/${C.total} (${F}%)\n`)},endPhase(a){n.write(`gjsify install: ${xN[a]} done\n`)}}}function formatBar(n,a,S,C,N){let F=xN[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 xN,SN,CN,wN=__esmMin(()=>{xN={resolve:`resolving`,download:`downloading`,extract:`extracting`,link:`linking bins`},SN={update(){},beginPhase(){},endPhase(){}},CN=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 DN?a:new DN(a),C=n instanceof SemVer?n:parse(String(n));return C?S.test(C):!1}function maxSatisfying(n,a){let S=a instanceof DN?a:new DN(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 TN,EN,SemVer,DN,ON=__esmMin(()=>{TN=/^(0|[1-9]\d*)$/,EN=/^(\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=EN.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=>TN.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}},DN=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.30.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 kN=__esmMin(()=>{}),PackageNotFoundError,IntegrityError,RegistryTimeoutError,AN=__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):jN}function parseNpmrc(n){let a={registry:jN,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 jN,MN=__esmMin(()=>{jN=`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 NN=__esmMin(()=>{AN(),__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 PN=__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 FN=__esmMin(()=>{kN(),AN(),MN(),NN()});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 IN=__esmMin(()=>{kN(),AN(),NN(),PN()});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 LN=__esmMin(()=>{kN(),MN()}),RN=__esmMin(()=>{kN(),MN(),FN(),IN(),LN()});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,zN=__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 BN=__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=ms(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(bs(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(bs(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=vs(a,n);return S!==``&&!S.startsWith(`..`)&&!gs(S)}var VN=__esmMin(()=>{zN(),gl(),Os(),__name$1(isInside$1,`isInside`)}),HN=__exportAll$4({BLOCK_SIZE:()=>512,TarParseError:()=>TarParseError,createTarball:()=>createTarball,extractTarball:()=>extractTarball,gunzip:()=>gunzip,gzip:()=>gzip,parseTar:()=>parseTar}),UN=__esmMin(()=>{zN(),BN(),VN()});function gjsifyCacheRoot(n,a){let S=process.env.XDG_CACHE_HOME;return _s(S&&S.length>0?S:_s(homedir(),`.cache`),`gjsify`,n,a)}function atomicWrite(n,a){try{atomicWriteStrict(n,a)}catch{}}function atomicWriteStrict(n,a){mkdirSync(_s(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 WN=__esmMin(()=>{gl(),um(),Os()});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 qN}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=_s(n,KN),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>JN?{stale:!0,reason:`no owner recorded within the acquire grace period`}:{stale:!1}}function stealStaleLock(n){let a=`${n}.stale-${process.pid}-${++QN}`;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=ZN.get(n);if(S&&(S.count--,!(S.count>0))){ZN.delete(n);try{let a=JSON.parse(readFileSync(_s(n,KN),`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=ms(n)}let C=_s(S,`node_modules`,GN),N=ZN.get(C);if(N)return N.count++,makeHandle(C);mkdirSync(bs(C),{recursive:!0});let F=`${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`,I=YN,H=!1;for(;;){if(a.signal?.aborted)throw abortErr(a.signal);try{return mkdirSync(C),writeFileSync(_s(C,KN),JSON.stringify({pid:process.pid,nonce:F,startedAt:Date.now()})),ZN.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)&&ge.warn(`gjsify install: removed stale install lock (${n.reason}) — ${C}`);continue}if(!H){H=!0;let a=n.ownerPid===void 0?``:` (pid ${n.ownerPid})`;ge.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),XN)}}var GN,KN,qN,JN,YN,XN,ZN,QN,$N=__esmMin(()=>{_e(),gl(),Os(),GN=`.gjsify-install-lock`,KN=`owner.json`,qN=35*6e4,JN=15e3,YN=150,XN=1e3,ZN=new Map,QN=0});function cacheRoot$1(){return gjsifyCacheRoot(`tarballs`,eP)}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=Ke.from(C,`base64`).toString(`hex`);return N.length<4?null:{algorithm:S,hex:N}}function pathFor$1(n){let a=parseSri$1(n);if(!a)return null;let S=a.hex.slice(0,2);return _s(cacheRoot$1(),a.algorithm,S,`${a.hex}.tgz`)}function getCachedTarball(n){let a=pathFor$1(n);return a?readCacheFile(a):null}function putCachedTarball(n,a){let S=pathFor$1(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:_s(a.endsWith(`_cacache`)?a:_s(a,`_cacache`),`content-v2`)}let a=process.env.npm_config_cache;return _s(a&&a.length>0?a:_s(homedir(),`.npm`),`_cacache`,`content-v2`)}function npmCachePathFor(n){let a=npmCacacheContentDir();if(!a)return null;let S=parseSri$1(n);return S?_s(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 eP,tP=__esmMin(()=>{tt(),gl(),um(),Os(),WN(),eP=`v1`,__name$1(cacheRoot$1,`cacheRoot`),__name$1(parseSri$1,`parseSri`),__name$1(pathFor$1,`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`,nP)}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(n,a,S){if(!isEnabled())return null;let C=packumentCacheKey(n,a,S);return _s(cacheRoot(),shardFor(C),`${C}.json`)}function getCachedPackument(n,a,S=`corgi`){let C=pathFor(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(n,a,N);F&&atomicWrite(F,JSON.stringify({etag:S,packument:C}))}var nP,rP=__esmMin(()=>{Os(),WN(),nP=`v3`});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 iP=__esmMin(()=>{Tm()});function parseShebang(n){let a=aP.exec(n.trim());return a?{variables:a[1]??``,prog:a[2]??``,args:a[3]??``}:null}function replaceDollarWithPercentPair(n){return n.replace(/\$\{?([^$@#?\- \t{}:]+)\}?/g,(n,a)=>`%${a}%`)}function convertToSetCommands(n){let a=``;for(let S of n.split(` `)){let n=S.indexOf(`=`);if(n<=0)continue;let C=S.slice(0,n).trim(),N=S.slice(n+1).trim();C&&N&&(a+=`@SET ${C}=${replaceDollarWithPercentPair(N)}\r\n`)}return a}function buildCmdShim(n,a){let S=n.split(`\\`).join(`/`),C=S.split(`/`).join(`\\`),N=S,F=a?.prog??``,I=a?.args??``,H=a?.variables??``,W=F?F.split(`\\`).join(`/`):``,K=W?`"${W}$exe"`:``,q=``,Y=``,X=``;F?(q=`"%dp0%\\${F}.exe"`,Y=`"$basedir/${F}"`,X=`"$basedir/${F}$exe"`,C=`"%dp0%\\${C}"`,S=`"$basedir_win/${S}"`,N=`"$basedir/${N}"`):(F=`"%dp0%\\${C}"`,W=`"$basedir/${S}"`,K=W,I=``,C=``,S=``,N=``);let te;if(q){let n=I.trim();te=oP+convertToSetCommands(H)+`\r
|
|
787
787
|
IF EXIST ${q} (\r\n SET "_prog=${q.replace(/(^")|("$)/g,``)}"\r\n) ELSE (\r
|
|
788
788
|
SET "_prog=${F.replace(/(^")|("$)/g,``)}"\r\n)\r
|
|
789
789
|
\r
|
|
@@ -813,13 +813,20 @@ if (\$MyInvocation.ExpectingInput) {
|
|
|
813
813
|
$input | & ${K} ${N} $args\n} else {
|
|
814
814
|
& ${K} ${N} $args\n}
|
|
815
815
|
exit \$LASTEXITCODE
|
|
816
|
-
`,{sh:ne,cmd:te,ps1:re}}function buildLauncherShims(n){let{interpreter:a,interpreterArgs:S=[],target:C,prependEnv:N={}}=n,
|
|
817
|
-
`;for(let[n,a]of
|
|
816
|
+
`,{sh:ne,cmd:te,ps1:re}}function buildLauncherShims(n){let{interpreter:a,interpreterArgs:S=[],target:C,prependEnv:N={},fallback:F}=n,I=C.split(`/`).join(`\\`),H=S.length>0?`${S.join(` `)} `:``,W=Object.entries(N),K=F===void 0?``:F.target.split(`/`).join(`\\`),q=F?.interpreterArgs!==void 0&&F.interpreterArgs.length>0?`${F.interpreterArgs.join(` `)} `:``,Y=oP;for(let[n,a]of W)Y+=`@SET "${n}=${a};%${n}%"\r\n`;F===void 0?Y+=`${a} ${H}"${I}" %*\r\n`:Y+=`@where ${a} >NUL 2>NUL\r\n@IF %ERRORLEVEL% EQU 0 (\r\n ${a} ${H}"${I}" %*\r\n) ELSE (\r\n ${F.interpreter} ${q}"${K}" %*\r\n)\r\n`;let X=`#!/usr/bin/env pwsh
|
|
817
|
+
`;for(let[n,a]of W)X+=`$env:${n} = "${a};" + $env:${n}\n`;let te=S.map(n=>`"${n}" `).join(``);if(F===void 0)X+=`# Support pipeline input
|
|
818
818
|
if (\$MyInvocation.ExpectingInput) {
|
|
819
|
-
$input | & "${a}" ${
|
|
820
|
-
& "${a}" ${
|
|
821
|
-
|
|
822
|
-
|
|
819
|
+
$input | & "${a}" ${te}"${I}" $args\n} else {
|
|
820
|
+
& "${a}" ${te}"${I}" $args\n}
|
|
821
|
+
`;else{let psList=n=>n.length===0?`@()`:`@(${n.map(n=>`"${n}"`).join(`, `)})`;X+=`$exe = "${a}"; $exeArgs = ${psList(S)}; $script = "${I}"\nif (-not (Get-Command "${a}" -ErrorAction SilentlyContinue)) {\n $exe = "${F.interpreter}"; $exeArgs = ${psList(F.interpreterArgs??[])}; $script = "${K}"\n}
|
|
822
|
+
# Support pipeline input
|
|
823
|
+
if (\$MyInvocation.ExpectingInput) {
|
|
824
|
+
\$input | & \$exe @exeArgs \$script \$args
|
|
825
|
+
} else {
|
|
826
|
+
& \$exe @exeArgs \$script \$args
|
|
827
|
+
}
|
|
828
|
+
`}return X+=`exit $LASTEXITCODE
|
|
829
|
+
`,{cmd:Y,ps1:X}}function shQuote(n){return`'${n.replace(/'/g,`'\\''`)}'`}function buildNativeEnvPreamble(n,a=[],S={}){let C=S.platform??process.platform,N=S.arch??process.arch,F=S.libc===void 0?detectHostLibc(C):S.libc,{name:I,separator:H}=libraryPathVar(C);if(C===`win32`){if(a.length===0)return``;let n=shQuote(a.join(H));return`GI_TYPELIB_PATH=${n}\${GI_TYPELIB_PATH:+"${H}$GI_TYPELIB_PATH"}\n${I}=${n}\${${I}:+"${H}$${I}"}\nexport GI_TYPELIB_PATH ${I}\n`}let W=`${n.replace(/\/+$/,``)}/node_modules/`,K=a.filter(n=>!n.startsWith(W)),q=prebuildDirCandidates(C,N,void 0,F),Y=[];for(let a of q)Y.push(`${shQuote(n)}/node_modules/@*/*/prebuilds/${a}`),Y.push(`${shQuote(n)}/node_modules/*/prebuilds/${a}`);return`gjsify_np=${K.length>0?shQuote(K.join(H)):`''`}\nfor gjsify_d in ${Y.join(` `)}; do\n [ -d "$gjsify_d" ] || continue\n for gjsify_t in "$gjsify_d"/*.typelib; do\n if [ -f "$gjsify_t" ]; then gjsify_np="\${gjsify_np:+$gjsify_np${H}}$gjsify_d"; break; fi\n done\ndone\nif [ -n "$gjsify_np" ]; then\n GI_TYPELIB_PATH="$gjsify_np\${GI_TYPELIB_PATH:+${H}$GI_TYPELIB_PATH}"\n ${I}="$gjsify_np\${${I}:+${H}$${I}}"\n export GI_TYPELIB_PATH ${I}\nfi\nunset gjsify_np gjsify_d gjsify_t\n`}function normalizeBinMap(n,a){let S=new Map;if(typeof a==`string`){let C=n.startsWith(`@`)?n.slice(n.indexOf(`/`)+1):n;return S.set(C,a),S}for(let[n,C]of Object.entries(a))S.set(n,C);return S}function pickBinMap(n,a){let S=a.gjsify?.bin,C=a.bin;return S===void 0?C===void 0?null:{map:normalizeBinMap(n,C),isGjsBin:!1,nodeFallback:null}:{map:normalizeBinMap(n,S),isGjsBin:!0,nodeFallback:C===void 0?null:normalizeBinMap(n,C)}}function buildShLauncher(n,a){let S=a.isGjsBundle?a.envPreamble??``:``;return a.isGjsBundle&&a.nodeFallbackAbs!==void 0?`#!/bin/sh\nif command -v gjs >/dev/null 2>&1; then\n${S}exec gjs -m ${shQuote(n)} "$@"\nfi\nexec node ${shQuote(a.nodeFallbackAbs)} "$@"\n`:`#!/bin/sh\n${S}${a.isGjsBundle?`exec gjs -m ${shQuote(n)} "$@"`:`exec ${shQuote(n)} "$@"`}\n`}function isGjsBundlePath(n){return n.endsWith(`.gjs.mjs`)||n.endsWith(`.mjs`)}var aP,oP,sP,cP,lP=__esmMin(()=>{OM(),aP=/^#!\s*(?:\/usr\/bin\/env\s+(?:-S\s+)?((?:[^ \t=]+=[^ \t=]+\s+)*))?([^ \t]+)(.*)$/,oP=`@ECHO off\r
|
|
823
830
|
GOTO start\r
|
|
824
831
|
:find_dp0\r
|
|
825
832
|
SET dp0=%~dp0\r
|
|
@@ -861,7 +868,7 @@ if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
|
|
861
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(`
|
|
862
869
|
+ `)}`),F.length>0&&I.push(` - ${F.sort().join(`
|
|
863
870
|
- `)}`),I.join(`
|
|
864
|
-
`)}function parseSpec(n){if(n.startsWith(`@`)){let a=n.indexOf(`/`);if(a<0)throw Error(`Invalid spec (scoped name without slash): ${n}`);let S=n.indexOf(`@`,a);return S<0?{name:n,range:`latest`}:{name:n.slice(0,S),range:n.slice(S+1)||`latest`}}let a=n.indexOf(`@`);return a<0?{name:n,range:`latest`}:{name:n.slice(0,a),range:n.slice(a+1)||`latest`}}function pickVersion(n,a,S){if(S&&n.versions[S]&&satisfiesRange(S,a))return S;if(n[`dist-tags`][a])return n[`dist-tags`][a];let C;try{C=new DN(a)}catch{throw Error(`Invalid version range for ${n.name}: ${a}`)}return maxSatisfying(Object.keys(n.versions).filter(n=>{try{return new SemVer(n),!0}catch{return!1}}),C)}async function downloadAndExtractAll(n,a,S,C,N,F){let I=[...n].sort((n,a)=>depth(n.installPath)-depth(a.installPath)||(n.installPath<a.installPath?-1:1)),H=[],W=Math.max(1,Math.min(gP,I.length));F?.beginPhase(`download`,I.length);let K=0,q=0,tickProgress=(n,a)=>{K++,a&&q++,F?.update({phase:`download`,current:K,total:I.length,name:`${n.name}@${n.version}`})},Y=0,X=I.findIndex(n=>depth(n.installPath)>1),te=X<0?I.length:X;for(;Y<te;){if(N?.aborted)throw abortError(N);let n=I[Y++];if(!n)break;tickProgress(n,await extractOne(n,a,S,C,N))}for(let n=0;n<W;n++)H.push((async()=>{for(;;){if(N?.aborted)throw abortError(N);let n=Y++;if(n>=I.length)return;let F=I[n];if(!F)return;let H=await extractOne(F,a,S,C,N);tickProgress(F,H)}})());await Promise.all(H),F?.endPhase(`download`),q>0&&C(`install: %d/%d package(s) already up to date — extracted %d`,q,I.length,I.length-q)}function isAlreadyExtracted(n,a){let S=_s(n,`package.json`),C;try{C=readFileSync(S,`utf-8`)}catch{return!1}try{let n=JSON.parse(C);return!(n.version!==a.version||typeof n.name==`string`&&n.name!==a.name)}catch{return!1}}async function extractOne(n,a,S,C,N){let F=_s(a,n.installPath);if(assertNodeModulesDest(F,n),process.env.GJSIFY_INSTALL_FORCE_EXTRACT!==`1`&&isAlreadyExtracted(F,n))return C(`up-to-date: %s@%s (already extracted at %s)`,n.name,n.version,n.installPath),!0;let I=getCachedTarball(n.integrity);return I?C(`cache-hit: %s@%s ← %s`,n.name,n.version,n.integrity):(I=getForeignCachedTarball(n.integrity))?(C(`npm-cache-hit: %s@%s ← %s`,n.name,n.version,n.integrity),putCachedTarball(n.integrity,I)):(C(`fetch: %s@%s ← %s (→ %s)`,n.name,n.version,n.tarballUrl,n.installPath),I=await fetchTarball(n.tarballUrl,{npmrc:S,signal:N,integrity:n.integrity,onRetry:({attempt:a,error:S,delayMs:N})=>{C(`tarball %s@%s: retry %d after %dms (%s)`,n.name,n.version,a,N,errMsg(S))}}),putCachedTarball(n.integrity,I)),rmWithRetry(F),mkdirSync(F,{recursive:!0}),await extractWithStallGuard(I,F,n,N),!1}async function extractWithStallGuard(n,a,S,C){if(bP===0&&!C){await extractTarball(n,a);return}let N,onAbort;try{await new Promise((F,I)=>{if(process.env.GJSIFY_TEST_HANG_EXTRACT!==`1`&&extractTarball(n,a).then(()=>F(),I),bP>0&&(N=setTimeout(()=>{I(Error(`gjsify install: extract of ${S.name}@${S.version} stalled for ${Math.round(bP/1e3)}s (${S.installPath}) — the tarball decompress/write never completed. This is usually a dropped Gio stream event under GJS; re-run the install. Override the cap with GJSIFY_EXTRACT_STALL_MS=<ms> (0 disables it).`))},bP),N.unref?.()),C){if(C.aborted){I(abortError(C));return}onAbort=()=>I(abortError(C)),C.addEventListener(`abort`,onAbort,{once:!0})}})}finally{N&&clearTimeout(N),C&&onAbort&&C.removeEventListener(`abort`,onAbort)}}function abortError(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 assertNodeModulesDest(n,a){if(!n.split(Ts).includes(`node_modules`))throw Error(`gjsify install: refusing to extract ${a.name}@${a.version} into ${n} — target is not inside a node_modules/ directory. This would overwrite working-tree files. A workspace package likely leaked into the fetch queue (it must be symlinked, not fetched).`);let S;try{S=realpathSync(n)}catch{return}if(!S.split(Ts).includes(`node_modules`))throw Error(`gjsify install: refusing to extract ${a.name}@${a.version} — ${n} resolves to ${S}, which is outside any node_modules/ directory (likely a symlink to a workspace source tree). Extracting here would delete working-tree source files.`)}function depth(n){return n.split(`/node_modules/`).length}function readShebang(n){let a;try{a=readFileSync(n,`utf-8`)}catch{return null}return parseShebang(a.trimStart().split(/\r*\n/,1)[0]??``)}function writeBinEntry(n){let{binDir:a,binName:S,targetAbs:C,gjs:N}=n,F=n.platform??process.platform,I=_s(a,S);if(N){let n=isGjsBundlePath(C);for(let n of[I,`${I}.cmd`,`${I}.ps1`])rmWithRetry(n);writeFileSync(I,buildShLauncher(C,{envPreamble:N.envPreamble,isGjsBundle:n}));try{chmodSync(I,493)}catch{}if(F===`win32`&&n){let n=N.prebuildDirs.join(`;`),a=buildLauncherShims({interpreter:`gjs`,interpreterArgs:[`-m`],target:C,prependEnv:N.prebuildDirs.length>0?{GI_TYPELIB_PATH:n,PATH:n}:{}});writeFileSync(`${I}.cmd`,a.cmd),writeFileSync(`${I}.ps1`,a.ps1)}return}if(F===`win32`){let{sh:n,cmd:S,ps1:N}=buildCmdShim(vs(a,C).split(`\\`).join(`/`),readShebang(C));for(let[a,C]of[[I,n],[`${I}.cmd`,S],[`${I}.ps1`,N]]){rmWithRetry(a),writeFileSync(a,C);try{chmodSync(a,493)}catch{}}return}rmWithRetry(I);let H=vs(a,C);try{symlinkSync(H,I)}catch{copyFileSync(C,I),chmodSync(I,493)}}async function linkBins(n,a,S){let C=_s(a,`node_modules`,`.bin`),N=0,F,gjsEnvForPrefix=()=>{if(F===void 0){let n=detectNativePackages(a).map(n=>n.prebuildsDir);F={envPreamble:buildNativeEnvPreamble(a,n),prebuildDirs:n}}return F};for(let S of n){if(depth(S.installPath)!==1)continue;let n=_s(a,S.installPath),F=readInstalledManifest(n)??(S.bin===void 0?null:{bin:S.bin});if(F===null)continue;let I=pickBinMap(S.name,F);if(!(I===null||I.map.size===0)){mkdirSync(C,{recursive:!0});for(let[a,S]of I.map){let F=_s(n,S);if(existsSync(F)){try{chmodSync(F,493)}catch{}writeBinEntry({binDir:C,binName:a,targetAbs:F,gjs:I.isGjsBin?gjsEnvForPrefix():void 0}),N++}}}}N>0&&S(`bin: linked %d entry(ies) under .bin/`,N)}function readInstalledManifest(n){try{let a=readFileSync(_s(n,`package.json`),`utf-8`);return JSON.parse(a)}catch{return null}}function rmWithRetry(n){rmSync(n,{recursive:!0,force:!0,maxRetries:10,retryDelay:100})}async function loadNpmrc$1(n){let a=homedir(),S={registry:n.registry??jN,scopes:{},authTokens:{},basicAuth:{}};for(let C of[_s(a,`.npmrc`),_s(n.prefix,`.npmrc`)])if(existsSync(C))try{let n=parseNpmrc(readFileSync(C,`utf-8`));S={...S,...n,scopes:{...S.scopes,...n.scopes}}}catch(n){ge.warn(`gjsify install: ignoring malformed ${C}: ${n.message}`)}let C=process.env.npm_config_registry;return C&&(S.registry=C),n.registry&&(S.registry=n.registry),S}function makeLogger(n){return n?(n,...a)=>{let S=n.replace(/%s|%d/g,()=>String(a.shift()));process.stderr.write(`gjsify install: ${S}\n`)}:()=>{}}var gP,_P,vP,yP,bP,xP=__esmMin(()=>{_e(),gl(),Os(),um(),ON(),RN(),UN(),WN(),$N(),tP(),rP(),iP(),lP(),OM(),mP(),gP=Number(process.env.GJSIFY_INSTALL_CONCURRENCY??`16`)||16,_P=`gjsify-lock.json`,vP=4,yP=new Set([2,3,vP]),bP=(()=>{let n=process.env.GJSIFY_EXTRACT_STALL_MS;if(n===void 0)return 12e4;let a=Number(n);return Number.isFinite(a)&&a>=0?a:12e4})(),__name$1(loadNpmrc$1,`loadNpmrc`)}),SP=__exportAll$4({installPackages:()=>installPackages,makeProgressReporter:()=>makeProgressReporter});async function installPackages(n){if(CP===`npm`)return await installViaNpm(n),{installed:[]};let{installPackagesNative:a}=await Promise.resolve().then(()=>(xP(),hP));return{installed:await a(n)}}async function installViaNpm({prefix:n,specs:a,verbose:S,registry:C}){if(a.length===0)throw Error(`installPackages: empty specs list`);writeFileSync(_s(n,`package.json`),JSON.stringify({name:`gjsify-dlx-cache`,version:`0.0.0`,private:!0},null,2)),C&&writeFileSync(_s(n,`.npmrc`),`registry=${C}\n`);let{code:N}=await spawnToCompletion(`npm`,[`install`,`--no-package-lock`,`--no-audit`,`--no-fund`,`--prefix`,n,...S?[`--loglevel`,`verbose`]:[`--loglevel`,`warn`],...a],{completion:`return`,notFound:n=>Error(`npm not found on PATH — install Node.js, or unset GJSIFY_INSTALL_BACKEND to use the default native backend (${n.message})`)});if(N!==0)throw Error(`npm install exited with code ${N}`)}var CP,wP=__esmMin(()=>{gl(),Os(),tN(),wN(),CP=process.env.GJSIFY_INSTALL_BACKEND??`native`});async function ensurePkgDir(n,a){if(n.kind===`local`)return{pkgDir:n.path,cachedPkgName:null};let S=[n.spec,...a.extraSpecs??[]],C=cacheDirFor(createCacheKey({packages:S})),N=a.cacheMaxAge>0?getValidCachedPkg(C,a.cacheMaxAge):void 0;if(N)return{pkgDir:resolveInstalledPkgDir(N,n.name),cachedPkgName:n.name};let F=makePrepareDir(C),I=makeProgressReporter({enabled:!a.verbose});return await installPackages({prefix:F,specs:S,verbose:a.verbose,registry:a.registry,lockfile:!0,frozen:a.frozen,progress:I}),{pkgDir:resolveInstalledPkgDir(symlinkSwap(C,F),n.name),cachedPkgName:n.name}}function splitBinAndArgs(n,a,S){if(!a)return{binName:null,extraArgs:S};let C=_s(n,`package.json`);if(existsSync(C))try{let n=JSON.parse(readFileSync(C,`utf-8`)).gjsify?.bin;if(n&&Object.prototype.hasOwnProperty.call(n,a))return{binName:a,extraArgs:S}}catch{}return{binName:null,extraArgs:[a,...S]}}var TP,EP=__esmMin(()=>{_e(),AM(),gN(),_N(),bN(),wP(),gl(),Os(),TP={command:`dlx <spec> [binOrArg] [extraArgs..]`,description:`Run the GJS bundle of an npm-published package without installing it locally.`,builder:n=>n.parserConfiguration({"populate--":!0}).positional(`spec`,{description:"Package spec (`name`, `name@version`, `@scope/name@spec`, or local path).",type:`string`,demandOption:!0}).positional(`binOrArg`,{description:"Optional bin name when the package defines `gjsify.bin` with multiple entries; otherwise treated as the first argument forwarded to the bundle. To pass a flag here (e.g. `--help`) use the `--` separator: `gjsify dlx <pkg> -- --help`.",type:`string`}).positional(`extraArgs`,{description:"Extra args forwarded to `gjs -m <bundle>`. Use `--` before flags to bypass gjsify-level parsing (`gjsify dlx <pkg> -- --help --verbose`).",type:`string`,array:!0}).option(`cache-max-age`,{description:`Cache TTL in minutes. Defaults to 7 days. Use 0 to bypass cache.`,type:`number`,default:1440*7}).option(`reinstall`,{description:`Bypass the cache for this run (alias for --cache-max-age=0).`,type:`boolean`,default:!1}).option(`frozen`,{description:`Use the project-local gjsify-lock.json verbatim — fail if missing or stale (no resolver pass).`,type:`boolean`,default:!1}).option(`verbose`,{description:`Verbose logging (passes --loglevel verbose to npm).`,type:`boolean`,default:!1}).option(`registry`,{description:`Registry URL override.`,type:`string`}),handler:async n=>{let a=parseSpec$1(n.spec),S=n.reinstall?0:n[`cache-max-age`],{pkgDir:C,cachedPkgName:N}=await ensurePkgDir(a,{verbose:n.verbose,registry:n.registry,cacheMaxAge:S,frozen:n.frozen}),F=(n[`--`]??[]).map(n=>String(n)),I=[...n.extraArgs??[],...F],{binName:H,extraArgs:W}=splitBinAndArgs(C,n.binOrArg,I),K=resolveGjsEntry(C,H);K.fromFallback&&ge.warn(`[gjsify dlx] package "${N??a.kind}" declares no \`gjsify.main\` — falling back to package.json#main. Add \`gjsify.main\` to silence.`),await runGjsBundle(K.bundlePath,W,{exitOnSuccess:!0})}}});function readCliVersion(){try{let n=new URL(`../../package.json`,import.meta.url),a=JSON.parse(readFileSync(n,`utf8`));return typeof a.version==`string`?a.version:void 0}catch{return}}function runningAs(n){return n?`[gjsify ${n}] `:``}async function resolveShowcaseDir(n,a,S=[]){try{let a=createRequire(import.meta.url).resolve(`${n.packageName}/package.json`);if(existsSync(a))return bs(a)}catch{}let{pkgDir:C}=await ensurePkgDir(parseSpec$1(a?`${n.packageName}@${a}`:n.packageName),{verbose:!1,cacheMaxAge:1440*7,frozen:!1,extraSpecs:S});return C}async function runShowcaseOnRuntime(n,a,S){let C;try{C=await resolveShowcaseDir(n,S,[S?`@gjsify/node-gi@${S}`:`@gjsify/node-gi`])}catch(a){return ge.error(`Could not resolve showcase "${n.name}": ${a.message}`),process.exit(1)}let N={};try{N=JSON.parse(readFileSync(`${C}/package.json`,`utf-8`))}catch{}let F=checkRuntimeSupported(a,readDeclaredRuntimes(N),n.name);if(!F.ok)return ge.error(F.message),process.exit(1);let I;try{I=resolveNodeEntry(C)}catch(C){let F=typeof N.name==`string`?`${N.name}@${S??`?`}`:n.packageName;return ge.error(`Cannot run showcase "${n.name}" on ${a}: ${C.message}\n\n ${F} declares --runtime ${a} but ships no \`--app node\` bundle, so that\n version of the showcase cannot run there. You are running gjsify ${S??`(unknown)`},\n and \`showcase\` pins the showcase to the CLI's own version.\n\n ${DP}\n\n Or run it on GJS, which every showcase ships: gjsify showcase ${n.name} --runtime gjs`),process.exit(1)}ge.log(`Running showcase: ${n.name} ${runningAs(S)}on ${a} (${I})\n`);try{await runRuntimeBundle(a,I,[],{exitOnSuccess:!0})}catch(n){return ge.error(`${n.message}\n\n The showcase and the \`@gjsify/node-gi\` bridge it needs are both installed by THIS CLI\n (gjsify ${S??`(unknown)`}) into its own cache, so a missing bridge points at the CLI\n rather than at anything in your project.\n\n ${DP}`),process.exit(1)}}var DP,OP,kP=__esmMin(()=>{_e(),mN(),GM(),is(),Os(),gl(),EP(),gN(),_N(),MM(),eh(),DP=`A package runner reuses a CACHED copy of an unpinned bin. Force the current one:
|
|
871
|
+
`)}function parseSpec(n){if(n.startsWith(`@`)){let a=n.indexOf(`/`);if(a<0)throw Error(`Invalid spec (scoped name without slash): ${n}`);let S=n.indexOf(`@`,a);return S<0?{name:n,range:`latest`}:{name:n.slice(0,S),range:n.slice(S+1)||`latest`}}let a=n.indexOf(`@`);return a<0?{name:n,range:`latest`}:{name:n.slice(0,a),range:n.slice(a+1)||`latest`}}function pickVersion(n,a,S){if(S&&n.versions[S]&&satisfiesRange(S,a))return S;if(n[`dist-tags`][a])return n[`dist-tags`][a];let C;try{C=new DN(a)}catch{throw Error(`Invalid version range for ${n.name}: ${a}`)}return maxSatisfying(Object.keys(n.versions).filter(n=>{try{return new SemVer(n),!0}catch{return!1}}),C)}async function downloadAndExtractAll(n,a,S,C,N,F){let I=[...n].sort((n,a)=>depth(n.installPath)-depth(a.installPath)||(n.installPath<a.installPath?-1:1)),H=[],W=Math.max(1,Math.min(gP,I.length));F?.beginPhase(`download`,I.length);let K=0,q=0,tickProgress=(n,a)=>{K++,a&&q++,F?.update({phase:`download`,current:K,total:I.length,name:`${n.name}@${n.version}`})},Y=0,X=I.findIndex(n=>depth(n.installPath)>1),te=X<0?I.length:X;for(;Y<te;){if(N?.aborted)throw abortError(N);let n=I[Y++];if(!n)break;tickProgress(n,await extractOne(n,a,S,C,N))}for(let n=0;n<W;n++)H.push((async()=>{for(;;){if(N?.aborted)throw abortError(N);let n=Y++;if(n>=I.length)return;let F=I[n];if(!F)return;let H=await extractOne(F,a,S,C,N);tickProgress(F,H)}})());await Promise.all(H),F?.endPhase(`download`),q>0&&C(`install: %d/%d package(s) already up to date — extracted %d`,q,I.length,I.length-q)}function isAlreadyExtracted(n,a){let S=_s(n,`package.json`),C;try{C=readFileSync(S,`utf-8`)}catch{return!1}try{let n=JSON.parse(C);return!(n.version!==a.version||typeof n.name==`string`&&n.name!==a.name)}catch{return!1}}async function extractOne(n,a,S,C,N){let F=_s(a,n.installPath);if(assertNodeModulesDest(F,n),process.env.GJSIFY_INSTALL_FORCE_EXTRACT!==`1`&&isAlreadyExtracted(F,n))return C(`up-to-date: %s@%s (already extracted at %s)`,n.name,n.version,n.installPath),!0;let I=getCachedTarball(n.integrity);return I?C(`cache-hit: %s@%s ← %s`,n.name,n.version,n.integrity):(I=getForeignCachedTarball(n.integrity))?(C(`npm-cache-hit: %s@%s ← %s`,n.name,n.version,n.integrity),putCachedTarball(n.integrity,I)):(C(`fetch: %s@%s ← %s (→ %s)`,n.name,n.version,n.tarballUrl,n.installPath),I=await fetchTarball(n.tarballUrl,{npmrc:S,signal:N,integrity:n.integrity,onRetry:({attempt:a,error:S,delayMs:N})=>{C(`tarball %s@%s: retry %d after %dms (%s)`,n.name,n.version,a,N,errMsg(S))}}),putCachedTarball(n.integrity,I)),rmWithRetry(F),mkdirSync(F,{recursive:!0}),await extractWithStallGuard(I,F,n,N),!1}async function extractWithStallGuard(n,a,S,C){if(bP===0&&!C){await extractTarball(n,a);return}let N,onAbort;try{await new Promise((F,I)=>{if(process.env.GJSIFY_TEST_HANG_EXTRACT!==`1`&&extractTarball(n,a).then(()=>F(),I),bP>0&&(N=setTimeout(()=>{I(Error(`gjsify install: extract of ${S.name}@${S.version} stalled for ${Math.round(bP/1e3)}s (${S.installPath}) — the tarball decompress/write never completed. This is usually a dropped Gio stream event under GJS; re-run the install. Override the cap with GJSIFY_EXTRACT_STALL_MS=<ms> (0 disables it).`))},bP),N.unref?.()),C){if(C.aborted){I(abortError(C));return}onAbort=()=>I(abortError(C)),C.addEventListener(`abort`,onAbort,{once:!0})}})}finally{N&&clearTimeout(N),C&&onAbort&&C.removeEventListener(`abort`,onAbort)}}function abortError(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 assertNodeModulesDest(n,a){if(!n.split(Ts).includes(`node_modules`))throw Error(`gjsify install: refusing to extract ${a.name}@${a.version} into ${n} — target is not inside a node_modules/ directory. This would overwrite working-tree files. A workspace package likely leaked into the fetch queue (it must be symlinked, not fetched).`);let S;try{S=realpathSync(n)}catch{return}if(!S.split(Ts).includes(`node_modules`))throw Error(`gjsify install: refusing to extract ${a.name}@${a.version} — ${n} resolves to ${S}, which is outside any node_modules/ directory (likely a symlink to a workspace source tree). Extracting here would delete working-tree source files.`)}function depth(n){return n.split(`/node_modules/`).length}function readShebang(n){let a;try{a=readFileSync(n,`utf-8`)}catch{return null}return parseShebang(a.trimStart().split(/\r*\n/,1)[0]??``)}function writeBinEntry(n){let{binDir:a,binName:S,targetAbs:C,gjs:N,nodeFallbackAbs:F}=n,I=n.platform??process.platform,H=_s(a,S);if(N){let n=isGjsBundlePath(C);for(let n of[H,`${H}.cmd`,`${H}.ps1`])rmWithRetry(n);writeFileSync(H,buildShLauncher(C,{envPreamble:N.envPreamble,isGjsBundle:n,nodeFallbackAbs:F}));try{chmodSync(H,493)}catch{}if(I===`win32`&&n){let n=N.prebuildDirs.join(`;`),a=buildLauncherShims({interpreter:`gjs`,interpreterArgs:[`-m`],target:C,prependEnv:N.prebuildDirs.length>0?{GI_TYPELIB_PATH:n,PATH:n}:{},fallback:F===void 0?void 0:{interpreter:`node`,target:F}});writeFileSync(`${H}.cmd`,a.cmd),writeFileSync(`${H}.ps1`,a.ps1)}return}if(I===`win32`){let{sh:n,cmd:S,ps1:N}=buildCmdShim(vs(a,C).split(`\\`).join(`/`),readShebang(C));for(let[a,C]of[[H,n],[`${H}.cmd`,S],[`${H}.ps1`,N]]){rmWithRetry(a),writeFileSync(a,C);try{chmodSync(a,493)}catch{}}return}rmWithRetry(H);let W=vs(a,C);try{symlinkSync(W,H)}catch{copyFileSync(C,H),chmodSync(H,493)}}async function linkBins(n,a,S){let C=_s(a,`node_modules`,`.bin`),N=0,F,gjsEnvForPrefix=()=>{if(F===void 0){let n=detectNativePackages(a).map(n=>n.prebuildsDir);F={envPreamble:buildNativeEnvPreamble(a,n),prebuildDirs:n}}return F};for(let S of n){if(depth(S.installPath)!==1)continue;let n=_s(a,S.installPath),F=readInstalledManifest(n)??(S.bin===void 0?null:{bin:S.bin});if(F===null)continue;let I=pickBinMap(S.name,F);if(!(I===null||I.map.size===0)){mkdirSync(C,{recursive:!0});for(let[a,S]of I.map){let F=_s(n,S);if(!existsSync(F))continue;try{chmodSync(F,493)}catch{}let H=I.nodeFallback?.get(a),W=H===void 0?void 0:_s(n,H);writeBinEntry({binDir:C,binName:a,targetAbs:F,gjs:I.isGjsBin?gjsEnvForPrefix():void 0,nodeFallbackAbs:W!==void 0&&existsSync(W)?W:void 0}),N++}}}N>0&&S(`bin: linked %d entry(ies) under .bin/`,N)}function readInstalledManifest(n){try{let a=readFileSync(_s(n,`package.json`),`utf-8`);return JSON.parse(a)}catch{return null}}function rmWithRetry(n){rmSync(n,{recursive:!0,force:!0,maxRetries:10,retryDelay:100})}async function loadNpmrc$1(n){let a=homedir(),S={registry:n.registry??jN,scopes:{},authTokens:{},basicAuth:{}};for(let C of[_s(a,`.npmrc`),_s(n.prefix,`.npmrc`)])if(existsSync(C))try{let n=parseNpmrc(readFileSync(C,`utf-8`));S={...S,...n,scopes:{...S.scopes,...n.scopes}}}catch(n){ge.warn(`gjsify install: ignoring malformed ${C}: ${n.message}`)}let C=process.env.npm_config_registry;return C&&(S.registry=C),n.registry&&(S.registry=n.registry),S}function makeLogger(n){return n?(n,...a)=>{let S=n.replace(/%s|%d/g,()=>String(a.shift()));process.stderr.write(`gjsify install: ${S}\n`)}:()=>{}}var gP,_P,vP,yP,bP,xP=__esmMin(()=>{_e(),gl(),Os(),um(),ON(),RN(),UN(),WN(),$N(),tP(),rP(),iP(),lP(),OM(),mP(),gP=Number(process.env.GJSIFY_INSTALL_CONCURRENCY??`16`)||16,_P=`gjsify-lock.json`,vP=4,yP=new Set([2,3,vP]),bP=(()=>{let n=process.env.GJSIFY_EXTRACT_STALL_MS;if(n===void 0)return 12e4;let a=Number(n);return Number.isFinite(a)&&a>=0?a:12e4})(),__name$1(loadNpmrc$1,`loadNpmrc`)}),SP=__exportAll$4({installPackages:()=>installPackages,makeProgressReporter:()=>makeProgressReporter});async function installPackages(n){if(CP===`npm`)return await installViaNpm(n),{installed:[]};let{installPackagesNative:a}=await Promise.resolve().then(()=>(xP(),hP));return{installed:await a(n)}}async function installViaNpm({prefix:n,specs:a,verbose:S,registry:C}){if(a.length===0)throw Error(`installPackages: empty specs list`);writeFileSync(_s(n,`package.json`),JSON.stringify({name:`gjsify-dlx-cache`,version:`0.0.0`,private:!0},null,2)),C&&writeFileSync(_s(n,`.npmrc`),`registry=${C}\n`);let{code:N}=await spawnToCompletion(`npm`,[`install`,`--no-package-lock`,`--no-audit`,`--no-fund`,`--prefix`,n,...S?[`--loglevel`,`verbose`]:[`--loglevel`,`warn`],...a],{completion:`return`,notFound:n=>Error(`npm not found on PATH — install Node.js, or unset GJSIFY_INSTALL_BACKEND to use the default native backend (${n.message})`)});if(N!==0)throw Error(`npm install exited with code ${N}`)}var CP,wP=__esmMin(()=>{gl(),Os(),tN(),wN(),CP=process.env.GJSIFY_INSTALL_BACKEND??`native`});async function ensurePkgDir(n,a){if(n.kind===`local`)return{pkgDir:n.path,cachedPkgName:null};let S=[n.spec,...a.extraSpecs??[]],C=cacheDirFor(createCacheKey({packages:S})),N=a.cacheMaxAge>0?getValidCachedPkg(C,a.cacheMaxAge):void 0;if(N)return{pkgDir:resolveInstalledPkgDir(N,n.name),cachedPkgName:n.name};let F=makePrepareDir(C),I=makeProgressReporter({enabled:!a.verbose});return await installPackages({prefix:F,specs:S,verbose:a.verbose,registry:a.registry,lockfile:!0,frozen:a.frozen,progress:I}),{pkgDir:resolveInstalledPkgDir(symlinkSwap(C,F),n.name),cachedPkgName:n.name}}function splitBinAndArgs(n,a,S){if(!a)return{binName:null,extraArgs:S};let C=_s(n,`package.json`);if(existsSync(C))try{let n=JSON.parse(readFileSync(C,`utf-8`)).gjsify?.bin;if(n&&Object.prototype.hasOwnProperty.call(n,a))return{binName:a,extraArgs:S}}catch{}return{binName:null,extraArgs:[a,...S]}}var TP,EP=__esmMin(()=>{_e(),AM(),gN(),_N(),bN(),wP(),gl(),Os(),TP={command:`dlx <spec> [binOrArg] [extraArgs..]`,description:`Run the GJS bundle of an npm-published package without installing it locally.`,builder:n=>n.parserConfiguration({"populate--":!0}).positional(`spec`,{description:"Package spec (`name`, `name@version`, `@scope/name@spec`, or local path).",type:`string`,demandOption:!0}).positional(`binOrArg`,{description:"Optional bin name when the package defines `gjsify.bin` with multiple entries; otherwise treated as the first argument forwarded to the bundle. To pass a flag here (e.g. `--help`) use the `--` separator: `gjsify dlx <pkg> -- --help`.",type:`string`}).positional(`extraArgs`,{description:"Extra args forwarded to `gjs -m <bundle>`. Use `--` before flags to bypass gjsify-level parsing (`gjsify dlx <pkg> -- --help --verbose`).",type:`string`,array:!0}).option(`cache-max-age`,{description:`Cache TTL in minutes. Defaults to 7 days. Use 0 to bypass cache.`,type:`number`,default:1440*7}).option(`reinstall`,{description:`Bypass the cache for this run (alias for --cache-max-age=0).`,type:`boolean`,default:!1}).option(`frozen`,{description:`Use the project-local gjsify-lock.json verbatim — fail if missing or stale (no resolver pass).`,type:`boolean`,default:!1}).option(`verbose`,{description:`Verbose logging (passes --loglevel verbose to npm).`,type:`boolean`,default:!1}).option(`registry`,{description:`Registry URL override.`,type:`string`}),handler:async n=>{let a=parseSpec$1(n.spec),S=n.reinstall?0:n[`cache-max-age`],{pkgDir:C,cachedPkgName:N}=await ensurePkgDir(a,{verbose:n.verbose,registry:n.registry,cacheMaxAge:S,frozen:n.frozen}),F=(n[`--`]??[]).map(n=>String(n)),I=[...n.extraArgs??[],...F],{binName:H,extraArgs:W}=splitBinAndArgs(C,n.binOrArg,I),K=resolveGjsEntry(C,H);K.fromFallback&&ge.warn(`[gjsify dlx] package "${N??a.kind}" declares no \`gjsify.main\` — falling back to package.json#main. Add \`gjsify.main\` to silence.`),await runGjsBundle(K.bundlePath,W,{exitOnSuccess:!0})}}});function readCliVersion(){try{let n=new URL(`../../package.json`,import.meta.url),a=JSON.parse(readFileSync(n,`utf8`));return typeof a.version==`string`?a.version:void 0}catch{return}}function runningAs(n){return n?`[gjsify ${n}] `:``}async function resolveShowcaseDir(n,a,S=[]){try{let a=createRequire(import.meta.url).resolve(`${n.packageName}/package.json`);if(existsSync(a))return bs(a)}catch{}let{pkgDir:C}=await ensurePkgDir(parseSpec$1(a?`${n.packageName}@${a}`:n.packageName),{verbose:!1,cacheMaxAge:1440*7,frozen:!1,extraSpecs:S});return C}async function runShowcaseOnRuntime(n,a,S){let C;try{C=await resolveShowcaseDir(n,S,[S?`@gjsify/node-gi@${S}`:`@gjsify/node-gi`])}catch(a){return ge.error(`Could not resolve showcase "${n.name}": ${a.message}`),process.exit(1)}let N={};try{N=JSON.parse(readFileSync(`${C}/package.json`,`utf-8`))}catch{}let F=checkRuntimeSupported(a,readDeclaredRuntimes(N),n.name);if(!F.ok)return ge.error(F.message),process.exit(1);let I;try{I=resolveNodeEntry(C)}catch(C){let F=typeof N.name==`string`?`${N.name}@${S??`?`}`:n.packageName;return ge.error(`Cannot run showcase "${n.name}" on ${a}: ${C.message}\n\n ${F} declares --runtime ${a} but ships no \`--app node\` bundle, so that\n version of the showcase cannot run there. You are running gjsify ${S??`(unknown)`},\n and \`showcase\` pins the showcase to the CLI's own version.\n\n ${DP}\n\n Or run it on GJS, which every showcase ships: gjsify showcase ${n.name} --runtime gjs`),process.exit(1)}ge.log(`Running showcase: ${n.name} ${runningAs(S)}on ${a} (${I})\n`);try{await runRuntimeBundle(a,I,[],{exitOnSuccess:!0})}catch(n){return ge.error(`${n.message}\n\n The showcase and the \`@gjsify/node-gi\` bridge it needs are both installed by THIS CLI\n (gjsify ${S??`(unknown)`}) into its own cache, so a missing bridge points at the CLI\n rather than at anything in your project.\n\n ${DP}`),process.exit(1)}}var DP,OP,kP=__esmMin(()=>{_e(),mN(),GM(),is(),Os(),gl(),EP(),gN(),_N(),MM(),eh(),DP=`A package runner reuses a CACHED copy of an unpinned bin. Force the current one:
|
|
865
872
|
npx @gjsify/cli@latest showcase <name>
|
|
866
873
|
bunx @gjsify/cli@latest showcase <name>
|
|
867
874
|
deno run -A --reload --min-dep-age 0 npm:@gjsify/cli@latest showcase <name>`,OP={command:`showcase [name]`,description:`List or run curated gjsify showcase applications.`,builder:n=>n.positional(`name`,{description:`Showcase name to run (omit to list all)`,type:`string`}).option(`json`,{description:`Output as JSON`,type:`boolean`,default:!1}).option(`list`,{description:`List available showcases`,type:`boolean`,default:!1}).option(`runtime`,{type:`string`,choices:Qm,defaultDescription:`gjs when gjs is installed, else the host runtime`,description:"Runtime to run the showcase on: gjs | node | bun | deno (default: gjs when installed, else the host runtime). node/bun/deno run its `--app node` bundle."}),handler:async n=>{if(!n.name||n.list){let a=discoverShowcases();if(n.json){ge.log(JSON.stringify(a,null,2));return}if(a.length===0){ge.log("No showcases found. The CLI ships a curated list in `showcases.json`; if it is missing the CLI install is incomplete.");return}let S=new Map;for(let n of a){let a=S.get(n.category)??[];a.push(n),S.set(n.category,a)}ge.log(`Available gjsify showcases:
|
|
@@ -904,16 +911,16 @@ jobs:
|
|
|
904
911
|
cache-key: ${n.cacheKey}
|
|
905
912
|
`}var lF,uF=__esmMin(()=>{_e(),gl(),Os(),dM(),XP(),lF={command:`ci`,description:`Scaffold .github/workflows/flatpak.yml using the flathub-infra container + flatpak-builder@v6 action.`,builder:n=>n.option(`manifest`,{description:`Manifest path the workflow points at (default: <app-id>.json)`,type:`string`,normalize:!0}).option(`bundle`,{description:`Bundle filename produced by the action (default: <app-id>.flatpak)`,type:`string`,normalize:!0}).option(`runtime-image`,{description:"Container image override. Default derived from gjsify.flatpak.runtime + runtimeVersion (e.g. `ghcr.io/flathub-infra/flatpak-github-actions:gnome-50`).",type:`string`}).option(`branches`,{description:`Branches the workflow runs on push for (default: main)`,type:`string`,array:!0}).option(`out`,{description:`Output path`,type:`string`,default:`.github/workflows/flatpak.yml`,normalize:!0}).option(`cache-key`,{description:"Override the action `cache-key` (default: `flatpak-builder-${{ github.sha }}`)",type:`string`}).option(`force`,{description:`Overwrite an existing workflow file`,type:`boolean`,default:!1}).option(`verbose`,{description:`Print resolved fields`,type:`boolean`,default:!1}),handler:async n=>{let a=process.cwd(),S=(await new Config().forBuild({}).catch(()=>({}))).flatpak??{},C=readPackageJson(a),N=S.appId??(looksLikeAppId(C.name)?C.name:void 0);if(!N)throw Error(`gjsify flatpak ci: no app id available. Set gjsify.flatpak.appId in package.json or rename the package to a reverse-DNS id.`);let F=n.manifest??`${N}.json`,I=n.bundle??`${N}.flatpak`,{runtime:H,runtimeVersion:W}=resolveRuntime(S,{}),K=n.runtimeImage??S.ciContainer??defaultCiContainer(H,W),q=n.branches??S.ciBranches??[`main`],Y=n.cacheKey??"flatpak-builder-${{ github.sha }}",X=ms(a,n.out??`.github/workflows/flatpak.yml`);if(existsSync(X)&&!n.force){if(readFileSync(X,`utf-8`)===renderWorkflow({manifest:F,bundle:I,runtimeImage:K,branches:q,cacheKey:Y})){ge.log(`[gjsify flatpak ci] ${X} already up to date`);return}throw Error(`gjsify flatpak ci: ${X} exists with different content. Pass --force to overwrite.`)}let te=renderWorkflow({manifest:F,bundle:I,runtimeImage:K,branches:q,cacheKey:Y});mkdirSync(bs(X),{recursive:!0}),writeFileSync(X,te,`utf-8`),n.verbose&&ge.log(`[gjsify flatpak ci] runtime-image=${K} manifest=${F} bundle=${I}`),ge.log(`[gjsify flatpak ci] wrote ${X}`)}}});function resolveAppId(n,a,S){if(a.appId)return a.appId;try{let n=readPackageJson(S);if(looksLikeAppId(n.name))return n.name}catch{}if(n)return n.replace(/\.json$/,``)}function resolveManifestPath(n,a,S){if(n)return ms(S,n);if(a)return ms(S,`${a}.json`);let C=readdirSync(S).filter(n=>n.endsWith(`.json`)&&!n.startsWith(`package`));if(C.length===1)return ms(S,C[0]);throw Error(`gjsify flatpak check: no manifest path given and could not auto-detect. Pass the manifest as a positional argument.`)}function runLinter(n,a,S){return new Promise(C=>{let N=spawn(n,a,{stdio:S?`inherit`:[`ignore`,`pipe`,`pipe`]}),F=``,I=``;S||(N.stdout?.setEncoding(`utf-8`),N.stderr?.setEncoding(`utf-8`),N.stdout?.on(`data`,n=>{F+=n}),N.stderr?.on(`data`,n=>{I+=n})),N.on(`error`,a=>{let S=a;S.code===`ENOENT`?ge.error(`[gjsify flatpak check] ${n} not found in PATH.\nInstall via:\n flatpak install -y flathub org.flatpak.Builder\n alias ${n}="flatpak run --command=${n} org.flatpak.Builder"`):ge.error(`[gjsify flatpak check] ${n} failed to spawn: ${S.message}`),C(!1)}),N.on(`exit`,N=>{let H=N===0,W=H?`OK`:`FAIL`;ge.log(`[gjsify flatpak check] ${W}: ${n} ${a.join(` `)}`),!H&&!S&&(F.trim()&&ge.log(F.trimEnd()),I.trim()&&ge.error(I.trimEnd())),C(H)})})}var dF,fF=__esmMin(()=>{_e(),gl(),Os(),Xm(),XP(),dM(),dF={command:`check [manifest]`,description:`Run Flathub pre-submission linters: appstreamcli validate + flatpak-builder-lint.`,builder:n=>n.positional(`manifest`,{description:"Path to the Flatpak manifest. Auto-detects `<app-id>.json` if omitted.",type:`string`,normalize:!0}).option(`repo`,{description:"Built ostree-repo path. If given, also runs `flatpak-builder-lint repo`.",type:`string`,normalize:!0}).option(`metainfo`,{description:"MetaInfo XML path. Default: `data/<app-id>.metainfo.xml.in`.",type:`string`,normalize:!0}).option(`appstream`,{description:"Run `appstreamcli validate --strict` (default: true).",type:`boolean`,default:!0}).option(`builder-lint`,{description:"Run `flatpak-builder-lint manifest` (default: true).",type:`boolean`,default:!0}).option(`verbose`,{description:`Stream linter stdout/stderr verbatim.`,type:`boolean`,default:!1}),handler:async n=>{let a=(await new Config().forBuild({}).catch(()=>({}))).flatpak??{},S=process.cwd(),C=resolveAppId(n.manifest,a,S),N=resolveManifestPath(n.manifest,C,S),F=ms(S,n.metainfo??`data/${C??`unknown`}.metainfo.xml.in`),I=0;if(n.appstream!==!1&&(existsSync(F)?await runLinter(`appstreamcli`,[`validate`,`--strict`,F],n.verbose??!1)||I++:ge.warn(`[gjsify flatpak check] skipping appstreamcli — ${F} not found`)),n.builderLint!==!1){if(!existsSync(N))return ge.error(`[gjsify flatpak check] manifest not found: ${N}`),process.exit(1);await runLinter(`flatpak-builder-lint`,[`manifest`,N],n.verbose??!1)||I++,n.repo&&(await runLinter(`flatpak-builder-lint`,[`repo`,ms(S,n.repo)],n.verbose??!1)||I++)}if(I>0)return ge.error(`\n[gjsify flatpak check] ${I} check(s) failed.`),process.exit(1);ge.log(`[gjsify flatpak check] all checks passed.`)}}});async function resolveLatestTag$1(n,a){try{let{stdout:S}=await pF(`git`,[`describe`,`--tags`,`--abbrev=0`],{cwd:n});return a&&ge.log(`[gjsify flatpak sync-flathub] resolved latest tag → ${S.trim()}`),S.trim()||null}catch{return null}}async function resolveCommitForTag(n,a,S){try{let{stdout:C}=await pF(`git`,[`rev-list`,`-n`,`1`,a],{cwd:n}),N=C.trim();if(!N)throw Error(`empty rev-list output`);return S&&ge.log(`[gjsify flatpak sync-flathub] resolved ${a} → ${N}`),N}catch(n){throw Error(`[gjsify flatpak sync-flathub] tag ${a} not found locally. Run \`git fetch --tags\` or pass --commit <sha>.\n underlying error: ${n instanceof Error?n.message:String(n)}`)}}function normaliseBranchSegment(n){return n.replace(/^v/,``).replace(/[^A-Za-z0-9._-]/g,`-`)}function flathubCacheRoot(){return _s(process.env.XDG_CACHE_HOME||_s(homedir(),`.cache`),`gjsify`,`flathub-sync`)}async function ensureClone(n,a,S){if(existsSync(_s(n,`.git`))){S&&ge.log(`[gjsify flatpak sync-flathub] reusing clone at ${n}`),await gitInRepo(n,[`fetch`,`origin`],S);let a=await detectDefaultBranch(n,S);await gitInRepo(n,[`checkout`,a],S),await gitInRepo(n,[`reset`,`--hard`,`origin/${a}`],S);return}mkdirSync(ms(n,`..`),{recursive:!0});let C=`https://github.com/${a}.git`;S&&ge.log(`[gjsify flatpak sync-flathub] git clone ${C} ${n}`);try{await pF(`git`,[`clone`,C,n])}catch(n){throw n?.code===`ENOENT`?Error("[gjsify flatpak sync-flathub] `git` not found. Install git from your distro (Fedora: `dnf install git`, Debian: `apt install git`)."):n}}async function detectDefaultBranch(n,a){try{let{stdout:S}=await pF(`git`,[`remote`,`show`,`origin`],{cwd:n}),C=S.match(/HEAD branch: (\S+)/);if(C&&C[1]&&C[1]!==`(unknown)`)return a&&ge.log(`[gjsify flatpak sync-flathub] default branch → ${C[1]}`),C[1]}catch{}return`master`}function gitInRepo(n,a,S){return S&&ge.log(`[gjsify flatpak sync-flathub] git ${a.join(` `)} (in ${n})`),new Promise((S,C)=>{let N=spawn(`git`,a,{cwd:n,stdio:`inherit`});N.on(`error`,n=>{n.code===`ENOENT`?C(Error("[gjsify flatpak sync-flathub] `git` not found. Install it from your distro.")):C(n)}),N.on(`exit`,n=>{n===0?S():C(Error(`git ${a[0]} exited ${n}`))})})}function ghCreate(n,a,S,C,N,F){let I=[`pr`,`create`,`--repo`,a,`--head`,S,`--title`,`Update to ${C}`,`--body`,N];return F&&ge.log(`[gjsify flatpak sync-flathub] gh ${I.join(` `)} (in ${n})`),new Promise((a,S)=>{let C=spawn(`gh`,I,{cwd:n,stdio:`inherit`});C.on(`error`,n=>{n.code===`ENOENT`?S(Error("[gjsify flatpak sync-flathub] `gh` (GitHub CLI) not found. Install via `dnf install gh` (Fedora), `apt install gh` (Debian/Ubuntu), or `flatpak install -y flathub com.github.cli`.")):S(n)}),C.on(`exit`,n=>{n===0?a():S(Error(`gh pr create exited ${n}`))})})}function editManifest(n,a){let S=JSON.parse(n),C=S.modules??[];if(C.length===0)throw Error(`[gjsify flatpak sync-flathub] manifest has no modules`);let N=C[0].sources??[];if(N.length===0)throw Error(`[gjsify flatpak sync-flathub] modules[0] has no sources`);let F=a.sourceIndex??N.findIndex(n=>n.type===`git`);if(F<0||F>=N.length)throw Error(`[gjsify flatpak sync-flathub] no git source found in modules[0].sources (use --source-index <n>)`);let I=N[F];if(I.type!==`git`)throw Error(`[gjsify flatpak sync-flathub] modules[0].sources[${F}].type is "${I.type}", expected "git"`);I.tag=a.tag,I.commit=a.commit,I[`x-checker-data`]||={type:`git`,"tag-pattern":`^v(\\d+\\.\\d+\\.\\d+)$`,"version-scheme":`semantic`};let H=detectIndent$1(n);return JSON.stringify(S,null,H)+(n.endsWith(`
|
|
906
913
|
`)?`
|
|
907
|
-
`:``)}function detectIndent$1(n){let a=n.match(/^\{\n( +)/);return a?a[1].length:2}var pF,mF,hF=__esmMin(()=>{_e(),gl(),Os(),um(),Xm(),gc(),dM(),XP(),pF=promisify(execFile),mF={command:`sync-flathub`,description:`Update the per-app Flathub tracking-repo manifest to a new git tag + commit. Clones, edits, commits, optionally opens a PR.`,builder:n=>n.version(!1).option(`version`,{description:"Git tag to sync to. Default: `git describe --tags --abbrev=0` in cwd.",type:`string`}).option(`app-id`,{description:"Reverse-DNS app id. Default: `gjsify.flatpak.appId`.",type:`string`}).option(`flathub-repo`,{description:"Flathub tracking-repo (owner/name). Default: `flathub/<appId>`.",type:`string`}).option(`commit`,{description:"Commit SHA to pin. Default: resolved via `git rev-list -n 1 <version>` in cwd.",type:`string`}).option(`branch`,{description:"Branch name in the flathub-repo. Default: `update-to-<version>`.",type:`string`}).option(`source-index`,{description:"Index into modules[0].sources[] to update (when manifest has multiple sources). Default: first `type: git` source.",type:`number`}).option(`pr`,{description:"After commit + push, open a PR via `gh pr create`. Pass `--no-pr` to skip and stop after push.",type:`boolean`,default:!0}).option(`dry-run`,{description:`Show what would be edited; touch no files, run no git commands.`,type:`boolean`,default:!1}).option(`verbose`,{description:`Echo every git / gh invocation before running.`,type:`boolean`,default:!1}),handler:async n=>{let a=process.cwd(),S=(await new Config().forBuild({}).catch(()=>({}))).flatpak??{},C=n.appId??S.appId??readPackageJson(a).name;if(!C)throw Error(`[gjsify flatpak sync-flathub] no app id available — pass --app-id or set gjsify.flatpak.appId.`);let N=n.flathubRepo??S.flathubRepo??`flathub/${C}`,F=n.version??await resolveLatestTag$1(a,n.verbose);if(!F)throw Error(`[gjsify flatpak sync-flathub] no version resolved — pass --version vX.Y.Z or create a git tag locally.`);let I=n.commit??await resolveCommitForTag(a,F,n.verbose),H=n.branch??`update-to-${normaliseBranchSegment(F)}`;if(ge.log(`[gjsify flatpak sync-flathub] appId=${C}`),ge.log(`[gjsify flatpak sync-flathub] flathubRepo=${N}`),ge.log(`[gjsify flatpak sync-flathub] version=${F}`),ge.log(`[gjsify flatpak sync-flathub] commit=${I}`),ge.log(`[gjsify flatpak sync-flathub] branch=${H}`),n.dryRun){ge.log(`[gjsify flatpak sync-flathub] --dry-run set; not cloning / writing / pushing.`);return}let W=flathubCacheRoot(),K=_s(W,N.replace(`/`,`__`));mkdirSync(W,{recursive:!0}),await ensureClone(K,N,n.verbose);let q=_s(K,`${C}.json`);if(!existsSync(q))throw Error(`[gjsify flatpak sync-flathub] Flathub manifest not found at ${q} — wrong appId / wrong flathub-repo?`);let Y=readFileSync(q,`utf-8`),X=editManifest(Y,{tag:F,commit:I,sourceIndex:n.sourceIndex});if(X===Y){ge.log(`[gjsify flatpak sync-flathub] manifest already at ${F} — nothing to do.`);return}if(writeFileSync(q,X,`utf-8`),ge.log(`[gjsify flatpak sync-flathub] manifest patched at ${q}`),await gitInRepo(K,[`checkout`,`-B`,H],n.verbose),await gitInRepo(K,[`add`,`.`],n.verbose),await gitInRepo(K,[`commit`,`-m`,`Update to ${F}`],n.verbose),n.pr===!1){ge.log(`[gjsify flatpak sync-flathub] --no-pr set; branch ${H} committed locally in ${K}.`);return}await gitInRepo(K,[`push`,`-u`,`origin`,H,`--force-with-lease`],n.verbose),await ghCreate(K,N,H,F,`Auto-generated by \`gjsify flatpak sync-flathub\`.\n\n- Version: \`${F}\`\n- Commit: \`${I}\`\n`,n.verbose)}},__name$1(resolveLatestTag$1,`resolveLatestTag`),__name$1(detectIndent$1,`detectIndent`)});async function loadFlathubSource(n,a){let S;if(n.against){if(!existsSync(n.against))throw Error(`[gjsify flatpak diff] --against path ${n.against} does not exist`);S=readFileSync(n.against,`utf-8`)}else S=await fetchFlathubManifest(n.flathubRepo,n.appId,n.verbose);let C;try{C=JSON.parse(S)}catch(n){throw Error(`[gjsify flatpak diff] failed to parse Flathub manifest as JSON: ${n.message}`)}let N=(C.modules??[])[0]?.sources??[];if(N.length===0)return null;let F=a??N.findIndex(n=>n?.type===`git`);return F<0||F>=N.length?null:N[F]??null}async function fetchFlathubManifest(n,a,S){for(let C of[`master`,`main`]){let N=`https://raw.githubusercontent.com/${n}/${C}/${a}.json`;S&&ge.log(`[gjsify flatpak diff] fetch ${N}`);try{let n=await fetch(N);if(n.ok)return await n.text();S&&ge.log(`[gjsify flatpak diff] ${C} → HTTP ${n.status}`)}catch(n){S&&ge.log(`[gjsify flatpak diff] ${C} fetch error: ${n.message}`)}}throw Error(`[gjsify flatpak diff] could not fetch flathub manifest from ${n} on master or main`)}async function resolveLatestTag(n,a){try{let{stdout:S}=await gF(`git`,[`describe`,`--tags`,`--abbrev=0`],{cwd:n}),C=S.trim();return a&&ge.log(`[gjsify flatpak diff] local latest tag → ${C}`),C||null}catch{return null}}var gF,_F,vF=__esmMin(()=>{_e(),gl(),Xm(),gc(),dM(),XP(),gF=promisify(execFile),_F={command:`diff`,description:`Compare the per-app Flathub tracking-repo manifest against the local git state and report version / commit drift.`,builder:n=>n.version(!1).option(`version`,{description:"Local version to compare against. Default: `git describe --tags --abbrev=0` in cwd.",type:`string`}).option(`app-id`,{description:"Reverse-DNS app id. Default: `gjsify.flatpak.appId`.",type:`string`}).option(`flathub-repo`,{description:"Flathub tracking-repo (owner/name). Default: `gjsify.flatpak.flathubRepo` or `flathub/<appId>`.",type:`string`}).option(`against`,{description:`Read the Flathub manifest from a local file instead of fetching it. Useful in CI or offline.`,type:`string`}).option(`detail`,{description:`Also print the full Flathub manifest source entry alongside the resolved local version.`,type:`boolean`,default:!1}).option(`source-index`,{description:`Index into modules[0].sources[] to inspect (when the manifest has multiple sources).`,type:`number`}).option(`verbose`,{description:`Echo fetch URL + resolved values.`,type:`boolean`,default:!1}),handler:async n=>{let a=process.cwd(),S=(await new Config().forBuild({}).catch(()=>({}))).flatpak??{},C=n.appId??S.appId??readPackageJson(a).name;if(!C)throw Error(`[gjsify flatpak diff] no app id available — pass --app-id or set gjsify.flatpak.appId.`);let N=n.flathubRepo??S.flathubRepo??`flathub/${C}`,F=n.version??await resolveLatestTag(a,n.verbose),I=await loadFlathubSource({appId:C,flathubRepo:N,against:n.against,verbose:n.verbose},n.sourceIndex),H=I?.tag,W=I?.commit;if(ge.log(`[gjsify flatpak diff] appId=${C}`),ge.log(`[gjsify flatpak diff] flathubRepo=${N}`),ge.log(`[gjsify flatpak diff] flathub: tag=${H??`(missing)`} commit=${W??`(missing)`}`),ge.log(`[gjsify flatpak diff] local: tag=${F??`(none)`}`),n.detail&&I&&(ge.log(`[gjsify flatpak diff] flathub manifest source:`),ge.log(JSON.stringify(I,null,2))),!F){ge.warn("[gjsify flatpak diff] no local git tag found — cut a release (`git tag vX.Y.Z`) or pass --version vX.Y.Z to compare against an explicit value.");return}if(!H)return ge.warn("[gjsify flatpak diff] flathub manifest has no `tag` field on the inspected source."),process.exit(1);if(H===F){ge.log(`✅ in sync (${F})`);return}ge.log(`❌ drift detected — flathub=${H} vs local=${F}`),ge.log(` run \`gjsify flatpak sync-flathub --version ${F}\` to update the Flathub manifest.`),process.exit(1)}}});function resolveCliEntry(){return ms(ms(bs(fileURLToPath(import.meta.url)),`..`,`..`),`index.js`)}async function runNode(n,a){await new Promise((S,C)=>{let N=spawn(`node`,n,{cwd:a,stdio:`inherit`});N.on(`error`,C),N.on(`exit`,a=>{a===0?S():C(Error(`sub-command exited with code ${a}: node ${n.join(` `)}`))})})}var yF,bF,xF=__esmMin(()=>{_e(),Xm(),gc(),rn(),Os(),yF=promisify(execFile),bF={command:`release <version>`,description:"Cut a release end-to-end: regenerate Flathub assets, run linters, create + push the git tag, then open the Flathub PR. Each step delegates to the equivalent `gjsify flatpak <sub>` command.",builder:n=>n.version(!1).positional(`version`,{description:"Release tag, e.g. `v0.6.6`.",type:`string`,demandOption:!0}).option(`skip-init`,{description:"Skip the `flatpak init --force` regen step.",type:`boolean`,default:!1}).option(`skip-check`,{description:"Skip the `flatpak check` linter step.",type:`boolean`,default:!1}).option(`skip-tag`,{description:"Skip the `git tag` + `git push --tags` step (use when the tag was already created out-of-band).",type:`boolean`,default:!1}).option(`push-tag`,{description:`Push the created tag after creating it. Default: true.`,type:`boolean`,default:!0}).option(`flathub-repo`,{description:`Flathub tracking-repo override forwarded to sync-flathub.`,type:`string`}).option(`dry-run`,{description:`Print each step that would run without executing any of them.`,type:`boolean`,default:!1}).option(`verbose`,{description:`Echo every sub-command invocation.`,type:`boolean`,default:!1}),handler:async n=>{let a=typeof n.version==`string`?n.version.trim():``;if(!a)throw Error(`[gjsify flatpak release] missing <version> positional`);let S=resolveCliEntry(),C=process.cwd(),N=[];n.skipInit||N.push({name:`init`,args:[S,`flatpak`,`init`,`--force`]}),n.skipCheck||N.push({name:`check`,args:[S,`flatpak`,`check`]});let F=[S,`flatpak`,`sync-flathub`,`--version`,a];if(n.flathubRepo&&F.push(`--flathub-repo`,n.flathubRepo),n.verbose&&F.push(`--verbose`),ge.log(`[gjsify flatpak release] starting release of ${a}`),n.dryRun){ge.log(`[gjsify flatpak release] --dry-run set; printing plan only:`);for(let n of N)ge.log(` · ${n.name}: node ${n.args.join(` `)}`);n.skipTag||ge.log(` · tag: git tag ${a}${n.pushTag===!1?``:` && git push origin `+a}`),ge.log(` · sync: node ${F.join(` `)}`);return}for(let a of N)n.verbose&&ge.log(`[gjsify flatpak release] step ${a.name}: node ${a.args.join(` `)}`),await runNode(a.args,C),ge.log(`[gjsify flatpak release] ${a.name} ✔`);if(!n.skipTag){n.verbose&&ge.log(`[gjsify flatpak release] git tag ${a}`);try{await yF(`git`,[`tag`,a],{cwd:C}),ge.log(`[gjsify flatpak release] tag ${a} created`)}catch(n){throw Error(`[gjsify flatpak release] git tag failed (${n.message}). If the tag already exists, re-run with --skip-tag.`)}n.pushTag!==!1&&(n.verbose&&ge.log(`[gjsify flatpak release] git push origin ${a}`),await yF(`git`,[`push`,`origin`,a],{cwd:C}),ge.log(`[gjsify flatpak release] tag pushed`))}n.verbose&&ge.log(`[gjsify flatpak release] sync: node ${F.join(` `)}`),await runNode(F,C),ge.log(`[gjsify flatpak release] ✅ release ${a} complete`)}}}),SF,CF=__esmMin(()=>{tF(),rF(),aF(),cF(),uF(),fF(),hF(),vF(),xF(),SF={command:`flatpak <subcommand>`,description:`Flatpak toolchain: init/build/deps/sources/ci/check/sync-flathub/diff/release subcommands for shipping GJS apps and CLIs as Flatpaks.`,builder:n=>n.command(eF.command,eF.description,eF.builder,eF.handler).command(nF.command,nF.description,nF.builder,nF.handler).command(iF.command,iF.description,iF.builder,iF.handler).command(sF.command,sF.description,sF.builder,sF.handler).command(lF.command,lF.description,lF.builder,lF.handler).command(dF.command,dF.description,dF.builder,dF.handler).command(mF.command,mF.description,mF.builder,mF.handler).command(_F.command,_F.description,_F.builder,_F.handler).command(bF.command,bF.description,bF.builder,bF.handler).demandCommand(1).strict()}});function defaultGlobalLayout(){let n=process.env.GJSIFY_GLOBAL_PREFIX,a=process.env.GJSIFY_GLOBAL_BIN_DIR,S=homedir(),C=process.env.XDG_DATA_HOME??_s(S,`.local`,`share`);return{prefix:n??_s(C,`gjsify`,`global`),binDir:a??_s(S,`.local`,`bin`)}}function hasBundlerEngineInstalled(n){return existsSync(_s(n,`node_modules`,`@gjsify/rolldown-native`,`package.json`))}async function installGjsEnginePackages(n,a,S={}){let C=S.verbose??!1,N=S.installFn??(async a=>{let{installPackages:S}=await Promise.resolve().then(()=>(wP(),SP));await S({prefix:n,specs:[a],verbose:C})});for(let n of wF){let S=a?`${n}@${a}`:n;try{await N(S)}catch(S){let N=S instanceof Error?S.message:String(S);n===`@gjsify/rolldown-native`?ge.warn(`\nWarning: could not install the GJS bundler engine ${n}@${a} — ${N}\n \`gjsify build\` (and storybook / flatpak) will fail under GJS until it is present.\n This usually means no prebuild is published for this platform (${process.platform}/${process.arch}).`):C&&ge.warn(`gjsify install: optional GJS engine ${n}@${a} not installed — ${N}`)}}}function linkGlobalBins(n,a){mkdirSync(a.binDir,{recursive:!0});let S=[],C=detectNativePackages(a.prefix).map(n=>n.prebuildsDir),N=buildNativeEnvPreamble(a.prefix,C);for(let F of n){let n=_s(a.prefix,`node_modules`,F),I=_s(n,`package.json`);if(!existsSync(I))continue;let H=pickBinMap(F,readJson(I));if(!(H===null||H.map.size===0))for(let[F,I]of H.map){let H=_s(n,I);if(!existsSync(H))continue;try{chmodSync(H,493)}catch{}let W=_s(a.binDir,F);for(let n of[W,`${W}.cmd`,`${W}.ps1`])rmSync(n,{force:!0,maxRetries:10,retryDelay:100});let K=isGjsBundlePath(H);if(writeFileSync(W,buildShLauncher(H,{envPreamble:N,isGjsBundle:K})),chmodSync(W,493),process.platform===`win32`){let n=C.join(`;`),a=K&&C.length>0?{GI_TYPELIB_PATH:n,PATH:n}:{},S=K?null:readShebangOf(H),N=buildLauncherShims(K?{interpreter:`gjs`,interpreterArgs:[`-m`],target:H,prependEnv:a}:{interpreter:S?.prog||`node`,interpreterArgs:S?.args.trim()?S.args.trim().split(/\s+/):[],target:H});writeFileSync(`${W}.cmd`,N.cmd),writeFileSync(`${W}.ps1`,N.ps1)}S.push({name:F,target:H,link:W})}}return S}function readShebangOf(n){try{return parseShebang(readFileSync(n,`utf-8`).trimStart().split(/\r*\n/,1)[0]??``)}catch{return null}}function readJson(n){return JSON.parse(readFileSync(n,`utf-8`))}function binDirOnPath(n){let a=process.env.PATH??``,S=process.platform===`win32`?`;`:`:`,C=ms(n);return a.split(S).some(n=>n&&ms(n)===C)}function specToPackageName(n){if(n.startsWith(`@`)){let a=n.indexOf(`/`);if(a<0)return n;let S=n.indexOf(`@`,a);return S<0?n:n.slice(0,S)}let a=n.indexOf(`@`);return a<0?n:n.slice(0,a)}var wF,TF=__esmMin(()=>{_e(),gl(),um(),Os(),OM(),lP(),wF=[`@gjsify/rolldown-native`,`@gjsify/lightningcss-native`,`@gjsify/oxfmt-native`]});function workspaceLinkTarget(n,a){return EF===`junction`?ms(a):vs(bs(n),a)}function applyPlatformConfigFromFlags(n){for(let[a,S]of[[`os`,`npm_config_os`],[`cpu`,`npm_config_cpu`],[`libc`,`npm_config_libc`]]){let C=n[a];if(typeof C!=`string`)continue;let N=C.trim();N!==``&&(process.env[S]=N)}n.force&&(process.env.npm_config_force=`true`)}function isAbortedFromOverallTimeout(n){if(!n||typeof n!=`object`)return!1;let a=n.name;if(a===`AbortError`)return!0;let S=n.message;return!!(typeof S==`string`&&S.includes(`install-overall-timeout`)||a===`RegistryTimeoutError`)}function forceExit(n){process.exitCode=n,!gjsExit(n)&&process.exit(n)}function readCliVersionFrom(n){try{if(!existsSync(n))return null;let a=JSON.parse(readFileSync(n,`utf-8`));if(a.name===kF&&typeof a.version==`string`)return a.version}catch{}return null}function readRunningCliVersion(){try{let n=bs(ms(fileURLToPath(import.meta.url)));for(let a=0;a<8&&n!==bs(n);a++){let a=readCliVersionFrom(_s(n,`package.json`));if(a)return a;n=bs(n)}}catch{}return null}function readWorkspaceCliVersion(n){return readCliVersionFrom(_s(n,`node_modules`,kF,`package.json`))??readCliVersionFrom(_s(n,`packages`,`infra`,`cli`,`package.json`))}function warnOnCliVersionSkew(n){if(process.env.GJSIFY_NO_VERSION_SKEW_WARNING===`1`)return;let a=readRunningCliVersion(),S=readWorkspaceCliVersion(n);!a||!S||a===S||ge.warn(`gjsify install: version skew — you are running @gjsify/cli v${a}, but this workspace pins v${S}.\n A mismatched CLI can stall the install (lock discarded → full re-resolve) or silently produce a wrong build.\n Align them: run \`gjsify self-update\` (global CLI) or use the workspace-local \`node_modules/.bin/gjsify\`.\n Suppress this with GJSIFY_NO_VERSION_SKEW_WARNING=1.`)}function isWorkspaceRoot(n){let a=readPackageJson$1(_s(n,`package.json`));return a?a.workspaces!==void 0:!1}function optionalDependencyNames(n){let a=new Set,S=new Set;for(let C of n){let n=new Set(Object.keys(C.optionalDependencies??{}));for(let S of n)a.add(S);for(let a of[`dependencies`,`devDependencies`])for(let N of Object.keys(C[a]??{}))n.has(N)||S.add(N)}for(let n of S)a.delete(n);return a}function depKindFromArgs(n){return n[`save-dev`]?`devDependencies`:n[`save-peer`]?`peerDependencies`:n[`save-optional`]?`optionalDependencies`:`dependencies`}async function projectInstallNative(n,a){let S=process.cwd(),C=_s(S,`package.json`),N=[`.pnp.cjs`,`.pnp.loader.mjs`].filter(n=>existsSync(_s(S,n)));if(N.length>0)throw Error(`gjsify install uses the node_modules linker and cannot run in a Yarn PnP project (found ${N.join(`, `)} in ${S}).\n\n• If this project uses \`gjsify install\` to manage dependencies, these PnP files are stale residue from an earlier \`yarn install\` — remove them and re-run:\n rm -f .pnp.cjs .pnp.loader.mjs && rm -rf .yarn/cache .yarn/unplugged\n gjsify install\n\n• If instead you want Yarn to manage dependencies, set \`nodeLinker: node-modules\` in .yarnrc.yml and run \`yarn install\` (not \`gjsify install\`).`);if(!n.packages||n.packages.length===0){let C=isWorkspaceRoot(S)?S:findWorkspaceRoot(S);if(C){C!==S&&ge.log(`gjsify install: resolved workspace root ${C} (from ${S}); installing the workspace.`),await workspaceInstall(C,n,a);return}}let F,I=readPackageJson$1(C),H=I?projectSpecsFromPackageJson(I):[];if(n.packages&&n.packages.length>0){let a=new Set(n.packages.map(n=>parseSpec$2(n).name));F=[...H.filter(n=>!a.has(parseSpec$2(n).name)),...n.packages]}else{if(!I)throw Error(`gjsify install: no package.json in ${S}`);if(F=H,F.length===0){ge.log(`gjsify install: no dependencies declared in package.json — nothing to do.`);return}}mkdirSync(S,{recursive:!0});let W=makeProgressReporter({enabled:!n.verbose&&!n.quiet&&n.progress!==!1}),K=await acquireInstallLock(S,{signal:a});try{let N=await installPackages({prefix:S,specs:F,verbose:n.verbose,lockfile:!n.immutable,frozen:n.immutable,refreshLockfile:n[`refresh-lockfile`],signal:a,progress:W,optionalSpecs:new Set([...optionalDependencyNames(I?[I]:[]),...n[`save-optional`]?(n.packages??[]).map(n=>parseSpec$2(n).name):[]])});if(n.packages&&n.packages.length>0&&I){let a=depKindFromArgs(n);for(let S of n.packages){let{name:n,range:C}=parseSpec$2(S),F=N.installed.find(a=>a.name===n);addDependencyEntry(I,n,C??(F?defaultRangeFromVersion(F.version):`latest`),a)}writePackageJson(C,I),n.immutable||syncLockfileRequested(S,projectSpecsFromPackageJson(I))}}finally{K.release()}}function syncLockfileRequested(n,a){let S=_s(n,`gjsify-lock.json`);if(existsSync(S))try{let n=JSON.parse(readFileSync(S,`utf-8`)),C=[...a].sort(),N=[...n.requested??[]].sort();if(C.length===N.length&&C.every((n,a)=>n===N[a]))return;n.requested=a,atomicWriteStrict(S,JSON.stringify(n,null,2)+`
|
|
914
|
+
`:``)}function detectIndent$1(n){let a=n.match(/^\{\n( +)/);return a?a[1].length:2}var pF,mF,hF=__esmMin(()=>{_e(),gl(),Os(),um(),Xm(),gc(),dM(),XP(),pF=promisify(execFile),mF={command:`sync-flathub`,description:`Update the per-app Flathub tracking-repo manifest to a new git tag + commit. Clones, edits, commits, optionally opens a PR.`,builder:n=>n.version(!1).option(`version`,{description:"Git tag to sync to. Default: `git describe --tags --abbrev=0` in cwd.",type:`string`}).option(`app-id`,{description:"Reverse-DNS app id. Default: `gjsify.flatpak.appId`.",type:`string`}).option(`flathub-repo`,{description:"Flathub tracking-repo (owner/name). Default: `flathub/<appId>`.",type:`string`}).option(`commit`,{description:"Commit SHA to pin. Default: resolved via `git rev-list -n 1 <version>` in cwd.",type:`string`}).option(`branch`,{description:"Branch name in the flathub-repo. Default: `update-to-<version>`.",type:`string`}).option(`source-index`,{description:"Index into modules[0].sources[] to update (when manifest has multiple sources). Default: first `type: git` source.",type:`number`}).option(`pr`,{description:"After commit + push, open a PR via `gh pr create`. Pass `--no-pr` to skip and stop after push.",type:`boolean`,default:!0}).option(`dry-run`,{description:`Show what would be edited; touch no files, run no git commands.`,type:`boolean`,default:!1}).option(`verbose`,{description:`Echo every git / gh invocation before running.`,type:`boolean`,default:!1}),handler:async n=>{let a=process.cwd(),S=(await new Config().forBuild({}).catch(()=>({}))).flatpak??{},C=n.appId??S.appId??readPackageJson(a).name;if(!C)throw Error(`[gjsify flatpak sync-flathub] no app id available — pass --app-id or set gjsify.flatpak.appId.`);let N=n.flathubRepo??S.flathubRepo??`flathub/${C}`,F=n.version??await resolveLatestTag$1(a,n.verbose);if(!F)throw Error(`[gjsify flatpak sync-flathub] no version resolved — pass --version vX.Y.Z or create a git tag locally.`);let I=n.commit??await resolveCommitForTag(a,F,n.verbose),H=n.branch??`update-to-${normaliseBranchSegment(F)}`;if(ge.log(`[gjsify flatpak sync-flathub] appId=${C}`),ge.log(`[gjsify flatpak sync-flathub] flathubRepo=${N}`),ge.log(`[gjsify flatpak sync-flathub] version=${F}`),ge.log(`[gjsify flatpak sync-flathub] commit=${I}`),ge.log(`[gjsify flatpak sync-flathub] branch=${H}`),n.dryRun){ge.log(`[gjsify flatpak sync-flathub] --dry-run set; not cloning / writing / pushing.`);return}let W=flathubCacheRoot(),K=_s(W,N.replace(`/`,`__`));mkdirSync(W,{recursive:!0}),await ensureClone(K,N,n.verbose);let q=_s(K,`${C}.json`);if(!existsSync(q))throw Error(`[gjsify flatpak sync-flathub] Flathub manifest not found at ${q} — wrong appId / wrong flathub-repo?`);let Y=readFileSync(q,`utf-8`),X=editManifest(Y,{tag:F,commit:I,sourceIndex:n.sourceIndex});if(X===Y){ge.log(`[gjsify flatpak sync-flathub] manifest already at ${F} — nothing to do.`);return}if(writeFileSync(q,X,`utf-8`),ge.log(`[gjsify flatpak sync-flathub] manifest patched at ${q}`),await gitInRepo(K,[`checkout`,`-B`,H],n.verbose),await gitInRepo(K,[`add`,`.`],n.verbose),await gitInRepo(K,[`commit`,`-m`,`Update to ${F}`],n.verbose),n.pr===!1){ge.log(`[gjsify flatpak sync-flathub] --no-pr set; branch ${H} committed locally in ${K}.`);return}await gitInRepo(K,[`push`,`-u`,`origin`,H,`--force-with-lease`],n.verbose),await ghCreate(K,N,H,F,`Auto-generated by \`gjsify flatpak sync-flathub\`.\n\n- Version: \`${F}\`\n- Commit: \`${I}\`\n`,n.verbose)}},__name$1(resolveLatestTag$1,`resolveLatestTag`),__name$1(detectIndent$1,`detectIndent`)});async function loadFlathubSource(n,a){let S;if(n.against){if(!existsSync(n.against))throw Error(`[gjsify flatpak diff] --against path ${n.against} does not exist`);S=readFileSync(n.against,`utf-8`)}else S=await fetchFlathubManifest(n.flathubRepo,n.appId,n.verbose);let C;try{C=JSON.parse(S)}catch(n){throw Error(`[gjsify flatpak diff] failed to parse Flathub manifest as JSON: ${n.message}`)}let N=(C.modules??[])[0]?.sources??[];if(N.length===0)return null;let F=a??N.findIndex(n=>n?.type===`git`);return F<0||F>=N.length?null:N[F]??null}async function fetchFlathubManifest(n,a,S){for(let C of[`master`,`main`]){let N=`https://raw.githubusercontent.com/${n}/${C}/${a}.json`;S&&ge.log(`[gjsify flatpak diff] fetch ${N}`);try{let n=await fetch(N);if(n.ok)return await n.text();S&&ge.log(`[gjsify flatpak diff] ${C} → HTTP ${n.status}`)}catch(n){S&&ge.log(`[gjsify flatpak diff] ${C} fetch error: ${n.message}`)}}throw Error(`[gjsify flatpak diff] could not fetch flathub manifest from ${n} on master or main`)}async function resolveLatestTag(n,a){try{let{stdout:S}=await gF(`git`,[`describe`,`--tags`,`--abbrev=0`],{cwd:n}),C=S.trim();return a&&ge.log(`[gjsify flatpak diff] local latest tag → ${C}`),C||null}catch{return null}}var gF,_F,vF=__esmMin(()=>{_e(),gl(),Xm(),gc(),dM(),XP(),gF=promisify(execFile),_F={command:`diff`,description:`Compare the per-app Flathub tracking-repo manifest against the local git state and report version / commit drift.`,builder:n=>n.version(!1).option(`version`,{description:"Local version to compare against. Default: `git describe --tags --abbrev=0` in cwd.",type:`string`}).option(`app-id`,{description:"Reverse-DNS app id. Default: `gjsify.flatpak.appId`.",type:`string`}).option(`flathub-repo`,{description:"Flathub tracking-repo (owner/name). Default: `gjsify.flatpak.flathubRepo` or `flathub/<appId>`.",type:`string`}).option(`against`,{description:`Read the Flathub manifest from a local file instead of fetching it. Useful in CI or offline.`,type:`string`}).option(`detail`,{description:`Also print the full Flathub manifest source entry alongside the resolved local version.`,type:`boolean`,default:!1}).option(`source-index`,{description:`Index into modules[0].sources[] to inspect (when the manifest has multiple sources).`,type:`number`}).option(`verbose`,{description:`Echo fetch URL + resolved values.`,type:`boolean`,default:!1}),handler:async n=>{let a=process.cwd(),S=(await new Config().forBuild({}).catch(()=>({}))).flatpak??{},C=n.appId??S.appId??readPackageJson(a).name;if(!C)throw Error(`[gjsify flatpak diff] no app id available — pass --app-id or set gjsify.flatpak.appId.`);let N=n.flathubRepo??S.flathubRepo??`flathub/${C}`,F=n.version??await resolveLatestTag(a,n.verbose),I=await loadFlathubSource({appId:C,flathubRepo:N,against:n.against,verbose:n.verbose},n.sourceIndex),H=I?.tag,W=I?.commit;if(ge.log(`[gjsify flatpak diff] appId=${C}`),ge.log(`[gjsify flatpak diff] flathubRepo=${N}`),ge.log(`[gjsify flatpak diff] flathub: tag=${H??`(missing)`} commit=${W??`(missing)`}`),ge.log(`[gjsify flatpak diff] local: tag=${F??`(none)`}`),n.detail&&I&&(ge.log(`[gjsify flatpak diff] flathub manifest source:`),ge.log(JSON.stringify(I,null,2))),!F){ge.warn("[gjsify flatpak diff] no local git tag found — cut a release (`git tag vX.Y.Z`) or pass --version vX.Y.Z to compare against an explicit value.");return}if(!H)return ge.warn("[gjsify flatpak diff] flathub manifest has no `tag` field on the inspected source."),process.exit(1);if(H===F){ge.log(`✅ in sync (${F})`);return}ge.log(`❌ drift detected — flathub=${H} vs local=${F}`),ge.log(` run \`gjsify flatpak sync-flathub --version ${F}\` to update the Flathub manifest.`),process.exit(1)}}});function resolveCliEntry(){return ms(ms(bs(fileURLToPath(import.meta.url)),`..`,`..`),`index.js`)}async function runNode(n,a){await new Promise((S,C)=>{let N=spawn(`node`,n,{cwd:a,stdio:`inherit`});N.on(`error`,C),N.on(`exit`,a=>{a===0?S():C(Error(`sub-command exited with code ${a}: node ${n.join(` `)}`))})})}var yF,bF,xF=__esmMin(()=>{_e(),Xm(),gc(),rn(),Os(),yF=promisify(execFile),bF={command:`release <version>`,description:"Cut a release end-to-end: regenerate Flathub assets, run linters, create + push the git tag, then open the Flathub PR. Each step delegates to the equivalent `gjsify flatpak <sub>` command.",builder:n=>n.version(!1).positional(`version`,{description:"Release tag, e.g. `v0.6.6`.",type:`string`,demandOption:!0}).option(`skip-init`,{description:"Skip the `flatpak init --force` regen step.",type:`boolean`,default:!1}).option(`skip-check`,{description:"Skip the `flatpak check` linter step.",type:`boolean`,default:!1}).option(`skip-tag`,{description:"Skip the `git tag` + `git push --tags` step (use when the tag was already created out-of-band).",type:`boolean`,default:!1}).option(`push-tag`,{description:`Push the created tag after creating it. Default: true.`,type:`boolean`,default:!0}).option(`flathub-repo`,{description:`Flathub tracking-repo override forwarded to sync-flathub.`,type:`string`}).option(`dry-run`,{description:`Print each step that would run without executing any of them.`,type:`boolean`,default:!1}).option(`verbose`,{description:`Echo every sub-command invocation.`,type:`boolean`,default:!1}),handler:async n=>{let a=typeof n.version==`string`?n.version.trim():``;if(!a)throw Error(`[gjsify flatpak release] missing <version> positional`);let S=resolveCliEntry(),C=process.cwd(),N=[];n.skipInit||N.push({name:`init`,args:[S,`flatpak`,`init`,`--force`]}),n.skipCheck||N.push({name:`check`,args:[S,`flatpak`,`check`]});let F=[S,`flatpak`,`sync-flathub`,`--version`,a];if(n.flathubRepo&&F.push(`--flathub-repo`,n.flathubRepo),n.verbose&&F.push(`--verbose`),ge.log(`[gjsify flatpak release] starting release of ${a}`),n.dryRun){ge.log(`[gjsify flatpak release] --dry-run set; printing plan only:`);for(let n of N)ge.log(` · ${n.name}: node ${n.args.join(` `)}`);n.skipTag||ge.log(` · tag: git tag ${a}${n.pushTag===!1?``:` && git push origin `+a}`),ge.log(` · sync: node ${F.join(` `)}`);return}for(let a of N)n.verbose&&ge.log(`[gjsify flatpak release] step ${a.name}: node ${a.args.join(` `)}`),await runNode(a.args,C),ge.log(`[gjsify flatpak release] ${a.name} ✔`);if(!n.skipTag){n.verbose&&ge.log(`[gjsify flatpak release] git tag ${a}`);try{await yF(`git`,[`tag`,a],{cwd:C}),ge.log(`[gjsify flatpak release] tag ${a} created`)}catch(n){throw Error(`[gjsify flatpak release] git tag failed (${n.message}). If the tag already exists, re-run with --skip-tag.`)}n.pushTag!==!1&&(n.verbose&&ge.log(`[gjsify flatpak release] git push origin ${a}`),await yF(`git`,[`push`,`origin`,a],{cwd:C}),ge.log(`[gjsify flatpak release] tag pushed`))}n.verbose&&ge.log(`[gjsify flatpak release] sync: node ${F.join(` `)}`),await runNode(F,C),ge.log(`[gjsify flatpak release] ✅ release ${a} complete`)}}}),SF,CF=__esmMin(()=>{tF(),rF(),aF(),cF(),uF(),fF(),hF(),vF(),xF(),SF={command:`flatpak <subcommand>`,description:`Flatpak toolchain: init/build/deps/sources/ci/check/sync-flathub/diff/release subcommands for shipping GJS apps and CLIs as Flatpaks.`,builder:n=>n.command(eF.command,eF.description,eF.builder,eF.handler).command(nF.command,nF.description,nF.builder,nF.handler).command(iF.command,iF.description,iF.builder,iF.handler).command(sF.command,sF.description,sF.builder,sF.handler).command(lF.command,lF.description,lF.builder,lF.handler).command(dF.command,dF.description,dF.builder,dF.handler).command(mF.command,mF.description,mF.builder,mF.handler).command(_F.command,_F.description,_F.builder,_F.handler).command(bF.command,bF.description,bF.builder,bF.handler).demandCommand(1).strict()}});function defaultGlobalLayout(){let n=process.env.GJSIFY_GLOBAL_PREFIX,a=process.env.GJSIFY_GLOBAL_BIN_DIR,S=homedir(),C=process.env.XDG_DATA_HOME??_s(S,`.local`,`share`);return{prefix:n??_s(C,`gjsify`,`global`),binDir:a??_s(S,`.local`,`bin`)}}function hasBundlerEngineInstalled(n){return existsSync(_s(n,`node_modules`,`@gjsify/rolldown-native`,`package.json`))}async function installGjsEnginePackages(n,a,S={}){let C=S.verbose??!1,N=S.installFn??(async a=>{let{installPackages:S}=await Promise.resolve().then(()=>(wP(),SP));await S({prefix:n,specs:[a],verbose:C})});for(let n of wF){let S=a?`${n}@${a}`:n;try{await N(S)}catch(S){let N=S instanceof Error?S.message:String(S);n===`@gjsify/rolldown-native`?ge.warn(`\nWarning: could not install the GJS bundler engine ${n}@${a} — ${N}\n \`gjsify build\` (and storybook / flatpak) will fail under GJS until it is present.\n This usually means no prebuild is published for this platform (${process.platform}/${process.arch}).`):C&&ge.warn(`gjsify install: optional GJS engine ${n}@${a} not installed — ${N}`)}}}function linkGlobalBins(n,a){mkdirSync(a.binDir,{recursive:!0});let S=[],C=detectNativePackages(a.prefix).map(n=>n.prebuildsDir),N=buildNativeEnvPreamble(a.prefix,C);for(let F of n){let n=_s(a.prefix,`node_modules`,F),I=_s(n,`package.json`);if(!existsSync(I))continue;let H=pickBinMap(F,readJson(I));if(!(H===null||H.map.size===0))for(let[F,I]of H.map){let W=_s(n,I);if(!existsSync(W))continue;try{chmodSync(W,493)}catch{}let K=_s(a.binDir,F);for(let n of[K,`${K}.cmd`,`${K}.ps1`])rmSync(n,{force:!0,maxRetries:10,retryDelay:100});let q=isGjsBundlePath(W),Y=H.nodeFallback?.get(F),X=Y===void 0?void 0:_s(n,Y),te=X!==void 0&&existsSync(X)?X:void 0;if(writeFileSync(K,buildShLauncher(W,{envPreamble:N,isGjsBundle:q,nodeFallbackAbs:te})),chmodSync(K,493),process.platform===`win32`){let n=C.join(`;`),a=q&&C.length>0?{GI_TYPELIB_PATH:n,PATH:n}:{},S=q?null:readShebangOf(W),N=buildLauncherShims(q?{interpreter:`gjs`,interpreterArgs:[`-m`],target:W,prependEnv:a,fallback:te===void 0?void 0:{interpreter:`node`,target:te}}:{interpreter:S?.prog||`node`,interpreterArgs:S?.args.trim()?S.args.trim().split(/\s+/):[],target:W});writeFileSync(`${K}.cmd`,N.cmd),writeFileSync(`${K}.ps1`,N.ps1)}S.push({name:F,target:W,link:K})}}return S}function readShebangOf(n){try{return parseShebang(readFileSync(n,`utf-8`).trimStart().split(/\r*\n/,1)[0]??``)}catch{return null}}function readJson(n){return JSON.parse(readFileSync(n,`utf-8`))}function binDirOnPath(n){let a=process.env.PATH??``,S=process.platform===`win32`?`;`:`:`,C=ms(n);return a.split(S).some(n=>n&&ms(n)===C)}function specToPackageName(n){if(n.startsWith(`@`)){let a=n.indexOf(`/`);if(a<0)return n;let S=n.indexOf(`@`,a);return S<0?n:n.slice(0,S)}let a=n.indexOf(`@`);return a<0?n:n.slice(0,a)}var wF,TF=__esmMin(()=>{_e(),gl(),um(),Os(),OM(),lP(),wF=[`@gjsify/rolldown-native`,`@gjsify/lightningcss-native`,`@gjsify/oxfmt-native`]});function workspaceLinkTarget(n,a){return EF===`junction`?ms(a):vs(bs(n),a)}function applyPlatformConfigFromFlags(n){for(let[a,S]of[[`os`,`npm_config_os`],[`cpu`,`npm_config_cpu`],[`libc`,`npm_config_libc`]]){let C=n[a];if(typeof C!=`string`)continue;let N=C.trim();N!==``&&(process.env[S]=N)}n.force&&(process.env.npm_config_force=`true`)}function isAbortedFromOverallTimeout(n){if(!n||typeof n!=`object`)return!1;let a=n.name;if(a===`AbortError`)return!0;let S=n.message;return!!(typeof S==`string`&&S.includes(`install-overall-timeout`)||a===`RegistryTimeoutError`)}function forceExit(n){process.exitCode=n,!gjsExit(n)&&process.exit(n)}function readCliVersionFrom(n){try{if(!existsSync(n))return null;let a=JSON.parse(readFileSync(n,`utf-8`));if(a.name===kF&&typeof a.version==`string`)return a.version}catch{}return null}function readRunningCliVersion(){try{let n=bs(ms(fileURLToPath(import.meta.url)));for(let a=0;a<8&&n!==bs(n);a++){let a=readCliVersionFrom(_s(n,`package.json`));if(a)return a;n=bs(n)}}catch{}return null}function readWorkspaceCliVersion(n){return readCliVersionFrom(_s(n,`node_modules`,kF,`package.json`))??readCliVersionFrom(_s(n,`packages`,`infra`,`cli`,`package.json`))}function warnOnCliVersionSkew(n){if(process.env.GJSIFY_NO_VERSION_SKEW_WARNING===`1`)return;let a=readRunningCliVersion(),S=readWorkspaceCliVersion(n);!a||!S||a===S||ge.warn(`gjsify install: version skew — you are running @gjsify/cli v${a}, but this workspace pins v${S}.\n A mismatched CLI can stall the install (lock discarded → full re-resolve) or silently produce a wrong build.\n Align them: run \`gjsify self-update\` (global CLI) or use the workspace-local \`node_modules/.bin/gjsify\`.\n Suppress this with GJSIFY_NO_VERSION_SKEW_WARNING=1.`)}function isWorkspaceRoot(n){let a=readPackageJson$1(_s(n,`package.json`));return a?a.workspaces!==void 0:!1}function optionalDependencyNames(n){let a=new Set,S=new Set;for(let C of n){let n=new Set(Object.keys(C.optionalDependencies??{}));for(let S of n)a.add(S);for(let a of[`dependencies`,`devDependencies`])for(let N of Object.keys(C[a]??{}))n.has(N)||S.add(N)}for(let n of S)a.delete(n);return a}function depKindFromArgs(n){return n[`save-dev`]?`devDependencies`:n[`save-peer`]?`peerDependencies`:n[`save-optional`]?`optionalDependencies`:`dependencies`}async function projectInstallNative(n,a){let S=process.cwd(),C=_s(S,`package.json`),N=[`.pnp.cjs`,`.pnp.loader.mjs`].filter(n=>existsSync(_s(S,n)));if(N.length>0)throw Error(`gjsify install uses the node_modules linker and cannot run in a Yarn PnP project (found ${N.join(`, `)} in ${S}).\n\n• If this project uses \`gjsify install\` to manage dependencies, these PnP files are stale residue from an earlier \`yarn install\` — remove them and re-run:\n rm -f .pnp.cjs .pnp.loader.mjs && rm -rf .yarn/cache .yarn/unplugged\n gjsify install\n\n• If instead you want Yarn to manage dependencies, set \`nodeLinker: node-modules\` in .yarnrc.yml and run \`yarn install\` (not \`gjsify install\`).`);if(!n.packages||n.packages.length===0){let C=isWorkspaceRoot(S)?S:findWorkspaceRoot(S);if(C){C!==S&&ge.log(`gjsify install: resolved workspace root ${C} (from ${S}); installing the workspace.`),await workspaceInstall(C,n,a);return}}let F,I=readPackageJson$1(C),H=I?projectSpecsFromPackageJson(I):[];if(n.packages&&n.packages.length>0){let a=new Set(n.packages.map(n=>parseSpec$2(n).name));F=[...H.filter(n=>!a.has(parseSpec$2(n).name)),...n.packages]}else{if(!I)throw Error(`gjsify install: no package.json in ${S}`);if(F=H,F.length===0){ge.log(`gjsify install: no dependencies declared in package.json — nothing to do.`);return}}mkdirSync(S,{recursive:!0});let W=makeProgressReporter({enabled:!n.verbose&&!n.quiet&&n.progress!==!1}),K=await acquireInstallLock(S,{signal:a});try{let N=await installPackages({prefix:S,specs:F,verbose:n.verbose,lockfile:!n.immutable,frozen:n.immutable,refreshLockfile:n[`refresh-lockfile`],signal:a,progress:W,optionalSpecs:new Set([...optionalDependencyNames(I?[I]:[]),...n[`save-optional`]?(n.packages??[]).map(n=>parseSpec$2(n).name):[]])});if(n.packages&&n.packages.length>0&&I){let a=depKindFromArgs(n);for(let S of n.packages){let{name:n,range:C}=parseSpec$2(S),F=N.installed.find(a=>a.name===n);addDependencyEntry(I,n,C??(F?defaultRangeFromVersion(F.version):`latest`),a)}writePackageJson(C,I),n.immutable||syncLockfileRequested(S,projectSpecsFromPackageJson(I))}}finally{K.release()}}function syncLockfileRequested(n,a){let S=_s(n,`gjsify-lock.json`);if(existsSync(S))try{let n=JSON.parse(readFileSync(S,`utf-8`)),C=[...a].sort(),N=[...n.requested??[]].sort();if(C.length===N.length&&C.every((n,a)=>n===N[a]))return;n.requested=a,atomicWriteStrict(S,JSON.stringify(n,null,2)+`
|
|
908
915
|
`)}catch{}}async function workspaceInstall(n,a,S){let C=await acquireInstallLock(n,{signal:S});try{await workspaceInstallLocked(n,a,S)}finally{C.release()}}async function workspaceInstallLocked(n,a,S){let C=discoverWorkspaces(n,{includeRoot:!0});if(C.length===0)throw Error(`gjsify install: ${n} has a "workspaces" field but no workspaces were discovered`);let N=new Map(C.map(n=>[n.name,n])),F=new Set,I=new Map,H=[];for(let n of C){let a=n.manifest;for(let S of[`dependencies`,`devDependencies`,`optionalDependencies`]){let C=a[S];if(C)for(let[a,S]of Object.entries(C)){if(typeof S!=`string`)continue;let C=N.get(a);if(C&&!/^(link|file|portal|git\+|https?):/.test(S)){H.push({fromWorkspaceName:n.name,depName:a,targetLocation:C.location});continue}if(S.startsWith(`workspace:`))throw Error(`gjsify install: ${n.name} declares "${a}: ${S}" but no workspace with that name exists`);if(/^(link|file|portal|git\+|https?):/.test(S))continue;let W=`${a}@${S}`;F.add(W);let K=I.get(W);K||(K=new Set,I.set(W,K)),K.add(n.name)}}}ge.log(`gjsify install: ${C.length} workspace(s), ${F.size} external dep spec(s), ${H.length} workspace symlink(s)`),writeWorkspaceBinShims(n,C);let wireWorkspaceSymlinks=async()=>{if(H.length>0){let n=await Promise.resolve().then(()=>(Jc(),Gc)),a=new Set,S=[];for(let n of H){let C=N.get(n.fromWorkspaceName);if(!C)continue;let F=_s(C.location,`node_modules`,n.depName);a.add(bs(F));let I=workspaceLinkTarget(F,n.targetLocation);S.push({linkPath:F,relTarget:I})}await Promise.all([...a].map(a=>n.mkdir(a,{recursive:!0})));let C=0,F=[],wireOne=async(a,S)=>{try{await n.rm(a,{recursive:!0,force:!0,maxRetries:10,retryDelay:100})}catch{}await n.symlink(S,a,EF)};for(let n=0;n<Math.min(32,S.length);n++)F.push((async()=>{for(;;){let n=C++;if(n>=S.length)return;let a=S[n];if(!a)return;await wireOne(a.linkPath,a.relTarget)}})());await Promise.all(F),ge.log(`gjsify install: wired ${H.length} workspace symlink(s)`)}let a=_s(n,`node_modules`),S=0;for(let N of C){if(N.location===n||!N.name)continue;let C=_s(a,N.name),F=!1;try{lstatSync(C),F=!0}catch{}F||(mkdirSync(bs(C),{recursive:!0}),symlinkSync(workspaceLinkTarget(C,N.location),C,EF),S++)}S>0&&ge.log(`gjsify install: hoisted ${S} workspace(s) to root node_modules/`)};await wireWorkspaceSymlinks();let W=C.find(a=>a.location===n)?.manifest,K=extractOverrides(W),q=K?.global,Y=new Map,X=new Set;if(K&&K.scoped.size>0){for(let n of C){let a=n.manifest;for(let S of[`dependencies`,`devDependencies`,`optionalDependencies`]){let C=a[S];if(C)for(let[a,S]of Object.entries(C)){let C=scopedOverrideFor(n,a,K);if(!C)continue;let N=C,F=n.location,I=Y.get(F);I||(I=new Set,Y.set(F,I)),I.add(`${a}@${N}`),X.add(`${a}@${S}`)}}}let n=new Set;for(let a of C)for(let S of[`dependencies`,`devDependencies`,`optionalDependencies`]){let C=a.manifest[S];if(C)for(let[S,N]of Object.entries(C))scopedOverrideFor(a,S,K)||n.add(`${S}@${N}`)}for(let a of X)n.has(a)||F.delete(a);Y.size>0&&ge.log(`gjsify install: ${Y.size} workspace(s) have scoped overrides — they will install their overridden deps locally after the root install`)}if(F.size>0){let H=makeProgressReporter({enabled:!a.verbose&&!a.quiet&&a.progress!==!1});await installPackages({prefix:n,specs:[...F],verbose:a.verbose,lockfile:!a.immutable,frozen:a.immutable,refreshLockfile:a[`refresh-lockfile`],overrides:q,signal:S,progress:H,workspaceNames:new Set(N.keys()),specOrigins:new Map([...I].map(([n,a])=>[n,[...a]])),optionalSpecs:optionalDependencyNames(C.map(n=>n.manifest))})}else a.verbose&&ge.log(`gjsify install: no external deps to fetch`);for(let[n,F]of Y){if(F.size===0)continue;let I=C.find(a=>a.location===n)?.name??n;a.verbose&&ge.log(`gjsify install: ${I} — installing ${F.size} scoped-override spec(s) into ${n}/node_modules/`),await installPackages({prefix:n,specs:[...F],verbose:a.verbose,lockfile:!a.immutable,frozen:a.immutable,signal:S,workspaceNames:new Set(N.keys()),optionalSpecs:optionalDependencyNames(C.map(n=>n.manifest))})}await wireWorkspaceSymlinks();let te=writeWorkspaceBinShims(n,C);te>0&&ge.log(`gjsify install: linked ${te} workspace bin(s) into node_modules/.bin/`)}function writeWorkspaceBinShims(n,a){let S=_s(n,`node_modules`,`.bin`),C=detectNativePackages(n).map(n=>n.prebuildsDir),N=0;for(let F of a){let a=F.manifest,I=a.gjsify?.bin,H=a.bin,W=mergeWorkspaceBins(F.name,I,H);if(W.size!==0){mkdirSync(S,{recursive:!0});for(let[a,{nodeTarget:I,gjsTarget:H}]of W){let W=_s(S,a);for(let n of[W,`${W}.cmd`,`${W}.ps1`])try{rmSync(n,{force:!0,maxRetries:10,retryDelay:100})}catch{}if(writeFileSync(W,buildBinShim(F.location,I,H,C,process.platform,n),{mode:493}),chmodSync(W,493),process.platform===`win32`)for(let[n,a]of Object.entries(buildWorkspaceBinShimsForWindows(F.location,I,H,C)))writeFileSync(`${W}.${n}`,a,{mode:493});N++}}}return N}function extractOverrides(n){if(!n)return;let a={},S=new Map,merge=(n,C)=>{if(n){for(let[N,F]of Object.entries(n))if(!N.startsWith(`_`)){if(typeof F==`string`){let n=N,S=N.startsWith(`@`)?N.indexOf(`@`,1):N.indexOf(`@`);S>0&&(n=N.slice(0,S)),a[n]=F;continue}if(F&&typeof F==`object`&&!Array.isArray(F)){let n={};for(let[a,S]of Object.entries(F)){if(a.startsWith(`_`))continue;if(typeof S!=`string`){ge.warn(`gjsify install: ${C}["${N}"]["${a}"] is not a string — only one level of nesting is supported, skipping`);continue}let F=a,I=a.startsWith(`@`)?a.indexOf(`@`,1):a.indexOf(`@`);I>0&&(F=a.slice(0,I)),n[F]=S}if(Object.keys(n).length>0){let a=S.get(N)??{};S.set(N,{...a,...n})}continue}ge.warn(`gjsify install: ${C}["${N}"] is not a string or object — skipping`)}}};if(merge(n.overrides,`overrides`),merge(n.resolutions,`resolutions`),!(Object.keys(a).length===0&&S.size===0))return{global:a,scoped:S}}function scopedOverrideFor(n,a,S){if(!S||S.scoped.size===0)return;let C=[n.name,n.relativeLocation];for(let n of C){let C=S.scoped.get(n);if(C?.[a])return C[a]}}function buildBinShim(n,a,S,C=[],N=process.platform,F=n){let I=a?_s(n,a):null,H=S?_s(n,S):null,W=buildNativeEnvPreamble(F,C,{platform:N});if(I&&H){let n=N===`darwin`||N===`win32`,a=`if command -v gjs >/dev/null 2>&1 && [ -f "${H}" ]; then\n${W}exec gjs -m "${H}" "$@"\nfi\nexec node "${I}" "$@"\n`,S=`if command -v node >/dev/null 2>&1 && [ -f "${I}" ]; then\nexec node "${I}" "$@"\nfi\n${W}exec gjs -m "${H}" "$@"\n`;return`#!/bin/sh
|
|
909
916
|
`+(n?S:a)}if(I)return`#!/bin/sh\nexec node "${I}" "$@"\n`;if(H)return`#!/bin/sh\n${W}exec gjs -m "${H}" "$@"\n`;throw Error(`buildBinShim: either nodeTarget or gjsTarget must be provided`)}function buildWorkspaceBinShimsForWindows(n,a,S,C=[]){let N=a?_s(n,a):null,F=S?_s(n,S):null;if(N)return buildLauncherShims({interpreter:`node`,target:N});if(F){let n=C.join(`;`);return buildLauncherShims({interpreter:`gjs`,interpreterArgs:[`-m`],target:F,prependEnv:C.length===0?{}:{GI_TYPELIB_PATH:n,PATH:n}})}throw Error(`buildWorkspaceBinShimsForWindows: either nodeTarget or gjsTarget must be provided`)}function mergeWorkspaceBins(n,a,S){let C=new Map,N=n.startsWith(`@`)?n.slice(n.indexOf(`/`)+1):n,get=n=>{let a=C.get(n);return a||(a={},C.set(n,a)),a};if(typeof S==`string`)get(N).nodeTarget=S;else if(S&&typeof S==`object`)for(let[n,a]of Object.entries(S))typeof a==`string`&&a.length>0&&(get(n).nodeTarget=a);if(typeof a==`string`)get(N).gjsTarget=a;else if(a&&typeof a==`object`)for(let[n,S]of Object.entries(a))typeof S==`string`&&S.length>0&&(get(n).gjsTarget=S);return C}async function projectInstallViaNpm(n){let a=[`install`];n[`save-dev`]&&a.push(`--save-dev`),n[`save-peer`]&&a.push(`--save-peer`),n[`save-optional`]&&a.push(`--save-optional`),n.verbose&&a.push(`--loglevel`,`verbose`),n.packages&&n.packages.length>0&&a.push(...n.packages),await spawnNpm(a)}async function spawnNpm(n){return spawnToCompletion(`npm`,n,{completion:`return`,notFound:()=>Error(`npm not found on PATH — install Node.js first.`)}).then(({code:n})=>{if(n!==0)throw Error(`npm install exited with code ${n}`)}).catch(n=>{let a=n.code;ge.error(a===void 0?n.message:`npm install failed: ${n.message}`),process.exit(1)})}async function installGlobalAndLink(n,a){let S=defaultGlobalLayout();mkdirSync(S.prefix,{recursive:!0}),ge.log(`gjsify install --global → ${S.prefix}`),ge.log(` bins → ${S.binDir}`);let C=await acquireInstallLock(S.prefix,{});try{let C=await installPackages({prefix:S.prefix,specs:n,verbose:a.verbose}),N=n.map(specToPackageName);if(N.includes(`@gjsify/cli`)){let n=C.installed.find(n=>n.name===`@gjsify/cli`)?.version??`latest`;await installGjsEnginePackages(S.prefix,n,{verbose:a.verbose})}reportLinkedBins(linkGlobalBins(N,S),S.binDir)}finally{C.release()}}function reportLinkedBins(n,a){if(n.length===0)ge.warn("\nNo bins declared (neither `gjsify.bin` nor `bin` in package.json) — nothing was symlinked.");else{ge.log(`\nLinked ${n.length} bin(s):`);for(let a of n)ge.log(` • ${a.link} → ${a.target}`)}n.length>0&&!binDirOnPath(a)&&ge.warn(`\nNote: ${a} is not on your PATH.\nAdd it to your shell rc file:\n export PATH="${a}:$PATH"`)}async function runPostInstallChecks(){ge.log(`
|
|
910
917
|
--- gjsify post-install checks ---`);let n=runMinimalChecks().filter(n=>!n.found&&n.severity===`required`);if(n.length>0){ge.warn(`Missing required system dependencies:
|
|
911
918
|
`);for(let a of n)ge.warn(` ✗ ${a.name}`);let a=buildInstallCommand(detectPackageManager$2(),n);a&&ge.warn(`\nInstall with:\n ${a}`)}else ge.log(`System dependencies OK.`);let a=detectNativePackages(process.cwd());if(a.length>0){ge.log(`\nDetected ${a.length} @gjsify/* package(s) with native prebuilds:`);for(let n of a)ge.log(` • ${n.name}`);ge.log("\nUse `gjsify run <bundle>` to launch with LD_LIBRARY_PATH/GI_TYPELIB_PATH set.")}maybeInstallGitHooks()}function maybeInstallGitHooks(){let n=process.cwd(),a=_s(n,`scripts`,`install-git-hooks.mjs`);if(existsSync(a)&&existsSync(_s(n,`.git`)))try{let S=spawnSync(nodeBinary(),[a,`--quiet`],{cwd:n,stdio:`inherit`,env:process.env});S.status!==0&&ge.warn(`[gjsify install] scripts/install-git-hooks.mjs exited ${S.status} — git hooks may not be active.`)}catch(n){ge.warn(`[gjsify install] git hook installation skipped: ${n instanceof Error?n.message:String(n)}`)}}var EF,DF,OF,kF,AF=__esmMin(()=>{_e(),gl(),Os(),rn(),Xm(),Tm(),R_(),GM(),OM(),lP(),wP(),WN(),$N(),MM(),tN(),B_(),TF(),FM(),EF=process.platform===`win32`?`junction`:void 0,DF=18e5,OF={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:DF}).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 ge.error(`gjsify install --immutable does not accept package arguments. Remove the package names or drop --immutable.`),process.exit(1);if(n.global)return ge.error(`gjsify install --immutable is incompatible with --global.`),process.exit(1);if(n[`refresh-lockfile`])return ge.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 ge.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]&&ge.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();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;ge.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()}catch(n){if(S!==null&&S.signal.aborted&&isAbortedFromOverallTimeout(n)){let n=Math.round(a/100)/10;return ge.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)}}},kF=`@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 jF){let S=a.pid?collectDescendants(a.pid):[];n.set(a,S),signalTree(a,S,`SIGTERM`)}setTimeout(()=>{for(let a of jF){let S=new Set(a.pid?collectDescendants(a.pid):[]);for(let C of n.get(a)??[])S.add(C);signalTree(a,[...S],`SIGKILL`)}},MF).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.`),ge.error(C.join(`
|
|
912
|
-
`)),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(),NF).unref?.())},oe=setInterval(()=>{let n=Date.now()-ie;n<3e5||re.size===0||(ge.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&&ge.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&&ge.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&&ge.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,jF.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&&jF.delete(N)}}var jF,MF,NF,PF,FF=__esmMin(()=>{_e(),tN(),gl(),um(),R_(),B_(),JM(),cN(),Tm(),jF=new Set,MF=5e3,NF=15e3,PF={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 ge.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 ge.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 ge.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 ge.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),ge.log(`gjsify foreach: shard ${S}/${C} → ${I.length} of ${n.length} workspace(s)`)}}if(I.length===0){ge.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 ge.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(),ge.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=[_s(n,`node_modules`,`.bin`)];F&&F!==n&&I.push(_s(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(Es),npm_lifecycle_event:S,npm_package_name:a.name??``,npm_package_version:a.version??``,...C.env},K=C.stdio===`inherit-stderr`?[`inherit`,2,2]:C.stdio??`inherit`;return await new Promise((a,C)=>{let F=spawn(N,[],{cwd:n,env:W,stdio:K,shell:!0});F.on(`close`,N=>{N===0?a():C(Error(`gjsify lifecycle-script: "${S}" in ${n} exited with code ${N}`))}),F.on(`error`,C)}),!0}var IF=__esmMin(()=>{Xm(),Os(),B_()});async function packWorkspace(n,a={}){let S=_s(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))+`
|
|
919
|
+
`)),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(),NF).unref?.())},oe=setInterval(()=>{let n=Date.now()-ie;n<3e5||re.size===0||(ge.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&&ge.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&&ge.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&&ge.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,jF.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&&jF.delete(N)}}var jF,MF,NF,PF,FF=__esmMin(()=>{_e(),tN(),gl(),um(),R_(),B_(),JM(),cN(),Tm(),jF=new Set,MF=5e3,NF=15e3,PF={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 ge.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 ge.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 ge.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 ge.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),ge.log(`gjsify foreach: shard ${S}/${C} → ${I.length} of ${n.length} workspace(s)`)}}if(I.length===0){ge.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 ge.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(),ge.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=[_s(n,`node_modules`,`.bin`)];F&&F!==n&&I.push(_s(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(Es),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 IF=__esmMin(()=>{Os(),tN(),B_()});async function packWorkspace(n,a={}){let S=_s(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))+`
|
|
913
920
|
`,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(_s(n,a)));let C=statSync(_s(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?ms(a.destination):n,ce=_s(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(_s(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=_s(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(`
|
|
914
921
|
`)+`
|
|
915
922
|
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?_s(n,a):n,N;try{N=readdirSync(C,{withFileTypes:!0})}catch{return S}for(let C of N){if(RF.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=_s(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=_s(n,`.npmignore`),S=_s(n,`.gitignore`),C=[],N=existsSync(a)?a:existsSync(S)?S:null;if(N){let n=readFileSync(N,`utf-8`).split(`
|
|
916
|
-
`);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 zF){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=_s(S,`package.json`);if(existsSync(n)&&readPackageJson$2(n)?.workspaces!==void 0)return S;let a=ms(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 zF){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 LF,RF,zF,BF=__esmMin(()=>{gl(),xo(),Os(),UN(),R_(),B_(),z_(),IF(),LF={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(ms(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`)}},RF=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`]),zF=[`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 VF===void 0&&(VF=`0.
|
|
923
|
+
`);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 zF){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=_s(S,`package.json`);if(existsSync(n)&&readPackageJson$2(n)?.workspaces!==void 0)return S;let a=ms(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 zF){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 LF,RF,zF,BF=__esmMin(()=>{gl(),xo(),Os(),UN(),R_(),B_(),z_(),IF(),LF={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(ms(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`)}},RF=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`]),zF=[`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 VF===void 0&&(VF=`0.30.0`),VF}function defaultUserAgent(){let n=globalThis.process,a=n?.arch??`x64`,S=n?.platform??`linux`;return`gjsify-publish/${cliVersion()} (${S} ${a})`}var VF,HF=__esmMin(()=>{gl(),Os(),RN()});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(UF.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 UF,sleep,OidcUnavailableError,OidcExchangeError,WF=__esmMin(()=>{UF=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(`
|
|
917
924
|
`)}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(`
|
|
918
925
|
`)}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 GF=__esmMin(()=>{RN()});async function loadNpmrc(n){let a=[],S=_s(n,`.npmrc`);existsSync(S)&&a.push(readFileSync(S,`utf-8`));let C=process.env.NPM_CONFIG_USERCONFIG;if(C&&existsSync(C))a.push(readFileSync(C,`utf-8`));else{let n=_s(homedir(),`.npmrc`);existsSync(n)&&a.push(readFileSync(n,`utf-8`))}return parseNpmrc(a.join(`
|
|
919
926
|
`).replace(/\$\{([A-Z_][A-Z0-9_]*)\}/gi,(n,a)=>process.env[a]??``))}function hasAnyAuthToken(n){return Object.keys(n.authTokens).length>0}function hasAnyCredential(n){return hasAnyAuthToken(n)||Object.keys(n.basicAuth).length>0}var KF=__esmMin(()=>{gl(),um(),Os(),RN()});function isTtyStdin(){let n=process.stdin;return!!n.isTTY&&typeof n.setRawMode==`function`}function applyKey(n,a,S){return a===`\r`||a===`
|