@radhya/mach 2.6.10 → 2.6.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- import{h as p,j as O}from"../chunk-QFXPWC5D.js";import v from"fs";import x from"path";var D=n=>new Promise(e=>setTimeout(e,n));function M(n){let e=n?.response?.status,t=n?.code||"",d=n?.message||"";return!e||e===408||e===409||e===425||e===429||e>=500||/ECONNRESET|ETIMEDOUT|EAI_AGAIN|ENOTFOUND|ECONNABORTED|socket hang up|network|timeout/i.test(`${t} ${d}`)}async function f(n,e,t=5){let d;for(let i=1;i<=t;i++)try{return await e()}catch(r){if(d=r,!M(r)||i>=t)break;let s=Math.min(3e4,1500*Math.pow(2,i-1));console.warn(`[UPLOAD_RETRY] ${n} failed transiently. Retrying in ${Math.round(s/1e3)}s... (${i}/${t})`),await D(s)}throw d}async function U(){let[n,e,t,d,i,r,s,c,l,m,y,w,T,g,I,R,E,h,u]=process.argv.slice(2);try{let a=x.basename(e),b=v.readFileSync(e),N;if(u&&u!=="undefined")try{let o=JSON.parse(u);o&&typeof o=="object"&&!Array.isArray(o)&&(N=o)}catch{throw new Error("Invalid iOS signing metadata supplied for credential upload.")}let k=await f("create upload URL",()=>p.post("/credentials/upload-url",{projectId:n,fileName:a,fileType:"application/octet-stream",type:t,distributionType:i})),{uploadUrl:A,key:S,fileId:$}=k.data,P=(await import("axios")).default;await f("upload file to storage",()=>P.put(A,b,{headers:{"Content-Type":"application/octet-stream"},maxContentLength:1/0,maxBodyLength:1/0,timeout:18e4}));let C=await f("register credential",()=>p.post("/credentials",{projectId:n,id:$,name:`${t} - ${i}`,type:t,bundleId:d,distributionType:i,s3Key:S,alias:r==="undefined"?void 0:r,expiresAt:s==="undefined"?void 0:s,issuerId:c==="undefined"?void 0:c,keyId:l==="undefined"?void 0:l,password:m==="undefined"?void 0:m,keystorePassword:y==="undefined"?void 0:y,keyPassword:w==="undefined"?void 0:w,teamId:T==="undefined"?void 0:T,teamName:g==="undefined"?void 0:g,developerTeamId:I==="undefined"?void 0:I,appStoreConnectTeamId:R==="undefined"?void 0:R,providerId:E==="undefined"?void 0:E,providerName:h==="undefined"?void 0:h,signingMetadata:N}));O({credentialType:t,requestedDistributionType:i,storedDistributionType:C.data?.credential?.distributionType}),console.log("SUCCESS"),process.exit(0)}catch(a){a.response?console.error(`API_ERROR: ${a.response.status} - ${JSON.stringify(a.response.data)}`):console.error(`NETWORK_ERROR: ${a.message}`),process.exit(1)}}U();
1
+ import{h as p,j as A}from"../chunk-QFXPWC5D.js";import b from"fs";import D from"path";var M=n=>new Promise(e=>setTimeout(e,n));function _({type:n,bundleId:e,distributionType:t,teamId:r}){if(n!=="ios_cert"&&n!=="ios_profile")return`${n} - ${t}`;let i={development:"Development",adhoc:"Ad Hoc",enterprise:"Enterprise",store:"App Store"}[t]||t,d=n==="ios_cert"?"Certificate":"Provisioning Profile",o=e&&e!=="*"?e:void 0;return["MACH",`iOS ${i} ${d}`,o,r?`Team ${r}`:void 0].filter(a=>!!a).join(" \xB7 ")}function x(n){let e=n?.response?.status,t=n?.code||"",r=n?.message||"";return!e||e===408||e===409||e===425||e===429||e>=500||/ECONNRESET|ETIMEDOUT|EAI_AGAIN|ENOTFOUND|ECONNABORTED|socket hang up|network|timeout/i.test(`${t} ${r}`)}async function l(n,e,t=5){let r;for(let i=1;i<=t;i++)try{return await e()}catch(d){if(r=d,!x(d)||i>=t)break;let o=Math.min(3e4,1500*Math.pow(2,i-1));console.warn(`[UPLOAD_RETRY] ${n} failed transiently. Retrying in ${Math.round(o/1e3)}s... (${i}/${t})`),await M(o)}throw r}async function U(){let[n,e,t,r,i,d,o,a,m,y,g,w,u,T,I,R,h,E,f]=process.argv.slice(2);try{let s=D.basename(e),O=b.readFileSync(e),N;if(f&&f!=="undefined")try{let c=JSON.parse(f);c&&typeof c=="object"&&!Array.isArray(c)&&(N=c)}catch{throw new Error("Invalid iOS signing metadata supplied for credential upload.")}let $=await l("create upload URL",()=>p.post("/credentials/upload-url",{projectId:n,fileName:s,fileType:"application/octet-stream",type:t,distributionType:i})),{uploadUrl:S,key:k,fileId:v}=$.data,C=(await import("axios")).default;await l("upload file to storage",()=>C.put(S,O,{headers:{"Content-Type":"application/octet-stream"},maxContentLength:1/0,maxBodyLength:1/0,timeout:18e4}));let P=await l("register credential",()=>p.post("/credentials",{projectId:n,id:v,name:_({type:t,bundleId:r,distributionType:i,teamId:u==="undefined"?void 0:u}),type:t,bundleId:r,distributionType:i,s3Key:k,alias:d==="undefined"?void 0:d,expiresAt:o==="undefined"?void 0:o,issuerId:a==="undefined"?void 0:a,keyId:m==="undefined"?void 0:m,password:y==="undefined"?void 0:y,keystorePassword:g==="undefined"?void 0:g,keyPassword:w==="undefined"?void 0:w,teamId:u==="undefined"?void 0:u,teamName:T==="undefined"?void 0:T,developerTeamId:I==="undefined"?void 0:I,appStoreConnectTeamId:R==="undefined"?void 0:R,providerId:h==="undefined"?void 0:h,providerName:E==="undefined"?void 0:E,signingMetadata:N}));A({credentialType:t,requestedDistributionType:i,storedDistributionType:P.data?.credential?.distributionType}),console.log("SUCCESS"),process.exit(0)}catch(s){s.response?console.error(`API_ERROR: ${s.response.status} - ${JSON.stringify(s.response.data)}`):console.error(`NETWORK_ERROR: ${s.message}`),process.exit(1)}}U();
@@ -0,0 +1 @@
1
+ import{fa as a,ga as b,ha as c,ia as d,ja as e,ka as f,la as g,ma as h,na as i,oa as j}from"./chunk-QRW3A5OH.js";import"./chunk-QFXPWC5D.js";export{e as buildMatchCommand,h as credentialsMainCommand,i as credentialsSetupCommand,j as downloadCredentialsCommand,a as isApplePortalAuthenticationError,b as isApplePortalServiceKeyError,g as normalizeCredentialsPlatform,f as resolveAndroidCredentialDistributionType,d as retryApplePortalOperationAfterAuthentication,c as unavailableApplePortalCertificateIds};
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{$ as Ot,A as Os,B as wr,C as vr,D as Rr,E as Ds,F as Ci,G as Ti,H as $r,I as Or,J as Ps,K as Dr,L as Pr,M as ki,N as ve,O as Cs,P as Ts,Q as ks,R as kn,S as Nn,T as Ns,U as xs,V as Ls,W as Ms,X as Fs,Y as Ni,Z as $t,_ as Us,a as Tn,aa as js,b as ce,ba as Bs,c as sn,ca as xi,d as ft,da as Hs,e as K,ea as Gs,f as se,g as W,h as Er,i as Ir,j as an,k as Bt,ka as xn,l as Es,m as Is,n as Pi,o as _s,p as ws,q as _r,r as tt,s as vt,t as vs,u as ln,v as cn,w as dn,x as Rs,y as Rt,z as $s}from"./chunk-532EHM4E.js";import{a as m,b as As,c as we,d as Ss,e as ke,f as wt,g as at,h as I}from"./chunk-QFXPWC5D.js";import{Command as bb,Option as Qe}from"commander";import{configDotenv as Ab}from"dotenv";import{intro as re,outro as Au}from"@clack/prompts";import J from"chalk";import Eb from"path";var mt=class extends Error{constructor(t){super(t),this.name="ProjectAccessError"}};function Li(e){return typeof e!="string"?void 0:e.trim()||void 0}function Vs(e,t){return Li(e?.projectId)||Li(t?.projectId)}function vu(e,t){if(Array.isArray(e))return e.find(n=>Li(n?.projectId)===t)}function Ru(e,t){let n=vu(e,t);if(n)return n;throw new mt(`The current ${m.name} account does not have access to the linked project (${t}).
2
+ import{$ as Ot,A as Os,B as wr,C as vr,D as Rr,E as Ds,F as Ci,G as Ti,H as $r,I as Or,J as Ps,K as Dr,L as Pr,M as ki,N as ve,O as Cs,P as Ts,Q as ks,R as kn,S as Nn,T as Ns,U as xs,V as Ls,W as Ms,X as Fs,Y as Ni,Z as $t,_ as Us,a as Tn,aa as js,b as ce,ba as Bs,c as sn,ca as xi,d as ft,da as Hs,e as K,ea as Gs,f as se,g as W,h as Er,i as Ir,j as an,k as Bt,l as Es,m as Is,n as Pi,na as xn,o as _s,p as ws,q as _r,r as tt,s as vt,t as vs,u as ln,v as cn,w as dn,x as Rs,y as Rt,z as $s}from"./chunk-QRW3A5OH.js";import{a as m,b as As,c as we,d as Ss,e as ke,f as wt,g as at,h as I}from"./chunk-QFXPWC5D.js";import{Command as bb,Option as Qe}from"commander";import{configDotenv as Ab}from"dotenv";import{intro as re,outro as Au}from"@clack/prompts";import J from"chalk";import Eb from"path";var mt=class extends Error{constructor(t){super(t),this.name="ProjectAccessError"}};function Li(e){return typeof e!="string"?void 0:e.trim()||void 0}function Vs(e,t){return Li(e?.projectId)||Li(t?.projectId)}function vu(e,t){if(Array.isArray(e))return e.find(n=>Li(n?.projectId)===t)}function Ru(e,t){let n=vu(e,t);if(n)return n;throw new mt(`The current ${m.name} account does not have access to the linked project (${t}).
3
3
  Run \`${m.nameLower} logout\`, then \`${m.nameLower} login\` with a project member, or run \`${m.nameLower} link\` to select an accessible project.`)}async function zs(e){try{let n=(await I.get("/projects")).data;if(n?.status!=="success"||!Array.isArray(n.projects))throw new mt(`Could not verify access to the linked project before starting this command. Try \`${m.nameLower} login\` again.`);return Ru(n.projects,e)}catch(t){throw t instanceof mt?t:t?.response?.status===401?new mt(`Could not verify access to the linked project because this ${m.name} session is no longer valid. Run \`${m.nameLower} login\` and try again.`):new mt("Could not verify access to the linked project before starting this command. Check your connection and try again.")}}import{text as Ks,confirm as $u,spinner as Ou,isCancel as Mi,cancel as Ln,note as Du,outro as Pu}from"@clack/prompts";import Mn from"chalk";async function Ws(){try{let e=await Ks({message:"Enter Bucket Name:",placeholder:"e.g. my-app-dev",validate(i){if(i.length===0)return"Bucket name is required"}});Mi(e)&&(Ln("Operation cancelled."),process.exit(0));let t=await Ks({message:"Enter Region:",initialValue:"ap-south-1"});Mi(t)&&(Ln("Operation cancelled."),process.exit(0));let n=await $u({message:"Do you want to create a CloudFront Distribution for this bucket?",initialValue:!0});Mi(n)&&(Ln("Operation cancelled."),process.exit(0));let r=Ou();r.start("Setting up hosting infrastructure...");try{let i=await I.post("/hosting/setup",{bucketName:e,region:t,createCloudFront:n});if(i.data.status!=="success")throw new Error(i.data.message||"Hosting setup failed");r.stop("Hosting setup complete!");let o=i.data,s=`Bucket Name: ${Mn.cyan(o.bucketName)}
4
4
  `;s+=`Region: ${Mn.cyan(o.region)}
5
5
  `,s+=`S3 Website URL: ${Mn.blue(o.s3WebsiteUrl)}`,o.cloudFrontId&&(s+=`
@@ -2491,5 +2491,5 @@ ${v.stderr||""}`),severity:"medium",recommendation:"Run `flutter analyze`, fix t
2491
2491
  Running expo prebuild for deeper analysis...`));try{rb("npx expo prebuild --no-install",{cwd:s,stdio:"pipe"})}catch{return yr.warn(Ve.yellow("Prebuild failed \u2014 skipping manifest/plist checks.")),o}}else if(!c)return t.json||yr.info(Ve.dim(`
2492
2492
  Skipping manifest/plist checks \u2014 no android/ios dirs. Use --prebuild to generate them.`)),o;for(let u of i){let f=t.json?null:su();f?.start(Ve.dim(`Running ${u.label}...`));try{let p=Date.now(),h=await u.fn(s,t);h.durationMs=Date.now()-p,o.push(h);let g=h.findings.length;f?.stop(g>0?Ve.yellow(`${u.label} \u2014 ${g} finding(s)`):Ve.green(`${u.label} \u2014 clean`))}catch(p){f?.stop(Ve.red(`${u.label} \u2014 error`)),o.push({category:u.category,label:u.label,findings:[],durationMs:0,error:p.message})}}}return o}import _e from"chalk";import{log as be}from"@clack/prompts";var Dn={critical:_e.bgRed.white.bold,high:_e.red.bold,medium:_e.yellow.bold,low:_e.blue,info:_e.dim},Di={critical:0,high:1,medium:2,low:3,info:4};function ob(e,t){if(!t)return!0;let n=Di[t];return n===void 0?!0:Di[e]<=n}function du(e,t){let n=0,r={critical:0,high:0,medium:0,low:0,info:0};for(let s of e){let a=s.findings.filter(d=>ob(d.severity,t));if(a.length===0&&!s.error)continue;if(be.info(""),be.info(_e.bold(` ${s.label}`)+_e.dim(` ${a.length} finding(s)`)),be.info(_e.dim(" "+"\u2500".repeat(60))),s.error){be.error(_e.red(` Error: ${s.error}`));continue}let l=[...a].sort((d,c)=>Di[d.severity]-Di[c.severity]);for(let d of l){let c=Dn[d.severity](` ${d.severity.toUpperCase()} `);be.info(` ${c} ${_e.bold(d.id)} ${d.title}`),be.info(_e.dim(` ${d.description}`)),d.file&&be.info(_e.dim(` File: ${d.file}${d.line?`:${d.line}`:""}`)),be.info(_e.cyan(` Fix: ${d.recommendation}`)),be.info(""),r[d.severity]++,n++}}be.info(""),be.info(_e.bold(" Summary")),be.info(_e.dim(" "+"\u2500".repeat(60))),be.info(` Total: ${_e.bold(String(n))} finding(s)`),be.info(` ${Dn.critical(` ${r.critical} Critical `)} ${Dn.high(` ${r.high} High `)} ${Dn.medium(` ${r.medium} Medium `)} ${Dn.low(` ${r.low} Low `)} ${Dn.info(` ${r.info} Info `)}`);let i=r.critical>0,o=r.high>0;i||o?(be.info(""),be.error(_e.red.bold(` FAIL \u2014 ${r.critical} critical, ${r.high} high issue(s) found`))):n>0?(be.info(""),be.warn(_e.yellow(" PASS (with warnings) \u2014 no critical or high issues"))):(be.info(""),be.success(_e.green.bold(" PASS \u2014 no issues found")))}function uu(e,t){let n=e.flatMap(i=>i.findings),r={};for(let i of Object.values(xe))r[i]=n.filter(o=>o.severity===i).length;return{version:"1.0.0",timestamp:new Date().toISOString(),project:t.name||"unknown",projectVersion:t.version||"0.0.0",summary:{total:n.length,...r},passed:r.critical===0&&r.high===0,checks:e.map(i=>({category:i.category,label:i.label,findingCount:i.findings.length,durationMs:i.durationMs,error:i.error||null})),findings:n}}import{log as Ae,spinner as sb}from"@clack/prompts";import ue from"chalk";import It from"fs";import ab from"os";import Pn from"path";import{execSync as lb}from"child_process";var pu=16384,cb=1,db=Buffer.from([127,69,76,70]);async function fu(e){Ae.info(ue.bold.underline("16KB Page Alignment Check")),console.log("");let t=Pn.resolve(e);if(!It.existsSync(t))return Ae.error(ue.red(`APK file not found: ${t}`)),!1;if(!t.endsWith(".apk"))return Ae.error(ue.red("The provided file is not an APK file.")),!1;let n=sb();n.start("Extracting and analyzing native libraries...");let r=It.mkdtempSync(Pn.join(ab.tmpdir(),"mach-16kb-"));try{try{lb(`unzip -o -q "${t}" "lib/arm64-v8a/*.so" "lib/x86_64/*.so" -d "${r}" 2>/dev/null`,{encoding:"utf-8",maxBuffer:50*1024*1024})}catch{}let i=mu(Pn.join(r,"lib"));if(i.length===0)return n.stop("Analysis complete."),Ae.info(ue.yellow("No arm64-v8a or x86_64 native libraries found in the APK.")),Ae.info(ue.dim("16KB alignment check only applies to arm64-v8a and x86_64 architectures.")),!0;let o=[];for(let l of i){let d=Pn.relative(r,l),c=pb(d),u=Pn.basename(l),f=ub(l);f!==null&&o.push({name:u,filePath:d,arch:c,align:f,compatible:f>=pu})}if(n.stop("Analysis complete."),o.length===0)return Ae.info(ue.yellow("No valid ELF shared libraries found.")),!0;let s=o.filter(l=>!l.compatible),a=o.filter(l=>l.compatible);if(Ae.info(ue.dim(`Checked ${o.length} native librar${o.length===1?"y":"ies"}
2493
2493
  `)),s.length>0){Ae.info(ue.red.bold(`Incompatible libraries:
2494
- `));for(let l of s)Ae.error(ue.red(`${ue.bold(l.name)} ${ue.dim(`(${l.arch})`)}`)),Ae.info(ue.dim(` PT_LOAD alignment: 2**${Math.log2(l.align)} (${l.align} bytes, needs 2**14 = ${pu})`))}return a.length>0&&(console.log(""),Ae.success(ue.green(`${a.length} librar${a.length===1?"y":"ies"} correctly aligned (2**14 or higher).`))),console.log(""),s.length===0?(Ae.success(ue.green.bold("ELF Verification Successful. APK is 16KB compatible.")),!0):(Ae.error(ue.red.bold(`Found ${s.length} unaligned lib${s.length===1?"":"s"} (arm64-v8a/x86_64 libs need to be aligned).`)),console.log(""),Ae.info(ue.yellow("To fix this:")),Ae.info(ue.dim(" 1. Rebuild with NDK r28+ which defaults to 16KB page alignment")),Ae.info(ue.dim(" 2. Or set -DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON in CMake")),Ae.info(ue.dim(" 3. Update third-party libraries that ship prebuilt .so files")),Ae.info(ue.dim(" 4. After rebuilding: zipalign -p -f -v 16 input.apk output.apk")),console.log(""),Ae.info(ue.dim("Reference: https://developer.android.com/guide/practices/page-sizes")),!1)}catch(i){return n.stop("Analysis failed."),Ae.error(ue.red(`Failed to analyze APK: ${i.message}`)),!1}finally{try{It.rmSync(r,{recursive:!0,force:!0})}catch{}}}function ub(e){let t=It.openSync(e,"r");try{let n=Buffer.alloc(64);if(It.readSync(t,n,0,64,0),!n.subarray(0,4).equals(db))return null;let r=n[4]===2,i=n[5]===1,o=(f,p)=>i?f.readUInt16LE(p):f.readUInt16BE(p),s=(f,p)=>i?f.readUInt32LE(p):f.readUInt32BE(p),a=(f,p)=>Number(i?f.readBigUInt64LE(p):f.readBigUInt64BE(p)),l,d,c;r?(l=a(n,32),d=o(n,54),c=o(n,56)):(l=s(n,28),d=o(n,42),c=o(n,44));let u=null;for(let f=0;f<c;f++){let p=Buffer.alloc(d);if(It.readSync(t,p,0,d,l+f*d),s(p,0)!==cb)continue;let g;r?g=a(p,48):g=s(p,28),g>0&&(u===null||g<u)&&(u=g)}return u??0}catch{return null}finally{It.closeSync(t)}}function mu(e){let t=[];if(!It.existsSync(e))return t;let n=It.readdirSync(e,{withFileTypes:!0});for(let r of n){let i=Pn.join(e,r.name);r.isDirectory()?t.push(...mu(i)):r.name.endsWith(".so")&&t.push(i)}return t}function pb(e){return e.includes("arm64-v8a")?"arm64-v8a":e.includes("x86_64")?"x86_64":"unknown"}var yu=async e=>{if(e.apk){await gb(e);return}let t=process.cwd(),n=pt(t).appRoot,r=br.join(n,"package.json"),i=br.join(n,"pubspec.yaml");!nn.existsSync(r)&&!nn.existsSync(i)&&(Ze.error(st.red("No package.json or Flutter pubspec.yaml found. Run this command from a project root.")),process.exit(1));let o=nn.existsSync(r)?JSON.parse(nn.readFileSync(r,"utf-8")):tt(n),s=_r(n),a=!s&&!!(o.dependencies?.expo||o.devDependencies?.expo);e.json||(Ze.info(st.dim(`Project: ${o.name||"unknown"} v${o.version||"0.0.0"}`)),Ze.info(st.dim(`Type: ${s?"Flutter":a?"Expo":"Bare React Native"}`)),Ze.info(""));let l={json:e.json,fix:e.fix,category:e.category,severity:e.severity,prebuild:e.prebuild,since:e.since},d=await cu(t,l);e.json?console.log(JSON.stringify(uu(d,o),null,2)):du(d,e.severity);let c=d.some(f=>f.findings.some(p=>p.severity==="critical")),u=d.some(f=>f.findings.some(p=>p.severity==="high"));(c||u)&&process.exit(1)},gu=["16kb"];async function gb(e){let t=e.category?.toLowerCase();t&&!gu.includes(t)&&(Ze.error(st.red(`Unknown APK check category: "${t}"`)),Ze.info(st.dim(`Available APK checks: ${gu.join(", ")}`)),process.exit(1));let n=await hb(e.apk);n||process.exit(1);let r=!t,i=!1;(r||t==="16kb")&&(await fu(n)||(i=!0)),i&&process.exit(1)}async function hb(e){if(e.startsWith("build:")){let n=e.slice(6);return await yb(n)}if(e.startsWith("http://")||e.startsWith("https://"))return await bu(e);let t=br.resolve(e);return nn.existsSync(t)?t:(Ze.error(st.red(`APK file not found: ${t}`)),null)}async function yb(e){if(!we())return Ze.error(st.red(`A Mach build ID requires authentication. Run \`${m.nameLower} login\` first, or pass a local APK path.`)),null;let n=hu();n.start(`Fetching APK from build ${e}...`);try{let r=await I.get(`/build/${e}`);if(r.data.status!=="success")throw new Error(r.data.message);let i=r.data.build;if(!i)throw new Error("Build not found");let o=i.artifacts?.find(s=>s.type?s.type==="apk":s.name?.endsWith(".apk")||s.url?.includes(".apk"));return!o||!o.url?(n.stop("No APK artifact found"),Ze.error(st.red("This build does not have an APK artifact.")),Ze.info(st.dim("Make sure the build produced an APK (not just an AAB).")),null):(n.stop(`Found build: ${i.buildId||e}`),await bu(o.url))}catch(r){return n.stop("Failed to fetch build"),Ze.error(st.red(r.message)),null}}async function bu(e){let t=hu();t.start("Downloading APK...");try{let n=nn.mkdtempSync(br.join(fb.tmpdir(),`${m.nameLower}-audit-`)),r=br.join(n,"app.apk"),i=await mb.get(e,{responseType:"arraybuffer"});nn.writeFileSync(r,i.data);let o=(i.data.length/(1024*1024)).toFixed(1);return t.stop(`Downloaded APK (${o} MB)`),r}catch(n){return t.stop("Download failed"),Ze.error(st.red(`Failed to download APK: ${n.message}`)),null}}var Sb=console.log;console.log=()=>{};Ab({quiet:!0});console.log=Sb;var Ib=process.argv.includes("--json");Ib||re(J.bgCyan.black(m.cliTag("Production Build Orchestrator")));var Ar=(e,t=[])=>t.concat(e),x=new bb;x.name(m.nameLower).description(`${m.name} CLI: Powerful Cloud Infrastructure Tools`).version(Ot).option("-y, --yes","Automatically answer yes to all prompts",!1).option("--config <path>",`Use a specific ${m.configFileName}; app paths still resolve from the current directory`).option("--quiet","Suppress non-essential output",!1);x.command("agent").description("Manage local device discovery agent for the Install Hub (port 7070)").argument("[action]","start, run, install, status, restart, stop, or uninstall","start").action(async e=>{await oc(e)});x.command("host").description("Setup AWS S3 static hosting and CloudFront").action(async()=>{re(J.bgCyan.black(m.cliTag("Hosting"))),await Ws()});var Cn=x.command("web").description("Deploy static Expo, React Native Web, and Flutter web apps through Mach");Cn.command("deploy").description("Upload a finished static web build and promote it by default").option("-o, --output <directory>","Finished static output directory (for example dist or build/web)").option("--build","Build Expo or Flutter web locally before deploying").option("-p, --profile <name>","Existing Mach build profile; its web.alias selects the release address").option("-a, --alias <alias>","Override the profile alias: production or staging").option("--no-promote","Keep the deployment as an immutable preview only").option("-m, --message <message>","Deployment message").option("--project-id <id>","Mach project ID").action(async e=>{await aa(e)});Cn.command("status").description("Show production, staging, and custom-domain status").option("--project-id <id>","Mach project ID").action(async e=>{await la(e)});Cn.command("list").description("List recent web deployments").option("--project-id <id>","Mach project ID").action(async e=>{await ca(e)});Cn.command("promote <deployment-id>").description("Point a release alias at an existing ready deployment").option("-a, --alias <alias>","production or staging","production").option("--project-id <id>","Mach project ID").action(async(e,t)=>{await da(e,t)});Cn.command("rollback").description("Restore the previous ready deployment for an alias").option("-a, --alias <alias>","production or staging","production").option("--deployment <id>","Specific deployment to restore").option("--project-id <id>","Mach project ID").action(async e=>{await ua(e)});var Su=Cn.command("domain").description("Attach and manage customer-owned domains");Su.command("add").description("Add a Cloudflare for SaaS custom hostname to production").requiredOption("--domain <hostname>","Hostname such as www.example.com").option("--project-id <id>","Mach project ID").action(async e=>{await pa(e)});Su.command("remove <hostname>").description("Remove a custom hostname").option("--project-id <id>","Mach project ID").action(async(e,t)=>{await fa(e,t)});x.command("sitemap").description("Generate sitemap.xml from Expo Router app structure").option("-o, --output <path>","Output path for sitemap.xml","./public/sitemap.xml").action(async e=>{re(J.bgCyan.black(m.cliTag("Sitemap Generator"))),await ya(e)});x.command("build").description("Run a build on a cloud provider (AWS Spot Instances)").argument("[platform]","Target platform (android, ios, or Flutter web)").option("--platform <os>","Target platform alias (android, ios, web) [Optional]").option("--repo <url>","Git Repository URL").option("--branch <name>","Git Branch").option("--ami <id>","AMI ID").option("--bucket <name>","S3 Bucket for artifacts").option("--region <region>","AWS Region").option("--aws-profile <name>","AWS Credentials Profile").option("-p, --build-profile <name>","Any configured build profile name").option("--profile <name>","Build Profile (alias for --build-profile)").option("--dry-run","Generate User Data script without launching").option("--keep-instance","Do not terminate the instance after build").option("--subnet <id>","VPC Subnet ID to launch the instance in").option("--security-group <id>","VPC Security Group ID to use").option("--ssh-host <host>","Remote host for iOS build (SSH)").option("--ssh-user <user>","SSH username for remote host").option("--ssh-key <path>","Path to private SSH key for remote host").option("--ios-scheme <scheme>","iOS Scheme to build").option("--ios-team-id <id>","Apple Development Team ID").option("--ios-configuration <config>","Xcode configuration (Release/Debug)").option("--ios-export-method <method>","Export method (ad-hoc, app-store, development, enterprise)").option("--ios-api-key-id <id>","App Store Connect API Key ID").option("--ios-api-key-issuer <id>","App Store Connect API Key Issuer ID").option("--ios-api-key-path <path>","Path to App Store Connect API Key (.p8) file").option("--simulator","Build for iOS Simulator (no signing required)").addOption(new Qe("--build-id <id>","Internal build ID").hideHelp()).addOption(new Qe("--project-id <id>","Internal project ID").hideHelp()).addOption(new Qe("--fail-only","Internal: mark an existing build failed").hideHelp()).addOption(new Qe("--error <message>","Internal failure message").hideHelp()).option("--local","Run build on local machine").option("--auto-version","Assign the next Android versionCode or iOS buildNumber from Mach").option("--auto-submit","Submit this build after it completes successfully").option("--submit-track <track>","Google Play track to use with --auto-submit").option("--submit-release-status <status>","Google Play release status to use with --auto-submit").option("--submit-rollout <fraction>","Google Play staged rollout fraction to use with --auto-submit").option("--submit-changes-not-sent-for-review","Commit Google Play changes without automatically sending them for review when using --auto-submit").option("--submit-credential-id <id>","Service credential ID to use with --auto-submit").option("--submit-json-output <path>","Write auto-submit metadata JSON to a file for CI/CD").option("--verbose","Enable verbose logging").option("--json-output <path>","Write build metadata JSON to a file for CI/CD").option("--flutter-obfuscate","Obfuscate Flutter release Dart code and preserve split debug symbols").option("--flutter-split-debug-info","Preserve Flutter release split debug symbols without enabling obfuscation").option("--maestro","Queue a managed Maestro test run after a successful build").option("--maestro-flows <path>","Maestro flow file or directory (default: .maestro)").option("--maestro-device <device>","Managed device profile id (run `mach maestro devices` to list)").option("--maestro-retries <n>","Retries for the Maestro run","1").option("--maestro-record","Enable screen recording where supported").option("--maestro-use-build-source","Use Maestro flows from the build source snapshot instead of uploading local flows").option("--maestro-env <name>","Forward an environment variable to the managed Maestro runner; repeat or comma-separate names",Ar,[]).option("-y, --yes","Automatically answer yes to all prompts",!1).option("--quiet","Suppress non-essential output",!1).action(async(e,t)=>{let n=x.opts();t.yes=t.yes||n.yes,t.quiet=t.quiet||n.quiet,t.platform=e||t.platform,t.buildProfile=t.profile||t.buildProfile,t.quiet||re(J.bgCyan.black(m.cliTag("Cloud Build"))),await Wr(t)});var _b=x.command("maestro").description("Run Maestro tests locally or with the managed Mach runner").option("--platform <os>","Target platform (android/ios)").option("-p, --profile <name>","Build profile to resolve when using --latest").option("--latest","Use the latest successful build for the platform/profile").option("--build-id <id>","Use a specific Mach build ID").option("--build-url <url>","Use a Mach build URL").option("--artifact-url <url>","Use a direct APK or iOS simulator app artifact URL").option("--local","Run Maestro on a connected local emulator/device instead of the managed runner").option("--maestro-flows <path>","Maestro flow file or directory (default: .maestro)").option("--maestro-device <device>","Managed device profile id (run `mach maestro devices` to list); local runs accept a device identifier").option("--maestro-retries <n>","Retries for the Maestro run","1").option("--maestro-record","Enable screen recording where supported").option("--maestro-use-build-source","Use Maestro flows from the build source snapshot instead of uploading local flows").option("--maestro-env <name>","Forward an environment variable to the managed Maestro runner; repeat or comma-separate names",Ar,[]).option("--wait","Wait for managed Maestro completion and exit non-zero on failure").option("--wait-timeout <minutes>","Maximum minutes to wait for managed Maestro completion","60").option("--wait-interval <seconds>","Polling interval while waiting for managed Maestro completion","15").option("--json-output <path>","Write test run metadata JSON to a file for CI/CD").addOption(new Qe("--local-runner","Internal: execute a managed Maestro run on this machine").hideHelp()).addOption(new Qe("--test-run-id <id>","Internal test run ID").hideHelp()).addOption(new Qe("--project-id <id>","Internal project ID").hideHelp()).addOption(new Qe("--runner-token <token>","Internal runner token").hideHelp()).action(async e=>{re(J.bgCyan.black(m.cliTag("Maestro Testing"))),await La(e)});_b.command("devices").description("List device profiles available on the managed Maestro runner fleet").option("--platform <os>","Filter to android or ios").option("--json","Print machine-readable JSON").action(async e=>{await Ma(e)});var rn=e=>e.option("--platform <os>","Target platform: ios, android, or all","all").option("-p, --profile <name>","Flutter build profile used to resolve flavor, target, and Dart defines").option("--channel <name>","OTA channel (for example: production, staging)").option("--branch <name>","Alias for --channel").option("--runtime-version <version>","Runtime version override").option("--message <text>","Release note/message for this OTA update").option("--framework <name>","Framework override: expo, react-native, or flutter").option("--engine <name>","OTA engine override: expo-updates or shorebird").option("--url <url>","Mach OTA update URL override").option("--install-plugin","Install @radhya/mach locally for the Expo config plugin").option("--skip-install","Do not install local Expo plugin dependency").option("--update-id <id>","OTA update id for rollback/promote").option("--release-version <version>","Shorebird release version (defaults to latest for publish)").option("--patch-number <number>","Shorebird patch number for promote/rollback").option("--track <name>","Shorebird track: stable or staging").option("--json","Print JSON output"),on=x.command("ota").description("Setup, publish, verify, and manage Mach OTA updates");rn(on.command("setup").description("Configure OTA for this project")).action(async e=>{let t=x.opts();re(J.bgCyan.black(m.cliTag("OTA Setup"))),await At("setup",{...e,yes:e.yes||t.yes})});rn(on.command("publish").description("Publish an OTA update")).action(async e=>{let t=x.opts();re(J.bgCyan.black(m.cliTag("OTA Publish"))),await At("publish",{...e,yes:e.yes||t.yes})});rn(on.command("release").description("Create a Flutter Shorebird base release")).action(async e=>{let t=x.opts();re(J.bgCyan.black(m.cliTag("OTA Release"))),await At("release",{...e,yes:e.yes||t.yes})});rn(on.command("verify").description("Verify OTA configuration")).action(async e=>{let t=x.opts();re(J.bgCyan.black(m.cliTag("OTA Verify"))),await At("verify",{...e,yes:e.yes||t.yes})});rn(on.command("list").description("List OTA updates for the linked project")).action(async e=>{let t=x.opts();re(J.bgCyan.black(m.cliTag("OTA Updates"))),await At("list",{...e,yes:e.yes||t.yes})});rn(on.command("rollback").description("Roll back an OTA update")).action(async e=>{let t=x.opts();re(J.bgCyan.black(m.cliTag("OTA Rollback"))),await At("rollback",{...e,yes:e.yes||t.yes})});rn(on.command("promote").description("Promote an OTA update")).action(async e=>{let t=x.opts();re(J.bgCyan.black(m.cliTag("OTA Promote"))),await At("promote",{...e,yes:e.yes||t.yes})});x.command("submit").description("Automated Store Submission (App Store / Google Play)").option("--platform <os>","Target platform (ios/android)").option("-p, --profile <name>","Build/submission profile to submit from (e.g. production, preprod)").option("--track <track>","Google Play Track (internal, alpha, beta, production)").option("--release-status <status>","Google Play release status (completed, draft, halted, inProgress)").option("--rollout <fraction>","Google Play staged rollout fraction for inProgress releases (example: 0.1)").option("--changes-not-sent-for-review","Commit Google Play changes without automatically sending them for review").option("--ssh-host <host>","Remote macOS host for iOS submission").option("--ssh-user <user>","SSH username for remote iOS submission").option("--ssh-key <path>","Path to private SSH key for remote iOS submission").option("--credential-id <id>","Service credential ID to use when multiple submission credentials exist").option("--local","Run submission on this machine (internal runner mode for iOS)").addOption(new Qe("--submit-id <id>","Internal submission ID").hideHelp()).addOption(new Qe("--project-id <id>","Internal project ID").hideHelp()).addOption(new Qe("--package-name <name>","Internal Android package name").hideHelp()).addOption(new Qe("--bundle-id <id>","Internal iOS bundle identifier").hideHelp()).option("--json-output <path>","Write submission metadata JSON to a file for CI/CD").option("--latest","Use the latest successful build for submission").option("--build-id <id>","Use a specific build ID for submission").action(async e=>{let t=x.opts();e.quiet=e.quiet||t.quiet,e.yes=e.yes||t.yes,re(J.bgCyan.black(m.cliTag("Store Submission"))),await jr(e)});x.command("login").description(`Login to ${m.name} Dashboard`).action(async()=>{re(J.bgCyan.black(m.cliTag("Login"))),await cc()});x.command("logout").description(`Logout from ${m.name} on this machine`).action(async()=>{re(J.bgCyan.black(m.cliTag("Logout"))),await dc()});x.command("link").description(`Link local directory to a ${m.name} Project`).action(async()=>{re(J.bgCyan.black(m.cliTag("Link Project"))),await pc()});x.command("me").description("Display currently logged in user details").action(async()=>{await Kc()});x.command("init").description(`Create a new ${m.name} Project`).action(async()=>{re(J.bgCyan.black(m.cliTag("Init Project"))),await fc()});x.command("env").description("Manage Environment Variables").argument("<action>","Action to perform: set, list, pull, download, or export").argument("[args...]","Key=Value pairs for set action").option("-e, --environment <name>","Environment to pull/download","development").option("-o, --out <file>","Output file for pull/download",".env.local").option("--overwrite","Overwrite output file if it already exists").action(async(e,t,n)=>{re(J.bgCyan.black(m.cliTag("Env Manager"))),await gc(e,t,n)});x.command("start").description("Start the app with its configured Flutter or JavaScript toolchain").option("-p, --build-profile <name>","Any configured build profile name").option("--tunnel","Use ngrok tunnel").option("--lan","Use LAN IP").option("--localhost","Use localhost").option("-c, --clear","Clear Metro cache").option("--port <number>","Port to listen on").option("--ios","Start on iOS").option("--android","Start on Android").option("--web","Start on Web").action(async e=>{re(J.bgCyan.black(m.cliTag("Dev Server"))),await Jc(e)});var Sr=x.command("push").description("Configure and send provider-direct APNs/FCM notifications");Sr.command("setup").description("Install and wire a working default push experience").option("-p, --profile <name>","Build profile used to resolve app identity and Flutter entrypoint").option("--name <name>","Push app display name").option("--ios-bundle <id>","iOS bundle identifier").option("--android-package <name>","Android package name").option("-e, --environment <name>","development, preview, or production").option("--google-services-file <path>","Android google-services.json path").option("--skip-install","Generate setup without installing SDK dependencies").action(Bs);Sr.command("init").description("Create only the server-side push app (advanced)").option("-p, --profile <name>","Build profile used to resolve app identity").option("--name <name>","Push app display name").option("--ios-bundle <id>","iOS bundle identifier").option("--android-package <name>","Android package name").option("-e, --environment <name>","development, preview, or production","production").option("--google-services-file <path>","Expo Android google-services.json path").action(js);var Eu=Sr.command("credentials").description("Configure provider credentials");Eu.command("apns").description("Configure an Apple APNs .p8 authentication key").requiredOption("--file <path>","APNs .p8 file").requiredOption("--team-id <id>","Apple Developer team ID").requiredOption("--key-id <id>","APNs key ID").option("--bundle-id <id>","iOS bundle identifier").option("--app <id>","MACH Push app ID").option("-e, --environment <name>","development, preview, or production").action(e=>xi("apns",e));Eu.command("fcm").description("Configure a Firebase service-account JSON file").requiredOption("--file <path>","Firebase service-account JSON").option("--app <id>","MACH Push app ID").option("-e, --environment <name>","Deprecated; accepted for compatibility because FCM credentials are package-wide").action(e=>xi("fcm",e));Sr.command("send").description("Queue one transient push notification").requiredOption("--title <text>","Notification title").requiredOption("--body <text>","Notification body").option("--app <id>","MACH Push app ID").option("-e, --environment <name>","development, preview, or production").option("--token <token>","MACH push token; repeatable",Ar,[]).option("--user <id>","Application user ID; repeatable",Ar,[]).option("--all","Send to all active devices").option("--platform <platform>","Limit --all to ios or android").option("--data <json>","String-to-string custom data JSON").option("--sound <name>","Provider sound name").option("--badge <number>","iOS badge count").option("--ttl <seconds>","Provider time-to-live").option("--collapse-key <key>","Provider collapse key").option("--android-channel-id <id>","Android notification channel").action(Hs);Sr.command("status").description("Show aggregate push delivery counters").option("--days <number>","Statistics range, 1-90","30").action(Gs);x.command("config").description("Show resolved configuration for a profile").option("-p, --profile <name>","Build profile to resolve").option("--json","Output as JSON").action(async e=>{await Xc(e)});var Iu=x.command("version").description("Show or seed DB-owned native version counters"),_u=e=>e.requiredOption("--platform <os>","Target platform: ios or android").option("-p, --profile <name>","Build profile used to resolve package/bundle scope").option("--scope <value>","Counter scope override, usually package name or bundle identifier").option("--package <name>","Android package override").option("--bundle-id <id>","iOS bundle identifier override").option("--json","Print JSON output");_u(Iu.command("show").description("Show the current native version counter")).action(async e=>{re(J.bgCyan.black(m.cliTag("Version Counter"))),await cs("show",e)});_u(Iu.command("seed").description("Seed the native version counter for an existing app").argument("[value]","Latest already-used value; the next build uses value + 1").option("--value <number>","Latest already-used value; the next build uses value + 1").option("--force","Allow lowering an existing counter")).action(async(e,t)=>{re(J.bgCyan.black(m.cliTag("Version Counter"))),await cs("seed",{...t,value:t.value??e})});var wu=x.command("deeplink").description("Configure and verify app links, universal links, and URI schemes");wu.command("setup").description("Generate deep link config, hosted association files, and Expo plugin support").option("--domain <domain>","Associated domain, e.g. app.example.com").option("--base-url <url>","Base URL, e.g. https://app.example.com").option("-p, --profile <name>","Profile used for build/submit overrides").option("--platform <platform>","ios, android, or all").option("--framework <framework>","expo, react-native, or flutter").option("--scheme <scheme>","URI scheme, e.g. myapp").option("--ios-bundle-id <id>","iOS bundle identifier").option("--android-package <name>","Android package name").option("--apple-team-id <id>","Apple Developer Team ID").option("--app-store-id <id>","App Store app ID for Smart App Banner").option("--android-fingerprint <sha256>","Android SHA256 signing certificate fingerprint; repeatable",Ar,[]).option("--output <dir>","Directory for hosted files, e.g. public or deep-links").option("--install-plugin","Install @radhya/mach locally so Expo can use the packaged config plugin").option("--no-install-plugin","Do not install @radhya/mach for Expo projects; use the local plugin fallback if the package is missing").option("-y, --yes","Automatically answer yes to prompts",!1).action(async e=>{let t=x.opts();e.yes=e.yes||t.yes,re(J.bgCyan.black(m.cliTag("Deep Links"))),await $d(e)});wu.command("verify").description("Verify local and optionally live deep link configuration").option("-p, --profile <name>","Profile used for build/submit overrides").option("--live","Check hosted files over HTTPS").option("--android-device","Print Android device verification commands").action(async e=>{re(J.bgCyan.black(m.cliTag("Deep Link Verify"))),await Od(e)});x.command("credentials").description("Unified, interactive credential management (iOS/Android)").option("--platform <os>","Platform to manage: ios or android").option("-p, --profile <name>","Any configured build profile name").option("--credential-type <type>","iOS signing type override: development, adhoc, or store").option("--force","Force recreate certificates (nuke existing on Apple Portal)",!1).action(async e=>{let{credentialsMainCommand:t}=await import("./credentials-YIUZ3DLH.js");await t(e)});x.command("credentials:setup").description("Automated credential provisioning (iOS/Android) [Legacy]").requiredOption("--platform <os>","Platform: ios or android").option("--profile <name>","Any configured build profile name").option("--credential-type <type>","iOS signing type override: development, adhoc, or store").option("--bundle-id <id>","Bundle ID / Package Name (optional, auto-detected)").option("--team-id <id>","Apple Team ID (iOS only)").option("--key-alias <alias>","Android keystore alias (optional, auto-generated)").option("--aws-profile <name>","AWS Credentials Profile (for S3 storage)").option("--force","Force recreate certificates (nuke existing on Apple Portal)",!1).action(async e=>{re(J.bgCyan.black(m.cliTag("Credentials Setup"))),await xn(e),Au(J.green("Done!"))});x.command("credentials:service").description("Upload Service Credentials (ASC API Key / Google Service JSON) [Legacy]").requiredOption("--platform <os>","Platform: ios or android").option("--file <path>","Path to credential file (.p8 or .json)").option("--issuer-id <id>","ASC API Key Issuer ID (iOS only)").option("--key-id <id>","ASC API Key ID (iOS only)").option("--bundle-id <id>","Bundle identifier / Android package name to attach this service credential to").option("--package-name <name>","Android package name to attach this service credential to").option("-p, --profile <name>","Build profile to resolve package/bundle identifier from config").action(async e=>{re(J.bgCyan.black(m.cliTag("Service Credentials"))),await Us(e),Au(J.green("Done!"))});var ys=x.command("device").description("Manage registered iOS test devices");ys.command("register").description("Register a connected iOS device or enter UDID manually").option("--udid <udid>","Device UDID (skip auto-detection)").option("--name <name>","Device name").option("--team-id <id>","Apple Developer Team ID for this device").action(async e=>{await yi("register",e)});ys.command("list").description("List all registered devices").option("--team-id <id>","Filter by Apple Developer Team ID").action(async e=>{await yi("list",e)});ys.command("remove").description("Remove a registered device").option("--udid <udid>","Device UDID to remove").option("--team-id <id>","Apple Developer Team ID for this device").action(async e=>{await yi("remove",e)});x.command("audit").description("Run project health, delivery impact, and security checks").option("--apk <path>","Path to APK file (runs APK diagnostics like 16KB alignment)").option("--json","Output results as JSON (for CI/CD)").option("--fix","Auto-apply fixes where possible").option("--category <name>","Run one category (e.g. project, impact, permissions, secrets)").option("--severity <level>","Minimum severity to display (critical, high, medium, low, info)").option("--prebuild","Run expo prebuild for deeper manifest/plist analysis").option("--since <git-ref>","Assess delivery impact from a branch, tag, or commit").action(async e=>{e.json||re(J.bgCyan.black(m.cliTag(e.apk?"APK Audit":"Project Audit"))),await yu(e)});var wb=new Set(["login","logout","agent"]),vb=new Set(["build","credentials","credentials:service","credentials:setup","env","push","submit","version"]),Rb=new Set(["publish","list","rollback","promote"]);function $b(e){let t=[],n=e;for(;n&&n!==x;)t.unshift(n.name()),n=n.parent;return t}function Ob(e,t){let[n,r]=$b(e);return vb.has(n)?!0:n==="ota"?Rb.has(r):n==="maestro"?r!=="devices"&&!t.local&&!t.localRunner:!1}x.hook("preAction",async(e,t)=>{let n=String(x.opts().config||"").trim();n&&(process.env.MACH_CONFIG_PATH=Eb.resolve(n));let r=t.name(),i=t.opts?.()||{};if(r==="maestro"&&(i.local||i.localRunner)||t.parent?.name()==="deeplink"||wb.has(r)||(ke(),!Ob(t,i)))return;let o=Vs(i,K());if(!o)throw new mt(`No linked ${m.name} project was found. Run \`${m.nameLower} link\` before using this command.`);await zs(o)});x.on("command:*",()=>{console.error(`Invalid command: %s
2494
+ `));for(let l of s)Ae.error(ue.red(`${ue.bold(l.name)} ${ue.dim(`(${l.arch})`)}`)),Ae.info(ue.dim(` PT_LOAD alignment: 2**${Math.log2(l.align)} (${l.align} bytes, needs 2**14 = ${pu})`))}return a.length>0&&(console.log(""),Ae.success(ue.green(`${a.length} librar${a.length===1?"y":"ies"} correctly aligned (2**14 or higher).`))),console.log(""),s.length===0?(Ae.success(ue.green.bold("ELF Verification Successful. APK is 16KB compatible.")),!0):(Ae.error(ue.red.bold(`Found ${s.length} unaligned lib${s.length===1?"":"s"} (arm64-v8a/x86_64 libs need to be aligned).`)),console.log(""),Ae.info(ue.yellow("To fix this:")),Ae.info(ue.dim(" 1. Rebuild with NDK r28+ which defaults to 16KB page alignment")),Ae.info(ue.dim(" 2. Or set -DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON in CMake")),Ae.info(ue.dim(" 3. Update third-party libraries that ship prebuilt .so files")),Ae.info(ue.dim(" 4. After rebuilding: zipalign -p -f -v 16 input.apk output.apk")),console.log(""),Ae.info(ue.dim("Reference: https://developer.android.com/guide/practices/page-sizes")),!1)}catch(i){return n.stop("Analysis failed."),Ae.error(ue.red(`Failed to analyze APK: ${i.message}`)),!1}finally{try{It.rmSync(r,{recursive:!0,force:!0})}catch{}}}function ub(e){let t=It.openSync(e,"r");try{let n=Buffer.alloc(64);if(It.readSync(t,n,0,64,0),!n.subarray(0,4).equals(db))return null;let r=n[4]===2,i=n[5]===1,o=(f,p)=>i?f.readUInt16LE(p):f.readUInt16BE(p),s=(f,p)=>i?f.readUInt32LE(p):f.readUInt32BE(p),a=(f,p)=>Number(i?f.readBigUInt64LE(p):f.readBigUInt64BE(p)),l,d,c;r?(l=a(n,32),d=o(n,54),c=o(n,56)):(l=s(n,28),d=o(n,42),c=o(n,44));let u=null;for(let f=0;f<c;f++){let p=Buffer.alloc(d);if(It.readSync(t,p,0,d,l+f*d),s(p,0)!==cb)continue;let g;r?g=a(p,48):g=s(p,28),g>0&&(u===null||g<u)&&(u=g)}return u??0}catch{return null}finally{It.closeSync(t)}}function mu(e){let t=[];if(!It.existsSync(e))return t;let n=It.readdirSync(e,{withFileTypes:!0});for(let r of n){let i=Pn.join(e,r.name);r.isDirectory()?t.push(...mu(i)):r.name.endsWith(".so")&&t.push(i)}return t}function pb(e){return e.includes("arm64-v8a")?"arm64-v8a":e.includes("x86_64")?"x86_64":"unknown"}var yu=async e=>{if(e.apk){await gb(e);return}let t=process.cwd(),n=pt(t).appRoot,r=br.join(n,"package.json"),i=br.join(n,"pubspec.yaml");!nn.existsSync(r)&&!nn.existsSync(i)&&(Ze.error(st.red("No package.json or Flutter pubspec.yaml found. Run this command from a project root.")),process.exit(1));let o=nn.existsSync(r)?JSON.parse(nn.readFileSync(r,"utf-8")):tt(n),s=_r(n),a=!s&&!!(o.dependencies?.expo||o.devDependencies?.expo);e.json||(Ze.info(st.dim(`Project: ${o.name||"unknown"} v${o.version||"0.0.0"}`)),Ze.info(st.dim(`Type: ${s?"Flutter":a?"Expo":"Bare React Native"}`)),Ze.info(""));let l={json:e.json,fix:e.fix,category:e.category,severity:e.severity,prebuild:e.prebuild,since:e.since},d=await cu(t,l);e.json?console.log(JSON.stringify(uu(d,o),null,2)):du(d,e.severity);let c=d.some(f=>f.findings.some(p=>p.severity==="critical")),u=d.some(f=>f.findings.some(p=>p.severity==="high"));(c||u)&&process.exit(1)},gu=["16kb"];async function gb(e){let t=e.category?.toLowerCase();t&&!gu.includes(t)&&(Ze.error(st.red(`Unknown APK check category: "${t}"`)),Ze.info(st.dim(`Available APK checks: ${gu.join(", ")}`)),process.exit(1));let n=await hb(e.apk);n||process.exit(1);let r=!t,i=!1;(r||t==="16kb")&&(await fu(n)||(i=!0)),i&&process.exit(1)}async function hb(e){if(e.startsWith("build:")){let n=e.slice(6);return await yb(n)}if(e.startsWith("http://")||e.startsWith("https://"))return await bu(e);let t=br.resolve(e);return nn.existsSync(t)?t:(Ze.error(st.red(`APK file not found: ${t}`)),null)}async function yb(e){if(!we())return Ze.error(st.red(`A Mach build ID requires authentication. Run \`${m.nameLower} login\` first, or pass a local APK path.`)),null;let n=hu();n.start(`Fetching APK from build ${e}...`);try{let r=await I.get(`/build/${e}`);if(r.data.status!=="success")throw new Error(r.data.message);let i=r.data.build;if(!i)throw new Error("Build not found");let o=i.artifacts?.find(s=>s.type?s.type==="apk":s.name?.endsWith(".apk")||s.url?.includes(".apk"));return!o||!o.url?(n.stop("No APK artifact found"),Ze.error(st.red("This build does not have an APK artifact.")),Ze.info(st.dim("Make sure the build produced an APK (not just an AAB).")),null):(n.stop(`Found build: ${i.buildId||e}`),await bu(o.url))}catch(r){return n.stop("Failed to fetch build"),Ze.error(st.red(r.message)),null}}async function bu(e){let t=hu();t.start("Downloading APK...");try{let n=nn.mkdtempSync(br.join(fb.tmpdir(),`${m.nameLower}-audit-`)),r=br.join(n,"app.apk"),i=await mb.get(e,{responseType:"arraybuffer"});nn.writeFileSync(r,i.data);let o=(i.data.length/(1024*1024)).toFixed(1);return t.stop(`Downloaded APK (${o} MB)`),r}catch(n){return t.stop("Download failed"),Ze.error(st.red(`Failed to download APK: ${n.message}`)),null}}var Sb=console.log;console.log=()=>{};Ab({quiet:!0});console.log=Sb;var Ib=process.argv.includes("--json");Ib||re(J.bgCyan.black(m.cliTag("Production Build Orchestrator")));var Ar=(e,t=[])=>t.concat(e),x=new bb;x.name(m.nameLower).description(`${m.name} CLI: Powerful Cloud Infrastructure Tools`).version(Ot).option("-y, --yes","Automatically answer yes to all prompts",!1).option("--config <path>",`Use a specific ${m.configFileName}; app paths still resolve from the current directory`).option("--quiet","Suppress non-essential output",!1);x.command("agent").description("Manage local device discovery agent for the Install Hub (port 7070)").argument("[action]","start, run, install, status, restart, stop, or uninstall","start").action(async e=>{await oc(e)});x.command("host").description("Setup AWS S3 static hosting and CloudFront").action(async()=>{re(J.bgCyan.black(m.cliTag("Hosting"))),await Ws()});var Cn=x.command("web").description("Deploy static Expo, React Native Web, and Flutter web apps through Mach");Cn.command("deploy").description("Upload a finished static web build and promote it by default").option("-o, --output <directory>","Finished static output directory (for example dist or build/web)").option("--build","Build Expo or Flutter web locally before deploying").option("-p, --profile <name>","Existing Mach build profile; its web.alias selects the release address").option("-a, --alias <alias>","Override the profile alias: production or staging").option("--no-promote","Keep the deployment as an immutable preview only").option("-m, --message <message>","Deployment message").option("--project-id <id>","Mach project ID").action(async e=>{await aa(e)});Cn.command("status").description("Show production, staging, and custom-domain status").option("--project-id <id>","Mach project ID").action(async e=>{await la(e)});Cn.command("list").description("List recent web deployments").option("--project-id <id>","Mach project ID").action(async e=>{await ca(e)});Cn.command("promote <deployment-id>").description("Point a release alias at an existing ready deployment").option("-a, --alias <alias>","production or staging","production").option("--project-id <id>","Mach project ID").action(async(e,t)=>{await da(e,t)});Cn.command("rollback").description("Restore the previous ready deployment for an alias").option("-a, --alias <alias>","production or staging","production").option("--deployment <id>","Specific deployment to restore").option("--project-id <id>","Mach project ID").action(async e=>{await ua(e)});var Su=Cn.command("domain").description("Attach and manage customer-owned domains");Su.command("add").description("Add a Cloudflare for SaaS custom hostname to production").requiredOption("--domain <hostname>","Hostname such as www.example.com").option("--project-id <id>","Mach project ID").action(async e=>{await pa(e)});Su.command("remove <hostname>").description("Remove a custom hostname").option("--project-id <id>","Mach project ID").action(async(e,t)=>{await fa(e,t)});x.command("sitemap").description("Generate sitemap.xml from Expo Router app structure").option("-o, --output <path>","Output path for sitemap.xml","./public/sitemap.xml").action(async e=>{re(J.bgCyan.black(m.cliTag("Sitemap Generator"))),await ya(e)});x.command("build").description("Run a build on a cloud provider (AWS Spot Instances)").argument("[platform]","Target platform (android, ios, or Flutter web)").option("--platform <os>","Target platform alias (android, ios, web) [Optional]").option("--repo <url>","Git Repository URL").option("--branch <name>","Git Branch").option("--ami <id>","AMI ID").option("--bucket <name>","S3 Bucket for artifacts").option("--region <region>","AWS Region").option("--aws-profile <name>","AWS Credentials Profile").option("-p, --build-profile <name>","Any configured build profile name").option("--profile <name>","Build Profile (alias for --build-profile)").option("--dry-run","Generate User Data script without launching").option("--keep-instance","Do not terminate the instance after build").option("--subnet <id>","VPC Subnet ID to launch the instance in").option("--security-group <id>","VPC Security Group ID to use").option("--ssh-host <host>","Remote host for iOS build (SSH)").option("--ssh-user <user>","SSH username for remote host").option("--ssh-key <path>","Path to private SSH key for remote host").option("--ios-scheme <scheme>","iOS Scheme to build").option("--ios-team-id <id>","Apple Development Team ID").option("--ios-configuration <config>","Xcode configuration (Release/Debug)").option("--ios-export-method <method>","Export method (ad-hoc, app-store, development, enterprise)").option("--ios-api-key-id <id>","App Store Connect API Key ID").option("--ios-api-key-issuer <id>","App Store Connect API Key Issuer ID").option("--ios-api-key-path <path>","Path to App Store Connect API Key (.p8) file").option("--simulator","Build for iOS Simulator (no signing required)").addOption(new Qe("--build-id <id>","Internal build ID").hideHelp()).addOption(new Qe("--project-id <id>","Internal project ID").hideHelp()).addOption(new Qe("--fail-only","Internal: mark an existing build failed").hideHelp()).addOption(new Qe("--error <message>","Internal failure message").hideHelp()).option("--local","Run build on local machine").option("--auto-version","Assign the next Android versionCode or iOS buildNumber from Mach").option("--auto-submit","Submit this build after it completes successfully").option("--submit-track <track>","Google Play track to use with --auto-submit").option("--submit-release-status <status>","Google Play release status to use with --auto-submit").option("--submit-rollout <fraction>","Google Play staged rollout fraction to use with --auto-submit").option("--submit-changes-not-sent-for-review","Commit Google Play changes without automatically sending them for review when using --auto-submit").option("--submit-credential-id <id>","Service credential ID to use with --auto-submit").option("--submit-json-output <path>","Write auto-submit metadata JSON to a file for CI/CD").option("--verbose","Enable verbose logging").option("--json-output <path>","Write build metadata JSON to a file for CI/CD").option("--flutter-obfuscate","Obfuscate Flutter release Dart code and preserve split debug symbols").option("--flutter-split-debug-info","Preserve Flutter release split debug symbols without enabling obfuscation").option("--maestro","Queue a managed Maestro test run after a successful build").option("--maestro-flows <path>","Maestro flow file or directory (default: .maestro)").option("--maestro-device <device>","Managed device profile id (run `mach maestro devices` to list)").option("--maestro-retries <n>","Retries for the Maestro run","1").option("--maestro-record","Enable screen recording where supported").option("--maestro-use-build-source","Use Maestro flows from the build source snapshot instead of uploading local flows").option("--maestro-env <name>","Forward an environment variable to the managed Maestro runner; repeat or comma-separate names",Ar,[]).option("-y, --yes","Automatically answer yes to all prompts",!1).option("--quiet","Suppress non-essential output",!1).action(async(e,t)=>{let n=x.opts();t.yes=t.yes||n.yes,t.quiet=t.quiet||n.quiet,t.platform=e||t.platform,t.buildProfile=t.profile||t.buildProfile,t.quiet||re(J.bgCyan.black(m.cliTag("Cloud Build"))),await Wr(t)});var _b=x.command("maestro").description("Run Maestro tests locally or with the managed Mach runner").option("--platform <os>","Target platform (android/ios)").option("-p, --profile <name>","Build profile to resolve when using --latest").option("--latest","Use the latest successful build for the platform/profile").option("--build-id <id>","Use a specific Mach build ID").option("--build-url <url>","Use a Mach build URL").option("--artifact-url <url>","Use a direct APK or iOS simulator app artifact URL").option("--local","Run Maestro on a connected local emulator/device instead of the managed runner").option("--maestro-flows <path>","Maestro flow file or directory (default: .maestro)").option("--maestro-device <device>","Managed device profile id (run `mach maestro devices` to list); local runs accept a device identifier").option("--maestro-retries <n>","Retries for the Maestro run","1").option("--maestro-record","Enable screen recording where supported").option("--maestro-use-build-source","Use Maestro flows from the build source snapshot instead of uploading local flows").option("--maestro-env <name>","Forward an environment variable to the managed Maestro runner; repeat or comma-separate names",Ar,[]).option("--wait","Wait for managed Maestro completion and exit non-zero on failure").option("--wait-timeout <minutes>","Maximum minutes to wait for managed Maestro completion","60").option("--wait-interval <seconds>","Polling interval while waiting for managed Maestro completion","15").option("--json-output <path>","Write test run metadata JSON to a file for CI/CD").addOption(new Qe("--local-runner","Internal: execute a managed Maestro run on this machine").hideHelp()).addOption(new Qe("--test-run-id <id>","Internal test run ID").hideHelp()).addOption(new Qe("--project-id <id>","Internal project ID").hideHelp()).addOption(new Qe("--runner-token <token>","Internal runner token").hideHelp()).action(async e=>{re(J.bgCyan.black(m.cliTag("Maestro Testing"))),await La(e)});_b.command("devices").description("List device profiles available on the managed Maestro runner fleet").option("--platform <os>","Filter to android or ios").option("--json","Print machine-readable JSON").action(async e=>{await Ma(e)});var rn=e=>e.option("--platform <os>","Target platform: ios, android, or all","all").option("-p, --profile <name>","Flutter build profile used to resolve flavor, target, and Dart defines").option("--channel <name>","OTA channel (for example: production, staging)").option("--branch <name>","Alias for --channel").option("--runtime-version <version>","Runtime version override").option("--message <text>","Release note/message for this OTA update").option("--framework <name>","Framework override: expo, react-native, or flutter").option("--engine <name>","OTA engine override: expo-updates or shorebird").option("--url <url>","Mach OTA update URL override").option("--install-plugin","Install @radhya/mach locally for the Expo config plugin").option("--skip-install","Do not install local Expo plugin dependency").option("--update-id <id>","OTA update id for rollback/promote").option("--release-version <version>","Shorebird release version (defaults to latest for publish)").option("--patch-number <number>","Shorebird patch number for promote/rollback").option("--track <name>","Shorebird track: stable or staging").option("--json","Print JSON output"),on=x.command("ota").description("Setup, publish, verify, and manage Mach OTA updates");rn(on.command("setup").description("Configure OTA for this project")).action(async e=>{let t=x.opts();re(J.bgCyan.black(m.cliTag("OTA Setup"))),await At("setup",{...e,yes:e.yes||t.yes})});rn(on.command("publish").description("Publish an OTA update")).action(async e=>{let t=x.opts();re(J.bgCyan.black(m.cliTag("OTA Publish"))),await At("publish",{...e,yes:e.yes||t.yes})});rn(on.command("release").description("Create a Flutter Shorebird base release")).action(async e=>{let t=x.opts();re(J.bgCyan.black(m.cliTag("OTA Release"))),await At("release",{...e,yes:e.yes||t.yes})});rn(on.command("verify").description("Verify OTA configuration")).action(async e=>{let t=x.opts();re(J.bgCyan.black(m.cliTag("OTA Verify"))),await At("verify",{...e,yes:e.yes||t.yes})});rn(on.command("list").description("List OTA updates for the linked project")).action(async e=>{let t=x.opts();re(J.bgCyan.black(m.cliTag("OTA Updates"))),await At("list",{...e,yes:e.yes||t.yes})});rn(on.command("rollback").description("Roll back an OTA update")).action(async e=>{let t=x.opts();re(J.bgCyan.black(m.cliTag("OTA Rollback"))),await At("rollback",{...e,yes:e.yes||t.yes})});rn(on.command("promote").description("Promote an OTA update")).action(async e=>{let t=x.opts();re(J.bgCyan.black(m.cliTag("OTA Promote"))),await At("promote",{...e,yes:e.yes||t.yes})});x.command("submit").description("Automated Store Submission (App Store / Google Play)").option("--platform <os>","Target platform (ios/android)").option("-p, --profile <name>","Build/submission profile to submit from (e.g. production, preprod)").option("--track <track>","Google Play Track (internal, alpha, beta, production)").option("--release-status <status>","Google Play release status (completed, draft, halted, inProgress)").option("--rollout <fraction>","Google Play staged rollout fraction for inProgress releases (example: 0.1)").option("--changes-not-sent-for-review","Commit Google Play changes without automatically sending them for review").option("--ssh-host <host>","Remote macOS host for iOS submission").option("--ssh-user <user>","SSH username for remote iOS submission").option("--ssh-key <path>","Path to private SSH key for remote iOS submission").option("--credential-id <id>","Service credential ID to use when multiple submission credentials exist").option("--local","Run submission on this machine (internal runner mode for iOS)").addOption(new Qe("--submit-id <id>","Internal submission ID").hideHelp()).addOption(new Qe("--project-id <id>","Internal project ID").hideHelp()).addOption(new Qe("--package-name <name>","Internal Android package name").hideHelp()).addOption(new Qe("--bundle-id <id>","Internal iOS bundle identifier").hideHelp()).option("--json-output <path>","Write submission metadata JSON to a file for CI/CD").option("--latest","Use the latest successful build for submission").option("--build-id <id>","Use a specific build ID for submission").action(async e=>{let t=x.opts();e.quiet=e.quiet||t.quiet,e.yes=e.yes||t.yes,re(J.bgCyan.black(m.cliTag("Store Submission"))),await jr(e)});x.command("login").description(`Login to ${m.name} Dashboard`).action(async()=>{re(J.bgCyan.black(m.cliTag("Login"))),await cc()});x.command("logout").description(`Logout from ${m.name} on this machine`).action(async()=>{re(J.bgCyan.black(m.cliTag("Logout"))),await dc()});x.command("link").description(`Link local directory to a ${m.name} Project`).action(async()=>{re(J.bgCyan.black(m.cliTag("Link Project"))),await pc()});x.command("me").description("Display currently logged in user details").action(async()=>{await Kc()});x.command("init").description(`Create a new ${m.name} Project`).action(async()=>{re(J.bgCyan.black(m.cliTag("Init Project"))),await fc()});x.command("env").description("Manage Environment Variables").argument("<action>","Action to perform: set, list, pull, download, or export").argument("[args...]","Key=Value pairs for set action").option("-e, --environment <name>","Environment to pull/download","development").option("-o, --out <file>","Output file for pull/download",".env.local").option("--overwrite","Overwrite output file if it already exists").action(async(e,t,n)=>{re(J.bgCyan.black(m.cliTag("Env Manager"))),await gc(e,t,n)});x.command("start").description("Start the app with its configured Flutter or JavaScript toolchain").option("-p, --build-profile <name>","Any configured build profile name").option("--tunnel","Use ngrok tunnel").option("--lan","Use LAN IP").option("--localhost","Use localhost").option("-c, --clear","Clear Metro cache").option("--port <number>","Port to listen on").option("--ios","Start on iOS").option("--android","Start on Android").option("--web","Start on Web").action(async e=>{re(J.bgCyan.black(m.cliTag("Dev Server"))),await Jc(e)});var Sr=x.command("push").description("Configure and send provider-direct APNs/FCM notifications");Sr.command("setup").description("Install and wire a working default push experience").option("-p, --profile <name>","Build profile used to resolve app identity and Flutter entrypoint").option("--name <name>","Push app display name").option("--ios-bundle <id>","iOS bundle identifier").option("--android-package <name>","Android package name").option("-e, --environment <name>","development, preview, or production").option("--google-services-file <path>","Android google-services.json path").option("--skip-install","Generate setup without installing SDK dependencies").action(Bs);Sr.command("init").description("Create only the server-side push app (advanced)").option("-p, --profile <name>","Build profile used to resolve app identity").option("--name <name>","Push app display name").option("--ios-bundle <id>","iOS bundle identifier").option("--android-package <name>","Android package name").option("-e, --environment <name>","development, preview, or production","production").option("--google-services-file <path>","Expo Android google-services.json path").action(js);var Eu=Sr.command("credentials").description("Configure provider credentials");Eu.command("apns").description("Configure an Apple APNs .p8 authentication key").requiredOption("--file <path>","APNs .p8 file").requiredOption("--team-id <id>","Apple Developer team ID").requiredOption("--key-id <id>","APNs key ID").option("--bundle-id <id>","iOS bundle identifier").option("--app <id>","MACH Push app ID").option("-e, --environment <name>","development, preview, or production").action(e=>xi("apns",e));Eu.command("fcm").description("Configure a Firebase service-account JSON file").requiredOption("--file <path>","Firebase service-account JSON").option("--app <id>","MACH Push app ID").option("-e, --environment <name>","Deprecated; accepted for compatibility because FCM credentials are package-wide").action(e=>xi("fcm",e));Sr.command("send").description("Queue one transient push notification").requiredOption("--title <text>","Notification title").requiredOption("--body <text>","Notification body").option("--app <id>","MACH Push app ID").option("-e, --environment <name>","development, preview, or production").option("--token <token>","MACH push token; repeatable",Ar,[]).option("--user <id>","Application user ID; repeatable",Ar,[]).option("--all","Send to all active devices").option("--platform <platform>","Limit --all to ios or android").option("--data <json>","String-to-string custom data JSON").option("--sound <name>","Provider sound name").option("--badge <number>","iOS badge count").option("--ttl <seconds>","Provider time-to-live").option("--collapse-key <key>","Provider collapse key").option("--android-channel-id <id>","Android notification channel").action(Hs);Sr.command("status").description("Show aggregate push delivery counters").option("--days <number>","Statistics range, 1-90","30").action(Gs);x.command("config").description("Show resolved configuration for a profile").option("-p, --profile <name>","Build profile to resolve").option("--json","Output as JSON").action(async e=>{await Xc(e)});var Iu=x.command("version").description("Show or seed DB-owned native version counters"),_u=e=>e.requiredOption("--platform <os>","Target platform: ios or android").option("-p, --profile <name>","Build profile used to resolve package/bundle scope").option("--scope <value>","Counter scope override, usually package name or bundle identifier").option("--package <name>","Android package override").option("--bundle-id <id>","iOS bundle identifier override").option("--json","Print JSON output");_u(Iu.command("show").description("Show the current native version counter")).action(async e=>{re(J.bgCyan.black(m.cliTag("Version Counter"))),await cs("show",e)});_u(Iu.command("seed").description("Seed the native version counter for an existing app").argument("[value]","Latest already-used value; the next build uses value + 1").option("--value <number>","Latest already-used value; the next build uses value + 1").option("--force","Allow lowering an existing counter")).action(async(e,t)=>{re(J.bgCyan.black(m.cliTag("Version Counter"))),await cs("seed",{...t,value:t.value??e})});var wu=x.command("deeplink").description("Configure and verify app links, universal links, and URI schemes");wu.command("setup").description("Generate deep link config, hosted association files, and Expo plugin support").option("--domain <domain>","Associated domain, e.g. app.example.com").option("--base-url <url>","Base URL, e.g. https://app.example.com").option("-p, --profile <name>","Profile used for build/submit overrides").option("--platform <platform>","ios, android, or all").option("--framework <framework>","expo, react-native, or flutter").option("--scheme <scheme>","URI scheme, e.g. myapp").option("--ios-bundle-id <id>","iOS bundle identifier").option("--android-package <name>","Android package name").option("--apple-team-id <id>","Apple Developer Team ID").option("--app-store-id <id>","App Store app ID for Smart App Banner").option("--android-fingerprint <sha256>","Android SHA256 signing certificate fingerprint; repeatable",Ar,[]).option("--output <dir>","Directory for hosted files, e.g. public or deep-links").option("--install-plugin","Install @radhya/mach locally so Expo can use the packaged config plugin").option("--no-install-plugin","Do not install @radhya/mach for Expo projects; use the local plugin fallback if the package is missing").option("-y, --yes","Automatically answer yes to prompts",!1).action(async e=>{let t=x.opts();e.yes=e.yes||t.yes,re(J.bgCyan.black(m.cliTag("Deep Links"))),await $d(e)});wu.command("verify").description("Verify local and optionally live deep link configuration").option("-p, --profile <name>","Profile used for build/submit overrides").option("--live","Check hosted files over HTTPS").option("--android-device","Print Android device verification commands").action(async e=>{re(J.bgCyan.black(m.cliTag("Deep Link Verify"))),await Od(e)});x.command("credentials").description("Unified, interactive credential management (iOS/Android)").option("--platform <os>","Platform to manage: ios or android").option("-p, --profile <name>","Any configured build profile name").option("--credential-type <type>","iOS signing type override: development, adhoc, or store").option("--force","Force recreate certificates (nuke existing on Apple Portal)",!1).action(async e=>{let{credentialsMainCommand:t}=await import("./credentials-LFUCTBJU.js");await t(e)});x.command("credentials:setup").description("Automated credential provisioning (iOS/Android) [Legacy]").requiredOption("--platform <os>","Platform: ios or android").option("--profile <name>","Any configured build profile name").option("--credential-type <type>","iOS signing type override: development, adhoc, or store").option("--bundle-id <id>","Bundle ID / Package Name (optional, auto-detected)").option("--team-id <id>","Apple Team ID (iOS only)").option("--key-alias <alias>","Android keystore alias (optional, auto-generated)").option("--aws-profile <name>","AWS Credentials Profile (for S3 storage)").option("--force","Force recreate certificates (nuke existing on Apple Portal)",!1).action(async e=>{re(J.bgCyan.black(m.cliTag("Credentials Setup"))),await xn(e),Au(J.green("Done!"))});x.command("credentials:service").description("Upload Service Credentials (ASC API Key / Google Service JSON) [Legacy]").requiredOption("--platform <os>","Platform: ios or android").option("--file <path>","Path to credential file (.p8 or .json)").option("--issuer-id <id>","ASC API Key Issuer ID (iOS only)").option("--key-id <id>","ASC API Key ID (iOS only)").option("--bundle-id <id>","Bundle identifier / Android package name to attach this service credential to").option("--package-name <name>","Android package name to attach this service credential to").option("-p, --profile <name>","Build profile to resolve package/bundle identifier from config").action(async e=>{re(J.bgCyan.black(m.cliTag("Service Credentials"))),await Us(e),Au(J.green("Done!"))});var ys=x.command("device").description("Manage registered iOS test devices");ys.command("register").description("Register a connected iOS device or enter UDID manually").option("--udid <udid>","Device UDID (skip auto-detection)").option("--name <name>","Device name").option("--team-id <id>","Apple Developer Team ID for this device").action(async e=>{await yi("register",e)});ys.command("list").description("List all registered devices").option("--team-id <id>","Filter by Apple Developer Team ID").action(async e=>{await yi("list",e)});ys.command("remove").description("Remove a registered device").option("--udid <udid>","Device UDID to remove").option("--team-id <id>","Apple Developer Team ID for this device").action(async e=>{await yi("remove",e)});x.command("audit").description("Run project health, delivery impact, and security checks").option("--apk <path>","Path to APK file (runs APK diagnostics like 16KB alignment)").option("--json","Output results as JSON (for CI/CD)").option("--fix","Auto-apply fixes where possible").option("--category <name>","Run one category (e.g. project, impact, permissions, secrets)").option("--severity <level>","Minimum severity to display (critical, high, medium, low, info)").option("--prebuild","Run expo prebuild for deeper manifest/plist analysis").option("--since <git-ref>","Assess delivery impact from a branch, tag, or commit").action(async e=>{e.json||re(J.bgCyan.black(m.cliTag(e.apk?"APK Audit":"Project Audit"))),await yu(e)});var wb=new Set(["login","logout","agent"]),vb=new Set(["build","credentials","credentials:service","credentials:setup","env","push","submit","version"]),Rb=new Set(["publish","list","rollback","promote"]);function $b(e){let t=[],n=e;for(;n&&n!==x;)t.unshift(n.name()),n=n.parent;return t}function Ob(e,t){let[n,r]=$b(e);return vb.has(n)?!0:n==="ota"?Rb.has(r):n==="maestro"?r!=="devices"&&!t.local&&!t.localRunner:!1}x.hook("preAction",async(e,t)=>{let n=String(x.opts().config||"").trim();n&&(process.env.MACH_CONFIG_PATH=Eb.resolve(n));let r=t.name(),i=t.opts?.()||{};if(r==="maestro"&&(i.local||i.localRunner)||t.parent?.name()==="deeplink"||wb.has(r)||(ke(),!Ob(t,i)))return;let o=Vs(i,K());if(!o)throw new mt(`No linked ${m.name} project was found. Run \`${m.nameLower} link\` before using this command.`);await zs(o)});x.on("command:*",()=>{console.error(`Invalid command: %s
2495
2495
  See --help for a list of available commands.`,x.args.join(" ")),process.exit(1)});process.argv.slice(2).length||x.help();x.parseAsync(process.argv).catch(e=>{let t=e instanceof Error?e.message:String(e);console.error(J.red(t)),process.exitCode=1});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@radhya/mach",
3
- "version": "2.6.10",
3
+ "version": "2.6.11",
4
4
  "description": "Mach CLI: cloud build and delivery for Flutter, React Native, and Expo",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",