agent-device 0.19.2 → 0.19.3
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/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.19.2.apk → agent-device-android-multitouch-helper-0.19.3.apk} +0 -0
- package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.19.3.apk.sha256 +1 -0
- package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.19.2.manifest.json → agent-device-android-multitouch-helper-0.19.3.manifest.json} +4 -4
- package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.19.2.apk → agent-device-android-snapshot-helper-0.19.3.apk} +0 -0
- package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.19.3.apk.sha256 +1 -0
- package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.19.2.manifest.json → agent-device-android-snapshot-helper-0.19.3.manifest.json} +6 -6
- package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.h +7 -0
- package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.m +99 -30
- package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +9 -1
- package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +21 -8
- package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +10 -0
- package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SequenceExecution.swift +1 -0
- package/dist/src/agent-browser-tool.js +1 -1
- package/dist/src/android-adb.js +1 -1
- package/dist/src/android-input-ownership.js +1 -1
- package/dist/src/android.js +1 -1
- package/dist/src/app-lifecycle.js +1 -1
- package/dist/src/apple-runner-options.js +1 -1
- package/dist/src/apps.js +5 -5
- package/dist/src/audio-probe.js +1 -1
- package/dist/src/cli-help.js +14 -14
- package/dist/src/cli-runner.js +1 -1
- package/dist/src/cli.js +11 -11
- package/dist/src/client.js +2 -2
- package/dist/src/contracts.js +1 -1
- package/dist/src/debug-symbols.js +1 -1
- package/dist/src/device-input-state.js +1 -1
- package/dist/src/devices2.js +1 -1
- package/dist/src/find.js +1 -1
- package/dist/src/generic.js +1 -1
- package/dist/src/helper.js +1 -1
- package/dist/src/index.d.ts +11 -7
- package/dist/src/index.js +1 -1
- package/dist/src/input-actions.js +1 -1
- package/dist/src/input-actions2.js +1 -1
- package/dist/src/install-source2.js +1 -1
- package/dist/src/interaction-snapshot.js +1 -1
- package/dist/src/interaction.js +1 -1
- package/dist/src/interactor.js +2 -2
- package/dist/src/internal/bin.js +1 -1
- package/dist/src/internal/daemon.js +20 -16
- package/dist/src/internal/png-worker.js +1 -1
- package/dist/src/lease.js +1 -1
- package/dist/src/linux.js +1 -1
- package/dist/src/notifications.js +1 -1
- package/dist/src/png-worker-contract.js +1 -1
- package/dist/src/points.js +3 -3
- package/dist/src/providers.js +1 -1
- package/dist/src/react-native.js +1 -1
- package/dist/src/record-trace-recording.js +2 -2
- package/dist/src/record-trace.js +1 -1
- package/dist/src/registry.js +14 -14
- package/dist/src/reporting.js +3 -3
- package/dist/src/runner-client.js +1 -1
- package/dist/src/runner-sequence.js +1 -1
- package/dist/src/runtime-transport.js +1 -1
- package/dist/src/runtime.js +2 -2
- package/dist/src/sdk-android-adb.js +3 -3
- package/dist/src/sdk-app-inventory.js +1 -1
- package/dist/src/sdk-batch-runner.js +2 -2
- package/dist/src/sdk-batch.js +2 -2
- package/dist/src/sdk-contracts.js +2 -2
- package/dist/src/sdk-device.js +1 -0
- package/dist/src/sdk-finders.js +1 -1
- package/dist/src/sdk-io.js +1 -1
- package/dist/src/sdk-remote-config.js +1 -1
- package/dist/src/sdk-selectors.js +1 -1
- package/dist/src/selector-runtime.js +1 -1
- package/dist/src/server.js +2 -2
- package/dist/src/session.js +10 -10
- package/dist/src/setting-state.js +1 -1
- package/dist/src/simctl.js +1 -1
- package/dist/src/simulator.js +1 -1
- package/dist/src/snapshot-diagnostics.js +1 -1
- package/dist/src/snapshot.js +1 -1
- package/dist/src/snapshot2.js +2 -2
- package/dist/src/tool-provider.js +2 -2
- package/dist/src/tool-provider2.js +1 -1
- package/dist/src/tv-remote.js +12 -12
- package/dist/src/web.js +1 -1
- package/package.json +11 -3
- package/server.json +2 -2
- package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.19.2.apk.sha256 +0 -1
- package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.19.2.apk.sha256 +0 -1
- package/dist/src/snapshot-helper.js +0 -5
package/dist/src/client.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{t as e}from"./rolldown-runtime.js";import{F as t,H as n,a as r}from"./sdk-contracts.js";import{A as i,C as a,F as o,b as s,j as c,v as l,x as u}from"./sdk-android-adb.js";import{g as d}from"./sdk-batch.js";import{An as f,Fn as p,Qn as m,Zn as h,mn as ee}from"./tv-remote.js";import{i as te,n as ne}from"./output-path.js";import{C as g,O as re,T as ie,b as ae,g as oe,h as se,l as ce,m as le,n as ue,s as de,u as fe,v as _,w as pe,y as me}from"./snapshot-diagnostics.js";import{n as v,t as he}from"./version.js";import{n as ge}from"./path-resolution.js";import{t as y}from"./timeouts.js";import{u as _e}from"./host-process.js";import{A as ve,C as ye,D as be,E as xe,O as Se,P as Ce,S as we,T as Te,b as Ee,d as De,f as Oe,i as ke,k as Ae,p as je,s as Me,w as Ne,x as Pe,y as Fe}from"./registry.js";import{l as Ie,m as b,v as x}from"./sdk-batch-runner.js";import{n as Le,t as Re}from"./url.js";import{t as ze}from"./client-metro-companion.js";import{n as Be,r as Ve}from"./project-runtime.js";import{t as He}from"./runtime-transport.js";import{t as Ue}from"./command-metadata.js";import{createHash as We,randomUUID as Ge}from"node:crypto";import S from"node:fs";import Ke from"node:os";import C from"node:path";import w from"node:http";import T from"node:https";import{pipeline as qe}from"node:stream/promises";import{Transform as Je,Writable as Ye}from"node:stream";import E from"node:net";const Xe=`/agent-device`;function Ze(e){return D(e,Xe)}function D(e,t){let n=e.endsWith(`/`)?e:`${e}/`;return new URL(t.replace(/^\/+/,``),n).toString()}function O(e){let t=e?.trim();return t?{authorization:`Bearer ${t}`,"x-agent-device-token":t}:{}}async function Qe(e,t){let n=S.statSync(e),r=C.basename(e),i=n.isDirectory(),a=tt(t)??et(e,n),o=[];try{let t=i?await $e(e,o):e,n=S.statSync(t);return{payloadPath:t,fileName:r,artifactType:i?`app-bundle`:`file`,platform:a,contentType:i?`application/gzip`:`application/octet-stream`,sha256:await rt(t),sizeBytes:n.size,cleanup:()=>nt(o)}}catch(e){throw nt(o),e}}async function $e(e,t){let n=S.mkdtempSync(C.join(Ke.tmpdir(),`agent-device-upload-${Ge()}-`));t.push(n);let r=C.join(n,`${C.basename(e)}.tar.gz`);return await l(`tar`,[`czf`,r,`-C`,C.dirname(e),C.basename(e)],{env:{...process.env,COPYFILE_DISABLE:`1`}}),r}function et(e,t){let n=e.toLowerCase();if(t.isDirectory()&&n.endsWith(`.app`)||n.endsWith(`.ipa`))return`ios`;if(n.endsWith(`.apk`)||n.endsWith(`.aab`))return`android`}function tt(e){return e===`ios`||e===`android`?e:void 0}function nt(e){for(let t of e)S.rmSync(t,{recursive:!0,force:!0})}async function rt(e){let n=We(`sha256`),r=new Ye({write(e,t,r){n.update(e),r()}});return await qe(S.createReadStream(e),r).catch(e=>{throw new t(`COMMAND_FAILED`,`Failed to read local artifact`,{},e instanceof Error?e:void 0)}),n.digest(`hex`)}function it(e){let{stage:t,fileName:n,startOffset:r,totalBytes:i,onProgress:a}=e,o=r,s=st(i),c=Math.min(i,r+s);return new Je({transform(e,r,l){o=Math.min(i,o+e.byteLength),o>=c&&(a?.({type:`progress`,stage:t,fileName:n,transferredBytes:o,totalBytes:i}),c=Math.min(i,o+s)),l(null,e)}})}function at(){if(!(process.stderr.isTTY!==!0||process.env.CI))return e=>{process.stderr.write(`${ot(e)}\n`)}}function ot(e){switch(e.type){case`start`:return`Uploading ${e.fileName} (${k(e.totalBytes)}) via ${ct(e.stage)} upload`;case`resume`:return`Resuming ${e.fileName} at ${k(e.transferredBytes)} of ${k(e.totalBytes)}`;case`progress`:return`Uploaded ${k(e.transferredBytes)} of ${k(e.totalBytes)} (${lt(e.transferredBytes,e.totalBytes)})`;case`fallback`:return`Direct upload did not complete; retrying ${e.fileName} with ${ct(e.to)} upload`}}function st(e){return Math.max(8388608,Math.ceil(e*.05))}function ct(e){return e===`direct`?`direct`:`legacy`}function lt(e,t){return t<=0?`100%`:`${Math.min(100,Math.floor(e/t*100))}%`}function k(e){if(e<1024)return`${e} B`;let t=e/1024;if(t<1024)return`${t.toFixed(1)} KiB`;let n=t/1024;return n<1024?`${n.toFixed(1)} MiB`:`${(n/1024).toFixed(1)} GiB`}const ut=300*1e3,dt=`uploadStreamRetryable`;async function ft(e){return await A({...e,url:e.url,redirectCount:0,startOffset:0})}function pt(e){return e instanceof t&&e.details?.[dt]===!0}async function A(e){let n=e.url.protocol===`https:`?T:w,r=S.statSync(e.payloadPath).size,i=gt(e.headers,e.startOffset,r);return ht(e.progress,e.startOffset,r),await new Promise((a,o)=>{let s=!1,c=n.request({protocol:e.url.protocol,host:e.url.hostname,port:e.url.port,method:e.method,path:e.url.pathname+e.url.search,headers:i},n=>{s=!0,re(n).then(i=>{clearTimeout(l);let s=n.statusCode??500,c=n.headers.location;if(c&&_t(s)){if(e.redirectCount>=5){o(new t(`COMMAND_FAILED`,`Artifact upload exceeded redirect limit`,{maxRedirects:5,url:e.url.toString()}));return}let n=new URL(c,e.url);A({...e,url:n,redirectCount:e.redirectCount+1}).then(a,o);return}let u=vt(s)?yt(n.headers,r):void 0;if(u!==void 0){if(u>=r){a({statusCode:200,statusMessage:`Upload already complete`,body:``});return}if(u<=e.startOffset){o(new t(`COMMAND_FAILED`,`Artifact upload resume did not advance`,{offset:u,previousOffset:e.startOffset,url:e.url.toString()}));return}A({...e,startOffset:u}).then(a,o);return}a({statusCode:s,statusMessage:n.statusMessage,body:i})}).catch(o)}),l=setTimeout(()=>{c.destroy(),o(new t(`COMMAND_FAILED`,e.timeoutMessage,{timeoutMs:ut,...e.timeoutHint?{hint:e.timeoutHint}:{},...mt(e)}))},ut);c.on(`error`,n=>{s||(clearTimeout(l),o(new t(`COMMAND_FAILED`,e.errorMessage,{...e.errorHint?{hint:e.errorHint}:{},...mt(e)},n)))}),c.on(`close`,()=>clearTimeout(l)),qe(S.createReadStream(e.payloadPath,{start:e.startOffset}),it({stage:e.progress?.stage??`legacy`,fileName:e.progress?.fileName??C.basename(e.payloadPath),startOffset:e.startOffset,totalBytes:r,onProgress:e.progress?.onProgress}),c).catch(e=>{s||(c.destroy(),o(new t(`COMMAND_FAILED`,`Failed to read local artifact`,{},e instanceof Error?e:Error(String(e)))))})})}function mt(e){return e.retryable===!0?{[dt]:!0}:{}}function ht(e,t,n){e?.onProgress?.({type:t>0?`resume`:`start`,stage:e.stage,fileName:e.fileName,transferredBytes:t,totalBytes:n})}function gt(e,t,n){return t<=0?e:{...e,"content-length":Math.max(n-t,0),"content-range":`bytes ${t}-${n-1}/${n}`}}function _t(e){return[301,302,303,307,308].includes(e)}function vt(e){return e===308}function yt(e,t){let n=bt(e[`x-upload-offset`]??e[`upload-offset`]);if(n!==void 0)return Math.min(n,t);let r=xt(e.range)?.match(/^bytes=0-(\d+)$/);if(!r)return;let i=Number(r[1]);if(!(!Number.isSafeInteger(i)||i<0))return Math.min(i+1,t)}function bt(e){let t=xt(e);if(t===void 0)return;let n=Number(t);return Number.isSafeInteger(n)&&n>=0?n:void 0}function xt(e){return Array.isArray(e)?e[0]:e}const St=30*1e3;async function Ct(e){let t=await Qe(e.localPath,e.platform),n=e.baseUrl.endsWith(`/`)?e.baseUrl:`${e.baseUrl}/`,r=Ge();try{let i=await Dt({normalizedBase:n,token:e.token,artifact:t,uploadAttemptId:r});return i?.kind===`cache-hit`?i.uploadId:i?.kind===`direct-upload`?await wt({normalizedBase:n,token:e.token,artifact:t,preflight:i,uploadAttemptId:r,onProgress:e.onProgress})||(e.onProgress?.({type:`fallback`,from:`direct`,to:`legacy`,fileName:t.fileName}),await Et({normalizedBase:n,token:e.token,artifact:t,onProgress:e.onProgress})):await Et({normalizedBase:n,token:e.token,artifact:t,onProgress:e.onProgress})}finally{t.cleanup()}}async function wt(e){let t=async t=>(await At(e.artifact,t,e.onProgress),await jt({normalizedBase:e.normalizedBase,token:e.token,uploadId:t.uploadId}));try{return await t(e.preflight)}catch(n){if(!Tt(n))return;let r=await Dt({normalizedBase:e.normalizedBase,token:e.token,artifact:e.artifact,uploadAttemptId:e.uploadAttemptId});if(r?.kind===`cache-hit`)return r.uploadId;if(r?.kind===`direct-upload`)try{return await t(r)}catch{return}return}}function Tt(e){return e instanceof t?pt(e):!0}async function Et(e){let{normalizedBase:n,token:r,artifact:i}=e,a=new URL(`upload`,n),o={"content-type":i.contentType,"x-artifact-type":i.artifactType,"x-artifact-filename":i.fileName,"x-artifact-hash":i.sha256,"x-artifact-hash-algorithm":`sha256`,"transfer-encoding":`chunked`};Object.assign(o,O(r));let s=await ft({url:a,method:`POST`,headers:o,payloadPath:i.payloadPath,timeoutMessage:`Artifact upload timed out`,timeoutHint:`The upload to the remote daemon exceeded the 5-minute timeout.`,errorMessage:`Failed to upload artifact to remote daemon`,errorHint:`Verify the remote daemon is reachable and supports artifact uploads.`,progress:{stage:`legacy`,fileName:i.fileName,onProgress:e.onProgress}});try{let e=JSON.parse(s.body);if(!e.ok||!e.uploadId)throw new t(`COMMAND_FAILED`,`Upload failed: ${s.body}`);return e.uploadId}catch(e){throw e instanceof t?e:new t(`COMMAND_FAILED`,`Invalid upload response: ${s.body}`)}}async function Dt(e){let t=new URL(`upload/preflight`,e.normalizedBase),n={"content-type":`application/json`};Object.assign(n,O(e.token));let r=await fetch(t,{method:`POST`,headers:n,signal:AbortSignal.timeout(St),body:JSON.stringify({uploadAttemptId:e.uploadAttemptId,sha256:e.artifact.sha256,fileName:e.artifact.fileName,sizeBytes:e.artifact.sizeBytes,artifactType:e.artifact.artifactType,...e.artifact.platform?{platform:e.artifact.platform}:{},contentType:e.artifact.contentType})}).catch(()=>void 0);if(r?.ok)return Ot(await r.json().catch(()=>void 0))}function Ot(e){if(!e||typeof e!=`object`)return;let t=e;if(t.ok!==!0||typeof t.uploadId!=`string`)return;if(t.cacheHit===!0)return{kind:`cache-hit`,uploadId:t.uploadId};let n=t.upload;if(!n||typeof n.url!=`string`)return;let r=n.headers??{};if(kt(r))return{kind:`direct-upload`,uploadId:t.uploadId,url:n.url,headers:r}}function kt(e){return!e||typeof e!=`object`||Array.isArray(e)?!1:Object.values(e).every(e=>typeof e==`string`)}async function At(e,n,r){let i=await ft({url:new URL(n.url),method:`PUT`,headers:n.headers,payloadPath:e.payloadPath,timeoutMessage:`Direct artifact upload timed out`,timeoutHint:`The direct upload ticket did not accept the artifact within the timeout.`,errorMessage:`Failed to upload artifact with direct upload ticket`,retryable:!0,progress:{stage:`direct`,fileName:e.fileName,onProgress:r}});if(i.statusCode<200||i.statusCode>=300)throw new t(`COMMAND_FAILED`,`Direct artifact upload failed`,{statusCode:i.statusCode,statusMessage:i.statusMessage})}async function jt(e){let n=new URL(`upload/finalize`,e.normalizedBase),r={"content-type":`application/json`};Object.assign(r,O(e.token));let i=await fetch(n,{method:`POST`,headers:r,signal:AbortSignal.timeout(St),body:JSON.stringify({uploadId:e.uploadId})}).catch(e=>{throw new t(`COMMAND_FAILED`,`Failed to finalize direct artifact upload`,{},e)});if(!i.ok)throw new t(`COMMAND_FAILED`,`Direct artifact upload finalize failed`,{status:i.status,statusText:i.statusText});let a=await i.json().catch(()=>void 0);if(!a?.ok||!a.uploadId)throw new t(`COMMAND_FAILED`,`Invalid upload finalize response`);return a.uploadId}async function Mt(e,t){let n=[...e.positionals??[]],r=e.flags?{...e.flags}:void 0,i=e.meta?.installSource,a={},o,s=at();if(!Jt(t))return Lt({positionals:n,flags:r,installSource:i,uploadedArtifactId:o,clientArtifactPaths:a});r=Pt(e,n,r,a);let c=await Rt(e,t,s);return c&&(i=c.installSource,o=c.uploadedArtifactId??o),e.command!==`install`&&e.command!==`reinstall`||(o=await Nt(e,t,n,s)??o),Lt({positionals:n,flags:r,installSource:i,uploadedArtifactId:o,clientArtifactPaths:a})}async function Nt(e,t,n,r){let i=n.length===1?0:1,a=n[i];if(a===void 0)return;if(a.startsWith(`remote:`)){n[i]=a.slice(7);return}let o=It(a,e.meta?.cwd);if(o)return await Ct({localPath:o,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform,onProgress:r})}function Pt(e,t,n,r){let i=zt(e,t);if(!i)return n;i.positionalPath!==void 0&&(t[i.positionalIndex]=i.positionalPath);let a=Ft(n,i.flagPath);return r[i.field]=i.localPath,a}function Ft(e,t){return t===void 0?e:{...e??{},out:t}}function It(e,t){let n=C.isAbsolute(e)?e:C.resolve(t??process.cwd(),e);return S.existsSync(n)?n:void 0}function Lt(e){return{positionals:e.positionals,flags:e.flags,installSource:e.installSource,uploadedArtifactId:e.uploadedArtifactId,...Object.keys(e.clientArtifactPaths).length>0?{clientArtifactPaths:e.clientArtifactPaths}:{}}}async function Rt(e,t,n){let r=e.meta?.installSource;if(e.command!==`install_source`||!r||r.kind!==`path`)return null;let i=r.path.trim();if(!i)return{installSource:r};if(i.startsWith(`remote:`))return{installSource:{...r,path:i.slice(7)}};let a=C.isAbsolute(i)?i:C.resolve(e.meta?.cwd??process.cwd(),i);if(!S.existsSync(a))return{installSource:{...r,path:a}};let o=await Ct({localPath:a,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform,onProgress:n});return{installSource:{...r,path:a},uploadedArtifactId:o}}function zt(e,t){if(e.command===`screenshot`){let n=Ut(e,`path`,`.png`);return t[0]?{field:`path`,localPath:n,positionalIndex:0,positionalPath:M(`screenshot`,`.png`)}:{field:`path`,localPath:n,positionalIndex:0,flagPath:M(`screenshot`,`.png`)}}if(e.command===`record`&&(t[0]??``).toLowerCase()===`start`){if(!Vt(e)&&e.flags?.platform===void 0)return null;let t=Bt(e),n=Ht(Ut(e,`outPath`,t,1),e);return{field:`outPath`,localPath:n,positionalIndex:1,positionalPath:M(`recording`,C.extname(n)||t)}}return null}function Bt(e){return te(e.flags?.platform)}function Vt(e){return j(e.positionals?.[1])||j(e.flags?.out)}function Ht(e,t){return t.flags?.platform===`web`?ne(e,Bt(t)):e}function Ut(e,t,n,r=0){let i=e.positionals?.[r]??e.flags?.out,a=`${t===`path`?`screenshot`:`recording`}-${Date.now()}${n}`,o=j(i)?i:a;return C.isAbsolute(o)?o:C.resolve(e.meta?.cwd??process.cwd(),o)}function j(e){return typeof e==`string`&&e.trim().length>0}function M(e,t){let n=t.startsWith(`.`)?t:`.${t}`;return C.posix.join(`/tmp`,`agent-device-${e}-${Date.now()}-${Math.random().toString(36).slice(2,8)}${n}`)}async function Wt(e,t,n){let r=Array.isArray(n.data?.artifacts)?n.data.artifacts:[];if(r.length===0||!e.baseUrl)return n;let i=n.data?{...n.data}:{},a=[];for(let n of r){if(!n||typeof n!=`object`||typeof n.artifactId!=`string`){a.push(n);continue}let r=Gt(n,t);await Kt({baseUrl:e.baseUrl,token:e.token,artifactId:n.artifactId,destinationPath:r,requestId:t.meta?.requestId}),i[n.field]=r,a.push({...n,localPath:r})}return i.artifacts=a,{ok:!0,data:i}}function Gt(e,t){if(e.localPath&&e.localPath.trim().length>0)return e.localPath;let n=t.meta?.clientArtifactPaths?.[e.field];if(n&&n.trim().length>0)return n;let r=e.fileName?.trim()||`${e.field}-${Date.now()}`;return C.resolve(t.meta?.cwd??process.cwd(),r)}async function Kt(e){let n=new URL(qt(e.baseUrl,e.artifactId)),r=n.protocol===`https:`?T:w;await S.promises.mkdir(C.dirname(e.destinationPath),{recursive:!0}),await new Promise((i,a)=>{let o=!1,s=e.timeoutMs??9e4,c=t=>{if(!o){if(o=!0,clearTimeout(u),t){S.promises.rm(e.destinationPath,{force:!0}).finally(()=>a(t));return}i()}},l=r.request({protocol:n.protocol,host:n.hostname,port:n.port,method:`GET`,path:n.pathname+n.search,headers:O(e.token)},n=>{if((n.statusCode??500)>=400){let r=``;n.setEncoding(`utf8`),n.on(`data`,e=>{r+=e}),n.on(`end`,()=>{c(new t(`COMMAND_FAILED`,`Failed to download remote artifact`,{artifactId:e.artifactId,statusCode:n.statusCode,requestId:e.requestId,body:r}))});return}n.on(`aborted`,()=>{c(new t(`COMMAND_FAILED`,`Remote artifact download was interrupted`,{artifactId:e.artifactId,requestId:e.requestId}))}),qe(n,S.createWriteStream(e.destinationPath)).then(()=>c(),e=>c(e instanceof Error?e:Error(String(e))))}),u=setTimeout(()=>{let n=new t(`COMMAND_FAILED`,`Remote artifact download timed out`,{artifactId:e.artifactId,requestId:e.requestId,timeoutMs:s});c(n),l.destroy(n)},s);l.on(`error`,n=>{if(n instanceof t){c(n);return}c(new t(`COMMAND_FAILED`,`Failed to download remote artifact`,{artifactId:e.artifactId,requestId:e.requestId,timeoutMs:s},n instanceof Error?n:void 0))}),l.end()})}function qt(e,t){let n=e.endsWith(`/`)?e:`${e}/`;return new URL(`artifacts/${encodeURIComponent(t)}`,n).toString()}function Jt(e){return typeof e.baseUrl==`string`&&e.baseUrl.length>0}const Yt=3e3,Xt=1e3;function N(e){let t=on(e);if(!t||typeof t!=`object`)return null;let n=t,r=Zt(n);if(!r)return null;let i=Qt(n);return i?{token:r,...i,transport:$t(n.transport),pid:F(n.pid)??0,version:P(n.version),codeSignature:P(n.codeSignature),processStartTime:P(n.processStartTime)}:null}function Zt(e){return typeof e.token==`string`&&e.token.length>0?e.token:null}function Qt(e){let t=F(e.port),n=F(e.httpPort);return t===void 0&&n===void 0?null:{port:t,httpPort:n}}function $t(e){return e===`socket`||e===`http`||e===`dual`?e:void 0}function P(e){return typeof e==`string`?e:void 0}function F(e){return Number.isInteger(e)&&Number(e)>0?Number(e):void 0}function I(e){let t=on(e);if(!t||typeof t!=`object`)return null;let n=t;return Number.isInteger(n.pid)&&Number(n.pid)>0?{pid:Number(n.pid),processStartTime:typeof n.processStartTime==`string`?n.processStartTime:void 0,startedAt:typeof n.startedAt==`number`?n.startedAt:void 0}:null}function L(e){sn(e)}function R(e){sn(e)}function en(e){let t=B(e);if(!t.hasLock||t.hasInfo)return;let n=I(e.lockPath);if(!n){R(e.lockPath);return}_(n.pid,n.processStartTime)||R(e.lockPath)}async function z(e,t,n={}){let r=n.stopLiveProcesses??!0,i={reason:t,removedInfo:!1,removedLock:!1,stoppedInfoProcess:!1,stoppedLockProcess:!1};try{let t=S.existsSync(e.infoPath),n=N(e.infoPath);if(n){let t=_(n.pid,n.processStartTime);t&&!r?i.retainedInfoProcess=!0:(t&&(await V(n),i.stoppedInfoProcess=!0),L(e.infoPath),i.removedInfo=!0)}else t&&(L(e.infoPath),i.removedInfo=!0);let a=S.existsSync(e.lockPath),o=I(e.lockPath);if(o){let t=_(o.pid,o.processStartTime);t&&!r?i.retainedLockProcess=!0:(t&&(await me(o.pid,{termTimeoutMs:Yt,killTimeoutMs:Xt,expectedStartTime:o.processStartTime}),i.stoppedLockProcess=!0),R(e.lockPath),i.removedLock=!0)}else a&&(R(e.lockPath),i.removedLock=!0)}catch(e){i.error=e instanceof Error?e.message:String(e)}return c({level:i.error?`warn`:`info`,phase:`daemon_startup_metadata_cleanup`,data:i}),i}function B(e){return{hasInfo:S.existsSync(e.infoPath),hasLock:S.existsSync(e.lockPath)}}async function tn(e){let t=B(e);if(!t.hasLock||t.hasInfo)return!1;let n=I(e.lockPath);return!n||!_(n.pid,n.processStartTime)?(R(e.lockPath),!0):!1}async function V(e){await me(e.pid,{termTimeoutMs:Yt,killTimeoutMs:Xt,expectedStartTime:e.processStartTime})}function nn(e){return typeof e.baseUrl==`string`&&e.baseUrl.length>0}function rn(e,t=g(process.env.AGENT_DEVICE_STATE_DIR)){let n=an(t);return e.hasLock&&!e.hasInfo?`agent-device attempted to clean stale daemon metadata automatically, but ${t.lockPath} still exists without ${t.infoPath}. Retry with --debug; if this persists after confirming no agent-device daemon process is running, run: ${n}`:e.hasLock&&e.hasInfo?`agent-device attempted to clean stale daemon metadata automatically, but ${t.infoPath} and ${t.lockPath} still remain. Retry with --debug; if this persists after confirming no agent-device daemon process is running, run: ${n}`:e.hasInfo?`agent-device did not observe reachable daemon metadata after retrying, and ${t.infoPath} still remains. Stale metadata was cleaned automatically when safe; retry with --debug. If this persists after confirming no agent-device daemon process is running, run: ${n}`:`agent-device did not observe reachable daemon metadata after retrying. Stale metadata was cleaned automatically when safe; retry with --debug and check daemon diagnostics logs. If stale metadata returns after confirming no agent-device daemon process is running, run: ${n}`}function an(e){return`rm -f ${oe(e.infoPath)} ${oe(e.lockPath)}`}function on(e){if(!S.existsSync(e))return null;try{return JSON.parse(S.readFileSync(e,`utf8`))}catch{return null}}function sn(e){try{S.existsSync(e)&&S.unlinkSync(e)}catch{}}function cn(e,t){if(t.onProgress){t.onProgress(e);return}e.type===`command`&&(t.req.command===`doctor`&&Ce(),process.stderr.write(`${e.message}\n`))}function H(e,n,r){return new t(`COMMAND_FAILED`,`Invalid daemon response`,{requestId:e.meta?.requestId,line:n},r instanceof Error?r:void 0)}function ln(e){let t=t=>(e.onError(t),!0);return{handleLine(n){let r;try{r=JSON.parse(n)}catch(r){return t(H(e.req,n,r))}if(ce(r))try{return cn(r.event,{req:e.req,onProgress:e.onProgress}),!1}catch(e){return t(e)}return fe(r)?(e.onResponse(r.response),!0):e.responseFormat===`socket-legacy`?(e.onResponse(r),!0):t(H(e.req,n,Error(`Missing daemon progress response envelope`)))}}}function un(e,t){return le(e)&&String(Array.isArray(t)?t.join(`,`):t??``).includes(`application/x-ndjson`)}function dn(e,t){let{req:n,isSettled:r,resolve:i,reject:a,clearTimeout:o}=t,s=``,c=ln({req:n,onProgress:t.onProgress,responseFormat:`socket-legacy`,onResponse(t){o(),i(t),e.end()},onError(e){o(),a(e)}});e.setEncoding(`utf8`),e.on(`data`,e=>{if(r())return;let t=se(s,e);s=t.buffer;for(let e of t.lines)if(c.handleLine(e))return})}function fn(e,n){let{req:r,handleResponseBody:i,reject:a,clearTimeout:o}=n,s=``,c=!1,l=ln({req:r,onProgress:n.onProgress,responseFormat:`ndjson-envelope`,onResponse(e){c=!0,o(),i(JSON.stringify(e))},onError(e){c=!0,o(),a(e)}});e.setEncoding(`utf8`),e.on(`data`,e=>{if(c)return;let t=se(s,e);s=t.buffer;for(let e of t.lines)if(e&&l.handleLine(e))return}),e.on(`end`,()=>{if(c)return;let e=s.trim();e&&l.handleLine(e)||(c=!0,o(),a(H(r,e)))}),e.on(`error`,e=>{c||(c=!0,o(),a(new t(`COMMAND_FAILED`,`Failed to read daemon response`,{requestId:r.meta?.requestId},e instanceof Error?e:void 0)))})}function pn(e,n){let{info:r,req:i,resolve:a,reject:o}=n;try{let n=mn(e);if(n.error){o(hn(n.error,i.meta?.requestId));return}if(!n.result||typeof n.result!=`object`){o(new t(`COMMAND_FAILED`,`Invalid daemon RPC response`,{requestId:i.meta?.requestId}));return}gn(r,i,n.result,a,o)}catch(n){o(new t(`COMMAND_FAILED`,`Invalid daemon response`,{requestId:i.meta?.requestId,line:e},n instanceof Error?n:void 0))}}function mn(e){return JSON.parse(e)}function hn(e,r){let i=e.data??{};return new t(n(i.code==null?void 0:String(i.code),`COMMAND_FAILED`),String(i.message??e.message??`Daemon RPC request failed`),{...typeof i.details==`object`&&i.details?i.details:{},hint:typeof i.hint==`string`?i.hint:void 0,diagnosticId:typeof i.diagnosticId==`string`?i.diagnosticId:void 0,logPath:typeof i.logPath==`string`?i.logPath:void 0,retriable:typeof i.retriable==`boolean`?i.retriable:void 0,supportedOn:typeof i.supportedOn==`string`?i.supportedOn:void 0,requestId:r})}async function gn(e,t,n,r,i){try{r(e.baseUrl&&n.ok?await Wt(e,t,n):n)}catch(e){i(e)}}function _n(e,t){let n=e.meta?.requestId??i();return vn(e.command)?{jsonrpc:`2.0`,id:n,method:yn(e.command),params:bn(e,e.command,t)}:{jsonrpc:`2.0`,id:n,method:`agent_device.command`,params:e}}function vn(e){return e===`lease_allocate`||e===`lease_heartbeat`||e===`lease_release`}function yn(e){switch(e){case`lease_allocate`:return`agent_device.lease.allocate`;case`lease_heartbeat`:return`agent_device.lease.heartbeat`;case`lease_release`:return`agent_device.lease.release`}}function bn(e,t,n){return p(f(e),t,{includeTokenParam:n.includeTokenParam,token:e.token,session:e.session})}const xn=[`xcodebuild .*AgentDeviceRunnerUITests/RunnerTests/testCommand`,`xcodebuild .*AgentDeviceRunner\\.env\\.session-`,`xcodebuild build-for-testing .*apple-runner/AgentDeviceRunner/AgentDeviceRunner\\.xcodeproj`];function Sn(e){let t=d(e.command);if(t.envelopeMs===`unbounded`)return;let n={...t,envelopeMs:t.envelopeMs};return Cn(n,e.positionals??[])??wn(n,e.flags)??n.envelopeMs}function Cn(e,t){if(e.budget.source!==`positional-parser`)return;let n=e.budget.parser(t);return n===null?void 0:En(e,n)}function wn(e,t){if(e.budget.source===`flag`)return e.budget.envelope===`widen`?Tn(e,e.budget,t):typeof t?.timeoutMs==`number`?t.timeoutMs:e.envelopeMs}function Tn(e,t,n){if(n?.settle!==!0)return e.envelopeMs;let r=typeof n.timeoutMs==`number`?n.timeoutMs:t.defaultBudgetMs;return typeof r==`number`?Dn(e,r):e.envelopeMs}function En(e,t){return Math.max(e.envelopeMs,t+Nn)}function Dn(e,t){return Math.max(e.envelopeMs,e.envelopeMs+t+Nn)}function On(e,n,r,i,a,o){let s=a?{terminated:0}:jn(),l=!a&&kn(i),u=l?Mn(e,n):{forcedKill:!1};return c({level:`error`,phase:`daemon_request_timeout`,data:{timeoutMs:o,requestId:r,command:i,timedOutRunnerPidsTerminated:s.terminated,timedOutRunnerCleanupError:s.error,daemonPidReset:l?e.pid:void 0,daemonPidForceKilled:l?u.forcedKill:void 0,daemonPreservedAfterTimeout:!a&&!l,daemonBaseUrl:e.baseUrl}}),new t(`COMMAND_FAILED`,`Daemon request timed out`,{timeoutMs:o,requestId:r,hint:An({remote:a,resetDaemon:l,command:i})})}function kn(e){return d(e).onTimeout===`reset-daemon`}function An(e){let{remote:t,resetDaemon:n,command:r}=e;if(t)return`Retry with --debug and verify the remote daemon URL, auth token, and remote host logs.`;if(!n){let e=r===m.snapshot?` If this was the first Apple-platform snapshot on the device, run agent-device prepare ios-runner with the same --platform before snapshot/test so runner startup is handled explicitly.`:``;return`Retry with --debug and check daemon diagnostics logs. The timed-out ${r??`request`} request was canceled and Apple runner work was aborted when detected; the daemon was kept alive so the session can still be closed or inspected.${e}`}return`Retry with --debug and check daemon diagnostics logs. Timed-out Apple runner xcodebuild processes were terminated when detected.`}function jn(){let e=0;try{for(let t of xn)a(`pkill`,[`-f`,t],{allowFailure:!0}).exitCode===0&&(e+=1);return{terminated:e}}catch(t){return{terminated:e,error:t instanceof Error?t.message:String(t)}}}function Mn(e,t){let n=!1;try{_(e.pid,e.processStartTime)&&(process.kill(e.pid,`SIGKILL`),n=!0)}catch{V(e)}finally{L(t.infoPath),R(t.lockPath)}return{forcedKill:n}}const Nn=3e4,Pn=`Daemon HTTP endpoint is unavailable`,Fn=`Daemon socket endpoint is unavailable`;async function In(e,t){let n=Gn(e,t);if(await Ln(e,n))return!0;let r=Kn(e,t,n);return r?await Ln(e,r):!1}async function Ln(e,t){return t===`http`?await zn(e):await Rn(e.port)}function Rn(e){return e?new Promise(t=>{let n=!1,r=E.createConnection({host:`127.0.0.1`,port:e},()=>{i(!0)}),i=e=>{n||(n=!0,r.destroy(),t(e))};r.setTimeout(500),r.on(`timeout`,()=>{i(!1)}),r.on(`error`,()=>{i(!1)})}):Promise.resolve(!1)}function zn(e){return Vn(e).then(e=>e.reachable)}async function Bn(e){let n=await Vn(e);if(!e.baseUrl||!n.reachable)return n;if(typeof n.rpcProtocolVersion==`number`&&n.rpcProtocolVersion!==1)throw new t(`COMMAND_FAILED`,`Remote daemon RPC protocol is incompatible`,{daemonBaseUrl:e.baseUrl,clientVersion:v(),remoteVersion:n.version,remoteService:n.service,supportedRpcProtocolVersion:1,remoteRpcProtocolVersion:n.rpcProtocolVersion,hint:`Upgrade agent-device on the client or remote host so both support the same daemon RPC protocol.`});return n}function Vn(e){let t=e.baseUrl?D(e.baseUrl,`health`):e.httpPort?`http://127.0.0.1:${e.httpPort}/health`:null;if(!t)return Promise.resolve({reachable:!1});let n=new URL(t),r=n.protocol===`https:`?T:w,i=e.baseUrl?3e3:500;return new Promise(t=>{let a=e.baseUrl?O(e.token):{},o=r.request({protocol:n.protocol,host:n.hostname,port:n.port,path:n.pathname+n.search,method:`GET`,timeout:i,headers:a},e=>{let n=``;e.setEncoding(`utf8`),e.on(`data`,e=>{n+=e}),e.on(`end`,()=>{let r=e.statusCode??500;t({reachable:r<500,statusCode:r,...Hn(n)})})});o.on(`timeout`,()=>{o.destroy(),t({reachable:!1})}),o.on(`error`,()=>{t({reachable:!1})}),o.end()})}function Hn(e){try{let t=JSON.parse(e);return{service:typeof t.service==`string`?t.service:void 0,version:typeof t.version==`string`?t.version:void 0,rpcProtocolVersion:typeof t.rpcProtocolVersion==`number`?t.rpcProtocolVersion:void 0}}catch{return{}}}async function Un(e,t,n,r,i,a={}){let o=Gn(e,n);try{return await Wn(e,t,r,i,o,a)}catch(s){let c=Kn(e,n,o);if(!c||!qn(s,o))throw s;return await Wn(e,t,r,i,c,a)}}async function Wn(e,t,n,r,i,a){return i===`http`?await Zn(e,t,n,r,a):await Xn(e,t,n,r,a)}function Gn(e,n){if(e.baseUrl){if(n===`socket`)throw new t(`COMMAND_FAILED`,`Remote daemon endpoint only supports HTTP transport`,{daemonBaseUrl:e.baseUrl});return`http`}if(n===`http`||n===`socket`)return Jn(e,n);let r=(e.transport===`socket`||e.transport===`dual`?[`socket`,`http`]:[`http`,`socket`]).find(t=>U(e,t));if(r)return r;throw new t(`COMMAND_FAILED`,`Daemon metadata has no reachable transport`)}function U(e,t){return t===`http`?!!e.httpPort:!!e.port}function Kn(e,t,n){if(t!==`auto`||e.baseUrl)return null;let r=n===`socket`?`http`:`socket`;return U(e,r)?r:null}function qn(e,n){return n===`socket`&&e instanceof t&&e.code===`COMMAND_FAILED`&&e.message===`Failed to communicate with daemon`&&e.details?.daemonSocketRequestWritten===!1}function Jn(e,n){if(U(e,n))return n;throw new t(`COMMAND_FAILED`,n===`http`?Pn:Fn)}function Yn(e,n,r,i={}){return c({level:`error`,phase:`daemon_request_socket_error`,data:{requestId:n,message:e instanceof Error?e.message:String(e)}}),new t(`COMMAND_FAILED`,`Failed to communicate with daemon`,{...i,requestId:n,hint:r?`Retry command. If this persists, verify the remote daemon URL, auth token, and remote host reachability.`:`Retry command. If this persists, clean stale daemon metadata and start a fresh session.`},e instanceof Error?e:void 0)}async function Xn(e,n,r,i,a){let o=e.port;if(!o)throw new t(`COMMAND_FAILED`,Fn);return new Promise((t,s)=>{let c=!1,l=E.createConnection({host:`127.0.0.1`,port:o},()=>{c=!0,l.write(`${JSON.stringify(n)}\n`)}),u=!1,d=typeof i==`number`?setTimeout(()=>{u=!0,l.destroy(),s(On(e,r,n.meta?.requestId,n.command,!1,i))},i):void 0;dn(l,{req:n,onProgress:a.onProgress,isSettled:()=>u,clearTimeout:()=>{d&&clearTimeout(d)},resolve:e=>{u=!0,t(e)},reject:e=>{u=!0,s(e)}}),l.on(`error`,e=>{u||(u=!0,d&&clearTimeout(d),s(Yn(e,n.meta?.requestId,!1,{daemonSocketRequestWritten:c})))})})}async function Zn(e,n,r,i,a){let o=e.baseUrl?new URL(D(e.baseUrl,`rpc`)):e.httpPort?new URL(`http://127.0.0.1:${e.httpPort}/rpc`):null;if(!o)throw new t(`COMMAND_FAILED`,Pn);let s=JSON.stringify(_n(n,{includeTokenParam:!e.baseUrl})),c={"content-type":`application/json`,"content-length":Buffer.byteLength(s)};return e.baseUrl&&Object.assign(c,O(e.token)),await new Promise((l,u)=>{let d=(o.protocol===`https:`?T:w).request({protocol:o.protocol,host:o.hostname,port:o.port,method:`POST`,path:o.pathname+o.search,headers:c},r=>{if(un(n,r.headers?.[`content-type`])){fn(r,{req:n,onProgress:a.onProgress,reject:u,clearTimeout:()=>{p&&clearTimeout(p)},handleResponseBody:t=>pn(t,{info:e,req:n,resolve:l,reject:u})});return}re(r).then(t=>{p&&clearTimeout(p),pn(t,{info:e,req:n,resolve:l,reject:u})}).catch(e=>{p&&clearTimeout(p),u(new t(`COMMAND_FAILED`,`Failed to read daemon response`,{requestId:n.meta?.requestId},e instanceof Error?e:void 0))})}),f=nn(e),p=typeof i==`number`?setTimeout(()=>{d.destroy(),u(On(e,r,n.meta?.requestId,n.command,f,i))},i):void 0;d.on(`error`,e=>{p&&clearTimeout(p),u(Yn(e,n.meta?.requestId,f))}),d.write(s),d.end()})}const W=15e3,G=new E.BlockList;G.addSubnet(`127.0.0.0`,8,`ipv4`),G.addAddress(`::1`,`ipv6`),G.addSubnet(`::ffff:127.0.0.0`,104,`ipv6`);function Qn(e){let t=$n(e),n=er(e),r=tr(e,n.remoteBaseUrl),i=nr(e,t,n.rawBaseUrl);return{paths:g(i?rr():t),transportPreference:r.preference,serverMode:r.serverMode,ownedStateDir:i,remoteBaseUrl:n.remoteBaseUrl,remoteAuthToken:n.authToken}}function $n(e){return e.flags?.stateDir??process.env.AGENT_DEVICE_STATE_DIR}function er(e){let t=e.flags?.daemonBaseUrl??process.env.AGENT_DEVICE_DAEMON_BASE_URL,n=xr(t),r=e.flags?.daemonAuthToken??process.env.AGENT_DEVICE_DAEMON_AUTH_TOKEN;return Sr(n,r),{rawBaseUrl:t,remoteBaseUrl:n,authToken:r}}function tr(e,n){let r=e.flags?.daemonTransport??process.env.AGENT_DEVICE_DAEMON_TRANSPORT,i=ie(r);if(n&&i===`socket`)throw new t(`INVALID_ARGS`,`Remote daemon base URL only supports HTTP transport. Remove --daemon-transport socket.`,{daemonBaseUrl:n});return{preference:i,serverMode:pe(e.flags?.daemonServerMode??process.env.AGENT_DEVICE_DAEMON_SERVER_MODE??(r===`dual`?`dual`:void 0))}}function nr(e,t,n){return mr(e.command)&&!t&&!n}function rr(){return S.mkdtempSync(C.join(Ke.tmpdir(),`agent-device-replay-daemon-`))}async function ir(e){if(e.remoteBaseUrl)return await ar(e);let t=await or(e);return t?{info:t,startedByClient:!1}:(en(e.paths),await fr(e))}async function ar(e){let n={transport:`http`,token:e.remoteAuthToken??``,pid:0,baseUrl:e.remoteBaseUrl};if((await Bn(n)).reachable)return{info:n,startedByClient:!1};throw new t(`COMMAND_FAILED`,`Remote daemon is unavailable`,{daemonBaseUrl:e.remoteBaseUrl,hint:`Verify AGENT_DEVICE_DAEMON_BASE_URL points to a reachable daemon with GET /health and POST /rpc. If this CLI was connected with connect proxy, run agent-device disconnect to return to the local daemon.`})}async function or(e){let t=N(e.paths.infoPath);if(!t)return null;let n=await sr(t,e.transportPreference);return lr(t,n)?t:(ur(t,n,e.paths.baseDir),await V(t),L(e.paths.infoPath),null)}async function sr(e,t){try{return await In(e,t)}catch(e){if(cr(e))return!1;throw e}}function cr(e){return e instanceof t&&e.code===`COMMAND_FAILED`&&(e.message===`Daemon HTTP endpoint is unavailable`||e.message===`Daemon socket endpoint is unavailable`)}function lr(e,t){return e.version===v()&&e.codeSignature===vr()&&t}function ur(e,t,n){try{let r=e.version?`pid ${e.pid}, v${e.version}`:`pid ${e.pid}`,i=dr(e,t);process.stderr.write(`Replacing daemon (${r}) in ${n}: ${i}\n`)}catch{}}function dr(e,t){return e.version===v()?e.codeSignature===vr()?t?`not reusable`:`unreachable`:`code-signature mismatch`:`version mismatch (client v${v()})`}async function fr(e){let n=0,r=[],i,a;for(let t=1;t<=2;t+=1){let o;try{o=gr(e),a={pid:o.pid}}catch(n){if(i=n instanceof Error?n.message:String(n),r.push(await z(e.paths,`start_error`)),t<2){await y(150);continue}break}let s=await hr(W,e,o);if(s.kind===`ready`)return{info:s.info,startedByClient:!0};if(s.kind===`early_exit`){if(a=s.exit,i=yr(s.exit),r.push(await z(e.paths,`start_error`)),t<2){await y(150);continue}break}if(await tn(e.paths)){n+=1;continue}let c=B(e.paths),l=t<2,u=await z(e.paths,`startup_timeout`,{stopLiveProcesses:!1});if(r.push(u),u.retainedInfoProcess||u.retainedLockProcess){let t=await hr(W,e,o);if(t.kind===`ready`)return{info:t.info,startedByClient:!0};t.kind===`early_exit`&&(a=t.exit,i=yr(t.exit));break}if(!l)break;!c.hasInfo&&!c.hasLock&&await y(150)}let o=B(e.paths),s=br(e.paths.logPath);throw new t(`COMMAND_FAILED`,`Failed to start daemon`,{kind:`daemon_startup_failed`,stateDir:e.paths.baseDir,infoPath:e.paths.infoPath,lockPath:e.paths.lockPath,logPath:e.paths.logPath,startupTimeoutMs:W,startupAttempts:2,lockRecoveryCount:n,cleanupResults:r,startError:i,daemonProcess:a,...s?{daemonLogTail:s}:{},metadataState:o,hint:rn(o,e.paths)})}async function pr(e,t,n){if(!mr(e.command)||!t.startedByClient&&!n.ownedStateDir||nn(t.info))return;let r={pid:t.info.pid,removedInfo:!1,removedLock:!1,removedStateDir:!1,error:void 0};try{await V(t.info)}catch(e){r.error=e instanceof Error?e.message:String(e)}finally{let e=S.existsSync(n.paths.infoPath);L(n.paths.infoPath),r.removedInfo=e&&!S.existsSync(n.paths.infoPath);let t=S.existsSync(n.paths.lockPath);R(n.paths.lockPath),r.removedLock=t&&!S.existsSync(n.paths.lockPath),n.ownedStateDir&&(S.rmSync(n.paths.baseDir,{recursive:!0,force:!0}),r.removedStateDir=!S.existsSync(n.paths.baseDir))}c({level:r.error?`warn`:`info`,phase:`daemon_replay_cleanup`,data:r})}function mr(e){return e===m.replay||e===m.test}async function hr(e,t,n){let r=Date.now(),i;for(n.exited.then(e=>{i=e});Date.now()-r<e;){if(i)return{kind:`early_exit`,exit:i};let e=N(t.paths.infoPath);if(e&&await In(e,t.transportPreference))return{kind:`ready`,info:e};if(i)return{kind:`early_exit`,exit:i};await y(100)}return{kind:`timeout`}}function gr(e){let t=_r(),n=t.useSrc?[`--experimental-strip-types`,t.srcPath]:[t.distPath],r={...process.env,AGENT_DEVICE_STATE_DIR:e.paths.baseDir,AGENT_DEVICE_DAEMON_SERVER_MODE:e.serverMode};S.mkdirSync(e.paths.baseDir,{recursive:!0});let i=S.openSync(e.paths.logPath,`a`),a=S.openSync(e.paths.logPath,`a`);try{return u(process.execPath,n,{env:r,stdio:[`ignore`,i,a]})}finally{S.closeSync(i),S.closeSync(a)}}function _r(){let e=he(),n=[C.join(e,`dist`,`src`,`internal`,`daemon.js`),C.join(e,`dist`,`src`,`daemon.js`)],r=n[0];if(r===void 0)throw new t(`COMMAND_FAILED`,`Daemon dist path list is empty`);let i=n.find(e=>S.existsSync(e))??r,a=C.join(e,`src`,`daemon.ts`),o=n.some(e=>S.existsSync(e)),s=S.existsSync(a);if(!o&&!s)throw new t(`COMMAND_FAILED`,`Daemon entry not found`,{distPaths:n,srcPath:a});return{root:e,distPath:i,distPaths:n,srcPath:a,useSrc:(process.execArgv.includes(`--experimental-strip-types`)||!o)&&s}}function vr(){let e=_r();return ae(e.useSrc?e.srcPath:e.distPath,e.root)}function yr(e){return e.error?`daemon process ${e.pid} failed to start: ${e.error}`:e.signal?`daemon process ${e.pid} exited before readiness with signal ${e.signal}`:`daemon process ${e.pid} exited before readiness with code ${e.exitCode??0}`}function br(e){try{if(!S.existsSync(e))return;let t=S.statSync(e);if(t.size<=0)return;let n=Math.min(t.size,64e3),r=S.openSync(e,`r`);try{let e=Buffer.alloc(n);S.readSync(r,e,0,n,t.size-n);let i=e.toString(`utf8`).trim();return i.length>0?i:void 0}finally{S.closeSync(r)}}catch{return}}function xr(e){if(!e)return;let n;try{n=new URL(e)}catch(n){throw new t(`INVALID_ARGS`,`Invalid daemon base URL`,{daemonBaseUrl:e},n instanceof Error?n:void 0)}if(n.protocol!==`http:`&&n.protocol!==`https:`)throw new t(`INVALID_ARGS`,`Daemon base URL must use http or https`,{daemonBaseUrl:e});return n.toString().replace(/\/+$/,``)}function Sr(e,n){if(!e)return;let r=new URL(e).hostname;if(!Cr(r)&&!(typeof n==`string`&&n.trim().length>0))throw new t(`INVALID_ARGS`,`Remote daemon base URL for non-loopback hosts requires daemon authentication`,{daemonBaseUrl:e,hint:`Provide --daemon-auth-token or AGENT_DEVICE_DAEMON_AUTH_TOKEN when using a non-loopback remote daemon URL.`})}function Cr(e){let t=e.trim().toLowerCase().replace(/^\[(.*)\]$/,`$1`);return t===`localhost`?!0:E.isIPv4(t)?G.check(t,`ipv4`):E.isIPv6(t)?G.check(t,`ipv6`):!1}async function wr(e,t={}){let n=e.meta?.requestId??i(),r=!!(e.meta?.debug||e.flags?.verbose),a=Qn(e),s=Sn(e),l=await o(`daemon_startup`,async()=>await ir(a),{requestId:n,session:e.session}),u=l.info,d=await Mt(e,u);Tr(e.command);let f={...e,positionals:d.positionals,flags:d.flags,token:u.token,meta:{...e.meta??{},requestId:n,debug:r,includeCost:e.meta?.includeCost,cwd:e.meta?.cwd,sessionExplicit:e.meta?.sessionExplicit,tenantId:e.meta?.tenantId??e.flags?.tenant,runId:e.meta?.runId??e.flags?.runId,leaseId:e.meta?.leaseId??e.flags?.leaseId,sessionIsolation:e.meta?.sessionIsolation??e.flags?.sessionIsolation,lockPolicy:e.meta?.lockPolicy,lockPlatform:e.meta?.lockPlatform,...d.uploadedArtifactId?{uploadedArtifactId:d.uploadedArtifactId}:{},...d.clientArtifactPaths?{clientArtifactPaths:d.clientArtifactPaths}:{},...d.installSource?{installSource:d.installSource}:{}}};c({level:`info`,phase:`daemon_request_prepare`,data:{requestId:n,command:e.command,session:e.session}});try{return await o(`daemon_request`,async()=>await Un(u,f,a.transportPreference,a.paths,s,t),{requestId:n,command:e.command})}finally{await pr(e,l,a)}}function Tr(e){!Er(e)||process.stderr.isTTY!==!0||process.env.CI||process.stderr.write(e===m.reinstall?`Reinstalling...
|
|
1
|
+
import{t as e}from"./rolldown-runtime.js";import{_ as t,a as n,w as r}from"./sdk-contracts.js";import{A as i,C as a,F as o,b as s,j as c,v as l,x as u}from"./sdk-android-adb.js";import{g as d}from"./sdk-batch.js";import{Nn as f,On as p,Xn as m,Yn as h,fn as ee}from"./tv-remote.js";import{i as te,n as ne}from"./output-path.js";import{C as g,O as re,T as ie,b as ae,g as oe,h as se,l as ce,m as le,n as ue,s as de,u as fe,v as _,w as pe,y as me}from"./snapshot-diagnostics.js";import{n as v,t as he}from"./version.js";import{n as ge}from"./path-resolution.js";import{t as y}from"./timeouts.js";import{u as _e}from"./host-process.js";import{A as ve,C as ye,D as be,E as xe,O as Se,P as Ce,S as we,T as Te,b as Ee,d as De,f as Oe,i as ke,k as Ae,p as je,s as Me,w as Ne,x as Pe,y as Fe}from"./registry.js";import{l as Ie,m as b,v as x}from"./sdk-batch-runner.js";import{n as Le,t as Re}from"./url.js";import{t as ze}from"./client-metro-companion.js";import{n as Be,r as Ve}from"./project-runtime.js";import{t as He}from"./runtime-transport.js";import{t as Ue}from"./command-metadata.js";import{createHash as We,randomUUID as Ge}from"node:crypto";import S from"node:fs";import Ke from"node:os";import C from"node:path";import w from"node:http";import T from"node:https";import{pipeline as qe}from"node:stream/promises";import{Transform as Je,Writable as Ye}from"node:stream";import E from"node:net";const Xe=`/agent-device`;function Ze(e){return D(e,Xe)}function D(e,t){let n=e.endsWith(`/`)?e:`${e}/`;return new URL(t.replace(/^\/+/,``),n).toString()}function O(e){let t=e?.trim();return t?{authorization:`Bearer ${t}`,"x-agent-device-token":t}:{}}async function Qe(e,t){let n=S.statSync(e),r=C.basename(e),i=n.isDirectory(),a=tt(t)??et(e,n),o=[];try{let t=i?await $e(e,o):e,n=S.statSync(t);return{payloadPath:t,fileName:r,artifactType:i?`app-bundle`:`file`,platform:a,contentType:i?`application/gzip`:`application/octet-stream`,sha256:await rt(t),sizeBytes:n.size,cleanup:()=>nt(o)}}catch(e){throw nt(o),e}}async function $e(e,t){let n=S.mkdtempSync(C.join(Ke.tmpdir(),`agent-device-upload-${Ge()}-`));t.push(n);let r=C.join(n,`${C.basename(e)}.tar.gz`);return await l(`tar`,[`czf`,r,`-C`,C.dirname(e),C.basename(e)],{env:{...process.env,COPYFILE_DISABLE:`1`}}),r}function et(e,t){let n=e.toLowerCase();if(t.isDirectory()&&n.endsWith(`.app`)||n.endsWith(`.ipa`))return`ios`;if(n.endsWith(`.apk`)||n.endsWith(`.aab`))return`android`}function tt(e){return e===`ios`||e===`android`?e:void 0}function nt(e){for(let t of e)S.rmSync(t,{recursive:!0,force:!0})}async function rt(e){let n=We(`sha256`),r=new Ye({write(e,t,r){n.update(e),r()}});return await qe(S.createReadStream(e),r).catch(e=>{throw new t(`COMMAND_FAILED`,`Failed to read local artifact`,{},e instanceof Error?e:void 0)}),n.digest(`hex`)}function it(e){let{stage:t,fileName:n,startOffset:r,totalBytes:i,onProgress:a}=e,o=r,s=st(i),c=Math.min(i,r+s);return new Je({transform(e,r,l){o=Math.min(i,o+e.byteLength),o>=c&&(a?.({type:`progress`,stage:t,fileName:n,transferredBytes:o,totalBytes:i}),c=Math.min(i,o+s)),l(null,e)}})}function at(){if(!(process.stderr.isTTY!==!0||process.env.CI))return e=>{process.stderr.write(`${ot(e)}\n`)}}function ot(e){switch(e.type){case`start`:return`Uploading ${e.fileName} (${k(e.totalBytes)}) via ${ct(e.stage)} upload`;case`resume`:return`Resuming ${e.fileName} at ${k(e.transferredBytes)} of ${k(e.totalBytes)}`;case`progress`:return`Uploaded ${k(e.transferredBytes)} of ${k(e.totalBytes)} (${lt(e.transferredBytes,e.totalBytes)})`;case`fallback`:return`Direct upload did not complete; retrying ${e.fileName} with ${ct(e.to)} upload`}}function st(e){return Math.max(8388608,Math.ceil(e*.05))}function ct(e){return e===`direct`?`direct`:`legacy`}function lt(e,t){return t<=0?`100%`:`${Math.min(100,Math.floor(e/t*100))}%`}function k(e){if(e<1024)return`${e} B`;let t=e/1024;if(t<1024)return`${t.toFixed(1)} KiB`;let n=t/1024;return n<1024?`${n.toFixed(1)} MiB`:`${(n/1024).toFixed(1)} GiB`}const ut=300*1e3,dt=`uploadStreamRetryable`;async function ft(e){return await A({...e,url:e.url,redirectCount:0,startOffset:0})}function pt(e){return e instanceof t&&e.details?.[dt]===!0}async function A(e){let n=e.url.protocol===`https:`?T:w,r=S.statSync(e.payloadPath).size,i=gt(e.headers,e.startOffset,r);return ht(e.progress,e.startOffset,r),await new Promise((a,o)=>{let s=!1,c=n.request({protocol:e.url.protocol,host:e.url.hostname,port:e.url.port,method:e.method,path:e.url.pathname+e.url.search,headers:i},n=>{s=!0,re(n).then(i=>{clearTimeout(l);let s=n.statusCode??500,c=n.headers.location;if(c&&_t(s)){if(e.redirectCount>=5){o(new t(`COMMAND_FAILED`,`Artifact upload exceeded redirect limit`,{maxRedirects:5,url:e.url.toString()}));return}let n=new URL(c,e.url);A({...e,url:n,redirectCount:e.redirectCount+1}).then(a,o);return}let u=vt(s)?yt(n.headers,r):void 0;if(u!==void 0){if(u>=r){a({statusCode:200,statusMessage:`Upload already complete`,body:``});return}if(u<=e.startOffset){o(new t(`COMMAND_FAILED`,`Artifact upload resume did not advance`,{offset:u,previousOffset:e.startOffset,url:e.url.toString()}));return}A({...e,startOffset:u}).then(a,o);return}a({statusCode:s,statusMessage:n.statusMessage,body:i})}).catch(o)}),l=setTimeout(()=>{c.destroy(),o(new t(`COMMAND_FAILED`,e.timeoutMessage,{timeoutMs:ut,...e.timeoutHint?{hint:e.timeoutHint}:{},...mt(e)}))},ut);c.on(`error`,n=>{s||(clearTimeout(l),o(new t(`COMMAND_FAILED`,e.errorMessage,{...e.errorHint?{hint:e.errorHint}:{},...mt(e)},n)))}),c.on(`close`,()=>clearTimeout(l)),qe(S.createReadStream(e.payloadPath,{start:e.startOffset}),it({stage:e.progress?.stage??`legacy`,fileName:e.progress?.fileName??C.basename(e.payloadPath),startOffset:e.startOffset,totalBytes:r,onProgress:e.progress?.onProgress}),c).catch(e=>{s||(c.destroy(),o(new t(`COMMAND_FAILED`,`Failed to read local artifact`,{},e instanceof Error?e:Error(String(e)))))})})}function mt(e){return e.retryable===!0?{[dt]:!0}:{}}function ht(e,t,n){e?.onProgress?.({type:t>0?`resume`:`start`,stage:e.stage,fileName:e.fileName,transferredBytes:t,totalBytes:n})}function gt(e,t,n){return t<=0?e:{...e,"content-length":Math.max(n-t,0),"content-range":`bytes ${t}-${n-1}/${n}`}}function _t(e){return[301,302,303,307,308].includes(e)}function vt(e){return e===308}function yt(e,t){let n=bt(e[`x-upload-offset`]??e[`upload-offset`]);if(n!==void 0)return Math.min(n,t);let r=xt(e.range)?.match(/^bytes=0-(\d+)$/);if(!r)return;let i=Number(r[1]);if(!(!Number.isSafeInteger(i)||i<0))return Math.min(i+1,t)}function bt(e){let t=xt(e);if(t===void 0)return;let n=Number(t);return Number.isSafeInteger(n)&&n>=0?n:void 0}function xt(e){return Array.isArray(e)?e[0]:e}const St=30*1e3;async function Ct(e){let t=await Qe(e.localPath,e.platform),n=e.baseUrl.endsWith(`/`)?e.baseUrl:`${e.baseUrl}/`,r=Ge();try{let i=await Dt({normalizedBase:n,token:e.token,artifact:t,uploadAttemptId:r});return i?.kind===`cache-hit`?i.uploadId:i?.kind===`direct-upload`?await wt({normalizedBase:n,token:e.token,artifact:t,preflight:i,uploadAttemptId:r,onProgress:e.onProgress})||(e.onProgress?.({type:`fallback`,from:`direct`,to:`legacy`,fileName:t.fileName}),await Et({normalizedBase:n,token:e.token,artifact:t,onProgress:e.onProgress})):await Et({normalizedBase:n,token:e.token,artifact:t,onProgress:e.onProgress})}finally{t.cleanup()}}async function wt(e){let t=async t=>(await At(e.artifact,t,e.onProgress),await jt({normalizedBase:e.normalizedBase,token:e.token,uploadId:t.uploadId}));try{return await t(e.preflight)}catch(n){if(!Tt(n))return;let r=await Dt({normalizedBase:e.normalizedBase,token:e.token,artifact:e.artifact,uploadAttemptId:e.uploadAttemptId});if(r?.kind===`cache-hit`)return r.uploadId;if(r?.kind===`direct-upload`)try{return await t(r)}catch{return}return}}function Tt(e){return e instanceof t?pt(e):!0}async function Et(e){let{normalizedBase:n,token:r,artifact:i}=e,a=new URL(`upload`,n),o={"content-type":i.contentType,"x-artifact-type":i.artifactType,"x-artifact-filename":i.fileName,"x-artifact-hash":i.sha256,"x-artifact-hash-algorithm":`sha256`,"transfer-encoding":`chunked`};Object.assign(o,O(r));let s=await ft({url:a,method:`POST`,headers:o,payloadPath:i.payloadPath,timeoutMessage:`Artifact upload timed out`,timeoutHint:`The upload to the remote daemon exceeded the 5-minute timeout.`,errorMessage:`Failed to upload artifact to remote daemon`,errorHint:`Verify the remote daemon is reachable and supports artifact uploads.`,progress:{stage:`legacy`,fileName:i.fileName,onProgress:e.onProgress}});try{let e=JSON.parse(s.body);if(!e.ok||!e.uploadId)throw new t(`COMMAND_FAILED`,`Upload failed: ${s.body}`);return e.uploadId}catch(e){throw e instanceof t?e:new t(`COMMAND_FAILED`,`Invalid upload response: ${s.body}`)}}async function Dt(e){let t=new URL(`upload/preflight`,e.normalizedBase),n={"content-type":`application/json`};Object.assign(n,O(e.token));let r=await fetch(t,{method:`POST`,headers:n,signal:AbortSignal.timeout(St),body:JSON.stringify({uploadAttemptId:e.uploadAttemptId,sha256:e.artifact.sha256,fileName:e.artifact.fileName,sizeBytes:e.artifact.sizeBytes,artifactType:e.artifact.artifactType,...e.artifact.platform?{platform:e.artifact.platform}:{},contentType:e.artifact.contentType})}).catch(()=>void 0);if(r?.ok)return Ot(await r.json().catch(()=>void 0))}function Ot(e){if(!e||typeof e!=`object`)return;let t=e;if(t.ok!==!0||typeof t.uploadId!=`string`)return;if(t.cacheHit===!0)return{kind:`cache-hit`,uploadId:t.uploadId};let n=t.upload;if(!n||typeof n.url!=`string`)return;let r=n.headers??{};if(kt(r))return{kind:`direct-upload`,uploadId:t.uploadId,url:n.url,headers:r}}function kt(e){return!e||typeof e!=`object`||Array.isArray(e)?!1:Object.values(e).every(e=>typeof e==`string`)}async function At(e,n,r){let i=await ft({url:new URL(n.url),method:`PUT`,headers:n.headers,payloadPath:e.payloadPath,timeoutMessage:`Direct artifact upload timed out`,timeoutHint:`The direct upload ticket did not accept the artifact within the timeout.`,errorMessage:`Failed to upload artifact with direct upload ticket`,retryable:!0,progress:{stage:`direct`,fileName:e.fileName,onProgress:r}});if(i.statusCode<200||i.statusCode>=300)throw new t(`COMMAND_FAILED`,`Direct artifact upload failed`,{statusCode:i.statusCode,statusMessage:i.statusMessage})}async function jt(e){let n=new URL(`upload/finalize`,e.normalizedBase),r={"content-type":`application/json`};Object.assign(r,O(e.token));let i=await fetch(n,{method:`POST`,headers:r,signal:AbortSignal.timeout(St),body:JSON.stringify({uploadId:e.uploadId})}).catch(e=>{throw new t(`COMMAND_FAILED`,`Failed to finalize direct artifact upload`,{},e)});if(!i.ok)throw new t(`COMMAND_FAILED`,`Direct artifact upload finalize failed`,{status:i.status,statusText:i.statusText});let a=await i.json().catch(()=>void 0);if(!a?.ok||!a.uploadId)throw new t(`COMMAND_FAILED`,`Invalid upload finalize response`);return a.uploadId}async function Mt(e,t){let n=[...e.positionals??[]],r=e.flags?{...e.flags}:void 0,i=e.meta?.installSource,a={},o,s=at();if(!Jt(t))return Lt({positionals:n,flags:r,installSource:i,uploadedArtifactId:o,clientArtifactPaths:a});r=Pt(e,n,r,a);let c=await Rt(e,t,s);return c&&(i=c.installSource,o=c.uploadedArtifactId??o),e.command!==`install`&&e.command!==`reinstall`||(o=await Nt(e,t,n,s)??o),Lt({positionals:n,flags:r,installSource:i,uploadedArtifactId:o,clientArtifactPaths:a})}async function Nt(e,t,n,r){let i=n.length===1?0:1,a=n[i];if(a===void 0)return;if(a.startsWith(`remote:`)){n[i]=a.slice(7);return}let o=It(a,e.meta?.cwd);if(o)return await Ct({localPath:o,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform,onProgress:r})}function Pt(e,t,n,r){let i=zt(e,t);if(!i)return n;i.positionalPath!==void 0&&(t[i.positionalIndex]=i.positionalPath);let a=Ft(n,i.flagPath);return r[i.field]=i.localPath,a}function Ft(e,t){return t===void 0?e:{...e??{},out:t}}function It(e,t){let n=C.isAbsolute(e)?e:C.resolve(t??process.cwd(),e);return S.existsSync(n)?n:void 0}function Lt(e){return{positionals:e.positionals,flags:e.flags,installSource:e.installSource,uploadedArtifactId:e.uploadedArtifactId,...Object.keys(e.clientArtifactPaths).length>0?{clientArtifactPaths:e.clientArtifactPaths}:{}}}async function Rt(e,t,n){let r=e.meta?.installSource;if(e.command!==`install_source`||!r||r.kind!==`path`)return null;let i=r.path.trim();if(!i)return{installSource:r};if(i.startsWith(`remote:`))return{installSource:{...r,path:i.slice(7)}};let a=C.isAbsolute(i)?i:C.resolve(e.meta?.cwd??process.cwd(),i);if(!S.existsSync(a))return{installSource:{...r,path:a}};let o=await Ct({localPath:a,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform,onProgress:n});return{installSource:{...r,path:a},uploadedArtifactId:o}}function zt(e,t){if(e.command===`screenshot`){let n=Ut(e,`path`,`.png`);return t[0]?{field:`path`,localPath:n,positionalIndex:0,positionalPath:M(`screenshot`,`.png`)}:{field:`path`,localPath:n,positionalIndex:0,flagPath:M(`screenshot`,`.png`)}}if(e.command===`record`&&(t[0]??``).toLowerCase()===`start`){if(!Vt(e)&&e.flags?.platform===void 0)return null;let t=Bt(e),n=Ht(Ut(e,`outPath`,t,1),e);return{field:`outPath`,localPath:n,positionalIndex:1,positionalPath:M(`recording`,C.extname(n)||t)}}return null}function Bt(e){return te(e.flags?.platform)}function Vt(e){return j(e.positionals?.[1])||j(e.flags?.out)}function Ht(e,t){return t.flags?.platform===`web`?ne(e,Bt(t)):e}function Ut(e,t,n,r=0){let i=e.positionals?.[r]??e.flags?.out,a=`${t===`path`?`screenshot`:`recording`}-${Date.now()}${n}`,o=j(i)?i:a;return C.isAbsolute(o)?o:C.resolve(e.meta?.cwd??process.cwd(),o)}function j(e){return typeof e==`string`&&e.trim().length>0}function M(e,t){let n=t.startsWith(`.`)?t:`.${t}`;return C.posix.join(`/tmp`,`agent-device-${e}-${Date.now()}-${Math.random().toString(36).slice(2,8)}${n}`)}async function Wt(e,t,n){let r=Array.isArray(n.data?.artifacts)?n.data.artifacts:[];if(r.length===0||!e.baseUrl)return n;let i=n.data?{...n.data}:{},a=[];for(let n of r){if(!n||typeof n!=`object`||typeof n.artifactId!=`string`){a.push(n);continue}let r=Gt(n,t);await Kt({baseUrl:e.baseUrl,token:e.token,artifactId:n.artifactId,destinationPath:r,requestId:t.meta?.requestId}),i[n.field]=r,a.push({...n,localPath:r})}return i.artifacts=a,{ok:!0,data:i}}function Gt(e,t){if(e.localPath&&e.localPath.trim().length>0)return e.localPath;let n=t.meta?.clientArtifactPaths?.[e.field];if(n&&n.trim().length>0)return n;let r=e.fileName?.trim()||`${e.field}-${Date.now()}`;return C.resolve(t.meta?.cwd??process.cwd(),r)}async function Kt(e){let n=new URL(qt(e.baseUrl,e.artifactId)),r=n.protocol===`https:`?T:w;await S.promises.mkdir(C.dirname(e.destinationPath),{recursive:!0}),await new Promise((i,a)=>{let o=!1,s=e.timeoutMs??9e4,c=t=>{if(!o){if(o=!0,clearTimeout(u),t){S.promises.rm(e.destinationPath,{force:!0}).finally(()=>a(t));return}i()}},l=r.request({protocol:n.protocol,host:n.hostname,port:n.port,method:`GET`,path:n.pathname+n.search,headers:O(e.token)},n=>{if((n.statusCode??500)>=400){let r=``;n.setEncoding(`utf8`),n.on(`data`,e=>{r+=e}),n.on(`end`,()=>{c(new t(`COMMAND_FAILED`,`Failed to download remote artifact`,{artifactId:e.artifactId,statusCode:n.statusCode,requestId:e.requestId,body:r}))});return}n.on(`aborted`,()=>{c(new t(`COMMAND_FAILED`,`Remote artifact download was interrupted`,{artifactId:e.artifactId,requestId:e.requestId}))}),qe(n,S.createWriteStream(e.destinationPath)).then(()=>c(),e=>c(e instanceof Error?e:Error(String(e))))}),u=setTimeout(()=>{let n=new t(`COMMAND_FAILED`,`Remote artifact download timed out`,{artifactId:e.artifactId,requestId:e.requestId,timeoutMs:s});c(n),l.destroy(n)},s);l.on(`error`,n=>{if(n instanceof t){c(n);return}c(new t(`COMMAND_FAILED`,`Failed to download remote artifact`,{artifactId:e.artifactId,requestId:e.requestId,timeoutMs:s},n instanceof Error?n:void 0))}),l.end()})}function qt(e,t){let n=e.endsWith(`/`)?e:`${e}/`;return new URL(`artifacts/${encodeURIComponent(t)}`,n).toString()}function Jt(e){return typeof e.baseUrl==`string`&&e.baseUrl.length>0}const Yt=3e3,Xt=1e3;function N(e){let t=on(e);if(!t||typeof t!=`object`)return null;let n=t,r=Zt(n);if(!r)return null;let i=Qt(n);return i?{token:r,...i,transport:$t(n.transport),pid:F(n.pid)??0,version:P(n.version),codeSignature:P(n.codeSignature),processStartTime:P(n.processStartTime)}:null}function Zt(e){return typeof e.token==`string`&&e.token.length>0?e.token:null}function Qt(e){let t=F(e.port),n=F(e.httpPort);return t===void 0&&n===void 0?null:{port:t,httpPort:n}}function $t(e){return e===`socket`||e===`http`||e===`dual`?e:void 0}function P(e){return typeof e==`string`?e:void 0}function F(e){return Number.isInteger(e)&&Number(e)>0?Number(e):void 0}function I(e){let t=on(e);if(!t||typeof t!=`object`)return null;let n=t;return Number.isInteger(n.pid)&&Number(n.pid)>0?{pid:Number(n.pid),processStartTime:typeof n.processStartTime==`string`?n.processStartTime:void 0,startedAt:typeof n.startedAt==`number`?n.startedAt:void 0}:null}function L(e){sn(e)}function R(e){sn(e)}function en(e){let t=B(e);if(!t.hasLock||t.hasInfo)return;let n=I(e.lockPath);if(!n){R(e.lockPath);return}_(n.pid,n.processStartTime)||R(e.lockPath)}async function z(e,t,n={}){let r=n.stopLiveProcesses??!0,i={reason:t,removedInfo:!1,removedLock:!1,stoppedInfoProcess:!1,stoppedLockProcess:!1};try{let t=S.existsSync(e.infoPath),n=N(e.infoPath);if(n){let t=_(n.pid,n.processStartTime);t&&!r?i.retainedInfoProcess=!0:(t&&(await V(n),i.stoppedInfoProcess=!0),L(e.infoPath),i.removedInfo=!0)}else t&&(L(e.infoPath),i.removedInfo=!0);let a=S.existsSync(e.lockPath),o=I(e.lockPath);if(o){let t=_(o.pid,o.processStartTime);t&&!r?i.retainedLockProcess=!0:(t&&(await me(o.pid,{termTimeoutMs:Yt,killTimeoutMs:Xt,expectedStartTime:o.processStartTime}),i.stoppedLockProcess=!0),R(e.lockPath),i.removedLock=!0)}else a&&(R(e.lockPath),i.removedLock=!0)}catch(e){i.error=e instanceof Error?e.message:String(e)}return c({level:i.error?`warn`:`info`,phase:`daemon_startup_metadata_cleanup`,data:i}),i}function B(e){return{hasInfo:S.existsSync(e.infoPath),hasLock:S.existsSync(e.lockPath)}}async function tn(e){let t=B(e);if(!t.hasLock||t.hasInfo)return!1;let n=I(e.lockPath);return!n||!_(n.pid,n.processStartTime)?(R(e.lockPath),!0):!1}async function V(e){await me(e.pid,{termTimeoutMs:Yt,killTimeoutMs:Xt,expectedStartTime:e.processStartTime})}function nn(e){return typeof e.baseUrl==`string`&&e.baseUrl.length>0}function rn(e,t=g(process.env.AGENT_DEVICE_STATE_DIR)){let n=an(t);return e.hasLock&&!e.hasInfo?`agent-device attempted to clean stale daemon metadata automatically, but ${t.lockPath} still exists without ${t.infoPath}. Retry with --debug; if this persists after confirming no agent-device daemon process is running, run: ${n}`:e.hasLock&&e.hasInfo?`agent-device attempted to clean stale daemon metadata automatically, but ${t.infoPath} and ${t.lockPath} still remain. Retry with --debug; if this persists after confirming no agent-device daemon process is running, run: ${n}`:e.hasInfo?`agent-device did not observe reachable daemon metadata after retrying, and ${t.infoPath} still remains. Stale metadata was cleaned automatically when safe; retry with --debug. If this persists after confirming no agent-device daemon process is running, run: ${n}`:`agent-device did not observe reachable daemon metadata after retrying. Stale metadata was cleaned automatically when safe; retry with --debug and check daemon diagnostics logs. If stale metadata returns after confirming no agent-device daemon process is running, run: ${n}`}function an(e){return`rm -f ${oe(e.infoPath)} ${oe(e.lockPath)}`}function on(e){if(!S.existsSync(e))return null;try{return JSON.parse(S.readFileSync(e,`utf8`))}catch{return null}}function sn(e){try{S.existsSync(e)&&S.unlinkSync(e)}catch{}}function cn(e,t){if(t.onProgress){t.onProgress(e);return}e.type===`command`&&(t.req.command===`doctor`&&Ce(),process.stderr.write(`${e.message}\n`))}function H(e,n,r){return new t(`COMMAND_FAILED`,`Invalid daemon response`,{requestId:e.meta?.requestId,line:n},r instanceof Error?r:void 0)}function ln(e){let t=t=>(e.onError(t),!0);return{handleLine(n){let r;try{r=JSON.parse(n)}catch(r){return t(H(e.req,n,r))}if(ce(r))try{return cn(r.event,{req:e.req,onProgress:e.onProgress}),!1}catch(e){return t(e)}return fe(r)?(e.onResponse(r.response),!0):e.responseFormat===`socket-legacy`?(e.onResponse(r),!0):t(H(e.req,n,Error(`Missing daemon progress response envelope`)))}}}function un(e,t){return le(e)&&String(Array.isArray(t)?t.join(`,`):t??``).includes(`application/x-ndjson`)}function dn(e,t){let{req:n,isSettled:r,resolve:i,reject:a,clearTimeout:o}=t,s=``,c=ln({req:n,onProgress:t.onProgress,responseFormat:`socket-legacy`,onResponse(t){o(),i(t),e.end()},onError(e){o(),a(e)}});e.setEncoding(`utf8`),e.on(`data`,e=>{if(r())return;let t=se(s,e);s=t.buffer;for(let e of t.lines)if(c.handleLine(e))return})}function fn(e,n){let{req:r,handleResponseBody:i,reject:a,clearTimeout:o}=n,s=``,c=!1,l=ln({req:r,onProgress:n.onProgress,responseFormat:`ndjson-envelope`,onResponse(e){c=!0,o(),i(JSON.stringify(e))},onError(e){c=!0,o(),a(e)}});e.setEncoding(`utf8`),e.on(`data`,e=>{if(c)return;let t=se(s,e);s=t.buffer;for(let e of t.lines)if(e&&l.handleLine(e))return}),e.on(`end`,()=>{if(c)return;let e=s.trim();e&&l.handleLine(e)||(c=!0,o(),a(H(r,e)))}),e.on(`error`,e=>{c||(c=!0,o(),a(new t(`COMMAND_FAILED`,`Failed to read daemon response`,{requestId:r.meta?.requestId},e instanceof Error?e:void 0)))})}function pn(e,n){let{info:r,req:i,resolve:a,reject:o}=n;try{let n=mn(e);if(n.error){o(hn(n.error,i.meta?.requestId));return}if(!n.result||typeof n.result!=`object`){o(new t(`COMMAND_FAILED`,`Invalid daemon RPC response`,{requestId:i.meta?.requestId}));return}gn(r,i,n.result,a,o)}catch(n){o(new t(`COMMAND_FAILED`,`Invalid daemon response`,{requestId:i.meta?.requestId,line:e},n instanceof Error?n:void 0))}}function mn(e){return JSON.parse(e)}function hn(e,n){let i=e.data??{};return new t(r(i.code==null?void 0:String(i.code),`COMMAND_FAILED`),String(i.message??e.message??`Daemon RPC request failed`),{...typeof i.details==`object`&&i.details?i.details:{},hint:typeof i.hint==`string`?i.hint:void 0,diagnosticId:typeof i.diagnosticId==`string`?i.diagnosticId:void 0,logPath:typeof i.logPath==`string`?i.logPath:void 0,retriable:typeof i.retriable==`boolean`?i.retriable:void 0,supportedOn:typeof i.supportedOn==`string`?i.supportedOn:void 0,requestId:n})}async function gn(e,t,n,r,i){try{r(e.baseUrl&&n.ok?await Wt(e,t,n):n)}catch(e){i(e)}}function _n(e,t){let n=e.meta?.requestId??i();return vn(e.command)?{jsonrpc:`2.0`,id:n,method:yn(e.command),params:bn(e,e.command,t)}:{jsonrpc:`2.0`,id:n,method:`agent_device.command`,params:e}}function vn(e){return e===`lease_allocate`||e===`lease_heartbeat`||e===`lease_release`}function yn(e){switch(e){case`lease_allocate`:return`agent_device.lease.allocate`;case`lease_heartbeat`:return`agent_device.lease.heartbeat`;case`lease_release`:return`agent_device.lease.release`}}function bn(e,t,n){return f(p(e),t,{includeTokenParam:n.includeTokenParam,token:e.token,session:e.session})}const xn=[`xcodebuild .*AgentDeviceRunnerUITests/RunnerTests/testCommand`,`xcodebuild .*AgentDeviceRunner\\.env\\.session-`,`xcodebuild build-for-testing .*apple-runner/AgentDeviceRunner/AgentDeviceRunner\\.xcodeproj`];function Sn(e){let t=d(e.command);if(t.envelopeMs===`unbounded`)return;let n={...t,envelopeMs:t.envelopeMs};return Cn(n,e.positionals??[])??wn(n,e.flags)??n.envelopeMs}function Cn(e,t){if(e.budget.source!==`positional-parser`)return;let n=e.budget.parser(t);return n===null?void 0:En(e,n)}function wn(e,t){if(e.budget.source===`flag`)return e.budget.envelope===`widen`?Tn(e,e.budget,t):typeof t?.timeoutMs==`number`?t.timeoutMs:e.envelopeMs}function Tn(e,t,n){if(n?.settle!==!0)return e.envelopeMs;let r=typeof n.timeoutMs==`number`?n.timeoutMs:t.defaultBudgetMs;return typeof r==`number`?Dn(e,r):e.envelopeMs}function En(e,t){return Math.max(e.envelopeMs,t+Nn)}function Dn(e,t){return Math.max(e.envelopeMs,e.envelopeMs+t+Nn)}function On(e,n,r,i,a,o){let s=a?{terminated:0}:jn(),l=!a&&kn(i),u=l?Mn(e,n):{forcedKill:!1};return c({level:`error`,phase:`daemon_request_timeout`,data:{timeoutMs:o,requestId:r,command:i,timedOutRunnerPidsTerminated:s.terminated,timedOutRunnerCleanupError:s.error,daemonPidReset:l?e.pid:void 0,daemonPidForceKilled:l?u.forcedKill:void 0,daemonPreservedAfterTimeout:!a&&!l,daemonBaseUrl:e.baseUrl}}),new t(`COMMAND_FAILED`,`Daemon request timed out`,{timeoutMs:o,requestId:r,hint:An({remote:a,resetDaemon:l,command:i})})}function kn(e){return d(e).onTimeout===`reset-daemon`}function An(e){let{remote:t,resetDaemon:n,command:r}=e;if(t)return`Retry with --debug and verify the remote daemon URL, auth token, and remote host logs.`;if(!n){let e=r===m.snapshot?` If this was the first Apple-platform snapshot on the device, run agent-device prepare ios-runner with the same --platform before snapshot/test so runner startup is handled explicitly.`:``;return`Retry with --debug and check daemon diagnostics logs. The timed-out ${r??`request`} request was canceled and Apple runner work was aborted when detected; the daemon was kept alive so the session can still be closed or inspected.${e}`}return`Retry with --debug and check daemon diagnostics logs. Timed-out Apple runner xcodebuild processes were terminated when detected.`}function jn(){let e=0;try{for(let t of xn)a(`pkill`,[`-f`,t],{allowFailure:!0}).exitCode===0&&(e+=1);return{terminated:e}}catch(t){return{terminated:e,error:t instanceof Error?t.message:String(t)}}}function Mn(e,t){let n=!1;try{_(e.pid,e.processStartTime)&&(process.kill(e.pid,`SIGKILL`),n=!0)}catch{V(e)}finally{L(t.infoPath),R(t.lockPath)}return{forcedKill:n}}const Nn=3e4,Pn=`Daemon HTTP endpoint is unavailable`,Fn=`Daemon socket endpoint is unavailable`;async function In(e,t){let n=Gn(e,t);if(await Ln(e,n))return!0;let r=Kn(e,t,n);return r?await Ln(e,r):!1}async function Ln(e,t){return t===`http`?await zn(e):await Rn(e.port)}function Rn(e){return e?new Promise(t=>{let n=!1,r=E.createConnection({host:`127.0.0.1`,port:e},()=>{i(!0)}),i=e=>{n||(n=!0,r.destroy(),t(e))};r.setTimeout(500),r.on(`timeout`,()=>{i(!1)}),r.on(`error`,()=>{i(!1)})}):Promise.resolve(!1)}function zn(e){return Vn(e).then(e=>e.reachable)}async function Bn(e){let n=await Vn(e);if(!e.baseUrl||!n.reachable)return n;if(typeof n.rpcProtocolVersion==`number`&&n.rpcProtocolVersion!==1)throw new t(`COMMAND_FAILED`,`Remote daemon RPC protocol is incompatible`,{daemonBaseUrl:e.baseUrl,clientVersion:v(),remoteVersion:n.version,remoteService:n.service,supportedRpcProtocolVersion:1,remoteRpcProtocolVersion:n.rpcProtocolVersion,hint:`Upgrade agent-device on the client or remote host so both support the same daemon RPC protocol.`});return n}function Vn(e){let t=e.baseUrl?D(e.baseUrl,`health`):e.httpPort?`http://127.0.0.1:${e.httpPort}/health`:null;if(!t)return Promise.resolve({reachable:!1});let n=new URL(t),r=n.protocol===`https:`?T:w,i=e.baseUrl?3e3:500;return new Promise(t=>{let a=e.baseUrl?O(e.token):{},o=r.request({protocol:n.protocol,host:n.hostname,port:n.port,path:n.pathname+n.search,method:`GET`,timeout:i,headers:a},e=>{let n=``;e.setEncoding(`utf8`),e.on(`data`,e=>{n+=e}),e.on(`end`,()=>{let r=e.statusCode??500;t({reachable:r<500,statusCode:r,...Hn(n)})})});o.on(`timeout`,()=>{o.destroy(),t({reachable:!1})}),o.on(`error`,()=>{t({reachable:!1})}),o.end()})}function Hn(e){try{let t=JSON.parse(e);return{service:typeof t.service==`string`?t.service:void 0,version:typeof t.version==`string`?t.version:void 0,rpcProtocolVersion:typeof t.rpcProtocolVersion==`number`?t.rpcProtocolVersion:void 0}}catch{return{}}}async function Un(e,t,n,r,i,a={}){let o=Gn(e,n);try{return await Wn(e,t,r,i,o,a)}catch(s){let c=Kn(e,n,o);if(!c||!qn(s,o))throw s;return await Wn(e,t,r,i,c,a)}}async function Wn(e,t,n,r,i,a){return i===`http`?await Zn(e,t,n,r,a):await Xn(e,t,n,r,a)}function Gn(e,n){if(e.baseUrl){if(n===`socket`)throw new t(`COMMAND_FAILED`,`Remote daemon endpoint only supports HTTP transport`,{daemonBaseUrl:e.baseUrl});return`http`}if(n===`http`||n===`socket`)return Jn(e,n);let r=(e.transport===`socket`||e.transport===`dual`?[`socket`,`http`]:[`http`,`socket`]).find(t=>U(e,t));if(r)return r;throw new t(`COMMAND_FAILED`,`Daemon metadata has no reachable transport`)}function U(e,t){return t===`http`?!!e.httpPort:!!e.port}function Kn(e,t,n){if(t!==`auto`||e.baseUrl)return null;let r=n===`socket`?`http`:`socket`;return U(e,r)?r:null}function qn(e,n){return n===`socket`&&e instanceof t&&e.code===`COMMAND_FAILED`&&e.message===`Failed to communicate with daemon`&&e.details?.daemonSocketRequestWritten===!1}function Jn(e,n){if(U(e,n))return n;throw new t(`COMMAND_FAILED`,n===`http`?Pn:Fn)}function Yn(e,n,r,i={}){return c({level:`error`,phase:`daemon_request_socket_error`,data:{requestId:n,message:e instanceof Error?e.message:String(e)}}),new t(`COMMAND_FAILED`,`Failed to communicate with daemon`,{...i,requestId:n,hint:r?`Retry command. If this persists, verify the remote daemon URL, auth token, and remote host reachability.`:`Retry command. If this persists, clean stale daemon metadata and start a fresh session.`},e instanceof Error?e:void 0)}async function Xn(e,n,r,i,a){let o=e.port;if(!o)throw new t(`COMMAND_FAILED`,Fn);return new Promise((t,s)=>{let c=!1,l=E.createConnection({host:`127.0.0.1`,port:o},()=>{c=!0,l.write(`${JSON.stringify(n)}\n`)}),u=!1,d=typeof i==`number`?setTimeout(()=>{u=!0,l.destroy(),s(On(e,r,n.meta?.requestId,n.command,!1,i))},i):void 0;dn(l,{req:n,onProgress:a.onProgress,isSettled:()=>u,clearTimeout:()=>{d&&clearTimeout(d)},resolve:e=>{u=!0,t(e)},reject:e=>{u=!0,s(e)}}),l.on(`error`,e=>{u||(u=!0,d&&clearTimeout(d),s(Yn(e,n.meta?.requestId,!1,{daemonSocketRequestWritten:c})))})})}async function Zn(e,n,r,i,a){let o=e.baseUrl?new URL(D(e.baseUrl,`rpc`)):e.httpPort?new URL(`http://127.0.0.1:${e.httpPort}/rpc`):null;if(!o)throw new t(`COMMAND_FAILED`,Pn);let s=JSON.stringify(_n(n,{includeTokenParam:!e.baseUrl})),c={"content-type":`application/json`,"content-length":Buffer.byteLength(s)};return e.baseUrl&&Object.assign(c,O(e.token)),await new Promise((l,u)=>{let d=(o.protocol===`https:`?T:w).request({protocol:o.protocol,host:o.hostname,port:o.port,method:`POST`,path:o.pathname+o.search,headers:c},r=>{if(un(n,r.headers?.[`content-type`])){fn(r,{req:n,onProgress:a.onProgress,reject:u,clearTimeout:()=>{p&&clearTimeout(p)},handleResponseBody:t=>pn(t,{info:e,req:n,resolve:l,reject:u})});return}re(r).then(t=>{p&&clearTimeout(p),pn(t,{info:e,req:n,resolve:l,reject:u})}).catch(e=>{p&&clearTimeout(p),u(new t(`COMMAND_FAILED`,`Failed to read daemon response`,{requestId:n.meta?.requestId},e instanceof Error?e:void 0))})}),f=nn(e),p=typeof i==`number`?setTimeout(()=>{d.destroy(),u(On(e,r,n.meta?.requestId,n.command,f,i))},i):void 0;d.on(`error`,e=>{p&&clearTimeout(p),u(Yn(e,n.meta?.requestId,f))}),d.write(s),d.end()})}const W=15e3,G=new E.BlockList;G.addSubnet(`127.0.0.0`,8,`ipv4`),G.addAddress(`::1`,`ipv6`),G.addSubnet(`::ffff:127.0.0.0`,104,`ipv6`);function Qn(e){let t=$n(e),n=er(e),r=tr(e,n.remoteBaseUrl),i=nr(e,t,n.rawBaseUrl);return{paths:g(i?rr():t),transportPreference:r.preference,serverMode:r.serverMode,ownedStateDir:i,remoteBaseUrl:n.remoteBaseUrl,remoteAuthToken:n.authToken}}function $n(e){return e.flags?.stateDir??process.env.AGENT_DEVICE_STATE_DIR}function er(e){let t=e.flags?.daemonBaseUrl??process.env.AGENT_DEVICE_DAEMON_BASE_URL,n=xr(t),r=e.flags?.daemonAuthToken??process.env.AGENT_DEVICE_DAEMON_AUTH_TOKEN;return Sr(n,r),{rawBaseUrl:t,remoteBaseUrl:n,authToken:r}}function tr(e,n){let r=e.flags?.daemonTransport??process.env.AGENT_DEVICE_DAEMON_TRANSPORT,i=ie(r);if(n&&i===`socket`)throw new t(`INVALID_ARGS`,`Remote daemon base URL only supports HTTP transport. Remove --daemon-transport socket.`,{daemonBaseUrl:n});return{preference:i,serverMode:pe(e.flags?.daemonServerMode??process.env.AGENT_DEVICE_DAEMON_SERVER_MODE??(r===`dual`?`dual`:void 0))}}function nr(e,t,n){return mr(e.command)&&!t&&!n}function rr(){return S.mkdtempSync(C.join(Ke.tmpdir(),`agent-device-replay-daemon-`))}async function ir(e){if(e.remoteBaseUrl)return await ar(e);let t=await or(e);return t?{info:t,startedByClient:!1}:(en(e.paths),await fr(e))}async function ar(e){let n={transport:`http`,token:e.remoteAuthToken??``,pid:0,baseUrl:e.remoteBaseUrl};if((await Bn(n)).reachable)return{info:n,startedByClient:!1};throw new t(`COMMAND_FAILED`,`Remote daemon is unavailable`,{daemonBaseUrl:e.remoteBaseUrl,hint:`Verify AGENT_DEVICE_DAEMON_BASE_URL points to a reachable daemon with GET /health and POST /rpc. If this CLI was connected with connect proxy, run agent-device disconnect to return to the local daemon.`})}async function or(e){let t=N(e.paths.infoPath);if(!t)return null;let n=await sr(t,e.transportPreference);return lr(t,n)?t:(ur(t,n,e.paths.baseDir),await V(t),L(e.paths.infoPath),null)}async function sr(e,t){try{return await In(e,t)}catch(e){if(cr(e))return!1;throw e}}function cr(e){return e instanceof t&&e.code===`COMMAND_FAILED`&&(e.message===`Daemon HTTP endpoint is unavailable`||e.message===`Daemon socket endpoint is unavailable`)}function lr(e,t){return e.version===v()&&e.codeSignature===vr()&&t}function ur(e,t,n){try{let r=e.version?`pid ${e.pid}, v${e.version}`:`pid ${e.pid}`,i=dr(e,t);process.stderr.write(`Replacing daemon (${r}) in ${n}: ${i}\n`)}catch{}}function dr(e,t){return e.version===v()?e.codeSignature===vr()?t?`not reusable`:`unreachable`:`code-signature mismatch`:`version mismatch (client v${v()})`}async function fr(e){let n=0,r=[],i,a;for(let t=1;t<=2;t+=1){let o;try{o=gr(e),a={pid:o.pid}}catch(n){if(i=n instanceof Error?n.message:String(n),r.push(await z(e.paths,`start_error`)),t<2){await y(150);continue}break}let s=await hr(W,e,o);if(s.kind===`ready`)return{info:s.info,startedByClient:!0};if(s.kind===`early_exit`){if(a=s.exit,i=yr(s.exit),r.push(await z(e.paths,`start_error`)),t<2){await y(150);continue}break}if(await tn(e.paths)){n+=1;continue}let c=B(e.paths),l=t<2,u=await z(e.paths,`startup_timeout`,{stopLiveProcesses:!1});if(r.push(u),u.retainedInfoProcess||u.retainedLockProcess){let t=await hr(W,e,o);if(t.kind===`ready`)return{info:t.info,startedByClient:!0};t.kind===`early_exit`&&(a=t.exit,i=yr(t.exit));break}if(!l)break;!c.hasInfo&&!c.hasLock&&await y(150)}let o=B(e.paths),s=br(e.paths.logPath);throw new t(`COMMAND_FAILED`,`Failed to start daemon`,{kind:`daemon_startup_failed`,stateDir:e.paths.baseDir,infoPath:e.paths.infoPath,lockPath:e.paths.lockPath,logPath:e.paths.logPath,startupTimeoutMs:W,startupAttempts:2,lockRecoveryCount:n,cleanupResults:r,startError:i,daemonProcess:a,...s?{daemonLogTail:s}:{},metadataState:o,hint:rn(o,e.paths)})}async function pr(e,t,n){if(!mr(e.command)||!t.startedByClient&&!n.ownedStateDir||nn(t.info))return;let r={pid:t.info.pid,removedInfo:!1,removedLock:!1,removedStateDir:!1,error:void 0};try{await V(t.info)}catch(e){r.error=e instanceof Error?e.message:String(e)}finally{let e=S.existsSync(n.paths.infoPath);L(n.paths.infoPath),r.removedInfo=e&&!S.existsSync(n.paths.infoPath);let t=S.existsSync(n.paths.lockPath);R(n.paths.lockPath),r.removedLock=t&&!S.existsSync(n.paths.lockPath),n.ownedStateDir&&(S.rmSync(n.paths.baseDir,{recursive:!0,force:!0}),r.removedStateDir=!S.existsSync(n.paths.baseDir))}c({level:r.error?`warn`:`info`,phase:`daemon_replay_cleanup`,data:r})}function mr(e){return e===m.replay||e===m.test}async function hr(e,t,n){let r=Date.now(),i;for(n.exited.then(e=>{i=e});Date.now()-r<e;){if(i)return{kind:`early_exit`,exit:i};let e=N(t.paths.infoPath);if(e&&await In(e,t.transportPreference))return{kind:`ready`,info:e};if(i)return{kind:`early_exit`,exit:i};await y(100)}return{kind:`timeout`}}function gr(e){let t=_r(),n=t.useSrc?[`--experimental-strip-types`,t.srcPath]:[t.distPath],r={...process.env,AGENT_DEVICE_STATE_DIR:e.paths.baseDir,AGENT_DEVICE_DAEMON_SERVER_MODE:e.serverMode};S.mkdirSync(e.paths.baseDir,{recursive:!0});let i=S.openSync(e.paths.logPath,`a`),a=S.openSync(e.paths.logPath,`a`);try{return u(process.execPath,n,{env:r,stdio:[`ignore`,i,a]})}finally{S.closeSync(i),S.closeSync(a)}}function _r(){let e=he(),n=[C.join(e,`dist`,`src`,`internal`,`daemon.js`),C.join(e,`dist`,`src`,`daemon.js`)],r=n[0];if(r===void 0)throw new t(`COMMAND_FAILED`,`Daemon dist path list is empty`);let i=n.find(e=>S.existsSync(e))??r,a=C.join(e,`src`,`daemon.ts`),o=n.some(e=>S.existsSync(e)),s=S.existsSync(a);if(!o&&!s)throw new t(`COMMAND_FAILED`,`Daemon entry not found`,{distPaths:n,srcPath:a});return{root:e,distPath:i,distPaths:n,srcPath:a,useSrc:(process.execArgv.includes(`--experimental-strip-types`)||!o)&&s}}function vr(){let e=_r();return ae(e.useSrc?e.srcPath:e.distPath,e.root)}function yr(e){return e.error?`daemon process ${e.pid} failed to start: ${e.error}`:e.signal?`daemon process ${e.pid} exited before readiness with signal ${e.signal}`:`daemon process ${e.pid} exited before readiness with code ${e.exitCode??0}`}function br(e){try{if(!S.existsSync(e))return;let t=S.statSync(e);if(t.size<=0)return;let n=Math.min(t.size,64e3),r=S.openSync(e,`r`);try{let e=Buffer.alloc(n);S.readSync(r,e,0,n,t.size-n);let i=e.toString(`utf8`).trim();return i.length>0?i:void 0}finally{S.closeSync(r)}}catch{return}}function xr(e){if(!e)return;let n;try{n=new URL(e)}catch(n){throw new t(`INVALID_ARGS`,`Invalid daemon base URL`,{daemonBaseUrl:e},n instanceof Error?n:void 0)}if(n.protocol!==`http:`&&n.protocol!==`https:`)throw new t(`INVALID_ARGS`,`Daemon base URL must use http or https`,{daemonBaseUrl:e});return n.toString().replace(/\/+$/,``)}function Sr(e,n){if(!e)return;let r=new URL(e).hostname;if(!Cr(r)&&!(typeof n==`string`&&n.trim().length>0))throw new t(`INVALID_ARGS`,`Remote daemon base URL for non-loopback hosts requires daemon authentication`,{daemonBaseUrl:e,hint:`Provide --daemon-auth-token or AGENT_DEVICE_DAEMON_AUTH_TOKEN when using a non-loopback remote daemon URL.`})}function Cr(e){let t=e.trim().toLowerCase().replace(/^\[(.*)\]$/,`$1`);return t===`localhost`?!0:E.isIPv4(t)?G.check(t,`ipv4`):E.isIPv6(t)?G.check(t,`ipv6`):!1}async function wr(e,t={}){let n=e.meta?.requestId??i(),r=!!(e.meta?.debug||e.flags?.verbose),a=Qn(e),s=Sn(e),l=await o(`daemon_startup`,async()=>await ir(a),{requestId:n,session:e.session}),u=l.info,d=await Mt(e,u);Tr(e.command);let f={...e,positionals:d.positionals,flags:d.flags,token:u.token,meta:{...e.meta??{},requestId:n,debug:r,includeCost:e.meta?.includeCost,cwd:e.meta?.cwd,sessionExplicit:e.meta?.sessionExplicit,tenantId:e.meta?.tenantId??e.flags?.tenant,runId:e.meta?.runId??e.flags?.runId,leaseId:e.meta?.leaseId??e.flags?.leaseId,sessionIsolation:e.meta?.sessionIsolation??e.flags?.sessionIsolation,lockPolicy:e.meta?.lockPolicy,lockPlatform:e.meta?.lockPlatform,...d.uploadedArtifactId?{uploadedArtifactId:d.uploadedArtifactId}:{},...d.clientArtifactPaths?{clientArtifactPaths:d.clientArtifactPaths}:{},...d.installSource?{installSource:d.installSource}:{}}};c({level:`info`,phase:`daemon_request_prepare`,data:{requestId:n,command:e.command,session:e.session}});try{return await o(`daemon_request`,async()=>await Un(u,f,a.transportPreference,a.paths,s,t),{requestId:n,command:e.command})}finally{await pr(e,l,a)}}function Tr(e){!Er(e)||process.stderr.isTTY!==!0||process.env.CI||process.stderr.write(e===m.reinstall?`Reinstalling...
|
|
2
2
|
`:`Installing...
|
|
3
|
-
`)}function Er(e){return e===m.install||e===m.reinstall||e===h.installSource}const Dr=8081;function Or(e){return typeof e==`string`&&e.trim()?Le(e.trim()):``}function K(e){return typeof e==`string`&&e.trim()?e.trim():void 0}function q(e,t,n){return ge(e,{env:t,cwd:n})}function J(e){try{return S.accessSync(e,S.constants.F_OK),!0}catch{return!1}}function kr(e){try{return S.statSync(e).isDirectory()}catch{return!1}}function Ar(e){let n=C.join(e,`package.json`),r=Ve(e);if(!r)throw new t(`INVALID_ARGS`,`package.json not found at ${n}`);return r}function jr(e){return J(C.join(e,`pnpm-lock.yaml`))?{command:`pnpm`,installArgs:[`install`]}:J(C.join(e,`yarn.lock`))?{command:`yarn`,installArgs:[`install`]}:{command:`npm`,installArgs:[`install`]}}function Mr(e,t){if(t!==`auto`)return t;let n=Be(e);return n===`expo`||n===`repack`?n:`react-native`}function Nr(e,t){return typeof{...e.dependencies??{},...e.devDependencies??{}}[t]==`string`}function Pr(e,t){return[`js`,`mjs`,`cjs`,`ts`,`mts`,`cts`].some(n=>J(C.join(e,`${t}.config.${n}`)))}function Fr(e,t){return Pr(e,`rspack`)?`rspack`:Pr(e,`webpack`)?`webpack`:Nr(t,`@rspack/core`)?`rspack`:Nr(t,`webpack`)?`webpack`:`rspack`}function Y(e,t,n){if(e==null||e===``)return t;let r=Number.parseInt(String(e),10);return Number.isInteger(r)?Math.max(r,n):t}function Ir(e,n){if(e==null||e===``)return n;let r=Number.parseInt(String(e),10);if(!Number.isInteger(r)||r<1||r>65535)throw new t(`INVALID_ARGS`,`Invalid Metro port: ${String(e)}. Use 1-65535.`);return r}function Lr(e,t){return{platform:t,bundleUrl:Re(e,t)}}function Rr(e,t){return{platform:t,metroHost:K(e?.metro_host),metroPort:e?.metro_port,bundleUrl:K(e?.metro_bundle_url),launchUrl:K(e?.launch_url)}}function zr(e,t){if(kr(C.join(e,`node_modules`)))return{installed:!1};let n=jr(e);return a(n.command,n.installArgs,{cwd:e,env:t}),{installed:!0,packageManager:n.command}}async function Br(e){await y(e)}async function Vr(e,n,r={}){try{let t=await fetch(e,{headers:r,signal:AbortSignal.timeout(n)});return{ok:t.ok,status:t.status,body:await t.text()}}catch(r){throw r instanceof Error&&r.name===`TimeoutError`?new t(`COMMAND_FAILED`,`Timed out fetching ${e} after ${n}ms`):r}}async function Hr(e,t){try{let n=await Vr(e,t);return n.ok&&n.body.includes(`packager-status:running`)}catch{return!1}}function Ur(e,t){let n=new URL(`${e.scheme}://localhost`);return n.hostname=e.host,n.port=String(e.port),n.pathname=t,n.toString()}function Wr(e){let t=K(e);if(!t)return`/reload`;let n=new URL(t).pathname.replace(/\/+$/,``);return n.endsWith(`/index.bundle`)?`${n.slice(0,-13)}/reload`:`/reload`}function Gr(e,t,n){return K(e.metroHost)??(t?void 0:K(e.runtime?.metroHost))??(n?void 0:`localhost`)}function Kr(e,t,n){if(e.metroPort!==void 0)return Ir(e.metroPort,Dr);if(!t)return e.runtime?.metroPort??(n?void 0:Dr)}function qr(e){let n=K(e.bundleUrl),r=n??e.runtime?.bundleUrl,i=!!n,a=!!K(r),o=He({metroHost:Gr(e,i,a),metroPort:Kr(e,i,a),bundleUrl:r});if(!o)throw new t(`INVALID_ARGS`,`Unable to resolve Metro host and port for reload.`);return Ur(o,Wr(r))}function Jr(e,t,n,r){return e===`expo`?{command:`npx`,installArgs:[`expo`,`start`,`--host`,`lan`,`--port`,String(n)]}:e===`repack`?{command:`npx`,installArgs:[`react-native`,t===`webpack`?`webpack-start`:`rspack-start`,`--host`,r,`--port`,String(n)]}:{command:`npx`,installArgs:[`react-native`,`start`,`--host`,r,`--port`,String(n)]}}function Yr(e,n,r,i,a,o,c){let l=Jr(n,r,i,a);S.mkdirSync(C.dirname(o),{recursive:!0});let u=S.openSync(o,`a`),d=0;try{d=s(l.command,l.installArgs,{cwd:e,env:c,stdio:[`ignore`,u,u]})}finally{S.closeSync(u)}if(!Number.isInteger(d)||d<=0)throw new t(`COMMAND_FAILED`,`Failed to start React Native dev server. Expected a detached child PID.`);return{pid:d}}async function Xr(e){if(!(!Number.isInteger(e)||e<=0)){try{process.kill(e,`SIGTERM`)}catch(e){let t=e.code;if(t===`ESRCH`||t===`EPERM`)return;throw e}if(!await _e(e,1e3)){try{process.kill(e,`SIGKILL`)}catch(e){let t=e.code;if(t===`ESRCH`||t===`EPERM`)return;throw e}await _e(e,1e3)}}}function Zr(e,t){return{Authorization:`Bearer ${t}`,"Content-Type":`application/json`,...e.includes(`ngrok`)?{"ngrok-skip-browser-warning":`1`}:{}}}function X(e,n){let r=new t(`COMMAND_FAILED`,e);return r.retryable=n,r}function Qr(e,t){return!!(e>=500||e===408||e===425||e===429||JSON.stringify(t).includes(`Metro companion is not connected`))}function $r(e){return!!(e&&typeof e==`object`&&`retryable`in e&&e.retryable===!0)}async function ei(e){let t;try{t=await fetch(`${e.baseUrl}/api/metro/bridge`,{method:`POST`,headers:Zr(e.baseUrl,e.bearerToken),body:JSON.stringify({...e.scope,...e.runtime?{ios_runtime:e.runtime}:{},timeout_ms:e.timeoutMs}),signal:AbortSignal.timeout(e.timeoutMs)})}catch(t){throw t instanceof Error&&t.name===`TimeoutError`?X(`/api/metro/bridge timed out after ${e.timeoutMs}ms calling ${e.baseUrl}/api/metro/bridge`,!0):X(t instanceof Error?t.message:String(t),!0)}let n=ti(await t.text(),t.status,e.baseUrl);if(!t.ok)throw X(`/api/metro/bridge failed (${t.status}): ${JSON.stringify(n)}`,Qr(t.status,n));return ri(n)}function ti(e,t,n){if(!e)return{};try{let t=JSON.parse(e);if(!t||typeof t!=`object`||Array.isArray(t))throw Error(`Expected a JSON object`);return t}catch(r){let i=e.slice(0,200);throw X(`/api/metro/bridge returned invalid JSON (${t}) from ${n}: ${r instanceof Error?r.message:String(r)}. body=${JSON.stringify(i)}`,Qr(t,e))}}function ni(e){return{enabled:e.enabled,baseUrl:e.base_url,statusUrl:e.status_url??``,bundleUrl:e.bundle_url??``,iosRuntime:Rr(e.ios_runtime,`ios`),androidRuntime:Rr(e.android_runtime,`android`),upstream:{bundleUrl:e.upstream.bundle_url??``,host:e.upstream.host??``,port:e.upstream.port??0,statusUrl:e.upstream.status_url??``},probe:{reachable:e.probe.reachable,statusCode:e.probe.status_code,latencyMs:e.probe.latency_ms,detail:e.probe.detail}}}function ri(e){let t=e.data??e;if(!t||typeof t!=`object`||Array.isArray(t))throw X(`/api/metro/bridge returned malformed descriptor: Expected a JSON object.`,!1);try{return ni(t)}catch(e){throw X(`/api/metro/bridge returned malformed descriptor: ${e instanceof Error?e.message:String(e)}`,!1)}}function Z(e,t,n,r,i){let a=[`Metro bridge is required for this run but could not be configured via ${e}/api/metro/bridge.`];return t&&a.push(`bridgeError=${t}`),n?.probe.reachable===!1&&a.push(`bridgeProbe=${n.probe.detail||`unreachable (status ${n.probe.statusCode||0})`}`),r&&r!==t&&a.push(`initialBridgeError=${r}`),i&&a.push(`metroCompanionLog=${i}`),a.join(` `)}function ii(e,n){if(!n?.iosRuntime.bundleUrl)throw new t(`COMMAND_FAILED`,Z(e,`bridge descriptor is missing ios_runtime.metro_bundle_url`,n))}function ai(e,n,r){let i=n||K(r.AGENT_DEVICE_METRO_BEARER_TOKEN)||``,a=i||e&&K(r.AGENT_DEVICE_DAEMON_AUTH_TOKEN)||``;if(e&&!a)throw new t(`INVALID_ARGS`,`metro prepare requires proxy auth when --proxy-base-url is provided. Pass --bearer-token or set AGENT_DEVICE_METRO_BEARER_TOKEN or AGENT_DEVICE_DAEMON_AUTH_TOKEN.`);if(!e&&i)throw new t(`INVALID_ARGS`,`metro prepare requires --proxy-base-url when proxy auth is provided.`);return{proxyEnabled:!!(e&&a),proxyBaseUrl:e,proxyBearerToken:a}}function oi(e){if(!e?.tenantId||!e.runId||!e.leaseId)throw new t(`INVALID_ARGS`,`metro prepare with proxy requires tenantId, runId, and leaseId bridge scope.`);return e}function si(e,n){if(!(e||n))throw new t(`INVALID_ARGS`,`metro prepare requires --public-base-url <url> or --proxy-base-url <url>.`)}function ci(e,t,n){return e.runtimeFilePath?q(e.runtimeFilePath,t,n):null}function li(e,t,n,r){return q(e.logPath??C.join(r,`.agent-device`,`metro.log`),t,n)}function ui(e){let t=e.env??process.env,n=process.cwd(),r=q(e.projectRoot??n,t,n),i=e.kind??`auto`,a=null,o;i===`auto`?(a=Ar(r),o=Mr(a,i)):o=i;let s=null;o===`repack`&&(a??=Ar(r),s=Fr(r,a));let c=Or(e.publicBaseUrl),l=Or(e.proxyBaseUrl);si(c,l);let{proxyEnabled:u,proxyBaseUrl:d,proxyBearerToken:f}=ai(l,K(e.proxyBearerToken)??``,t);return{env:t,projectRoot:r,kind:o,repackBundler:s,metroPort:Ir(e.metroPort??8081,8081),listenHost:K(e.listenHost)??`0.0.0.0`,statusHost:K(e.statusHost)??`127.0.0.1`,publicBaseUrl:c,proxyBaseUrl:d,proxyBearerToken:f,bridgeScope:u?oi(e.bridgeScope):null,startupTimeoutMs:Y(e.startupTimeoutMs,18e4,3e4),probeTimeoutMs:Y(e.probeTimeoutMs,1e4,1e3),reuseExisting:e.reuseExisting??!0,installProjectDeps:e.installDependenciesIfNeeded??!0,runtimeFilePath:ci(e,t,n),logPath:li(e,t,n,r)}}async function di(e,t,n){let r=Date.now()+t;for(;Date.now()<r;){let t=r-Date.now();if(await Hr(e,Math.min(n,Math.max(t,1))))return!0;let i=Math.min(500,Math.max(r-Date.now(),0));i>0&&await Br(i)}return!1}async function fi(e){let n=Date.now()+e.startupTimeoutMs,r=null,i=null;for(;Date.now()<n;){try{let t=await ei({baseUrl:e.baseUrl,bearerToken:e.bearerToken,scope:e.scope,runtime:e.runtime,timeoutMs:e.probeTimeoutMs});if(t.probe.reachable!==!1)return t;r=t,i=null}catch(n){if(i=n instanceof Error?n.message:String(n),!$r(n))throw new t(`COMMAND_FAILED`,Z(e.baseUrl,i,r,e.initialBridgeError,e.companionLogPath),void 0,n)}let a=Math.min(1e3,Math.max(n-Date.now(),0));a>0&&await Br(a)}throw new t(`COMMAND_FAILED`,Z(e.baseUrl,i,r,e.initialBridgeError,e.companionLogPath))}async function pi(e){let n=`http://${e.statusHost}:${e.metroPort}/status`;if(e.reuseExisting&&await Hr(n,e.probeTimeoutMs))return{started:!1,reused:!0,pid:0,statusUrl:n};let r=Yr(e.projectRoot,e.kind,e.repackBundler,e.metroPort,e.listenHost,e.logPath,e.env);if(await di(n,e.startupTimeoutMs,e.probeTimeoutMs))return{started:!0,reused:!1,pid:r.pid,statusUrl:n};throw await Xr(r.pid).catch(()=>{}),new t(`COMMAND_FAILED`,`React Native dev server did not become ready at ${n} within ${e.startupTimeoutMs}ms. Check ${e.logPath}.`,{logPath:e.logPath})}async function mi(e,t){let n=t.bridgeScope;if(!n)return null;let r=null,i=null;try{r=await ei({baseUrl:t.proxyBaseUrl,bearerToken:t.proxyBearerToken,scope:n,timeoutMs:t.probeTimeoutMs})}catch(e){if(!$r(e))throw e;i=e instanceof Error?e.message:String(e)}return(!r||r.probe.reachable===!1)&&(r=await hi(e,t,n,r,i)),ii(t.proxyBaseUrl,r),r}async function hi(e,n,r,i,a){let o;try{o=(await ze({projectRoot:n.projectRoot,serverBaseUrl:n.proxyBaseUrl,bearerToken:n.proxyBearerToken,bridgeScope:r,localBaseUrl:`http://${n.statusHost}:${n.metroPort}`,launchUrl:K(e.launchUrl),profileKey:K(e.companionProfileKey),consumerKey:K(e.companionConsumerKey),env:n.env})).logPath}catch(e){throw new t(`COMMAND_FAILED`,Z(n.proxyBaseUrl,e instanceof Error?e.message:String(e),i,a),void 0,e)}try{return await fi({baseUrl:n.proxyBaseUrl,bearerToken:n.proxyBearerToken,scope:r,probeTimeoutMs:n.probeTimeoutMs,startupTimeoutMs:n.startupTimeoutMs,initialBridgeError:a,companionLogPath:o})}catch(e){throw e instanceof Error?e:Error(String(e))}}function gi(e){return{baseIosRuntime:e?Lr(e,`ios`):{platform:`ios`},baseAndroidRuntime:e?Lr(e,`android`):{platform:`android`}}}function _i(e,t){e&&(S.mkdirSync(C.dirname(e),{recursive:!0}),S.writeFileSync(e,JSON.stringify(t,null,2)))}async function vi(e={}){let t=ui(e),n=t.installProjectDeps?zr(t.projectRoot,t.env):{installed:!1},r=await pi(t),{baseIosRuntime:i,baseAndroidRuntime:a}=gi(t.publicBaseUrl),o=await mi(e,t),s=o?.iosRuntime??i,c=o?.androidRuntime??a,l={projectRoot:t.projectRoot,kind:t.kind,dependenciesInstalled:n.installed,packageManager:n.packageManager??null,started:r.started,reused:r.reused,pid:r.pid,logPath:t.logPath,statusUrl:r.statusUrl,runtimeFilePath:t.runtimeFilePath,iosRuntime:s,androidRuntime:c,bridge:o};return _i(t.runtimeFilePath,l),l}async function yi(e={}){let n=Y(e.timeoutMs,1e4,1e3),r=qr(e),i=await Vr(r,n);if(!i.ok)throw new t(`COMMAND_FAILED`,`React Native dev server reload failed (${i.status}).`,{reloadUrl:r,status:i.status,body:i.body,hint:`Verify Metro or Re.Pack is running and the target React Native app is connected to this dev server instance.`});return{reloaded:!0,reloadUrl:r,status:i.status,body:i.body}}const bi={...ke(),batch:De(xi)};function xi(e,n,r){let i=bi[e];if(!i)throw Error(`Missing daemon writer for batch command: ${e}`);let a=Ue(e);if(!a)throw Error(`Missing command metadata for batch command: ${e}`);try{return Ci(i,a,a.readInput(n))}catch(n){throw new t(`INVALID_ARGS`,`Batch step ${r} ${e} input is invalid: ${n instanceof Error?n.message:String(n)}`,void 0,n)}}function Si(e,t){let n=bi[e];if(!n)throw Error(`Missing daemon writer for command: ${e}`);return Ci(n,Ue(e),t)}function Ci(e,t,n){let r=e(n);return{...r,...t?{metadataFlags:je(t,r.options)}:{}}}function wi(e){throw new t(n(e.code),e.message,{...e.details??{},hint:e.hint,diagnosticId:e.diagnosticId,logPath:e.logPath,retriable:e.retriable,supportedOn:e.supportedOn})}var Ti=e({createAgentDeviceClient:()=>Ei});function Ei(e={},t={}){let n=t.transport??wr,i=t=>r(t.responseLevel??e.responseLevel),a=async(t,r=[],i={},a)=>{let o=$(e,i),s=await n({session:ve(o.session),command:t,positionals:r,flags:Oe(o,a),runtime:o.runtime,meta:Fe(o)});return s.ok||wi(s.error),s.data??{}},o=async(e={})=>{let t=await a(h.sessionList,[],e);return(Array.isArray(t.sessions)?t.sessions:[]).map(xe)},s=async(e,t={})=>{let n=Si(e,t);return await a(n.command,n.positionals,n.options,n.metadataFlags)},c=(t={})=>ve($(e,t).session);return{command:{wait:async e=>await s(`wait`,e),alert:async(e={})=>await s(`alert`,e),...ki(s),reactNative:async e=>await s(`react-native`,e),doctor:async(e={})=>await s(`doctor`,e),prepare:async e=>await s(`prepare`,e),viewport:async e=>await s(`viewport`,e)},devices:{list:async(e={})=>{let t=await s(`devices`,e);return(Array.isArray(t.devices)?t.devices:[]).map(Pe)},capabilities:async(e={})=>{let t=await s(`capabilities`,e),n=Array.isArray(t.availableCommands)?t.availableCommands.filter(e=>typeof e==`string`):[];return{device:Pe(t.device),availableCommands:n}},boot:async(e={})=>await s(`boot`,e),shutdown:async(e={})=>await s(`shutdown`,e)},sessions:{list:async(e={})=>await o(e),stateDir:async(t={})=>g($(e,t).stateDir??process.env.AGENT_DEVICE_STATE_DIR).baseDir,close:async(e={})=>{let t=c(e),n=await s(`close`,e);return{session:t,shutdown:Se(n.shutdown),provider:Q(n.provider),identifiers:{session:t}}},artifacts:async(e={})=>await s(`artifacts`,e)},apps:{install:async e=>Ee(await s(`install`,e),c(e)),reinstall:async e=>Ee(await s(`reinstall`,e),c(e)),installFromSource:async e=>we(await s(`install-from-source`,e),c(e)),list:async(e={})=>{let t=await s(`apps`,e);return Array.isArray(t.apps)?t.apps.filter(e=>typeof e==`string`):[]},open:async e=>{let t=c(e),n=await s(`open`,e),r=Ne(n),i=b(n,`appBundleId`),a=i;return{session:t,sessionStateDir:b(n,`sessionStateDir`),eventLogPath:b(n,`eventLogPath`),appName:b(n,`appName`),appBundleId:i,appId:a,startup:be(n.startup),runtime:Te(n.runtime),device:r,identifiers:{session:t,deviceId:r?.id,deviceName:r?.name,udid:r?.ios?.udid,serial:r?.android?.serial,appId:a,appBundleId:i}}},close:async(e={})=>{let t=c(e),n=await s(`close`,e);return{session:t,closedApp:e.app,shutdown:Se(n.shutdown),identifiers:{session:t}}},push:async e=>await s(`push`,e),triggerEvent:async e=>await s(`trigger-app-event`,e)},materializations:{release:async e=>ye(await a(h.releaseMaterializedPaths,[],{...e,materializationId:e.materializationId}))},leases:{allocate:async e=>Ai(await a(h.leaseAllocate,[],{...e,leaseId:void 0})),heartbeat:async e=>Ai(await a(h.leaseHeartbeat,[],e)),release:async e=>{let t=await a(h.leaseRelease,[],e);return{released:t.released===!0,provider:Q(t.provider)}}},metro:{prepare:async t=>await vi({projectRoot:t.projectRoot??e.cwd,kind:t.kind,publicBaseUrl:t.publicBaseUrl,proxyBaseUrl:t.proxyBaseUrl,proxyBearerToken:t.bearerToken,bridgeScope:t.bridgeScope,launchUrl:t.launchUrl,companionProfileKey:t.companionProfileKey,companionConsumerKey:t.companionConsumerKey,metroPort:t.port,listenHost:t.listenHost,statusHost:t.statusHost,startupTimeoutMs:t.startupTimeoutMs,probeTimeoutMs:t.probeTimeoutMs,reuseExisting:t.reuseExisting,installDependenciesIfNeeded:t.installDependenciesIfNeeded,runtimeFilePath:t.runtimeFilePath,logPath:t.logPath}),reload:async(t={})=>await yi({metroHost:t.metroHost,metroPort:t.metroPort,bundleUrl:t.bundleUrl,runtime:e.runtime,timeoutMs:t.timeoutMs})},capture:{snapshot:async(e={})=>{let t=c(e),n=await s(`snapshot`,e);return i(e)?n:Di(n,t)},screenshot:async(e={})=>{let t=c(e),n=await s(`screenshot`,e);if(i(e))return n;let r=de(n);return{path:x(n,`path`),width:r?.width,height:r?.height,logicalWidth:r?.logicalWidth,logicalHeight:r?.logicalHeight,pixelDensity:r?.pixelDensity,overlayRefs:r?.overlayRefs,identifiers:{session:t}}},diff:async e=>await s(`diff`,e)},interactions:{click:async e=>await s(`click`,e),press:async e=>await s(`press`,e),longPress:async e=>await s(`longpress`,e),swipe:async e=>await s(`swipe`,e),pan:async e=>await s(`gesture-pan`,e),fling:async e=>await s(`gesture-fling`,e),swipeGesture:async e=>await s(`gesture-swipe`,e),focus:async e=>await s(`focus`,e),type:async e=>await s(`type`,e),fill:async e=>await s(`fill`,e),scroll:async e=>await s(`scroll`,e),pinch:async e=>await s(`gesture-pinch`,e),rotateGesture:async e=>await s(`gesture-rotate`,e),transformGesture:async e=>await s(`gesture-transform`,e),get:async e=>await s(`get`,e),is:async e=>await s(`is`,e),find:async e=>await s(`find`,e)},replay:{run:async e=>await s(`replay`,e),test:async e=>await s(`test`,e)},batch:{run:async e=>await s(`batch`,e)},observability:{perf:async(e={})=>await s(`perf`,e),logs:async(e={})=>await s(`logs`,e),events:async(e={})=>await s(`events`,e),network:async(e={})=>await s(`network`,e),audio:async(e={})=>await s(`audio`,e)},debug:{symbols:async t=>{let{symbolicateCrashArtifact:n}=await import(`./debug-symbols.js`);return n({cwd:t.cwd??e.cwd,...t})}},recording:{record:async e=>await s(`record`,e),trace:async e=>await s(`trace`,e)},settings:{update:async e=>await s(`settings`,e)}}}function Di(e,t){let n=b(e,`appBundleId`);return{nodes:Ae(e.nodes),truncated:e.truncated===!0,appName:b(e,`appName`),appBundleId:n,...Oi(e),identifiers:{session:t,appId:n,appBundleId:n}}}function Oi(e){let t=Q(e.visibility),n=Q(e.unchanged),r=ue(e.snapshotDiagnostics);return{...t?{visibility:t}:{},...ee(e),...n?{unchanged:n}:{},...r?{snapshotDiagnostics:r}:{}}}function ki(e){let t={};for(let[n,r]of Object.entries(Me.clientCommandMethods??{}))t[n]=async(t={})=>await e(r,t);return t}function Q(e){return Ie(e)?e:void 0}function $(e,t){return{...e,...t}}function Ai(e){let t=e.lease;if(!Ie(t))throw Error(`Invalid lease response from daemon`);return{leaseId:x(t,`leaseId`),tenantId:x(t,`tenantId`),runId:x(t,`runId`),backend:x(t,`backend`),leaseProvider:b(t,`leaseProvider`),clientId:b(t,`clientId`),deviceKey:b(t,`deviceKey`),createdAt:typeof t.createdAt==`number`?t.createdAt:void 0,heartbeatAt:typeof t.heartbeatAt==`number`?t.heartbeatAt:void 0,expiresAt:typeof t.expiresAt==`number`?t.expiresAt:void 0}}export{Qn as a,Ze as c,ir as i,D as l,Ei as n,Xe as o,wr as r,O as s,Ti as t};
|
|
3
|
+
`)}function Er(e){return e===m.install||e===m.reinstall||e===h.installSource}const Dr=8081;function Or(e){return typeof e==`string`&&e.trim()?Le(e.trim()):``}function K(e){return typeof e==`string`&&e.trim()?e.trim():void 0}function q(e,t,n){return ge(e,{env:t,cwd:n})}function J(e){try{return S.accessSync(e,S.constants.F_OK),!0}catch{return!1}}function kr(e){try{return S.statSync(e).isDirectory()}catch{return!1}}function Ar(e){let n=C.join(e,`package.json`),r=Ve(e);if(!r)throw new t(`INVALID_ARGS`,`package.json not found at ${n}`);return r}function jr(e){return J(C.join(e,`pnpm-lock.yaml`))?{command:`pnpm`,installArgs:[`install`]}:J(C.join(e,`yarn.lock`))?{command:`yarn`,installArgs:[`install`]}:{command:`npm`,installArgs:[`install`]}}function Mr(e,t){if(t!==`auto`)return t;let n=Be(e);return n===`expo`||n===`repack`?n:`react-native`}function Nr(e,t){return typeof{...e.dependencies??{},...e.devDependencies??{}}[t]==`string`}function Pr(e,t){return[`js`,`mjs`,`cjs`,`ts`,`mts`,`cts`].some(n=>J(C.join(e,`${t}.config.${n}`)))}function Fr(e,t){return Pr(e,`rspack`)?`rspack`:Pr(e,`webpack`)?`webpack`:Nr(t,`@rspack/core`)?`rspack`:Nr(t,`webpack`)?`webpack`:`rspack`}function Y(e,t,n){if(e==null||e===``)return t;let r=Number.parseInt(String(e),10);return Number.isInteger(r)?Math.max(r,n):t}function Ir(e,n){if(e==null||e===``)return n;let r=Number.parseInt(String(e),10);if(!Number.isInteger(r)||r<1||r>65535)throw new t(`INVALID_ARGS`,`Invalid Metro port: ${String(e)}. Use 1-65535.`);return r}function Lr(e,t){return{platform:t,bundleUrl:Re(e,t)}}function Rr(e,t){return{platform:t,metroHost:K(e?.metro_host),metroPort:e?.metro_port,bundleUrl:K(e?.metro_bundle_url),launchUrl:K(e?.launch_url)}}function zr(e,t){if(kr(C.join(e,`node_modules`)))return{installed:!1};let n=jr(e);return a(n.command,n.installArgs,{cwd:e,env:t}),{installed:!0,packageManager:n.command}}async function Br(e){await y(e)}async function Vr(e,n,r={}){try{let t=await fetch(e,{headers:r,signal:AbortSignal.timeout(n)});return{ok:t.ok,status:t.status,body:await t.text()}}catch(r){throw r instanceof Error&&r.name===`TimeoutError`?new t(`COMMAND_FAILED`,`Timed out fetching ${e} after ${n}ms`):r}}async function Hr(e,t){try{let n=await Vr(e,t);return n.ok&&n.body.includes(`packager-status:running`)}catch{return!1}}function Ur(e,t){let n=new URL(`${e.scheme}://localhost`);return n.hostname=e.host,n.port=String(e.port),n.pathname=t,n.toString()}function Wr(e){let t=K(e);if(!t)return`/reload`;let n=new URL(t).pathname.replace(/\/+$/,``);return n.endsWith(`/index.bundle`)?`${n.slice(0,-13)}/reload`:`/reload`}function Gr(e,t,n){return K(e.metroHost)??(t?void 0:K(e.runtime?.metroHost))??(n?void 0:`localhost`)}function Kr(e,t,n){if(e.metroPort!==void 0)return Ir(e.metroPort,Dr);if(!t)return e.runtime?.metroPort??(n?void 0:Dr)}function qr(e){let n=K(e.bundleUrl),r=n??e.runtime?.bundleUrl,i=!!n,a=!!K(r),o=He({metroHost:Gr(e,i,a),metroPort:Kr(e,i,a),bundleUrl:r});if(!o)throw new t(`INVALID_ARGS`,`Unable to resolve Metro host and port for reload.`);return Ur(o,Wr(r))}function Jr(e,t,n,r){return e===`expo`?{command:`npx`,installArgs:[`expo`,`start`,`--host`,`lan`,`--port`,String(n)]}:e===`repack`?{command:`npx`,installArgs:[`react-native`,t===`webpack`?`webpack-start`:`rspack-start`,`--host`,r,`--port`,String(n)]}:{command:`npx`,installArgs:[`react-native`,`start`,`--host`,r,`--port`,String(n)]}}function Yr(e,n,r,i,a,o,c){let l=Jr(n,r,i,a);S.mkdirSync(C.dirname(o),{recursive:!0});let u=S.openSync(o,`a`),d=0;try{d=s(l.command,l.installArgs,{cwd:e,env:c,stdio:[`ignore`,u,u]})}finally{S.closeSync(u)}if(!Number.isInteger(d)||d<=0)throw new t(`COMMAND_FAILED`,`Failed to start React Native dev server. Expected a detached child PID.`);return{pid:d}}async function Xr(e){if(!(!Number.isInteger(e)||e<=0)){try{process.kill(e,`SIGTERM`)}catch(e){let t=e.code;if(t===`ESRCH`||t===`EPERM`)return;throw e}if(!await _e(e,1e3)){try{process.kill(e,`SIGKILL`)}catch(e){let t=e.code;if(t===`ESRCH`||t===`EPERM`)return;throw e}await _e(e,1e3)}}}function Zr(e,t){return{Authorization:`Bearer ${t}`,"Content-Type":`application/json`,...e.includes(`ngrok`)?{"ngrok-skip-browser-warning":`1`}:{}}}function X(e,n){let r=new t(`COMMAND_FAILED`,e);return r.retryable=n,r}function Qr(e,t){return!!(e>=500||e===408||e===425||e===429||JSON.stringify(t).includes(`Metro companion is not connected`))}function $r(e){return!!(e&&typeof e==`object`&&`retryable`in e&&e.retryable===!0)}async function ei(e){let t;try{t=await fetch(`${e.baseUrl}/api/metro/bridge`,{method:`POST`,headers:Zr(e.baseUrl,e.bearerToken),body:JSON.stringify({...e.scope,...e.runtime?{ios_runtime:e.runtime}:{},timeout_ms:e.timeoutMs}),signal:AbortSignal.timeout(e.timeoutMs)})}catch(t){throw t instanceof Error&&t.name===`TimeoutError`?X(`/api/metro/bridge timed out after ${e.timeoutMs}ms calling ${e.baseUrl}/api/metro/bridge`,!0):X(t instanceof Error?t.message:String(t),!0)}let n=ti(await t.text(),t.status,e.baseUrl);if(!t.ok)throw X(`/api/metro/bridge failed (${t.status}): ${JSON.stringify(n)}`,Qr(t.status,n));return ri(n)}function ti(e,t,n){if(!e)return{};try{let t=JSON.parse(e);if(!t||typeof t!=`object`||Array.isArray(t))throw Error(`Expected a JSON object`);return t}catch(r){let i=e.slice(0,200);throw X(`/api/metro/bridge returned invalid JSON (${t}) from ${n}: ${r instanceof Error?r.message:String(r)}. body=${JSON.stringify(i)}`,Qr(t,e))}}function ni(e){return{enabled:e.enabled,baseUrl:e.base_url,statusUrl:e.status_url??``,bundleUrl:e.bundle_url??``,iosRuntime:Rr(e.ios_runtime,`ios`),androidRuntime:Rr(e.android_runtime,`android`),upstream:{bundleUrl:e.upstream.bundle_url??``,host:e.upstream.host??``,port:e.upstream.port??0,statusUrl:e.upstream.status_url??``},probe:{reachable:e.probe.reachable,statusCode:e.probe.status_code,latencyMs:e.probe.latency_ms,detail:e.probe.detail}}}function ri(e){let t=e.data??e;if(!t||typeof t!=`object`||Array.isArray(t))throw X(`/api/metro/bridge returned malformed descriptor: Expected a JSON object.`,!1);try{return ni(t)}catch(e){throw X(`/api/metro/bridge returned malformed descriptor: ${e instanceof Error?e.message:String(e)}`,!1)}}function Z(e,t,n,r,i){let a=[`Metro bridge is required for this run but could not be configured via ${e}/api/metro/bridge.`];return t&&a.push(`bridgeError=${t}`),n?.probe.reachable===!1&&a.push(`bridgeProbe=${n.probe.detail||`unreachable (status ${n.probe.statusCode||0})`}`),r&&r!==t&&a.push(`initialBridgeError=${r}`),i&&a.push(`metroCompanionLog=${i}`),a.join(` `)}function ii(e,n){if(!n?.iosRuntime.bundleUrl)throw new t(`COMMAND_FAILED`,Z(e,`bridge descriptor is missing ios_runtime.metro_bundle_url`,n))}function ai(e,n,r){let i=n||K(r.AGENT_DEVICE_METRO_BEARER_TOKEN)||``,a=i||e&&K(r.AGENT_DEVICE_DAEMON_AUTH_TOKEN)||``;if(e&&!a)throw new t(`INVALID_ARGS`,`metro prepare requires proxy auth when --proxy-base-url is provided. Pass --bearer-token or set AGENT_DEVICE_METRO_BEARER_TOKEN or AGENT_DEVICE_DAEMON_AUTH_TOKEN.`);if(!e&&i)throw new t(`INVALID_ARGS`,`metro prepare requires --proxy-base-url when proxy auth is provided.`);return{proxyEnabled:!!(e&&a),proxyBaseUrl:e,proxyBearerToken:a}}function oi(e){if(!e?.tenantId||!e.runId||!e.leaseId)throw new t(`INVALID_ARGS`,`metro prepare with proxy requires tenantId, runId, and leaseId bridge scope.`);return e}function si(e,n){if(!(e||n))throw new t(`INVALID_ARGS`,`metro prepare requires --public-base-url <url> or --proxy-base-url <url>.`)}function ci(e,t,n){return e.runtimeFilePath?q(e.runtimeFilePath,t,n):null}function li(e,t,n,r){return q(e.logPath??C.join(r,`.agent-device`,`metro.log`),t,n)}function ui(e){let t=e.env??process.env,n=process.cwd(),r=q(e.projectRoot??n,t,n),i=e.kind??`auto`,a=null,o;i===`auto`?(a=Ar(r),o=Mr(a,i)):o=i;let s=null;o===`repack`&&(a??=Ar(r),s=Fr(r,a));let c=Or(e.publicBaseUrl),l=Or(e.proxyBaseUrl);si(c,l);let{proxyEnabled:u,proxyBaseUrl:d,proxyBearerToken:f}=ai(l,K(e.proxyBearerToken)??``,t);return{env:t,projectRoot:r,kind:o,repackBundler:s,metroPort:Ir(e.metroPort??8081,8081),listenHost:K(e.listenHost)??`0.0.0.0`,statusHost:K(e.statusHost)??`127.0.0.1`,publicBaseUrl:c,proxyBaseUrl:d,proxyBearerToken:f,bridgeScope:u?oi(e.bridgeScope):null,startupTimeoutMs:Y(e.startupTimeoutMs,18e4,3e4),probeTimeoutMs:Y(e.probeTimeoutMs,1e4,1e3),reuseExisting:e.reuseExisting??!0,installProjectDeps:e.installDependenciesIfNeeded??!0,runtimeFilePath:ci(e,t,n),logPath:li(e,t,n,r)}}async function di(e,t,n){let r=Date.now()+t;for(;Date.now()<r;){let t=r-Date.now();if(await Hr(e,Math.min(n,Math.max(t,1))))return!0;let i=Math.min(500,Math.max(r-Date.now(),0));i>0&&await Br(i)}return!1}async function fi(e){let n=Date.now()+e.startupTimeoutMs,r=null,i=null;for(;Date.now()<n;){try{let t=await ei({baseUrl:e.baseUrl,bearerToken:e.bearerToken,scope:e.scope,runtime:e.runtime,timeoutMs:e.probeTimeoutMs});if(t.probe.reachable!==!1)return t;r=t,i=null}catch(n){if(i=n instanceof Error?n.message:String(n),!$r(n))throw new t(`COMMAND_FAILED`,Z(e.baseUrl,i,r,e.initialBridgeError,e.companionLogPath),void 0,n)}let a=Math.min(1e3,Math.max(n-Date.now(),0));a>0&&await Br(a)}throw new t(`COMMAND_FAILED`,Z(e.baseUrl,i,r,e.initialBridgeError,e.companionLogPath))}async function pi(e){let n=`http://${e.statusHost}:${e.metroPort}/status`;if(e.reuseExisting&&await Hr(n,e.probeTimeoutMs))return{started:!1,reused:!0,pid:0,statusUrl:n};let r=Yr(e.projectRoot,e.kind,e.repackBundler,e.metroPort,e.listenHost,e.logPath,e.env);if(await di(n,e.startupTimeoutMs,e.probeTimeoutMs))return{started:!0,reused:!1,pid:r.pid,statusUrl:n};throw await Xr(r.pid).catch(()=>{}),new t(`COMMAND_FAILED`,`React Native dev server did not become ready at ${n} within ${e.startupTimeoutMs}ms. Check ${e.logPath}.`,{logPath:e.logPath})}async function mi(e,t){let n=t.bridgeScope;if(!n)return null;let r=null,i=null;try{r=await ei({baseUrl:t.proxyBaseUrl,bearerToken:t.proxyBearerToken,scope:n,timeoutMs:t.probeTimeoutMs})}catch(e){if(!$r(e))throw e;i=e instanceof Error?e.message:String(e)}return(!r||r.probe.reachable===!1)&&(r=await hi(e,t,n,r,i)),ii(t.proxyBaseUrl,r),r}async function hi(e,n,r,i,a){let o;try{o=(await ze({projectRoot:n.projectRoot,serverBaseUrl:n.proxyBaseUrl,bearerToken:n.proxyBearerToken,bridgeScope:r,localBaseUrl:`http://${n.statusHost}:${n.metroPort}`,launchUrl:K(e.launchUrl),profileKey:K(e.companionProfileKey),consumerKey:K(e.companionConsumerKey),env:n.env})).logPath}catch(e){throw new t(`COMMAND_FAILED`,Z(n.proxyBaseUrl,e instanceof Error?e.message:String(e),i,a),void 0,e)}try{return await fi({baseUrl:n.proxyBaseUrl,bearerToken:n.proxyBearerToken,scope:r,probeTimeoutMs:n.probeTimeoutMs,startupTimeoutMs:n.startupTimeoutMs,initialBridgeError:a,companionLogPath:o})}catch(e){throw e instanceof Error?e:Error(String(e))}}function gi(e){return{baseIosRuntime:e?Lr(e,`ios`):{platform:`ios`},baseAndroidRuntime:e?Lr(e,`android`):{platform:`android`}}}function _i(e,t){e&&(S.mkdirSync(C.dirname(e),{recursive:!0}),S.writeFileSync(e,JSON.stringify(t,null,2)))}async function vi(e={}){let t=ui(e),n=t.installProjectDeps?zr(t.projectRoot,t.env):{installed:!1},r=await pi(t),{baseIosRuntime:i,baseAndroidRuntime:a}=gi(t.publicBaseUrl),o=await mi(e,t),s=o?.iosRuntime??i,c=o?.androidRuntime??a,l={projectRoot:t.projectRoot,kind:t.kind,dependenciesInstalled:n.installed,packageManager:n.packageManager??null,started:r.started,reused:r.reused,pid:r.pid,logPath:t.logPath,statusUrl:r.statusUrl,runtimeFilePath:t.runtimeFilePath,iosRuntime:s,androidRuntime:c,bridge:o};return _i(t.runtimeFilePath,l),l}async function yi(e={}){let n=Y(e.timeoutMs,1e4,1e3),r=qr(e),i=await Vr(r,n);if(!i.ok)throw new t(`COMMAND_FAILED`,`React Native dev server reload failed (${i.status}).`,{reloadUrl:r,status:i.status,body:i.body,hint:`Verify Metro or Re.Pack is running and the target React Native app is connected to this dev server instance.`});return{reloaded:!0,reloadUrl:r,status:i.status,body:i.body}}const bi={...ke(),batch:De(xi)};function xi(e,n,r){let i=bi[e];if(!i)throw Error(`Missing daemon writer for batch command: ${e}`);let a=Ue(e);if(!a)throw Error(`Missing command metadata for batch command: ${e}`);try{return Ci(i,a,a.readInput(n))}catch(n){throw new t(`INVALID_ARGS`,`Batch step ${r} ${e} input is invalid: ${n instanceof Error?n.message:String(n)}`,void 0,n)}}function Si(e,t){let n=bi[e];if(!n)throw Error(`Missing daemon writer for command: ${e}`);return Ci(n,Ue(e),t)}function Ci(e,t,n){let r=e(n);return{...r,...t?{metadataFlags:je(t,r.options)}:{}}}function wi(e){throw new t(r(e.code),e.message,{...e.details??{},hint:e.hint,diagnosticId:e.diagnosticId,logPath:e.logPath,retriable:e.retriable,supportedOn:e.supportedOn})}var Ti=e({createAgentDeviceClient:()=>Ei});function Ei(e={},t={}){let r=t.transport??wr,i=t=>n(t.responseLevel??e.responseLevel),a=async(t,n=[],i={},a)=>{let o=$(e,i),s=await r({session:ve(o.session),command:t,positionals:n,flags:Oe(o,a),runtime:o.runtime,meta:Fe(o)});return s.ok||wi(s.error),s.data??{}},o=async(e={})=>{let t=await a(h.sessionList,[],e);return(Array.isArray(t.sessions)?t.sessions:[]).map(xe)},s=async(e,t={})=>{let n=Si(e,t);return await a(n.command,n.positionals,n.options,n.metadataFlags)},c=(t={})=>ve($(e,t).session);return{command:{wait:async e=>await s(`wait`,e),alert:async(e={})=>await s(`alert`,e),...ki(s),reactNative:async e=>await s(`react-native`,e),doctor:async(e={})=>await s(`doctor`,e),prepare:async e=>await s(`prepare`,e),viewport:async e=>await s(`viewport`,e)},devices:{list:async(e={})=>{let t=await s(`devices`,e);return(Array.isArray(t.devices)?t.devices:[]).map(Pe)},capabilities:async(e={})=>{let t=await s(`capabilities`,e),n=Array.isArray(t.availableCommands)?t.availableCommands.filter(e=>typeof e==`string`):[];return{device:Pe(t.device),availableCommands:n}},boot:async(e={})=>await s(`boot`,e),shutdown:async(e={})=>await s(`shutdown`,e)},sessions:{list:async(e={})=>await o(e),stateDir:async(t={})=>g($(e,t).stateDir??process.env.AGENT_DEVICE_STATE_DIR).baseDir,close:async(e={})=>{let t=c(e),n=await s(`close`,e);return{session:t,shutdown:Se(n.shutdown),provider:Q(n.provider),identifiers:{session:t}}},artifacts:async(e={})=>await s(`artifacts`,e)},apps:{install:async e=>Ee(await s(`install`,e),c(e)),reinstall:async e=>Ee(await s(`reinstall`,e),c(e)),installFromSource:async e=>we(await s(`install-from-source`,e),c(e)),list:async(e={})=>{let t=await s(`apps`,e);return Array.isArray(t.apps)?t.apps.filter(e=>typeof e==`string`):[]},open:async e=>{let t=c(e),n=await s(`open`,e),r=Ne(n),i=b(n,`appBundleId`),a=i;return{session:t,sessionStateDir:b(n,`sessionStateDir`),eventLogPath:b(n,`eventLogPath`),appName:b(n,`appName`),appBundleId:i,appId:a,startup:be(n.startup),runtime:Te(n.runtime),device:r,identifiers:{session:t,deviceId:r?.id,deviceName:r?.name,udid:r?.ios?.udid,serial:r?.android?.serial,appId:a,appBundleId:i}}},close:async(e={})=>{let t=c(e),n=await s(`close`,e);return{session:t,closedApp:e.app,shutdown:Se(n.shutdown),identifiers:{session:t}}},push:async e=>await s(`push`,e),triggerEvent:async e=>await s(`trigger-app-event`,e)},materializations:{release:async e=>ye(await a(h.releaseMaterializedPaths,[],{...e,materializationId:e.materializationId}))},leases:{allocate:async e=>Ai(await a(h.leaseAllocate,[],{...e,leaseId:void 0})),heartbeat:async e=>Ai(await a(h.leaseHeartbeat,[],e)),release:async e=>{let t=await a(h.leaseRelease,[],e);return{released:t.released===!0,provider:Q(t.provider)}}},metro:{prepare:async t=>await vi({projectRoot:t.projectRoot??e.cwd,kind:t.kind,publicBaseUrl:t.publicBaseUrl,proxyBaseUrl:t.proxyBaseUrl,proxyBearerToken:t.bearerToken,bridgeScope:t.bridgeScope,launchUrl:t.launchUrl,companionProfileKey:t.companionProfileKey,companionConsumerKey:t.companionConsumerKey,metroPort:t.port,listenHost:t.listenHost,statusHost:t.statusHost,startupTimeoutMs:t.startupTimeoutMs,probeTimeoutMs:t.probeTimeoutMs,reuseExisting:t.reuseExisting,installDependenciesIfNeeded:t.installDependenciesIfNeeded,runtimeFilePath:t.runtimeFilePath,logPath:t.logPath}),reload:async(t={})=>await yi({metroHost:t.metroHost,metroPort:t.metroPort,bundleUrl:t.bundleUrl,runtime:e.runtime,timeoutMs:t.timeoutMs})},capture:{snapshot:async(e={})=>{let t=c(e),n=await s(`snapshot`,e);return i(e)?n:Di(n,t)},screenshot:async(e={})=>{let t=c(e),n=await s(`screenshot`,e);if(i(e))return n;let r=de(n);return{path:x(n,`path`),width:r?.width,height:r?.height,logicalWidth:r?.logicalWidth,logicalHeight:r?.logicalHeight,pixelDensity:r?.pixelDensity,overlayRefs:r?.overlayRefs,identifiers:{session:t}}},diff:async e=>await s(`diff`,e)},interactions:{click:async e=>await s(`click`,e),press:async e=>await s(`press`,e),longPress:async e=>await s(`longpress`,e),swipe:async e=>await s(`swipe`,e),pan:async e=>await s(`gesture-pan`,e),fling:async e=>await s(`gesture-fling`,e),swipeGesture:async e=>await s(`gesture-swipe`,e),focus:async e=>await s(`focus`,e),type:async e=>await s(`type`,e),fill:async e=>await s(`fill`,e),scroll:async e=>await s(`scroll`,e),pinch:async e=>await s(`gesture-pinch`,e),rotateGesture:async e=>await s(`gesture-rotate`,e),transformGesture:async e=>await s(`gesture-transform`,e),get:async e=>await s(`get`,e),is:async e=>await s(`is`,e),find:async e=>await s(`find`,e)},replay:{run:async e=>await s(`replay`,e),test:async e=>await s(`test`,e)},batch:{run:async e=>await s(`batch`,e)},observability:{perf:async(e={})=>await s(`perf`,e),logs:async(e={})=>await s(`logs`,e),events:async(e={})=>await s(`events`,e),network:async(e={})=>await s(`network`,e),audio:async(e={})=>await s(`audio`,e)},debug:{symbols:async t=>{let{symbolicateCrashArtifact:n}=await import(`./debug-symbols.js`);return n({cwd:t.cwd??e.cwd,...t})}},recording:{record:async e=>await s(`record`,e),trace:async e=>await s(`trace`,e)},settings:{update:async e=>await s(`settings`,e)}}}function Di(e,t){let n=b(e,`appBundleId`);return{nodes:Ae(e.nodes),truncated:e.truncated===!0,appName:b(e,`appName`),appBundleId:n,...Oi(e),identifiers:{session:t,appId:n,appBundleId:n}}}function Oi(e){let t=Q(e.visibility),n=Q(e.unchanged),r=ue(e.snapshotDiagnostics);return{...t?{visibility:t}:{},...ee(e),...n?{unchanged:n}:{},...r?{snapshotDiagnostics:r}:{}}}function ki(e){let t={};for(let[n,r]of Object.entries(Me.clientCommandMethods??{}))t[n]=async(t={})=>await e(r,t);return t}function Q(e){return Ie(e)?e:void 0}function $(e,t){return{...e,...t}}function Ai(e){let t=e.lease;if(!Ie(t))throw Error(`Invalid lease response from daemon`);return{leaseId:x(t,`leaseId`),tenantId:x(t,`tenantId`),runId:x(t,`runId`),backend:x(t,`backend`),leaseProvider:b(t,`leaseProvider`),clientId:b(t,`clientId`),deviceKey:b(t,`deviceKey`),createdAt:typeof t.createdAt==`number`?t.createdAt:void 0,heartbeatAt:typeof t.heartbeatAt==`number`?t.heartbeatAt:void 0,expiresAt:typeof t.expiresAt==`number`?t.expiresAt:void 0}}export{Qn as a,Ze as c,ir as i,D as l,Ei as n,Xe as o,wr as r,O as s,Ti as t};
|
package/dist/src/contracts.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{S as e,u as t,y as n}from"./sdk-contracts.js";export{t as centerOfRect,n as defaultHintForCode,e as normalizeError};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{_ as e}from"./sdk-contracts.js";import{h as t,v as n}from"./sdk-android-adb.js";import{l as r}from"./sdk-batch-runner.js";import i from"node:path";import a from"node:fs/promises";const o=/^[0-9a-fA-F-]{32,36}$/;function s(e){if(!(!e||!o.test(e)))return e.replaceAll(`-`,``).toUpperCase()}function c(e,t){return`${e.uuid}:${l(t)}`}function l(e){return`0x${e.toString(16)}`}function u(e){return typeof e==`string`&&e.length>0?e:void 0}function d(...e){for(let t of e){let e=u(t);if(e)return e}}function f(e){let t=e.filter(e=>!!e);return t.length>0?t.join(` `):void 0}function p(e){try{let t=JSON.parse(e);return r(t)?t:null}catch{return null}}function m(e){if(typeof e==`number`&&Number.isSafeInteger(e))return e;if(typeof e==`string`){let t=e.startsWith(`0x`)?Number.parseInt(e,16):Number(e);return Number.isSafeInteger(t)?t:void 0}}function h(e,t,n){if(!Object.hasOwn(e,t))return;let r=m(e[t]);if(r!==void 0)return r;v(n,t)}function g(e,t,n){if(!Object.hasOwn(e,t))return;let r=_(e[t]);if(r!==void 0)return r;v(n,t)}function _(e){if(typeof e==`bigint`)return e;if(typeof e==`number`&&Number.isSafeInteger(e)||typeof e==`string`&&/^(?:0x[0-9a-fA-F]+|\d+)$/.test(e))return BigInt(e)}function v(t,n){throw new e(`INVALID_ARGS`,`Invalid ${t} numeric field: ${n}`,{hint:`Crash artifact numeric fields must be integer numbers or integer numeric strings.`})}function y(e){return e.length===1?e[0]:void 0}function b(e){return[...new Set(e)]}function x(e){let t=e.match(/^(.*) \+ (\d+)$/);return t?{symbol:t[1],location:Number(t[2])}:{symbol:e}}const S=/^(?:arm64e?|arm64_32|x86_64|armv7[sk]?|i386)$/;function ee(e){return te(e)??w(e)}function te(e){let t=ne(e);if(!t)return null;let n=(Array.isArray(t.payload.usedImages)?t.payload.usedImages:[]).flatMap((e,t)=>C(e,t));if(n.length===0)return null;let r=re(Array.isArray(t.payload.threads)?t.payload.threads:[],n);return{format:`ips`,images:n,addresses:r.map(({frame:e,...t})=>t),document:t,frameMatches:r,write:e=>oe(t,r,e)}}function ne(e){let t=p(e);if(t)return{payload:t};let n=e.indexOf(`
|
|
2
2
|
`);if(n===-1)return null;let r=e.slice(0,n),i=p(e.slice(n+1));return i?{header:r,payload:i}:null}function re(e,t){let n=new Map(t.map(e=>[e.index,e]));return e.flatMap((e,t)=>ie(e).flatMap((e,r)=>ae(e,n,t,r)))}function ie(e){return!r(e)||!Array.isArray(e.frames)?[]:e.frames.filter(r)}function ae(e,t,n,r){let i=h(e,`imageIndex`,`IPS frame`),a=g(e,`imageOffset`,`IPS frame`);if(i===void 0||a===void 0)return[];let o=t.get(i);return o?[{frame:e,frameIndex:r,threadIndex:n,image:o,address:o.base+a}]:[]}function oe(e,t,n){for(let e of t){let t=n.get(c(e.image,e.address))?.text;t&&se(e.frame,t)}e.payload.agentDeviceSymbolication={tool:`agent-device debug symbols`,symbolicatedFrames:[...n.values()].filter(e=>e.text).length};let r=`${JSON.stringify(e.payload,null,2)}\n`;return e.header?`${e.header}\n${r}`:r}function se(e,t){let n=x(t);e.symbol=n.symbol,n.location!==void 0&&(e.symbolLocation=n.location)}function C(e,t){if(!r(e))return[];let n=s(u(e.uuid)),a=g(e,`base`,`IPS usedImages`);if(!n||a===void 0)return[];let o=u(e.path);return[{index:t,name:u(e.name)??(o?i.basename(o):`image-${t}`),uuid:n,arch:u(e.arch),base:a,path:o}]}function w(e){let t=e.split(`
|
|
3
3
|
`),n=T(t);if(n.length===0)return null;let r=O(t,n);return{format:`text`,images:n,addresses:r,lines:t,frameMatches:r,write(e){let n=new Map(r.map(e=>[e.lineIndex,e]));return t.map((t,r)=>{let i=n.get(r);if(!i)return t;let a=e.get(c(i.image,i.address))?.text;return!a||t.includes(a)?t:`${t} // ${a}`}).join(`
|
|
4
4
|
`)}}}function T(e){let t=[],n=e.findIndex(e=>/^Binary Images:/i.test(e.trim()));if(n===-1)return t;for(let r of e.slice(n+1)){let e=E(r);e&&t.push(e)}return t}function E(e){let t=e.match(/^\s*(0x[0-9a-fA-F]+)\s*-\s*(0x[0-9a-fA-F]+)\s+\+?(.+?)\s+<([0-9a-fA-F-]{32,36})>\s+(.+)$/);if(!t)return null;let n=s(t[4]);if(!n)return null;let r=D(t[3].trim(),t[5].trim());return{name:r.name,arch:r.arch,uuid:n,base:BigInt(t[1]),end:BigInt(t[2]),path:t[5].trim()}}function D(e,t){let n=e.split(/\s+/),r=n.at(-1);if(r&&S.test(r))return{name:n.slice(0,-1).join(` `).trim(),arch:r};let a=i.basename(t);return{name:e.startsWith(a)?a:e}}function O(e,t){let n=[],r;for(let[i,a]of e.entries()){let e=a.match(/^Thread\s+(\d+)\s+Crashed:/);e?r=Number(e[1]):(a.trim().length===0||/^Thread\s+\d+/.test(a))&&(r=void 0);let o=k(a,t),s=a.match(/^\s*(\d+)/);o&&s&&n.push({...o,frameIndex:Number(s[1]),lineIndex:i,threadIndex:r})}return n}function k(e,t){let n=e.match(/^\s*\d+\s+(.+?)\s+(0x[0-9a-fA-F]+)\b/);if(!n)return null;let r=n[1].trim(),i=BigInt(n[2]),a=A(t,r,i);return a?{image:a,address:i}:null}function A(e,t,n){let r=e.filter(e=>e.name===t);return r.find(e=>j(e,n))??y(r)}function j(e,t){return e.end!==void 0&&e.base<=t&&t<=e.end}const M=1e4;async function N(e){return e.dsym&&e.searchPath?[H(e.cwd,e.dsym),...await P(H(e.cwd,e.searchPath))]:e.dsym?[H(e.cwd,e.dsym)]:e.searchPath?await P(H(e.cwd,e.searchPath)):[]}async function P(t){let n=[],r=0;async function o(s){if(n.length>=200)return;if(r+=1,r>M)throw new e(`COMMAND_FAILED`,`debug symbols search-path scan exceeded bounds.`,{searchPath:t,maxEntries:M,hint:`Pass --dsym <App.dSYM> directly or narrow --search-path to the build products directory.`});if(!(await F(s,t)).isDirectory()){s===t&&I(t);return}if(s.endsWith(`.dSYM`)){n.push(s);return}let c=await a.readdir(s,{withFileTypes:!0});for(let e of c)e.isDirectory()&&await o(i.join(s,e.name))}return await o(t),n}async function F(t,n){try{return await a.stat(t)}catch{throw new e(`INVALID_ARGS`,`debug symbols search path does not exist: ${n}`,{hint:`Pass an existing build products directory to --search-path, or pass --dsym <App.dSYM> directly.`})}}function I(t){throw new e(`INVALID_ARGS`,`debug symbols search path is not a directory: ${t}`,{hint:`Pass an existing build products directory to --search-path, or pass --dsym <App.dSYM> directly.`})}async function L(t,n){let r=(await Promise.all(b(t).map(e=>R(e,n)))).flat();if(r.length===0)throw new e(`COMMAND_FAILED`,`No UUIDs found in dSYM bundle.`,{hint:`Verify the path points to a built .dSYM bundle with DWARF contents.`});return r}async function R(e,r){return await z(e),B(e,t(await n(r,[`--uuid`,e],{timeoutMs:15e3,allowFailure:!0}),`Failed to inspect dSYM UUIDs: ${e}`,{hint:`Verify the dSYM bundle is valid and readable.`}).stdout)}async function z(t){if(!((await a.stat(t).catch(()=>null))?.isDirectory()&&t.endsWith(`.dSYM`)))throw new e(`INVALID_ARGS`,`Not a .dSYM bundle: ${t}`,{hint:`Pass the .dSYM bundle path, not the DWARF executable inside it.`})}function B(e,t){return t.split(`
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{t as e}from"./rolldown-runtime.js";import{
|
|
1
|
+
import{t as e}from"./rolldown-runtime.js";import{_ as t}from"./sdk-contracts.js";import{c as n,j as r,n as i}from"./sdk-android-adb.js";import{t as a}from"./timeouts.js";import{a as o,f as s,i as c,o as l,t as u}from"./android-input-ownership.js";var d=e({dismissAndroidKeyboard:()=>v,dismissAndroidKeyboardWithAdb:()=>y,getAndroidKeyboardState:()=>g,getAndroidKeyboardStatusWithAdb:()=>_,readAndroidClipboardText:()=>A,readAndroidClipboardWithAdb:()=>j,writeAndroidClipboardText:()=>M,writeAndroidClipboardWithAdb:()=>N});const f=[`mInputShown`,`mIsInputViewShown`,`isInputViewShown`,`mDecorViewVisible`,`mWindowVisible`,`mInShowWindow`],p=new Map([[2,`number`],[3,`phone`],[4,`datetime`]]),m=new Set([32,208]),h=new Set([128,224,144]);async function g(e){return await _(n(e))}async function _(e){let t=await e([`shell`,`dumpsys`,`input_method`],{allowFailure:!0});if(t.exitCode!==0)throw i(`Failed to query Android keyboard state`,t);return b(t.stdout)}async function v(e){return await y(n(e))}async function y(e){let n=await _(e),r=n,i=0;for(;r.visible&&i<2;)await e([`shell`,`input`,`keyevent`,`111`]),i+=1,await a(120),r=await _(e);if(n.visible&&r.visible)throw new t(`UNSUPPORTED_OPERATION`,`Android keyboard dismiss is unavailable for the current IME without back navigation.`,{attempts:i,inputType:r.inputType,type:r.type,inputMethodPackage:r.inputMethodPackage,focusedPackage:r.focusedPackage,focusedResourceId:r.focusedResourceId,inputOwner:r.inputOwner});return{attempts:i,wasVisible:n.visible,dismissed:n.visible&&!r.visible,visible:r.visible,inputType:r.inputType,type:r.type,inputMethodPackage:r.inputMethodPackage,focusedPackage:r.focusedPackage,focusedResourceId:r.focusedResourceId,inputOwner:r.inputOwner}}function b(e){let t=T(e)??x(e),n=S(e),r=C(e,/\bpackageName=([A-Za-z0-9_.]+)\b/g),i=C(e,/\b(?:resourceId|resource-id)=([^\s,}]+)/g),a=l(e),o=u(r,i,a);return w(r,i,a),{visible:t??!1,inputType:n,type:n?k(n):void 0,inputMethodPackage:a,focusedPackage:r,focusedResourceId:i,inputOwner:o}}function x(e){let t=e.match(/\bmImeWindowVis=0x([0-9a-fA-F]+)\b/)?.[1];if(!t)return null;let n=Number.parseInt(t,16);return Number.isNaN(n)?null:(n&1)!=0}function S(e){let t=C(e,/\binputType=0x([0-9a-fA-F]+)\b/gi);return t?`0x${t.toLowerCase()}`:void 0}function C(e,t){let n;for(let r of e.matchAll(t))n=r[1];return n}function w(e,t,n){n||!c(e)&&!o(t)||r({level:`warn`,phase:`android_input_ownership_fallback`,data:{focusedPackage:e,focusedResourceId:t}})}function T(e){return D(E(e,f))}function E(e,t){let n=new Map,r=RegExp(`\\b(${t.join(`|`)})=([a-zA-Z]+)\\b`,`g`);for(let t of e.matchAll(r)){let e=t[1],r=t[2]?.toLowerCase();!e||r!==`true`&&r!==`false`||n.set(e,r===`true`)}return n}function D(e){if(e.size===0)return null;let t=O(e,[`mWindowVisible`,`mDecorViewVisible`,`mInShowWindow`]);if(t!==void 0)return t;let n=e.get(`mInputShown`);return n===void 0?O(e,[`mIsInputViewShown`,`isInputViewShown`])??null:n}function O(e,t){for(let n of t){let t=e.get(n);if(t!==void 0)return t}}function k(e){let t=Number.parseInt(e.replace(/^0x/i,``),16);if(Number.isNaN(t))return`unknown`;let n=t&15,r=p.get(n);if(r)return r;if(n!==1)return`unknown`;let i=t&4080;return m.has(i)?`email`:h.has(i)?`password`:`text`}async function A(e){return await j(n(e))}async function j(e){return F(await P(e,[`shell`,`cmd`,`clipboard`,`get`,`text`],`read`))}async function M(e,t){await N(n(e),t)}async function N(e,t){await P(e,[`shell`,`cmd`,`clipboard`,`set`,`text`,t],`write`)}async function P(e,n,r){let a=await e(n,{allowFailure:!0});if(s(a.stdout,a.stderr))throw new t(`UNSUPPORTED_OPERATION`,`Android shell clipboard ${r} is not supported on this device.`);if(a.exitCode!==0)throw i(`Failed to ${r} Android clipboard text`,a);return a.stdout}function F(e){let t=e.replace(/\r\n/g,`
|
|
2
2
|
`).replace(/\n$/,``),n=t.match(/^clipboard text:\s*(.*)$/i);return n?n[1]??``:t.trim().toLowerCase()===`null`?``:t}export{A as a,N as c,_ as i,y as n,j as o,g as r,M as s,d as t};
|
package/dist/src/devices2.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{_ as e}from"./sdk-contracts.js";import{s as t,v as n}from"./sdk-device.js";import{x as r}from"./android-input-ownership.js";import{a as i,r as a}from"./tool-provider.js";import{t as o}from"./simctl.js";import{r as s}from"./simulator.js";import{buildHostMacDevice as c}from"./devices.js";import{promises as l}from"node:fs";import u from"node:os";import d from"node:path";const f=/^(iphone|ipad|ipod|appletv|realitydevice)/i,p=/ipad/i,m=/\b(apple vision|vision pro|xros|visionos|realitydevice)\b/i,h=/\b(iphone|ipad|ipod)\b/i,g=/^appletv/i,_=[`apple tv`,`appletv`,`tvos`],v=/^==\s*(.+?)\s*==$/,y=/^(?<name>.+?)\s+\[(?<id>[^[\]]+)\]\s*$/;function b(e){return(e??``).trim().toLowerCase()}function x(e){return b(e)}function S(e){return b(e.hardwareProperties?.platform)}function C(e){return e.includes(`tvos`)}function w(e){return e.includes(`xros`)||e.includes(`visionos`)}function T(e){return C(x(e))?`tv`:`mobile`}function E(e){let t=x(e);return t.includes(`ios`)||t.includes(`tvos`)||t.includes(`xros`)||t.includes(`visionos`)}function D(e){let t=b(e);return _.some(e=>t.includes(e))}function O(e){return h.test(e.trim())}function k(e){return D(e)?`tv`:O(e)||m.test(e)?`mobile`:null}function A(e,t){return e===`tv`?`tvos`:t.some(e=>m.test(e))?`visionos`:t.some(e=>p.test(e))?`ipados`:`ios`}function j(e){return f.test(e.trim())}function M(e){return g.test(e.trim())}function N(e){return[e.name??``,e.deviceProperties?.name??``,e.deviceProperties?.deviceType??``]}function P(e){return e.hardwareProperties?.productType??e.deviceProperties?.productType??``}function F(e){return C(S(e))||M(P(e))||N(e).some(D)?`tv`:`mobile`}function I(e){let t=S(e);return t.includes(`ios`)||t.includes(`tvos`)||w(t)||j(P(e))?!0:N(e).some(D)}async function L(e={}){let t=r(e.simulatorSetPath),a=e.target,s;try{s=await i(o([`list`,`devices`,`-j`],{simulatorSetPath:t}))}catch{return null}let c;try{c=JSON.parse(s.stdout)}catch{return null}return n(R(c,t)).find(e=>!a||e.target===a)??null}function R(e,t){let n=[];for(let[r,i]of Object.entries(e.devices))if(E(r))for(let e of i){if(!e.isAvailable)continue;let i=T(r),a={platform:`apple`,id:e.udid,name:e.name,kind:`simulator`,target:i,appleOs:A(i,[e.deviceTypeIdentifier??``,e.name]),booted:e.state===`Booted`,...t?{simulatorSetPath:t}:{}};a.booted&&s(a),n.push(a)}return n}function z(e){let t=[];for(let n of e.result?.devices??[]){if(!I(n))continue;let e=n.hardwareProperties?.udid??n.identifier??``,r=n.name??n.deviceProperties?.name??e;if(!e)continue;let i=F(n);t.push({platform:`apple`,id:e,name:r,kind:`device`,target:i,appleOs:A(i,[P(n),...N(n)]),booted:!0})}return t}function B(e){let t=[],n=null;for(let r of e.split(/\r?\n/)){let e=r.trim();if(!e)continue;let i=v.exec(e);if(i){n=i[1]?.trim()??null;continue}if(n!==`Devices`)continue;let a=y.exec(e),o=a?.groups?.id?.trim()??``,s=a?.groups?.name?.trim()??``;if(!o||!s)continue;let c=k(s);c&&t.push({platform:`apple`,id:o,name:s,kind:`device`,target:c,appleOs:A(c,[s]),booted:!0})}return t}function V(e,t){let n=new Set(e.map(e=>e.id)),r=[...e];for(let e of t)n.has(e.id)||(n.add(e.id),r.push(e));return r}async function H(){let e=null;try{if(e=d.join(u.tmpdir(),`agent-device-devicectl-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`),(await i([`devicectl`,`list`,`devices`,`--json-output`,e],{allowFailure:!0,timeoutMs:8e3})).exitCode!==0)return[];let t=await l.readFile(e,`utf8`);return z(JSON.parse(t))}catch{return[]}finally{e&&await l.rm(e,{force:!0}).catch(()=>{})}}async function U(){try{let e=await i([`xctrace`,`list`,`devices`],{allowFailure:!0});return e.exitCode===0?B(e.stdout):[]}catch{return[]}}async function W(s={}){if(process.platform!==`darwin`)throw new e(`UNSUPPORTED_PLATFORM`,`Apple tools are only available on macOS`);if(!await a().whichCommand(`xcrun`))throw new e(`TOOL_MISSING`,`xcrun not found in PATH`);let l=r(s.simulatorSetPath),u=await i(o([`list`,`devices`,`-j`],{simulatorSetPath:l})),d=[];try{d=R(JSON.parse(u.stdout),l)}catch(t){throw new e(`COMMAND_FAILED`,`Failed to parse simctl devices JSON`,void 0,t)}if(d.push(c()),s.udid&&d.some(e=>t(e)&&e.id===s.udid))return d;if(l)return n(d);let[f,p]=await Promise.all([H(),U()]);return d=V(d,f),n(V(d,p))}export{L as findBootableIosSimulator,W as listAppleDevices};
|
package/dist/src/find.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{u as e}from"./sdk-contracts.js";import{F as t,G as n,I as r,Sn as i,xn as a}from"./tv-remote.js";import{t as o}from"./timeouts.js";import{d as s}from"./sdk-selectors.js";import{t as c}from"./snapshot-quality.js";import{a as l,o as u,r as d}from"./sdk-finders.js";import{a as f}from"./selectors2.js";import{Pt as p,Ut as m,Wt as h,Xt as g,an as _,in as v,mn as y}from"./internal/daemon.js";import{a as b}from"./apple-runner-options.js";import{a as x,t as S,w as C}from"./selector-runtime.js";import{t as w}from"./handler-utils.js";async function T(e){let{req:t,sessionName:n,logPath:r,sessionStore:i,invoke:a}=e,o=t.command;if(o!==`find`)return null;let s=t.positionals??[];if(s.length===0)return v(`INVALID_ARGS`,`find requires a locator or text`);let{locator:d,query:f,action:m,value:h,timeoutMs:g}=l(s);if(!f)return v(`INVALID_ARGS`,`find requires a value`);if(t.flags?.findFirst&&t.flags?.findLast)return v(`INVALID_ARGS`,`find accepts only one of --first or --last`);let x=await S({req:t,sessionName:n,logPath:r,sessionStore:i});if(x)return x;let C=i.get(n),w=D(m);if(!C&&!w)return _();let T=C?.device??await y(t.flags??{});C||await b(T);let M=O(m),N=u(d,f),P=k({device:T,session:C,req:t,logPath:r,locator:d,query:f,scope:T.platform!==`web`&&!N&&$(d)&&!M?f:void 0,interactiveOnly:M,sessionStore:i,sessionName:n}),F={req:t,sessionName:n,logPath:r,sessionStore:i,invoke:a,session:C,device:T,command:o,locator:d,query:f,publicFlags:Q(t.flags)};if(m===`wait`)return V(F,P,d,f,g);let I=await P();if(c(I.snapshotQuality))return A(I.snapshotQuality);let{nodes:L}=I,z=j({nodes:L,locator:d,query:f,selectorChain:N,requiresRect:M,flags:t.flags,platform:T.platform});if(!z.ok)return z.response;let B=z.node,Y=M?R(L,B):B,X={node:B,resolvedNode:Y,ref:`@${Y.ref}`,nodes:L,actionFlags:{...t.flags??{},noRecord:!0}};C&&(p(C),i.set(n,C));let Z={exists:()=>H(F),get_text:()=>U(F,X),get_attrs:()=>W(F,X),click:()=>G(F,X),fill:()=>K(F,X,h),focus:()=>q(F,X),type:()=>J(F,X,h)}[m];return Z?E(await Z(),()=>i.get(n)):null}function E(e,t){if(!e?.ok||!e.data||typeof e.data.ref!=`string`)return e;let n=t()?.snapshotGeneration;return n===void 0?e:{...e,data:{...e.data,refsGeneration:n}}}function D(e){return e===`exists`||e===`wait`||e===`get_text`||e===`get_attrs`}function O(e){return e===`click`||e===`focus`||e===`fill`||e===`type`}function k(e){let{device:t,session:n,req:r,logPath:i,locator:a,query:o,scope:s,interactiveOnly:c}=e,{sessionStore:l,sessionName:u}=e,d=x({device:t,session:n,sessionStore:l,sessionName:u,req:r,logPath:i});return async()=>{let{snapshot:e}=await d.capture({flags:{...r.flags,snapshotInteractiveOnly:c},snapshotScope:s,recovery:c?{legacyIosSparse:{query:o,scope:s,shouldScope:$(a)},sparseVerdictQueryScope:{query:o,shouldScope:$(a)}}:void 0});return{nodes:e.nodes,truncated:e.truncated,backend:e.backend,snapshotQuality:e.snapshotQuality}}}function A(e){return v(`COMMAND_FAILED`,`find could not read the current accessibility tree`,{reason:e.reason,hint:`The snapshot quality verdict is sparse. Use screenshot as visual truth, navigate with coordinates if needed, then retry find after reaching a readable screen.`})}function j(e){let{nodes:t,locator:n,query:r,selectorChain:i,requiresRect:a,flags:o,platform:s}=e,c=a?t.filter(e=>!z(e,t[0])):t;if(i){let e=f(c,i,{platform:s,requireRect:a,requireUnique:!1});return e?{ok:!0,node:e.node}:{ok:!1,response:v(`COMMAND_FAILED`,`find did not match any element`)}}let l=d(c,n,r,{requireRect:a});if(a&&(l.matches=N(l.matches,t)),a&&l.matches.length>1){let e=M(l.matches,o);if(!e)return{ok:!1,response:ee(l.matches,n,r)};l.matches=e}let u=l.matches[0]??null;return u?{ok:!0,node:u}:{ok:!1,response:v(`COMMAND_FAILED`,`find did not match any element`)}}function M(e,t){return t?.findFirst?[e[0]]:t?.findLast?[e[e.length-1]]:null}function N(t,n){let r=n[0]?.rect;if(!r)return t;let i=t.filter(t=>{if(!t.rect)return!1;let n=e(t.rect);return n.x>=r.x&&n.x<=r.x+r.width&&n.y>=r.y&&n.y<=r.y+r.height});return P(i.length>0?i:t,n)}function P(e,t){return e.length<2?e:e.map((e,n)=>({node:e,index:n,score:F(e,t)})).sort((e,t)=>t.score===e.score?L(e.node)-L(t.node)||e.index-t.index:t.score-e.score).map(e=>e.node)}function F(e,t){let n=r(t,e);if(n.reason===`covered`)return 0;let i=I(n,t[0]);return i>0?i:e.hittable&&e.rect&&!z(e,t[0])?3:+!!e.rect}function I(e,t){return e.node.rect?e.reason===`semantic-target`||e.reason===`same-rect-descendant`?4:e.reason===`hittable-ancestor`&&!z(e.node,t)?2:0:0}function L(e){return e.rect?e.rect.width*e.rect.height:1/0}function R(e,n){let r=t(e,n);return z(r,e[0])&&n.rect?n:r}function z(e,t){if(!t?.rect||!e.rect)return!1;let n=e.type?.toLowerCase()??``;return!n.includes(`application`)&&!n.includes(`window`)?!1:B(e.rect,t.rect)}function B(e,t){return e.x===t.x&&e.y===t.y&&e.width===t.width&&e.height===t.height}async function V(e,t,n,r,i){let{req:a,sessionStore:s,session:l,command:u,publicFlags:f}=e,p=i??1e4,m=Date.now(),h;for(;Date.now()-m<p;){let{nodes:e,snapshotQuality:i}=await t();if(c(i)){h=i,await o(300);continue}if(d(e,n,r,{requireRect:!1}).matches[0])return w(s,l,a,u,{found:!0,waitedMs:Date.now()-m},{flags:f}),{ok:!0,data:{found:!0,waitedMs:Date.now()-m}};await o(300)}return h?A(h):v(`COMMAND_FAILED`,`find wait timed out`)}async function H(e){let{req:t,sessionStore:n,session:r,command:i,publicFlags:a}=e;return w(n,r,t,i,{found:!0},{flags:a}),{ok:!0,data:{found:!0}}}async function U(e,t){let{req:n,sessionStore:r,session:i,command:a,device:o,logPath:s,publicFlags:c}=e,l=await C({device:o,node:t.node,flags:n.flags,appBundleId:i?.appBundleId,traceOutPath:i?.trace?.outPath,surface:i?.surface,contextFromFlags:(e,t,n)=>h(s,e,t,n)});return w(r,i,n,a,{ref:t.ref,action:`get text`,text:l},{flags:c}),{ok:!0,data:{ref:t.ref,text:l,node:t.node}}}async function W(e,t){let{req:n,sessionStore:r,session:i,command:a,publicFlags:o}=e;return w(r,i,n,a,{ref:t.ref,action:`get attrs`},{flags:o}),{ok:!0,data:{ref:t.ref,node:t.node}}}async function G(t,n){let{req:r,sessionName:o,sessionStore:s,session:c,invoke:l,command:u,locator:d,query:f,publicFlags:p}=t,m=await l({token:r.token,session:o,command:`click`,positionals:[n.ref],flags:n.actionFlags});if(!m.ok)return m;let h=n.resolvedNode.rect?e(n.resolvedNode.rect):n.node.rect?e(n.node.rect):null,g={ref:n.ref,locator:d,query:f};h&&(g.x=h.x,g.y=h.y);let _=a(m.data)??`Tapped ${n.ref}${h?` (${h.x}, ${h.y})`:``}`;return Object.assign(g,i(_)),w(s,c,r,u,{ref:n.ref,action:`click`,locator:d,query:f},{flags:p}),{ok:!0,data:g}}async function K(e,t,n){let{req:r,sessionName:i,sessionStore:a,session:o,invoke:s,command:c,publicFlags:l}=e;if(!n)return v(`INVALID_ARGS`,`find fill requires text`);let u=await s({token:r.token,session:i,command:`fill`,positionals:[t.ref,n],flags:t.actionFlags});return u.ok&&w(a,o,r,c,{ref:t.ref,action:`fill`},{flags:l}),u}async function q(e,t){let n=await Y(e,t);return n.ok&&Z(e,t,`focus`),n}async function J(e,t,n){let{req:r,device:i,logPath:a,session:o}=e;if(!n)return v(`INVALID_ARGS`,`find type requires text`);let s=await Y(e,t);if(!s.ok)return s;let c=await g(i,`type`,[n],r.flags?.out,{...h(a,r.flags,o?.appBundleId,o?.trace?.outPath)});return Z(e,t,`type`),{ok:!0,data:c??{ref:t.ref}}}async function Y(t,n){let{req:r,device:i,logPath:a,session:o}=t,s=X(n,`be focused`);if(s)return s;let c=n.resolvedNode.rect?e(n.resolvedNode.rect):null;return c?{ok:!0,data:await g(i,`focus`,[String(c.x),String(c.y)],r.flags?.out,{...h(a,r.flags,o?.appBundleId,o?.trace?.outPath)})??{ref:n.ref}}:v(`COMMAND_FAILED`,`matched element has no bounds`)}function X(e,t){let r=[e.resolvedNode,e.node].find(n);return r?v(`COMMAND_FAILED`,`Matched element ${e.ref} is covered by another visible element and cannot ${t} safely`,{ref:`@${r.ref}`,interactionBlocked:r.interactionBlocked,hint:`Use a different visible target, scroll it clear of the overlay, or inspect with snapshot/screenshot before retrying.`}):null}function Z(e,t,n){let{req:r,sessionStore:i,session:a,command:o,publicFlags:s}=e;w(i,a,r,o,{ref:t.ref,action:n},{flags:s})}function Q(e){return{...m(e)??{}}}function ee(e,t,n){let r=e.slice(0,8).map(e=>{let t=s(e)||e.label||e.identifier||e.type||``;return`@${e.ref}${t?`(${t})`:``}`});return v(`AMBIGUOUS_MATCH`,`find matched ${e.length} elements for ${t} "${n}". Use a more specific locator or selector.`,{locator:t,query:n,matches:e.length,candidates:r})}function $(e){return e!==`role`}export{T as handleFindCommands,l as parseFindArgs};
|
package/dist/src/generic.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e}from"./sdk-contracts.js";import{
|
|
1
|
+
import{a as e}from"./sdk-contracts.js";import{xn as t}from"./tv-remote.js";import{i as n,n as r}from"./cli-runner.js";async function i({command:t,positionals:i,flags:s,client:c,debug:l,replayTestReporterRuntime:u}){let{result:d,cliOutput:f}=await r({client:c,command:t,positionals:i,flags:s});if(e(s.responseLevel))return n(s,d,()=>JSON.stringify(d,null,2)),!0;if(f)o(s,f);else{let e=await a(t,s,d,{debug:l,replayTestReporterRuntime:u});e!==0&&process.exit(e)}return!0}function a(e,r,i,a={}){return e===`test`?import(`./reporting.js`).then(({renderReplayTestResponse:e})=>e({suite:i,debug:a.debug,verbose:r.verbose,json:r.json,reporter:r.reporter,reportJunit:r.reportJunit,reporterRuntime:a.replayTestReporterRuntime})):(n(r,i,()=>t(i)),0)}function o(e,t){!e.json&&t.stderr&&process.stderr.write(t.stderr),n(e,e.json?t.jsonData??t.data:t.data,()=>t.text)}export{i as runGenericClientBackedCommand};
|
package/dist/src/helper.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{t as e}from"./rolldown-runtime.js";import{
|
|
1
|
+
import{t as e}from"./rolldown-runtime.js";import{_ as t}from"./sdk-contracts.js";import{g as n,y as r}from"./sdk-android-adb.js";import{i,r as a,t as o}from"./tool-provider.js";import{createHash as s}from"node:crypto";import{existsSync as c,promises as l}from"node:fs";import u from"node:os";import d from"node:path";import{fileURLToPath as f}from"node:url";var p=e({quitMacOsApp:()=>N,resolveFrontmostMacOsApp:()=>M,resolveMacOsHelperPackageRootFrom:()=>x,runMacOsAlertAction:()=>F,runMacOsPermissionAction:()=>P,runMacOsPressAction:()=>R,runMacOsReadTextAction:()=>L,runMacOsScreenshotAction:()=>z,runMacOsSnapshotAction:()=>I,startMacOsAudioProbeProcess:()=>A});const m=`agent-device-macos-helper`,h=`AGENT_DEVICE_MACOS_HELPER_BIN`,g=d.join(u.homedir(),`.agent-device`,`macos-helper`,`current`),_=d.join(g,`manifest.json`),v=/^[A-Za-z0-9_-]+(?:\.[A-Za-z0-9_-]+)+$/;function y(e){let n=e.trim();if(!v.test(n))throw new t(`INVALID_ARGS`,`macOS bundle id must use reverse-DNS form like com.example.App`,{bundleId:e});return n}function b(e,t){t.bundleId&&e.push(`--bundle-id`,y(t.bundleId)),t.surface&&e.push(`--surface`,t.surface)}function x(e){let n=d.dirname(e);for(;;){let e=d.join(n,`macos-helper`);if(c(d.join(e,`Package.swift`)))return e;let t=d.dirname(n);if(t===n)break;n=t}throw new t(`COMMAND_FAILED`,`Unable to locate macOS helper package root`,{modulePath:e})}function S(){return x(f(import.meta.url))}function C(){return d.join(S(),`.build`,`release`,m)}function w(){return d.join(g,m)}async function T(e){let t=await l.readdir(e,{withFileTypes:!0});return(await Promise.all(t.map(async t=>{let n=d.join(e,t.name);return t.isDirectory()?t.name===`.build`?[]:await T(n):!t.isFile()||!t.name.endsWith(`.swift`)&&t.name!==`Package.swift`?[]:[n]}))).flat().sort()}async function E(e){let t=await T(e),n=s(`sha256`);for(let r of t)n.update(d.relative(e,r)),n.update(`\0`),n.update(await l.readFile(r)),n.update(`\0`);let r=await i(`swift`,[`--version`],{allowFailure:!0,cwd:e,timeoutMs:1e4});return n.update(`swift-version`),n.update(`\0`),n.update(r.stdout||r.stderr||`exit:${r.exitCode}`),n.update(`\0`),n.digest(`hex`)}async function D(){try{let e=JSON.parse(await l.readFile(_,`utf8`));return typeof e.fingerprint==`string`?e.fingerprint:null}catch{return null}}async function O(){let e=await n(process.env[h],h);if(e)return e;let t=S(),r=await E(t),a=w();try{if(await D()===r)return await l.access(a),a}catch{}let o=C();process.stderr.write(`agent-device: building macOS helper (first run or helper update)
|
|
2
2
|
`),await i(`swift`,[`build`,`-c`,`release`,`--package-path`,t],{cwd:t,timeoutMs:12e4}),await l.mkdir(g,{recursive:!0});let s=`${a}.tmp`;return await l.copyFile(o,s),await l.rename(s,a),await l.chmod(a,493),await l.writeFile(_,`${JSON.stringify({fingerprint:r},null,2)}\n`,`utf8`),a}async function k(){let e=process.env[h]?.trim();if(e){let t=await n(e,h);if(t)return t}if(o())return m;if(process.platform!==`darwin`)throw new t(`UNSUPPORTED_PLATFORM`,`macOS helper is only available on macOS`);return await O()}async function A(e){return r(await k(),[`audio-probe`,`--duration-ms`,String(e.durationMs),`--bucket-ms`,String(e.bucketMs),`--out`,e.statusPath],{allowFailure:!0,captureOutput:!0})}async function j(e){let n={allowFailure:!0,timeoutMs:3e4},r=a().macosHelper,o=r?m:await k(),s=r?await r.run(e,n):await i(o,e,n),c=s.stdout.trim(),l=null;if(c)try{l=JSON.parse(c)}catch{l=null}if(s.exitCode===0&&l?.ok)return l.data;throw new t(`COMMAND_FAILED`,l&&!l.ok?l.error?.message??`macOS helper exited with code ${s.exitCode}`:c||s.stderr.trim()||`macOS helper exited with code ${s.exitCode}`,{helperPath:o,args:e,stdout:s.stdout,stderr:s.stderr,exitCode:s.exitCode,...l&&!l.ok?l.error?.details:{}})}async function M(){return await j([`app`,`frontmost`])}async function N(e){return await j([`app`,`quit`,`--bundle-id`,y(e)])}async function P(e,t){return await j([`permission`,e,t])}async function F(e,t={}){let n=[`alert`,e];return b(n,t),await j(n)}async function I(e,t={}){let n=[`snapshot`,`--surface`,e];return b(n,t),await j(n)}async function L(e,t,n={}){let r=[`read`,`--x`,String(e),`--y`,String(t)];return b(r,n),await j(r)}async function R(e,t,n={}){let r=[`press`,`--x`,String(e),`--y`,String(t)];return b(r,n),await j(r)}async function z(e,t={}){let n=[`screenshot`,`--out`,e];return b(n,t),t.fullscreen&&n.push(`--fullscreen`),await j(n)}export{P as a,A as c,F as i,N as n,z as o,M as r,I as s,p as t};
|
package/dist/src/index.d.ts
CHANGED
|
@@ -289,13 +289,17 @@ type SettleObservation = {
|
|
|
289
289
|
* change-only diff omits refs for elements that did not change — after a
|
|
290
290
|
* modal dismiss the diff shows only removals, and the next button to press
|
|
291
291
|
* (already on screen, untouched) is absent from the response. `tail` lists
|
|
292
|
-
* the settled tree's remaining
|
|
293
|
-
*
|
|
294
|
-
*
|
|
295
|
-
*
|
|
296
|
-
*
|
|
297
|
-
*
|
|
298
|
-
*
|
|
292
|
+
* the settled tree's remaining uncovered interactive elements (excluding
|
|
293
|
+
* structural application/window chrome and the keyboard window's chrome)
|
|
294
|
+
* so the response stays actionable without that extra round trip. Attached
|
|
295
|
+
* ONLY when `diff` carries zero added-line refs naming a NEW target (the
|
|
296
|
+
* modal-dismiss/toast-only/fill signature) — a diff whose added refs hand
|
|
297
|
+
* the next target already pays its way, so the tail would be pure byte
|
|
298
|
+
* cost. Keyboard-chrome refs and self-echo refs (added lines whose node
|
|
299
|
+
* contains the action point: the acted-on element re-describing itself,
|
|
300
|
+
* e.g. a filled field re-labeled with its new value) do not count as new
|
|
301
|
+
* targets. Refs already present on `diff`'s added lines are excluded.
|
|
302
|
+
* Capped; `tailTruncated` marks when candidates exceeded the cap.
|
|
299
303
|
*/
|
|
300
304
|
tail?: SettleTailEntry[];
|
|
301
305
|
tailTruncated?: true;
|
package/dist/src/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{_ as e,b as t,u as n,x as r}from"./sdk-contracts.js";import{n as i}from"./client.js";import{t as a}from"./sdk-io.js";export{e as AppError,n as centerOfRect,i as createAgentDeviceClient,a as createLocalArtifactAdapter,t as isAgentDeviceError,r as normalizeAgentDeviceError};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{t as e}from"./rolldown-runtime.js";import{
|
|
1
|
+
import{t as e}from"./rolldown-runtime.js";import{_ as t}from"./sdk-contracts.js";import{j as n,u as r}from"./sdk-android-adb.js";import{i,st as a}from"./tv-remote.js";import{t as o}from"./timeouts.js";import{p as s,r as c}from"./android-input-ownership.js";import{r as l}from"./device-input-state.js";import{Et as u,Mt as d}from"./internal/daemon.js";function ee(e,t){if(!t)return{expected:e,actual:null,failureReason:`text_mismatch`,targetInput:null,actualInput:null};let n=h(t),r={failureReason:t.reason??`text_mismatch`,targetInput:m(t.targetInput),actualInput:m(t.actualInput)};return n?{...r,expectedLength:Array.from(e).length,actual:null,masked:!0,actualLength:Array.from(t.actual??``).length}:{...r,expected:e,actual:t.actual}}function f(e){return e?e.password?!0:p(e.text):!1}function p(e){return e?Array.from(e).every(te):!1}function m(e){if(!e)return null;let t=f(e);return{...e,text:t?null:e.text,...t?{textRedacted:!0}:{}}}function te(e){return e===`•`||e===`*`||e===`●`}function h(e){return e.masked===!0||f(e.targetInput)||f(e.actualInput)}async function g(e,t,n,r){let i=[0,150,350],a=null,s=null,c=await ae(e);for(let l of i){l>0&&await o(l);let i=await S(e,t,n,r,c);if(a=i,i.reason===`ime_capture`)return i;s=i.ok?i:null}return s??a??{ok:!1,actual:null,reason:`text_mismatch`,targetInput:null,actualInput:null}}async function _(e,t,n){return y(await u(e),t,n)}function v(e,t,n,r,i={}){let a=C(e,t,n,i);return w(a)?{ok:!1,actual:a.actualInput?.text??null,reason:`ime_capture`,targetInput:a.targetInput,actualInput:a.actualInput}:T(a,r)??E(a,r)}function y(e,t,n){return C(e,t,n).actualInput?.text??null}function b(e){return e?.reason===`ime_capture`?`Android fill input was captured by the active keyboard instead of the app field`:e?.reason===`masked_unverified`?`Android fill verification could not confirm masked text value`:`Android fill verification failed`}function x(e,t){let n=ee(e,t);return t?.reason===`ime_capture`&&(n.hint=`The focused input belongs to the Android keyboard/IME, not the app field. Disable handwriting/stylus input or switch to a standard IME, then retry fill.`),n}async function S(e,t,n,r,i){return v(await u(e),t,n,r,i)}function C(e,t,n,r={}){let i={focusedEdit:null,editAtPoint:null,anyAtPoint:null};for(let a of d(e)){let e=ie(a,r);e&&oe(i,e,t,n)}return ce(i)}function w(e){let{targetInput:t,actualInput:n}=e;return!t||!n||n===t?!1:n.inputMethodOwned&&!t.inputMethodOwned}function T(e,t){let n=e.actualInput;if(!n||!A(n))return null;let r=n.text??null,i=Array.from(r??``).length,a=Array.from(t).length,o=r!==null&&i>0&&a>0&&i===a;return{ok:o,actual:r,reason:o?void 0:`masked_unverified`,masked:!0,targetInput:e.targetInput,actualInput:n}}function E(e,t){let n=e.actualInput?.text??null;return{ok:ne(n,t),actual:n,reason:`text_mismatch`,targetInput:e.targetInput,actualInput:e.actualInput}}function ne(e,t){if(e===t)return!0;let n=D(e),r=D(t);return!n||!r?!1:!!(n===r||re(n,r))}function D(e){return(e??``).replace(/\s+/g,` `).trim()}function re(e,t){if(e.length!==t.length||e.length===0||e.slice(1)!==t.slice(1))return!1;let n=e[0],r=t[0];return!n||!r?!1:r.toLowerCase()===r&&n===r.toUpperCase()}function ie(e,t){if(!e.rect)return null;let n=e.text??``,r=Math.max(1,e.rect.width*e.rect.height);return{text:n||null,className:e.className,resourceId:e.resourceId,packageName:e.packageName,rect:e.rect,focused:e.focused??!1,password:e.password===!0,inputMethodOwned:c({packageName:e.packageName,resourceId:e.resourceId,activeInputMethodPackage:t.activeInputMethodPackage}),area:r,editText:k(e.className??``)}}async function ae(e){try{return{activeInputMethodPackage:(await l(e)).inputMethodPackage}}catch(e){return n({level:`warn`,phase:`android_fill_verification_input_method_probe_failed`,data:{error:e instanceof Error?e.message:String(e)}}),{}}}function oe(e,t,n,r){let i=se(t.rect,n,r);if(i&&t.editText&&(e.editAtPoint=O(e.editAtPoint,t)),t.focused&&t.editText){e.focusedEdit=O(e.focusedEdit,t);return}i&&t.text&&(e.anyAtPoint=O(e.anyAtPoint,t))}function se(e,t,n){return t>=e.x&&t<=e.x+e.width&&n>=e.y&&n<=e.y+e.height}function O(e,t){return e&&e.area<t.area?e:t}function ce(e){let t=e.editAtPoint??e.anyAtPoint;return{targetInput:t,actualInput:(e.focusedEdit?.text?e.focusedEdit:null)??t}}function k(e){let t=e.toLowerCase();return t.includes(`edittext`)||t.includes(`textfield`)}function A(e){return f(e)}var j=e({appSwitcherAndroid:()=>z,backAndroid:()=>F,fillAndroid:()=>U,focusAndroid:()=>H,getAndroidScreenSize:()=>q,homeAndroid:()=>I,longPressAndroid:()=>B,pressAndroid:()=>M,pressAndroidEnter:()=>L,pressAndroidTvRemote:()=>N,readAndroidTextAtPoint:()=>_,rotateAndroid:()=>R,scrollAndroid:()=>G,swipeAndroid:()=>P,typeAndroid:()=>V});async function M(e,t,n){await s(e,[`shell`,`input`,`tap`,String(t),String(n)])}async function N(e,t,n){let r=i(t);await s(e,[`shell`,`input`,...n&&n>0?[`keyevent`,`--longpress`]:[`keyevent`],r])}async function P(e,t,n,r,i,a=250){await s(e,[`shell`,`input`,`swipe`,String(t),String(n),String(r),String(i),String(a)])}async function F(e){await s(e,[`shell`,`input`,`keyevent`,`4`])}async function I(e){await s(e,[`shell`,`input`,`keyevent`,`3`])}async function L(e){await s(e,[`shell`,`input`,`keyevent`,`ENTER`])}async function R(e,t){let n=le(t);await s(e,[`shell`,`settings`,`put`,`system`,`accelerometer_rotation`,`0`]),await s(e,[`shell`,`settings`,`put`,`system`,`user_rotation`,n])}async function z(e){await s(e,[`shell`,`input`,`keyevent`,`187`])}async function B(e,t,n,r=800){await s(e,[`shell`,`input`,`swipe`,String(t),String(n),String(t),String(n),String(r)])}async function V(e,t,n=0){let i=r(e);if(i){await i({action:`type`,text:t,delayMs:n}),$(`type`,`provider-native`,t);return}if(X(t),await K(e,`type`),n>0&&Array.from(t).length>1){await Y(e,{action:`type`,text:t,chunkSize:1,delayMs:n});return}await Y(e,{action:`type`,text:t,chunkSize:J,delayMs:0})}async function H(e,t,n){await M(e,t,n)}async function U(e,t,n,i,a=0){let o=r(e);if(o){await o({action:`fill`,target:{x:t,y:n},text:i,delayMs:a}),$(`fill`,`provider-native`,i);let r=await g(e,t,n,i);if(r.ok)return;W(i,r)}X(i);let s=Array.from(i).length,c=[{clearPadding:12,minClear:8,maxClear:48,chunkSize:a>0?1:J,inputDelayMs:a},{clearPadding:24,minClear:16,maxClear:96,chunkSize:a>0?1:4,inputDelayMs:a>0?a:15}],l=null;for(let r of c){await H(e,t,n),await K(e,`fill`),await me(e,he(s+r.clearPadding,r.minClear,r.maxClear)),await Y(e,{action:`fill`,text:i,chunkSize:r.chunkSize,delayMs:r.inputDelayMs});let a=await g(e,t,n,i);if(l=a,a.ok)return;a.reason===`ime_capture`&&W(i,a)}W(i,l)}function W(e,n){throw new t(`COMMAND_FAILED`,b(n),x(e,n))}async function G(e,t,n){let r=await q(e),i=a({direction:t,amount:n?.amount,pixels:n?.pixels,referenceWidth:r.width,referenceHeight:r.height}),o=n?.durationMs??300;return await s(e,[`shell`,`input`,`swipe`,String(i.x1),String(i.y1),String(i.x2),String(i.y2),String(o)]),{...i,...n?.durationMs===void 0?{}:{durationMs:n.durationMs}}}function le(e){switch(e){case`portrait`:return`0`;case`landscape-left`:return`1`;case`portrait-upside-down`:return`2`;case`landscape-right`:return`3`;default:throw new t(`INVALID_ARGS`,`Unsupported Android rotation: ${e}`)}}async function K(e,r){let i;try{i=await l(e)}catch(e){n({level:`warn`,phase:`android_input_ownership_probe_failed`,data:{action:r,error:e instanceof Error?e.message:String(e)}});return}if(i.inputOwner===`ime`)throw new t(`COMMAND_FAILED`,`KEYBOARD_OVERLAY_BLOCKING: Android text input is blocked because the focused input belongs to the active keyboard/IME.`,{failureReason:`ime_capture`,action:r,inputOwner:i.inputOwner,inputType:i.inputType,type:i.type,inputMethodPackage:i.inputMethodPackage,focusedPackage:i.focusedPackage,focusedResourceId:i.focusedResourceId,nextAction:`Focused input appears to be owned by the keyboard/IME; dismiss or change the IME before retrying text entry.`})}async function q(e){let n=(await s(e,[`shell`,`wm`,`size`])).stdout.match(/Physical size:\s*(\d+)x(\d+)/);if(!n)throw new t(`COMMAND_FAILED`,`Unable to read screen size`);return{width:Number(n[1]),height:Number(n[2])}}const J=8;async function Y(e,t){let n=t.text.split(`
|
|
2
2
|
`);for(let[r,i]of n.entries()){let a=pe(i,t.chunkSize);for(let[i,s]of a.entries())await ue(e,s),t.delayMs>0&&(i+1<a.length||r+1<n.length)&&await o(t.delayMs);r+1<n.length&&await s(e,[`shell`,`input`,`keyevent`,`ENTER`])}$(t.action,`adb-shell`,t.text)}async function ue(e,t){if(t)try{await s(e,[`shell`,`input`,`text`,Z(t)])}catch(e){throw fe(e)?Q(t,e):e}}function X(e){if(!de(e))throw Q(e)}function de(e){for(let t of e){let e=t.codePointAt(0);if(e!==void 0&&t!==`
|
|
3
3
|
`&&(e<32||e>126))return!1}return!0}function Z(e){return e.replace(/ /g,`%s`)}function fe(e){if(!(e instanceof t)||e.code!==`COMMAND_FAILED`)return!1;let n=e.details?.stderr,r=(typeof n==`string`?n:``).toLowerCase();return!!(r.includes(`exception occurred while executing 'text'`)||r.includes(`nullpointerexception`)&&r.includes(`inputshellcommand.sendtext`))}function Q(e,n){return new t(`COMMAND_FAILED`,`Android text input requires provider-native text injection for non-ASCII/control characters; the current adb-shell fallback supports ASCII text only.`,{backend:`adb-shell`,textLength:Array.from(e).length,textPreview:e.slice(0,32)},n instanceof Error?n:void 0)}function pe(e,t){let n=Math.max(1,Math.floor(t)),r=[],i=Array.from(e);for(let e=0;e<i.length;e+=n)r.push(i.slice(e,e+n).join(``));return r.length>0?r:[``]}function $(e,t,r){n({phase:`android_text_injection`,data:{action:e,backend:t,textLength:Array.from(r).length}})}async function me(e,t){let n=Math.max(0,t);await s(e,[`shell`,`input`,`keyevent`,`KEYCODE_MOVE_END`],{allowFailure:!0});for(let t=0;t<n;t+=24){let r=Math.min(24,n-t);await s(e,[`shell`,`input`,`keyevent`,...Array(r).fill(`KEYCODE_DEL`)],{allowFailure:!0})}}function he(e,t,n){return Math.max(t,Math.min(n,e))}export{q as a,B as c,R as d,G as f,H as i,M as l,V as m,F as n,I as o,P as p,U as r,j as s,z as t,N as u};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{_ as e}from"./sdk-contracts.js";import{t}from"./timeouts.js";import{t as n}from"./tool-provider2.js";function r(){return process.env.WAYLAND_DISPLAY||process.env.XDG_SESSION_TYPE===`wayland`?`wayland`:`x11`}let i=null;async function a(){let t=n();if(i?.provider===t)return i;let a=r();if(a===`wayland`){if(await t.whichCommand(`ydotool`))return i={tool:`ydotool`,display:a,provider:t},i;throw new e(`TOOL_MISSING`,`ydotool is required for input synthesis on Wayland (xdotool does not work on Wayland). Install it via your package manager.`)}if(await t.whichCommand(`xdotool`))return i={tool:`xdotool`,display:a,provider:t},i;throw new e(`TOOL_MISSING`,`xdotool is required for input synthesis on X11. Install it via your package manager.`)}const o=1e4;async function s(...e){await n().runCommand(`xdotool`,e,{allowFailure:!1,timeoutMs:o})}async function c(...e){await n().runCommand(`ydotool`,e,{allowFailure:!1,timeoutMs:o})}function l(){return n().input}async function u(e,t){let{tool:n}=await a();n===`xdotool`?await s(`mousemove`,`--sync`,String(e),String(t)):await c(`mousemove`,`--absolute`,`-x`,String(e),`-y`,String(t))}async function d(e,t){let n=l();if(n){await n.key(e,t);return}let{tool:r}=await a();r===`xdotool`?await s(`key`,`--clearmodifiers`,e):await c(`key`,...t)}async function f(e,t,n,r){await u(e,t);let{tool:i}=await a();i===`xdotool`?await s(`click`,n):await c(`click`,r)}async function p(e,t,n,r,i){let a=l();if(a){await a.click(e,t,n);return}await f(e,t,r,i)}async function m(e,t){await p(e,t,`primary`,`1`,`0xC0`)}async function h(e,t){await p(e,t,`secondary`,`3`,`0xC1`)}async function g(e,t){await p(e,t,`middle`,`2`,`0xC2`)}async function _(e,t){let n=l();if(n){await n.doubleClick(e,t);return}let{tool:r}=await a();await u(e,t),r===`xdotool`?await s(`click`,`--repeat`,`2`,`1`):(await c(`click`,`0xC0`),await c(`click`,`0xC0`))}async function v(e,n,r=800){let i=l();if(i){await i.longPress(e,n,r);return}let{tool:o}=await a();await u(e,n),o===`xdotool`?(await s(`mousedown`,`1`),await t(r),await s(`mouseup`,`1`)):(await c(`click`,`--down`,`0xC0`),await t(r),await c(`click`,`--up`,`0xC0`))}async function y(e,t){await m(e,t)}async function b(e,n,r,i,o=300){let d=l();if(d){await d.drag(e,n,r,i,o);return}let{tool:f}=await a();await u(e,n),f===`xdotool`?(await s(`mousedown`,`1`),await s(`mousemove`,`--sync`,String(r),String(i)),await t(o),await s(`mouseup`,`1`)):(await c(`click`,`--down`,`0xC0`),await c(`mousemove`,`--absolute`,`-x`,String(r),`-y`,String(i)),await t(o),await c(`click`,`--up`,`0xC0`))}async function x(e,t){let n=l();if(n)return await n.scroll(e,t),C(t);let{tool:r}=await a(),i=5;if(t?.pixels==null?t?.amount!=null&&(i=Math.max(1,Math.round(5*(t.amount/.6)))):i=r===`xdotool`?Math.max(1,Math.round(t.pixels/15)):Math.max(1,Math.round(t.pixels/40)),r===`xdotool`){let n=e===`up`?`4`:e===`down`?`5`:e===`left`?`6`:`7`;await S(i,t?.durationMs,async e=>{await s(`click`,`--repeat`,String(e),n)})}else e===`up`||e===`down`?await S(i,t?.durationMs,async t=>{await c(`mousemove`,`--wheel`,`-y`,String(e===`up`?-t:t))}):await S(i,t?.durationMs,async t=>{await c(`mousemove`,`--wheel`,`-x`,String(e===`left`?-t:t))});return C(t)}async function S(e,n,r){if(n===void 0||n<=0||e<=1){await r(e);return}let i=n/Math.max(1,e-1);for(let n=0;n<e;n+=1)await r(1),n<e-1&&await t(i)}function C(e){return e?.durationMs===void 0?{}:{durationMs:e.durationMs}}async function w(e,t=0){let n=l();if(n){await n.typeText(e,{delayMs:t});return}let{tool:r}=await a();if(r===`xdotool`){let n=[`type`];t>0&&n.push(`--delay`,String(t)),n.push(`--clearmodifiers`,`--`,e),await s(...n)}else await c(`type`,`--`,e)}async function T(e,n,r,i=0){await m(e,n),await t(100),await d(`ctrl+a`,[`29:1`,`30:1`,`30:0`,`29:0`]),await t(50),await w(r,i)}export{_ as doubleClickLinux,T as fillLinux,y as focusLinux,v as longPressLinux,g as middleClickLinux,m as pressLinux,h as rightClickLinux,x as scrollLinux,d as sendKey,b as swipeLinux,w as typeLinux};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{_ as e}from"./sdk-contracts.js";import{v as t}from"./sdk-android-adb.js";import{t as n}from"./path-resolution.js";import{createWriteStream as r,promises as i}from"node:fs";import a from"node:os";import o from"node:path";import{pipeline as s}from"node:stream/promises";import{Readable as c}from"node:stream";import l from"node:net";import u from"node:dns/promises";const d=[`.zip`,`.tar`,`.tar.gz`,`.tgz`];Object.freeze([...d]);async function f(e){let t=[];try{let n=await m(e.source,{signal:e.signal,downloadTimeoutMs:e.downloadTimeoutMs});t.push(n.cleanup);let r=await T(n.localPath,{archivePath:void 0,isInstallablePath:e.isInstallablePath,installableLabel:e.installableLabel,allowArchiveExtraction:e.allowArchiveExtraction!==!1,registerCleanup:e=>{t.push(e)}});return{archivePath:r.archivePath,installablePath:r.installablePath,cleanup:async()=>{await A(t)}}}catch(e){throw await A(t),e}}function p(e){return n(e)}async function m(e,t){if(e.kind===`path`)return{localPath:p(e.path),cleanup:async()=>{}};let n=await i.mkdtemp(o.join(a.tmpdir(),`agent-device-source-`));try{return{localPath:await h(n,e.url,e.headers,t),cleanup:async()=>{await i.rm(n,{recursive:!0,force:!0})}}}catch(e){throw await i.rm(n,{recursive:!0,force:!0}),e}}async function h(t,n,i,a){let l;try{l=new URL(n)}catch{throw new e(`INVALID_ARGS`,`Invalid source URL: ${n}`)}await g(l);let u=a?.signal;if(u?.aborted)throw new e(`COMMAND_FAILED`,`request canceled`,{reason:`request_canceled`});let d=a?.downloadTimeoutMs??12e4,f=AbortSignal.timeout(d),p=u?AbortSignal.any([u,f]):f;try{let n=await fetch(l,{headers:i,redirect:`follow`,signal:p});if(!n.ok)throw new e(`COMMAND_FAILED`,`Failed to download app source: ${n.status} ${n.statusText}`,{status:n.status,statusText:n.statusText,url:l.toString()});let a=b(n,l),u=o.join(t,a),d=n.body;if(!d)throw new e(`COMMAND_FAILED`,`Download response body was empty`,{url:l.toString()});return await s(c.fromWeb(d),r(u)),u}catch(t){throw u?.aborted?new e(`COMMAND_FAILED`,`request canceled`,{reason:`request_canceled`},t):f.aborted?new e(`COMMAND_FAILED`,`App source download timed out after ${d}ms`,{timeoutMs:d,url:l.toString()},t):t}}async function g(t){if(t.protocol!==`http:`&&t.protocol!==`https:`)throw new e(`INVALID_ARGS`,`Unsupported source URL protocol: ${t.protocol}`);if(x(t.hostname.toLowerCase()))throw new e(`INVALID_ARGS`,`Source URL host is not allowed: ${t.hostname}`,{hint:`Use a public artifact URL.`});if((await u.lookup(t.hostname,{all:!0,verbatim:!0}).catch(()=>[])).some(e=>S(e.address)))throw new e(`INVALID_ARGS`,`Source URL host resolved to a private or loopback address: ${t.hostname}`,{hint:`Use a public artifact URL.`})}function _(e){let t=e instanceof URL?e:new URL(e),n=t.hostname.toLowerCase();if(!n)return!1;let r=t.pathname;return v(n,r)||y(n,r)}function v(e,t){return e===`api.github.com`?/^\/repos\/[^/]+\/[^/]+\/actions\/artifacts\/\d+\/zip$/i.test(t):e===`github.com`?/^\/[^/]+\/[^/]+\/(?:actions\/runs\/\d+\/artifacts\/\d+|suites\/\d+\/artifacts\/\d+)$/i.test(t):!1}function y(e,t){return e!==`expo.dev`&&!e.endsWith(`.expo.dev`)?!1:/^\/(?:artifacts\/eas\/|accounts\/[^/]+\/projects\/[^/]+\/builds\/)/i.test(t)}function b(e,t){let n=(e.headers.get(`content-disposition`)?.match(/filename\*?=(?:UTF-8'')?"?([^";]+)"?/i))?.[1]?.trim();return n?o.basename(n):o.basename(t.pathname)||`downloaded-artifact.bin`}function x(e){return!e||e===`localhost`||e.endsWith(`.localhost`)?!0:S(e)}function S(e){let t=l.isIP(e);return t===4?C(e):t===6?w(e):!1}function C(e){let t=e.split(`.`).map(e=>Number.parseInt(e,10));if(t.length!==4||t.some(e=>Number.isNaN(e)||e<0||e>255))return!1;let n=t[0],r=t[1];return n===void 0||r===void 0?!1:n===10||n===127||n===169&&r===254||n===172&&r>=16&&r<=31||n===192&&r===168}function w(e){let t=e.toLowerCase();return!!(t===`::1`||t.startsWith(`fc`)||t.startsWith(`fd`)||t.startsWith(`fe80:`))}async function T(t,n){let r=await i.stat(t).catch(()=>null);if(!r)throw new e(`INVALID_ARGS`,`App source not found: ${t}`);if(n.isInstallablePath(t,r))return{archivePath:n.archivePath,installablePath:t};if(r.isFile()&&k(t)){if(!n.allowArchiveExtraction)throw new e(`INVALID_ARGS`,`URL sources must point directly to a ${n.installableLabel}; archive extraction is not allowed`,{path:t});let r=await D(t);return n.registerCleanup(r.cleanup),await T(r.outputPath,{...n,archivePath:n.archivePath??t})}if(r.isDirectory()){let r=await E(t,n.isInstallablePath),i=r[0];if(i!==void 0&&r.length===1)return{archivePath:n.archivePath,installablePath:i};if(r.length>1)throw new e(`INVALID_ARGS`,`Found multiple ${n.installableLabel} candidates under ${t}`,{matches:r});let a=await E(t,(e,t)=>t.isFile()&&k(e)),o=a[0];if(o!==void 0&&a.length===1){if(!n.allowArchiveExtraction)throw new e(`INVALID_ARGS`,`URL sources must point directly to a ${n.installableLabel}; nested archives are not allowed`,{path:o});let t=await D(o);return n.registerCleanup(t.cleanup),await T(t.outputPath,{...n,archivePath:n.archivePath??o})}if(a.length>1)throw new e(`INVALID_ARGS`,`Found multiple nested archives under ${t}; expected one ${n.installableLabel} source`,{matches:a})}throw new e(`INVALID_ARGS`,`Expected ${n.installableLabel} source, but got ${t}`)}async function E(e,t){let n=[],r=[{path:e,depth:0}];for(;r.length>0;){let e=r.shift();if(!e)continue;let a=await i.readdir(e.path,{withFileTypes:!0});a.sort((e,t)=>e.name.localeCompare(t.name));for(let i of a){let a=o.join(e.path,i.name);if(t(a,i)){n.push(a);continue}i.isDirectory()&&e.depth<5&&r.push({path:a,depth:e.depth+1})}}return n}async function D(e){let n=await i.mkdtemp(o.join(a.tmpdir(),`agent-device-archive-`));try{return e.toLowerCase().endsWith(`.zip`)?await O(e,n):e.toLowerCase().endsWith(`.tar.gz`)||e.toLowerCase().endsWith(`.tgz`)?await t(`tar`,[`-xzf`,e,`-C`,n]):await t(`tar`,[`-xf`,e,`-C`,n]),{outputPath:n,cleanup:async()=>{await i.rm(n,{recursive:!0,force:!0})}}}catch(e){throw await i.rm(n,{recursive:!0,force:!0}),e}}async function O(e,n){await t(`unzip`,[`-q`,e,`-d`,n])}function k(e){let t=e.toLowerCase();return d.some(e=>t.endsWith(e))}async function A(e){for(let t of[...e].reverse())await t()}export{f as n,g as r,_ as t};
|