@stacksjs/desktop-build 0.75.98 → 0.75.100
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/index.d.ts +32 -0
- package/dist/index.js +2 -2
- package/dist/probe/runner.js +1 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -65,6 +65,33 @@ export declare function isMachO(path: string): boolean;
|
|
|
65
65
|
* Executables go in MacOS; everything else in Resources.
|
|
66
66
|
*/
|
|
67
67
|
export declare function bundleDirectoryFor(path: string): 'MacOS' | 'Resources';
|
|
68
|
+
/**
|
|
69
|
+
* The volume name for the app's DMG, which must never be the app's own name.
|
|
70
|
+
*
|
|
71
|
+
* `hdiutil create -volname <appName> -srcfolder <staging>` stages the bundle at
|
|
72
|
+
* `/Volumes/<appName>/<appName>.app`. On a Mac where that app is installed in
|
|
73
|
+
* `/Applications` and TCC-managed - it carries `com.apple.macl` and
|
|
74
|
+
* `com.apple.provenance` - macOS refuses to let a process without App
|
|
75
|
+
* Management rights create a bundle that would shadow it, and imaging fails
|
|
76
|
+
* with "Operation not permitted" (stacksjs/stacks#2884). The bundle is complete
|
|
77
|
+
* and correct by then; only the final step dies.
|
|
78
|
+
*
|
|
79
|
+
* It is the path rather than the content: the same bundle images fine under any
|
|
80
|
+
* other volume name, and a plain `cp -R` into that path is refused the same
|
|
81
|
+
* way, so it is not an hdiutil quirk. And it hits exactly the people most
|
|
82
|
+
* likely to be building, since it takes having installed the app you are
|
|
83
|
+
* working on.
|
|
84
|
+
*
|
|
85
|
+
* `${appName} ${version}` sidesteps it and is the usual convention anyway -
|
|
86
|
+
* most shipped DMGs mount as "AppName 1.2.3". hdiutil does not truncate long
|
|
87
|
+
* names (36 characters round-trip intact, probed against the real tool), so
|
|
88
|
+
* appending the version cannot fold the name back onto the app's.
|
|
89
|
+
*
|
|
90
|
+
* An explicit override is returned as given, collision included: the caller is
|
|
91
|
+
* warned at build time rather than quietly overruled, because rewriting what
|
|
92
|
+
* somebody typed is how a build becomes unpredictable.
|
|
93
|
+
*/
|
|
94
|
+
export declare function dmgVolumeName(options: DmgVolumeOptions): string;
|
|
68
95
|
/**
|
|
69
96
|
* The `codesign` invocation for one target in a distributable bundle:
|
|
70
97
|
* hardened runtime (notarization rejects anything without it) and a secure
|
|
@@ -173,6 +200,11 @@ export declare interface BundledRuntime {
|
|
|
173
200
|
name: string
|
|
174
201
|
bytes: number
|
|
175
202
|
}
|
|
203
|
+
export declare interface DmgVolumeOptions {
|
|
204
|
+
appName: string
|
|
205
|
+
version?: string
|
|
206
|
+
override?: string
|
|
207
|
+
}
|
|
176
208
|
export declare interface CodesignOptions {
|
|
177
209
|
identity: string
|
|
178
210
|
target: string
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
var u=(e,t,r)=>()=>{if(e)try{t=e(e=0)}catch(n){r=[n]}if(r)throw r[0];return t};function B(e,t,r={}){if(!t.trim())throw Error("Invite token is required");let n=new URL("/invite",/^https?:\/\//.test(e)?e:`https://${e}`);if(n.searchParams.set("token",t),r.email)n.searchParams.set("email",r.email);if(r.team)n.searchParams.set("team",r.team);if(r.role)n.searchParams.set("role",r.role);if(r.expiresAt){let i=r.expiresAt instanceof Date?r.expiresAt:new Date(r.expiresAt);if(Number.isNaN(i.valueOf()))throw Error("Invite expiration must be a valid date");n.searchParams.set("expires",i.toISOString())}return n.toString()}async function ce(e,t){return Promise.all(e.map(async(r)=>{let n=typeof r==="string"?{email:r}:r;try{L(n.email);let i=await t.createToken(n),s=B(t.baseUrl,i,{email:n.email,team:n.team,role:n.role,expiresAt:t.expiresAt});return await t.send({recipient:n,url:s}),{recipient:n,url:s,delivered:!0}}catch(i){return{recipient:n,url:"",delivered:!1,error:i instanceof Error?i.message:String(i)}}}))}function L(e){if(!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e))throw Error(`Invalid invite email: ${e}`)}import{createHash as j,createPublicKey as F,verify as O}from"crypto";import{mkdir as M,rename as P,rm as T,writeFile as z}from"fs/promises";import m from"process";import{dirname as N}from"path";async function ge(e){y(e.manifestUrl);let t=await(e.fetcher||fetch)(e.manifestUrl,{headers:{Accept:"application/json"}});if(!t.ok)throw Error(`Desktop update check failed with HTTP ${t.status}`);let r=k(await t.json());return w(r,e.trustedKeys),b(r,e.target),K(r.version,e.currentVersion)>0?r:null}async function he(e,t,r=fetch,n,i){if(k(e),!n)throw Error("Desktop update staging requires trusted signing keys");w(e,n),b(e,i),y(e.url);let s=await r(e.url);if(!s.ok)throw Error(`Desktop update download failed with HTTP ${s.status}`);let o=new Uint8Array(await s.arrayBuffer());if(o.byteLength!==e.size)throw Error(`Desktop update size mismatch: expected ${e.size}, received ${o.byteLength}`);if(j("sha256").update(o).digest("hex")!==e.sha256.toLowerCase())throw Error("Desktop update checksum mismatch");await M(N(t),{recursive:!0});let p=`${t}.download-${crypto.randomUUID()}`;try{await z(p,o,{mode:448}),await P(p,t)}catch(A){throw await T(p,{force:!0}),A}return{manifest:e,path:t,bytes:o.byteLength}}function K(e,t){let r=l(e),n=l(t);for(let i=0;i<3;i++){let s=r[i]-n[i];if(s!==0)return Math.sign(s)}return 0}function k(e){if(!e||typeof e!=="object")throw Error("Desktop update manifest must be an object");let t=e;if(l(t.version||""),typeof t.url!=="string")throw Error("Desktop update manifest requires a URL");if(typeof t.sha256!=="string"||!/^[a-f0-9]{64}$/i.test(t.sha256))throw Error("Desktop update manifest requires a SHA-256 checksum");if(!Number.isInteger(t.size)||t.size<0)throw Error("Desktop update manifest requires a non-negative integer size");if(typeof t.sourceRevision!=="string"||!/^[0-9a-f]{40}$/.test(t.sourceRevision))throw Error("Desktop update manifest requires a full source revision");if(typeof t.platform!=="string"||!["darwin","linux","win32"].includes(t.platform))throw Error("Desktop update manifest requires a supported platform identifier");if(typeof t.architecture!=="string"||!/^[a-z0-9_-]+$/.test(t.architecture))throw Error("Desktop update manifest requires an architecture");if(typeof t.signingKeyId!=="string"||!/^[a-zA-Z0-9._-]+$/.test(t.signingKeyId))throw Error("Desktop update manifest requires a signing key ID");if(typeof t.signature!=="string"||!/^[A-Za-z0-9_-]+$/.test(t.signature))throw Error("Desktop update manifest requires an Ed25519 signature");return t}function _(e){return Buffer.from(JSON.stringify({version:e.version,url:e.url,sha256:e.sha256.toLowerCase(),size:e.size,sourceRevision:e.sourceRevision,platform:e.platform,architecture:e.architecture,signingKeyId:e.signingKeyId,publishedAt:e.publishedAt||null,notes:e.notes||null}),"utf8")}function w(e,t){let r=t[e.signingKeyId];if(!r)throw Error(`Desktop update signing key is not trusted: ${e.signingKeyId}`);let n="ed25519-public:";if(!r.startsWith(n))throw Error("Desktop update signing key has an invalid encoding");try{let i=F({key:Buffer.from(r.slice(n.length),"base64url"),format:"der",type:"spki"}),s=Buffer.from(e.signature,"base64url");if(i.asymmetricKeyType!=="ed25519"||s.length!==64||!O(null,_(e),i,s))throw Error("invalid")}catch{throw Error("Desktop update manifest signature verification failed")}}function b(e,t={platform:m.platform,architecture:m.arch}){if(e.platform!==t.platform||e.architecture!==t.architecture)throw Error(`Desktop update is built for ${e.platform}-${e.architecture}, not this app's ${t.platform}-${t.architecture}`)}function l(e){let t=e.match(/^v?(\d+)\.(\d+)\.(\d+)(?:-[0-9A-Za-z.-]+)?$/);if(!t)throw Error(`Invalid semantic version: ${e}`);return[Number(t[1]),Number(t[2]),Number(t[3])]}function y(e){let t=new URL(e),r=["localhost","127.0.0.1","::1"].includes(t.hostname);if(t.protocol!=="https:"&&!(t.protocol==="http:"&&r))throw Error("Desktop updates require HTTPS outside loopback development")}var v=()=>{};function V(e=process.platform,t=process.arch){return q.find((r)=>r.platform===e&&r.architecture===t)}function ke(e,t=process.platform,r=process.arch){let n=V(t,r);if(!n)throw Error(`Desktop target ${t}/${r} is unsupported`);if(e==="stable"&&(n.status!=="stable"||n.signing!=="enforced"||n.platform==="darwin"&&n.notarization!=="enforced"||!n.installLaunchEvidence||!n.updateRollbackEvidence))throw Error(`Desktop target ${t}/${r} cannot be released as stable; complete stacksjs/stacks#2059, #2062, and #2063 first`);return n}var q;var x=u(()=>{q=[{platform:"darwin",architecture:"arm64",status:"experimental",osVersions:["macOS 27.0 (local run, Craft v0.0.107 published archive)","macOS 15 runner (CI, Craft v0.0.48 from source)"],packageFormat:"DMG + PKG",signing:"pending",notarization:"pending",installLaunchEvidence:"https://github.com/stacksjs/stacks/blob/main/storage/framework/core/desktop/evidence/lifecycle-darwin-arm64.json",updateRollbackEvidence:"https://github.com/stacksjs/stacks/blob/main/storage/framework/core/desktop/evidence/lifecycle-darwin-arm64.json",packagingEvidence:"https://github.com/stacksjs/protocol/blob/main/evidence/craft.json",blockingIssues:["https://github.com/stacksjs/stacks/issues/2062"],limitations:["The Stacks-built app bundle, DMG and PKG are unsigned while platform identities remain unprovisioned. The Craft runtime inside them is Developer ID-signed by Craft's own release workflow, which does not make the app signed.","Lifecycle evidence was re-run on 2026-10-03 against the published Craft v0.0.107 archive (craft-darwin-arm64.zip, sha256 98e1a7ae478a8900256add2884d05cc07aea2f3de7d550590d9458abd4fe7725) with `storage/framework/core/desktop/evidence/lifecycle.ts`: PKG and DMG install, a real Craft window launched from the installed bundle, update, a refused truncated update, rollback and uninstall all passed.","That run was local on macOS 27.0, not CI, and installed into the user domain (~/Applications) rather than /Applications. Gatekeeper was not exercised, since nothing carried a quarantine flag. The last CI lifecycle run for this target (https://github.com/stacksjs/stacks/actions/runs/29890804159, macOS 15 runner) used Craft v0.0.48 built from source."]},{platform:"darwin",architecture:"x64",status:"experimental",osVersions:["macOS 15 Intel runner"],packageFormat:"DMG + PKG",signing:"pending",notarization:"pending",installLaunchEvidence:"https://github.com/stacksjs/stacks/actions/runs/29890804159",updateRollbackEvidence:"https://github.com/stacksjs/stacks/actions/runs/29890804159",packagingEvidence:"https://github.com/stacksjs/protocol/blob/main/evidence/craft.json",blockingIssues:["https://github.com/stacksjs/stacks/issues/2062"],limitations:["Lifecycle fixtures are unsigned while platform identities remain unprovisioned.","Lifecycle evidence was produced against Craft v0.0.48 built from source (bf75807). Craft now publishes a prebuilt craft-darwin-x64.zip with every release, and no Stacks lifecycle run has re-verified a prebuilt release yet."]},{platform:"linux",architecture:"x64",status:"experimental",osVersions:["Ubuntu 24.04 runner"],packageFormat:"DEB",signing:"pending",notarization:"not-applicable",installLaunchEvidence:"https://github.com/stacksjs/stacks/actions/runs/29890804159",updateRollbackEvidence:"https://github.com/stacksjs/stacks/actions/runs/29890804159",packagingEvidence:"https://github.com/stacksjs/protocol/blob/main/evidence/craft.json",blockingIssues:["https://github.com/stacksjs/stacks/issues/2062"],limitations:["The lifecycle fixture is unsigned and no package repository support policy is published.","Lifecycle evidence was produced against Craft v0.0.48 built from source (bf75807). Craft now publishes a prebuilt craft-linux-x64.zip with every release, and no Stacks lifecycle run has re-verified a prebuilt release yet."]},{platform:"win32",architecture:"x64",status:"experimental",osVersions:["Windows Server 2025 runner"],packageFormat:"MSI + ZIP",signing:"pending",notarization:"not-applicable",installLaunchEvidence:"https://github.com/stacksjs/stacks/actions/runs/29890804159",updateRollbackEvidence:"https://github.com/stacksjs/stacks/actions/runs/29890804159",packagingEvidence:"https://github.com/stacksjs/protocol/blob/main/evidence/craft.json",blockingIssues:["https://github.com/stacksjs/stacks/issues/2062"],limitations:["The lifecycle fixture is not Authenticode-signed.","Lifecycle evidence was produced against Craft v0.0.48 built from source (bf75807). Craft now publishes a prebuilt craft-windows-x64.zip with every release, and no Stacks lifecycle run has re-verified a prebuilt release yet."]}]});import{closeSync as E,existsSync as d,openSync as S,readSync as C,statSync as G}from"fs";import{dirname as W,join as c}from"path";import a from"process";import{fileURLToPath as H}from"url";import{craftBinaryNotFoundMessage as Z,resolveCraftBinary as J}from"craft-native";function R(e=a.env.CRAFT_BIN){return J(e)}function Ee(e=a.env.CRAFT_BIN,t=(r)=>Bun.which(r)){let r=R(e);if(r!=="craft")return r;let n=t(r);if(!n)throw Error(Z(r));return n}function Se(e=a.cwd()){return d(c(e,I))}function Ce(e){return["build","--compile",...e.minify===!1?[]:["--minify"],"--no-compile-autoload-bunfig","--no-compile-autoload-dotenv",e.entry,"--outfile",e.outfile]}function Re(e=a.cwd()){let t=c(e,I);if(d(t))return t;let r=W(H(import.meta.url)),i=[c(r,"launcher.ts"),c(r,"launcher.js")].find((s)=>d(s));if(!i)throw Error("Desktop launcher entrypoint not found. Reinstall @stacksjs/desktop - the package must ship dist/launcher.js.");return i}function f(e){return e.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""").replaceAll("'","'")}function g(e,t=""){if(typeof e==="string")return`<string>${f(e)}</string>`;if(typeof e==="boolean")return e?"<true/>":"<false/>";if(typeof e==="number"){if(!Number.isFinite(e))throw Error(`Unsupported Info.plist number: ${e}`);return Number.isInteger(e)?`<integer>${e}</integer>`:`<real>${e}</real>`}if(Array.isArray(e)){if(e.length===0)return"<array/>";return`<array>
|
|
2
|
+
var u=(e,t,r)=>()=>{if(e)try{t=e(e=0)}catch(n){r=[n]}if(r)throw r[0];return t};function B(e,t,r={}){if(!t.trim())throw Error("Invite token is required");let n=new URL("/invite",/^https?:\/\//.test(e)?e:`https://${e}`);if(n.searchParams.set("token",t),r.email)n.searchParams.set("email",r.email);if(r.team)n.searchParams.set("team",r.team);if(r.role)n.searchParams.set("role",r.role);if(r.expiresAt){let i=r.expiresAt instanceof Date?r.expiresAt:new Date(r.expiresAt);if(Number.isNaN(i.valueOf()))throw Error("Invite expiration must be a valid date");n.searchParams.set("expires",i.toISOString())}return n.toString()}async function ce(e,t){return Promise.all(e.map(async(r)=>{let n=typeof r==="string"?{email:r}:r;try{L(n.email);let i=await t.createToken(n),s=B(t.baseUrl,i,{email:n.email,team:n.team,role:n.role,expiresAt:t.expiresAt});return await t.send({recipient:n,url:s}),{recipient:n,url:s,delivered:!0}}catch(i){return{recipient:n,url:"",delivered:!1,error:i instanceof Error?i.message:String(i)}}}))}function L(e){if(!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e))throw Error(`Invalid invite email: ${e}`)}import{createHash as j,createPublicKey as F,verify as O}from"crypto";import{mkdir as M,rename as P,rm as T,writeFile as z}from"fs/promises";import m from"process";import{dirname as N}from"path";async function ge(e){y(e.manifestUrl);let t=await(e.fetcher||fetch)(e.manifestUrl,{headers:{Accept:"application/json"}});if(!t.ok)throw Error(`Desktop update check failed with HTTP ${t.status}`);let r=k(await t.json());return w(r,e.trustedKeys),b(r,e.target),K(r.version,e.currentVersion)>0?r:null}async function he(e,t,r=fetch,n,i){if(k(e),!n)throw Error("Desktop update staging requires trusted signing keys");w(e,n),b(e,i),y(e.url);let s=await r(e.url);if(!s.ok)throw Error(`Desktop update download failed with HTTP ${s.status}`);let o=new Uint8Array(await s.arrayBuffer());if(o.byteLength!==e.size)throw Error(`Desktop update size mismatch: expected ${e.size}, received ${o.byteLength}`);if(j("sha256").update(o).digest("hex")!==e.sha256.toLowerCase())throw Error("Desktop update checksum mismatch");await M(N(t),{recursive:!0});let p=`${t}.download-${crypto.randomUUID()}`;try{await z(p,o,{mode:448}),await P(p,t)}catch(A){throw await T(p,{force:!0}),A}return{manifest:e,path:t,bytes:o.byteLength}}function K(e,t){let r=l(e),n=l(t);for(let i=0;i<3;i++){let s=r[i]-n[i];if(s!==0)return Math.sign(s)}return 0}function k(e){if(!e||typeof e!=="object")throw Error("Desktop update manifest must be an object");let t=e;if(l(t.version||""),typeof t.url!=="string")throw Error("Desktop update manifest requires a URL");if(typeof t.sha256!=="string"||!/^[a-f0-9]{64}$/i.test(t.sha256))throw Error("Desktop update manifest requires a SHA-256 checksum");if(!Number.isInteger(t.size)||t.size<0)throw Error("Desktop update manifest requires a non-negative integer size");if(typeof t.sourceRevision!=="string"||!/^[0-9a-f]{40}$/.test(t.sourceRevision))throw Error("Desktop update manifest requires a full source revision");if(typeof t.platform!=="string"||!["darwin","linux","win32"].includes(t.platform))throw Error("Desktop update manifest requires a supported platform identifier");if(typeof t.architecture!=="string"||!/^[a-z0-9_-]+$/.test(t.architecture))throw Error("Desktop update manifest requires an architecture");if(typeof t.signingKeyId!=="string"||!/^[a-zA-Z0-9._-]+$/.test(t.signingKeyId))throw Error("Desktop update manifest requires a signing key ID");if(typeof t.signature!=="string"||!/^[A-Za-z0-9_-]+$/.test(t.signature))throw Error("Desktop update manifest requires an Ed25519 signature");return t}function _(e){return Buffer.from(JSON.stringify({version:e.version,url:e.url,sha256:e.sha256.toLowerCase(),size:e.size,sourceRevision:e.sourceRevision,platform:e.platform,architecture:e.architecture,signingKeyId:e.signingKeyId,publishedAt:e.publishedAt||null,notes:e.notes||null}),"utf8")}function w(e,t){let r=t[e.signingKeyId];if(!r)throw Error(`Desktop update signing key is not trusted: ${e.signingKeyId}`);let n="ed25519-public:";if(!r.startsWith(n))throw Error("Desktop update signing key has an invalid encoding");try{let i=F({key:Buffer.from(r.slice(n.length),"base64url"),format:"der",type:"spki"}),s=Buffer.from(e.signature,"base64url");if(i.asymmetricKeyType!=="ed25519"||s.length!==64||!O(null,_(e),i,s))throw Error("invalid")}catch{throw Error("Desktop update manifest signature verification failed")}}function b(e,t={platform:m.platform,architecture:m.arch}){if(e.platform!==t.platform||e.architecture!==t.architecture)throw Error(`Desktop update is built for ${e.platform}-${e.architecture}, not this app's ${t.platform}-${t.architecture}`)}function l(e){let t=e.match(/^v?(\d+)\.(\d+)\.(\d+)(?:-[0-9A-Za-z.-]+)?$/);if(!t)throw Error(`Invalid semantic version: ${e}`);return[Number(t[1]),Number(t[2]),Number(t[3])]}function y(e){let t=new URL(e),r=["localhost","127.0.0.1","::1"].includes(t.hostname);if(t.protocol!=="https:"&&!(t.protocol==="http:"&&r))throw Error("Desktop updates require HTTPS outside loopback development")}var v=()=>{};function q(e=process.platform,t=process.arch){return V.find((r)=>r.platform===e&&r.architecture===t)}function ke(e,t=process.platform,r=process.arch){let n=q(t,r);if(!n)throw Error(`Desktop target ${t}/${r} is unsupported`);if(e==="stable"&&(n.status!=="stable"||n.signing!=="enforced"||n.platform==="darwin"&&n.notarization!=="enforced"||!n.installLaunchEvidence||!n.updateRollbackEvidence))throw Error(`Desktop target ${t}/${r} cannot be released as stable; complete stacksjs/stacks#2059, #2062, and #2063 first`);return n}var V;var x=u(()=>{V=[{platform:"darwin",architecture:"arm64",status:"experimental",osVersions:["macOS 27.0 (local run, Craft v0.0.107 published archive)","macOS 15 runner (CI, Craft v0.0.48 from source)"],packageFormat:"DMG + PKG",signing:"pending",notarization:"pending",installLaunchEvidence:"https://github.com/stacksjs/stacks/blob/main/storage/framework/core/desktop/evidence/lifecycle-darwin-arm64.json",updateRollbackEvidence:"https://github.com/stacksjs/stacks/blob/main/storage/framework/core/desktop/evidence/lifecycle-darwin-arm64.json",packagingEvidence:"https://github.com/stacksjs/protocol/blob/main/evidence/craft.json",blockingIssues:["https://github.com/stacksjs/stacks/issues/2062"],limitations:["The Stacks-built app bundle, DMG and PKG are unsigned while platform identities remain unprovisioned. The Craft runtime inside them is Developer ID-signed by Craft's own release workflow, which does not make the app signed.","Lifecycle evidence was re-run on 2026-10-03 against the published Craft v0.0.107 archive (craft-darwin-arm64.zip, sha256 98e1a7ae478a8900256add2884d05cc07aea2f3de7d550590d9458abd4fe7725) with `storage/framework/core/desktop/evidence/lifecycle.ts`: PKG and DMG install, a real Craft window launched from the installed bundle, update, a refused truncated update, rollback and uninstall all passed.","That run was local on macOS 27.0, not CI, and installed into the user domain (~/Applications) rather than /Applications. Gatekeeper was not exercised, since nothing carried a quarantine flag. The last CI lifecycle run for this target (https://github.com/stacksjs/stacks/actions/runs/29890804159, macOS 15 runner) used Craft v0.0.48 built from source."]},{platform:"darwin",architecture:"x64",status:"experimental",osVersions:["macOS 15 Intel runner"],packageFormat:"DMG + PKG",signing:"pending",notarization:"pending",installLaunchEvidence:"https://github.com/stacksjs/stacks/actions/runs/29890804159",updateRollbackEvidence:"https://github.com/stacksjs/stacks/actions/runs/29890804159",packagingEvidence:"https://github.com/stacksjs/protocol/blob/main/evidence/craft.json",blockingIssues:["https://github.com/stacksjs/stacks/issues/2062"],limitations:["Lifecycle fixtures are unsigned while platform identities remain unprovisioned.","Lifecycle evidence was produced against Craft v0.0.48 built from source (bf75807). Craft now publishes a prebuilt craft-darwin-x64.zip with every release, and no Stacks lifecycle run has re-verified a prebuilt release yet."]},{platform:"linux",architecture:"x64",status:"experimental",osVersions:["Ubuntu 24.04 runner"],packageFormat:"DEB",signing:"pending",notarization:"not-applicable",installLaunchEvidence:"https://github.com/stacksjs/stacks/actions/runs/29890804159",updateRollbackEvidence:"https://github.com/stacksjs/stacks/actions/runs/29890804159",packagingEvidence:"https://github.com/stacksjs/protocol/blob/main/evidence/craft.json",blockingIssues:["https://github.com/stacksjs/stacks/issues/2062"],limitations:["The lifecycle fixture is unsigned and no package repository support policy is published.","Lifecycle evidence was produced against Craft v0.0.48 built from source (bf75807). Craft now publishes a prebuilt craft-linux-x64.zip with every release, and no Stacks lifecycle run has re-verified a prebuilt release yet."]},{platform:"win32",architecture:"x64",status:"experimental",osVersions:["Windows Server 2025 runner"],packageFormat:"MSI + ZIP",signing:"pending",notarization:"not-applicable",installLaunchEvidence:"https://github.com/stacksjs/stacks/actions/runs/29890804159",updateRollbackEvidence:"https://github.com/stacksjs/stacks/actions/runs/29890804159",packagingEvidence:"https://github.com/stacksjs/protocol/blob/main/evidence/craft.json",blockingIssues:["https://github.com/stacksjs/stacks/issues/2062"],limitations:["The lifecycle fixture is not Authenticode-signed.","Lifecycle evidence was produced against Craft v0.0.48 built from source (bf75807). Craft now publishes a prebuilt craft-windows-x64.zip with every release, and no Stacks lifecycle run has re-verified a prebuilt release yet."]}]});import{closeSync as E,existsSync as d,openSync as S,readSync as C,statSync as G}from"fs";import{dirname as W,join as c}from"path";import a from"process";import{fileURLToPath as H}from"url";import{craftBinaryNotFoundMessage as Z,resolveCraftBinary as J}from"craft-native";function R(e=a.env.CRAFT_BIN){return J(e)}function Ee(e=a.env.CRAFT_BIN,t=(r)=>Bun.which(r)){let r=R(e);if(r!=="craft")return r;let n=t(r);if(!n)throw Error(Z(r));return n}function Se(e=a.cwd()){return d(c(e,I))}function Ce(e){return["build","--compile",...e.minify===!1?[]:["--minify"],"--no-compile-autoload-bunfig","--no-compile-autoload-dotenv",e.entry,"--outfile",e.outfile]}function Re(e=a.cwd()){let t=c(e,I);if(d(t))return t;let r=W(H(import.meta.url)),i=[c(r,"launcher.ts"),c(r,"launcher.js")].find((s)=>d(s));if(!i)throw Error("Desktop launcher entrypoint not found. Reinstall @stacksjs/desktop - the package must ship dist/launcher.js.");return i}function f(e){return e.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""").replaceAll("'","'")}function g(e,t=""){if(typeof e==="string")return`<string>${f(e)}</string>`;if(typeof e==="boolean")return e?"<true/>":"<false/>";if(typeof e==="number"){if(!Number.isFinite(e))throw Error(`Unsupported Info.plist number: ${e}`);return Number.isInteger(e)?`<integer>${e}</integer>`:`<real>${e}</real>`}if(Array.isArray(e)){if(e.length===0)return"<array/>";return`<array>
|
|
3
3
|
${e.map((n)=>`${t} ${g(n,`${t} `)}`).join(`
|
|
4
4
|
`)}
|
|
5
5
|
${t}</array>`}if(e&&typeof e==="object"){let r=Object.entries(e);if(r.length===0)return"<dict/>";return`<dict>
|
|
@@ -7,4 +7,4 @@ ${r.map(([i,s])=>`${t} <key>${f(i)}</key>${g(s,`${t} `)}`).join(`
|
|
|
7
7
|
`)}
|
|
8
8
|
${t}</dict>`}throw Error(`Unsupported Info.plist value: ${JSON.stringify(e)??String(e)}`)}function Ie(e){let t=Object.keys(e).filter((i)=>D.has(i)),r=Object.entries(e).filter(([i])=>!D.has(i));if(r.length===0)return{xml:"",ignored:t};return{xml:`
|
|
9
9
|
${r.map(([i,s])=>` <key>${f(i)}</key>${g(s," ")}`).join(`
|
|
10
|
-
`)}`,ignored:t}}function Y(e,t={}){if(!Number.isInteger(e)||e<1||e>65535)throw RangeError(`Invalid desktop development port: ${e}`);let r=t.url||a.env.APP_URL;if(!r)return"https://stacks.test";let n=/^https?:\/\//.test(r)?r:`https://${r}`;return new URL(n).toString().replace(/\/$/,"")}function X(e,t={}){let r=[R(t.craftBin),Y(e,t),"--title",t.title||"Stacks","--width",String(t.width||1400),"--height",String(t.height||900)];if(t.hotReload!==!1)r.push("--hot-reload");if(t.devTools===!1)r.push("--no-devtools");if(t.darkMode)r.push("--dark");if(t.systemTray)r.push("--system-tray");if(t.hideDockIcon)r.push("--hide-dock-icon");if(t.menubarOnly)r.push("--menubar-only");return r}function $e(e,t="stable"){if(!/^[a-z0-9-]+$/i.test(t))throw Error("Update channel may only contain letters, numbers, and hyphens");return new URL(`/desktop/updates/${t}.json`,/^https?:\/\//.test(e)?e:`https://${e}`).toString()}async function Q(e){Bun.spawn(e,{stdin:"inherit",stdout:"inherit",stderr:"inherit"}).unref()}async function Ae(e,t={},r=Q){return await r(X(e,t)),!0}function ne(e){try{let t=S(e,"r");try{let r=Buffer.alloc(4);if(C(t,r,0,4,0)<4)return!1;return re.has(r.readUInt32BE(0))}finally{E(t)}}catch{return!1}}function Ue(e){return ne(e)?"MacOS":"Resources"}function Be(e){return["codesign","--force",e.identity==="-"?"--timestamp=none":"--timestamp","--options","runtime",...e.entitlements?["--entitlements",e.entitlements]:[],"--sign",e.identity,e.target]}function
|
|
10
|
+
`)}`,ignored:t}}function Y(e,t={}){if(!Number.isInteger(e)||e<1||e>65535)throw RangeError(`Invalid desktop development port: ${e}`);let r=t.url||a.env.APP_URL;if(!r)return"https://stacks.test";let n=/^https?:\/\//.test(r)?r:`https://${r}`;return new URL(n).toString().replace(/\/$/,"")}function X(e,t={}){let r=[R(t.craftBin),Y(e,t),"--title",t.title||"Stacks","--width",String(t.width||1400),"--height",String(t.height||900)];if(t.hotReload!==!1)r.push("--hot-reload");if(t.devTools===!1)r.push("--no-devtools");if(t.darkMode)r.push("--dark");if(t.systemTray)r.push("--system-tray");if(t.hideDockIcon)r.push("--hide-dock-icon");if(t.menubarOnly)r.push("--menubar-only");return r}function $e(e,t="stable"){if(!/^[a-z0-9-]+$/i.test(t))throw Error("Update channel may only contain letters, numbers, and hyphens");return new URL(`/desktop/updates/${t}.json`,/^https?:\/\//.test(e)?e:`https://${e}`).toString()}async function Q(e){Bun.spawn(e,{stdin:"inherit",stdout:"inherit",stderr:"inherit"}).unref()}async function Ae(e,t={},r=Q){return await r(X(e,t)),!0}function ne(e){try{let t=S(e,"r");try{let r=Buffer.alloc(4);if(C(t,r,0,4,0)<4)return!1;return re.has(r.readUInt32BE(0))}finally{E(t)}}catch{return!1}}function Ue(e){return ne(e)?"MacOS":"Resources"}function Be(e){let t=e.override?.trim();if(t)return t;let r=e.appName.trim(),n=e.version?.trim();return n?`${r} ${n}`:`${r} Installer`}function Le(e){return["codesign","--force",e.identity==="-"?"--timestamp=none":"--timestamp","--options","runtime",...e.entitlements?["--entitlements",e.entitlements]:[],"--sign",e.identity,e.target]}function je(e,t=ie){let r=t(e);if(!r||r.size<h)return!1;return r.tail.includes(ee)}function ie(e){try{let{size:t}=G(e);if(t<h)return{size:t,tail:""};let r=S(e,"r");try{let n=Math.min(te,t),i=Buffer.alloc(n);return C(r,i,0,n,t-n),{size:t,tail:i.toString("latin1")}}finally{E(r)}}catch{return null}}function Fe(e){if(e.length<2)return null;let t=[...e].sort((s,o)=>o.bytes-s.bytes),n=t.slice(1).length*h,i=t.map((s)=>`${s.name} (${(s.bytes/1024/1024).toFixed(1)} MB)`).join(", ");return`This bundle ships ${e.length} Bun-compiled executables: ${i}. Each embeds a full copy of the Bun runtime, so at least ${(n/1024/1024).toFixed(0)} MB of the bundle is the same runtime repeated. `+"Compiling one binary that dispatches on a subcommand \u2014 `MyApp agent`, `MyApp worker` \u2014 keeps the helpers as separate processes and pays for the runtime once."}var I="app/Desktop/launcher.ts",D,ee="---- Bun!",te=8388608,h=41943040,re;var se=u(()=>{v();x();D=new Set(["CFBundleName","CFBundleDisplayName","CFBundleIdentifier","CFBundleVersion","CFBundleShortVersionString","CFBundleExecutable","CFBundlePackageType","CFBundleInfoDictionaryVersion","CFBundleIconFile"]);re=new Set([4277009102,3472551422,4277009103,3489328638,3405691582,3199925962])});se();export{ee as BUN_EXECUTABLE_MARKER,D as RESERVED_PLIST_KEYS,I as USERLAND_LAUNCHER,ke as assertDesktopReleaseChannel,Ue as bundleDirectoryFor,ge as checkForDesktopUpdate,Le as codesignArgs,K as compareVersions,X as craftDevCommand,B as createInviteLink,$e as createUpdateManifestUrl,Fe as describeRuntimeDuplication,Ce as desktopLauncherCompileArgs,q as desktopSupport,V as desktopSupportMatrix,Be as dmgVolumeName,Se as hasUserlandDesktopLauncher,ne as isMachO,je as looksLikeBunExecutable,Ae as openDevWindow,g as plistValue,Ie as renderUserlandPlistEntries,R as resolveCraftBinary,Ee as resolveCraftExecutable,Re as resolveDesktopLauncher,Y as resolveDevWindowUrl,ce as sendDesktopInvites,he as stageDesktopUpdate,_ as updateManifestPayload,k as validateUpdateManifest,w as verifyUpdateManifestSignature,f as xmlEscape};
|
package/dist/probe/runner.js
CHANGED
|
@@ -7,7 +7,7 @@ ${n.map(([s,o])=>`${t} <key>${H(s)}</key>${q(o,`${t} `)}`).join(`
|
|
|
7
7
|
`)}
|
|
8
8
|
${t}</dict>`}throw Error(`Unsupported Info.plist value: ${JSON.stringify(e)??String(e)}`)}function yn(e){let t=Object.keys(e).filter((s)=>fe.has(s)),n=Object.entries(e).filter(([s])=>!fe.has(s));if(n.length===0)return{xml:"",ignored:t};return{xml:`
|
|
9
9
|
${n.map(([s,o])=>` <key>${H(s)}</key>${q(o," ")}`).join(`
|
|
10
|
-
`)}`,ignored:t}}function gt(e,t={}){if(!Number.isInteger(e)||e<1||e>65535)throw RangeError(`Invalid desktop development port: ${e}`);let n=t.url||E.env.APP_URL;if(!n)return"https://stacks.test";let r=/^https?:\/\//.test(n)?n:`https://${n}`;return new URL(r).toString().replace(/\/$/,"")}function ht(e,t={}){let n=[we(t.craftBin),gt(e,t),"--title",t.title||"Stacks","--width",String(t.width||1400),"--height",String(t.height||900)];if(t.hotReload!==!1)n.push("--hot-reload");if(t.devTools===!1)n.push("--no-devtools");if(t.darkMode)n.push("--dark");if(t.systemTray)n.push("--system-tray");if(t.hideDockIcon)n.push("--hide-dock-icon");if(t.menubarOnly)n.push("--menubar-only");return n}function kn(e,t="stable"){if(!/^[a-z0-9-]+$/i.test(t))throw Error("Update channel may only contain letters, numbers, and hyphens");return new URL(`/desktop/updates/${t}.json`,/^https?:\/\//.test(e)?e:`https://${e}`).toString()}async function bt(e){Bun.spawn(e,{stdin:"inherit",stdout:"inherit",stderr:"inherit"}).unref()}async function vn(e,t={},n=bt){return await n(ht(e,t)),!0}function vt(e){try{let t=he(e,"r");try{let n=Buffer.alloc(4);if(be(t,n,0,4,0)<4)return!1;return kt.has(n.readUInt32BE(0))}finally{ge(t)}}catch{return!1}}function xn(e){return vt(e)?"MacOS":"Resources"}function Pn(e){return["codesign","--force",e.identity==="-"?"--timestamp=none":"--timestamp","--options","runtime",...e.entitlements?["--entitlements",e.entitlements]:[],"--sign",e.identity,e.target]}function
|
|
10
|
+
`)}`,ignored:t}}function gt(e,t={}){if(!Number.isInteger(e)||e<1||e>65535)throw RangeError(`Invalid desktop development port: ${e}`);let n=t.url||E.env.APP_URL;if(!n)return"https://stacks.test";let r=/^https?:\/\//.test(n)?n:`https://${n}`;return new URL(r).toString().replace(/\/$/,"")}function ht(e,t={}){let n=[we(t.craftBin),gt(e,t),"--title",t.title||"Stacks","--width",String(t.width||1400),"--height",String(t.height||900)];if(t.hotReload!==!1)n.push("--hot-reload");if(t.devTools===!1)n.push("--no-devtools");if(t.darkMode)n.push("--dark");if(t.systemTray)n.push("--system-tray");if(t.hideDockIcon)n.push("--hide-dock-icon");if(t.menubarOnly)n.push("--menubar-only");return n}function kn(e,t="stable"){if(!/^[a-z0-9-]+$/i.test(t))throw Error("Update channel may only contain letters, numbers, and hyphens");return new URL(`/desktop/updates/${t}.json`,/^https?:\/\//.test(e)?e:`https://${e}`).toString()}async function bt(e){Bun.spawn(e,{stdin:"inherit",stdout:"inherit",stderr:"inherit"}).unref()}async function vn(e,t={},n=bt){return await n(ht(e,t)),!0}function vt(e){try{let t=he(e,"r");try{let n=Buffer.alloc(4);if(be(t,n,0,4,0)<4)return!1;return kt.has(n.readUInt32BE(0))}finally{ge(t)}}catch{return!1}}function xn(e){return vt(e)?"MacOS":"Resources"}function Pn(e){let t=e.override?.trim();if(t)return t;let n=e.appName.trim(),r=e.version?.trim();return r?`${n} ${r}`:`${n} Installer`}function $n(e){return["codesign","--force",e.identity==="-"?"--timestamp=none":"--timestamp","--options","runtime",...e.entitlements?["--entitlements",e.entitlements]:[],"--sign",e.identity,e.target]}function Rn(e,t=xt){let n=t(e);if(!n||n.size<W)return!1;return n.tail.includes(wt)}function xt(e){try{let{size:t}=lt(e);if(t<W)return{size:t,tail:""};let n=he(e,"r");try{let r=Math.min(yt,t),s=Buffer.alloc(r);return be(n,s,0,r,t-r),{size:t,tail:s.toString("latin1")}}finally{ge(n)}}catch{return null}}function Sn(e){if(e.length<2)return null;let t=[...e].sort((o,a)=>a.bytes-o.bytes),r=t.slice(1).length*W,s=t.map((o)=>`${o.name} (${(o.bytes/1024/1024).toFixed(1)} MB)`).join(", ");return`This bundle ships ${e.length} Bun-compiled executables: ${s}. Each embeds a full copy of the Bun runtime, so at least ${(r/1024/1024).toFixed(0)} MB of the bundle is the same runtime repeated. `+"Compiling one binary that dispatches on a subcommand \u2014 `MyApp agent`, `MyApp worker` \u2014 keeps the helpers as separate processes and pays for the runtime once."}var ke="app/Desktop/launcher.ts",fe,wt="---- Bun!",yt=8388608,W=41943040,kt;var ve=O(()=>{pe();me();fe=new Set(["CFBundleName","CFBundleDisplayName","CFBundleIdentifier","CFBundleVersion","CFBundleShortVersionString","CFBundleExecutable","CFBundlePackageType","CFBundleInfoDictionaryVersion","CFBundleIconFile"]);kt=new Set([4277009102,3472551422,4277009103,3489328638,3405691582,3199925962])});import{existsSync as Se,mkdirSync as Pt,writeFileSync as xe}from"fs";import Pe from"os";import{dirname as $t,join as L,relative as $e,resolve as Rt}from"path";import l from"process";import{fileURLToPath as St}from"url";function Me(e){return e.replaceAll("</script","<\\/script")}function G(e,t){return`<!doctype html>
|
|
11
11
|
<html lang="en">
|
|
12
12
|
<head>
|
|
13
13
|
<meta charset="utf-8">
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@stacksjs/desktop-build",
|
|
3
3
|
"type": "module",
|
|
4
4
|
"sideEffects": false,
|
|
5
|
-
"version": "0.75.
|
|
5
|
+
"version": "0.75.100",
|
|
6
6
|
"description": "Build and launch Craft desktop applications for Stacks",
|
|
7
7
|
"author": "Chris Breuer",
|
|
8
8
|
"contributors": [
|
|
@@ -70,8 +70,8 @@
|
|
|
70
70
|
"craft-native": ">=0.0.124"
|
|
71
71
|
},
|
|
72
72
|
"devDependencies": {
|
|
73
|
-
"@stacksjs/build": "0.75.
|
|
73
|
+
"@stacksjs/build": "0.75.100",
|
|
74
74
|
"better-dx": "^0.2.24",
|
|
75
|
-
"@stacksjs/server": "0.75.
|
|
75
|
+
"@stacksjs/server": "0.75.100"
|
|
76
76
|
}
|
|
77
77
|
}
|