agent-device 0.20.3 → 0.20.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.3.apk → agent-device-android-ime-helper-0.20.4.apk} +0 -0
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.4.apk.sha256 +1 -0
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.3.manifest.json → agent-device-android-ime-helper-0.20.4.manifest.json} +4 -4
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.4.apk +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.4.apk.sha256 +1 -0
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.3.manifest.json → agent-device-android-snapshot-helper-0.20.4.manifest.json} +6 -6
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +57 -4
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +45 -9
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Keyboard.swift +73 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Navigation.swift +1 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollGesture.swift +3 -2
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SequenceExecution.swift +1 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedGesturePolicy.swift +8 -2
- package/dist/src/agent-browser-tool.js +1 -1
- package/dist/src/agent-device-client.js +2 -2
- package/dist/src/android-adb.d.ts +1 -1
- package/dist/src/android.js +1 -1
- package/dist/src/app-helpers.js +1 -1
- package/dist/src/app-inventory.d.ts +4 -0
- package/dist/src/app-lifecycle.js +7 -7
- package/dist/src/app-resolution.js +1 -1
- package/dist/src/apps.js +5 -5
- package/dist/src/boot-diagnostics.js +1 -1
- package/dist/src/cli-config.js +1 -1
- package/dist/src/cli-help.js +27 -19
- package/dist/src/cli-runner.js +1 -1
- package/dist/src/cli.js +15 -14
- package/dist/src/client-metro.js +1 -1
- package/dist/src/{tv-remote.d.ts → cloud-artifacts.d.ts} +109 -126
- package/dist/src/command-metadata.js +1 -1
- package/dist/src/command-schema.js +1 -1
- package/dist/src/command-surface.js +1 -1
- package/dist/src/context.js +1 -1
- package/dist/src/contracts.d.ts +1 -1
- package/dist/src/debug-symbols.js +4 -4
- package/dist/src/device-input-state.d.ts +2 -2
- package/dist/src/device-input-state.js +1 -1
- package/dist/src/device.js +1 -9
- package/dist/src/devices2.js +1 -1
- package/dist/src/entities.js +1 -0
- package/dist/src/find.js +1 -1
- package/dist/src/finders.d.ts +1 -1
- package/dist/src/finders.js +1 -1
- package/dist/src/generic.js +1 -1
- package/dist/src/helper.js +2 -2
- package/dist/src/ime-lifecycle.js +9 -0
- package/dist/src/index.d.ts +592 -555
- package/dist/src/input-actions.js +4 -4
- package/dist/src/install-artifact.js +4 -4
- package/dist/src/install-artifact2.js +1 -1
- package/dist/src/install-source2.js +1 -1
- package/dist/src/interaction-snapshot.js +1 -1
- package/dist/src/interaction.d.ts +7 -4
- package/dist/src/interaction.js +1 -1
- package/dist/src/interactor.js +2 -2
- package/dist/src/interactor2.js +1 -1
- package/dist/src/internal/bin.js +1 -1
- package/dist/src/internal/daemon.js +14 -14
- package/dist/src/internal/png-worker.js +1 -1
- package/dist/src/lease-context.js +1 -1
- package/dist/src/lease.js +1 -1
- package/dist/src/limrun.d.ts +103 -198
- package/dist/src/limrun.js +1 -1
- package/dist/src/linux.js +1 -1
- package/dist/src/logcat.js +1 -1
- package/dist/src/manifest.js +1 -1
- package/dist/src/metro.d.ts +1 -1
- package/dist/src/parser.js +2 -0
- package/dist/src/path-resolution.js +1 -1
- package/dist/src/physical-device-control.js +1 -1
- package/dist/src/plist-xml.js +1 -0
- package/dist/src/plist.js +1 -1
- package/dist/src/png-worker-contract.js +1 -1
- package/dist/src/process-lock.js +1 -1
- package/dist/src/provider-limrun-runtime.js +1 -0
- package/dist/src/react-native.js +1 -1
- package/dist/src/record-trace.js +1 -1
- package/dist/src/register-builtins.js +1 -1
- package/dist/src/registry.js +22 -22
- package/dist/src/remote-config2.js +1 -1
- package/dist/src/reporting.js +7 -7
- package/dist/src/runner-client.js +1 -1
- package/dist/src/runner-disposal.js +1 -1
- package/dist/src/runner-lease.js +1 -1
- package/dist/src/runner-provider.js +1 -1
- package/dist/src/runner-sequence.js +1 -1
- package/dist/src/runtime-transport.js +1 -1
- package/dist/src/runtime.js +3 -3
- package/dist/src/screenshot-geometry.js +1 -0
- package/dist/src/screenshot-result.js +6 -0
- package/dist/src/sdk-android-adb.d.ts +5 -6
- package/dist/src/sdk-android-adb.js +3 -3
- package/dist/src/sdk-batch-runner.d.ts +2 -2
- package/dist/src/sdk-batch-runner.js +3 -3
- package/dist/src/sdk-contracts.d.ts +21 -25
- package/dist/src/sdk-contracts.js +2 -2
- package/dist/src/sdk-finders.d.ts +1 -1
- package/dist/src/sdk-finders.js +1 -1
- package/dist/src/sdk-io.js +1 -1
- package/dist/src/sdk-remote-config.d.ts +19 -4
- 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/selector-vocabulary.js +1 -1
- package/dist/src/selectors.d.ts +1 -1
- package/dist/src/selectors.js +1 -1
- package/dist/src/server.js +2 -2
- package/dist/src/session-target-evidence.js +1 -1
- package/dist/src/session.js +8 -8
- package/dist/src/setting-state.js +1 -1
- package/dist/src/simulator.js +1 -1
- package/dist/src/snapshot.js +1 -1
- package/dist/src/snapshot2.js +1 -1
- package/dist/src/src.js +1 -0
- package/dist/src/tool-provider.js +3 -3
- package/dist/src/tool-provider2.js +1 -1
- package/dist/src/tool-provider3.js +1 -1
- package/dist/src/update-check.js +1 -1
- package/dist/src/version.js +1 -1
- package/dist/src/viewport-dimension.js +14 -0
- package/package.json +17 -7
- package/server.json +2 -2
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.3.apk.sha256 +0 -1
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.3.apk +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.3.apk.sha256 +0 -1
- package/dist/src/android-input-method-overlays.js +0 -1
- package/dist/src/android-input-ownership.js +0 -1
- package/dist/src/apple-multitouch-support.js +0 -1
- package/dist/src/click-button.d.ts +0 -5
- package/dist/src/compatibility-policy.js +0 -1
- package/dist/src/gesture-plan-types.js +0 -1
- package/dist/src/gesture-plan.js +0 -1
- package/dist/src/launch-console.js +0 -1
- package/dist/src/recording-export-quality.js +0 -14
- package/dist/src/rolldown-runtime.js +0 -1
- package/dist/src/runtime2.js +0 -1
- package/dist/src/sdk-app-inventory.d.ts +0 -4
- package/dist/src/sdk-app-inventory.js +0 -1
- package/dist/src/snapshot-diagnostics.js +0 -6
- package/dist/src/xml.js +0 -2
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{t as e}from"./rolldown-runtime.js";import{S as t,_ as n,a as r,w as i}from"./sdk-contracts.js";import{A as a,C as o,I as s,j as c,v as l,x as u}from"./sdk-android-adb.js";import{C as d,F as f,S as p,T as ee,_ as te,b as ne,m,p as re,v as ie,x as ae,y as h}from"./sdk-batch-runner.js";import{$ as oe,Dn as g,Ft as se,It as ce,On as _,Ut as le,Vt as ue,et as v}from"./recording-export-quality.js";import{E as de,T as fe,_ as pe,_t as y,b as me,bt as he,ct as ge,ft as _e,g as b,h as ve,k as ye,l as be,m as xe,mt as Se,n as Ce,s as we,u as Te,ut as Ee,w as x,x as De,y as Oe,yt as ke}from"./snapshot-diagnostics.js";import{n as S,t as Ae}from"./version.js";import{a as je,d as Me,o as Ne,u as Pe}from"./sdk-device.js";import{h as Fe}from"./gesture-plan-types.js";import{t as C}from"./timeouts.js";import{S as Ie,c as Le,g as Re,h as ze,i as Be,m as Ve}from"./registry.js";import{n as He,t as Ue}from"./client-metro.js";import{t as We}from"./command-metadata.js";import{createHash as Ge,randomUUID as Ke}from"node:crypto";import w from"node:fs";import qe from"node:os";import T from"node:path";import E from"node:http";import D from"node:https";import{pipeline as O}from"node:stream/promises";import{Transform as Je,Writable as Ye}from"node:stream";import k from"node:net";async function Xe(e,t){let n=w.statSync(e),r=T.basename(e),i=n.isDirectory(),a=$e(t)??Qe(e,n),o=[];try{let t=i?await Ze(e,o):e,n=w.statSync(t);return{payloadPath:t,fileName:r,artifactType:i?`app-bundle`:`file`,platform:a,contentType:i?`application/gzip`:`application/octet-stream`,sha256:await tt(t),sizeBytes:n.size,cleanup:()=>et(o)}}catch(e){throw et(o),e}}async function Ze(e,t){let n=w.mkdtempSync(T.join(qe.tmpdir(),`agent-device-upload-${Ke()}-`));t.push(n);let r=T.join(n,`${T.basename(e)}.tar.gz`);return await l(`tar`,[`czf`,r,`-C`,T.dirname(e),T.basename(e)],{env:{...process.env,COPYFILE_DISABLE:`1`}}),r}function Qe(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 $e(e){return e===`ios`||e===`android`?e:void 0}function et(e){for(let t of e)w.rmSync(t,{recursive:!0,force:!0})}async function tt(e){let t=Ge(`sha256`),r=new Ye({write(e,n,r){t.update(e),r()}});return await O(w.createReadStream(e),r).catch(e=>{throw new n(`COMMAND_FAILED`,`Failed to read local artifact`,{},e instanceof Error?e:void 0)}),t.digest(`hex`)}function nt(e){let{stage:t,fileName:n,startOffset:r,totalBytes:i,onProgress:a}=e,o=r,s=at(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 rt(){if(!(process.stderr.isTTY!==!0||process.env.CI))return e=>{process.stderr.write(`${it(e)}\n`)}}function it(e){switch(e.type){case`start`:return`Uploading ${e.fileName} (${A(e.totalBytes)}) via ${ot(e.stage)} upload`;case`resume`:return`Resuming ${e.fileName} at ${A(e.transferredBytes)} of ${A(e.totalBytes)}`;case`progress`:return`Uploaded ${A(e.transferredBytes)} of ${A(e.totalBytes)} (${st(e.transferredBytes,e.totalBytes)})`;case`fallback`:return`Direct upload did not complete; retrying ${e.fileName} with ${ot(e.to)} upload`}}function at(e){return Math.max(8388608,Math.ceil(e*.05))}function ot(e){return e===`direct`?`direct`:`legacy`}function st(e,t){return t<=0?`100%`:`${Math.min(100,Math.floor(e/t*100))}%`}function A(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 ct=300*1e3,lt=`uploadStreamRetryable`;async function ut(e){return await j({...e,url:e.url,redirectCount:0,startOffset:0})}function dt(e){return e instanceof n&&e.details?.[lt]===!0}async function j(e){let t=e.url.protocol===`https:`?D:E,r=w.statSync(e.payloadPath).size,i=mt(e.headers,e.startOffset,r);return pt(e.progress,e.startOffset,r),await new Promise((a,o)=>{let s=!1,c=t.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},t=>{s=!0,Ee(t).then(i=>{clearTimeout(l);let s=t.statusCode??500,c=t.headers.location;if(c&&ht(s)){if(e.redirectCount>=5){o(new n(`COMMAND_FAILED`,`Artifact upload exceeded redirect limit`,{maxRedirects:5,url:e.url.toString()}));return}let t=new URL(c,e.url);j({...e,url:t,redirectCount:e.redirectCount+1}).then(a,o);return}let u=gt(s)?_t(t.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 n(`COMMAND_FAILED`,`Artifact upload resume did not advance`,{offset:u,previousOffset:e.startOffset,url:e.url.toString()}));return}j({...e,startOffset:u}).then(a,o);return}a({statusCode:s,statusMessage:t.statusMessage,body:i})}).catch(o)}),l=setTimeout(()=>{c.destroy(),o(new n(`COMMAND_FAILED`,e.timeoutMessage,{timeoutMs:ct,...e.timeoutHint?{hint:e.timeoutHint}:{},...ft(e)}))},ct);c.on(`error`,t=>{s||(clearTimeout(l),o(new n(`COMMAND_FAILED`,e.errorMessage,{...e.errorHint?{hint:e.errorHint}:{},...ft(e)},t)))}),c.on(`close`,()=>clearTimeout(l)),O(w.createReadStream(e.payloadPath,{start:e.startOffset}),nt({stage:e.progress?.stage??`legacy`,fileName:e.progress?.fileName??T.basename(e.payloadPath),startOffset:e.startOffset,totalBytes:r,onProgress:e.progress?.onProgress}),c).catch(e=>{s||(c.destroy(),o(new n(`COMMAND_FAILED`,`Failed to read local artifact`,{},e instanceof Error?e:Error(String(e)))))})})}function ft(e){return e.retryable===!0?{[lt]:!0}:{}}function pt(e,t,n){e?.onProgress?.({type:t>0?`resume`:`start`,stage:e.stage,fileName:e.fileName,transferredBytes:t,totalBytes:n})}function mt(e,t,n){return t<=0?e:{...e,"content-length":Math.max(n-t,0),"content-range":`bytes ${t}-${n-1}/${n}`}}function ht(e){return[301,302,303,307,308].includes(e)}function gt(e){return e===308}function _t(e,t){let n=vt(e[`x-upload-offset`]??e[`upload-offset`]);if(n!==void 0)return Math.min(n,t);let r=yt(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 vt(e){let t=yt(e);if(t===void 0)return;let n=Number(t);return Number.isSafeInteger(n)&&n>=0?n:void 0}function yt(e){return Array.isArray(e)?e[0]:e}const bt=30*1e3;async function xt(e){let t=await Xe(e.localPath,e.platform),n=e.baseUrl.endsWith(`/`)?e.baseUrl:`${e.baseUrl}/`,r=Ke();try{let i=await Tt({normalizedBase:n,token:e.token,artifact:t,uploadAttemptId:r});return i?.kind===`cache-hit`?i.uploadId:i?.kind===`direct-upload`?await St({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 wt({normalizedBase:n,token:e.token,artifact:t,onProgress:e.onProgress})):await wt({normalizedBase:n,token:e.token,artifact:t,onProgress:e.onProgress})}finally{t.cleanup()}}async function St(e){let t=async t=>(await Ot(e.artifact,t,e.onProgress),await kt({normalizedBase:e.normalizedBase,token:e.token,uploadId:t.uploadId}));try{return await t(e.preflight)}catch(n){if(!Ct(n))return;let r=await Tt({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 Ct(e){return e instanceof n?dt(e):!0}async function wt(e){let{normalizedBase:t,token:r,artifact:i}=e,a=new URL(`upload`,t),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,y(r));let s=await ut({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 n(`COMMAND_FAILED`,`Upload failed: ${s.body}`);return e.uploadId}catch(e){throw e instanceof n?e:new n(`COMMAND_FAILED`,`Invalid upload response: ${s.body}`)}}async function Tt(e){let t=new URL(`upload/preflight`,e.normalizedBase),n={"content-type":`application/json`};Object.assign(n,y(e.token));let r=await fetch(t,{method:`POST`,headers:n,signal:AbortSignal.timeout(bt),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 Et(await r.json().catch(()=>void 0))}function Et(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(Dt(r))return{kind:`direct-upload`,uploadId:t.uploadId,url:n.url,headers:r}}function Dt(e){return!e||typeof e!=`object`||Array.isArray(e)?!1:Object.values(e).every(e=>typeof e==`string`)}async function Ot(e,t,r){let i=await ut({url:new URL(t.url),method:`PUT`,headers:t.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 n(`COMMAND_FAILED`,`Direct artifact upload failed`,{statusCode:i.statusCode,statusMessage:i.statusMessage})}async function kt(e){let t=new URL(`upload/finalize`,e.normalizedBase),r={"content-type":`application/json`};Object.assign(r,y(e.token));let i=await fetch(t,{method:`POST`,headers:r,signal:AbortSignal.timeout(bt),body:JSON.stringify({uploadId:e.uploadId})}).catch(e=>{throw new n(`COMMAND_FAILED`,`Failed to finalize direct artifact upload`,{},e)});if(!i.ok)throw new n(`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 n(`COMMAND_FAILED`,`Invalid upload finalize response`);return a.uploadId}async function At(e,t){let n=[...e.positionals??[]],r=e.flags?{...e.flags}:void 0,i=e.meta?.installSource,a={},o,s=rt();if(!Kt(t))return Ft({positionals:n,flags:r,installSource:i,uploadedArtifactId:o,clientArtifactPaths:a});r=Mt(e,n,r,a);let c=await It(e,t,s);return c&&(i=c.installSource,o=c.uploadedArtifactId??o),e.command!==`install`&&e.command!==`reinstall`||(o=await jt(e,t,n,s)??o),Ft({positionals:n,flags:r,installSource:i,uploadedArtifactId:o,clientArtifactPaths:a})}async function jt(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=Pt(a,e.meta?.cwd);if(o)return await xt({localPath:o,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform,onProgress:r})}function Mt(e,t,n,r){let i=Lt(e,t);if(!i)return n;i.positionalPath!==void 0&&(t[i.positionalIndex]=i.positionalPath);let a=Nt(n,i.flagPath);return r[i.field]=i.localPath,a}function Nt(e,t){return t===void 0?e:{...e??{},out:t}}function Pt(e,t){let n=T.isAbsolute(e)?e:T.resolve(t??process.cwd(),e);return w.existsSync(n)?n:void 0}function Ft(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 It(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=T.isAbsolute(i)?i:T.resolve(e.meta?.cwd??process.cwd(),i);if(!w.existsSync(a))return{installSource:{...r,path:a}};let o=await xt({localPath:a,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform,onProgress:n});return{installSource:{...r,path:a},uploadedArtifactId:o}}function Lt(e,t){if(e.command===`screenshot`){let n=Vt(e,`path`,`.png`);return t[0]?{field:`path`,localPath:n,positionalIndex:0,positionalPath:N(`screenshot`,`.png`)}:{field:`path`,localPath:n,positionalIndex:0,flagPath:N(`screenshot`,`.png`)}}if(e.command===`record`&&(t[0]??``).toLowerCase()===`start`){if(!zt(e)&&e.flags?.platform===void 0)return null;let t=Rt(e),n=Bt(Vt(e,`outPath`,t,1),e);return{field:`outPath`,localPath:n,positionalIndex:1,positionalPath:N(`recording`,T.extname(n)||t)}}return null}function Rt(e){return Se(e.flags?.platform)}function zt(e){return M(e.positionals?.[1])||M(e.flags?.out)}function Bt(e,t){return t.flags?.platform===`web`?_e(e,Rt(t)):e}function Vt(e,t,n,r=0){let i=e.positionals?.[r]??e.flags?.out,a=`${t===`path`?`screenshot`:`recording`}-${Date.now()}${n}`,o=M(i)?i:a;return T.isAbsolute(o)?o:T.resolve(e.meta?.cwd??process.cwd(),o)}function M(e){return typeof e==`string`&&e.trim().length>0}function N(e,t){let n=t.startsWith(`.`)?t:`.${t}`;return T.posix.join(`/tmp`,`agent-device-${e}-${Date.now()}-${Math.random().toString(36).slice(2,8)}${n}`)}async function Ht(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=Ut(n,t);await Wt({baseUrl:e.baseUrl,token:e.token,artifactId:n.artifactId,destinationPath:r,requestScope:t.meta}),i[n.field]=r,a.push({...n,localPath:r})}return i.artifacts=a,{ok:!0,data:i}}function Ut(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 T.resolve(t.meta?.cwd??process.cwd(),r)}async function Wt(e){let t=new URL(Gt(e.baseUrl,e.artifactId)),r=t.protocol===`https:`?D:E;await w.promises.mkdir(T.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){w.promises.rm(e.destinationPath,{force:!0}).finally(()=>a(t));return}i()}},l=r.request({protocol:t.protocol,host:t.hostname,port:t.port,method:`GET`,path:t.pathname+t.search,headers:{...y(e.token),...ke(e.requestScope?.tenantId)}},t=>{if((t.statusCode??500)>=400){let r=``;t.setEncoding(`utf8`),t.on(`data`,e=>{r+=e}),t.on(`end`,()=>{c(new n(`COMMAND_FAILED`,`Failed to download remote artifact`,{artifactId:e.artifactId,statusCode:t.statusCode,requestId:e.requestScope?.requestId,body:r}))});return}t.on(`aborted`,()=>{c(new n(`COMMAND_FAILED`,`Remote artifact download was interrupted`,{artifactId:e.artifactId,requestId:e.requestScope?.requestId}))}),O(t,w.createWriteStream(e.destinationPath)).then(()=>c(),e=>c(e instanceof Error?e:Error(String(e))))}),u=setTimeout(()=>{let t=new n(`COMMAND_FAILED`,`Remote artifact download timed out`,{artifactId:e.artifactId,requestId:e.requestScope?.requestId,timeoutMs:s});c(t),l.destroy(t)},s);l.on(`error`,t=>{if(t instanceof n){c(t);return}c(new n(`COMMAND_FAILED`,`Failed to download remote artifact`,{artifactId:e.artifactId,requestId:e.requestScope?.requestId,timeoutMs:s},t instanceof Error?t:void 0))}),l.end()})}function Gt(e,t){let n=e.endsWith(`/`)?e:`${e}/`;return new URL(`artifacts/${encodeURIComponent(t)}`,n).toString()}function Kt(e){return typeof e.baseUrl==`string`&&e.baseUrl.length>0}const qt=3e3,Jt=1e3;function P(e){let t=rn(e);if(!t||typeof t!=`object`)return null;let n=t,r=Yt(n);if(!r)return null;let i=Xt(n);return i?{token:r,...i,transport:Zt(n.transport),pid:I(n.pid)??0,version:F(n.version),codeSignature:F(n.codeSignature),processStartTime:F(n.processStartTime)}:null}function Yt(e){return typeof e.token==`string`&&e.token.length>0?e.token:null}function Xt(e){let t=I(e.port),n=I(e.httpPort);return t===void 0&&n===void 0?null:{port:t,httpPort:n}}function Zt(e){return e===`socket`||e===`http`||e===`dual`?e:void 0}function F(e){return typeof e==`string`?e:void 0}function I(e){return Number.isInteger(e)&&Number(e)>0?Number(e):void 0}function L(e){let t=rn(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 R(e){an(e)}function z(e){an(e)}function Qt(e){let t=V(e);if(!t.hasLock||t.hasInfo)return;let n=L(e.lockPath);if(!n){z(e.lockPath);return}b(n.pid,n.processStartTime)||z(e.lockPath)}async function B(e,t,n={}){let r=n.stopLiveProcesses??!0,i={reason:t,removedInfo:!1,removedLock:!1,stoppedInfoProcess:!1,stoppedLockProcess:!1};try{let t=w.existsSync(e.infoPath),n=P(e.infoPath);if(n){let t=b(n.pid,n.processStartTime);t&&!r?i.retainedInfoProcess=!0:(t&&(await H(n),i.stoppedInfoProcess=!0),R(e.infoPath),i.removedInfo=!0)}else t&&(R(e.infoPath),i.removedInfo=!0);let a=w.existsSync(e.lockPath),o=L(e.lockPath);if(o){let t=b(o.pid,o.processStartTime);t&&!r?i.retainedLockProcess=!0:(t&&(await pe(o.pid,{termTimeoutMs:qt,killTimeoutMs:Jt,expectedStartTime:o.processStartTime}),i.stoppedLockProcess=!0),z(e.lockPath),i.removedLock=!0)}else a&&(z(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 V(e){return{hasInfo:w.existsSync(e.infoPath),hasLock:w.existsSync(e.lockPath)}}async function $t(e){let t=V(e);if(!t.hasLock||t.hasInfo)return!1;let n=L(e.lockPath);return!n||!b(n.pid,n.processStartTime)?(z(e.lockPath),!0):!1}async function H(e){await pe(e.pid,{termTimeoutMs:qt,killTimeoutMs:Jt,expectedStartTime:e.processStartTime})}function en(e){return typeof e.baseUrl==`string`&&e.baseUrl.length>0}function tn(e,t=x(process.env.AGENT_DEVICE_STATE_DIR)){let n=nn(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 nn(e){return`rm -f ${Oe(e.infoPath)} ${Oe(e.lockPath)}`}function rn(e){if(!w.existsSync(e))return null;try{return JSON.parse(w.readFileSync(e,`utf8`))}catch{return null}}function an(e){try{w.existsSync(e)&&w.unlinkSync(e)}catch{}}function on(e,t){if(t.onProgress){t.onProgress(e);return}e.type===`command`&&(t.req.command===`doctor`&&Ie(),process.stderr.write(`${e.message}\n`))}function U(e,t,r){return new n(`COMMAND_FAILED`,`Invalid daemon response`,{requestId:e.meta?.requestId,line:t},r instanceof Error?r:void 0)}function sn(e){let t=t=>(e.onError(t),!0);return{handleLine(n){let r;try{r=JSON.parse(n)}catch(r){return t(U(e.req,n,r))}if(be(r))try{return on(r.event,{req:e.req,onProgress:e.onProgress}),!1}catch(e){return t(e)}return Te(r)?(e.onResponse(r.response),!0):e.responseFormat===`socket-legacy`?(e.onResponse(r),!0):t(U(e.req,n,Error(`Missing daemon progress response envelope`)))}}}function cn(e,t){return xe(e)&&String(Array.isArray(t)?t.join(`,`):t??``).includes(`application/x-ndjson`)}function ln(e,t){let{req:n,isSettled:r,resolve:i,reject:a,clearTimeout:o}=t,s=``,c=sn({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=ve(s,e);s=t.buffer;for(let e of t.lines)if(c.handleLine(e))return})}function un(e,t){let{req:r,handleResponseBody:i,reject:a,clearTimeout:o}=t,s=``,c=!1,l=sn({req:r,onProgress:t.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=ve(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(U(r,e)))}),e.on(`error`,e=>{c||(c=!0,o(),a(new n(`COMMAND_FAILED`,`Failed to read daemon response`,{requestId:r.meta?.requestId},e instanceof Error?e:void 0)))})}function dn(e,t){let{info:r,req:i,resolve:a,reject:o}=t;try{let t=fn(e);if(t.error){o(pn(t.error,i.meta?.requestId));return}if(!t.result||typeof t.result!=`object`){o(new n(`COMMAND_FAILED`,`Invalid daemon RPC response`,{requestId:i.meta?.requestId}));return}mn(r,i,t.result,a,o)}catch(t){o(new n(`COMMAND_FAILED`,`Invalid daemon response`,{requestId:i.meta?.requestId,line:e},t instanceof Error?t:void 0))}}function fn(e){return JSON.parse(e)}function pn(e,t){let r=e.data??{};return new n(i(r.code==null?void 0:String(r.code),`COMMAND_FAILED`),String(r.message??e.message??`Daemon RPC request failed`),{...typeof r.details==`object`&&r.details?r.details:{},hint:typeof r.hint==`string`?r.hint:void 0,diagnosticId:typeof r.diagnosticId==`string`?r.diagnosticId:void 0,logPath:typeof r.logPath==`string`?r.logPath:void 0,retriable:typeof r.retriable==`boolean`?r.retriable:void 0,supportedOn:typeof r.supportedOn==`string`?r.supportedOn:void 0,requestId:t})}async function mn(e,t,n,r,i){try{r(e.baseUrl&&n.ok?await Ht(e,t,n):n)}catch(e){i(e)}}function hn(e,t){let n=e.meta?.requestId??a();return gn(e.command)?{jsonrpc:`2.0`,id:n,method:_n(e.command),params:vn(e,e.command,t)}:{jsonrpc:`2.0`,id:n,method:`agent_device.command`,params:e}}function gn(e){return e===`lease_allocate`||e===`lease_heartbeat`||e===`lease_release`}function _n(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 vn(e,t,n){return ue(ce(e),t,{includeTokenParam:n.includeTokenParam,token:e.token,session:e.session})}const yn=[`xcodebuild .*AgentDeviceRunnerUITests/RunnerTests/testCommand`,`xcodebuild .*AgentDeviceRunner\\.env\\.session-`,`xcodebuild build-for-testing .*apple/runner/AgentDeviceRunner/AgentDeviceRunner\\.xcodeproj`];function bn(e){let t=f(e.command);if(t.envelopeMs===`unbounded`)return;let n={...t,envelopeMs:t.envelopeMs};return xn(n,e.positionals??[])??Sn(n,e.flags)??n.envelopeMs}function xn(e,t){if(e.budget.source!==`positional-parser`)return;let n=e.budget.parser(t);return n===null?void 0:wn(e,n)}function Sn(e,t){if(e.budget.source===`flag`)return e.budget.envelope===`widen`?Cn(e,e.budget,t):typeof t?.timeoutMs==`number`?t.timeoutMs:e.envelopeMs}function Cn(e,t,n){if(n?.settle!==!0)return e.envelopeMs;let r=typeof n.timeoutMs==`number`?n.timeoutMs:t.defaultBudgetMs;return typeof r==`number`?Tn(e,r):e.envelopeMs}function wn(e,t){return Math.max(e.envelopeMs,t+jn)}function Tn(e,t){return Math.max(e.envelopeMs,e.envelopeMs+t+jn)}function En(e,t,r,i,a,o){let s=a?{terminated:0}:kn(),l=!a&&Dn(i),u=l?An(e,t):{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 n(`COMMAND_FAILED`,`Daemon request timed out`,{timeoutMs:o,requestId:r,hint:On({remote:a,resetDaemon:l,command:i})})}function Dn(e){return f(e).onTimeout===`reset-daemon`}function On(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===_.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 kn(){let e=0;try{for(let t of yn)o(`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 An(e,t){let n=!1;try{b(e.pid,e.processStartTime)&&(process.kill(e.pid,`SIGKILL`),n=!0)}catch{H(e)}finally{R(t.infoPath),z(t.lockPath)}return{forcedKill:n}}const jn=3e4,Mn=`Daemon HTTP endpoint is unavailable`,Nn=`Daemon socket endpoint is unavailable`;async function W(e,t){let n=Hn(e,t);if(await Pn(e,n))return!0;let r=Un(e,t,n);return r?await Pn(e,r):!1}async function Pn(e,t){return t===`http`?await In(e):await Fn(e.port)}function Fn(e){return e?new Promise(t=>{let n=!1,r=k.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 In(e){return Rn(e).then(e=>e.reachable)}async function Ln(e){let t=await Rn(e);if(!e.baseUrl||!t.reachable)return t;if(typeof t.rpcProtocolVersion==`number`&&t.rpcProtocolVersion!==2)throw new n(`COMMAND_FAILED`,`Remote daemon RPC protocol is incompatible`,{daemonBaseUrl:e.baseUrl,clientVersion:S(),remoteVersion:t.version,remoteService:t.service,supportedRpcProtocolVersion:2,remoteRpcProtocolVersion:t.rpcProtocolVersion,hint:`Upgrade agent-device on the client or remote host so both support the same daemon RPC protocol.`});return t}function Rn(e){let t=e.baseUrl?he(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:`?D:E,i=e.baseUrl?3e3:500;return new Promise(t=>{let a=e.baseUrl?y(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,...zn(n)})})});o.on(`timeout`,()=>{o.destroy(),t({reachable:!1})}),o.on(`error`,()=>{t({reachable:!1})}),o.end()})}function zn(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 Bn(e,t,n,r,i,a={}){let o=Hn(e,n);try{return await Vn(e,t,r,i,o,a)}catch(s){let c=Un(e,n,o);if(!c||!Wn(s,o))throw s;return await Vn(e,t,r,i,c,a)}}async function Vn(e,t,n,r,i,a){return i===`http`?await Jn(e,t,n,r,a):await qn(e,t,n,r,a)}function Hn(e,t){if(e.baseUrl){if(t===`socket`)throw new n(`COMMAND_FAILED`,`Remote daemon endpoint only supports HTTP transport`,{daemonBaseUrl:e.baseUrl});return`http`}if(t===`http`||t===`socket`)return Gn(e,t);let r=(e.transport===`socket`||e.transport===`dual`?[`socket`,`http`]:[`http`,`socket`]).find(t=>G(e,t));if(r)return r;throw new n(`COMMAND_FAILED`,`Daemon metadata has no reachable transport`)}function G(e,t){return t===`http`?!!e.httpPort:!!e.port}function Un(e,t,n){if(t!==`auto`||e.baseUrl)return null;let r=n===`socket`?`http`:`socket`;return G(e,r)?r:null}function Wn(e,t){return t===`socket`&&e instanceof n&&e.code===`COMMAND_FAILED`&&e.message===`Failed to communicate with daemon`&&e.details?.daemonSocketRequestWritten===!1}function Gn(e,t){if(G(e,t))return t;throw new n(`COMMAND_FAILED`,t===`http`?Mn:Nn)}function Kn(e,t,r,i={}){return c({level:`error`,phase:`daemon_request_socket_error`,data:{requestId:t,message:e instanceof Error?e.message:String(e)}}),new n(`COMMAND_FAILED`,`Failed to communicate with daemon`,{...i,requestId:t,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 qn(e,t,r,i,a){let o=e.port;if(!o)throw new n(`COMMAND_FAILED`,Nn);return new Promise((n,s)=>{let c=!1,l=k.createConnection({host:`127.0.0.1`,port:o},()=>{c=!0,l.write(`${JSON.stringify(t)}\n`)}),u=!1,d=typeof i==`number`?setTimeout(()=>{u=!0,l.destroy(),s(En(e,r,t.meta?.requestId,t.command,!1,i))},i):void 0;ln(l,{req:t,onProgress:a.onProgress,isSettled:()=>u,clearTimeout:()=>{d&&clearTimeout(d)},resolve:e=>{u=!0,n(e)},reject:e=>{u=!0,s(e)}}),l.on(`error`,e=>{u||(u=!0,d&&clearTimeout(d),s(Kn(e,t.meta?.requestId,!1,{daemonSocketRequestWritten:c})))})})}async function Jn(e,t,r,i,a){let o=e.baseUrl?new URL(he(e.baseUrl,`rpc`)):e.httpPort?new URL(`http://127.0.0.1:${e.httpPort}/rpc`):null;if(!o)throw new n(`COMMAND_FAILED`,Mn);let s=JSON.stringify(hn(t,{includeTokenParam:!e.baseUrl})),c={"content-type":`application/json`,"content-length":Buffer.byteLength(s)};return e.baseUrl&&Object.assign(c,y(e.token)),await new Promise((l,u)=>{let d=(o.protocol===`https:`?D:E).request({protocol:o.protocol,host:o.hostname,port:o.port,method:`POST`,path:o.pathname+o.search,headers:c},r=>{if(cn(t,r.headers?.[`content-type`])){un(r,{req:t,onProgress:a.onProgress,reject:u,clearTimeout:()=>{p&&clearTimeout(p)},handleResponseBody:n=>dn(n,{info:e,req:t,resolve:l,reject:u})});return}Ee(r).then(n=>{p&&clearTimeout(p),dn(n,{info:e,req:t,resolve:l,reject:u})}).catch(e=>{p&&clearTimeout(p),u(new n(`COMMAND_FAILED`,`Failed to read daemon response`,{requestId:t.meta?.requestId},e instanceof Error?e:void 0))})}),f=en(e),p=typeof i==`number`?setTimeout(()=>{d.destroy(),u(En(e,r,t.meta?.requestId,t.command,f,i))},i):void 0;d.on(`error`,e=>{p&&clearTimeout(p),u(Kn(e,t.meta?.requestId,f))}),d.write(s),d.end()})}const K=15e3,q=new k.BlockList;q.addSubnet(`127.0.0.0`,8,`ipv4`),q.addAddress(`::1`,`ipv6`),q.addSubnet(`::ffff:127.0.0.0`,104,`ipv6`);function Yn(e){let t=Xn(e),n=Zn(e),r=Qn(e,n.remoteBaseUrl),i=$n(e,t,n.rawBaseUrl);return{paths:x(i?er():t),transportPreference:r.preference,serverMode:r.serverMode,ownedStateDir:i,remoteBaseUrl:n.remoteBaseUrl,remoteAuthToken:n.authToken}}function Xn(e){return e.flags?.stateDir??process.env.AGENT_DEVICE_STATE_DIR}function Zn(e){let t=e.flags?.daemonBaseUrl??process.env.AGENT_DEVICE_DAEMON_BASE_URL,n=Cr(t),r=e.flags?.daemonAuthToken??process.env.AGENT_DEVICE_DAEMON_AUTH_TOKEN;return wr(n,r),{rawBaseUrl:t,remoteBaseUrl:n,authToken:r}}function Qn(e,t){let r=e.flags?.daemonTransport??process.env.AGENT_DEVICE_DAEMON_TRANSPORT,i=de(r);if(t&&i===`socket`)throw new n(`INVALID_ARGS`,`Remote daemon base URL only supports HTTP transport. Remove --daemon-transport socket.`,{daemonBaseUrl:t});return{preference:i,serverMode:fe(e.flags?.daemonServerMode??process.env.AGENT_DEVICE_DAEMON_SERVER_MODE??(r===`dual`?`dual`:void 0))}}function $n(e,t,n){return mr(e.command)&&!t&&!n}function er(){return w.mkdtempSync(T.join(qe.tmpdir(),`agent-device-replay-daemon-`))}async function tr(e){if(e.remoteBaseUrl)return await nr(e);let t=await rr(e);return t?{info:t,startedByClient:!1}:(Qt(e.paths),await lr(e))}async function nr(e){let t={transport:`http`,token:e.remoteAuthToken??``,pid:0,baseUrl:e.remoteBaseUrl};if((await Ln(t)).reachable)return{info:t,startedByClient:!1};throw new n(`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 rr(e){let t=P(e.paths.infoPath);if(!t)return null;let n=await ir(t,e.transportPreference);return or(t,n)?t:(sr(t,n,e.paths.baseDir),await H(t),R(e.paths.infoPath),null)}async function ir(e,t){try{return await W(e,t)}catch(e){if(ar(e))return!1;throw e}}function ar(e){return e instanceof n&&e.code===`COMMAND_FAILED`&&(e.message===`Daemon HTTP endpoint is unavailable`||e.message===`Daemon socket endpoint is unavailable`)}function or(e,t){return e.version===S()&&e.codeSignature===br()&&t}function sr(e,t,n){try{let r=e.version?`pid ${e.pid}, v${e.version}`:`pid ${e.pid}`,i=cr(e,t);process.stderr.write(`Replacing daemon (${r}) in ${n}: ${i}\n`)}catch{}}function cr(e,t){return e.version===S()?e.codeSignature===br()?t?`not reusable`:`unreachable`:`code-signature mismatch`:`version mismatch (client v${S()})`}async function lr(e){let t=0,r=[],i,a;for(let n=1;n<=2;n+=1){let o;try{o=vr(e),a={pid:o.pid}}catch(t){if(i=t instanceof Error?t.message:String(t),r.push(await B(e.paths,`start_error`)),n<2){await C(150);continue}break}let s=await _r(K,e,o);if(s.kind===`ready`)return{info:s.info,startedByClient:!0};if(s.kind===`early_exit`){if(a=s.exit,i=xr(s.exit),r.push(await B(e.paths,`start_error`)),n<2){await C(150);continue}break}if(await $t(e.paths)){t+=1;continue}let c=V(e.paths),l=n<2,u=await B(e.paths,`startup_timeout`,{stopLiveProcesses:!1});if(r.push(u),u.retainedInfoProcess||u.retainedLockProcess){let t=await _r(K,e,o);if(t.kind===`ready`)return{info:t.info,startedByClient:!0};t.kind===`early_exit`&&(a=t.exit,i=xr(t.exit));break}if(!l)break;!c.hasInfo&&!c.hasLock&&await C(150)}let o=V(e.paths),s=Sr(e.paths.logPath);throw new n(`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:K,startupAttempts:2,lockRecoveryCount:t,cleanupResults:r,startError:i,daemonProcess:a,...s?{daemonLogTail:s}:{},metadataState:o,hint:tn(o,e.paths)})}async function ur(e,t,n,r){if(!mr(e.command)||!t.startedByClient&&!n.ownedStateDir||en(t.info)||fr(r)||hr(e,r))return r;let i={pid:t.info.pid,removedInfo:!1,removedLock:!1,removedStateDir:!1,error:void 0},a=r;try{await H(t.info)}catch(e){i.error=e instanceof Error?e.message:String(e)}finally{let e=w.existsSync(n.paths.infoPath);R(n.paths.infoPath),i.removedInfo=e&&!w.existsSync(n.paths.infoPath);let t=w.existsSync(n.paths.lockPath);if(z(n.paths.lockPath),i.removedLock=t&&!w.existsSync(n.paths.lockPath),n.ownedStateDir){let e=ye(n.paths.sessionsDir);e?a=dr(r,e):(w.rmSync(n.paths.baseDir,{recursive:!0,force:!0}),i.removedStateDir=!w.existsSync(n.paths.baseDir))}}return c({level:i.error?`warn`:`info`,phase:`daemon_replay_cleanup`,data:i}),a}function dr(e,r){if(e&&!e.ok)return e;let{sessionName:i,tombstone:a}=r,o=a.sourcePath?`re-run: replay ${a.sourcePath} --save-script`:`re-run your replay <script> --save-script from the start`;return{ok:!1,error:t(new n(`REPAIR_COMMIT_FAILED`,`The repair transaction for session "${i}" completed, but committing its healed script failed at teardown: ${a.commitFailure.message}. ${o}.`))}}function fr(e){if(!e||e.ok||e.error.code!==`REPLAY_DIVERGENCE`)return!1;let t=e.error.details?.divergence;if(!t||typeof t!=`object`)return!1;let n=t.resume;return!n||typeof n!=`object`?!1:n.repairSessionHeld===!0}function pr(e,t){let n=`This repair session's daemon was kept alive to continue the repair; pass --state-dir ${t} on your next command (press, replay --from, or close --save-script) to reach it.`,r=e.error.hint;return{...e,error:{...e.error,hint:r?`${r} ${n}`:n}}}function mr(e){return e===_.replay||e===_.test}function hr(e,t){return e.command!==_.replay||!t||!t.ok?!1:t.data?.sessionActive===!0}function gr(e,t){let n=e.data??{},r=typeof n.session==`string`?n.session:void 0,i=[...t?[`--state-dir ${me(t)}`]:[],...r?[`--session ${me(r)}`]:[]];if(i.length===0)return e;let a=`This session's daemon was kept alive because its script left the session active; pass ${i.join(` `)} on your next command to reach it.`,o=typeof n.message==`string`?n.message:void 0;return{...e,data:{...n,hint:a,message:o?`${o} ${a}`:a}}}async function _r(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=P(t.paths.infoPath);if(e&&await W(e,t.transportPreference))return{kind:`ready`,info:e};if(i)return{kind:`early_exit`,exit:i};await C(100)}return{kind:`timeout`}}function vr(e){let t=yr(),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};w.mkdirSync(e.paths.baseDir,{recursive:!0});let i=w.openSync(e.paths.logPath,`a`),a=w.openSync(e.paths.logPath,`a`);try{return u(process.execPath,n,{env:r,stdio:[`ignore`,i,a]})}finally{w.closeSync(i),w.closeSync(a)}}function yr(){let e=Ae(),t=[T.join(e,`dist`,`src`,`internal`,`daemon.js`),T.join(e,`dist`,`src`,`daemon.js`)],r=t[0];if(r===void 0)throw new n(`COMMAND_FAILED`,`Daemon dist path list is empty`);let i=t.find(e=>w.existsSync(e))??r,a=T.join(e,`src`,`daemon.ts`),o=t.some(e=>w.existsSync(e)),s=w.existsSync(a);if(!o&&!s)throw new n(`COMMAND_FAILED`,`Daemon entry not found`,{distPaths:t,srcPath:a});return{root:e,distPath:i,distPaths:t,srcPath:a,useSrc:(process.execArgv.includes(`--experimental-strip-types`)||!o)&&s}}function br(){let e=yr();return De(e.useSrc?e.srcPath:e.distPath,e.root)}function xr(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 Sr(e){try{if(!w.existsSync(e))return;let t=w.statSync(e);if(t.size<=0)return;let n=Math.min(t.size,64e3),r=w.openSync(e,`r`);try{let e=Buffer.alloc(n);w.readSync(r,e,0,n,t.size-n);let i=e.toString(`utf8`).trim();return i.length>0?i:void 0}finally{w.closeSync(r)}}catch{return}}function Cr(e){if(!e)return;let t;try{t=new URL(e)}catch(t){throw new n(`INVALID_ARGS`,`Invalid daemon base URL`,{daemonBaseUrl:e},t instanceof Error?t:void 0)}if(t.protocol!==`http:`&&t.protocol!==`https:`)throw new n(`INVALID_ARGS`,`Daemon base URL must use http or https`,{daemonBaseUrl:e});return t.toString().replace(/\/+$/,``)}function wr(e,t){if(!e)return;let r=new URL(e).hostname;if(!Tr(r)&&!(typeof t==`string`&&t.trim().length>0))throw new n(`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 Tr(e){let t=e.trim().toLowerCase().replace(/^\[(.*)\]$/,`$1`);return t===`localhost`?!0:k.isIPv4(t)?q.check(t,`ipv4`):k.isIPv6(t)?q.check(t,`ipv6`):!1}async function Er(e,t={}){let n=e.meta?.requestId??a(),r=!!(e.meta?.debug||e.flags?.verbose),i=Yn(e),o=bn(e),l=await s(`daemon_startup`,async()=>await tr(i),{requestId:n,session:e.session}),u=l.info,d=await At(e,u);Ar(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}:{}}};return c({level:`info`,phase:`daemon_request_prepare`,data:{requestId:n,command:e.command,session:e.session}}),await Dr(e,l,i,async()=>kr(Or(await s(`daemon_request`,async()=>await Bn(u,f,i.transportPreference,i.paths,o,t),{requestId:n,command:e.command}),i),e,i))}async function Dr(e,t,r,i){let a,o=!1,s;try{a=await i()}catch(e){o=!0,s=e}let c=await ur(e,t,r,a);if(o)throw s;if(!c)throw new n(`COMMAND_FAILED`,`Daemon request produced no response after cleanup`);return c}function Or(e,t){return e.ok||!t.ownedStateDir||!fr(e)?e:pr(e,t.paths.baseDir)}function kr(e,t,n){return!e.ok||!hr(t,e)?e:gr(e,n.ownedStateDir?n.paths.baseDir:void 0)}function Ar(e){!jr(e)||process.stderr.isTTY!==!0||process.env.CI||process.stderr.write(e===_.reinstall?`Reinstalling...
|
|
1
|
+
import{o as e}from"./png-worker-contract.js";import{S as t,T as n,_ as r,a as i,w as a}from"./sdk-contracts.js";import{Gt as o,Ht as s,Kt as c,Vt as l,cn as u,gn as d,ln as f,mn as p}from"./viewport-dimension.js";import{et as ee}from"./screenshot-geometry.js";import{$ as te,K as ne,Q as m,T as re,X as ie,Z as ae,et as oe,it as se,nt as h,q as g,tt as ce}from"./sdk-batch-runner.js";import{_t as le,a as ue,b as de,bt as fe,ct as pe,d as _,f as me,ft as he,g as ge,h as _e,ht as v,i as ve,l as ye,m as be,n as xe,rt as Se,u as Ce,ut as we,vt as Te,w as Ee,x as De,y}from"./screenshot-result.js";import{a as Oe,d as ke,o as Ae,u as je}from"./sdk-device.js";import{b as Me,c as Ne,d as Pe,h as Fe,i as Ie,y as Le}from"./registry.js";import{t as Re}from"./command-metadata.js";import{A as ze,C as Be,I as Ve,j as b,v as He,x as Ue}from"./sdk-android-adb.js";import{n as x,t as We}from"./version.js";import{t as S}from"./timeouts.js";import{n as Ge,t as Ke}from"./client-metro.js";import C from"node:path";import{createHash as qe,randomUUID as Je}from"node:crypto";import w from"node:fs";import Ye from"node:os";import T from"node:http";import E from"node:https";import{pipeline as D}from"node:stream/promises";import{Transform as Xe,Writable as Ze}from"node:stream";import O from"node:net";function Qe(e,t){let n=m(e,`bundleId`),r=m(e,`package`);return{app:h(e,`app`),appPath:h(e,`appPath`),platform:ce(e,`platform`),appId:n??r,bundleId:n,package:r,identifiers:o({session:t,bundleId:n,packageName:r})}}function $e(e,t){let n=m(e,`bundleId`),i=m(e,`packageName`),a=n??i??m(e,`appId`),s=m(e,`launchTarget`)??i??n??a;if(!s)throw new r(`COMMAND_FAILED`,`Daemon response is missing "launchTarget".`,{response:e});return{appName:m(e,`appName`),appId:a,bundleId:n,packageName:i,launchTarget:s,installablePath:m(e,`installablePath`),archivePath:m(e,`archivePath`),materializationId:m(e,`materializationId`),materializationExpiresAt:m(e,`materializationExpiresAt`),identifiers:o({session:t,bundleId:n,packageName:i,appId:a})}}function et(e){return{released:e.released===!0,materializationId:h(e,`materializationId`),identifiers:{}}}function tt(e){let{record:t,platform:n,id:r,name:i,target:a}=it(e,`name`),o=rt(t);return{platform:n,target:a,kind:te(t,`kind`),id:r,name:i,booted:typeof t.booted==`boolean`?t.booted:void 0,...Ae(n)&&o?{appleOs:o}:{},identifiers:c(n,r,i),...k(n,r)}}function nt(e){let{record:t,platform:n,id:r,name:i,target:a}=it(e,`name`),o=h(t,`device`),s=rt(t),l={session:i,...c(n,r,o)};return{name:i,createdAt:oe(t,`createdAt`),sessionStateDir:m(t,`sessionStateDir`),runnerLogPath:m(t,`runnerLogPath`),device:{platform:n,target:a,id:r,name:o,...s?{appleOs:s}:{},identifiers:l,...k(n,r,{simulatorSetPath:ae(t,`ios_simulator_device_set`)})},identifiers:l}}function rt(e){let t=e.appleOs;return Oe(t)?t:void 0}function it(e,t){let n=ne(e);return{record:n,platform:ce(n,`platform`),id:h(n,`id`),name:h(n,t),target:ie(n,`target`)}}function k(e,t,n={}){if(e===`ios`)return{ios:{udid:t,...n.simulatorSetPath===void 0?{}:{simulatorSetPath:n.simulatorSetPath}}};if(!ke(e))return{};let r=n.serial??t;return e===`android`?{android:{serial:r}}:{vega:{serial:r}}}function at(e){if(!g(e))return;let t=e.platform,n=m(e,`metroHost`),r=typeof e.metroPort==`number`?e.metroPort:void 0,i=m(e,`bundleUrl`),a=m(e,`launchUrl`);return{platform:t===`ios`||t===`android`?t:void 0,metroHost:n,metroPort:r,bundleUrl:i,launchUrl:a}}function ot(e){let t=e.platform,n=m(e,`id`),r=m(e,`device`);if(!je(t)||!n||!r)return;let i=ie(e,`target`),a=ke(t)?m(e,`serial`)??n:void 0;return{platform:t,target:i,id:n,name:r,identifiers:{...c(t,n,r),...a?{serial:a}:{}},...k(t,t===`ios`?m(e,`device_udid`)??n:n,{simulatorSetPath:ae(e,`ios_simulator_device_set`),serial:a})}}function st(e){if(g(e)&&!(typeof e.durationMs!=`number`||typeof e.measuredAt!=`string`||typeof e.method!=`string`))return{durationMs:e.durationMs,measuredAt:e.measuredAt,method:e.method,appTarget:m(e,`appTarget`),appBundleId:m(e,`appBundleId`)}}function ct(e){if(!g(e)||typeof e.success!=`boolean`||typeof e.exitCode!=`number`||typeof e.stdout!=`string`||typeof e.stderr!=`string`)return;let t=lt(e.error);return{success:e.success,exitCode:e.exitCode,stdout:e.stdout,stderr:e.stderr,...t?{error:t}:{}}}function lt(e){if(g(e)&&!(typeof e.code!=`string`||typeof e.message!=`string`))return{code:e.code,message:e.message,...typeof e.hint==`string`?{hint:e.hint}:{},...typeof e.diagnosticId==`string`?{diagnosticId:e.diagnosticId}:{},...typeof e.logPath==`string`?{logPath:e.logPath}:{},...g(e.details)?{details:e.details}:{}}}function ut(e){return Array.isArray(e)?e:[]}function dt(e){let t=u(e);return se({requestId:e.requestId,cwd:e.cwd,sessionExplicit:e.session!==void 0,debug:e.debug,includeCost:e.cost,responseLevel:e.responseLevel,lockPolicy:e.lockPolicy,lockPlatform:e.lockPlatform,...d(t),sessionIsolation:e.sessionIsolation,installSource:e.installSource,retainMaterializedPaths:e.retainMaterializedPaths,materializedPathRetentionMs:e.materializedPathRetentionMs,materializationId:e.materializationId})}function A(e){return e??`default`}const ft={...Ie(),batch:Fe(pt)};function pt(e,t,n){let i=ft[e];if(!i)throw Error(`Missing daemon writer for batch command: ${e}`);let a=Re(e);if(!a)throw Error(`Missing command metadata for batch command: ${e}`);try{return ht(i,a,a.readInput(t))}catch(t){throw new r(`INVALID_ARGS`,`Batch step ${n} ${e} input is invalid: ${t instanceof Error?t.message:String(t)}`,void 0,t)}}function mt(e,t){let n=ft[e];if(!n)throw Error(`Missing daemon writer for command: ${e}`);return ht(n,Re(e),t)}function ht(e,t,n){let r=e(n);return{...r,...t?{metadataFlags:Me(t,r.options)}:{}}}async function gt(e,t){let n=w.statSync(e),r=C.basename(e),i=n.isDirectory(),a=yt(t)??vt(e,n),o=[];try{let t=i?await _t(e,o):e,n=w.statSync(t);return{payloadPath:t,fileName:r,artifactType:i?`app-bundle`:`file`,platform:a,contentType:i?`application/gzip`:`application/octet-stream`,sha256:await xt(t),sizeBytes:n.size,cleanup:()=>bt(o)}}catch(e){throw bt(o),e}}async function _t(e,t){let n=w.mkdtempSync(C.join(Ye.tmpdir(),`agent-device-upload-${Je()}-`));t.push(n);let r=C.join(n,`${C.basename(e)}.tar.gz`);return await He(`tar`,[`czf`,r,`-C`,C.dirname(e),C.basename(e)],{env:{...process.env,COPYFILE_DISABLE:`1`}}),r}function vt(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 yt(e){return e===`ios`||e===`android`?e:void 0}function bt(e){for(let t of e)w.rmSync(t,{recursive:!0,force:!0})}async function xt(e){let t=qe(`sha256`),n=new Ze({write(e,n,r){t.update(e),r()}});return await D(w.createReadStream(e),n).catch(e=>{throw new r(`COMMAND_FAILED`,`Failed to read local artifact`,{},e instanceof Error?e:void 0)}),t.digest(`hex`)}function St(e){let{stage:t,fileName:n,startOffset:r,totalBytes:i,onProgress:a}=e,o=r,s=Tt(i),c=Math.min(i,r+s);return new Xe({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 Ct(){if(!(process.stderr.isTTY!==!0||process.env.CI))return e=>{process.stderr.write(`${wt(e)}\n`)}}function wt(e){switch(e.type){case`start`:return`Uploading ${e.fileName} (${M(e.totalBytes)}) via ${j(e.stage)} upload`;case`resume`:return`Resuming ${e.fileName} at ${M(e.transferredBytes)} of ${M(e.totalBytes)}`;case`progress`:return`Uploaded ${M(e.transferredBytes)} of ${M(e.totalBytes)} (${Et(e.transferredBytes,e.totalBytes)})`;case`fallback`:return`Direct upload did not complete; retrying ${e.fileName} with ${j(e.to)} upload`}}function Tt(e){return Math.max(8388608,Math.ceil(e*.05))}function j(e){return e===`direct`?`direct`:`legacy`}function Et(e,t){return t<=0?`100%`:`${Math.min(100,Math.floor(e/t*100))}%`}function M(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 Dt=300*1e3,Ot=`uploadStreamRetryable`;async function kt(e){return await N({...e,url:e.url,redirectCount:0,startOffset:0})}function At(e){return e instanceof r&&e.details?.[Ot]===!0}async function N(e){let t=e.url.protocol===`https:`?E:T,n=w.statSync(e.payloadPath).size,i=Nt(e.headers,e.startOffset,n);return Mt(e.progress,e.startOffset,n),await new Promise((a,o)=>{let s=!1,c=t.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},t=>{s=!0,pe(t).then(i=>{clearTimeout(l);let s=t.statusCode??500,c=t.headers.location;if(c&&Pt(s)){if(e.redirectCount>=5){o(new r(`COMMAND_FAILED`,`Artifact upload exceeded redirect limit`,{maxRedirects:5,url:e.url.toString()}));return}let t=new URL(c,e.url);N({...e,url:t,redirectCount:e.redirectCount+1}).then(a,o);return}let u=Ft(s)?It(t.headers,n):void 0;if(u!==void 0){if(u>=n){a({statusCode:200,statusMessage:`Upload already complete`,body:``});return}if(u<=e.startOffset){o(new r(`COMMAND_FAILED`,`Artifact upload resume did not advance`,{offset:u,previousOffset:e.startOffset,url:e.url.toString()}));return}N({...e,startOffset:u}).then(a,o);return}a({statusCode:s,statusMessage:t.statusMessage,body:i})}).catch(o)}),l=setTimeout(()=>{c.destroy(),o(new r(`COMMAND_FAILED`,e.timeoutMessage,{timeoutMs:Dt,...e.timeoutHint?{hint:e.timeoutHint}:{},...jt(e)}))},Dt);c.on(`error`,t=>{s||(clearTimeout(l),o(new r(`COMMAND_FAILED`,e.errorMessage,{...e.errorHint?{hint:e.errorHint}:{},...jt(e)},t)))}),c.on(`close`,()=>clearTimeout(l)),D(w.createReadStream(e.payloadPath,{start:e.startOffset}),St({stage:e.progress?.stage??`legacy`,fileName:e.progress?.fileName??C.basename(e.payloadPath),startOffset:e.startOffset,totalBytes:n,onProgress:e.progress?.onProgress}),c).catch(e=>{s||(c.destroy(),o(new r(`COMMAND_FAILED`,`Failed to read local artifact`,{},e instanceof Error?e:Error(String(e)))))})})}function jt(e){return e.retryable===!0?{[Ot]:!0}:{}}function Mt(e,t,n){e?.onProgress?.({type:t>0?`resume`:`start`,stage:e.stage,fileName:e.fileName,transferredBytes:t,totalBytes:n})}function Nt(e,t,n){return t<=0?e:{...e,"content-length":Math.max(n-t,0),"content-range":`bytes ${t}-${n-1}/${n}`}}function Pt(e){return[301,302,303,307,308].includes(e)}function Ft(e){return e===308}function It(e,t){let n=Lt(e[`x-upload-offset`]??e[`upload-offset`]);if(n!==void 0)return Math.min(n,t);let r=Rt(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 Lt(e){let t=Rt(e);if(t===void 0)return;let n=Number(t);return Number.isSafeInteger(n)&&n>=0?n:void 0}function Rt(e){return Array.isArray(e)?e[0]:e}const zt=30*1e3;async function Bt(e){let t=await gt(e.localPath,e.platform),n=e.baseUrl.endsWith(`/`)?e.baseUrl:`${e.baseUrl}/`,r=Je();try{let i=await Wt({normalizedBase:n,token:e.token,artifact:t,uploadAttemptId:r});return i?.kind===`cache-hit`?i.uploadId:i?.kind===`direct-upload`?await Vt({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 Ut({normalizedBase:n,token:e.token,artifact:t,onProgress:e.onProgress})):await Ut({normalizedBase:n,token:e.token,artifact:t,onProgress:e.onProgress})}finally{t.cleanup()}}async function Vt(e){let t=async t=>(await qt(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(!Ht(n))return;let r=await Wt({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 Ht(e){return e instanceof r?At(e):!0}async function Ut(e){let{normalizedBase:t,token:n,artifact:i}=e,a=new URL(`upload`,t),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,v(n));let s=await kt({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 r(`COMMAND_FAILED`,`Upload failed: ${s.body}`);return e.uploadId}catch(e){throw e instanceof r?e:new r(`COMMAND_FAILED`,`Invalid upload response: ${s.body}`)}}async function Wt(e){let t=new URL(`upload/preflight`,e.normalizedBase),n={"content-type":`application/json`};Object.assign(n,v(e.token));let r=await fetch(t,{method:`POST`,headers:n,signal:AbortSignal.timeout(zt),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 Gt(await r.json().catch(()=>void 0))}function Gt(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 qt(e,t,n){let i=await kt({url:new URL(t.url),method:`PUT`,headers:t.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:n}});if(i.statusCode<200||i.statusCode>=300)throw new r(`COMMAND_FAILED`,`Direct artifact upload failed`,{statusCode:i.statusCode,statusMessage:i.statusMessage})}async function Jt(e){let t=new URL(`upload/finalize`,e.normalizedBase),n={"content-type":`application/json`};Object.assign(n,v(e.token));let i=await fetch(t,{method:`POST`,headers:n,signal:AbortSignal.timeout(zt),body:JSON.stringify({uploadId:e.uploadId})}).catch(e=>{throw new r(`COMMAND_FAILED`,`Failed to finalize direct artifact upload`,{},e)});if(!i.ok)throw new r(`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 r(`COMMAND_FAILED`,`Invalid upload finalize response`);return a.uploadId}async function Yt(e,t){let n=[...e.positionals??[]],r=e.flags?{...e.flags}:void 0,i=e.meta?.installSource,a={},o,s=Ct();if(!fn(t))return en({positionals:n,flags:r,installSource:i,uploadedArtifactId:o,clientArtifactPaths:a});r=Zt(e,n,r,a);let c=await tn(e,t,s);return c&&(i=c.installSource,o=c.uploadedArtifactId??o),e.command!==`install`&&e.command!==`reinstall`||(o=await Xt(e,t,n,s)??o),en({positionals:n,flags:r,installSource:i,uploadedArtifactId:o,clientArtifactPaths:a})}async function Xt(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=$t(a,e.meta?.cwd);if(o)return await Bt({localPath:o,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform,onProgress:r})}function Zt(e,t,n,r){let i=nn(e,t);if(!i)return n;i.positionalPath!==void 0&&(t[i.positionalIndex]=i.positionalPath);let a=Qt(n,i.flagPath);return r[i.field]=i.localPath,a}function Qt(e,t){return t===void 0?e:{...e??{},out:t}}function $t(e,t){let n=C.isAbsolute(e)?e:C.resolve(t??process.cwd(),e);return w.existsSync(n)?n:void 0}function en(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 tn(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(!w.existsSync(a))return{installSource:{...r,path:a}};let o=await Bt({localPath:a,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform,onProgress:n});return{installSource:{...r,path:a},uploadedArtifactId:o}}function nn(e,t){if(e.command===`screenshot`){let n=sn(e,`path`,`.png`);return t[0]?{field:`path`,localPath:n,positionalIndex:0,positionalPath:F(`screenshot`,`.png`)}:{field:`path`,localPath:n,positionalIndex:0,flagPath:F(`screenshot`,`.png`)}}if(e.command===`record`&&(t[0]??``).toLowerCase()===`start`){if(!an(e)&&e.flags?.platform===void 0)return null;let t=rn(e),n=on(sn(e,`outPath`,t,1),e);return{field:`outPath`,localPath:n,positionalIndex:1,positionalPath:F(`recording`,C.extname(n)||t)}}return null}function rn(e){return he(e.flags?.platform)}function an(e){return P(e.positionals?.[1])||P(e.flags?.out)}function on(e,t){return t.flags?.platform===`web`?we(e,rn(t)):e}function sn(e,t,n,r=0){let i=e.positionals?.[r]??e.flags?.out,a=`${t===`path`?`screenshot`:`recording`}-${Date.now()}${n}`,o=P(i)?i:a;return C.isAbsolute(o)?o:C.resolve(e.meta?.cwd??process.cwd(),o)}function P(e){return typeof e==`string`&&e.trim().length>0}function F(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 cn(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=ln(n,t);await un({baseUrl:e.baseUrl,token:e.token,artifactId:n.artifactId,destinationPath:r,requestScope:t.meta}),i[n.field]=r,a.push({...n,localPath:r})}return i.artifacts=a,{ok:!0,data:i}}function ln(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 un(e){let t=new URL(dn(e.baseUrl,e.artifactId)),n=t.protocol===`https:`?E:T;await w.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){w.promises.rm(e.destinationPath,{force:!0}).finally(()=>a(t));return}i()}},l=n.request({protocol:t.protocol,host:t.hostname,port:t.port,method:`GET`,path:t.pathname+t.search,headers:{...v(e.token),...le(e.requestScope?.tenantId)}},t=>{if((t.statusCode??500)>=400){let n=``;t.setEncoding(`utf8`),t.on(`data`,e=>{n+=e}),t.on(`end`,()=>{c(new r(`COMMAND_FAILED`,`Failed to download remote artifact`,{artifactId:e.artifactId,statusCode:t.statusCode,requestId:e.requestScope?.requestId,body:n}))});return}t.on(`aborted`,()=>{c(new r(`COMMAND_FAILED`,`Remote artifact download was interrupted`,{artifactId:e.artifactId,requestId:e.requestScope?.requestId}))}),D(t,w.createWriteStream(e.destinationPath)).then(()=>c(),e=>c(e instanceof Error?e:Error(String(e))))}),u=setTimeout(()=>{let t=new r(`COMMAND_FAILED`,`Remote artifact download timed out`,{artifactId:e.artifactId,requestId:e.requestScope?.requestId,timeoutMs:s});c(t),l.destroy(t)},s);l.on(`error`,t=>{if(t instanceof r){c(t);return}c(new r(`COMMAND_FAILED`,`Failed to download remote artifact`,{artifactId:e.artifactId,requestId:e.requestScope?.requestId,timeoutMs:s},t instanceof Error?t:void 0))}),l.end()})}function dn(e,t){let n=e.endsWith(`/`)?e:`${e}/`;return new URL(`artifacts/${encodeURIComponent(t)}`,n).toString()}function fn(e){return typeof e.baseUrl==`string`&&e.baseUrl.length>0}const pn=3e3,mn=1e3;function I(e){let t=Cn(e);if(!t||typeof t!=`object`)return null;let n=t,r=hn(n);if(!r)return null;let i=gn(n);return i?{token:r,...i,transport:_n(n.transport),pid:R(n.pid)??0,version:L(n.version),codeSignature:L(n.codeSignature),processStartTime:L(n.processStartTime)}:null}function hn(e){return typeof e.token==`string`&&e.token.length>0?e.token:null}function gn(e){let t=R(e.port),n=R(e.httpPort);return t===void 0&&n===void 0?null:{port:t,httpPort:n}}function _n(e){return e===`socket`||e===`http`||e===`dual`?e:void 0}function L(e){return typeof e==`string`?e:void 0}function R(e){return Number.isInteger(e)&&Number(e)>0?Number(e):void 0}function z(e){let t=Cn(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 B(e){wn(e)}function V(e){wn(e)}function vn(e){let t=U(e);if(!t.hasLock||t.hasInfo)return;let n=z(e.lockPath);if(!n){V(e.lockPath);return}_(n.pid,n.processStartTime)||V(e.lockPath)}async function H(e,t,n={}){let r=n.stopLiveProcesses??!0,i={reason:t,removedInfo:!1,removedLock:!1,stoppedInfoProcess:!1,stoppedLockProcess:!1};try{let t=w.existsSync(e.infoPath),n=I(e.infoPath);if(n){let t=_(n.pid,n.processStartTime);t&&!r?i.retainedInfoProcess=!0:(t&&(await W(n),i.stoppedInfoProcess=!0),B(e.infoPath),i.removedInfo=!0)}else t&&(B(e.infoPath),i.removedInfo=!0);let a=w.existsSync(e.lockPath),o=z(e.lockPath);if(o){let t=_(o.pid,o.processStartTime);t&&!r?i.retainedLockProcess=!0:(t&&(await me(o.pid,{termTimeoutMs:pn,killTimeoutMs:mn,expectedStartTime:o.processStartTime}),i.stoppedLockProcess=!0),V(e.lockPath),i.removedLock=!0)}else a&&(V(e.lockPath),i.removedLock=!0)}catch(e){i.error=e instanceof Error?e.message:String(e)}return b({level:i.error?`warn`:`info`,phase:`daemon_startup_metadata_cleanup`,data:i}),i}function U(e){return{hasInfo:w.existsSync(e.infoPath),hasLock:w.existsSync(e.lockPath)}}async function yn(e){let t=U(e);if(!t.hasLock||t.hasInfo)return!1;let n=z(e.lockPath);return!n||!_(n.pid,n.processStartTime)?(V(e.lockPath),!0):!1}async function W(e){await me(e.pid,{termTimeoutMs:pn,killTimeoutMs:mn,expectedStartTime:e.processStartTime})}function bn(e){return typeof e.baseUrl==`string`&&e.baseUrl.length>0}function xn(e,t=y(process.env.AGENT_DEVICE_STATE_DIR)){let n=Sn(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 Sn(e){return`rm -f ${be(e.infoPath)} ${be(e.lockPath)}`}function Cn(e){if(!w.existsSync(e))return null;try{return JSON.parse(w.readFileSync(e,`utf8`))}catch{return null}}function wn(e){try{w.existsSync(e)&&w.unlinkSync(e)}catch{}}function Tn(e,t){if(t.onProgress){t.onProgress(e);return}e.type===`command`&&(t.req.command===`doctor`&&Pe(),process.stderr.write(`${e.message}\n`))}function G(e,t,n){return new r(`COMMAND_FAILED`,`Invalid daemon response`,{requestId:e.meta?.requestId,line:t},n instanceof Error?n:void 0)}function En(e){let t=t=>(e.onError(t),!0);return{handleLine(n){let r;try{r=JSON.parse(n)}catch(r){return t(G(e.req,n,r))}if(ve(r))try{return Tn(r.event,{req:e.req,onProgress:e.onProgress}),!1}catch(e){return t(e)}return ue(r)?(e.onResponse(r.response),!0):e.responseFormat===`socket-legacy`?(e.onResponse(r),!0):t(G(e.req,n,Error(`Missing daemon progress response envelope`)))}}}function Dn(e,t){return ye(e)&&String(Array.isArray(t)?t.join(`,`):t??``).includes(`application/x-ndjson`)}function On(e,t){let{req:n,isSettled:r,resolve:i,reject:a,clearTimeout:o}=t,s=``,c=En({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=Ce(s,e);s=t.buffer;for(let e of t.lines)if(c.handleLine(e))return})}function kn(e,t){let{req:n,handleResponseBody:i,reject:a,clearTimeout:o}=t,s=``,c=!1,l=En({req:n,onProgress:t.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=Ce(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(G(n,e)))}),e.on(`error`,e=>{c||(c=!0,o(),a(new r(`COMMAND_FAILED`,`Failed to read daemon response`,{requestId:n.meta?.requestId},e instanceof Error?e:void 0)))})}function An(e,t){let{info:n,req:i,resolve:a,reject:o}=t;try{let t=jn(e);if(t.error){o(Mn(t.error,i.meta?.requestId));return}if(!t.result||typeof t.result!=`object`){o(new r(`COMMAND_FAILED`,`Invalid daemon RPC response`,{requestId:i.meta?.requestId}));return}Nn(n,i,t.result,a,o)}catch(t){o(new r(`COMMAND_FAILED`,`Invalid daemon response`,{requestId:i.meta?.requestId,line:e},t instanceof Error?t:void 0))}}function jn(e){return JSON.parse(e)}function Mn(e,t){let i=e.data??{};return new r(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:t})}async function Nn(e,t,n,r,i){try{r(e.baseUrl&&n.ok?await cn(e,t,n):n)}catch(e){i(e)}}function Pn(e,t){let n=e.meta?.requestId??ze();return Fn(e.command)?{jsonrpc:`2.0`,id:n,method:In(e.command),params:Ln(e,e.command,t)}:{jsonrpc:`2.0`,id:n,method:`agent_device.command`,params:e}}function Fn(e){return e===`lease_allocate`||e===`lease_heartbeat`||e===`lease_release`}function In(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 Ln(e,t,n){return p(f(e),t,{includeTokenParam:n.includeTokenParam,token:e.token,session:e.session})}const Rn=[`xcodebuild .*AgentDeviceRunnerUITests/RunnerTests/testCommand`,`xcodebuild .*AgentDeviceRunner\\.env\\.session-`,`xcodebuild build-for-testing .*apple/runner/AgentDeviceRunner/AgentDeviceRunner\\.xcodeproj`];function zn(e){let t=re(e.command);if(t.envelopeMs===`unbounded`)return;let n={...t,envelopeMs:t.envelopeMs};return Bn(n,e.positionals??[])??Vn(n,e.flags)??n.envelopeMs}function Bn(e,t){if(e.budget.source!==`positional-parser`)return;let n=e.budget.parser(t);return n===null?void 0:Un(e,n)}function Vn(e,t){if(e.budget.source===`flag`)return e.budget.envelope===`widen`?Hn(e,e.budget,t):typeof t?.timeoutMs==`number`?t.timeoutMs:e.envelopeMs}function Hn(e,t,n){if(n?.settle!==!0)return e.envelopeMs;let r=typeof n.timeoutMs==`number`?n.timeoutMs:t.defaultBudgetMs;return typeof r==`number`?Wn(e,r):e.envelopeMs}function Un(e,t){return Math.max(e.envelopeMs,t+Xn)}function Wn(e,t){return Math.max(e.envelopeMs,e.envelopeMs+t+Xn)}function Gn(e,t,n,i,a,o){let s=a?{terminated:0}:Jn(),c=!a&&Kn(i),l=c?Yn(e,t):{forcedKill:!1};return b({level:`error`,phase:`daemon_request_timeout`,data:{timeoutMs:o,requestId:n,command:i,timedOutRunnerPidsTerminated:s.terminated,timedOutRunnerCleanupError:s.error,daemonPidReset:c?e.pid:void 0,daemonPidForceKilled:c?l.forcedKill:void 0,daemonPreservedAfterTimeout:!a&&!c,daemonBaseUrl:e.baseUrl}}),new r(`COMMAND_FAILED`,`Daemon request timed out`,{timeoutMs:o,requestId:n,hint:qn({remote:a,resetDaemon:c,command:i})})}function Kn(e){return re(e).onTimeout===`reset-daemon`}function qn(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===s.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 Rn)Be(`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 Yn(e,t){let n=!1;try{_(e.pid,e.processStartTime)&&(process.kill(e.pid,`SIGKILL`),n=!0)}catch{W(e)}finally{B(t.infoPath),V(t.lockPath)}return{forcedKill:n}}const Xn=3e4,Zn=`Daemon HTTP endpoint is unavailable`,Qn=`Daemon socket endpoint is unavailable`;async function $n(e,t){let n=cr(e,t);if(await er(e,n))return!0;let r=lr(e,t,n);return r?await er(e,r):!1}async function er(e,t){return t===`http`?await nr(e):await tr(e.port)}function tr(e){return e?new Promise(t=>{let n=!1,r=O.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 nr(e){return ir(e).then(e=>e.reachable)}async function rr(e){let t=await ir(e);if(!e.baseUrl||!t.reachable)return t;if(typeof t.rpcProtocolVersion==`number`&&t.rpcProtocolVersion!==2)throw new r(`COMMAND_FAILED`,`Remote daemon RPC protocol is incompatible`,{daemonBaseUrl:e.baseUrl,clientVersion:x(),remoteVersion:t.version,remoteService:t.service,supportedRpcProtocolVersion:2,remoteRpcProtocolVersion:t.rpcProtocolVersion,hint:`Upgrade agent-device on the client or remote host so both support the same daemon RPC protocol.`});return t}function ir(e){let t=e.baseUrl?Te(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:`?E:T,i=e.baseUrl?3e3:500;return new Promise(t=>{let a=e.baseUrl?v(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,...ar(n)})})});o.on(`timeout`,()=>{o.destroy(),t({reachable:!1})}),o.on(`error`,()=>{t({reachable:!1})}),o.end()})}function ar(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 or(e,t,n,r,i,a={}){let o=cr(e,n);try{return await sr(e,t,r,i,o,a)}catch(s){let c=lr(e,n,o);if(!c||!ur(s,o))throw s;return await sr(e,t,r,i,c,a)}}async function sr(e,t,n,r,i,a){return i===`http`?await mr(e,t,n,r,a):await pr(e,t,n,r,a)}function cr(e,t){if(e.baseUrl){if(t===`socket`)throw new r(`COMMAND_FAILED`,`Remote daemon endpoint only supports HTTP transport`,{daemonBaseUrl:e.baseUrl});return`http`}if(t===`http`||t===`socket`)return dr(e,t);let n=(e.transport===`socket`||e.transport===`dual`?[`socket`,`http`]:[`http`,`socket`]).find(t=>K(e,t));if(n)return n;throw new r(`COMMAND_FAILED`,`Daemon metadata has no reachable transport`)}function K(e,t){return t===`http`?!!e.httpPort:!!e.port}function lr(e,t,n){if(t!==`auto`||e.baseUrl)return null;let r=n===`socket`?`http`:`socket`;return K(e,r)?r:null}function ur(e,t){return t===`socket`&&e instanceof r&&e.code===`COMMAND_FAILED`&&e.message===`Failed to communicate with daemon`&&e.details?.daemonSocketRequestWritten===!1}function dr(e,t){if(K(e,t))return t;throw new r(`COMMAND_FAILED`,t===`http`?Zn:Qn)}function fr(e,t,n,i={}){return b({level:`error`,phase:`daemon_request_socket_error`,data:{requestId:t,message:e instanceof Error?e.message:String(e)}}),new r(`COMMAND_FAILED`,`Failed to communicate with daemon`,{...i,requestId:t,hint:n?`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 pr(e,t,n,i,a){let o=e.port;if(!o)throw new r(`COMMAND_FAILED`,Qn);return new Promise((r,s)=>{let c=!1,l=O.createConnection({host:`127.0.0.1`,port:o},()=>{c=!0,l.write(`${JSON.stringify(t)}\n`)}),u=!1,d=typeof i==`number`?setTimeout(()=>{u=!0,l.destroy(),s(Gn(e,n,t.meta?.requestId,t.command,!1,i))},i):void 0;On(l,{req:t,onProgress:a.onProgress,isSettled:()=>u,clearTimeout:()=>{d&&clearTimeout(d)},resolve:e=>{u=!0,r(e)},reject:e=>{u=!0,s(e)}}),l.on(`error`,e=>{u||(u=!0,d&&clearTimeout(d),s(fr(e,t.meta?.requestId,!1,{daemonSocketRequestWritten:c})))})})}async function mr(e,t,n,i,a){let o=e.baseUrl?new URL(Te(e.baseUrl,`rpc`)):e.httpPort?new URL(`http://127.0.0.1:${e.httpPort}/rpc`):null;if(!o)throw new r(`COMMAND_FAILED`,Zn);let s=JSON.stringify(Pn(t,{includeTokenParam:!e.baseUrl})),c={"content-type":`application/json`,"content-length":Buffer.byteLength(s)};return e.baseUrl&&Object.assign(c,v(e.token)),await new Promise((l,u)=>{let d=(o.protocol===`https:`?E:T).request({protocol:o.protocol,host:o.hostname,port:o.port,method:`POST`,path:o.pathname+o.search,headers:c},n=>{if(Dn(t,n.headers?.[`content-type`])){kn(n,{req:t,onProgress:a.onProgress,reject:u,clearTimeout:()=>{p&&clearTimeout(p)},handleResponseBody:n=>An(n,{info:e,req:t,resolve:l,reject:u})});return}pe(n).then(n=>{p&&clearTimeout(p),An(n,{info:e,req:t,resolve:l,reject:u})}).catch(e=>{p&&clearTimeout(p),u(new r(`COMMAND_FAILED`,`Failed to read daemon response`,{requestId:t.meta?.requestId},e instanceof Error?e:void 0))})}),f=bn(e),p=typeof i==`number`?setTimeout(()=>{d.destroy(),u(Gn(e,n,t.meta?.requestId,t.command,f,i))},i):void 0;d.on(`error`,e=>{p&&clearTimeout(p),u(fr(e,t.meta?.requestId,f))}),d.write(s),d.end()})}const q=15e3,J=new O.BlockList;J.addSubnet(`127.0.0.0`,8,`ipv4`),J.addAddress(`::1`,`ipv6`),J.addSubnet(`::ffff:127.0.0.0`,104,`ipv6`);function hr(e,t){let n=gr(e),r=_r(e,t),i=vr(e,r.remoteBaseUrl),a=yr(e,n,r.rawBaseUrl);return{paths:y(a?br():n),transportPreference:i.preference,serverMode:i.serverMode,ownedStateDir:a,remoteBaseUrl:r.remoteBaseUrl,remoteAuthToken:r.authToken}}function gr(e){return e.flags?.stateDir??process.env.AGENT_DEVICE_STATE_DIR}function _r(e,t){let n=e.flags?.daemonBaseUrl??process.env.AGENT_DEVICE_DAEMON_BASE_URL,r=Hr(n),i=t??process.env.AGENT_DEVICE_DAEMON_AUTH_TOKEN;return Ur(r,i),{rawBaseUrl:n,remoteBaseUrl:r,authToken:i}}function vr(e,t){let n=e.flags?.daemonTransport??process.env.AGENT_DEVICE_DAEMON_TRANSPORT,i=De(n);if(t&&i===`socket`)throw new r(`INVALID_ARGS`,`Remote daemon base URL only supports HTTP transport. Remove --daemon-transport socket.`,{daemonBaseUrl:t});return{preference:i,serverMode:de(e.flags?.daemonServerMode??process.env.AGENT_DEVICE_DAEMON_SERVER_MODE??(n===`dual`?`dual`:void 0))}}function yr(e,t,n){return Pr(e.command)&&!t&&!n}function br(){return w.mkdtempSync(C.join(Ye.tmpdir(),`agent-device-replay-daemon-`))}async function xr(e){if(e.remoteBaseUrl)return await Sr(e);let t=await Cr(e);return t?{info:t,startedByClient:!1}:(vn(e.paths),await kr(e))}async function Sr(e){let t={transport:`http`,token:e.remoteAuthToken??``,pid:0,baseUrl:e.remoteBaseUrl};if((await rr(t)).reachable)return{info:t,startedByClient:!1};throw new r(`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 Cr(e){let t=I(e.paths.infoPath);if(!t)return null;let n=await wr(t,e.transportPreference);return Er(t,n)?t:(Dr(t,n,e.paths.baseDir),await W(t),B(e.paths.infoPath),null)}async function wr(e,t){try{return await $n(e,t)}catch(e){if(Tr(e))return!1;throw e}}function Tr(e){return e instanceof r&&e.code===`COMMAND_FAILED`&&(e.message===`Daemon HTTP endpoint is unavailable`||e.message===`Daemon socket endpoint is unavailable`)}function Er(e,t){return e.version===x()&&e.codeSignature===zr()&&t}function Dr(e,t,n){try{let r=e.version?`pid ${e.pid}, v${e.version}`:`pid ${e.pid}`,i=Or(e,t);process.stderr.write(`Replacing daemon (${r}) in ${n}: ${i}\n`)}catch{}}function Or(e,t){return e.version===x()?e.codeSignature===zr()?t?`not reusable`:`unreachable`:`code-signature mismatch`:`version mismatch (client v${x()})`}async function kr(e){let t=0,n=[],i,a;for(let r=1;r<=2;r+=1){let o;try{o=Rr(e),a={pid:o.pid}}catch(t){if(i=t instanceof Error?t.message:String(t),n.push(await H(e.paths,`start_error`)),r<2){await S(150);continue}break}let s=await Lr(q,e,o);if(s.kind===`ready`)return{info:s.info,startedByClient:!0};if(s.kind===`early_exit`){if(a=s.exit,i=Br(s.exit),n.push(await H(e.paths,`start_error`)),r<2){await S(150);continue}break}if(await yn(e.paths)){t+=1;continue}let c=U(e.paths),l=r<2,u=await H(e.paths,`startup_timeout`,{stopLiveProcesses:!1});if(n.push(u),u.retainedInfoProcess||u.retainedLockProcess){let t=await Lr(q,e,o);if(t.kind===`ready`)return{info:t.info,startedByClient:!0};t.kind===`early_exit`&&(a=t.exit,i=Br(t.exit));break}if(!l)break;!c.hasInfo&&!c.hasLock&&await S(150)}let o=U(e.paths),s=Vr(e.paths.logPath);throw new r(`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:q,startupAttempts:2,lockRecoveryCount:t,cleanupResults:n,startError:i,daemonProcess:a,...s?{daemonLogTail:s}:{},metadataState:o,hint:xn(o,e.paths)})}async function Ar(e,t,n,r){if(!Pr(e.command)||!t.startedByClient&&!n.ownedStateDir||bn(t.info)||Mr(r)||Fr(e,r))return r;let i={pid:t.info.pid,removedInfo:!1,removedLock:!1,removedStateDir:!1,error:void 0},a=r;try{await W(t.info)}catch(e){i.error=e instanceof Error?e.message:String(e)}finally{let e=w.existsSync(n.paths.infoPath);B(n.paths.infoPath),i.removedInfo=e&&!w.existsSync(n.paths.infoPath);let t=w.existsSync(n.paths.lockPath);if(V(n.paths.lockPath),i.removedLock=t&&!w.existsSync(n.paths.lockPath),n.ownedStateDir){let e=Ee(n.paths.sessionsDir);e?a=jr(r,e):(w.rmSync(n.paths.baseDir,{recursive:!0,force:!0}),i.removedStateDir=!w.existsSync(n.paths.baseDir))}}return b({level:i.error?`warn`:`info`,phase:`daemon_replay_cleanup`,data:i}),a}function jr(e,n){if(e&&!e.ok)return e;let{sessionName:i,tombstone:a}=n,o=a.sourcePath?`re-run: replay ${a.sourcePath} --save-script`:`re-run your replay <script> --save-script from the start`;return{ok:!1,error:t(new r(`REPAIR_COMMIT_FAILED`,`The repair transaction for session "${i}" completed, but committing its healed script failed at teardown: ${a.commitFailure.message}. ${o}.`))}}function Mr(e){if(!e||e.ok||e.error.code!==`REPLAY_DIVERGENCE`)return!1;let t=e.error.details?.divergence;if(!t||typeof t!=`object`)return!1;let n=t.resume;return!n||typeof n!=`object`?!1:n.repairSessionHeld===!0}function Nr(e,t){let n=`This repair session's daemon was kept alive to continue the repair; pass --state-dir ${t} on your next command (press, replay --from, or close --save-script) to reach it.`,r=e.error.hint;return{...e,error:{...e.error,hint:r?`${r} ${n}`:n}}}function Pr(e){return e===s.replay||e===s.test}function Fr(e,t){return e.command!==s.replay||!t||!t.ok?!1:t.data?.sessionActive===!0}function Ir(e,t){let n=e.data??{},r=typeof n.session==`string`?n.session:void 0,i=[...t?[`--state-dir ${_e(t)}`]:[],...r?[`--session ${_e(r)}`]:[]];if(i.length===0)return e;let a=`This session's daemon was kept alive because its script left the session active; pass ${i.join(` `)} on your next command to reach it.`,o=typeof n.message==`string`?n.message:void 0;return{...e,data:{...n,hint:a,message:o?`${o} ${a}`:a}}}async function Lr(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=I(t.paths.infoPath);if(e&&await $n(e,t.transportPreference))return{kind:`ready`,info:e};if(i)return{kind:`early_exit`,exit:i};await S(100)}return{kind:`timeout`}}function Rr(e){let t=Y(),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};w.mkdirSync(e.paths.baseDir,{recursive:!0});let i=w.openSync(e.paths.logPath,`a`),a=w.openSync(e.paths.logPath,`a`);try{return Ue(process.execPath,n,{env:r,stdio:[`ignore`,i,a]})}finally{w.closeSync(i),w.closeSync(a)}}function Y(){let e=We(),t=[C.join(e,`dist`,`src`,`internal`,`daemon.js`),C.join(e,`dist`,`src`,`daemon.js`)],n=t[0];if(n===void 0)throw new r(`COMMAND_FAILED`,`Daemon dist path list is empty`);let i=t.find(e=>w.existsSync(e))??n,a=C.join(e,`src`,`daemon.ts`),o=t.some(e=>w.existsSync(e)),s=w.existsSync(a);if(!o&&!s)throw new r(`COMMAND_FAILED`,`Daemon entry not found`,{distPaths:t,srcPath:a});return{root:e,distPath:i,distPaths:t,srcPath:a,useSrc:(process.execArgv.includes(`--experimental-strip-types`)||!o)&&s}}function zr(){let e=Y();return ge(e.useSrc?e.srcPath:e.distPath,e.root)}function Br(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(!w.existsSync(e))return;let t=w.statSync(e);if(t.size<=0)return;let n=Math.min(t.size,64e3),r=w.openSync(e,`r`);try{let e=Buffer.alloc(n);w.readSync(r,e,0,n,t.size-n);let i=e.toString(`utf8`).trim();return i.length>0?i:void 0}finally{w.closeSync(r)}}catch{return}}function Hr(e){if(!e)return;let t;try{t=new URL(e)}catch(t){throw new r(`INVALID_ARGS`,`Invalid daemon base URL`,{daemonBaseUrl:e},t instanceof Error?t:void 0)}if(t.protocol!==`http:`&&t.protocol!==`https:`)throw new r(`INVALID_ARGS`,`Daemon base URL must use http or https`,{daemonBaseUrl:e});return t.toString().replace(/\/+$/,``)}function Ur(e,t){if(!e)return;let n=new URL(e).hostname;if(!Wr(n)&&!(typeof t==`string`&&t.trim().length>0))throw new r(`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 Wr(e){let t=e.trim().toLowerCase().replace(/^\[(.*)\]$/,`$1`);return t===`localhost`?!0:O.isIPv4(t)?J.check(t,`ipv4`):O.isIPv6(t)?J.check(t,`ipv6`):!1}async function Gr(e,t={}){let n=e.meta?.requestId??ze(),r=!!(e.meta?.debug||e.flags?.verbose),i=e.flags,{daemonAuthToken:a,...o}=i??{},s=i?{...e,flags:o}:e,c=hr(s,t.authToken??a),l=zn(s),u=await Ve(`daemon_startup`,async()=>await xr(c),{requestId:n,session:e.session}),d=u.info,f=await Yt(s,d);$r(s.command);let p=Kr(s,f,d.token,n,r);return b({level:`info`,phase:`daemon_request_prepare`,data:{requestId:n,command:s.command,session:s.session}}),await Xr(s,u,c,async()=>Qr(Zr(await Ve(`daemon_request`,async()=>await or(d,p,c.transportPreference,c.paths,l,t.onProgress?{onProgress:t.onProgress}:void 0),{requestId:n,command:e.command}),c),s,c))}function Kr(e,t,n,r,i){return{...e,positionals:t.positionals,flags:t.flags,token:n,meta:qr(e,t,r,i)}}function qr(e,t,n,r){let i=e.meta??{};return{...i,requestId:n,debug:r,...Jr(i,e.flags),...Yr(t)}}function Jr(e,t){return{includeCost:e.includeCost,cwd:e.cwd,sessionExplicit:e.sessionExplicit,tenantId:e.tenantId??t?.tenant,runId:e.runId??t?.runId,leaseId:e.leaseId??t?.leaseId,sessionIsolation:e.sessionIsolation??t?.sessionIsolation,lockPolicy:e.lockPolicy,lockPlatform:e.lockPlatform}}function Yr(e){return{...e.uploadedArtifactId?{uploadedArtifactId:e.uploadedArtifactId}:{},...e.clientArtifactPaths?{clientArtifactPaths:e.clientArtifactPaths}:{},...e.installSource?{installSource:e.installSource}:{}}}async function Xr(e,t,n,i){let a,o=!1,s;try{a=await i()}catch(e){o=!0,s=e}let c=await Ar(e,t,n,a);if(o)throw s;if(!c)throw new r(`COMMAND_FAILED`,`Daemon request produced no response after cleanup`);return c}function Zr(e,t){return e.ok||!t.ownedStateDir||!Mr(e)?e:Nr(e,t.paths.baseDir)}function Qr(e,t,n){return!e.ok||!Fr(t,e)?e:Ir(e,n.ownedStateDir?n.paths.baseDir:void 0)}function $r(e){!ei(e)||process.stderr.isTTY!==!0||process.env.CI||process.stderr.write(e===s.reinstall?`Reinstalling...
|
|
2
2
|
`:`Installing...
|
|
3
|
-
`)}function jr(e){return e===_.install||e===_.reinstall||e===g.installSource}function J(e,t){return T.join(e,`metro-sessions`,`${ge(t)}.json`)}function Mr(e){let t=J(e.stateDir,e.session);w.mkdirSync(T.dirname(t),{recursive:!0}),w.writeFileSync(t,`${JSON.stringify(e.hints,null,2)}\n`,`utf8`)}function Nr(e){let t=J(e.stateDir,e.session),n;try{n=w.readFileSync(t,`utf8`)}catch{return}let r;try{r=JSON.parse(n)}catch{return}if(!r||typeof r!=`object`||Array.isArray(r))return;let i=r,a={};return typeof i.metroHost==`string`&&i.metroHost&&(a.metroHost=i.metroHost),typeof i.metroPort==`number`&&Number.isInteger(i.metroPort)&&(a.metroPort=i.metroPort),typeof i.bundleUrl==`string`&&i.bundleUrl&&(a.bundleUrl=i.bundleUrl),Object.keys(a).length>0?a:void 0}function Pr(e){w.rmSync(J(e.stateDir,e.session),{force:!0})}const Fr={...Be(),batch:Ve(Ir)};function Ir(e,t,r){let i=Fr[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 Rr(i,a,a.readInput(t))}catch(t){throw new n(`INVALID_ARGS`,`Batch step ${r} ${e} input is invalid: ${t instanceof Error?t.message:String(t)}`,void 0,t)}}function Lr(e,t){let n=Fr[e];if(!n)throw Error(`Missing daemon writer for command: ${e}`);return Rr(n,We(e),t)}function Rr(e,t,n){let r=e(n);return{...r,...t?{metadataFlags:Re(t,r.options)}:{}}}function zr(e){throw new n(i(e.code),e.message,{...e.details??{},hint:e.hint,diagnosticId:e.diagnosticId,logPath:e.logPath,retriable:e.retriable,supportedOn:e.supportedOn})}function Br(e,t){let n=h(e,`bundleId`),r=h(e,`package`);return{app:d(e,`app`),appPath:d(e,`appPath`),platform:p(e,`platform`),appId:n??r,bundleId:n,package:r,identifiers:oe({session:t,bundleId:n,packageName:r})}}function Vr(e,t){let r=h(e,`bundleId`),i=h(e,`packageName`),a=r??i??h(e,`appId`),o=h(e,`launchTarget`)??i??r??a;if(!o)throw new n(`COMMAND_FAILED`,`Daemon response is missing "launchTarget".`,{response:e});return{appName:h(e,`appName`),appId:a,bundleId:r,packageName:i,launchTarget:o,installablePath:h(e,`installablePath`),archivePath:h(e,`archivePath`),materializationId:h(e,`materializationId`),materializationExpiresAt:h(e,`materializationExpiresAt`),identifiers:oe({session:t,bundleId:r,packageName:i,appId:a})}}function Hr(e){return{released:e.released===!0,materializationId:d(e,`materializationId`),identifiers:{}}}function Ur(e){let{record:t,platform:n,id:r,name:i,target:a}=Kr(e,`name`),o=Gr(t);return{platform:n,target:a,kind:ne(t,`kind`),id:r,name:i,booted:typeof t.booted==`boolean`?t.booted:void 0,...Ne(n)&&o?{appleOs:o}:{},identifiers:v(n,r,i),...Y(n,r)}}function Wr(e){let{record:t,platform:n,id:r,name:i,target:a}=Kr(e,`name`),o=d(t,`device`),s=Gr(t),c={session:i,...v(n,r,o)};return{name:i,createdAt:ae(t,`createdAt`),sessionStateDir:h(t,`sessionStateDir`),runnerLogPath:h(t,`runnerLogPath`),device:{platform:n,target:a,id:r,name:o,...s?{appleOs:s}:{},identifiers:c,...Y(n,r,{simulatorSetPath:ie(t,`ios_simulator_device_set`)})},identifiers:c}}function Gr(e){let t=e.appleOs;return je(t)?t:void 0}function Kr(e,t){let n=re(e);return{record:n,platform:p(n,`platform`),id:d(n,`id`),name:d(n,t),target:te(n,`target`)}}function Y(e,t,n={}){if(e===`ios`)return{ios:{udid:t,...n.simulatorSetPath===void 0?{}:{simulatorSetPath:n.simulatorSetPath}}};if(!Me(e))return{};let r=n.serial??t;return e===`android`?{android:{serial:r}}:{vega:{serial:r}}}function qr(e){if(!m(e))return;let t=e.platform,n=h(e,`metroHost`),r=typeof e.metroPort==`number`?e.metroPort:void 0,i=h(e,`bundleUrl`),a=h(e,`launchUrl`);return{platform:t===`ios`||t===`android`?t:void 0,metroHost:n,metroPort:r,bundleUrl:i,launchUrl:a}}function Jr(e){let t=e.platform,n=h(e,`id`),r=h(e,`device`);if(!Pe(t)||!n||!r)return;let i=te(e,`target`),a=Me(t)?h(e,`serial`)??n:void 0;return{platform:t,target:i,id:n,name:r,identifiers:{...v(t,n,r),...a?{serial:a}:{}},...Y(t,t===`ios`?h(e,`device_udid`)??n:n,{simulatorSetPath:ie(e,`ios_simulator_device_set`),serial:a})}}function Yr(e){if(m(e)&&!(typeof e.durationMs!=`number`||typeof e.measuredAt!=`string`||typeof e.method!=`string`))return{durationMs:e.durationMs,measuredAt:e.measuredAt,method:e.method,appTarget:h(e,`appTarget`),appBundleId:h(e,`appBundleId`)}}function Xr(e){if(!m(e)||typeof e.success!=`boolean`||typeof e.exitCode!=`number`||typeof e.stdout!=`string`||typeof e.stderr!=`string`)return;let t=Zr(e.error);return{success:e.success,exitCode:e.exitCode,stdout:e.stdout,stderr:e.stderr,...t?{error:t}:{}}}function Zr(e){if(m(e)&&!(typeof e.code!=`string`||typeof e.message!=`string`))return{code:e.code,message:e.message,...typeof e.hint==`string`?{hint:e.hint}:{},...typeof e.diagnosticId==`string`?{diagnosticId:e.diagnosticId}:{},...typeof e.logPath==`string`?{logPath:e.logPath}:{},...m(e.details)?{details:e.details}:{}}}function Qr(e){return Array.isArray(e)?e:[]}function $r(e){let t=se(e);return ee({requestId:e.requestId,cwd:e.cwd,sessionExplicit:e.session!==void 0,debug:e.debug,includeCost:e.cost,responseLevel:e.responseLevel,lockPolicy:e.lockPolicy,lockPlatform:e.lockPlatform,...le(t),sessionIsolation:e.sessionIsolation,installSource:e.installSource,retainMaterializedPaths:e.retainMaterializedPaths,materializedPathRetentionMs:e.materializedPathRetentionMs,materializationId:e.materializationId})}function X(e){return e??`default`}var ei=e({createAgentDeviceClient:()=>ti});function ti(e={},t={}){let i=t.transport??Er,a=t=>r(t.responseLevel??e.responseLevel),o=async(t,n=[],r={},a,o)=>{let s=Q(e,r),c=await i({session:X(s.session),command:t,positionals:n,...o?{input:o}:{},flags:ze(s,a),runtime:s.runtime,meta:$r(s)});return c.ok||zr(c.error),c.data??{}},s=async(e={})=>{let t=await o(g.sessionList,[],e);return(Array.isArray(t.sessions)?t.sessions:[]).map(Wr)},c=async(e,t={})=>{let n=Lr(e,t);return await o(n.command,n.positionals,n.options,n.metadataFlags,n.input)},l=(t={})=>X(Q(e,t).session);return{command:{wait:async e=>await c(`wait`,e),alert:async(e={})=>await c(`alert`,e),...di(c),reactNative:async e=>await c(`react-native`,e),doctor:async(e={})=>await c(`doctor`,e),prepare:async e=>await c(`prepare`,e),viewport:async e=>await c(`viewport`,e)},devices:{list:async(e={})=>{let t=await c(`devices`,e);return(Array.isArray(t.devices)?t.devices:[]).map(Ur)},capabilities:async(e={})=>{let t=await c(`capabilities`,e),n=Array.isArray(t.availableCommands)?t.availableCommands.filter(e=>typeof e==`string`):[];return{device:Ur(t.device),availableCommands:n}},boot:async(e={})=>await c(`boot`,e),shutdown:async(e={})=>await c(`shutdown`,e)},sessions:{list:async(e={})=>await s(e),stateDir:async(t={})=>x(Q(e,t).stateDir??process.env.AGENT_DEVICE_STATE_DIR).baseDir,close:async(t={})=>{let n=l(t);try{let e=await c(`close`,t);return{session:n,shutdown:Xr(e.shutdown),provider:Z(e.provider),savedScript:h(e,`savedScript`),identifiers:{session:n}}}finally{gi(e,t)}},saveScript:async(e={})=>{let t=await o(g.sessionSaveScript,e.path===void 0?[]:[e.path],e,{force:e.force}),r=t.actionCount;if(typeof r!=`number`||!Number.isInteger(r)||r<0)throw new n(`COMMAND_FAILED`,`Daemon returned an invalid saved-script action count.`);let i=d(t,`session`);return{session:i,savedScript:d(t,`savedScript`),actionCount:r,identifiers:{session:i}}},artifacts:async(e={})=>await c(`artifacts`,e)},apps:{install:async e=>Br(await c(`install`,e),l(e)),reinstall:async e=>Br(await c(`reinstall`,e),l(e)),installFromSource:async e=>Vr(await c(`install-from-source`,e),l(e)),list:async(e={})=>{let t=await c(`apps`,e);return Array.isArray(t.apps)?t.apps.filter(e=>typeof e==`string`):[]},open:async t=>{let n=l(t),r=await c(`open`,t);hi({config:e,options:t,runtime:Q(e,t).runtime,sessionReused:r.sessionReused===!0});let i=Jr(r),a=h(r,`appBundleId`),o=a,s=Array.isArray(r.warnings)?r.warnings.filter(e=>typeof e==`string`):[];return{session:n,...s.length>0?{warnings:s}:{},sessionStateDir:h(r,`sessionStateDir`),eventLogPath:h(r,`eventLogPath`),appName:h(r,`appName`),appBundleId:a,appId:o,startup:Yr(r.startup),runtime:qr(r.runtime),device:i,identifiers:{session:n,deviceId:i?.id,deviceName:i?.name,udid:i?.ios?.udid,serial:i?.android?.serial,appId:o,appBundleId:a}}},close:async(e={})=>{let t=l(e),n=await c(`close`,e);return{session:t,closedApp:e.app,shutdown:Xr(n.shutdown),savedScript:h(n,`savedScript`),identifiers:{session:t}}},push:async e=>await c(`push`,e),triggerEvent:async e=>await c(`trigger-app-event`,e)},materializations:{release:async e=>Hr(await o(g.releaseMaterializedPaths,[],{...e,materializationId:e.materializationId}))},leases:{allocate:async e=>_i(await o(g.leaseAllocate,[],{...e,leaseId:void 0})),heartbeat:async e=>_i(await o(g.leaseHeartbeat,[],e)),release:async e=>{let t=await o(g.leaseRelease,[],e);return{released:t.released===!0,provider:Z(t.provider)}}},metro:{prepare:async t=>{let n=await Ue({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});return fi(e,n),n},reload:async(t={})=>await He({metroHost:t.metroHost,metroPort:t.metroPort,bundleUrl:t.bundleUrl,runtime:e.runtime??pi(e),timeoutMs:t.timeoutMs})},capture:{snapshot:async(e={})=>{let t=l(e),n=await c(`snapshot`,e);return a(e)?n:li(n,t)},screenshot:async(e={})=>{let t=l(e),n=await c(`screenshot`,e);if(a(e))return n;let r=we(n);return{path:d(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 c(`diff`,e)},interactions:{click:async e=>await c(`click`,e),press:async e=>await c(`press`,e),longPress:async e=>await c(`longpress`,e),swipe:async e=>await c(`swipe`,e),pan:async e=>await c(`gesture`,ni(e)),fling:async e=>await c(`gesture`,ri(e)),swipeGesture:async e=>await c(`gesture`,ii(e)),focus:async e=>await c(`focus`,e),type:async e=>await c(`type`,e),fill:async e=>await c(`fill`,e),scroll:async e=>await c(`scroll`,e),pinch:async e=>await c(`gesture`,ai(e)),rotateGesture:async e=>await c(`gesture`,oi(e)),transformGesture:async e=>await c(`gesture`,si(e)),get:async e=>await c(`get`,e),is:async e=>await c(`is`,e),find:async e=>await c(`find`,e)},replay:{run:async e=>await c(`replay`,e),test:async e=>await c(`test`,e)},batch:{run:async e=>await c(`batch`,e)},observability:{perf:async(e={})=>await c(`perf`,e),logs:async(e={})=>await c(`logs`,e),events:async(e={})=>await c(`events`,e),network:async(e={})=>await c(`network`,e),audio:async(e={})=>await c(`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 c(`record`,e),trace:async e=>await c(`trace`,e)},settings:{update:async e=>await c(`settings`,e)}}}function ni(e){let{x:t,y:n,dx:r,dy:i,...a}=e;return{...a,kind:`pan`,origin:{x:t,y:n},delta:{x:r,y:i}}}function ri(e){let{x:t,y:n,...r}=e;return{...r,kind:`fling`,origin:{x:t,y:n}}}function ii(e){return{...e,kind:`swipe`}}function ai(e){let{x:t,y:n,...r}=e;return ci(t,n,`pinch`),{...r,kind:`pinch`,...t===void 0&&n===void 0?{}:{origin:{x:t,y:n}}}}function oi(e){let{x:t,y:n,...r}=e;return ci(t,n,`rotate`),{...r,kind:`rotate`,...t===void 0&&n===void 0?{}:{origin:{x:t,y:n}}}}function si(e){let{x:t,y:n,dx:r,dy:i,...a}=e;return{...a,kind:`transform`,origin:{x:t,y:n},delta:{x:r,y:i}}}function ci(e,t,r){if(e===void 0!=(t===void 0))throw new n(`INVALID_ARGS`,`gesture ${r} center requires both x and y`)}function li(e,t){let n=h(e,`appBundleId`);return{nodes:Qr(e.nodes),truncated:e.truncated===!0,appName:h(e,`appName`),appBundleId:n,...ui(e),identifiers:{session:t,appId:n,appBundleId:n}}}function ui(e){let t=Z(e.visibility),n=Z(e.unchanged),r=Ce(e.snapshotDiagnostics);return{...t?{visibility:t}:{},...Fe(e),...n?{unchanged:n}:{},...r?{snapshotDiagnostics:r}:{},...typeof e.refsGeneration==`number`?{refsGeneration:e.refsGeneration}:{}}}function di(e){let t={};for(let[n,r]of Object.entries(Le.clientCommandMethods??{}))t[n]=async(t={})=>await e(r,t);let n=t.orientation;if(!n)throw Error(`orientation client method missing from the system command family`);return t.rotate=async(e={})=>({...await n(e),action:`rotate`}),t}function Z(e){return m(e)?e:void 0}function Q(e,t){return{...e,...t}}function $(e,t={}){let n=Q(e,t);return{stateDir:x(n.stateDir??process.env.AGENT_DEVICE_STATE_DIR).baseDir,session:X(n.session)}}function fi(e,t){try{let n=new URL(t.statusUrl),r=Number.parseInt(n.port,10);if(!n.hostname||!Number.isInteger(r))return;let i=t.bridge?void 0:t.iosRuntime.bundleUrl??t.androidRuntime.bundleUrl;Mr({...$(e),hints:{metroHost:n.hostname,metroPort:r,bundleUrl:i}})}catch{}}function pi(e){try{return Nr($(e))}catch{return}}function mi(e){if(!e)return;let{metroHost:t,metroPort:n,bundleUrl:r}=e;if(!(t===void 0&&n===void 0&&r===void 0))return{metroHost:t,metroPort:n,bundleUrl:r}}function hi(e){try{let t=$(e.config,e.options),n=mi(e.runtime);if(n){Mr({...t,hints:n});return}e.sessionReused||Pr(t)}catch{}}function gi(e,t){try{Pr($(e,t))}catch{}}function _i(e){let t=e.lease;if(!m(t))throw Error(`Invalid lease response from daemon`);return{leaseId:d(t,`leaseId`),tenantId:d(t,`tenantId`),runId:d(t,`runId`),backend:d(t,`backend`),leaseProvider:h(t,`leaseProvider`),clientId:h(t,`clientId`),deviceKey:h(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{tr as a,Er as i,ti as n,Yn as o,zr as r,ei as t};
|
|
3
|
+
`)}function ei(e){return e===s.install||e===s.reinstall||e===l.installSource}function X(e,t){return C.join(e,`metro-sessions`,`${Se(t)}.json`)}function ti(e){let t=X(e.stateDir,e.session);w.mkdirSync(C.dirname(t),{recursive:!0}),w.writeFileSync(t,`${JSON.stringify(e.hints,null,2)}\n`,`utf8`)}function ni(e){let t=X(e.stateDir,e.session),n;try{n=w.readFileSync(t,`utf8`)}catch{return}let r;try{r=JSON.parse(n)}catch{return}if(!r||typeof r!=`object`||Array.isArray(r))return;let i=r,a={};return typeof i.metroHost==`string`&&i.metroHost&&(a.metroHost=i.metroHost),typeof i.metroPort==`number`&&Number.isInteger(i.metroPort)&&(a.metroPort=i.metroPort),typeof i.bundleUrl==`string`&&i.bundleUrl&&(a.bundleUrl=i.bundleUrl),Object.keys(a).length>0?a:void 0}function ri(e){w.rmSync(X(e.stateDir,e.session),{force:!0})}var ii=e({createAgentDeviceClient:()=>ai});function ai(e={},t={}){let n=t.transport??Gr,o=t=>i(t.responseLevel??e.responseLevel),s=async(t,r=[],i={},o,s)=>{let c=Q(e,i),l={session:A(c.session),command:t,positionals:r,...s?{input:s}:{},flags:Le(c,o),runtime:c.runtime,meta:dt(c)},u=await n(l,{authToken:c.daemonAuthToken});return u.ok||a(u.error),u.data??{}},c=async(e={})=>{let t=await s(l.sessionList,[],e);return(Array.isArray(t.sessions)?t.sessions:[]).map(nt)},u=async(e,t={})=>{let n=mt(e,t);return await s(n.command,n.positionals,n.options,n.metadataFlags,n.input)},d=(t={})=>A(Q(e,t).session);return{command:{wait:async e=>await u(`wait`,e),alert:async(e={})=>await u(`alert`,e),...hi(u),reactNative:async e=>await u(`react-native`,e),doctor:async(e={})=>await u(`doctor`,e),prepare:async e=>await u(`prepare`,e),viewport:async e=>await u(`viewport`,e)},devices:{list:async(e={})=>{let t=await u(`devices`,e);return(Array.isArray(t.devices)?t.devices:[]).map(tt)},capabilities:async(e={})=>{let t=await u(`capabilities`,e),n=Array.isArray(t.availableCommands)?t.availableCommands.filter(e=>typeof e==`string`):[];return{device:tt(t.device),availableCommands:n}},boot:async(e={})=>await u(`boot`,e),shutdown:async(e={})=>await u(`shutdown`,e)},sessions:{list:async(e={})=>await c(e),stateDir:async(t={})=>y(Q(e,t).stateDir??process.env.AGENT_DEVICE_STATE_DIR).baseDir,close:async(t={})=>{let n=d(t);try{let e=await u(`close`,t);return{session:n,shutdown:ct(e.shutdown),provider:Z(e.provider),savedScript:m(e,`savedScript`),identifiers:{session:n}}}finally{bi(e,t)}},saveScript:async(e={})=>{let t=await s(l.sessionSaveScript,e.path===void 0?[]:[e.path],e,{force:e.force}),n=t.actionCount;if(typeof n!=`number`||!Number.isInteger(n)||n<0)throw new r(`COMMAND_FAILED`,`Daemon returned an invalid saved-script action count.`);let i=h(t,`session`);return{session:i,savedScript:h(t,`savedScript`),actionCount:n,identifiers:{session:i}}},artifacts:async(e={})=>await u(`artifacts`,e)},apps:{install:async e=>Qe(await u(`install`,e),d(e)),reinstall:async e=>Qe(await u(`reinstall`,e),d(e)),installFromSource:async e=>$e(await u(`install-from-source`,e),d(e)),list:async(e={})=>{let t=await u(`apps`,e);return Array.isArray(t.apps)?t.apps.filter(e=>typeof e==`string`):[]},open:async t=>{let n=d(t),r=await u(`open`,t);yi({config:e,options:t,runtime:Q(e,t).runtime,sessionReused:r.sessionReused===!0});let i=ot(r),a=m(r,`appBundleId`),o=a,s=Array.isArray(r.warnings)?r.warnings.filter(e=>typeof e==`string`):[];return{session:n,...s.length>0?{warnings:s}:{},sessionStateDir:m(r,`sessionStateDir`),eventLogPath:m(r,`eventLogPath`),appName:m(r,`appName`),appBundleId:a,appId:o,startup:st(r.startup),runtime:at(r.runtime),device:i,identifiers:{session:n,deviceId:i?.id,deviceName:i?.name,udid:i?.ios?.udid,serial:i?.android?.serial,appId:o,appBundleId:a}}},close:async(e={})=>{let t=d(e),n=await u(`close`,e);return{session:t,closedApp:e.app,shutdown:ct(n.shutdown),savedScript:m(n,`savedScript`),identifiers:{session:t}}},push:async e=>await u(`push`,e),triggerEvent:async e=>await u(`trigger-app-event`,e)},materializations:{release:async e=>et(await s(l.releaseMaterializedPaths,[],{...e,materializationId:e.materializationId}))},leases:{allocate:async e=>xi(await s(l.leaseAllocate,[],{...e,leaseId:void 0})),heartbeat:async e=>xi(await s(l.leaseHeartbeat,[],e)),release:async e=>{let t=await s(l.leaseRelease,[],e);return{released:t.released===!0,provider:Z(t.provider)}}},metro:{prepare:async t=>{let n=await Ke({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});return gi(e,n),n},reload:async(t={})=>await Ge({metroHost:t.metroHost,metroPort:t.metroPort,bundleUrl:t.bundleUrl,runtime:e.runtime??_i(e),timeoutMs:t.timeoutMs})},capture:{snapshot:async(e={})=>{let t=d(e),n=await u(`snapshot`,e);return o(e)?n:pi(n,t)},screenshot:async(e={})=>{let t=d(e),n=await u(`screenshot`,e);if(o(e))return n;let r=xe(n);return{path:h(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 u(`diff`,e)},interactions:{click:async e=>await u(`click`,e),press:async e=>await u(`press`,e),longPress:async e=>await u(`longpress`,e),swipe:async e=>await u(`swipe`,e),pan:async e=>await u(`gesture`,oi(e)),fling:async e=>await u(`gesture`,si(e)),swipeGesture:async e=>await u(`gesture`,ci(e)),focus:async e=>await u(`focus`,e),type:async e=>await u(`type`,e),fill:async e=>await u(`fill`,e),scroll:async e=>await u(`scroll`,e),pinch:async e=>await u(`gesture`,li(e)),rotateGesture:async e=>await u(`gesture`,ui(e)),transformGesture:async e=>await u(`gesture`,di(e)),get:async e=>await u(`get`,e),is:async e=>await u(`is`,e),find:async e=>await u(`find`,e)},replay:{run:async e=>await u(`replay`,e),test:async e=>await u(`test`,e)},batch:{run:async e=>await u(`batch`,e)},observability:{perf:async(e={})=>await u(`perf`,e),logs:async(e={})=>await u(`logs`,e),events:async(e={})=>await u(`events`,e),network:async(e={})=>await u(`network`,e),audio:async(e={})=>await u(`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 u(`record`,e),trace:async e=>await u(`trace`,e)},settings:{update:async e=>await u(`settings`,e)}}}function oi(e){let{x:t,y:n,dx:r,dy:i,...a}=e;return{...a,kind:`pan`,origin:{x:t,y:n},delta:{x:r,y:i}}}function si(e){let{x:t,y:n,...r}=e;return{...r,kind:`fling`,origin:{x:t,y:n}}}function ci(e){return{...e,kind:`swipe`}}function li(e){let{x:t,y:n,...r}=e;return fi(t,n,`pinch`),{...r,kind:`pinch`,...t===void 0&&n===void 0?{}:{origin:{x:t,y:n}}}}function ui(e){let{x:t,y:n,...r}=e;return fi(t,n,`rotate`),{...r,kind:`rotate`,...t===void 0&&n===void 0?{}:{origin:{x:t,y:n}}}}function di(e){let{x:t,y:n,dx:r,dy:i,...a}=e;return{...a,kind:`transform`,origin:{x:t,y:n},delta:{x:r,y:i}}}function fi(e,t,n){if(e===void 0!=(t===void 0))throw new r(`INVALID_ARGS`,`gesture ${n} center requires both x and y`)}function pi(e,t){let n=m(e,`appBundleId`);return{nodes:ut(e.nodes),truncated:e.truncated===!0,appName:m(e,`appName`),appBundleId:n,...mi(e),identifiers:{session:t,appId:n,appBundleId:n}}}function mi(e){let t=Z(e.visibility),n=Z(e.unchanged),r=fe(e.snapshotDiagnostics);return{...t?{visibility:t}:{},...ee(e),...n?{unchanged:n}:{},...r?{snapshotDiagnostics:r}:{},...typeof e.refsGeneration==`number`?{refsGeneration:e.refsGeneration}:{}}}function hi(e){let t={};for(let[n,r]of Object.entries(Ne.clientCommandMethods??{}))t[n]=async(t={})=>await e(r,t);let n=t.orientation;if(!n)throw Error(`orientation client method missing from the system command family`);return t.rotate=async(e={})=>({...await n(e),action:`rotate`}),t}function Z(e){return g(e)?e:void 0}function Q(e,t){return{...e,...t}}function $(e,t={}){let n=Q(e,t);return{stateDir:y(n.stateDir??process.env.AGENT_DEVICE_STATE_DIR).baseDir,session:A(n.session)}}function gi(e,t){try{let n=new URL(t.statusUrl),r=Number.parseInt(n.port,10);if(!n.hostname||!Number.isInteger(r))return;let i=t.bridge?void 0:t.iosRuntime.bundleUrl??t.androidRuntime.bundleUrl;ti({...$(e),hints:{metroHost:n.hostname,metroPort:r,bundleUrl:i}})}catch{}}function _i(e){try{return ni($(e))}catch{return}}function vi(e){if(!e)return;let{metroHost:t,metroPort:n,bundleUrl:r}=e;if(!(t===void 0&&n===void 0&&r===void 0))return{metroHost:t,metroPort:n,bundleUrl:r}}function yi(e){try{let t=$(e.config,e.options),n=vi(e.runtime);if(n){ti({...t,hints:n});return}e.sessionReused||ri(t)}catch{}}function bi(e,t){try{ri($(e,t))}catch{}}function xi(e){let t=e.lease;if(!g(t))throw Error(`Invalid lease response from daemon`);return{leaseId:h(t,`leaseId`),tenantId:h(t,`tenantId`),runId:h(t,`runId`),backend:h(t,`backend`),leaseProvider:m(t,`leaseProvider`),clientId:m(t,`clientId`),deviceKey:m(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{hr as a,xr as i,ai as n,Gr as r,ii as t};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { a as createAndroidPortReverseManager, i as AndroidPortReverseEndpoint, n as AndroidAdbExecutorOptions, r as AndroidAdbProvider, t as AndroidAdbExecutor } from "./sdk-android-adb.js";
|
|
2
|
-
import { t as AppsFilter } from "./
|
|
2
|
+
import { t as AppsFilter } from "./app-inventory.js";
|
|
3
3
|
import { a as readAndroidClipboardWithAdb, i as getAndroidKeyboardStatusWithAdb, n as AndroidKeyboardState, o as writeAndroidClipboardWithAdb, r as dismissAndroidKeyboardWithAdb, t as AndroidKeyboardDismissResult } from "./device-input-state.js";
|
|
4
4
|
import fs from "node:fs";
|
|
5
5
|
//#region src/platforms/android/app-parsers.d.ts
|
package/dist/src/android.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{o as e}from"./png-worker-contract.js";import{_ as t}from"./sdk-contracts.js";import{i as n,l as r,tt as i,u as a}from"./screenshot-geometry.js";import{I as o,d as s,n as c}from"./sdk-android-adb.js";import{t as ee}from"./timeouts.js";import{c as l,d as u,l as d,n as f}from"./app-lifecycle.js";import{a as p}from"./install-artifact.js";import{a as m,s as h}from"./device-input-state.js";import{c as g,d as te,f as _,h as v,i as y,l as b,m as x,n as S,o as C,p as w,r as T,t as E,u as D}from"./input-actions.js";import{f as O}from"./ime-lifecycle.js";import{n as k,r as A,t as j}from"./setting-state.js";import{t as M}from"./method-scope.js";import{promises as N}from"node:fs";const P=[`window_animation_scale`,`transition_animation_scale`,`animator_duration_scale`];async function F(e,i,a,o,s){switch(i.toLowerCase()){case`wifi`:await p(e,[`shell`,`svc`,`wifi`,j(a)?`enable`:`disable`]);return;case`airplane`:{let t=j(a),n=t?`1`:`0`,r=t?`true`:`false`;await p(e,[`shell`,`settings`,`put`,`global`,`airplane_mode_on`,n]),await p(e,[`shell`,`am`,`broadcast`,`-a`,`android.intent.action.AIRPLANE_MODE`,`--ez`,`state`,r]);return}case`location`:if(a.toLowerCase()===`set`){if(e.kind!==`emulator`)throw new t(`UNSUPPORTED_OPERATION`,`Android precise location coordinates are supported only on emulators.`,{deviceId:e.id,hint:`Use an Android emulator for adb emu geo fix, or configure location through device/provider tooling.`});let{latitude:r,longitude:i}=n(s);return await p(e,[`emu`,`geo`,`fix`,String(i),String(r)]),{latitude:r,longitude:i}}await p(e,[`shell`,`settings`,`put`,`secure`,`location_mode`,j(a)?`3`:`0`]);return;case`animations`:{let t=j(a)?`1`:`0`;for(let n of P)await p(e,[`shell`,`settings`,`put`,`global`,n,t]);return{scale:t,keys:[...P]}}case`appearance`:await p(e,[`shell`,`cmd`,`uimode`,`night`,await B(e,a)===`dark`?`yes`:`no`]);return;case`clear-app-state`:{if(a.toLowerCase()!==`clear`)throw new t(`INVALID_ARGS`,`settings clear-app-state only supports clear.`);if(!o)throw new t(`INVALID_ARGS`,`settings clear-app-state requires an app id or an active app session.`);let n=await u(e,o);if(n.type===`intent`)throw new t(`INVALID_ARGS`,`settings clear-app-state requires a package name, not an intent.`);await p(e,[`shell`,`am`,`force-stop`,n.value],{allowFailure:!0});let r=await p(e,[`shell`,`pm`,`clear`,n.value],{allowFailure:!0});if(r.exitCode!==0||!/\bSuccess\b/i.test(r.stdout))throw new t(`COMMAND_FAILED`,`Failed to clear Android app data for ${n.value}`,{package:n.value,stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode});return{package:n.value,cleared:!0}}case`fingerprint`:await L(e,I(a));return;case`permission`:{if(!o)throw new t(`INVALID_ARGS`,`permission setting requires an active app in session`);let n=r(a),i=H(s?.permissionTarget,s?.permissionMode);if(i.kind===`notifications`){await W(e,o,n,i);return}let c=n===`grant`?`grant`:`revoke`;if(i.type===`photos`){let t=await U(e,o,c);n===`reset`&&await G(e,o,t);return}await p(e,[`shell`,`pm`,c,o,i.value]),n===`reset`&&await G(e,o,i.value);return}default:throw new t(`INVALID_ARGS`,`Unsupported setting: ${i}`)}}function I(e){let n=e.trim().toLowerCase();if(n===`match`)return`match`;if(n===`nonmatch`)return`nonmatch`;throw new t(`INVALID_ARGS`,`Invalid fingerprint state: ${e}. Use match|nonmatch.`)}async function L(e,n){let r=R(e,n),i=[];for(let t of r){let n=await p(e,t,{allowFailure:!0});if(n.exitCode===0)return;i.push({args:t,stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode})}let a=A(i);throw i.length>0&&i.every(e=>z(e.stdout,e.stderr))?new t(`UNSUPPORTED_OPERATION`,`Android fingerprint simulation is not supported on this target/runtime.`,{deviceId:e.id,action:n,hint:`Use an Android emulator with biometric support, or a device/runtime that exposes cmd fingerprint.`,attempts:a}):new t(`COMMAND_FAILED`,`Failed to simulate Android fingerprint.`,{deviceId:e.id,action:n,attempts:a})}function R(e,t){let n=t===`match`?`1`:`9999`,r=[[`shell`,`cmd`,`fingerprint`,`touch`,n],[`shell`,`cmd`,`fingerprint`,`finger`,n]];return e.kind===`emulator`&&r.push([`emu`,`finger`,`touch`,n]),r}function z(e,t){let n=`${e}\n${t}`.toLowerCase();return n.includes(`unknown command`)||n.includes(`can't find service: fingerprint`)||n.includes(`service fingerprint was not found`)||n.includes(`fingerprint cmd unavailable`)||n.includes(`emu command is not supported`)||n.includes(`emulator console is not running`)||n.includes(`fingerprint`)&&n.includes(`not found`)}async function B(e,n){let r=k(n);if(r!==`toggle`)return r;let i=await p(e,[`shell`,`cmd`,`uimode`,`night`],{allowFailure:!0});if(i.exitCode!==0)throw c(`Failed to read current Android appearance`,i);let a=V(i.stdout,i.stderr);if(!a)throw new t(`COMMAND_FAILED`,`Unable to determine current Android appearance for toggle`,{stdout:i.stdout,stderr:i.stderr});return a===`auto`?`dark`:a===`dark`?`light`:`dark`}function V(e,t){let n=/night mode:\s*(yes|no|auto)\b/i.exec(`${e}\n${t}`);if(!n)return null;let r=n[1]?.toLowerCase();return r===`yes`?`dark`:r===`no`?`light`:r===`auto`?`auto`:null}function H(e,n){let r=a(e);if(n?.trim())throw new t(`INVALID_ARGS`,`Permission mode is only supported for photos. Received: ${n}.`);if(r===`camera`)return{kind:`pm`,value:`android.permission.CAMERA`,type:`camera`};if(r===`microphone`)return{kind:`pm`,value:`android.permission.RECORD_AUDIO`,type:`microphone`};if(r===`photos`)return{kind:`pm`,value:`android.permission.READ_MEDIA_IMAGES`,type:`photos`};if(r===`contacts`)return{kind:`pm`,value:`android.permission.READ_CONTACTS`,type:`contacts`};if(r===`notifications`)return{kind:`notifications`,appOps:`POST_NOTIFICATION`,permission:`android.permission.POST_NOTIFICATIONS`};throw new t(`INVALID_ARGS`,`Unsupported permission target on Android: ${e}. Use camera|microphone|photos|contacts|notifications.`)}async function U(e,n,r){let i=await K(e),a=i!==null&&i>=33?[`android.permission.READ_MEDIA_IMAGES`,`android.permission.READ_EXTERNAL_STORAGE`]:[`android.permission.READ_EXTERNAL_STORAGE`,`android.permission.READ_MEDIA_IMAGES`],o=[];for(let t of a){let i=await p(e,[`shell`,`pm`,r,n,t],{allowFailure:!0});if(i.exitCode===0)return t;o.push({permission:t,stderr:i.stderr,exitCode:i.exitCode})}throw new t(`COMMAND_FAILED`,`Failed to ${r} Android photos permission`,{appPackage:n,sdkInt:i,attempts:o})}async function W(e,t,n,r){let i=n===`grant`?`allow`:n===`deny`?`deny`:`default`;n===`grant`?await p(e,[`shell`,`pm`,`grant`,t,r.permission],{allowFailure:!0}):(await p(e,[`shell`,`pm`,`revoke`,t,r.permission],{allowFailure:!0}),n===`reset`&&await G(e,t,r.permission)),await p(e,[`shell`,`appops`,`set`,t,r.appOps,i])}async function G(e,t,n){await p(e,[`shell`,`pm`,`clear-permission-flags`,t,n,`user-set`],{allowFailure:!0}),await p(e,[`shell`,`pm`,`clear-permission-flags`,t,n,`user-fixed`],{allowFailure:!0})}async function K(e){let t=await p(e,[`shell`,`getprop`,`ro.build.version.sdk`],{allowFailure:!0});if(t.exitCode!==0)return null;let n=Number.parseInt(t.stdout.trim(),10);return!Number.isFinite(n)||n<=0?null:n}const q=Buffer.from([137,80,78,71,13,10,26,10]);async function J(e,t,n={}){if(n.stabilize===!1){await Z(e,t);return}await Y(e);try{await ee(1e3),await Z(e,t)}finally{await X(e).catch(()=>{})}}async function Y(e){let t=t=>p(e,[`shell`,t],{allowFailure:!0});await t(`settings put global sysui_demo_allowed 1`);let n=e=>t(`am broadcast -a com.android.systemui.demo -e command ${e}`);await n(`clock -e hhmm 0941`),await n(`notifications -e visible false`)}async function X(e){await p(e,[`shell`,`am broadcast -a com.android.systemui.demo -e command exit`],{allowFailure:!0})}async function Z(e,n){let r=await p(e,[`exec-out`,`screencap`,`-p`],{binaryStdout:!0});if(!r.stdoutBuffer)throw new t(`COMMAND_FAILED`,`Failed to capture screenshot`);let i=r.stdoutBuffer.indexOf(q);if(i<0)throw new t(`COMMAND_FAILED`,`Screenshot data does not contain a valid PNG header`);let a=Q(r.stdoutBuffer,i);if(!a)throw new t(`COMMAND_FAILED`,`Screenshot data does not contain a complete PNG payload`);await N.writeFile(n,r.stdoutBuffer.subarray(i,a))}function Q(e,t){let n=t+q.length;for(;n+8<=e.length;){let t=e.readUInt32BE(n),r=n+4,i=e.toString(`ascii`,r,r+4),a=n+12+t;if(a>e.length)return null;if(i===`IEND`)return a;n=a}return null}var ne=e({createAndroidInteractor:()=>$});function $(e,t,n){let r={open:(t,n)=>l(e,t,{activity:n?.activity,appBundleId:n?.appBundleId,launchArgs:n?.launchArgs,url:n?.url}),openDevice:()=>d(e),close:t=>f(e,t),tap:(t,n)=>b(e,t,n),doubleTap:async(t,n)=>{await b(e,t,n),await b(e,t,n)},longPress:(t,n,r)=>g(e,t,n,r),focus:(t,n)=>y(e,t,n),type:(t,n)=>w(e,t,n),fill:(t,n,r,i)=>T(e,t,n,r,i),scroll:(t,n)=>te(e,t,n),performGesture:t=>x(e,t),gestureViewport:()=>v(e),screenshot:(t,n)=>J(e,t,n),snapshot:async t=>{let r=t??{},a=await o(`snapshot_capture`,async()=>await O(e,{appBundleId:r.appBundleId,signal:r.signal??n?.signal,interactiveOnly:r.interactiveOnly,depth:r.depth,scope:r.scope,raw:r.raw,includeHiddenContentHints:r.includeHiddenContentHints,helperSessionScope:r.appBundleId?`daemon-session`:`command`}),{backend:`android`});return{nodes:a.nodes??[],truncated:a.truncated??!1,backend:`android`,...i(a)}},back:t=>S(e),home:()=>C(e),setOrientation:t=>_(e,t),appSwitcher:()=>E(e),tvRemote:(t,n)=>D(e,t,n),readClipboard:()=>m(e),writeClipboard:t=>h(e,t),setSetting:(t,n,r,i)=>F(e,t,n,r,i)};return t?M(r,n=>s(t,{serial:e.id},n)):r}export{$ as n,ne as t};
|
package/dist/src/app-helpers.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{o as e}from"./png-worker-contract.js";import{f as t}from"./device.js";import{n}from"./sdk-android-adb.js";import{a as r,g as i,h as a,m as o}from"./app-lifecycle.js";var s=e({getAndroidAppStateWithAdb:()=>d,listAndroidAppsWithAdb:()=>u});const c=`android.intent.category.LAUNCHER`,l=`android.intent.category.LEANBACK_LAUNCHER`;async function u(e,n={}){let i=await f(e,n.target??`auto`);return(t(n.filter)===`user-installed`?(await g(e)).filter(e=>i.has(e)):Array.from(i)).map(e=>({package:e,name:r(e)})).sort((e,t)=>e.package.localeCompare(t.package))}async function d(e){return await _(e,[[`shell`,`dumpsys`,`window`,`windows`],[`shell`,`dumpsys`,`window`]])||await _(e,[[`shell`,`dumpsys`,`activity`,`activities`],[`shell`,`dumpsys`,`activity`]])||{}}async function f(e,t){let n=(await Promise.all(p(t).map(async t=>{let n=await e(m(t),{allowFailure:!0});return n.exitCode===0?h(n.stdout):[]}))).flat();return new Set(n)}function p(e){switch(e){case`mobile`:return[c];case`tv`:return[l];default:return[c,l]}}function m(e){return[`shell`,`cmd`,`package`,`query-activities`,`--brief`,`-a`,`android.intent.action.MAIN`,`-c`,e]}function h(e){return e.trim().length===0?[]:a(e)}async function g(e){let t=await e([`shell`,`pm`,`list`,`packages`,`-3`],{allowFailure:!0});if(t.exitCode!==0)throw n(`Failed to list Android user-installed apps`,t);return i(t.stdout)}async function _(e,t){for(let n of t){let t=o((await e(n,{allowFailure:!0})).stdout??``);if(t)return t}return null}export{d as n,u as r,s as t};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import{
|
|
2
|
-
`)){let e=n.trim();if(!e)continue;let r=e.split(/\s+/)[0]??``;if(!r.includes(`/`))continue;let i=r.split(`/`)[0]??``;i.includes(`.`)&&i&&t.add(i)}return Array.from(t)}function
|
|
3
|
-
`).map(e=>{let t=e.trim();return t.startsWith(`package:`)?t.slice(8):t}).filter(Boolean)}function
|
|
4
|
-
`);for(let e of
|
|
5
|
-
`).map(e=>e.replace(`package:`,``).trim()).filter(Boolean).filter(e=>e.toLowerCase().includes(r.toLowerCase())),c=s[0];if(c!==void 0&&s.length===1)return
|
|
6
|
-
`).map(e=>e.trim()).filter(Boolean);for(let e=t.length-1;e>=0;--e){let n=t[e];if(n===void 0||!n.includes(`/`))continue;let r=n.split(/\s+/)[0];if(r!==void 0)return r}return null}async function G(e){e.booted||await
|
|
7
|
-
`).map(e=>e.replace(`package:`,``).trim()).filter(Boolean))}async function Ve(e,t){let n=await Z(e),r=Array.from(n).filter(e=>!t.has(e));if(r.length===1)return r[0]}async function Q(e,t){await
|
|
1
|
+
import{o as e}from"./png-worker-contract.js";import{_ as t}from"./sdk-contracts.js";import{s as n}from"./sdk-batch-runner.js";import{_ as r,a as i,c as a,i as o,n as s,v as c,w as ee}from"./sdk-android-adb.js";import{t as l}from"./timeouts.js";import{a as u,c as te,n as d,s as f}from"./install-artifact.js";import p from"node:path";import{promises as m}from"node:fs";import ne from"node:os";const re=[`mCurrentFocus=Window{`,`mFocusedApp=AppWindowToken{`,`mResumedActivity:`,`ResumedActivity:`],ie=/\bApplication Not Responding:\s*([A-Za-z0-9_.]+)/i,ae=/([^{}]*\bis(?:n't| not)\s+responding[^{}]*)/i,oe=/\b([A-Za-z][A-Za-z0-9_]*(?:\.[A-Za-z0-9_]+)+)\b/;function h(e){let t=new Set;for(let n of e.split(`
|
|
2
|
+
`)){let e=n.trim();if(!e)continue;let r=e.split(/\s+/)[0]??``;if(!r.includes(`/`))continue;let i=r.split(`/`)[0]??``;i.includes(`.`)&&i&&t.add(i)}return Array.from(t)}function g(e){return e.split(`
|
|
3
|
+
`).map(e=>{let t=e.trim();return t.startsWith(`package:`)?t.slice(8):t}).filter(Boolean)}function _(e){return v(e,e=>le(e))}function se(e){return v(e,(e,t)=>ce(e,t))}function v(e,t){let n=e.split(`
|
|
4
|
+
`);for(let e of re)for(let r of n){let n=r.indexOf(e);if(n===-1)continue;let i=r.trim(),a=t(r.slice(n+e.length),i);if(a)return a}return null}function ce(e,t){let n=e.split(`}`)[0]?.trim()??e.trim(),r=ie.exec(n);if(r){let e=r[1];return{package:e,focusedWindow:`Application Not Responding: ${e}`,raw:t}}let i=ae.exec(n);if(!i)return null;let a=i[1];if(a===void 0)return null;let o=a.trim().replace(/\s+/g,` `),s=oe.exec(o)?.[1];return{...s?{package:s}:{},focusedWindow:o,raw:t}}function le(e){for(let t of e.trim().split(/\s+/)){let e=t.indexOf(`/`);if(e<=0)continue;let n=y(t.slice(0,e),!1),r=y(t.slice(e+1),!0);if(n&&r&&n.length===e)return{package:n,activity:r}}return null}function y(e,t){let n=0;for(;n<e.length&&ue(e[n],t);)n+=1;return e.slice(0,n)}function ue(e,t){if(!e)return!1;let n=e.charCodeAt(0);return n>=48&&n<=57||n>=65&&n<=90||n>=97&&n<=122||e===`_`||e===`.`||t&&e===`$`}const de=/\.(?:apk|aab)$/i,fe=/^[A-Za-z_][\w]*(\.[A-Za-z_][\w]*)+$/;function b(e){let t=e.trim();return t.length===0?`other`:de.test(t)?t.includes(`/`)||t.includes(`\\`)||t.startsWith(`.`)||t.startsWith(`~`)||!x(t)?`binary`:`package`:x(t)?`package`:`other`}function x(e){return fe.test(e)}function pe(e){return`Android runtime hints require an installed package name, not "${e}". Install or reinstall the app first, then relaunch by package.`}var me=e({closeAndroidApp:()=>K,getAndroidAppState:()=>M,getAndroidBlockingDialogFocus:()=>N,inferAndroidAppName:()=>j,installAndroidApp:()=>He,installAndroidInstallablePath:()=>Q,installAndroidInstallablePathAndResolvePackageName:()=>$,isAmStartError:()=>U,listAndroidApps:()=>k,openAndroidApp:()=>R,openAndroidDevice:()=>G,parseAndroidLaunchComponent:()=>W,reinstallAndroidApp:()=>Ue,resolveAndroidApp:()=>O});const he={settings:{type:`intent`,value:`android.settings.SETTINGS`}},S=`android.intent.category.LAUNCHER`,C=`android.intent.category.LEANBACK_LAUNCHER`,w=`android.intent.category.DEFAULT`,T=`Run agent-device apps --platform android to discover the installed package name, then retry open with that exact package.`,ge=new Set([`localhost`,`127.0.0.1`,`::1`,`[::1]`]),E=te();function D(e){return{platform:`android`,deviceId:e.id,variant:e.target??``}}async function O(e,n){let r=n.trim();if(b(r)===`package`)return{type:`package`,value:r};let i=he[r.toLowerCase()];if(i)return i;let a=D(e),o=E.get(a,r);if(o)return o;let s=(await u(e,[`shell`,`pm`,`list`,`packages`])).stdout.split(`
|
|
5
|
+
`).map(e=>e.replace(`package:`,``).trim()).filter(Boolean).filter(e=>e.toLowerCase().includes(r.toLowerCase())),c=s[0];if(c!==void 0&&s.length===1)return E.set(a,r,{type:`package`,value:c});throw s.length>1?new t(`INVALID_ARGS`,`Multiple packages matched "${n}"`,{matches:s,hint:`Run agent-device apps --platform android to see the exact installed package names before retrying open.`}):new t(`APP_NOT_INSTALLED`,`No package found matching "${n}"`,{hint:T})}async function k(e,t){let n=await _e(e);return(t===`user-installed`?(await ye(e)).filter(e=>n.has(e)):Array.from(n)).sort((e,t)=>e.localeCompare(t)).map(e=>({package:e,name:j(e)}))}async function _e(e){let t=new Set;for(let n of A(e,{includeFallbackWhenUnknown:!0})){let r=await u(e,[`shell`,`cmd`,`package`,`query-activities`,`--brief`,`-a`,`android.intent.action.MAIN`,`-c`,n],{allowFailure:!0});if(!(r.exitCode!==0||r.stdout.trim().length===0))for(let e of h(r.stdout))t.add(e)}return t}function ve(e){return A(e)[0]??S}function A(e,t={}){return e.target===`tv`?[C]:e.target===`mobile`?[S]:t.includeFallbackWhenUnknown?[S,C]:[S]}async function ye(e){return g((await u(e,[`shell`,`pm`,`list`,`packages`,`-3`])).stdout)}function j(e){let t=new Set([`com`,`android`,`google`,`app`,`apps`,`service`,`services`,`mobile`,`client`]),n=e.split(`.`).flatMap(e=>e.split(/[_-]+/)).map(e=>e.trim().toLowerCase()).filter(e=>e.length>0),r=n[n.length-1]??e;for(let e=n.length-1;e>=0;--e){let i=n[e];if(i&&!t.has(i)){r=i;break}}return r.split(/[^a-z0-9]+/i).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(` `)}async function M(e){return await P(e,[[`shell`,`dumpsys`,`window`,`windows`],[`shell`,`dumpsys`,`window`]])||await P(e,[[`shell`,`dumpsys`,`activity`,`activities`],[`shell`,`dumpsys`,`activity`]])||{}}async function N(e){return await be(e,[[`shell`,`dumpsys`,`window`,`windows`],[`shell`,`dumpsys`,`window`]])}async function P(e,t){for(let n of t){let t=_((await u(e,n,{allowFailure:!0})).stdout??``);if(t)return t}return null}async function be(e,t){for(let n of t){let t=se((await u(e,n,{allowFailure:!0})).stdout??``);if(t)return t}return null}function xe(e){let t;try{t=new URL(e)}catch{return null}let n=t.hostname.toLowerCase();if(!ge.has(n)||!t.port)return null;let r=Number(t.port);return Number.isInteger(r)?`tcp:${r}`:null}async function F(e,n){let r=xe(n);if(!r)return;let i=o(a(e));try{await i.ensure({local:r,remote:r})}catch(e){let n={localPort:r.replace(`tcp:`,``),operation:`adb reverse ${r} ${r}`};throw e instanceof t&&Object.assign(n,{hint:e.details?.hint,diagnosticId:e.details?.diagnosticId,logPath:e.details?.logPath}),new t(`COMMAND_FAILED`,`Failed to ensure Android port reverse ${r} before opening localhost URL`,n,e)}}function I(e){return/^[A-Za-z0-9_@%+=:,./-]+$/.test(e)?e:`'${e.replace(/'/g,`'\\''`)}'`}function L(e){return(e.launchArgs??[]).map(I)}async function R(e,t,r){e.booted||await f(e.id);let i=Oe(r),a=i.activity,o=t.trim();if(n(o)){await Se(e,o,i);return}if(i.url!==void 0){await Ce(e,t,i);return}let s=await O(e,t),c=ve(e);if(s.type===`intent`){await we(e,s.value,i);return}if(a){await Te(e,s.value,a,c,i);return}await Ee(e,s.value,c,i)}async function Se(e,n,r){if(r.activity)throw new t(`INVALID_ARGS`,`Activity override is not supported when opening a deep link URL`);await F(e,n),await u(e,[`shell`,`am`,`start`,`-W`,`-a`,`android.intent.action.VIEW`,`-d`,I(n),...ke(r.appBundleId),...L(r)])}async function Ce(e,r,i){if(i.activity)throw new t(`INVALID_ARGS`,`Activity override is not supported when opening an app-bound deep link URL`);let a=i.url?.trim()??``;if(!n(a))throw new t(`INVALID_ARGS`,`Android app-bound open requires a valid URL target`);await F(e,a);let o=await De(e,r,`app-bound open`);await u(e,[`shell`,`am`,`start`,`-W`,`-a`,`android.intent.action.VIEW`,`-d`,I(a),`-p`,o,...L(i)])}async function we(e,n,r){if(r.activity)throw new t(`INVALID_ARGS`,`Activity override requires a package name, not an intent`);await u(e,[`shell`,`am`,`start`,`-W`,`-a`,n,...L(r)])}async function Te(e,t,n,r,i){let a=n.includes(`/`)?n:`${t}/${n.startsWith(`.`)?n:`.${n}`}`;try{await u(e,z(a,r,i))}catch(n){throw await Ae(e,t,n),n}}async function Ee(e,t,n,r){let i=await u(e,[`shell`,`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,w,`-c`,n,`-p`,t,...L(r)],{allowFailure:!0});if(i.exitCode===0&&!U(i.stdout,i.stderr))return;let a=await je(e,t);if(!a)throw await V(e,t)?s(`Failed to launch ${t}`,i):B(t);await u(e,z(a,n,r))}function z(e,t,n){return[`shell`,`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,w,`-c`,t,`-n`,e,...L(n)]}async function De(e,n,r){let i=await O(e,n);if(i.type===`intent`)throw new t(`INVALID_ARGS`,`Android ${r} requires a package name, not an intent`);return i.value}function Oe(e){return typeof e==`string`?{activity:e}:e??{}}function ke(e){let t=e?.trim();return t?[`-p`,t]:[]}function B(e){return new t(`APP_NOT_INSTALLED`,`No package found matching "${e}"`,{package:e,hint:T})}async function V(e,t){let n=await u(e,[`shell`,`pm`,`path`,t],{allowFailure:!0}),r=`${n.stdout}\n${n.stderr}`;return n.exitCode===0&&/\bpackage:/i.test(r)?!0:(H(r),!1)}async function Ae(e,n,r){if(H(r instanceof t?`${String(r.details?.stdout??``)}\n${String(r.details?.stderr??``)}`:``)||!await V(e,n))throw B(n)}function H(e){return/\bunknown package\b/i.test(e)||/\bpackage .* (?:was|is) not found\b/i.test(e)||/\bpackage .* does not exist\b/i.test(e)||/\bcould not find package\b/i.test(e)}async function je(e,t){let n=Array.from(new Set(A(e,{includeFallbackWhenUnknown:!0})));for(let r of n){let n=await u(e,[`shell`,`cmd`,`package`,`resolve-activity`,`--brief`,`-a`,`android.intent.action.MAIN`,`-c`,r,t],{allowFailure:!0});if(n.exitCode!==0)continue;let i=W(n.stdout);if(i)return i}return null}function U(e,t){let n=`${e}\n${t}`;return/Error:.*(?:Activity not started|unable to resolve Intent)/i.test(n)}function W(e){let t=e.split(`
|
|
6
|
+
`).map(e=>e.trim()).filter(Boolean);for(let e=t.length-1;e>=0;--e){let n=t[e];if(n===void 0||!n.includes(`/`))continue;let r=n.split(/\s+/)[0];if(r!==void 0)return r}return null}async function G(e){e.booted||await f(e.id)}async function K(e,n){if(n.trim().toLowerCase()===`settings`){await u(e,[`shell`,`am`,`force-stop`,`com.android.settings`]),await q(e,`com.android.settings`);return}let r=await O(e,n);if(r.type===`intent`)throw new t(`INVALID_ARGS`,`Close requires a package name, not an intent`);await u(e,[`shell`,`am`,`force-stop`,r.value]),await q(e,r.value)}async function q(e,t){await Me(e,t),await Pe(e,t)}async function Me(e,t){let n=Date.now()+2e3;for(;Date.now()<n;){if((await Ne(e))?.package!==t)return;await l(50)}}async function Ne(e){for(let t of[[`shell`,`dumpsys`,`window`,`windows`],[`shell`,`dumpsys`,`window`],[`shell`,`dumpsys`,`activity`,`activities`],[`shell`,`dumpsys`,`activity`]]){let n=_((await u(e,t,{allowFailure:!0})).stdout??``);if(n)return n}return null}async function Pe(e,t){let n=Date.now()+2e3;for(;Date.now()<n;){if(!await J(e,t)&&(await l(150),!await J(e,t)))return;await l(50)}}async function J(e,t){return((await u(e,[`shell`,`pidof`,t],{allowFailure:!0})).stdout??``).trim().length>0}async function Fe(e,n){let r=await O(e,n);if(r.type===`intent`)throw new t(`INVALID_ARGS`,`App uninstall requires a package name, not an intent`);let i=await u(e,[`uninstall`,r.value],{allowFailure:!0});if(i.exitCode!==0){let e=`${i.stdout}\n${i.stderr}`.toLowerCase();if(!e.includes(`unknown package`)&&!e.includes(`not installed`))throw s(`adb uninstall failed for ${r.value}`,i)}return{package:r.value}}let Y=null;function Ie(){return`${process.env.PATH??``}::${process.env.AGENT_DEVICE_BUNDLETOOL_JAR??``}`}async function Le(){let e=Ie();if(Y?.key===e)return Y.invocation;if(await ee(`bundletool`)){let t={cmd:`bundletool`,prefixArgs:[]};return Y={key:e,invocation:t},t}let n=await r(process.env.AGENT_DEVICE_BUNDLETOOL_JAR,`AGENT_DEVICE_BUNDLETOOL_JAR`);if(!n)throw new t(`TOOL_MISSING`,`bundletool not found in PATH. Install bundletool or set AGENT_DEVICE_BUNDLETOOL_JAR to a bundletool-all.jar path.`);let i={cmd:`java`,prefixArgs:[`-jar`,n]};return Y={key:e,invocation:i},i}async function X(e){let t=await Le();await c(t.cmd,[...t.prefixArgs,...e])}function Re(e){return p.extname(e).toLowerCase()===`.aab`}async function ze(e,t){let n=a(e),r=`universal`;if(n.installBundle){await n.installBundle(t,{mode:r});return}let i=await m.mkdtemp(p.join(ne.tmpdir(),`agent-device-aab-`)),o=p.join(i,`bundle.apks`);try{await X([`build-apks`,`--bundle`,t,`--output`,o,`--mode`,r]),await X([`install-apks`,`--apks`,o,`--device-id`,e.id])}finally{await m.rm(i,{recursive:!0,force:!0})}}async function Be(e,t){if(Re(t)){await ze(e,t);return}await i(t,{device:e,replace:!0})}async function Z(e){let t=await u(e,[`shell`,`pm`,`list`,`packages`]);return new Set(t.stdout.split(`
|
|
7
|
+
`).map(e=>e.replace(`package:`,``).trim()).filter(Boolean))}async function Ve(e,t){let n=await Z(e),r=Array.from(n).filter(e=>!t.has(e));if(r.length===1)return r[0]}async function Q(e,t){await E.invalidateWhile(D(e),async()=>{e.booted||await f(e.id),await Be(e,t)})}async function $(e,t,n){let r=n?void 0:await Z(e);return await Q(e,t),n??(r?await Ve(e,r):void 0)}async function He(e,t){e.booted||await f(e.id);let n=await d({kind:`path`,path:t});try{let t=await $(e,n.installablePath,n.packageName),r=t?j(t):void 0;return{archivePath:n.archivePath,installablePath:n.installablePath,packageName:t,appName:r,launchTarget:t}}finally{await n.cleanup()}}async function Ue(e,t,n){return await E.invalidateWhile(D(e),async()=>{e.booted||await f(e.id);let{package:r}=await Fe(e,t),i=await d({kind:`path`,path:n},{resolveIdentity:!1});try{await Q(e,i.installablePath)}finally{await i.cleanup()}return{package:r}})}export{j as a,R as c,O as d,b as f,g,h,N as i,G as l,_ as m,K as n,U as o,pe as p,M as r,k as s,me as t,W as u};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{o as e}from"./png-worker-contract.js";import{_ as t}from"./sdk-contracts.js";import{s as n}from"./sdk-batch-runner.js";import{c as r,s as i}from"./sdk-device.js";import{c as a}from"./install-artifact.js";import{n as o}from"./setting-state.js";import{i as s,r as c,s as l}from"./tool-provider.js";import{n as u}from"./helper.js";import{a as d,t as f}from"./physical-device-control.js";import p from"node:path";import{fileURLToPath as m}from"node:url";const h={settings:`com.apple.systempreferences`},g=/^[a-z0-9-]+(?:\.[a-z0-9-]+)+$/,_={platform:`macos`,deviceId:`host`,variant:`all`},v=a();function y(e){return g.test(e)}async function b(e){let n=e.trim(),r=h[n.toLowerCase()];if(r)return r;if(y(n))return n;let i=v.get(_,n);if(i)return i;let a=(await D(`all`)).filter(e=>e.name.toLowerCase()===n.toLowerCase()),o=a[0];if(o!==void 0&&a.length===1)return v.set(_,n,o.bundleId);throw a.length>1?new t(`INVALID_ARGS`,`Multiple apps matched "${e}"`,{matches:a}):new t(`APP_NOT_INSTALLED`,`No app found matching "${e}"`)}async function x(e,r,i){let a=i?.url?.trim();if(a){if(!n(a))throw new t(`INVALID_ARGS`,`open <app> <url> requires a valid URL target`);let e=i?.appBundleId??await b(r);await O().openBundle(e,a);return}let o=r.trim();if(n(o)){await O().openTarget(o);return}let s=i?.appBundleId??await b(o);await O().openBundle(s)}async function S(e,n){let r=await b(n),i=await u(r);if(!(!i.running||i.terminated||i.forceTerminated))throw new t(`COMMAND_FAILED`,`Failed to close macOS app ${n}`,{bundleId:r,running:i.running,terminated:i.terminated,forceTerminated:i.forceTerminated})}async function C(){return await O().readClipboard()}async function w(e){await O().writeClipboard(e)}async function T(){return await O().readDarkMode()}async function E(e){let t=o(e),n=t===`toggle`?!await T():t===`dark`;await O().setDarkMode(n)}async function D(e){return await O().listApps(e)}function O(){let e=c().macosHost;if(!e)throw new t(`UNSUPPORTED_OPERATION`,`macOS host provider is not available`);return e}var k=e({buildAppNotInstalledError:()=>F,findIosSimulatorInstalledApp:()=>I,invalidateIosAppResolutionCache:()=>N,listIosApps:()=>B,resolveIosApp:()=>P,resolveIosAppAlias:()=>L,resolveIosSimulatorDeepLinkBundleId:()=>R});const A={settings:`com.apple.Preferences`},j=a();function M(e){return{platform:`ios`,deviceId:e.id,variant:e.kind}}async function N(e,t){return await j.invalidateWhile(M(e),t)}async function P(e,n){if(r(e))return await b(n);let i=n.trim();if(i.includes(`.`))return i;let a=L(i);if(a!==i)return a;let o=M(e),s=j.get(o,i);if(s)return s;let c=(e.kind===`simulator`?await V(e):await f(e).listApps(e,`all`)).filter(e=>e.name.toLowerCase()===i.toLowerCase()),l=c[0];if(l!==void 0&&c.length===1)return j.set(o,i,l.bundleId);throw c.length>1?new t(`INVALID_ARGS`,`Multiple apps matched "${n}"`,{matches:c}):F(n)}function F(e){return new t(`APP_NOT_INSTALLED`,`No app found matching "${e}"`)}async function I(e,t){if(!i(e)||e.kind!==`simulator`||e.booted!==!0)return;let n=L(t.trim());if(!n)return;let r=await V(e);if(n.includes(`.`))return r.find(e=>e.bundleId===n)?.bundleId;let a=r.filter(e=>e.name.toLowerCase()===n.toLowerCase());return a.length===1?a[0]?.bundleId:void 0}function L(e){let t=e.trim();return A[t.toLowerCase()]??e}async function R(e,t){if(!i(e)||e.kind!==`simulator`)return;let n=z(t);if(!n)return;let r=await H(e),a=[];for(let e of r)e.bundleId.startsWith(`com.callstack.agentdevice.runner`)||e.path&&(await W(p.join(e.path,`Info.plist`))).has(n)&&a.push(e);let o=a.filter(e=>e.applicationType===`User`);if(o.length===1)return o[0]?.bundleId;if(!(o.length>1))return a.length===1?a[0]?.bundleId:void 0}function z(e){return/^([A-Za-z][A-Za-z0-9+.-]*):/.exec(e.trim())?.[1]?.toLowerCase()}async function B(e,t){return r(e)?await D(t):e.kind===`simulator`?l(await V(e),t):await f(e).listApps(e,t)}async function V(e){return(await H(e)).map(e=>({bundleId:e.bundleId,name:e.name}))}async function H(e){let t=(await d(e,[`listapps`,e.id],{allowFailure:!0})).stdout.trim();if(!t)return[];let n=null;if(t.startsWith(`{`))try{n=JSON.parse(t)}catch{n=null}if(!n&&t.startsWith(`{`))try{let e=await s(`plutil`,[`-convert`,`json`,`-o`,`-`,`-`],{allowFailure:!0,stdin:t});e.exitCode===0&&e.stdout.trim().startsWith(`{`)&&(n=JSON.parse(e.stdout))}catch{n=null}return n?Object.entries(n).map(([e,t])=>{let n=U(t);return{bundleId:e,name:t.CFBundleDisplayName??t.CFBundleName??e,...n?{path:n}:{},...t.ApplicationType?{applicationType:t.ApplicationType}:{}}}):[]}function U(e){if(e.Path)return e.Path;if(e.Bundle)try{return m(e.Bundle)}catch{return}}async function W(e){let t=await s(`plutil`,[`-convert`,`json`,`-o`,`-`,e],{allowFailure:!0});if(t.exitCode!==0)return new Set;try{let e=JSON.parse(t.stdout),n=new Set;for(let t of e.CFBundleURLTypes??[])if(Array.isArray(t.CFBundleURLSchemes))for(let e of t.CFBundleURLSchemes)typeof e==`string`&&e.trim()&&n.add(e.trim().toLowerCase());return n}catch{return new Set}}export{P as a,x as c,w as d,B as i,C as l,I as n,R as o,N as r,S as s,k as t,E as u};
|