agent-device 0.19.0 → 0.19.1
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/README.md +5 -1
- package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.19.0.apk → agent-device-android-multitouch-helper-0.19.1.apk} +0 -0
- package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.19.1.apk.sha256 +1 -0
- package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.19.0.manifest.json → agent-device-android-multitouch-helper-0.19.1.manifest.json} +4 -4
- package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.19.0.apk → agent-device-android-snapshot-helper-0.19.1.apk} +0 -0
- package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.19.1.apk.sha256 +1 -0
- package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.19.0.manifest.json → agent-device-android-snapshot-helper-0.19.1.manifest.json} +6 -6
- package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +24 -7
- package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +506 -119
- package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +153 -48
- package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Navigation.swift +172 -0
- package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SequenceExecution.swift +76 -5
- package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +60 -52
- package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +159 -56
- package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedGesturePolicy.swift +142 -0
- package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +16 -14
- package/dist/src/android-adb.d.ts +1 -2
- package/dist/src/android-adb.js +1 -1
- package/dist/src/android-input-ownership.js +6 -0
- package/dist/src/android.js +1 -1
- package/dist/src/app-lifecycle.js +3 -3
- package/dist/src/apple-runner-options.js +1 -1
- package/dist/src/apps.js +5 -5
- package/dist/src/cli-help.js +131 -34
- 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/command-metadata.js +1 -1
- package/dist/src/command-schema.js +3 -3
- package/dist/src/device-input-state.js +2 -2
- package/dist/src/devices2.js +1 -1
- package/dist/src/find.js +1 -1
- package/dist/src/generic.js +1 -1
- package/dist/src/index.d.ts +199 -20
- package/dist/src/input-actions.js +3 -3
- 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 +17 -15
- package/dist/src/lease.js +1 -1
- package/dist/src/linux.js +1 -1
- package/dist/src/metro.d.ts +0 -1
- package/dist/src/notifications.js +1 -1
- package/dist/src/points.js +1 -1
- package/dist/src/project-runtime.js +1 -1
- 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 +24 -23
- package/dist/src/reporting.js +3 -3
- package/dist/src/runner-client.js +1 -1
- package/dist/src/runtime.js +2 -2
- package/dist/src/sdk-android-adb.d.ts +2 -2
- package/dist/src/sdk-batch-runner.d.ts +0 -1
- package/dist/src/sdk-batch.js +2 -2
- package/dist/src/sdk-finders.d.ts +1 -2
- package/dist/src/sdk-finders.js +1 -1
- package/dist/src/sdk-io.d.ts +0 -1
- package/dist/src/sdk-remote-config.d.ts +1 -2
- 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/selectors.d.ts +0 -1
- package/dist/src/selectors.js +1 -1
- package/dist/src/selectors2.js +1 -1
- package/dist/src/server.js +3 -3
- package/dist/src/session.js +10 -10
- package/dist/src/simctl.js +1 -1
- package/dist/src/simulator.js +1 -1
- package/dist/src/snapshot-diagnostics.js +2 -2
- package/dist/src/snapshot-helper.js +4 -4
- package/dist/src/snapshot-quality.js +1 -1
- package/dist/src/snapshot2.js +2 -2
- package/dist/src/tv-remote.js +14 -0
- package/dist/src/web.js +1 -1
- package/package.json +5 -4
- package/server.json +2 -2
- package/skills/agent-device/SKILL.md +8 -7
- package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.19.0.apk.sha256 +0 -1
- package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.19.0.apk.sha256 +0 -1
- package/dist/src/device-rotation.js +0 -14
- package/dist/src/logcat.js +0 -6
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{C as d,p as f,w as p}from"./sdk-batch.js";import{i as ee,n as te}from"./output-path.js";import{C as ne,D as re,S as m,_ as h,c as ie,h as ae,l as oe,m as se,n as ce,o as le,p as ue,v as de,w as fe,y as pe}from"./snapshot-diagnostics.js";import{n as g,t as me}from"./version.js";import{n as he}from"./path-resolution.js";import{t as _}from"./timeouts.js";import{u as ge}from"./host-process.js";import{Dn as _e,Sn as ve,on as ye}from"./device-rotation.js";import{C as be,D as xe,E as Se,M as Ce,O as we,S as Te,T as Ee,_ as De,b as Oe,d as ke,i as Ae,l as je,u as Me,v as Ne,w as Pe,x as Fe,y as Ie}from"./registry.js";import{l as Le,m as v,v as y}from"./sdk-batch-runner.js";import{n as Re,t as ze}from"./url.js";import{t as Be}from"./client-metro-companion.js";import{n as Ve,r as He}from"./project-runtime.js";import{t as Ue}from"./runtime-transport.js";import{t as We}from"./command-metadata.js";import{createHash as Ge,randomUUID as Ke}from"node:crypto";import b from"node:fs";import qe from"node:os";import x from"node:path";import S from"node:http";import C from"node:https";import{pipeline as w}from"node:stream/promises";import{Transform as Je,Writable as Ye}from"node:stream";import T from"node:net";const Xe=`/agent-device`;function Ze(e){return E(e,Xe)}function E(e,t){let n=e.endsWith(`/`)?e:`${e}/`;return new URL(t.replace(/^\/+/,``),n).toString()}function D(e){let t=e?.trim();return t?{authorization:`Bearer ${t}`,"x-agent-device-token":t}:{}}async function Qe(e,t){let n=b.statSync(e),r=x.basename(e),i=n.isDirectory(),a=tt(t)??et(e,n),o=[];try{let t=i?await $e(e,o):e,n=b.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=b.mkdtempSync(x.join(qe.tmpdir(),`agent-device-upload-${Ke()}-`));t.push(n);let r=x.join(n,`${x.basename(e)}.tar.gz`);return await l(`tar`,[`czf`,r,`-C`,x.dirname(e),x.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)b.rmSync(t,{recursive:!0,force:!0})}async function rt(e){let n=Ge(`sha256`),r=new Ye({write(e,t,r){n.update(e),r()}});return await w(b.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} (${O(e.totalBytes)}) via ${ct(e.stage)} upload`;case`resume`:return`Resuming ${e.fileName} at ${O(e.transferredBytes)} of ${O(e.totalBytes)}`;case`progress`:return`Uploaded ${O(e.transferredBytes)} of ${O(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 O(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 k({...e,url:e.url,redirectCount:0,startOffset:0})}function pt(e){return e instanceof t&&e.details?.[dt]===!0}async function k(e){let n=e.url.protocol===`https:`?C:S,r=b.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);k({...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}k({...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)),w(b.createReadStream(e.payloadPath,{start:e.startOffset}),it({stage:e.progress?.stage??`legacy`,fileName:e.progress?.fileName??x.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=Ke();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,D(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,D(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,D(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(!qt(t))return A({positionals:n,flags:r,installSource:i,uploadedArtifactId:o,clientArtifactPaths:a});r=Pt(e,n,r,a);let c=await Lt(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),A({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=Rt(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=x.isAbsolute(e)?e:x.resolve(t??process.cwd(),e);return b.existsSync(n)?n:void 0}function A(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 Lt(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=x.isAbsolute(i)?i:x.resolve(e.meta?.cwd??process.cwd(),i);if(!b.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 Rt(e,t){if(e.command===`screenshot`){let n=Ht(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(!Bt(e)&&e.flags?.platform===void 0)return null;let t=zt(e),n=Vt(Ht(e,`outPath`,t,1),e);return{field:`outPath`,localPath:n,positionalIndex:1,positionalPath:M(`recording`,x.extname(n)||t)}}return null}function zt(e){return ee(e.flags?.platform)}function Bt(e){return j(e.positionals?.[1])||j(e.flags?.out)}function Vt(e,t){return t.flags?.platform===`web`?te(e,zt(t)):e}function Ht(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 x.isAbsolute(o)?o:x.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 x.posix.join(`/tmp`,`agent-device-${e}-${Date.now()}-${Math.random().toString(36).slice(2,8)}${n}`)}async function Ut(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=Wt(n,t);await Gt({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 Wt(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 x.resolve(t.meta?.cwd??process.cwd(),r)}async function Gt(e){let n=new URL(Kt(e.baseUrl,e.artifactId)),r=n.protocol===`https:`?C:S;await b.promises.mkdir(x.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){b.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:D(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}))}),w(n,b.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 Kt(e,t){let n=e.endsWith(`/`)?e:`${e}/`;return new URL(`artifacts/${encodeURIComponent(t)}`,n).toString()}function qt(e){return typeof e.baseUrl==`string`&&e.baseUrl.length>0}const Jt=3e3,Yt=1e3;function N(e){let t=an(e);if(!t||typeof t!=`object`)return null;let n=t,r=Xt(n);if(!r)return null;let i=Zt(n);return i?{token:r,...i,transport:Qt(n.transport),pid:F(n.pid)??0,version:P(n.version),codeSignature:P(n.codeSignature),processStartTime:P(n.processStartTime)}:null}function Xt(e){return typeof e.token==`string`&&e.token.length>0?e.token:null}function Zt(e){let t=F(e.port),n=F(e.httpPort);return t===void 0&&n===void 0?null:{port:t,httpPort:n}}function Qt(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=an(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){on(e)}function R(e){on(e)}function $t(e){let t=B(e);if(!t.hasLock||t.hasInfo)return;let n=I(e.lockPath);if(!n){R(e.lockPath);return}h(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=b.existsSync(e.infoPath),n=N(e.infoPath);if(n){let t=h(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=b.existsSync(e.lockPath),o=I(e.lockPath);if(o){let t=h(o.pid,o.processStartTime);t&&!r?i.retainedLockProcess=!0:(t&&(await de(o.pid,{termTimeoutMs:Jt,killTimeoutMs:Yt,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:b.existsSync(e.infoPath),hasLock:b.existsSync(e.lockPath)}}async function en(e){let t=B(e);if(!t.hasLock||t.hasInfo)return!1;let n=I(e.lockPath);return!n||!h(n.pid,n.processStartTime)?(R(e.lockPath),!0):!1}async function V(e){await de(e.pid,{termTimeoutMs:Jt,killTimeoutMs:Yt,expectedStartTime:e.processStartTime})}function tn(e){return typeof e.baseUrl==`string`&&e.baseUrl.length>0}function nn(e,t=m(process.env.AGENT_DEVICE_STATE_DIR)){let n=rn(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 rn(e){return`rm -f ${ae(e.infoPath)} ${ae(e.lockPath)}`}function an(e){if(!b.existsSync(e))return null;try{return JSON.parse(b.readFileSync(e,`utf8`))}catch{return null}}function on(e){try{b.existsSync(e)&&b.unlinkSync(e)}catch{}}function sn(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 cn(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(ie(r))try{return sn(r.event,{req:e.req,onProgress:e.onProgress}),!1}catch(e){return t(e)}return oe(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 ln(e,t){return ue(e)&&String(Array.isArray(t)?t.join(`,`):t??``).includes(`application/x-ndjson`)}function un(e,t){let{req:n,isSettled:r,resolve:i,reject:a,clearTimeout:o}=t,s=``,c=cn({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 dn(e,n){let{req:r,handleResponseBody:i,reject:a,clearTimeout:o}=n,s=``,c=!1,l=cn({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 fn(e,n){let{info:r,req:i,resolve:a,reject:o}=n;try{let n=pn(e);if(n.error){o(mn(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}hn(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 pn(e){return JSON.parse(e)}function mn(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 hn(e,t,n,r,i){try{r(e.baseUrl&&n.ok?await Ut(e,t,n):n)}catch(e){i(e)}}function gn(e,t){let n=e.meta?.requestId??i();return _n(e.command)?{jsonrpc:`2.0`,id:n,method:vn(e.command),params:yn(e,e.command,t)}:{jsonrpc:`2.0`,id:n,method:`agent_device.command`,params:e}}function _n(e){return e===`lease_allocate`||e===`lease_heartbeat`||e===`lease_release`}function vn(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 yn(e,t,n){return _e(ve(e),t,{includeTokenParam:n.includeTokenParam,token:e.token,session:e.session})}const bn=[`xcodebuild .*AgentDeviceRunnerUITests/RunnerTests/testCommand`,`xcodebuild .*AgentDeviceRunner\\.env\\.session-`,`xcodebuild build-for-testing .*apple-runner/AgentDeviceRunner/AgentDeviceRunner\\.xcodeproj`];function xn(e){let t=f(e.command);if(t.envelopeMs===`unbounded`)return;let n={...t,envelopeMs:t.envelopeMs};return Sn(n,e.positionals??[])??Cn(n,e.flags)??n.envelopeMs}function Sn(e,t){if(e.budget.source!==`positional-parser`)return;let n=e.budget.parser(t);return n===null?void 0:Tn(e,n)}function Cn(e,t){if(e.budget.source===`flag`)return e.budget.envelope===`widen`?wn(e,e.budget,t):typeof t?.timeoutMs==`number`?t.timeoutMs:e.envelopeMs}function wn(e,t,n){if(n?.settle!==!0)return e.envelopeMs;let r=typeof n.timeoutMs==`number`?n.timeoutMs:t.defaultBudgetMs;return typeof r==`number`?En(e,r):e.envelopeMs}function Tn(e,t){return Math.max(e.envelopeMs,t+Mn)}function En(e,t){return Math.max(e.envelopeMs,e.envelopeMs+t+Mn)}function Dn(e,n,r,i,a,o){let s=a?{terminated:0}:An(),l=!a&&On(i),u=l?jn(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:kn({remote:a,resetDaemon:l,command:i})})}function On(e){return f(e).onTimeout===`reset-daemon`}function kn(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===p.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 An(){let e=0;try{for(let t of bn)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 jn(e,t){let n=!1;try{h(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 Mn=3e4,Nn=`Daemon HTTP endpoint is unavailable`,Pn=`Daemon socket endpoint is unavailable`;async function U(e,t){let n=Un(e,t);if(await Fn(e,n))return!0;let r=Wn(e,t,n);return r?await Fn(e,r):!1}async function Fn(e,t){return t===`http`?await Ln(e):await In(e.port)}function In(e){return e?new Promise(t=>{let n=!1,r=T.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 Ln(e){return zn(e).then(e=>e.reachable)}async function Rn(e){let n=await zn(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:g(),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 zn(e){let t=e.baseUrl?E(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:`?C:S,i=e.baseUrl?3e3:500;return new Promise(t=>{let a=e.baseUrl?D(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,...Bn(n)})})});o.on(`timeout`,()=>{o.destroy(),t({reachable:!1})}),o.on(`error`,()=>{t({reachable:!1})}),o.end()})}function Bn(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 Vn(e,t,n,r,i,a={}){let o=Un(e,n);try{return await Hn(e,t,r,i,o,a)}catch(s){let c=Wn(e,n,o);if(!c||!Gn(s,o))throw s;return await Hn(e,t,r,i,c,a)}}async function Hn(e,t,n,r,i,a){return i===`http`?await Yn(e,t,n,r,a):await Jn(e,t,n,r,a)}function Un(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 Kn(e,n);let r=(e.transport===`socket`||e.transport===`dual`?[`socket`,`http`]:[`http`,`socket`]).find(t=>W(e,t));if(r)return r;throw new t(`COMMAND_FAILED`,`Daemon metadata has no reachable transport`)}function W(e,t){return t===`http`?!!e.httpPort:!!e.port}function Wn(e,t,n){if(t!==`auto`||e.baseUrl)return null;let r=n===`socket`?`http`:`socket`;return W(e,r)?r:null}function Gn(e,n){return n===`socket`&&e instanceof t&&e.code===`COMMAND_FAILED`&&e.message===`Failed to communicate with daemon`&&e.details?.daemonSocketRequestWritten===!1}function Kn(e,n){if(W(e,n))return n;throw new t(`COMMAND_FAILED`,n===`http`?Nn:Pn)}function qn(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 Jn(e,n,r,i,a){let o=e.port;if(!o)throw new t(`COMMAND_FAILED`,Pn);return new Promise((t,s)=>{let c=!1,l=T.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(Dn(e,r,n.meta?.requestId,n.command,!1,i))},i):void 0;un(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(qn(e,n.meta?.requestId,!1,{daemonSocketRequestWritten:c})))})})}async function Yn(e,n,r,i,a){let o=e.baseUrl?new URL(E(e.baseUrl,`rpc`)):e.httpPort?new URL(`http://127.0.0.1:${e.httpPort}/rpc`):null;if(!o)throw new t(`COMMAND_FAILED`,Nn);let s=JSON.stringify(gn(n,{includeTokenParam:!e.baseUrl})),c={"content-type":`application/json`,"content-length":Buffer.byteLength(s)};return e.baseUrl&&Object.assign(c,D(e.token)),await new Promise((l,u)=>{let d=(o.protocol===`https:`?C:S).request({protocol:o.protocol,host:o.hostname,port:o.port,method:`POST`,path:o.pathname+o.search,headers:c},r=>{if(ln(n,r.headers?.[`content-type`])){dn(r,{req:n,onProgress:a.onProgress,reject:u,clearTimeout:()=>{p&&clearTimeout(p)},handleResponseBody:t=>fn(t,{info:e,req:n,resolve:l,reject:u})});return}re(r).then(t=>{p&&clearTimeout(p),fn(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=tn(e),p=typeof i==`number`?setTimeout(()=>{d.destroy(),u(Dn(e,r,n.meta?.requestId,n.command,f,i))},i):void 0;d.on(`error`,e=>{p&&clearTimeout(p),u(qn(e,n.meta?.requestId,f))}),d.write(s),d.end()})}const G=15e3,K=new T.BlockList;K.addSubnet(`127.0.0.0`,8,`ipv4`),K.addAddress(`::1`,`ipv6`),K.addSubnet(`::ffff:127.0.0.0`,104,`ipv6`);function Xn(e){let t=Zn(e),n=Qn(e),r=$n(e,n.remoteBaseUrl),i=er(e,t,n.rawBaseUrl);return{paths:m(i?tr():t),transportPreference:r.preference,serverMode:r.serverMode,ownedStateDir:i,remoteBaseUrl:n.remoteBaseUrl,remoteAuthToken:n.authToken}}function Zn(e){return e.flags?.stateDir??process.env.AGENT_DEVICE_STATE_DIR}function Qn(e){let t=e.flags?.daemonBaseUrl??process.env.AGENT_DEVICE_DAEMON_BASE_URL,n=yr(t),r=e.flags?.daemonAuthToken??process.env.AGENT_DEVICE_DAEMON_AUTH_TOKEN;return br(n,r),{rawBaseUrl:t,remoteBaseUrl:n,authToken:r}}function $n(e,n){let r=e.flags?.daemonTransport??process.env.AGENT_DEVICE_DAEMON_TRANSPORT,i=fe(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:ne(e.flags?.daemonServerMode??process.env.AGENT_DEVICE_DAEMON_SERVER_MODE??(r===`dual`?`dual`:void 0))}}function er(e,t,n){return fr(e.command)&&!t&&!n}function tr(){return b.mkdtempSync(x.join(qe.tmpdir(),`agent-device-replay-daemon-`))}async function nr(e){if(e.remoteBaseUrl)return await rr(e);let t=await ir(e);return t?{info:t,startedByClient:!1}:($t(e.paths),await ur(e))}async function rr(e){let n={transport:`http`,token:e.remoteAuthToken??``,pid:0,baseUrl:e.remoteBaseUrl};if((await Rn(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 ir(e){let t=N(e.paths.infoPath);if(!t)return null;let n=await ar(t,e.transportPreference);return sr(t,n)?t:(cr(t,n,e.paths.baseDir),await V(t),L(e.paths.infoPath),null)}async function ar(e,t){try{return await U(e,t)}catch(e){if(or(e))return!1;throw e}}function or(e){return e instanceof t&&e.code===`COMMAND_FAILED`&&(e.message===`Daemon HTTP endpoint is unavailable`||e.message===`Daemon socket endpoint is unavailable`)}function sr(e,t){return e.version===g()&&e.codeSignature===gr()&&t}function cr(e,t,n){try{let r=e.version?`pid ${e.pid}, v${e.version}`:`pid ${e.pid}`,i=lr(e,t);process.stderr.write(`Replacing daemon (${r}) in ${n}: ${i}\n`)}catch{}}function lr(e,t){return e.version===g()?e.codeSignature===gr()?t?`not reusable`:`unreachable`:`code-signature mismatch`:`version mismatch (client v${g()})`}async function ur(e){let n=0,r=[],i,a;for(let t=1;t<=2;t+=1){let o;try{o=mr(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 _(150);continue}break}let s=await pr(G,e,o);if(s.kind===`ready`)return{info:s.info,startedByClient:!0};if(s.kind===`early_exit`){if(a=s.exit,i=_r(s.exit),r.push(await z(e.paths,`start_error`)),t<2){await _(150);continue}break}if(await en(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 pr(G,e,o);if(t.kind===`ready`)return{info:t.info,startedByClient:!0};t.kind===`early_exit`&&(a=t.exit,i=_r(t.exit));break}if(!l)break;!c.hasInfo&&!c.hasLock&&await _(150)}let o=B(e.paths),s=vr(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:G,startupAttempts:2,lockRecoveryCount:n,cleanupResults:r,startError:i,daemonProcess:a,...s?{daemonLogTail:s}:{},metadataState:o,hint:nn(o,e.paths)})}async function dr(e,t,n){if(!fr(e.command)||!t.startedByClient&&!n.ownedStateDir||tn(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=b.existsSync(n.paths.infoPath);L(n.paths.infoPath),r.removedInfo=e&&!b.existsSync(n.paths.infoPath);let t=b.existsSync(n.paths.lockPath);R(n.paths.lockPath),r.removedLock=t&&!b.existsSync(n.paths.lockPath),n.ownedStateDir&&(b.rmSync(n.paths.baseDir,{recursive:!0,force:!0}),r.removedStateDir=!b.existsSync(n.paths.baseDir))}c({level:r.error?`warn`:`info`,phase:`daemon_replay_cleanup`,data:r})}function fr(e){return e===p.replay||e===p.test}async function pr(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 U(e,t.transportPreference))return{kind:`ready`,info:e};if(i)return{kind:`early_exit`,exit:i};await _(100)}return{kind:`timeout`}}function mr(e){let t=hr(),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};b.mkdirSync(e.paths.baseDir,{recursive:!0});let i=b.openSync(e.paths.logPath,`a`),a=b.openSync(e.paths.logPath,`a`);try{return u(process.execPath,n,{env:r,stdio:[`ignore`,i,a]})}finally{b.closeSync(i),b.closeSync(a)}}function hr(){let e=me(),n=[x.join(e,`dist`,`src`,`internal`,`daemon.js`),x.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=>b.existsSync(e))??r,a=x.join(e,`src`,`daemon.ts`),o=n.some(e=>b.existsSync(e)),s=b.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 gr(){let e=hr();return pe(e.useSrc?e.srcPath:e.distPath,e.root)}function _r(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 vr(e){try{if(!b.existsSync(e))return;let t=b.statSync(e);if(t.size<=0)return;let n=Math.min(t.size,64e3),r=b.openSync(e,`r`);try{let e=Buffer.alloc(n);b.readSync(r,e,0,n,t.size-n);let i=e.toString(`utf8`).trim();return i.length>0?i:void 0}finally{b.closeSync(r)}}catch{return}}function yr(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 br(e,n){if(!e)return;let r=new URL(e).hostname;if(!xr(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 xr(e){let t=e.trim().toLowerCase().replace(/^\[(.*)\]$/,`$1`);return t===`localhost`?!0:T.isIPv4(t)?K.check(t,`ipv4`):T.isIPv6(t)?K.check(t,`ipv6`):!1}async function Sr(e,t={}){let n=e.meta?.requestId??i(),r=!!(e.meta?.debug||e.flags?.verbose),a=Xn(e),s=xn(e),l=await o(`daemon_startup`,async()=>await nr(a),{requestId:n,session:e.session}),u=l.info,d=await Mt(e,u);Cr(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 Vn(u,f,a.transportPreference,a.paths,s,t),{requestId:n,command:e.command})}finally{await dr(e,l,a)}}function Cr(e){!wr(e)||process.stderr.isTTY!==!0||process.env.CI||process.stderr.write(e===p.reinstall?`Reinstalling...
|
|
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...
|
|
2
2
|
`:`Installing...
|
|
3
|
-
`)}function wr(e){return e===p.install||e===p.reinstall||e===d.installSource}const Tr=8081;function Er(e){return typeof e==`string`&&e.trim()?Re(e.trim()):``}function q(e){return typeof e==`string`&&e.trim()?e.trim():void 0}function J(e,t,n){return he(e,{env:t,cwd:n})}function Dr(e){try{return b.accessSync(e,b.constants.F_OK),!0}catch{return!1}}function Or(e){try{return b.statSync(e).isDirectory()}catch{return!1}}function kr(e){let n=x.join(e,`package.json`),r=He(e);if(!r)throw new t(`INVALID_ARGS`,`package.json not found at ${n}`);return r}function Ar(e){return Dr(x.join(e,`pnpm-lock.yaml`))?{command:`pnpm`,installArgs:[`install`]}:Dr(x.join(e,`yarn.lock`))?{command:`yarn`,installArgs:[`install`]}:{command:`npm`,installArgs:[`install`]}}function jr(e,t){return t===`auto`?Ve(kr(e))===`expo`?`expo`:`react-native`:t}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 Mr(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 Nr(e,t){return{platform:t,bundleUrl:ze(e,t)}}function Pr(e,t){return{platform:t,metroHost:q(e?.metro_host),metroPort:e?.metro_port,bundleUrl:q(e?.metro_bundle_url),launchUrl:q(e?.launch_url)}}function Fr(e,t){if(Or(x.join(e,`node_modules`)))return{installed:!1};let n=Ar(e);return a(n.command,n.installArgs,{cwd:e,env:t}),{installed:!0,packageManager:n.command}}async function Ir(e){await _(e)}async function Lr(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 Rr(e,t){try{let n=await Lr(e,t);return n.ok&&n.body.includes(`packager-status:running`)}catch{return!1}}function zr(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 Br(e){let t=q(e);if(!t)return`/reload`;let n=new URL(t).pathname.replace(/\/+$/,``);return n.endsWith(`/index.bundle`)?`${n.slice(0,-13)}/reload`:`/reload`}function Vr(e,t,n){return q(e.metroHost)??(t?void 0:q(e.runtime?.metroHost))??(n?void 0:`localhost`)}function Hr(e,t,n){if(e.metroPort!==void 0)return Mr(e.metroPort,Tr);if(!t)return e.runtime?.metroPort??(n?void 0:Tr)}function Ur(e){let n=q(e.bundleUrl),r=n??e.runtime?.bundleUrl,i=!!n,a=!!q(r),o=Ue({metroHost:Vr(e,i,a),metroPort:Hr(e,i,a),bundleUrl:r});if(!o)throw new t(`INVALID_ARGS`,`Unable to resolve Metro host and port for reload.`);return zr(o,Br(r))}function Wr(e,t,n){return e===`expo`?{command:`npx`,installArgs:[`expo`,`start`,`--host`,`lan`,`--port`,String(t)]}:{command:`npx`,installArgs:[`react-native`,`start`,`--host`,n,`--port`,String(t)]}}function Gr(e,n,r,i,a,o){let c=Wr(n,r,i);b.mkdirSync(x.dirname(a),{recursive:!0});let l=b.openSync(a,`a`),u=0;try{u=s(c.command,c.installArgs,{cwd:e,env:o,stdio:[`ignore`,l,l]})}finally{b.closeSync(l)}if(!Number.isInteger(u)||u<=0)throw new t(`COMMAND_FAILED`,`Failed to start Metro. Expected a detached child PID.`);return{pid:u}}async function Kr(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 ge(e,1e3)){try{process.kill(e,`SIGKILL`)}catch(e){let t=e.code;if(t===`ESRCH`||t===`EPERM`)return;throw e}await ge(e,1e3)}}}function qr(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 Jr(e,t){return!!(e>=500||e===408||e===425||e===429||JSON.stringify(t).includes(`Metro companion is not connected`))}function Yr(e){return!!(e&&typeof e==`object`&&`retryable`in e&&e.retryable===!0)}async function Xr(e){let t;try{t=await fetch(`${e.baseUrl}/api/metro/bridge`,{method:`POST`,headers:qr(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=Zr(await t.text(),t.status,e.baseUrl);if(!t.ok)throw X(`/api/metro/bridge failed (${t.status}): ${JSON.stringify(n)}`,Jr(t.status,n));return $r(n)}function Zr(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)}`,Jr(t,e))}}function Qr(e){return{enabled:e.enabled,baseUrl:e.base_url,statusUrl:e.status_url??``,bundleUrl:e.bundle_url??``,iosRuntime:Pr(e.ios_runtime,`ios`),androidRuntime:Pr(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 $r(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 Qr(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 ei(e,n){if(!n?.iosRuntime.bundleUrl)throw new t(`COMMAND_FAILED`,Z(e,`bridge descriptor is missing ios_runtime.metro_bundle_url`,n))}function ti(e,n,r){let i=n||q(r.AGENT_DEVICE_METRO_BEARER_TOKEN)||``,a=i||e&&q(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 ni(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 ri(e,n){if(!(e||n))throw new t(`INVALID_ARGS`,`metro prepare requires --public-base-url <url> or --proxy-base-url <url>.`)}function ii(e,t,n){return e.runtimeFilePath?J(e.runtimeFilePath,t,n):null}function ai(e,t,n,r){return J(e.logPath??x.join(r,`.agent-device`,`metro.log`),t,n)}function oi(e){let t=e.env??process.env,n=process.cwd(),r=J(e.projectRoot??n,t,n),i=Er(e.publicBaseUrl),a=Er(e.proxyBaseUrl);ri(i,a);let{proxyEnabled:o,proxyBaseUrl:s,proxyBearerToken:c}=ti(a,q(e.proxyBearerToken)??``,t);return{env:t,projectRoot:r,kind:jr(r,e.kind??`auto`),metroPort:Mr(e.metroPort??8081,8081),listenHost:q(e.listenHost)??`0.0.0.0`,statusHost:q(e.statusHost)??`127.0.0.1`,publicBaseUrl:i,proxyBaseUrl:s,proxyBearerToken:c,bridgeScope:o?ni(e.bridgeScope):null,startupTimeoutMs:Y(e.startupTimeoutMs,18e4,3e4),probeTimeoutMs:Y(e.probeTimeoutMs,1e4,1e3),reuseExisting:e.reuseExisting??!0,installProjectDeps:e.installDependenciesIfNeeded??!0,runtimeFilePath:ii(e,t,n),logPath:ai(e,t,n,r)}}async function si(e,t,n){let r=Date.now()+t;for(;Date.now()<r;){let t=r-Date.now();if(await Rr(e,Math.min(n,Math.max(t,1))))return!0;let i=Math.min(500,Math.max(r-Date.now(),0));i>0&&await Ir(i)}return!1}async function ci(e){let n=Date.now()+e.startupTimeoutMs,r=null,i=null;for(;Date.now()<n;){try{let t=await Xr({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),!Yr(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 Ir(a)}throw new t(`COMMAND_FAILED`,Z(e.baseUrl,i,r,e.initialBridgeError,e.companionLogPath))}async function li(e){let n=`http://${e.statusHost}:${e.metroPort}/status`;if(e.reuseExisting&&await Rr(n,e.probeTimeoutMs))return{started:!1,reused:!0,pid:0,statusUrl:n};let r=Gr(e.projectRoot,e.kind,e.metroPort,e.listenHost,e.logPath,e.env);if(await si(n,e.startupTimeoutMs,e.probeTimeoutMs))return{started:!0,reused:!1,pid:r.pid,statusUrl:n};throw await Kr(r.pid).catch(()=>{}),new t(`COMMAND_FAILED`,`Metro did not become ready at ${n} within ${e.startupTimeoutMs}ms. Check ${e.logPath}.`,{logPath:e.logPath})}async function ui(e,t){let n=t.bridgeScope;if(!n)return null;let r=null,i=null;try{r=await Xr({baseUrl:t.proxyBaseUrl,bearerToken:t.proxyBearerToken,scope:n,timeoutMs:t.probeTimeoutMs})}catch(e){if(!Yr(e))throw e;i=e instanceof Error?e.message:String(e)}return(!r||r.probe.reachable===!1)&&(r=await di(e,t,n,r,i)),ei(t.proxyBaseUrl,r),r}async function di(e,n,r,i,a){let o;try{o=(await Be({projectRoot:n.projectRoot,serverBaseUrl:n.proxyBaseUrl,bearerToken:n.proxyBearerToken,bridgeScope:r,localBaseUrl:`http://${n.statusHost}:${n.metroPort}`,launchUrl:q(e.launchUrl),profileKey:q(e.companionProfileKey),consumerKey:q(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 ci({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 fi(e){return{baseIosRuntime:e?Nr(e,`ios`):{platform:`ios`},baseAndroidRuntime:e?Nr(e,`android`):{platform:`android`}}}function pi(e,t){e&&(b.mkdirSync(x.dirname(e),{recursive:!0}),b.writeFileSync(e,JSON.stringify(t,null,2)))}async function mi(e={}){let t=oi(e),n=t.installProjectDeps?Fr(t.projectRoot,t.env):{installed:!1},r=await li(t),{baseIosRuntime:i,baseAndroidRuntime:a}=fi(t.publicBaseUrl),o=await ui(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 pi(t.runtimeFilePath,l),l}async function hi(e={}){let n=Y(e.timeoutMs,1e4,1e3),r=Ur(e),i=await Lr(r,n);if(!i.ok)throw new t(`COMMAND_FAILED`,`Metro reload failed (${i.status}).`,{reloadUrl:r,status:i.status,body:i.body,hint:`Verify Metro is running and the target React Native app is connected to this Metro instance.`});return{reloaded:!0,reloadUrl:r,status:i.status,body:i.body}}const gi={...Ae(),batch:je(_i)};function _i(e,n,r){let i=gi[e];if(!i)throw Error(`Missing daemon writer for batch command: ${e}`);let a=We(e);if(!a)throw Error(`Missing command metadata for batch command: ${e}`);try{return yi(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 vi(e,t){let n=gi[e];if(!n)throw Error(`Missing daemon writer for command: ${e}`);return yi(n,We(e),t)}function yi(e,t,n){let r=e(n);return{...r,...t?{metadataFlags:ke(t,r.options)}:{}}}function bi(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 xi=e({createAgentDeviceClient:()=>Si});function Si(e={},t={}){let n=t.transport??Sr,i=t=>r(t.responseLevel??e.responseLevel),a=async(t,r=[],i={},a)=>{let o=$(e,i),s=await n({session:we(o.session),command:t,positionals:r,flags:Me(o,a),runtime:o.runtime,meta:De(o)});return s.ok||bi(s.error),s.data??{}},o=async(e={})=>{let t=await a(d.sessionList,[],e);return(Array.isArray(t.sessions)?t.sessions:[]).map(Pe)},s=async(e,t={})=>{let n=vi(e,t);return await a(n.command,n.positionals,n.options,n.metadataFlags)},c=(t={})=>we($(e,t).session);return{command:{wait:async e=>await s(`wait`,e),alert:async(e={})=>await s(`alert`,e),appState:async(e={})=>await s(`appstate`,e),back:async(e={})=>await s(`back`,e),home:async(e={})=>await s(`home`,e),rotate:async e=>await s(`rotate`,e),appSwitcher:async(e={})=>await s(`app-switcher`,e),keyboard:async(e={})=>await s(`keyboard`,e),clipboard:async e=>await s(`clipboard`,e),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(Ie)},capabilities:async(e={})=>{let t=await s(`capabilities`,e),n=Array.isArray(t.availableCommands)?t.availableCommands.filter(e=>typeof e==`string`):[];return{device:Ie(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={})=>m($(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=>Ne(await s(`install`,e),c(e)),reinstall:async e=>Ne(await s(`reinstall`,e),c(e)),installFromSource:async e=>Oe(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=Te(n),i=v(n,`appBundleId`),a=i;return{session:t,sessionStateDir:v(n,`sessionStateDir`),appName:v(n,`appName`),appBundleId:i,appId:a,startup:Ee(n.startup),runtime:be(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=>Fe(await a(d.releaseMaterializedPaths,[],{...e,materializationId:e.materializationId}))},leases:{allocate:async e=>Ti(await a(d.leaseAllocate,[],{...e,leaseId:void 0})),heartbeat:async e=>Ti(await a(d.leaseHeartbeat,[],e)),release:async e=>{let t=await a(d.leaseRelease,[],e);return{released:t.released===!0,provider:Q(t.provider)}}},metro:{prepare:async t=>await mi({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 hi({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:Ci(n,t)},screenshot:async(e={})=>{let t=c(e),n=await s(`screenshot`,e);if(i(e))return n;let r=le(n);return{path:y(n,`path`),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),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 Ci(e,t){let n=v(e,`appBundleId`);return{nodes:xe(e.nodes),truncated:e.truncated===!0,appName:v(e,`appName`),appBundleId:n,...wi(e),identifiers:{session:t,appId:n,appBundleId:n}}}function wi(e){let t=Q(e.visibility),n=Q(e.unchanged),r=ce(e.snapshotDiagnostics);return{...t?{visibility:t}:{},...ye(e),...n?{unchanged:n}:{},...r?{snapshotDiagnostics:r}:{}}}function Q(e){return Le(e)?e:void 0}function $(e,t){return{...e,...t}}function Ti(e){let t=e.lease;if(!Le(t))throw Error(`Invalid lease response from daemon`);return{leaseId:y(t,`leaseId`),tenantId:y(t,`tenantId`),runId:y(t,`runId`),backend:y(t,`backend`),leaseProvider:v(t,`leaseProvider`),clientId:v(t,`clientId`),deviceKey:v(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{Xn as a,Ze as c,nr as i,E as l,Si as n,Xe as o,Sr as r,D as s,xi 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(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};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{m as e}from"./sdk-batch.js";import{o as t}from"./registry.js";const n=t(),r=new Map(n.map(e=>[e.name,e]));function i(){return[...n]}function a(){return e().map(e=>{let t=s(e);if(!t)throw Error(`Missing command metadata for MCP-exposed command: ${e}`);return t})}function o(e){return r.has(e)}function s(e){return r.get(e)}export{a as i,o as n,i as r,s as t};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{g as e,m as t,r as n}from"./registry.js";import{r}from"./command-metadata.js";const i={cdp:{usageOverride:`cdp [...args]`,listUsageOverride:`cdp`,helpDescription:`Run CDP commands for React Native diagnostics, JS heap usage, heap snapshots, and leak analysis`,summary:`Inspect React Native CDP targets, JS heap growth, heap snapshots, retainers, and leak signals`,positionalArgs:[`args?`],allowsExtraPositionals:!0,supportedFlags:t},auth:{usageOverride:`auth status|login|logout`,listUsageOverride:`auth`,helpDescription:`Manage cloud login state used by remote daemon and cloud device workflows.`,summary:`Manage cloud login state used by remote daemon and cloud device workflows`,positionalArgs:[`status|login|logout`],supportedFlags:[`remoteConfig`,`stateDir`]},connect:{usageOverride:`connect [cloud|proxy|browserstack|aws-device-farm] [--remote-config <path>] [--daemon-base-url <url>] [--tenant <id>] [--run-id <id>] [--lease-id <id>] [--lease-backend <backend>] [--force] [--no-login]`,helpDescription:`Connect to a remote daemon, authenticate when needed, and save remote session state. AGENT_DEVICE_CLOUD_BASE_URL is the bridge/control-plane API origin; use AGENT_DEVICE_DAEMON_AUTH_TOKEN=adc_live_... for CI/service-token automation.`,listUsageOverride:`connect`,summary:`Attach CLI commands to a saved remote daemon/cloud lease; inspect for remote runs, tenants, or service-token CI`,allowedFlags:[`remoteConfig`,`daemonBaseUrl`,`tenant`,`runId`,`leaseId`,`leaseBackend`,`providerApp`,`providerOsVersion`,`providerProject`,`providerBuild`,`providerSessionName`,`awsProjectArn`,`awsDeviceArn`,`awsAppArn`,`awsRegion`,`awsInteractionMode`,`force`,`noLogin`],supportedFlags:[`stateDir`,`daemonAuthToken`,`session`,`platform`,`device`,...e,`launchUrl`]},connection:{usageOverride:`connection status`,listUsageOverride:`connection`,helpDescription:`Inspect active remote connection state`,summary:`Inspect the active saved remote connection before assuming commands are local`,positionalArgs:[`status`],supportedFlags:[`remoteConfig`,`stateDir`,`session`]},disconnect:{helpDescription:`Disconnect remote daemon state, stop owned Metro companion, and release lease`,listUsageOverride:`disconnect`,summary:`Clear remote connection state, stop owned Metro companions, and release remote leases`,allowedFlags:[`shutdown`],supportedFlags:[`remoteConfig`,`stateDir`,`session`]},mcp:{helpDescription:`Start the official stdio MCP server. It exposes structured command tools backed by the agent-device client.`,summary:`Start MCP server`},proxy:{usageOverride:`proxy [--host <host>] [--port <port>] [--daemon-auth-token <token>] [--state-dir <path>]`,listUsageOverride:`proxy`,helpDescription:`Expose the local daemon HTTP contract through a tunnel-friendly reverse proxy.
|
|
2
2
|
|
|
3
3
|
Run this on the host that has access to simulators/devices, expose the printed local proxy URL through a tunnel, then point another machine at the tunnel URL with connect proxy.
|
|
4
4
|
|
|
@@ -9,7 +9,7 @@ Use the /agent-device base path when connecting through cloudflared, ngrok, or a
|
|
|
9
9
|
Examples:
|
|
10
10
|
agent-device proxy --port 4310
|
|
11
11
|
cloudflared tunnel --url http://127.0.0.1:4310
|
|
12
|
-
agent-device connect proxy --daemon-base-url https://example.trycloudflare.com/agent-device --daemon-auth-token <token>`,summary:`Expose a local daemon through cloudflared, ngrok, or another HTTP tunnel`,allowedFlags:[`proxyHost`,`proxyPort`,`daemonAuthToken`,`stateDir`]},"react-devtools":{usageOverride:`react-devtools [...args]`,listUsageOverride:`react-devtools`,helpDescription:`Run pinned agent-react-devtools commands for React Native performance profiling, component trees, props/state/hooks, and render analysis`,summary:`Inspect React Native components, props, hooks, errors, slow renders, and rerender profiles`,positionalArgs:[`args?`],allowsExtraPositionals:!0,supportedFlags:
|
|
12
|
+
agent-device connect proxy --daemon-base-url https://example.trycloudflare.com/agent-device --daemon-auth-token <token>`,summary:`Expose a local daemon through cloudflared, ngrok, or another HTTP tunnel`,allowedFlags:[`proxyHost`,`proxyPort`,`daemonAuthToken`,`stateDir`]},"react-devtools":{usageOverride:`react-devtools [...args]`,listUsageOverride:`react-devtools`,helpDescription:`Run pinned agent-react-devtools commands for React Native performance profiling, component trees, props/state/hooks, and render analysis`,summary:`Inspect React Native components, props, hooks, errors, slow renders, and rerender profiles`,positionalArgs:[`args?`],allowsExtraPositionals:!0,supportedFlags:t},web:{usageOverride:`web setup | web doctor`,listUsageOverride:`web setup|doctor`,helpDescription:`Install and inspect the managed web automation backend used by --platform web.
|
|
13
13
|
|
|
14
14
|
First-run flow:
|
|
15
15
|
agent-device web setup
|
|
@@ -19,4 +19,4 @@ First-run flow:
|
|
|
19
19
|
|
|
20
20
|
Runtime web commands do not install the backend implicitly. If the managed backend is missing, run agent-device web setup. The backend is resolved only from the managed install in the effective agent-device state dir.
|
|
21
21
|
|
|
22
|
-
Use web setup to install or reuse the pinned backend. Use web doctor after setup to verify browser backend health.`,summary:`Manage web automation backend`,positionalArgs:[`setup|doctor`],supportedFlags:[`stateDir`]}},a=n();function o(e){return Object.hasOwn(i,e)?i[e]:void 0}function s(e){return Object.hasOwn(a,e)?a[e]:void 0}const c=new Map(r().map(
|
|
22
|
+
Use web setup to install or reuse the pinned backend. Use web doctor after setup to verify browser backend health.`,summary:`Manage web automation backend`,positionalArgs:[`setup|doctor`],supportedFlags:[`stateDir`]}},a=n();function o(e){return Object.hasOwn(i,e)?i[e]:void 0}function s(e){return Object.hasOwn(a,e)?a[e]:void 0}const c=new Map(r().map(e=>[e.name,{helpDescription:e.description,supportedFlags:t}]));function l(e){if(e)return d(e)}function u(e){let t=d(e);if(!t)throw Error(`Missing command schema for ${e}`);return t}function d(e){let t=o(e);if(t)return t;let n=c.get(e),r=s(e);if(n)return r?{...n,...r}:n}function f(e,t){let n=l(e);if(!n?.defaults)return!1;let r=!1;for(let[e,i]of Object.entries(n.defaults))t[e]===void 0&&(t[e]=i,r=!0);return r}export{u as n,l as r,f as t};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{t as e}from"./rolldown-runtime.js";import{F 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{
|
|
2
|
-
`).replace(/\n$/,``),n=t.match(/^clipboard text:\s*(.*)$/i);return n?n[1]??``:t.trim().toLowerCase()===`null`?``:t}export{
|
|
1
|
+
import{t as e}from"./rolldown-runtime.js";import{F 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
|
+
`).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{F as e,p as t,w as n}from"./sdk-contracts.js";import{
|
|
1
|
+
import{F as e,p as t,w as n}from"./sdk-contracts.js";import{x as r}from"./android-input-ownership.js";import{i,o 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),i=e.target,s;try{s=await a(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=>!i||e.target===i)??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 a([`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 a([`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 i().whichCommand(`xcrun`))throw new e(`TOOL_MISSING`,`xcrun not found in PATH`);let l=r(s.simulatorSetPath),u=await a(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{O as e}from"./sdk-contracts.js";import{t
|
|
1
|
+
import{O as e}from"./sdk-contracts.js";import{Cn as t,F as n,G as r,I as i,wn 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{$t as p,Gt as m,Rt as h,en as g,kt as _,ln as v,zt 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 p(`INVALID_ARGS`,`find requires a locator or text`);let{locator:d,query:f,action:m,value:h,timeoutMs:y}=l(s);if(!f)return p(`INVALID_ARGS`,`find requires a value`);if(t.flags?.findFirst&&t.flags?.findLast)return p(`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 g();let T=C?.device??await v(t.flags??{});C||await b(T);let j=O(m),M=u(d,f),N=ee({device:T,session:C,req:t,logPath:r,locator:d,query:f,scope:T.platform!==`web`&&!M&&$(d)&&!j?f:void 0,interactiveOnly:j,sessionStore:i,sessionName:n}),P={req:t,sessionName:n,logPath:r,sessionStore:i,invoke:a,session:C,device:T,command:o,locator:d,query:f,publicFlags:Z(t.flags)};if(m===`wait`)return B(P,N,d,f,y);let F=await N();if(c(F.snapshotQuality))return k(F.snapshotQuality);let{nodes:I}=F,R=A({nodes:I,locator:d,query:f,selectorChain:M,requiresRect:j,flags:t.flags,platform:T.platform});if(!R.ok)return R.response;let z=R.node,J=j?L(I,z):z,Y={node:z,resolvedNode:J,ref:`@${J.ref}`,nodes:I,actionFlags:{...t.flags??{},noRecord:!0}};C&&(_(C),i.set(n,C));let X={exists:()=>V(P),get_text:()=>H(P,Y),get_attrs:()=>U(P,Y),click:()=>W(P,Y),fill:()=>G(P,Y,h),focus:()=>K(P,Y),type:()=>q(P,Y,h)}[m];return X?E(await X(),()=>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 ee(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 k(e){return p(`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 A(e){let{nodes:t,locator:n,query:r,selectorChain:i,requiresRect:a,flags:o,platform:s}=e,c=a?t.filter(e=>!R(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:p(`COMMAND_FAILED`,`find did not match any element`)}}let l=d(c,n,r,{requireRect:a});if(a&&(l.matches=M(l.matches,t)),a&&l.matches.length>1){let e=j(l.matches,o);if(!e)return{ok:!1,response:Q(l.matches,n,r)};l.matches=e}let u=l.matches[0]??null;return u?{ok:!0,node:u}:{ok:!1,response:p(`COMMAND_FAILED`,`find did not match any element`)}}function j(e,t){return t?.findFirst?[e[0]]:t?.findLast?[e[e.length-1]]:null}function M(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 N(i.length>0?i:t,n)}function N(e,t){return e.length<2?e:e.map((e,n)=>({node:e,index:n,score:P(e,t)})).sort((e,t)=>t.score===e.score?I(e.node)-I(t.node)||e.index-t.index:t.score-e.score).map(e=>e.node)}function P(e,t){let n=i(t,e);if(n.reason===`covered`)return 0;let r=F(n,t[0]);return r>0?r:e.hittable&&e.rect&&!R(e,t[0])?3:+!!e.rect}function F(e,t){return e.node.rect?e.reason===`semantic-target`||e.reason===`same-rect-descendant`?4:e.reason===`hittable-ancestor`&&!R(e.node,t)?2:0:0}function I(e){return e.rect?e.rect.width*e.rect.height:1/0}function L(e,t){let r=n(e,t);return R(r,e[0])&&t.rect?t:r}function R(e,t){if(!t?.rect||!e.rect)return!1;let n=e.type?.toLowerCase()??``;return!n.includes(`application`)&&!n.includes(`window`)?!1:z(e.rect,t.rect)}function z(e,t){return e.x===t.x&&e.y===t.y&&e.width===t.width&&e.height===t.height}async function B(e,t,n,r,i){let{req:a,sessionStore:s,session:l,command:u,publicFlags:f}=e,m=i??1e4,h=Date.now(),g;for(;Date.now()-h<m;){let{nodes:e,snapshotQuality:i}=await t();if(c(i)){g=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()-h},{flags:f}),{ok:!0,data:{found:!0,waitedMs:Date.now()-h}};await o(300)}return g?k(g):p(`COMMAND_FAILED`,`find wait timed out`)}async function V(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 H(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)=>y(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 U(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 W(n,r){let{req:i,sessionName:o,sessionStore:s,session:c,invoke:l,command:u,locator:d,query:f,publicFlags:p}=n,m=await l({token:i.token,session:o,command:`click`,positionals:[r.ref],flags:r.actionFlags});if(!m.ok)return m;let h=r.resolvedNode.rect?e(r.resolvedNode.rect):r.node.rect?e(r.node.rect):null,g={ref:r.ref,locator:d,query:f};h&&(g.x=h.x,g.y=h.y);let _=t(m.data)??`Tapped ${r.ref}${h?` (${h.x}, ${h.y})`:``}`;return Object.assign(g,a(_)),w(s,c,i,u,{ref:r.ref,action:`click`,locator:d,query:f},{flags:p}),{ok:!0,data:g}}async function G(e,t,n){let{req:r,sessionName:i,sessionStore:a,session:o,invoke:s,command:c,publicFlags:l}=e;if(!n)return p(`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 K(e,t){let n=await J(e,t);return n.ok&&X(e,t,`focus`),n}async function q(e,t,n){let{req:r,device:i,logPath:a,session:o}=e;if(!n)return p(`INVALID_ARGS`,`find type requires text`);let s=await J(e,t);if(!s.ok)return s;let c=await m(i,`type`,[n],r.flags?.out,{...y(a,r.flags,o?.appBundleId,o?.trace?.outPath)});return X(e,t,`type`),{ok:!0,data:c??{ref:t.ref}}}async function J(t,n){let{req:r,device:i,logPath:a,session:o}=t,s=Y(n,`be focused`);if(s)return s;let c=n.resolvedNode.rect?e(n.resolvedNode.rect):null;return c?{ok:!0,data:await m(i,`focus`,[String(c.x),String(c.y)],r.flags?.out,{...y(a,r.flags,o?.appBundleId,o?.trace?.outPath)})??{ref:n.ref}}:p(`COMMAND_FAILED`,`matched element has no bounds`)}function Y(e,t){let n=[e.resolvedNode,e.node].find(r);return n?p(`COMMAND_FAILED`,`Matched element ${e.ref} is covered by another visible element and cannot ${t} safely`,{ref:`@${n.ref}`,interactionBlocked:n.interactionBlocked,hint:`Use a different visible target, scroll it clear of the overlay, or inspect with snapshot/screenshot before retrying.`}):null}function X(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 Z(e){return{...h(e)??{}}}function Q(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 p(`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{Cn 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};
|