agent-device 0.17.2 → 0.17.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/README.md +2 -2
- package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.17.2.apk → agent-device-android-multitouch-helper-0.17.4.apk} +0 -0
- package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.17.4.apk.sha256 +1 -0
- package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.17.2.manifest.json → agent-device-android-multitouch-helper-0.17.4.manifest.json} +4 -4
- package/android-snapshot-helper/README.md +3 -0
- package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.17.2.apk → agent-device-android-snapshot-helper-0.17.4.apk} +0 -0
- package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.17.4.apk.sha256 +1 -0
- package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.17.2.manifest.json → agent-device-android-snapshot-helper-0.17.4.manifest.json} +6 -6
- package/dist/src/123.js +1 -1
- package/dist/src/1231.js +1 -1
- package/dist/src/1352.js +1 -1
- package/dist/src/221.js +2 -2
- package/dist/src/2403.js +3 -3
- package/dist/src/2415.js +37 -29
- package/dist/src/4012.js +4 -0
- package/dist/src/5611.js +1 -0
- package/dist/src/5827.js +1 -0
- package/dist/src/6088.js +1 -0
- package/dist/src/6133.js +1 -0
- package/dist/src/7847.js +1 -1
- package/dist/src/9471.js +1 -1
- package/dist/src/9542.js +6 -3
- package/dist/src/9616.js +2 -1
- package/dist/src/9818.js +1 -1
- package/dist/src/android-snapshot-helper.d.ts +0 -1
- package/dist/src/android.js +5 -5
- package/dist/src/apple.js +1 -1
- package/dist/src/apps.js +10 -10
- package/dist/src/args.js +53 -14
- package/dist/src/batch.js +1 -1
- package/dist/src/cli-output.js +30 -0
- package/dist/src/cli.js +15 -16
- package/dist/src/command-surface.js +1 -1
- package/dist/src/contracts.d.ts +52 -0
- package/dist/src/contracts.js +1 -1
- package/dist/src/find.js +1 -1
- package/dist/src/generic.js +5 -5
- package/dist/src/index.d.ts +127 -8
- package/dist/src/index.js +1 -1
- package/dist/src/input-actions.js +1 -1
- package/dist/src/interaction.js +1 -1
- package/dist/src/react-native.js +1 -1
- package/dist/src/record-trace-recording.js +3 -3
- package/dist/src/selector-runtime.js +1 -1
- package/dist/src/selectors.d.ts +14 -0
- package/dist/src/selectors.js +1 -1
- package/dist/src/server.js +2 -2
- package/dist/src/session.js +8 -10
- package/dist/src/snapshot.js +2 -2
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/AgentDeviceRunnerUITests-Bridging-Header.h +1 -0
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.h +14 -0
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.m +297 -0
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +327 -0
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +122 -173
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +153 -5
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+FlatSnapshotFiltering.swift +171 -0
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +0 -10
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +64 -18
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollGesture.swift +200 -0
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SequenceExecution.swift +450 -0
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +82 -178
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +425 -0
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SystemModal.swift +77 -6
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Transport.swift +10 -1
- package/ios-runner/README.md +5 -5
- package/ios-runner/RUNNER_PROTOCOL.md +0 -1
- package/package.json +3 -3
- package/server.json +2 -2
- package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.17.2.apk.sha256 +0 -1
- package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.17.2.apk.sha256 +0 -1
- package/dist/src/1534.js +0 -1
- package/dist/src/1620.js +0 -1
- package/dist/src/1644.js +0 -2
- package/dist/src/2284.js +0 -1
- package/dist/src/2474.js +0 -1
- package/dist/src/2672.js +0 -1
- package/dist/src/3393.js +0 -1
- package/dist/src/5898.js +0 -1
- package/dist/src/695.js +0 -1
- package/dist/src/7455.js +0 -1
- package/dist/src/8173.js +0 -27
- package/dist/src/8407.js +0 -1
- package/dist/src/8699.js +0 -1
- package/dist/src/9238.js +0 -4
- package/dist/src/9673.js +0 -1
- package/dist/src/9974.js +0 -1
package/dist/src/9542.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
-
import e from"node:net";import t from"node:http";import a from"node:https";import r from"node:fs";import n from"node:os";import o from"node:path";import{pipeline as i}from"node:stream/promises";import{createHash as s,randomUUID as l}from"node:crypto";import{Writable as c}from"node:stream";import{toAppErrorCode as d,AppError as u}from"./9152.js";import{consumeTextLines as p,shellQuote as f,shouldStreamRequestProgress as m,isDaemonResponseEnvelope as h,resolveDaemonPaths as y,isDaemonProgressEnvelope as w,resolveDaemonServerMode as g,computeDaemonCodeSignature as I,resolveDaemonTransportPreference as v}from"./9238.js";import{runCmdSync as A,runCmd as _,runCmdDetached as b}from"./9818.js";import{readVersion as S,findProjectRoot as k}from"./9671.js";import{createRequestId as P,withDiagnosticTimer as D,emitDiagnostic as M}from"./7599.js";import{isAgentDeviceDaemonProcess as E,stopProcessForTakeover as T}from"./8656.js";import{INTERNAL_COMMANDS as N,PUBLIC_COMMANDS as C}from"./5898.js";import{sleep as U}from"./4829.js";import{reloadMetro as L,prepareMetroRuntime as R}from"./1974.js";import{normalizeSession as O,resolveSessionName as x,buildFlags as $,normalizeStartupSample as F,normalizeInstallFromSourceResult as q,normalizeMaterializationReleaseResult as B,prepareDaemonCommandRequest as j,readSnapshotNodes as K,normalizeRuntimeHints as H,normalizeDeployResult as z,normalizeOpenDevice as G,readScreenshotOverlayRefs as V,buildMeta as W,normalizeDevice as J}from"./8699.js";import{readRequiredString as Y,readOptionalString as Q}from"./7455.js";function X(e){return new Promise((t,a)=>{let r="";e.setEncoding("utf8"),e.on("data",e=>{r+=e}),e.on("end",()=>t(r)),e.on("error",a)})}function Z(e){let t=Math.max(0,e)/1e3;return t>=10?`${t.toFixed(1)}s`:t>=1?`${t.toFixed(2)}s`:`${t.toFixed(3).replace(/0+$/,"").replace(/\.$/,"")}s`}function ee(e){let t=function(e){var t,a,r;let n,i;if("replay-test"!==e.type||"pass"===e.status||"fail"===e.status&&!e.retrying)return;let s=(t=e,(n=t.title?.trim())?JSON.stringify(n):o.basename(t.file)),l=void 0!==e.durationMs?` (${i=Z((a=e).durationMs??0),a.attempt&&a.attempt>1&&!a.retrying?`total ${i}`:i})`:"",c=void 0===(r=e).attempt?"":"fail"===r.status&&r.retrying&&void 0!==r.maxAttempts?` attempt ${r.attempt}/${r.maxAttempts} retrying`:r.attempt>1?` after ${r.attempt} attempts`:"",d=e.message?.replace(/\s+/g," ").trim();return"skip"===e.status?[`SKIP ${s}`,d?` ${d}`:""].filter(Boolean).join("\n"):[`FAIL ${s}${c}${l}`,d?` ${d}`:"",e.artifactsDir?` artifacts: ${e.artifactsDir}`:""].filter(Boolean).join("\n")}(e);t&&process.stderr.write(`${t}
|
|
2
|
-
`)}let et="sha256";async function ea(e){let t=await er(e.localPath,e.platform),a=e.baseUrl.endsWith("/")?e.baseUrl:`${e.baseUrl}/`;try{let r=await es({normalizedBase:a,token:e.token,artifact:t});if(r?.kind==="cache-hit")return r.uploadId;if(r?.kind==="direct-upload")try{return await el(t.payloadPath,r),await ep({normalizedBase:a,token:e.token,uploadId:r.uploadId})}catch{}return await ei({normalizedBase:a,token:e.token,artifact:t})}finally{t.cleanup()}}async function er(e,t){var a,n,i;let s,l=r.statSync(e),c=o.basename(e),d=l.isDirectory(),u=("ios"===(a=t)||"android"===a?a:void 0)??(n=e,i=l,s=n.toLowerCase(),i.isDirectory()&&s.endsWith(".app")||s.endsWith(".ipa")?"ios":s.endsWith(".apk")||s.endsWith(".aab")?"android":void 0),p=[];try{let t=d?await en(e,p):e,a=r.statSync(t);return{payloadPath:t,fileName:c,artifactType:d?"app-bundle":"file",platform:u,contentType:d?"application/gzip":"application/octet-stream",sha256:await ef(t),sizeBytes:a.size,cleanup:()=>eo(p)}}catch(e){throw eo(p),e}}async function en(e,t){let a=r.mkdtempSync(o.join(n.tmpdir(),`agent-device-upload-${l()}-`));t.push(a);let i=o.join(a,`${o.basename(e)}.tar.gz`);return await _("tar",["czf",i,"-C",o.dirname(e),o.basename(e)],{env:{...process.env,COPYFILE_DISABLE:"1"}}),i}function eo(e){for(let t of e)r.rmSync(t,{recursive:!0,force:!0})}async function ei(e){let{normalizedBase:t,token:a,artifact:r}=e,n=new URL("upload",t),o={"content-type":r.contentType,"x-artifact-type":r.artifactType,"x-artifact-filename":r.fileName,"x-artifact-hash":r.sha256,"x-artifact-hash-algorithm":et,"transfer-encoding":"chunked"};a&&(o.authorization=`Bearer ${a}`,o["x-agent-device-token"]=a);let i=await ec({url:n,method:"POST",headers:o,payloadPath:r.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."});try{let e=JSON.parse(i.body);if(!e.ok||!e.uploadId)throw new u("COMMAND_FAILED",`Upload failed: ${i.body}`);return e.uploadId}catch(e){if(e instanceof u)throw e;throw new u("COMMAND_FAILED",`Invalid upload response: ${i.body}`)}}async function es(e){let t=new URL("upload/preflight",e.normalizedBase),a={"content-type":"application/json"};e.token&&(a.authorization=`Bearer ${e.token}`,a["x-agent-device-token"]=e.token);let r=await fetch(t,{method:"POST",headers:a,signal:AbortSignal.timeout(3e4),body:JSON.stringify({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 function(e){var t;if(!e||"object"!=typeof e||!0!==e.ok||"string"!=typeof e.uploadId)return;if(!0===e.cacheHit)return{kind:"cache-hit",uploadId:e.uploadId};let a=e.upload;if(!a||"string"!=typeof a.url)return;let r=a.headers??{};if(!(!(t=r)||"object"!=typeof t||Array.isArray(t))&&Object.values(t).every(e=>"string"==typeof e))return{kind:"direct-upload",uploadId:e.uploadId,url:a.url,headers:r}}(await r.json().catch(()=>void 0))}async function el(e,t){let a=await ec({url:new URL(t.url),method:"PUT",headers:t.headers,payloadPath:e,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"});if(a.statusCode<200||a.statusCode>=300)throw new u("COMMAND_FAILED","Direct artifact upload failed",{statusCode:a.statusCode,statusMessage:a.statusMessage})}async function ec(e){return await ed({...e,url:e.url,redirectCount:0,startOffset:0})}async function ed(e){var n,o,s;let l="https:"===e.url.protocol?a:t,c=r.statSync(e.payloadPath).size,d=(n=e.headers,o=e.startOffset,s=c,o<=0?n:{...n,"content-length":Math.max(s-o,0),"content-range":`bytes ${o}-${s-1}/${s}`});return await new Promise((t,a)=>{let n=!1,o=l.request({protocol:e.url.protocol,host:e.url.hostname,port:e.url.port,method:e.method,path:e.url.pathname+e.url.search,headers:d},r=>{n=!0,X(r).then(n=>{clearTimeout(s);let o=r.statusCode??500,i=r.headers.location;if(i&&[301,302,303,307,308].includes(o)){if(e.redirectCount>=5)return void a(new u("COMMAND_FAILED","Artifact upload exceeded redirect limit",{maxRedirects:5,url:e.url.toString()}));let r=new URL(i,e.url);return void ed({...e,url:r,redirectCount:e.redirectCount+1}).then(t,a)}let l=308===o?function(e,t){let a=function(e){let t=eu(e);if(void 0===t)return;let a=Number(t);return Number.isSafeInteger(a)&&a>=0?a:void 0}(e["x-upload-offset"]??e["upload-offset"]);if(void 0!==a)return Math.min(a,t);let r=eu(e.range),n=r?.match(/^bytes=0-(\d+)$/);if(!n)return;let o=Number(n[1]);if(Number.isSafeInteger(o)&&!(o<0))return Math.min(o+1,t)}(r.headers,c):void 0;void 0!==l?l>=c?t({statusCode:200,statusMessage:"Upload already complete",body:""}):l<=e.startOffset?a(new u("COMMAND_FAILED","Artifact upload resume did not advance",{offset:l,previousOffset:e.startOffset,url:e.url.toString()})):ed({...e,startOffset:l}).then(t,a):t({statusCode:o,statusMessage:r.statusMessage,body:n})}).catch(a)}),s=setTimeout(()=>{o.destroy(),a(new u("COMMAND_FAILED",e.timeoutMessage,{timeoutMs:3e5,...e.timeoutHint?{hint:e.timeoutHint}:{}}))},3e5);o.on("error",t=>{n||(clearTimeout(s),a(new u("COMMAND_FAILED",e.errorMessage,e.errorHint?{hint:e.errorHint}:{},t)))}),o.on("close",()=>clearTimeout(s)),i(r.createReadStream(e.payloadPath,{start:e.startOffset}),o).catch(e=>{n||(o.destroy(),a(new u("COMMAND_FAILED","Failed to read local artifact",{},e instanceof Error?e:Error(String(e)))))})})}function eu(e){return Array.isArray(e)?e[0]:e}async function ep(e){let t=new URL("upload/finalize",e.normalizedBase),a={"content-type":"application/json"};e.token&&(a.authorization=`Bearer ${e.token}`,a["x-agent-device-token"]=e.token);let r=await fetch(t,{method:"POST",headers:a,signal:AbortSignal.timeout(3e4),body:JSON.stringify({uploadId:e.uploadId})}).catch(e=>{throw new u("COMMAND_FAILED","Failed to finalize direct artifact upload",{},e)});if(!r.ok)throw new u("COMMAND_FAILED","Direct artifact upload finalize failed",{status:r.status,statusText:r.statusText});let n=await r.json().catch(()=>void 0);if(!n?.ok||!n.uploadId)throw new u("COMMAND_FAILED","Invalid upload finalize response");return n.uploadId}async function ef(e){let t=s(et),a=new c({write(e,a,r){t.update(e),r()}});return await i(r.createReadStream(e),a).catch(e=>{throw new u("COMMAND_FAILED","Failed to read local artifact",{},e instanceof Error?e:void 0)}),t.digest("hex")}async function em(e,t){var a;let r,n=[...e.positionals??[]],i=e.flags?{...e.flags}:void 0,s=e.meta?.installSource,l={};if(!("string"==typeof(a=t).baseUrl&&a.baseUrl.length>0))return ey({positionals:n,flags:i,installSource:s,uploadedArtifactId:r,clientArtifactPaths:l});i=function(e,t,a,r){var n,i;let s=function(e,t){if("screenshot"===e.command){let a=eg(e,"path",".png");return t[0]?{field:"path",localPath:a,positionalIndex:0,positionalPath:eI("screenshot",".png")}:{field:"path",localPath:a,positionalIndex:0,flagPath:eI("screenshot",".png")}}if("record"===e.command&&"start"===(t[0]??"").toLowerCase()){let t=eg(e,"outPath",".mp4",1);return{field:"outPath",localPath:t,positionalIndex:1,positionalPath:eI("recording",o.extname(t)||".mp4")}}return null}(e,t);if(!s)return a;void 0!==s.positionalPath&&(t[s.positionalIndex]=s.positionalPath);let l=(n=a,void 0===(i=s.flagPath)?n:{...n??{},out:i});return r[s.field]=s.localPath,l}(e,n,i,l);let c=await ew(e,t);c&&(s=c.installSource,r=c.uploadedArtifactId??r);let d=()=>ey({positionals:n,flags:i,installSource:s,uploadedArtifactId:r,clientArtifactPaths:l});return"install"!==e.command&&"reinstall"!==e.command||(r=await eh(e,t,n)??r),d()}async function eh(e,t,a){var n,i;let s,l=a[1];if(void 0===l)return;if(l.startsWith("remote:")){a[1]=l.slice(7);return}let c=(n=l,i=e.meta?.cwd,s=o.isAbsolute(n)?n:o.resolve(i??process.cwd(),n),r.existsSync(s)?s:void 0);if(c)return await ea({localPath:c,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform})}function ey(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 ew(e,t){let a=e.meta?.installSource;if("install_source"!==e.command||!a||"path"!==a.kind)return null;let n=a.path.trim();if(!n)return{installSource:a};if(n.startsWith("remote:"))return{installSource:{...a,path:n.slice(7)}};let i=o.isAbsolute(n)?n:o.resolve(e.meta?.cwd??process.cwd(),n);if(!r.existsSync(i))return{installSource:{...a,path:i}};let s=await ea({localPath:i,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform});return{installSource:{...a,path:i},uploadedArtifactId:s}}function eg(e,t,a,r=0){let n=e.positionals?.[r]??e.flags?.out,i=`${"path"===t?"screenshot":"recording"}-${Date.now()}${a}`,s=n&&n.trim().length>0?n:i;return o.isAbsolute(s)?s:o.resolve(e.meta?.cwd??process.cwd(),s)}function eI(e,t){let a=t.startsWith(".")?t:`.${t}`;return o.posix.join("/tmp",`agent-device-${e}-${Date.now()}-${Math.random().toString(36).slice(2,8)}${a}`)}async function ev(e,t,a){let r=Array.isArray(a.data?.artifacts)?a.data.artifacts:[];if(0===r.length||!e.baseUrl)return a;let n=a.data?{...a.data}:{},i=[];for(let a of r){if(!a||"object"!=typeof a||"string"!=typeof a.artifactId){i.push(a);continue}let r=function(e,t){if(e.localPath&&e.localPath.trim().length>0)return e.localPath;let a=t.meta?.clientArtifactPaths?.[e.field];if(a&&a.trim().length>0)return a;let r=e.fileName?.trim()||`${e.field}-${Date.now()}`;return o.resolve(t.meta?.cwd??process.cwd(),r)}(a,t);await eA({baseUrl:e.baseUrl,token:e.token,artifactId:a.artifactId,destinationPath:r,requestId:t.meta?.requestId}),n[a.field]=r,i.push({...a,localPath:r})}return n.artifacts=i,{ok:!0,data:n}}async function eA(e){var n,s;let l,c=new URL((n=e.baseUrl,s=e.artifactId,l=n.endsWith("/")?n:`${n}/`,new URL(`artifacts/${encodeURIComponent(s)}`,l).toString())),d="https:"===c.protocol?a:t;await r.promises.mkdir(o.dirname(e.destinationPath),{recursive:!0}),await new Promise((t,a)=>{let n=!1,o=e.timeoutMs??9e4,s=o=>{if(!n){if(n=!0,clearTimeout(p),o)return void r.promises.rm(e.destinationPath,{force:!0}).finally(()=>a(o));t()}},l=d.request({protocol:c.protocol,host:c.hostname,port:c.port,method:"GET",path:c.pathname+c.search,headers:e.token?{authorization:`Bearer ${e.token}`,"x-agent-device-token":e.token}:void 0},t=>{if((t.statusCode??500)>=400){let a="";t.setEncoding("utf8"),t.on("data",e=>{a+=e}),t.on("end",()=>{s(new u("COMMAND_FAILED","Failed to download remote artifact",{artifactId:e.artifactId,statusCode:t.statusCode,requestId:e.requestId,body:a}))});return}t.on("aborted",()=>{s(new u("COMMAND_FAILED","Remote artifact download was interrupted",{artifactId:e.artifactId,requestId:e.requestId}))}),i(t,r.createWriteStream(e.destinationPath)).then(()=>s(),e=>s(e instanceof Error?e:Error(String(e))))}),p=setTimeout(()=>{let t=new u("COMMAND_FAILED","Remote artifact download timed out",{artifactId:e.artifactId,requestId:e.requestId,timeoutMs:o});s(t),l.destroy(t)},o);l.on("error",t=>{t instanceof u?s(t):s(new u("COMMAND_FAILED","Failed to download remote artifact",{artifactId:e.artifactId,requestId:e.requestId,timeoutMs:o},t instanceof Error?t:void 0))}),l.end()})}let e_=["xcodebuild .*AgentDeviceRunnerUITests/RunnerTests/testCommand","xcodebuild .*AgentDeviceRunner\\.env\\.session-","xcodebuild build-for-testing .*ios-runner/AgentDeviceRunner/AgentDeviceRunner\\.xcodeproj"],eb=new e.BlockList;async function eS(t){var a,i,s,l,c,d;let p,f,m,h,w,I,A,_=t.meta?.requestId??P(),b=!!(t.meta?.debug||t.flags?.verbose),S=(h=(i=a=t,i.flags?.stateDir??process.env.AGENT_DEVICE_STATE_DIR),w=(s=a,f=function(e){let t;if(e){try{t=new URL(e)}catch(t){throw new u("INVALID_ARGS","Invalid daemon base URL",{daemonBaseUrl:e},t instanceof Error?t:void 0)}if("http:"!==t.protocol&&"https:"!==t.protocol)throw new u("INVALID_ARGS","Daemon base URL must use http or https",{daemonBaseUrl:e});return t.toString().replace(/\/+$/,"")}}(p=s.flags?.daemonBaseUrl??process.env.AGENT_DEVICE_DAEMON_BASE_URL),function(t,a){let r;if(!(!t||"localhost"===(r=new URL(t).hostname.trim().toLowerCase().replace(/^\[(.*)\]$/,"$1"))||(e.isIPv4(r)?eb.check(r,"ipv4"):!!e.isIPv6(r)&&eb.check(r,"ipv6")))&&("string"!=typeof a||!(a.trim().length>0)))throw new u("INVALID_ARGS","Remote daemon base URL for non-loopback hosts requires daemon authentication",{daemonBaseUrl:t,hint:"Provide --daemon-auth-token or AGENT_DEVICE_DAEMON_AUTH_TOKEN when using a non-loopback remote daemon URL."})}(f,m=s.flags?.daemonAuthToken??process.env.AGENT_DEVICE_DAEMON_AUTH_TOKEN),{rawBaseUrl:p,remoteBaseUrl:f,authToken:m}),I=function(e,t){let a=e.flags?.daemonTransport??process.env.AGENT_DEVICE_DAEMON_TRANSPORT,r=v(a);if(t&&"socket"===r)throw new u("INVALID_ARGS","Remote daemon base URL only supports HTTP transport. Remove --daemon-transport socket.",{daemonBaseUrl:t});return{preference:r,serverMode:g(e.flags?.daemonServerMode??process.env.AGENT_DEVICE_DAEMON_SERVER_MODE??("dual"===a?"dual":void 0))}}(a,w.remoteBaseUrl),{paths:y((A=(l=a,c=h,d=w.rawBaseUrl,eT(l.command)&&!c&&!d))?r.mkdtempSync(o.join(n.tmpdir(),"agent-device-replay-daemon-")):h),transportPreference:I.preference,serverMode:I.serverMode,ownedStateDir:A,remoteBaseUrl:w.remoteBaseUrl,remoteAuthToken:w.authToken}),k=function(e){if(e.command!==C.test){var t;return"number"==typeof e.flags?.timeoutMs&&((t=e.command)===C.prepare||t===C.replay||t===C.snapshot)?e.flags.timeoutMs:e.command===C.prepare?24e4:9e4}}(t),E=await D("daemon_startup",async()=>await ek(S),{requestId:_,session:t.session}),T=E.info,N=await em(t,T),U={...t,positionals:N.positionals,flags:N.flags,token:T.token,meta:{...t.meta??{},requestId:_,debug:b,cwd:t.meta?.cwd,sessionExplicit:t.meta?.sessionExplicit,tenantId:t.meta?.tenantId??t.flags?.tenant,runId:t.meta?.runId??t.flags?.runId,leaseId:t.meta?.leaseId??t.flags?.leaseId,sessionIsolation:t.meta?.sessionIsolation??t.flags?.sessionIsolation,lockPolicy:t.meta?.lockPolicy,lockPlatform:t.meta?.lockPlatform,...N.uploadedArtifactId?{uploadedArtifactId:N.uploadedArtifactId}:{},...N.clientArtifactPaths?{clientArtifactPaths:N.clientArtifactPaths}:{},...N.installSource?{installSource:N.installSource}:{}}};M({level:"info",phase:"daemon_request_prepare",data:{requestId:_,command:t.command,session:t.session}});try{return await D("daemon_request",async()=>await eG(T,U,S.transportPreference,k),{requestId:_,command:t.command})}finally{await eE(t,E,S)}}async function ek(e){if(e.remoteBaseUrl)return await eP(e);let t=await eD(e);return t?{info:t,startedByClient:!1}:(function(e){let t=eF(e);if(!t.hasLock||t.hasInfo)return;let a=ex(e.lockPath);if(!a)return eB(e.lockPath);E(a.pid,a.processStartTime)||eB(e.lockPath)}(e.paths),await eM(e))}async function eP(e){let t={transport:"http",token:e.remoteAuthToken??"",pid:0,baseUrl:e.remoteBaseUrl};if(await ej(t,"http"))return{info:t,startedByClient:!1};throw new u("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."})}async function eD(e){var t,a;let r,n=eL(e.paths.infoPath);if(!n)return null;let o=await ej(n,e.transportPreference);return(t=n,a=o,t.version===S()&&t.codeSignature===I((r=ez()).useSrc?r.srcPath:r.distPath,r.root)&&a)?n:(await eU(n),eB(e.paths.infoPath),null)}async function eM(e){let t,a=0,r=[];for(let n=1;n<=2;n+=1){try{await eH(e)}catch(a){if(t=a instanceof Error?a.message:String(a),r.push(await e$(e.paths,"start_error")),n<2){await U(150);continue}break}let o=await eN(15e3,e);if(o)return{info:o,startedByClient:!0};if(await eC(e.paths)){a+=1;continue}let i=eF(e.paths),s=n<2,l=await e$(e.paths,"startup_timeout",{stopLiveProcesses:!1});if(r.push(l),l.retainedInfoProcess||l.retainedLockProcess){let t=await eN(15e3,e);if(t)return{info:t,startedByClient:!0};break}if(!s)break;i.hasInfo||i.hasLock||await U(150)}let n=eF(e.paths);throw new u("COMMAND_FAILED","Failed to start daemon",{kind:"daemon_startup_failed",infoPath:e.paths.infoPath,lockPath:e.paths.lockPath,startupTimeoutMs:15e3,startupAttempts:2,lockRecoveryCount:a,cleanupResults:r,startError:t,metadataState:n,hint:function(e,t=y(process.env.AGENT_DEVICE_STATE_DIR)){var a;let r=(a=t,`rm -f ${f(a.infoPath)} ${f(a.lockPath)}`);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: ${r}`: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: ${r}`: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: ${r}`:`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: ${r}`}(n,e.paths)})}async function eE(e,t,a){if(!eT(e.command)||!t.startedByClient&&!a.ownedStateDir||e5(t.info))return;let n={pid:t.info.pid,removedInfo:!1,removedLock:!1,removedStateDir:!1,error:void 0};try{await eU(t.info)}catch(e){n.error=e instanceof Error?e.message:String(e)}finally{let e=r.existsSync(a.paths.infoPath);eB(a.paths.infoPath),n.removedInfo=e&&!r.existsSync(a.paths.infoPath);let t=r.existsSync(a.paths.lockPath);eB(a.paths.lockPath),n.removedLock=t&&!r.existsSync(a.paths.lockPath),a.ownedStateDir&&(r.rmSync(a.paths.baseDir,{recursive:!0,force:!0}),n.removedStateDir=!r.existsSync(a.paths.baseDir))}M({level:n.error?"warn":"info",phase:"daemon_replay_cleanup",data:n})}function eT(e){return e===C.replay||e===C.test}async function eN(e,t){let a=Date.now();for(;Date.now()-a<e;){let e=eL(t.paths.infoPath);if(e&&await ej(e,t.transportPreference))return e;await U(100)}return null}async function eC(e){let t=eF(e);if(!t.hasLock||t.hasInfo)return!1;let a=ex(e.lockPath);return!(a&&E(a.pid,a.processStartTime))&&(eB(e.lockPath),!0)}async function eU(e){await T(e.pid,{termTimeoutMs:3e3,killTimeoutMs:1e3,expectedStartTime:e.processStartTime})}function eL(e){var t,a,r;let n,o,i=eq(e);if(!i||"object"!=typeof i)return null;let s="string"==typeof(t=i).token&&t.token.length>0?t.token:null;if(!s)return null;let l=(n=eO((a=i).port),o=eO(a.httpPort),void 0===n&&void 0===o?null:{port:n,httpPort:o});return l?{token:s,...l,transport:"socket"===(r=i.transport)||"http"===r||"dual"===r?r:void 0,pid:eO(i.pid)??0,version:eR(i.version),codeSignature:eR(i.codeSignature),processStartTime:eR(i.processStartTime)}:null}function eR(e){return"string"==typeof e?e:void 0}function eO(e){return Number.isInteger(e)&&Number(e)>0?Number(e):void 0}function ex(e){let t=eq(e);return t&&"object"==typeof t&&Number.isInteger(t.pid)&&Number(t.pid)>0?{pid:Number(t.pid),processStartTime:"string"==typeof t.processStartTime?t.processStartTime:void 0,startedAt:"number"==typeof t.startedAt?t.startedAt:void 0}:null}eb.addSubnet("127.0.0.0",8,"ipv4"),eb.addAddress("::1","ipv6"),eb.addSubnet("::ffff:127.0.0.0",104,"ipv6");async function e$(e,t,a={}){let n=a.stopLiveProcesses??!0,o={reason:t,removedInfo:!1,removedLock:!1,stoppedInfoProcess:!1,stoppedLockProcess:!1};try{var i,s,l,c;let t=r.existsSync(e.infoPath),a=eL(e.infoPath);if(a){let t=E(a.pid,a.processStartTime);t&&!n?o.retainedInfoProcess=!0:(t&&(await eU(a),o.stoppedInfoProcess=!0),i=e.infoPath,eB(i),o.removedInfo=!0)}else t&&(s=e.infoPath,eB(s),o.removedInfo=!0);let d=r.existsSync(e.lockPath),u=ex(e.lockPath);if(u){let t=E(u.pid,u.processStartTime);t&&!n?o.retainedLockProcess=!0:(t&&(await T(u.pid,{termTimeoutMs:3e3,killTimeoutMs:1e3,expectedStartTime:u.processStartTime}),o.stoppedLockProcess=!0),l=e.lockPath,eB(l),o.removedLock=!0)}else d&&(c=e.lockPath,eB(c),o.removedLock=!0)}catch(e){o.error=e instanceof Error?e.message:String(e)}return M({level:o.error?"warn":"info",phase:"daemon_startup_metadata_cleanup",data:o}),o}function eF(e){return{hasInfo:r.existsSync(e.infoPath),hasLock:r.existsSync(e.lockPath)}}function eq(e){if(!r.existsSync(e))return null;try{return JSON.parse(r.readFileSync(e,"utf8"))}catch{return null}}function eB(e){try{r.existsSync(e)&&r.unlinkSync(e)}catch{}}async function ej(e,t){let a=eW(e,t);if(await eK(e,a))return!0;let r=eY(e,t,a);return!!r&&await eK(e,r)}async function eK(r,n){var o;return"http"===n?await function(e){let r=e.baseUrl?e2(e.baseUrl,"health"):e.httpPort?`http://127.0.0.1:${e.httpPort}/health`:null;if(!r)return Promise.resolve(!1);let n=new URL(r),o="https:"===n.protocol?a:t,i=e.baseUrl?3e3:500;return new Promise(e=>{let t=o.request({protocol:n.protocol,host:n.hostname,port:n.port,path:n.pathname+n.search,method:"GET",timeout:i},t=>{t.resume(),e((t.statusCode??500)<500)});t.on("timeout",()=>{t.destroy(),e(!1)}),t.on("error",()=>{e(!1)}),t.end()})}(r):await ((o=r.port)?new Promise(t=>{let a=!1,r=e.createConnection({host:"127.0.0.1",port:o},()=>{n(!0)}),n=e=>{a||(a=!0,r.destroy(),t(e))};r.setTimeout(500),r.on("timeout",()=>{n(!1)}),r.on("error",()=>{n(!1)})}):Promise.resolve(!1))}async function eH(e){let t=ez(),a=t.useSrc?["--experimental-strip-types",t.srcPath]:[t.distPath],r={...process.env,AGENT_DEVICE_STATE_DIR:e.paths.baseDir,AGENT_DEVICE_DAEMON_SERVER_MODE:e.serverMode};b(process.execPath,a,{env:r})}function ez(){let e=k(),t=[o.join(e,"dist","src","internal","daemon.js"),o.join(e,"dist","src","daemon.js")],a=t[0];if(void 0===a)throw new u("COMMAND_FAILED","Daemon dist path list is empty");let n=t.find(e=>r.existsSync(e))??a,i=o.join(e,"src","daemon.ts"),s=t.some(e=>r.existsSync(e)),l=r.existsSync(i);if(!s&&!l)throw new u("COMMAND_FAILED","Daemon entry not found",{distPaths:t,srcPath:i});return{root:e,distPath:n,distPaths:t,srcPath:i,useSrc:process.execArgv.includes("--experimental-strip-types")?l:!s&&l}}async function eG(e,t,a,r){let n=eW(e,a);try{return await eV(e,t,r,n)}catch(s){var o;let i=eY(e,a,n);if(!i||(o=s,"socket"!==n||!(o instanceof u)||"COMMAND_FAILED"!==o.code||"Failed to communicate with daemon"!==o.message||o.details?.daemonSocketRequestWritten!==!1))throw s;return await eV(e,t,r,i)}}async function eV(e,t,a,r){return"http"===r?await e0(e,t,a):await eZ(e,t,a)}function eW(e,t){if(e.baseUrl){if("socket"===t)throw new u("COMMAND_FAILED","Remote daemon endpoint only supports HTTP transport",{daemonBaseUrl:e.baseUrl});return"http"}if("http"===t||"socket"===t){var a=e,r=t;if(eJ(a,r))return r;throw new u("COMMAND_FAILED","http"===r?"Daemon HTTP endpoint is unavailable":"Daemon socket endpoint is unavailable")}let n=("socket"===e.transport||"dual"===e.transport?["socket","http"]:["http","socket"]).find(t=>eJ(e,t));if(n)return n;throw new u("COMMAND_FAILED","Daemon metadata has no reachable transport")}function eJ(e,t){return"http"===t?!!e.httpPort:!!e.port}function eY(e,t,a){if("auto"!==t||e.baseUrl)return null;let r="socket"===a?"http":"socket";return eJ(e,r)?r:null}function eQ(e,t,a,r,n,o){let i=n?{terminated:0}:function(){let e=0;try{for(let t of e_){let a=A("pkill",["-f",t],{allowFailure:!0});0===a.exitCode&&(e+=1)}return{terminated:e}}catch(t){return{terminated:e,error:t instanceof Error?t.message:String(t)}}}(),s=!n&&"snapshot"!==r,l=s?function(e,t){let a=!1;try{E(e.pid,e.processStartTime)&&(process.kill(e.pid,"SIGKILL"),a=!0)}catch{T(e.pid,{termTimeoutMs:3e3,killTimeoutMs:1e3,expectedStartTime:e.processStartTime})}finally{eB(t.infoPath),eB(t.lockPath)}return{forcedKill:a}}(e,t):{forcedKill:!1};return M({level:"error",phase:"daemon_request_timeout",data:{timeoutMs:o,requestId:a,command:r,timedOutRunnerPidsTerminated:i.terminated,timedOutRunnerCleanupError:i.error,daemonPidReset:s?e.pid:void 0,daemonPidForceKilled:s?l.forcedKill:void 0,daemonPreservedAfterTimeout:!n&&!s,daemonBaseUrl:e.baseUrl}}),new u("COMMAND_FAILED","Daemon request timed out",{timeoutMs:o,requestId:a,hint:function(e){let{remote:t,resetDaemon:a,command:r}=e;if(t)return"Retry with --debug and verify the remote daemon URL, auth token, and remote host logs.";if(!a){let e=r===C.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."}({remote:n,resetDaemon:s,command:r})})}function eX(e,t,a,r={}){return M({level:"error",phase:"daemon_request_socket_error",data:{requestId:t,message:e instanceof Error?e.message:String(e)}}),new u("COMMAND_FAILED","Failed to communicate with daemon",{...r,requestId:t,hint:a?"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 eZ(t,a,r){let n=t.port;if(!n)throw new u("COMMAND_FAILED","Daemon socket endpoint is unavailable");return new Promise((o,i)=>{let s=!1,l=e.createConnection({host:"127.0.0.1",port:n},()=>{s=!0,l.write(`${JSON.stringify(a)}
|
|
3
|
-
`)}),c=y(a.flags?.stateDir??process.env.AGENT_DEVICE_STATE_DIR),d=!1,f="number"==typeof r?setTimeout(()=>{d=!0,l.destroy(),i(eQ(t,c,a.meta?.requestId,a.command,!1,r))},r):void 0;!function(e,t){let{req:a,isSettled:r,resolve:n,reject:o,clearTimeout:i}=t,s="",l=(e,t)=>{i(),o(new u("COMMAND_FAILED","Invalid daemon response",{requestId:a.meta?.requestId,line:e},t instanceof Error?t:void 0))};e.setEncoding("utf8"),e.on("data",t=>{if(r())return;let a=p(s,t);for(let t of(s=a.buffer,a.lines))try{let a=JSON.parse(t);if(w(a)){ee(a.event);continue}let r=h(a)?a.response:a;i(),n(r),e.end();return}catch(e){l(t,e);return}})}(l,{req:a,isSettled:()=>d,clearTimeout:()=>{f&&clearTimeout(f)},resolve:e=>{d=!0,o(e)},reject:e=>{d=!0,i(e)}}),l.on("error",e=>{d||(d=!0,f&&clearTimeout(f),i(eX(e,a.meta?.requestId,!1,{daemonSocketRequestWritten:s})))})})}async function e0(e,r,n){var o,i,s;let l,c=e.baseUrl?new URL(e2(e.baseUrl,"rpc")):e.httpPort?new URL(`http://127.0.0.1:${e.httpPort}/rpc`):null;if(!c)throw new u("COMMAND_FAILED","Daemon HTTP endpoint is unavailable");let d=JSON.stringify((o=r,i={includeTokenParam:!e.baseUrl},l=o.meta?.requestId??P(),"lease_allocate"!==(s=o.command)&&"lease_heartbeat"!==s&&"lease_release"!==s?{jsonrpc:"2.0",id:l,method:"agent_device.command",params:o}:{jsonrpc:"2.0",id:l,method:function(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"}}(o.command),params:function(e,t,a){let r={...a.includeTokenParam?{token:e.token}:{},session:e.session,tenantId:e.meta?.tenantId,runId:e.meta?.runId};switch(t){case"lease_allocate":return{...r,ttlMs:e.meta?.leaseTtlMs,backend:e.meta?.leaseBackend};case"lease_heartbeat":return{...r,leaseId:e.meta?.leaseId,ttlMs:e.meta?.leaseTtlMs};case"lease_release":return{...r,leaseId:e.meta?.leaseId}}}(o,o.command,i)})),f={"content-type":"application/json","content-length":Buffer.byteLength(d)};return e.baseUrl&&e.token&&(f.authorization=`Bearer ${e.token}`,f["x-agent-device-token"]=e.token),await new Promise((o,i)=>{let s=y(r.flags?.stateDir??process.env.AGENT_DEVICE_STATE_DIR),l=("https:"===c.protocol?a:t).request({protocol:c.protocol,host:c.hostname,port:c.port,method:"POST",path:c.pathname+c.search,headers:f},t=>{var a;(a=t.headers?.["content-type"],m(r)&&String(Array.isArray(a)?a.join(","):a??"").includes("application/x-ndjson"))?function(e,t){let{req:a,handleResponseBody:r,reject:n,clearTimeout:o}=t,i="",s=!1,l=e=>{try{let t=JSON.parse(e);if(w(t))return ee(t.event),!1;if(h(t))return s=!0,o(),r(JSON.stringify(t.response)),!0;throw Error("Missing daemon progress response envelope")}catch(t){return s=!0,o(),n(new u("COMMAND_FAILED","Invalid daemon response",{requestId:a.meta?.requestId,line:e},t instanceof Error?t:void 0)),!0}};e.setEncoding("utf8"),e.on("data",e=>{if(s)return;let t=p(i,e);for(let e of(i=t.buffer,t.lines))if(e&&l(e))return}),e.on("end",()=>{if(s)return;let e=i.trim();e&&l(e)||(s=!0,o(),n(new u("COMMAND_FAILED","Invalid daemon response",{requestId:a.meta?.requestId,line:e})))}),e.on("error",e=>{s||(s=!0,o(),n(new u("COMMAND_FAILED","Failed to read daemon response",{requestId:a.meta?.requestId},e instanceof Error?e:void 0)))})}(t,{req:r,reject:i,clearTimeout:()=>{I&&clearTimeout(I)},handleResponseBody:t=>e1(t,{info:e,req:r,resolve:o,reject:i})}):X(t).then(t=>{I&&clearTimeout(I),e1(t,{info:e,req:r,resolve:o,reject:i})}).catch(e=>{I&&clearTimeout(I),i(new u("COMMAND_FAILED","Failed to read daemon response",{requestId:r.meta?.requestId},e instanceof Error?e:void 0))})}),g=e5(e),I="number"==typeof n?setTimeout(()=>{l.destroy(),i(eQ(e,s,r.meta?.requestId,r.command,g,n))},n):void 0;l.on("error",e=>{I&&clearTimeout(I),i(eX(e,r.meta?.requestId,g))}),l.write(d),l.end()})}function e1(e,t){let{info:a,req:r,resolve:n,reject:o}=t;try{var i,s,l;let t=(i=e,JSON.parse(i));if(t.error){let e;return void o((s=t.error,l=r.meta?.requestId,e=s.data??{},new u(d(null!=e.code?String(e.code):void 0,"COMMAND_FAILED"),String(e.message??s.message??"Daemon RPC request failed"),{..."object"==typeof e.details&&e.details?e.details:{},hint:"string"==typeof e.hint?e.hint:void 0,diagnosticId:"string"==typeof e.diagnosticId?e.diagnosticId:void 0,logPath:"string"==typeof e.logPath?e.logPath:void 0,requestId:l})))}if(!t.result||"object"!=typeof t.result)return void o(new u("COMMAND_FAILED","Invalid daemon RPC response",{requestId:r.meta?.requestId}));e3(a,r,t.result,n,o)}catch(t){o(new u("COMMAND_FAILED","Invalid daemon response",{requestId:r.meta?.requestId,line:e},t instanceof Error?t:void 0))}}async function e3(e,t,a,r,n){try{r(e.baseUrl&&a.ok?await ev(e,t,a):a)}catch(e){n(e)}}function e5(e){return"string"==typeof e.baseUrl&&e.baseUrl.length>0}function e2(e,t){return new URL(t,e.endsWith("/")?e:`${e}/`).toString()}function e8(e={},t={}){let a=t.transport??eS,r=async(t,r=[],n={})=>{var o,i;let s=(o=e,i=n,{...o,...i}),l=await a({session:x(s.session),command:t,positionals:r,flags:$(s),runtime:s.runtime,meta:W(s)});return l.ok||function(e){throw new u(d(e.code),e.message,{...e.details??{},hint:e.hint,diagnosticId:e.diagnosticId,logPath:e.logPath})}(l.error),l.data??{}},n=async(e={})=>{let t=await r(N.sessionList,[],e);return(Array.isArray(t.sessions)?t.sessions:[]).map(O)},o=async(e,t={})=>{let a=j(e,t);return await r(a.command,a.positionals,a.options)},i=(t={})=>{var a,r;return x((a=e,r=t,{...a,...r}).session)};return{command:{wait:async e=>await o("wait",e),alert:async(e={})=>await o("alert",e),appState:async(e={})=>await o("appstate",e),back:async(e={})=>await o("back",e),home:async(e={})=>await o("home",e),rotate:async e=>await o("rotate",e),appSwitcher:async(e={})=>await o("app-switcher",e),keyboard:async(e={})=>await o("keyboard",e),clipboard:async e=>await o("clipboard",e),reactNative:async e=>await o("react-native",e),prepare:async e=>await o("prepare",e)},devices:{list:async(e={})=>{let t=await o("devices",e);return(Array.isArray(t.devices)?t.devices:[]).map(J)},boot:async(e={})=>await o("boot",e),shutdown:async(e={})=>await o("shutdown",e)},sessions:{list:async(e={})=>await n(e),close:async(e={})=>{let t=i(e),a=(await o("close",e)).shutdown;return{session:t,shutdown:"object"==typeof a&&null!==a?a:void 0,identifiers:{session:t}}}},apps:{install:async e=>z(await o("install",e),i(e)),reinstall:async e=>z(await o("reinstall",e),i(e)),installFromSource:async e=>q(await o("install-from-source",e),i(e)),list:async(e={})=>{let t=await o("apps",e);return Array.isArray(t.apps)?t.apps.filter(e=>"string"==typeof e):[]},open:async e=>{let t=i(e),a=await o("open",e),r=G(a),n=Q(a,"appBundleId");return{session:t,sessionStateDir:Q(a,"sessionStateDir"),appName:Q(a,"appName"),appBundleId:n,appId:n,startup:F(a.startup),runtime:H(a.runtime),device:r,identifiers:{session:t,deviceId:r?.id,deviceName:r?.name,udid:r?.ios?.udid,serial:r?.android?.serial,appId:n,appBundleId:n}}},close:async(e={})=>{let t=i(e),a=(await o("close",e)).shutdown;return{session:t,closedApp:e.app,shutdown:"object"==typeof a&&null!==a?a:void 0,identifiers:{session:t}}},push:async e=>await o("push",e),triggerEvent:async e=>await o("trigger-app-event",e)},materializations:{release:async e=>B(await r(N.releaseMaterializedPaths,[],{...e,materializationId:e.materializationId}))},leases:{allocate:async e=>e6(await r(N.leaseAllocate,[],{...e,leaseId:void 0,leaseTtlMs:e.ttlMs})),heartbeat:async e=>e6(await r(N.leaseHeartbeat,[],{...e,leaseTtlMs:e.ttlMs})),release:async e=>({released:!0===(await r(N.leaseRelease,[],e)).released})},metro:{prepare:async t=>await R({projectRoot:t.projectRoot??e.cwd,kind:t.kind,publicBaseUrl:t.publicBaseUrl,proxyBaseUrl:t.proxyBaseUrl,proxyBearerToken:t.bearerToken,bridgeScope:t.bridgeScope,launchUrl:t.launchUrl,companionProfileKey:t.companionProfileKey,companionConsumerKey:t.companionConsumerKey,metroPort:t.port,listenHost:t.listenHost,statusHost:t.statusHost,startupTimeoutMs:t.startupTimeoutMs,probeTimeoutMs:t.probeTimeoutMs,reuseExisting:t.reuseExisting,installDependenciesIfNeeded:t.installDependenciesIfNeeded,runtimeFilePath:t.runtimeFilePath,logPath:t.logPath}),reload:async(t={})=>await L({metroHost:t.metroHost,metroPort:t.metroPort,bundleUrl:t.bundleUrl,runtime:e.runtime,timeoutMs:t.timeoutMs})},capture:{snapshot:async(e={})=>{var t,a,r;let n,s,l,c,d,u=i(e);return t=await o("snapshot",e),a=u,n=Q(t,"appBundleId"),{nodes:K(t.nodes),truncated:!0===t.truncated,appName:Q(t,"appName"),appBundleId:n,...(s=e4((r=t).visibility),l=e4(r.androidSnapshot),c=e4(r.unchanged),d=Array.isArray(r.warnings)?r.warnings.filter(e=>"string"==typeof e):void 0,{...s?{visibility:s}:{},...l?{androidSnapshot:l}:{},...c?{unchanged:c}:{},...d?{warnings:d}:{}}),identifiers:{session:a,appId:n,appBundleId:n}}},screenshot:async(e={})=>{let t=i(e),a=await o("screenshot",e);return{path:Y(a,"path"),overlayRefs:V(a),identifiers:{session:t}}},diff:async e=>await o("diff",e)},interactions:{click:async e=>await o("click",e),press:async e=>await o("press",e),longPress:async e=>await o("longpress",e),swipe:async e=>await o("swipe",e),pan:async e=>await o("gesture-pan",e),fling:async e=>await o("gesture-fling",e),swipeGesture:async e=>await o("gesture-swipe",e),focus:async e=>await o("focus",e),type:async e=>await o("type",e),fill:async e=>await o("fill",e),scroll:async e=>await o("scroll",e),pinch:async e=>await o("gesture-pinch",e),rotateGesture:async e=>await o("gesture-rotate",e),transformGesture:async e=>await o("gesture-transform",e),get:async e=>await o("get",e),is:async e=>await o("is",e),find:async e=>await o("find",e)},replay:{run:async e=>await o("replay",e),test:async e=>await o("test",e)},batch:{run:async e=>await o("batch",e)},observability:{perf:async(e={})=>await o("perf",e),logs:async(e={})=>await o("logs",e),network:async(e={})=>await o("network",e)},recording:{record:async e=>await o("record",e),trace:async e=>await o("trace",e)},settings:{update:async e=>await o("settings",e)}}}function e4(e){return"object"==typeof e&&null!==e?e:void 0}function e6(e){let t=e.lease;if(!t||"object"!=typeof t||Array.isArray(t))throw Error("Invalid lease response from daemon");return{leaseId:Y(t,"leaseId"),tenantId:Y(t,"tenantId"),runId:Y(t,"runId"),backend:Y(t,"backend"),createdAt:"number"==typeof t.createdAt?t.createdAt:void 0,heartbeatAt:"number"==typeof t.heartbeatAt?t.heartbeatAt:void 0,expiresAt:"number"==typeof t.expiresAt?t.expiresAt:void 0}}export{e8 as createAgentDeviceClient,Z as formatDurationSeconds,eS as sendToDaemon};
|
|
1
|
+
import e from"node:fs";import t from"node:http";import a from"node:https";import r from"node:path";import{pipeline as n}from"node:stream/promises";import i from"node:os";import{createHash as o,randomUUID as s}from"node:crypto";import{Writable as d}from"node:stream";import l from"node:net";import c from"node:fs/promises";import{toAppErrorCode as u,AppError as f}from"./9152.js";import{runCmdDetachedMonitored as p,runCmd as m,runCmdSync as h}from"./9818.js";import{createRequestId as y,withDiagnosticTimer as w,emitDiagnostic as g}from"./7599.js";import{isAgentDeviceDaemonProcess as I,stopProcessForTakeover as v}from"./8656.js";import{readSnapshotDiagnosticsSummary as b,consumeTextLines as A,shellQuote as S,shouldStreamRequestProgress as M,isDaemonResponseEnvelope as P,isDaemonProgressEnvelope as D,resolveDaemonPaths as _,resolveDaemonServerMode as k,computeDaemonCodeSignature as E,resolveDaemonTransportPreference as x}from"./4012.js";import{INTERNAL_COMMANDS as N,PUBLIC_COMMANDS as $}from"./6088.js";import{readVersion as T,findProjectRoot as C}from"./9671.js";import{sleep as U}from"./4829.js";import{normalizeSession as L,readRequiredString as R,readSerializedSnapshotCaptureAnnotations as O,readOptionalString as F,normalizeMaterializationReleaseResult as B,readSnapshotNodes as q,normalizeDeployResult as j,appDaemonWriters as V,observabilityDaemonWriters as G,normalizeOpenDevice as H,replayDaemonWriters as K,buildMeta as z,systemDaemonWriters as Y,resolveSessionName as W,buildFlags as J,reactNativeDaemonWriters as X,interactionDaemonWriters as Q,captureDaemonWriters as Z,perfDaemonWriters as ee,gestureDaemonWriters as et,selectorDaemonWriters as ea,createBatchDaemonWriter as er,normalizeRuntimeHints as en,normalizeDevice as ei,recordingDaemonWriters as eo,readScreenshotOverlayRefs as es,normalizeStartupSample as ed,normalizeInstallFromSourceResult as el}from"./6133.js";import{reloadMetro as ec,prepareMetroRuntime as eu}from"./1974.js";function ef(e){return new Promise((t,a)=>{let r="";e.setEncoding("utf8"),e.on("data",e=>{r+=e}),e.on("end",()=>t(r)),e.on("error",a)})}let ep="sha256";async function em(e){let t=await eh(e.localPath,e.platform),a=e.baseUrl.endsWith("/")?e.baseUrl:`${e.baseUrl}/`;try{let r=await eI({normalizedBase:a,token:e.token,artifact:t});if(r?.kind==="cache-hit")return r.uploadId;if(r?.kind==="direct-upload")try{return await ev(t.payloadPath,r),await eM({normalizedBase:a,token:e.token,uploadId:r.uploadId})}catch{}return await eg({normalizedBase:a,token:e.token,artifact:t})}finally{t.cleanup()}}async function eh(t,a){var n,i,o;let s,d=e.statSync(t),l=r.basename(t),c=d.isDirectory(),u=("ios"===(n=a)||"android"===n?n:void 0)??(i=t,o=d,s=i.toLowerCase(),o.isDirectory()&&s.endsWith(".app")||s.endsWith(".ipa")?"ios":s.endsWith(".apk")||s.endsWith(".aab")?"android":void 0),f=[];try{let a=c?await ey(t,f):t,r=e.statSync(a);return{payloadPath:a,fileName:l,artifactType:c?"app-bundle":"file",platform:u,contentType:c?"application/gzip":"application/octet-stream",sha256:await eP(a),sizeBytes:r.size,cleanup:()=>ew(f)}}catch(e){throw ew(f),e}}async function ey(t,a){let n=e.mkdtempSync(r.join(i.tmpdir(),`agent-device-upload-${s()}-`));a.push(n);let o=r.join(n,`${r.basename(t)}.tar.gz`);return await m("tar",["czf",o,"-C",r.dirname(t),r.basename(t)],{env:{...process.env,COPYFILE_DISABLE:"1"}}),o}function ew(t){for(let a of t)e.rmSync(a,{recursive:!0,force:!0})}async function eg(e){let{normalizedBase:t,token:a,artifact:r}=e,n=new URL("upload",t),i={"content-type":r.contentType,"x-artifact-type":r.artifactType,"x-artifact-filename":r.fileName,"x-artifact-hash":r.sha256,"x-artifact-hash-algorithm":ep,"transfer-encoding":"chunked"};a&&(i.authorization=`Bearer ${a}`,i["x-agent-device-token"]=a);let o=await eb({url:n,method:"POST",headers:i,payloadPath:r.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."});try{let e=JSON.parse(o.body);if(!e.ok||!e.uploadId)throw new f("COMMAND_FAILED",`Upload failed: ${o.body}`);return e.uploadId}catch(e){if(e instanceof f)throw e;throw new f("COMMAND_FAILED",`Invalid upload response: ${o.body}`)}}async function eI(e){let t=new URL("upload/preflight",e.normalizedBase),a={"content-type":"application/json"};e.token&&(a.authorization=`Bearer ${e.token}`,a["x-agent-device-token"]=e.token);let r=await fetch(t,{method:"POST",headers:a,signal:AbortSignal.timeout(3e4),body:JSON.stringify({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 function(e){var t;if(!e||"object"!=typeof e||!0!==e.ok||"string"!=typeof e.uploadId)return;if(!0===e.cacheHit)return{kind:"cache-hit",uploadId:e.uploadId};let a=e.upload;if(!a||"string"!=typeof a.url)return;let r=a.headers??{};if(!(!(t=r)||"object"!=typeof t||Array.isArray(t))&&Object.values(t).every(e=>"string"==typeof e))return{kind:"direct-upload",uploadId:e.uploadId,url:a.url,headers:r}}(await r.json().catch(()=>void 0))}async function ev(e,t){let a=await eb({url:new URL(t.url),method:"PUT",headers:t.headers,payloadPath:e,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"});if(a.statusCode<200||a.statusCode>=300)throw new f("COMMAND_FAILED","Direct artifact upload failed",{statusCode:a.statusCode,statusMessage:a.statusMessage})}async function eb(e){return await eA({...e,url:e.url,redirectCount:0,startOffset:0})}async function eA(r){var i,o,s;let d="https:"===r.url.protocol?a:t,l=e.statSync(r.payloadPath).size,c=(i=r.headers,o=r.startOffset,s=l,o<=0?i:{...i,"content-length":Math.max(s-o,0),"content-range":`bytes ${o}-${s-1}/${s}`});return await new Promise((t,a)=>{let i=!1,o=d.request({protocol:r.url.protocol,host:r.url.hostname,port:r.url.port,method:r.method,path:r.url.pathname+r.url.search,headers:c},e=>{i=!0,ef(e).then(n=>{clearTimeout(s);let i=e.statusCode??500,o=e.headers.location;if(o&&[301,302,303,307,308].includes(i)){if(r.redirectCount>=5)return void a(new f("COMMAND_FAILED","Artifact upload exceeded redirect limit",{maxRedirects:5,url:r.url.toString()}));let e=new URL(o,r.url);return void eA({...r,url:e,redirectCount:r.redirectCount+1}).then(t,a)}let d=308===i?function(e,t){let a=function(e){let t=eS(e);if(void 0===t)return;let a=Number(t);return Number.isSafeInteger(a)&&a>=0?a:void 0}(e["x-upload-offset"]??e["upload-offset"]);if(void 0!==a)return Math.min(a,t);let r=eS(e.range),n=r?.match(/^bytes=0-(\d+)$/);if(!n)return;let i=Number(n[1]);if(Number.isSafeInteger(i)&&!(i<0))return Math.min(i+1,t)}(e.headers,l):void 0;void 0!==d?d>=l?t({statusCode:200,statusMessage:"Upload already complete",body:""}):d<=r.startOffset?a(new f("COMMAND_FAILED","Artifact upload resume did not advance",{offset:d,previousOffset:r.startOffset,url:r.url.toString()})):eA({...r,startOffset:d}).then(t,a):t({statusCode:i,statusMessage:e.statusMessage,body:n})}).catch(a)}),s=setTimeout(()=>{o.destroy(),a(new f("COMMAND_FAILED",r.timeoutMessage,{timeoutMs:3e5,...r.timeoutHint?{hint:r.timeoutHint}:{}}))},3e5);o.on("error",e=>{i||(clearTimeout(s),a(new f("COMMAND_FAILED",r.errorMessage,r.errorHint?{hint:r.errorHint}:{},e)))}),o.on("close",()=>clearTimeout(s)),n(e.createReadStream(r.payloadPath,{start:r.startOffset}),o).catch(e=>{i||(o.destroy(),a(new f("COMMAND_FAILED","Failed to read local artifact",{},e instanceof Error?e:Error(String(e)))))})})}function eS(e){return Array.isArray(e)?e[0]:e}async function eM(e){let t=new URL("upload/finalize",e.normalizedBase),a={"content-type":"application/json"};e.token&&(a.authorization=`Bearer ${e.token}`,a["x-agent-device-token"]=e.token);let r=await fetch(t,{method:"POST",headers:a,signal:AbortSignal.timeout(3e4),body:JSON.stringify({uploadId:e.uploadId})}).catch(e=>{throw new f("COMMAND_FAILED","Failed to finalize direct artifact upload",{},e)});if(!r.ok)throw new f("COMMAND_FAILED","Direct artifact upload finalize failed",{status:r.status,statusText:r.statusText});let n=await r.json().catch(()=>void 0);if(!n?.ok||!n.uploadId)throw new f("COMMAND_FAILED","Invalid upload finalize response");return n.uploadId}async function eP(t){let a=o(ep),r=new d({write(e,t,r){a.update(e),r()}});return await n(e.createReadStream(t),r).catch(e=>{throw new f("COMMAND_FAILED","Failed to read local artifact",{},e instanceof Error?e:void 0)}),a.digest("hex")}async function eD(e,t){var a;let n,i=[...e.positionals??[]],o=e.flags?{...e.flags}:void 0,s=e.meta?.installSource,d={};if(!("string"==typeof(a=t).baseUrl&&a.baseUrl.length>0))return ek({positionals:i,flags:o,installSource:s,uploadedArtifactId:n,clientArtifactPaths:d});o=function(e,t,a,n){var i,o;let s=function(e,t){if("screenshot"===e.command){let a=ex(e,"path",".png");return t[0]?{field:"path",localPath:a,positionalIndex:0,positionalPath:eN("screenshot",".png")}:{field:"path",localPath:a,positionalIndex:0,flagPath:eN("screenshot",".png")}}if("record"===e.command&&"start"===(t[0]??"").toLowerCase()){let t=ex(e,"outPath",".mp4",1);return{field:"outPath",localPath:t,positionalIndex:1,positionalPath:eN("recording",r.extname(t)||".mp4")}}return null}(e,t);if(!s)return a;void 0!==s.positionalPath&&(t[s.positionalIndex]=s.positionalPath);let d=(i=a,void 0===(o=s.flagPath)?i:{...i??{},out:o});return n[s.field]=s.localPath,d}(e,i,o,d);let l=await eE(e,t);l&&(s=l.installSource,n=l.uploadedArtifactId??n);let c=()=>ek({positionals:i,flags:o,installSource:s,uploadedArtifactId:n,clientArtifactPaths:d});return"install"!==e.command&&"reinstall"!==e.command||(n=await e_(e,t,i)??n),c()}async function e_(t,a,n){var i,o;let s,d=n[1];if(void 0===d)return;if(d.startsWith("remote:")){n[1]=d.slice(7);return}let l=(i=d,o=t.meta?.cwd,s=r.isAbsolute(i)?i:r.resolve(o??process.cwd(),i),e.existsSync(s)?s:void 0);if(l)return await em({localPath:l,baseUrl:a.baseUrl,token:a.token,platform:t.flags?.platform})}function ek(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 eE(t,a){let n=t.meta?.installSource;if("install_source"!==t.command||!n||"path"!==n.kind)return null;let i=n.path.trim();if(!i)return{installSource:n};if(i.startsWith("remote:"))return{installSource:{...n,path:i.slice(7)}};let o=r.isAbsolute(i)?i:r.resolve(t.meta?.cwd??process.cwd(),i);if(!e.existsSync(o))return{installSource:{...n,path:o}};let s=await em({localPath:o,baseUrl:a.baseUrl,token:a.token,platform:t.flags?.platform});return{installSource:{...n,path:o},uploadedArtifactId:s}}function ex(e,t,a,n=0){let i=e.positionals?.[n]??e.flags?.out,o=`${"path"===t?"screenshot":"recording"}-${Date.now()}${a}`,s=i&&i.trim().length>0?i:o;return r.isAbsolute(s)?s:r.resolve(e.meta?.cwd??process.cwd(),s)}function eN(e,t){let a=t.startsWith(".")?t:`.${t}`;return r.posix.join("/tmp",`agent-device-${e}-${Date.now()}-${Math.random().toString(36).slice(2,8)}${a}`)}async function e$(e,t,a){let n=Array.isArray(a.data?.artifacts)?a.data.artifacts:[];if(0===n.length||!e.baseUrl)return a;let i=a.data?{...a.data}:{},o=[];for(let a of n){if(!a||"object"!=typeof a||"string"!=typeof a.artifactId){o.push(a);continue}let n=function(e,t){if(e.localPath&&e.localPath.trim().length>0)return e.localPath;let a=t.meta?.clientArtifactPaths?.[e.field];if(a&&a.trim().length>0)return a;let n=e.fileName?.trim()||`${e.field}-${Date.now()}`;return r.resolve(t.meta?.cwd??process.cwd(),n)}(a,t);await eT({baseUrl:e.baseUrl,token:e.token,artifactId:a.artifactId,destinationPath:n,requestId:t.meta?.requestId}),i[a.field]=n,o.push({...a,localPath:n})}return i.artifacts=o,{ok:!0,data:i}}async function eT(i){var o,s;let d,l=new URL((o=i.baseUrl,s=i.artifactId,d=o.endsWith("/")?o:`${o}/`,new URL(`artifacts/${encodeURIComponent(s)}`,d).toString())),c="https:"===l.protocol?a:t;await e.promises.mkdir(r.dirname(i.destinationPath),{recursive:!0}),await new Promise((t,a)=>{let r=!1,o=i.timeoutMs??9e4,s=n=>{if(!r){if(r=!0,clearTimeout(u),n)return void e.promises.rm(i.destinationPath,{force:!0}).finally(()=>a(n));t()}},d=c.request({protocol:l.protocol,host:l.hostname,port:l.port,method:"GET",path:l.pathname+l.search,headers:i.token?{authorization:`Bearer ${i.token}`,"x-agent-device-token":i.token}:void 0},t=>{if((t.statusCode??500)>=400){let e="";t.setEncoding("utf8"),t.on("data",t=>{e+=t}),t.on("end",()=>{s(new f("COMMAND_FAILED","Failed to download remote artifact",{artifactId:i.artifactId,statusCode:t.statusCode,requestId:i.requestId,body:e}))});return}t.on("aborted",()=>{s(new f("COMMAND_FAILED","Remote artifact download was interrupted",{artifactId:i.artifactId,requestId:i.requestId}))}),n(t,e.createWriteStream(i.destinationPath)).then(()=>s(),e=>s(e instanceof Error?e:Error(String(e))))}),u=setTimeout(()=>{let e=new f("COMMAND_FAILED","Remote artifact download timed out",{artifactId:i.artifactId,requestId:i.requestId,timeoutMs:o});s(e),d.destroy(e)},o);d.on("error",e=>{e instanceof f?s(e):s(new f("COMMAND_FAILED","Failed to download remote artifact",{artifactId:i.artifactId,requestId:i.requestId,timeoutMs:o},e instanceof Error?e:void 0))}),d.end()})}function eC(e){var t,a,r;let n,i,o=eV(e);if(!o||"object"!=typeof o)return null;let s="string"==typeof(t=o).token&&t.token.length>0?t.token:null;if(!s)return null;let d=(n=eL((a=o).port),i=eL(a.httpPort),void 0===n&&void 0===i?null:{port:n,httpPort:i});return d?{token:s,...d,transport:"socket"===(r=o.transport)||"http"===r||"dual"===r?r:void 0,pid:eL(o.pid)??0,version:eU(o.version),codeSignature:eU(o.codeSignature),processStartTime:eU(o.processStartTime)}:null}function eU(e){return"string"==typeof e?e:void 0}function eL(e){return Number.isInteger(e)&&Number(e)>0?Number(e):void 0}function eR(e){let t=eV(e);return t&&"object"==typeof t&&Number.isInteger(t.pid)&&Number(t.pid)>0?{pid:Number(t.pid),processStartTime:"string"==typeof t.processStartTime?t.processStartTime:void 0,startedAt:"number"==typeof t.startedAt?t.startedAt:void 0}:null}async function eO(t,a,r={}){let n=r.stopLiveProcesses??!0,i={reason:a,removedInfo:!1,removedLock:!1,stoppedInfoProcess:!1,stoppedLockProcess:!1};try{var o,s,d,l;let a=e.existsSync(t.infoPath),r=eC(t.infoPath);if(r){let e=I(r.pid,r.processStartTime);e&&!n?i.retainedInfoProcess=!0:(e&&(await eq(r),i.stoppedInfoProcess=!0),o=t.infoPath,eG(o),i.removedInfo=!0)}else a&&(s=t.infoPath,eG(s),i.removedInfo=!0);let c=e.existsSync(t.lockPath),u=eR(t.lockPath);if(u){let e=I(u.pid,u.processStartTime);e&&!n?i.retainedLockProcess=!0:(e&&(await v(u.pid,{termTimeoutMs:3e3,killTimeoutMs:1e3,expectedStartTime:u.processStartTime}),i.stoppedLockProcess=!0),d=t.lockPath,eG(d),i.removedLock=!0)}else c&&(l=t.lockPath,eG(l),i.removedLock=!0)}catch(e){i.error=e instanceof Error?e.message:String(e)}return g({level:i.error?"warn":"info",phase:"daemon_startup_metadata_cleanup",data:i}),i}function eF(t){return{hasInfo:e.existsSync(t.infoPath),hasLock:e.existsSync(t.lockPath)}}async function eB(e){let t=eF(e);if(!t.hasLock||t.hasInfo)return!1;let a=eR(e.lockPath);return!(a&&I(a.pid,a.processStartTime))&&(eG(e.lockPath),!0)}async function eq(e){await v(e.pid,{termTimeoutMs:3e3,killTimeoutMs:1e3,expectedStartTime:e.processStartTime})}function ej(e){return"string"==typeof e.baseUrl&&e.baseUrl.length>0}function eV(t){if(!e.existsSync(t))return null;try{return JSON.parse(e.readFileSync(t,"utf8"))}catch{return null}}function eG(t){try{e.existsSync(t)&&e.unlinkSync(t)}catch{}}function eH(e){let t=Math.max(0,e)/1e3;return t>=10?`${t.toFixed(1)}s`:t>=1?`${t.toFixed(2)}s`:`${t.toFixed(3).replace(/0+$/,"").replace(/\.$/,"")}s`}let eK={start:"START",pass:"PASS",fail:"FAIL",skip:"SKIP"};function ez(e){var t,a,n,i,o,s,d;let l,c,u,f,p,m,h,y,w,g,I,v="replay-test-suite"===e.type?(t=e,l=[`Running replay suite: ${t.total} ${1===t.total?"file":"files"}`],t.shardMode&&t.shardCount&&t.shardCount>1&&l.push(` sharding: ${t.shardMode} across ${t.shardCount} devices`),l.push(` artifacts: ${t.artifactsDir}`),l.join("\n")):"replay-test"===e.type?(function(e,t){if("start"===t.status){t.session&&e.push(` session: ${t.session}`),t.artifactsDir&&e.push(` artifacts: ${t.artifactsDir}`);return}let a=t.message?.replace(/\s+/g," ").trim();a&&e.push(` ${a}`),"fail"===t.status&&!t.retrying&&(t.session&&e.push(` session: ${t.session}`),t.artifactsDir&&e.push(` artifacts: ${t.artifactsDir}`))}(I=[(n=a=e,p=`[${n.index}/${n.total}]`,m=(i=n).retrying?"RETRY":eK[i.status],h=(o=n,c=o.title?.trim(),u=r.basename(o.file),c?`${JSON.stringify(c)} in ${u}`:u),y=function(e){if("number"!=typeof e.shardIndex)return"";let t="number"==typeof e.shardCount?e.shardCount:"?",a="string"==typeof e.deviceId?` ${e.deviceId}`:"";return` [shard ${e.shardIndex+1}/${t}${a}]`}(n),w=void 0===(s=n).attempt||"start"===s.status?"":"fail"===s.status&&s.retrying&&void 0!==s.maxAttempts?` attempt ${s.attempt}/${s.maxAttempts}`:s.attempt>1?` after ${s.attempt} attempts`:"",g=void 0!==n.durationMs?` (${f=eH((d=n).durationMs??0),d.attempt&&d.attempt>1&&!d.retrying?`total ${f}`:f})`:"",`${p} ${m} ${h}${y}${w}${g}`)],a),I.join("\n")):void 0;v&&process.stderr.write(`${v}
|
|
2
|
+
`)}function eY(e,t){let{info:a,req:r,resolve:n,reject:i}=t;try{var o,s,d;let t=(o=e,JSON.parse(o));if(t.error){let e;return void i((s=t.error,d=r.meta?.requestId,e=s.data??{},new f(u(null!=e.code?String(e.code):void 0,"COMMAND_FAILED"),String(e.message??s.message??"Daemon RPC request failed"),{..."object"==typeof e.details&&e.details?e.details:{},hint:"string"==typeof e.hint?e.hint:void 0,diagnosticId:"string"==typeof e.diagnosticId?e.diagnosticId:void 0,logPath:"string"==typeof e.logPath?e.logPath:void 0,requestId:d})))}if(!t.result||"object"!=typeof t.result)return void i(new f("COMMAND_FAILED","Invalid daemon RPC response",{requestId:r.meta?.requestId}));eW(a,r,t.result,n,i)}catch(t){i(new f("COMMAND_FAILED","Invalid daemon response",{requestId:r.meta?.requestId,line:e},t instanceof Error?t:void 0))}}async function eW(e,t,a,r,n){try{r(e.baseUrl&&a.ok?await e$(e,t,a):a)}catch(e){n(e)}}let eJ=["xcodebuild .*AgentDeviceRunnerUITests/RunnerTests/testCommand","xcodebuild .*AgentDeviceRunner\\.env\\.session-","xcodebuild build-for-testing .*ios-runner/AgentDeviceRunner/AgentDeviceRunner\\.xcodeproj"];function eX(e,t,a,r,n,i){let o=n?{terminated:0}:function(){let e=0;try{for(let t of eJ){let a=h("pkill",["-f",t],{allowFailure:!0});0===a.exitCode&&(e+=1)}return{terminated:e}}catch(t){return{terminated:e,error:t instanceof Error?t.message:String(t)}}}(),s=!n&&"snapshot"!==r,d=s?function(e,t){let a=!1;try{I(e.pid,e.processStartTime)&&(process.kill(e.pid,"SIGKILL"),a=!0)}catch{eq(e)}finally{eG(t.infoPath),eG(t.lockPath)}return{forcedKill:a}}(e,t):{forcedKill:!1};return g({level:"error",phase:"daemon_request_timeout",data:{timeoutMs:i,requestId:a,command:r,timedOutRunnerPidsTerminated:o.terminated,timedOutRunnerCleanupError:o.error,daemonPidReset:s?e.pid:void 0,daemonPidForceKilled:s?d.forcedKill:void 0,daemonPreservedAfterTimeout:!n&&!s,daemonBaseUrl:e.baseUrl}}),new f("COMMAND_FAILED","Daemon request timed out",{timeoutMs:i,requestId:a,hint:function(e){let{remote:t,resetDaemon:a,command:r}=e;if(t)return"Retry with --debug and verify the remote daemon URL, auth token, and remote host logs.";if(!a){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."}({remote:n,resetDaemon:s,command:r})})}async function eQ(e,t){let a=e3(e,t);if(await eZ(e,a))return!0;let r=e5(e,t,a);return!!r&&await eZ(e,r)}async function eZ(e,r){var n;return"http"===r?await function(e){let r=e.baseUrl?e9(e.baseUrl,"health"):e.httpPort?`http://127.0.0.1:${e.httpPort}/health`:null;if(!r)return Promise.resolve(!1);let n=new URL(r),i="https:"===n.protocol?a:t,o=e.baseUrl?3e3:500;return new Promise(e=>{let t=i.request({protocol:n.protocol,host:n.hostname,port:n.port,path:n.pathname+n.search,method:"GET",timeout:o},t=>{t.resume(),e((t.statusCode??500)<500)});t.on("timeout",()=>{t.destroy(),e(!1)}),t.on("error",()=>{e(!1)}),t.end()})}(e):await ((n=e.port)?new Promise(e=>{let t=!1,a=l.createConnection({host:"127.0.0.1",port:n},()=>{r(!0)}),r=r=>{t||(t=!0,a.destroy(),e(r))};a.setTimeout(500),a.on("timeout",()=>{r(!1)}),a.on("error",()=>{r(!1)})}):Promise.resolve(!1))}async function e0(e,t,a,r,n){let i=e3(e,a);try{return await e1(e,t,r,n,i)}catch(d){var o;let s=e5(e,a,i);if(!s||(o=d,"socket"!==i||!(o instanceof f)||"COMMAND_FAILED"!==o.code||"Failed to communicate with daemon"!==o.message||o.details?.daemonSocketRequestWritten!==!1))throw d;return await e1(e,t,r,n,s)}}async function e1(e,t,a,r,n){return"http"===n?await e8(e,t,a,r):await e6(e,t,a,r)}function e3(e,t){if(e.baseUrl){if("socket"===t)throw new f("COMMAND_FAILED","Remote daemon endpoint only supports HTTP transport",{daemonBaseUrl:e.baseUrl});return"http"}if("http"===t||"socket"===t){var a=e,r=t;if(e2(a,r))return r;throw new f("COMMAND_FAILED","http"===r?"Daemon HTTP endpoint is unavailable":"Daemon socket endpoint is unavailable")}let n=("socket"===e.transport||"dual"===e.transport?["socket","http"]:["http","socket"]).find(t=>e2(e,t));if(n)return n;throw new f("COMMAND_FAILED","Daemon metadata has no reachable transport")}function e2(e,t){return"http"===t?!!e.httpPort:!!e.port}function e5(e,t,a){if("auto"!==t||e.baseUrl)return null;let r="socket"===a?"http":"socket";return e2(e,r)?r:null}function e4(e,t,a,r={}){return g({level:"error",phase:"daemon_request_socket_error",data:{requestId:t,message:e instanceof Error?e.message:String(e)}}),new f("COMMAND_FAILED","Failed to communicate with daemon",{...r,requestId:t,hint:a?"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 e6(e,t,a,r){let n=e.port;if(!n)throw new f("COMMAND_FAILED","Daemon socket endpoint is unavailable");return new Promise((i,o)=>{let s=!1,d=l.createConnection({host:"127.0.0.1",port:n},()=>{s=!0,d.write(`${JSON.stringify(t)}
|
|
3
|
+
`)}),c=!1,u="number"==typeof r?setTimeout(()=>{c=!0,d.destroy(),o(eX(e,a,t.meta?.requestId,t.command,!1,r))},r):void 0;!function(e,t){let{req:a,isSettled:r,resolve:n,reject:i,clearTimeout:o}=t,s="",d=(e,t)=>{o(),i(new f("COMMAND_FAILED","Invalid daemon response",{requestId:a.meta?.requestId,line:e},t instanceof Error?t:void 0))};e.setEncoding("utf8"),e.on("data",t=>{if(r())return;let a=A(s,t);for(let t of(s=a.buffer,a.lines))try{let a=JSON.parse(t);if(D(a)){ez(a.event);continue}let r=P(a)?a.response:a;o(),n(r),e.end();return}catch(e){d(t,e);return}})}(d,{req:t,isSettled:()=>c,clearTimeout:()=>{u&&clearTimeout(u)},resolve:e=>{c=!0,i(e)},reject:e=>{c=!0,o(e)}}),d.on("error",e=>{c||(c=!0,u&&clearTimeout(u),o(e4(e,t.meta?.requestId,!1,{daemonSocketRequestWritten:s})))})})}async function e8(e,r,n,i){var o,s;let d,l=e.baseUrl?new URL(e9(e.baseUrl,"rpc")):e.httpPort?new URL(`http://127.0.0.1:${e.httpPort}/rpc`):null;if(!l)throw new f("COMMAND_FAILED","Daemon HTTP endpoint is unavailable");let c=JSON.stringify((o={includeTokenParam:!e.baseUrl},d=r.meta?.requestId??y(),"lease_allocate"!==(s=r.command)&&"lease_heartbeat"!==s&&"lease_release"!==s?{jsonrpc:"2.0",id:d,method:"agent_device.command",params:r}:{jsonrpc:"2.0",id:d,method:function(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"}}(r.command),params:function(e,t,a){let r={...a.includeTokenParam?{token:e.token}:{},session:e.session,tenantId:e.meta?.tenantId,runId:e.meta?.runId};switch(t){case"lease_allocate":return{...r,ttlMs:e.meta?.leaseTtlMs,backend:e.meta?.leaseBackend};case"lease_heartbeat":return{...r,leaseId:e.meta?.leaseId,ttlMs:e.meta?.leaseTtlMs};case"lease_release":return{...r,leaseId:e.meta?.leaseId}}}(r,r.command,o)})),u={"content-type":"application/json","content-length":Buffer.byteLength(c)};return e.baseUrl&&e.token&&(u.authorization=`Bearer ${e.token}`,u["x-agent-device-token"]=e.token),await new Promise((o,s)=>{let d=("https:"===l.protocol?a:t).request({protocol:l.protocol,host:l.hostname,port:l.port,method:"POST",path:l.pathname+l.search,headers:u},t=>{var a;(a=t.headers?.["content-type"],M(r)&&String(Array.isArray(a)?a.join(","):a??"").includes("application/x-ndjson"))?function(e,t){let{req:a,handleResponseBody:r,reject:n,clearTimeout:i}=t,o="",s=!1,d=e=>{try{let t=JSON.parse(e);if(D(t))return ez(t.event),!1;if(P(t))return s=!0,i(),r(JSON.stringify(t.response)),!0;throw Error("Missing daemon progress response envelope")}catch(t){return s=!0,i(),n(new f("COMMAND_FAILED","Invalid daemon response",{requestId:a.meta?.requestId,line:e},t instanceof Error?t:void 0)),!0}};e.setEncoding("utf8"),e.on("data",e=>{if(s)return;let t=A(o,e);for(let e of(o=t.buffer,t.lines))if(e&&d(e))return}),e.on("end",()=>{if(s)return;let e=o.trim();e&&d(e)||(s=!0,i(),n(new f("COMMAND_FAILED","Invalid daemon response",{requestId:a.meta?.requestId,line:e})))}),e.on("error",e=>{s||(s=!0,i(),n(new f("COMMAND_FAILED","Failed to read daemon response",{requestId:a.meta?.requestId},e instanceof Error?e:void 0)))})}(t,{req:r,reject:s,clearTimeout:()=>{m&&clearTimeout(m)},handleResponseBody:t=>eY(t,{info:e,req:r,resolve:o,reject:s})}):ef(t).then(t=>{m&&clearTimeout(m),eY(t,{info:e,req:r,resolve:o,reject:s})}).catch(e=>{m&&clearTimeout(m),s(new f("COMMAND_FAILED","Failed to read daemon response",{requestId:r.meta?.requestId},e instanceof Error?e:void 0))})}),p=ej(e),m="number"==typeof i?setTimeout(()=>{d.destroy(),s(eX(e,n,r.meta?.requestId,r.command,p,i))},i):void 0;d.on("error",e=>{m&&clearTimeout(m),s(e4(e,r.meta?.requestId,p))}),d.write(c),d.end()})}function e9(e,t){return new URL(t,e.endsWith("/")?e:`${e}/`).toString()}let e7=new l.BlockList;async function te(e){if(e.remoteBaseUrl)return await tt(e);let t=await ta(e);return t?{info:t,startedByClient:!1}:(!function(e){let t=eF(e);if(!t.hasLock||t.hasInfo)return;let a=eR(e.lockPath);if(!a)return eG(e.lockPath);I(a.pid,a.processStartTime)||eG(e.lockPath)}(e.paths),await tr(e))}async function tt(e){let t={transport:"http",token:e.remoteAuthToken??"",pid:0,baseUrl:e.remoteBaseUrl};if(await eQ(t,"http"))return{info:t,startedByClient:!1};throw new f("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."})}async function ta(e){var t,a;let r=eC(e.paths.infoPath);if(!r)return null;let n=await eQ(r,e.transportPreference);return(t=r,a=n,t.version===T()&&t.codeSignature===td()&&a)?r:(function(e,t,a){try{var r,n;let i=e.version?`pid ${e.pid}, v${e.version}`:`pid ${e.pid}`,o=(r=e,n=t,r.version!==T()?`version mismatch (client v${T()})`:r.codeSignature!==td()?"code-signature mismatch":n?"not reusable":"unreachable");process.stderr.write(`Replacing daemon (${i}) in ${a}: ${o}
|
|
4
|
+
`)}catch{}}(r,n,e.paths.baseDir),await eq(r),eG(e.paths.infoPath),null)}async function tr(t){let a,r,n=0,i=[];for(let o=1;o<=2;o+=1){let s;try{r={pid:(s=function(t){let a=ts(),r=a.useSrc?["--experimental-strip-types",a.srcPath]:[a.distPath],n={...process.env,AGENT_DEVICE_STATE_DIR:t.paths.baseDir,AGENT_DEVICE_DAEMON_SERVER_MODE:t.serverMode};e.mkdirSync(t.paths.baseDir,{recursive:!0});let i=e.openSync(t.paths.logPath,"a"),o=e.openSync(t.paths.logPath,"a");try{return p(process.execPath,r,{env:n,stdio:["ignore",i,o]})}finally{e.closeSync(i),e.closeSync(o)}}(t)).pid}}catch(e){if(a=e instanceof Error?e.message:String(e),i.push(await eO(t.paths,"start_error")),o<2){await U(150);continue}break}let d=await to(15e3,t,s);if("ready"===d.kind)return{info:d.info,startedByClient:!0};if("early_exit"===d.kind){if(r=d.exit,a=tl(d.exit),i.push(await eO(t.paths,"start_error")),o<2){await U(150);continue}break}if(await eB(t.paths)){n+=1;continue}let l=eF(t.paths),c=o<2,u=await eO(t.paths,"startup_timeout",{stopLiveProcesses:!1});if(i.push(u),u.retainedInfoProcess||u.retainedLockProcess){let e=await to(15e3,t,s);if("ready"===e.kind)return{info:e.info,startedByClient:!0};"early_exit"===e.kind&&(r=e.exit,a=tl(e.exit));break}if(!c)break;l.hasInfo||l.hasLock||await U(150)}let o=eF(t.paths),s=function(t){try{if(!e.existsSync(t))return;let a=e.statSync(t);if(a.size<=0)return;let r=Math.min(a.size,64e3),n=e.openSync(t,"r");try{let t=Buffer.alloc(r);e.readSync(n,t,0,r,a.size-r);let i=t.toString("utf8").trim();return i.length>0?i:void 0}finally{e.closeSync(n)}}catch{return}}(t.paths.logPath);throw new f("COMMAND_FAILED","Failed to start daemon",{kind:"daemon_startup_failed",stateDir:t.paths.baseDir,infoPath:t.paths.infoPath,lockPath:t.paths.lockPath,logPath:t.paths.logPath,startupTimeoutMs:15e3,startupAttempts:2,lockRecoveryCount:n,cleanupResults:i,startError:a,daemonProcess:r,...s?{daemonLogTail:s}:{},metadataState:o,hint:function(e,t=_(process.env.AGENT_DEVICE_STATE_DIR)){var a;let r=(a=t,`rm -f ${S(a.infoPath)} ${S(a.lockPath)}`);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: ${r}`: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: ${r}`: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: ${r}`:`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: ${r}`}(o,t.paths)})}async function tn(t,a,r){if(!ti(t.command)||!a.startedByClient&&!r.ownedStateDir||ej(a.info))return;let n={pid:a.info.pid,removedInfo:!1,removedLock:!1,removedStateDir:!1,error:void 0};try{await eq(a.info)}catch(e){n.error=e instanceof Error?e.message:String(e)}finally{let t=e.existsSync(r.paths.infoPath);eG(r.paths.infoPath),n.removedInfo=t&&!e.existsSync(r.paths.infoPath);let a=e.existsSync(r.paths.lockPath);eG(r.paths.lockPath),n.removedLock=a&&!e.existsSync(r.paths.lockPath),r.ownedStateDir&&(e.rmSync(r.paths.baseDir,{recursive:!0,force:!0}),n.removedStateDir=!e.existsSync(r.paths.baseDir))}g({level:n.error?"warn":"info",phase:"daemon_replay_cleanup",data:n})}function ti(e){return e===$.replay||e===$.test}async function to(e,t,a){let r,n=Date.now();for(a.exited.then(e=>{r=e});Date.now()-n<e;){if(r)return{kind:"early_exit",exit:r};let e=eC(t.paths.infoPath);if(e&&await eQ(e,t.transportPreference))return{kind:"ready",info:e};if(r)return{kind:"early_exit",exit:r};await U(100)}return{kind:"timeout"}}function ts(){let t=C(),a=[r.join(t,"dist","src","internal","daemon.js"),r.join(t,"dist","src","daemon.js")],n=a[0];if(void 0===n)throw new f("COMMAND_FAILED","Daemon dist path list is empty");let i=a.find(t=>e.existsSync(t))??n,o=r.join(t,"src","daemon.ts"),s=a.some(t=>e.existsSync(t)),d=e.existsSync(o);if(!s&&!d)throw new f("COMMAND_FAILED","Daemon entry not found",{distPaths:a,srcPath:o});return{root:t,distPath:i,distPaths:a,srcPath:o,useSrc:process.execArgv.includes("--experimental-strip-types")?d:!s&&d}}function td(){let e=ts();return E(e.useSrc?e.srcPath:e.distPath,e.root)}function tl(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}`}async function tc(t){var a,n,o,s,d;let c,u,p,m,h,I,v,b=t.meta?.requestId??y(),A=!!(t.meta?.debug||t.flags?.verbose),S=(a=t,m=a.flags?.stateDir??process.env.AGENT_DEVICE_STATE_DIR,n=t,function(e,t){let a;if(!(!e||"localhost"===(a=new URL(e).hostname.trim().toLowerCase().replace(/^\[(.*)\]$/,"$1"))||(l.isIPv4(a)?e7.check(a,"ipv4"):!!l.isIPv6(a)&&e7.check(a,"ipv6")))&&("string"!=typeof t||!(t.trim().length>0)))throw new f("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."})}(u=function(e){let t;if(e){try{t=new URL(e)}catch(t){throw new f("INVALID_ARGS","Invalid daemon base URL",{daemonBaseUrl:e},t instanceof Error?t:void 0)}if("http:"!==t.protocol&&"https:"!==t.protocol)throw new f("INVALID_ARGS","Daemon base URL must use http or https",{daemonBaseUrl:e});return t.toString().replace(/\/+$/,"")}}(c=n.flags?.daemonBaseUrl??process.env.AGENT_DEVICE_DAEMON_BASE_URL),p=n.flags?.daemonAuthToken??process.env.AGENT_DEVICE_DAEMON_AUTH_TOKEN),I=function(e,t){let a=e.flags?.daemonTransport??process.env.AGENT_DEVICE_DAEMON_TRANSPORT,r=x(a);if(t&&"socket"===r)throw new f("INVALID_ARGS","Remote daemon base URL only supports HTTP transport. Remove --daemon-transport socket.",{daemonBaseUrl:t});return{preference:r,serverMode:k(e.flags?.daemonServerMode??process.env.AGENT_DEVICE_DAEMON_SERVER_MODE??("dual"===a?"dual":void 0))}}(t,(h={rawBaseUrl:c,remoteBaseUrl:u,authToken:p}).remoteBaseUrl),o=t,s=m,d=h.rawBaseUrl,{paths:_((v=ti(o.command)&&!s&&!d)?e.mkdtempSync(r.join(i.tmpdir(),"agent-device-replay-daemon-")):m),transportPreference:I.preference,serverMode:I.serverMode,ownedStateDir:v,remoteBaseUrl:h.remoteBaseUrl,remoteAuthToken:h.authToken}),M=function(e){if(e.command!==$.test){var t;return"number"==typeof e.flags?.timeoutMs&&((t=e.command)===$.prepare||t===$.replay||t===$.snapshot)?e.flags.timeoutMs:e.command===$.prepare?24e4:9e4}}(t),P=await w("daemon_startup",async()=>await te(S),{requestId:b,session:t.session}),D=P.info,E=await eD(t,D),N={...t,positionals:E.positionals,flags:E.flags,token:D.token,meta:{...t.meta??{},requestId:b,debug:A,cwd:t.meta?.cwd,sessionExplicit:t.meta?.sessionExplicit,tenantId:t.meta?.tenantId??t.flags?.tenant,runId:t.meta?.runId??t.flags?.runId,leaseId:t.meta?.leaseId??t.flags?.leaseId,sessionIsolation:t.meta?.sessionIsolation??t.flags?.sessionIsolation,lockPolicy:t.meta?.lockPolicy,lockPlatform:t.meta?.lockPlatform,...E.uploadedArtifactId?{uploadedArtifactId:E.uploadedArtifactId}:{},...E.clientArtifactPaths?{clientArtifactPaths:E.clientArtifactPaths}:{},...E.installSource?{installSource:E.installSource}:{}}};g({level:"info",phase:"daemon_request_prepare",data:{requestId:b,command:t.command,session:t.session}});try{return await w("daemon_request",async()=>await e0(D,N,S.transportPreference,S.paths,M),{requestId:b,command:t.command})}finally{await tn(t,P,S)}}e7.addSubnet("127.0.0.0",8,"ipv4"),e7.addAddress("::1","ipv6"),e7.addSubnet("::ffff:127.0.0.0",104,"ipv6");let tu=/^[0-9a-fA-F-]{32,36}$/;function tf(e){if(e&&tu.test(e))return e.replaceAll("-","").toUpperCase()}function tp(e,t){return`${e.uuid}:${tm(t)}`}function tm(e){return`0x${e.toString(16)}`}function th(e){return"string"==typeof e&&e.length>0?e:void 0}function ty(...e){for(let t of e){let e=th(t);if(e)return e}}function tw(e){return"object"==typeof e&&null!==e}function tg(e){return tw(e)?e:void 0}function tI(e){try{let t=JSON.parse(e);return tw(t)?t:null}catch{return null}}function tv(e){if("number"==typeof e&&Number.isSafeInteger(e))return e;if("string"==typeof e){let t=e.startsWith("0x")?Number.parseInt(e,16):Number(e);return Number.isSafeInteger(t)?t:void 0}}function tb(e,t,a){var r;if(!Object.hasOwn(e,t))return;let n="bigint"==typeof(r=e[t])?r:"number"==typeof r&&Number.isSafeInteger(r)?BigInt(r):"string"!=typeof r?void 0:/^(?:0x[0-9a-fA-F]+|\d+)$/.test(r)?BigInt(r):void 0;if(void 0!==n)return n;tA(a,t)}function tA(e,t){throw new f("INVALID_ARGS",`Invalid ${e} numeric field: ${t}`,{hint:"Crash artifact numeric fields must be integer numbers or integer numeric strings."})}function tS(e){return[...new Set(e)]}let tM=/^(?:arm64e?|arm64_32|x86_64|armv7[sk]?|i386)$/;async function tP(e){return e.dsym&&e.searchPath?[tN(e.cwd,e.dsym),...await tD(tN(e.cwd,e.searchPath))]:e.dsym?[tN(e.cwd,e.dsym)]:e.searchPath?await tD(tN(e.cwd,e.searchPath)):[]}async function tD(e){let t=[],a=0;async function n(i){if(!(t.length>=200)){if((a+=1)>1e4)throw new f("COMMAND_FAILED","debug symbols search-path scan exceeded bounds.",{searchPath:e,maxEntries:1e4,hint:"Pass --dsym <App.dSYM> directly or narrow --search-path to the build products directory."});if(!(await t_(i,e)).isDirectory()){i===e&&function(e){throw new f("INVALID_ARGS",`debug symbols search path is not a directory: ${e}`,{hint:"Pass an existing build products directory to --search-path, or pass --dsym <App.dSYM> directly."})}(e);return}if(i.endsWith(".dSYM"))return void t.push(i);for(let e of(await c.readdir(i,{withFileTypes:!0})))e.isDirectory()&&await n(r.join(i,e.name))}}return await n(e),t}async function t_(e,t){try{return await c.stat(e)}catch{throw new f("INVALID_ARGS",`debug symbols search path does not exist: ${t}`,{hint:"Pass an existing build products directory to --search-path, or pass --dsym <App.dSYM> directly."})}}async function tk(e,t){let a=(await Promise.all(tS(e).map(e=>tE(e,t)))).flat();if(0===a.length)throw new f("COMMAND_FAILED","No UUIDs found in dSYM bundle.",{hint:"Verify the path points to a built .dSYM bundle with DWARF contents."});return a}async function tE(e,t){var a;await tx(e);let r=await m(t,["--uuid",e],{timeoutMs:15e3,allowFailure:!0});if(0!==r.exitCode)throw new f("COMMAND_FAILED",`Failed to inspect dSYM UUIDs: ${e}`,{stderr:r.stderr,hint:"Verify the dSYM bundle is valid and readable."});return a=e,r.stdout.split("\n").flatMap(e=>{let t=e.match(/^UUID:\s+([0-9a-fA-F-]{32,36})\s+\(([^)]+)\)\s+(.+)$/),r=tf(t?.[1]);return t&&r?[{dsymPath:a,uuid:r,arch:t[2],binaryPath:t[3].trim()}]:[]})}async function tx(e){let t=await c.stat(e).catch(()=>null);if(!(t?.isDirectory()&&e.endsWith(".dSYM")))throw new f("INVALID_ARGS",`Not a .dSYM bundle: ${e}`,{hint:"Pass the .dSYM bundle path, not the DWARF executable inside it."})}function tN(e,t){return r.resolve(e,t)}function t$(e,t){let a=`${t}:`,r=e.find(e=>e.trimStart().startsWith(a));return r&&r.slice(r.indexOf(":")+1).trim()||void 0}function tT(e,t,a,r){return{index:e,image:t.name,address:tm(a),symbol:r.get(tp(t,a))?.text}}function tC(e){var t;let a;return[(a=(t=e).topFrames.find(e=>e.symbol))?`Start with ${a.symbol} in ${a.image}; it is the first symbolicated frame captured on the crashed thread.`:t.topFrames.length>0?"No symbolicated frame was found on the crashed thread; verify matching dSYMs for the top images.":void 0,e.exceptionType?`Exception: ${e.exceptionType}`:void 0,e.terminationReason?`Termination: ${e.terminationReason}`:void 0].filter(e=>!!e).slice(0,3)}async function tU(e,t,a){let r=new Map;for(let n of(function(e,t){let a=new Map;for(let r of e){let e=t.get(r.image.uuid);if(!e)continue;let n=`${r.image.uuid}:${e.dsym.binaryPath}`,i=a.get(n)??{...e,addresses:[]};i.addresses.push(r.address),a.set(n,i)}return a})(e,t).values())for(let e of(await tL(a,n)))r.set(tp(e.image,e.address),e);return r}async function tL(e,t){var a,r,n,i;let o,s,d=tS(t.addresses.map(tm)),l=await m(e,(a=t,r=d,["-arch",a.image.arch??a.dsym.arch??"arm64","-o",a.dsym.binaryPath,"-l",tm(a.image.base),...r]),{timeoutMs:3e4,allowFailure:!0});return 0!==l.exitCode&&function(e){throw new f("COMMAND_FAILED","atos failed while symbolicating crash frames.",{stderr:e,hint:"Verify the crash artifact and dSYM were produced from the same build and architecture."})}(l.stderr),n=t.image,i=d,s=(""===(o=l.stdout.split(/\r?\n/)).at(-1)&&o.pop(),o),i.map((e,t)=>{let a=s[t]?.trim();return{image:n,address:BigInt(e),text:!function(e,t){if(!e)return!1;let a=e.trim().toLowerCase();return!!a&&"??"!==a&&a!==t.toLowerCase()&&!a.startsWith("0x")}(a,e)?void 0:a}})}async function tR(){return{dwarfdump:await tO("dwarfdump"),atos:await tO("atos")}}async function tO(e){try{let t=await m("xcrun",["--find",e],{timeoutMs:5e3,allowFailure:!0}),a=t.stdout.trim();if(0===t.exitCode&&a.length>0)return a}catch{}throw new f("TOOL_MISSING",`Apple symbolication tool not found: ${e}`,{hint:"Install Xcode Command Line Tools and verify xcrun --find dwarfdump and xcrun --find atos succeed."})}async function tF(e){var t,a,n,i,o,s,d,l,u,p,m,h,y,w,g,I,v,b,A,S,M,P,D,_,k,E,x;let N,$,T,C,U,L,R,O,F;if(void 0!==e.action&&"symbols"!==e.action)throw new f("INVALID_ARGS","debug supports only the symbols workflow.",{hint:"Use debug symbols --artifact <crash.ips|crash.log> --dsym <App.dSYM> or --search-path <dir> --out <path>."});let B=e.cwd??process.cwd(),q=tj(B,e.artifact),j=tj(B,e.out??(a=q,$=(N=r.extname(a))?a.slice(0,-N.length):a,`${$}-symbolicated${N||".log"}`)),V=function(e){var t;let a,n=function(e){let t=tI(e);if(t)return{payload:t};let a=e.indexOf("\n");if(-1===a)return null;let r=e.slice(0,a),n=tI(e.slice(a+1));return n?{header:r,payload:n}:null}(e);if(!n)return null;let i=(Array.isArray(n.payload.usedImages)?n.payload.usedImages:[]).flatMap((e,t)=>(function(e,t){if(!e||"object"!=typeof e)return[];let a=tf(th(e.uuid)),n=tb(e,"base","IPS usedImages");if(!a||void 0===n)return[];let i=th(e.path);return[{index:t,name:th(e.name)??(i?r.basename(i):`image-${t}`),uuid:a,arch:th(e.arch),base:n,path:i}]})(e,t));if(0===i.length)return null;let o=(t=Array.isArray(n.payload.threads)?n.payload.threads:[],a=new Map(i.map(e=>[e.index,e])),t.flatMap((e,t)=>(function(e){if(!e||"object"!=typeof e)return[];let t=e.frames;return Array.isArray(t)?t.filter(e=>tw(e)):[]})(e).flatMap((e,r)=>(function(e,t,a,r){let n=function(e,t,a){if(!Object.hasOwn(e,t))return;let r=tv(e[t]);if(void 0!==r)return r;tA(a,t)}(e,"imageIndex","IPS frame"),i=tb(e,"imageOffset","IPS frame");if(void 0===n||void 0===i)return[];let o=t.get(n);return o?[{frame:e,frameIndex:r,threadIndex:a,image:o,address:o.base+i}]:[]})(e,a,t,r))));return{format:"ips",images:i,addresses:o.map(({frame:e,...t})=>t),document:n,frameMatches:o,write:e=>(function(e,t,a){for(let e of t){let t=a.get(tp(e.image,e.address))?.text;t&&function(e,t){let a,r=(a=t.match(/^(.*) \+ (\d+)$/))?{symbol:a[1],location:Number(a[2])}:{symbol:t};e.symbol=r.symbol,void 0!==r.location&&(e.symbolLocation=r.location)}(e.frame,t)}e.payload.agentDeviceSymbolication={tool:"agent-device debug symbols",symbolicatedFrames:[...a.values()].filter(e=>e.text).length};let r=`${JSON.stringify(e.payload,null,2)}
|
|
5
|
+
`;return e.header?`${e.header}
|
|
6
|
+
${r}`:r})(n,o,e)}}(t=await tB(q,"crash artifact"))??function(e){let t=e.split("\n"),a=function(e){let t=[],a=e.findIndex(e=>/^Binary Images:/i.test(e.trim()));if(-1===a)return t;for(let n of e.slice(a+1)){let e=function(e){let t=e.match(/^\s*(0x[0-9a-fA-F]+)\s*-\s*(0x[0-9a-fA-F]+)\s+\+?(.+?)\s+<([0-9a-fA-F-]{32,36})>\s+(.+)$/);if(!t)return null;let a=tf(t[4]);if(!a)return null;let n=function(e,t){let a=e.split(/\s+/),n=a.at(-1);if(n&&tM.test(n))return{name:a.slice(0,-1).join(" ").trim(),arch:n};let i=r.basename(t);return{name:e.startsWith(i)?i:e}}(t[3].trim(),t[5].trim());return{name:n.name,arch:n.arch,uuid:a,base:BigInt(t[1]),end:BigInt(t[2]),path:t[5].trim()}}(n);e&&t.push(e)}return t}(t);if(0===a.length)return null;let n=function(e,t){let a,r=[];for(let[n,i]of e.entries()){let e=i.match(/^Thread\s+(\d+)\s+Crashed:/);e?a=Number(e[1]):(0===i.trim().length||/^Thread\s+\d+/.test(i))&&(a=void 0);let o=function(e,t){let a=e.match(/^\s*\d+\s+(.+?)\s+(0x[0-9a-fA-F]+)\b/);if(!a)return null;let r=a[1].trim(),n=BigInt(a[2]),i=function(e,t,a){let r=e.filter(e=>e.name===t);return r.find(e=>{var t,r;return t=e,r=a,void 0!==t.end&&t.base<=r&&r<=t.end})??(1===r.length?r[0]:void 0)}(t,r,n);return i?{image:i,address:n}:null}(i,t),s=i.match(/^\s*(\d+)/);o&&s&&r.push({...o,frameIndex:Number(s[1]),lineIndex:n,threadIndex:a})}return r}(t,a);return{format:"text",images:a,addresses:n,lines:t,frameMatches:n,write(e){let a=new Map(n.map(e=>[e.lineIndex,e]));return t.map((t,r)=>{let n=a.get(r);if(!n)return t;let i=e.get(tp(n.image,n.address))?.text;return!i||t.includes(i)?t:`${t} // ${i}`}).join("\n")}}}(t);V||function(){throw new f("UNSUPPORTED_OPERATION","debug symbols currently supports Apple crash artifacts with Binary Images or IPS usedImages.",{hint:"For Android Java/R8 crashes, use retrace with mapping.txt. For Android native crashes, use ndk-stack or addr2line with unstripped .so symbols. Capture the crash with logs, then symbolicate externally until Android support is added."})}();let G=await tP({cwd:B,dsym:e.dsym,searchPath:e.searchPath});if(0===G.length)throw new f("INVALID_ARGS","debug symbols requires --dsym or --search-path.",{hint:"Pass a matching .dSYM bundle directly, or pass --search-path <dir> so agent-device can match crash image UUIDs to local dSYMs."});let H=await tR(),K=await tk(G,H.dwarfdump),z=function(e,t,a){let r=new Map;for(let a of e){let e=t.find(e=>e.uuid===a.uuid&&(void 0===a.arch||void 0===e.arch||e.arch===a.arch));e&&r.set(a.uuid,{image:a,dsym:e})}if(r.size>0)return r;let n=tS(e.map(e=>e.uuid)),i=tS(t.map(e=>e.uuid));throw new f("COMMAND_FAILED",a?"dSYM UUID does not match any Apple image in the crash artifact.":"No matching dSYM UUID found under search path.",{artifactUuidCount:n.length,artifactUuidSample:n.slice(0,5),dsymUuidCount:i.length,dsymUuidSample:i.slice(0,5),hint:"Use dwarfdump --uuid <App.dSYM> and compare it with the crash Binary Images or usedImages UUID, then pass the matching dSYM/search path."})}(V.images,K,!!e.dsym),Y=await tU(V.addresses,z,H.atos),W=V.write(Y);await c.mkdir(r.dirname(j),{recursive:!0}),await c.writeFile(j,W,"utf8");let J=[...z.values()].map(({image:e,dsym:t})=>({name:e.name,uuid:e.uuid,arch:e.arch??t.arch,dsymPath:t.dsymPath,binaryPath:t.binaryPath})),X=[...Y.values()].filter(e=>e.text).length,Q=V.images.length-J.length,Z=Q>0?[`${Q} Apple image${1===Q?"":"s"} had no matching dSYM and were left unchanged.`]:void 0;return{kind:"debugSymbols",platform:"apple",artifactPath:q,outPath:j,crash:"ips"===V.format?(n=V.document,i=V.frameMatches,o=Y,U=function(e){let t=tv(e.faultingThread);if(void 0!==t)return t;let a=(Array.isArray(e.threads)?e.threads:[]).findIndex(e=>tg(e)?.triggered===!0);return -1===a?void 0:a}(n.payload),{...L={format:"ips",...(T=(s=n).payload,C=(d=s.header)?tI(d):null,{appName:(l=T,u=C,ty(l.procName,u?.app_name,u?.name)),bundleId:(p=T,m=C,ty(tg(p.bundleInfo)?.CFBundleIdentifier,m?.bundleID)),version:(h=T,y=C,ty(tg(h.bundleInfo)?.CFBundleShortVersionString,y?.app_version)),incident:(w=T,g=C,ty(w.incident,g?.incident_id)),timestamp:(I=T,v=C,ty(I.captureTime,v?.timestamp)),exceptionType:(b=T.exception,th(tg(b)?.type)),exceptionCodes:function(e){let t=tg(e);if(t)return ty(t.codes,t.rawCodes)}(T.exception),terminationReason:function(e){let t=tg(e);if(t){let e;return(e=[th(t.namespace),th(t.code),th(t.reason)].filter(e=>!!e)).length>0?e.join(" "):void 0}}(T.termination)}),crashedThread:U,topFrames:(A=i,S=U,M=o,A.filter(e=>void 0===S||e.threadIndex===S).slice(0,5).map(e=>tT(e.frameIndex,e.image,e.address,M))),findings:[]},findings:tC(L)}):(P=V.lines,D=V.frameMatches,_=Y,O=function(e){let t=t$(e,"Triggered by Thread"),a=t?Number.parseInt(t,10):NaN;if(Number.isSafeInteger(a))return a;for(let t of e){let e=t.match(/^Thread\s+(\d+)\s+Crashed:/);if(e)return Number(e[1])}}(P),{...F={format:"text",appName:(R=t$(P,"Process"),R?.replace(/\s+\[\d+\]$/,"")),bundleId:t$(P,"Identifier"),version:t$(P,"Version"),incident:t$(P,"Incident Identifier"),timestamp:t$(P,"Date/Time"),exceptionType:t$(P,"Exception Type"),exceptionCodes:t$(P,"Exception Codes"),terminationReason:t$(P,"Termination Reason"),crashedThread:O,topFrames:(k=D,E=O,x=_,void 0===E?[]:k.filter(e=>e.threadIndex===E).slice(0,5).map(e=>tT(e.frameIndex,e.image,e.address,x))),findings:[]},findings:tC(F)}),matchedImages:J,symbolicatedFrames:X,skippedImages:Q,warnings:Z,message:`Symbolicated ${X} frame${1===X?"":"s"} -> ${j}`}}async function tB(e,t){await tq(e,t);try{return await c.readFile(e,"utf8")}catch(a){throw new f("INVALID_ARGS",`Failed to read ${t}: ${e}`,{message:a instanceof Error?a.message:String(a)})}}async function tq(e,t){try{let a=await c.stat(e);if(a.size<=0x4000000)return;throw new f("INVALID_ARGS",`${t} is too large: ${e}`,{actualBytes:a.size,maxBytes:0x4000000,hint:"Pass a bounded Apple .ips/.crash artifact. For very large logs, first narrow the log to the crash report, or use logs grep/tail for lead-up context."})}catch(a){if(a instanceof f)throw a;throw new f("INVALID_ARGS",`Failed to read ${t}: ${e}`,{message:a instanceof Error?a.message:String(a)})}}function tj(e,t){return r.resolve(e,t)}let tV={...V,...Z,...Q,...et,...ea,...G,...ee,...X,...eo,...K,...Y,batch:er(function(e,t){let a=tV[e];if(!a)throw Error(`Missing daemon writer for batch command: ${e}`);return a(t)})};function tG(e={},t={}){let a=t.transport??tc,r=async(t,r=[],n={})=>{let i=tK(e,n),o=await a({session:W(i.session),command:t,positionals:r,flags:J(i),runtime:i.runtime,meta:z(i)});return o.ok||function(e){throw new f(u(e.code),e.message,{...e.details??{},hint:e.hint,diagnosticId:e.diagnosticId,logPath:e.logPath})}(o.error),o.data??{}},n=async(e={})=>{let t=await r(N.sessionList,[],e);return(Array.isArray(t.sessions)?t.sessions:[]).map(L)},i=async(e,t={})=>{let a=tV[e](t);return await r(a.command,a.positionals,a.options)},o=(t={})=>W(tK(e,t).session);return{command:{wait:async e=>await i("wait",e),alert:async(e={})=>await i("alert",e),appState:async(e={})=>await i("appstate",e),back:async(e={})=>await i("back",e),home:async(e={})=>await i("home",e),rotate:async e=>await i("rotate",e),appSwitcher:async(e={})=>await i("app-switcher",e),keyboard:async(e={})=>await i("keyboard",e),clipboard:async e=>await i("clipboard",e),reactNative:async e=>await i("react-native",e),prepare:async e=>await i("prepare",e)},devices:{list:async(e={})=>{let t=await i("devices",e);return(Array.isArray(t.devices)?t.devices:[]).map(ei)},boot:async(e={})=>await i("boot",e),shutdown:async(e={})=>await i("shutdown",e)},sessions:{list:async(e={})=>await n(e),stateDir:async(t={})=>_(tK(e,t).stateDir??process.env.AGENT_DEVICE_STATE_DIR).baseDir,close:async(e={})=>{let t=o(e),a=(await i("close",e)).shutdown;return{session:t,shutdown:"object"==typeof a&&null!==a?a:void 0,identifiers:{session:t}}}},apps:{install:async e=>j(await i("install",e),o(e)),reinstall:async e=>j(await i("reinstall",e),o(e)),installFromSource:async e=>el(await i("install-from-source",e),o(e)),list:async(e={})=>{let t=await i("apps",e);return Array.isArray(t.apps)?t.apps.filter(e=>"string"==typeof e):[]},open:async e=>{let t=o(e),a=await i("open",e),r=H(a),n=F(a,"appBundleId");return{session:t,sessionStateDir:F(a,"sessionStateDir"),appName:F(a,"appName"),appBundleId:n,appId:n,startup:ed(a.startup),runtime:en(a.runtime),device:r,identifiers:{session:t,deviceId:r?.id,deviceName:r?.name,udid:r?.ios?.udid,serial:r?.android?.serial,appId:n,appBundleId:n}}},close:async(e={})=>{let t=o(e),a=(await i("close",e)).shutdown;return{session:t,closedApp:e.app,shutdown:"object"==typeof a&&null!==a?a:void 0,identifiers:{session:t}}},push:async e=>await i("push",e),triggerEvent:async e=>await i("trigger-app-event",e)},materializations:{release:async e=>B(await r(N.releaseMaterializedPaths,[],{...e,materializationId:e.materializationId}))},leases:{allocate:async e=>tz(await r(N.leaseAllocate,[],{...e,leaseId:void 0,leaseTtlMs:e.ttlMs})),heartbeat:async e=>tz(await r(N.leaseHeartbeat,[],{...e,leaseTtlMs:e.ttlMs})),release:async e=>({released:!0===(await r(N.leaseRelease,[],e)).released})},metro:{prepare:async t=>await eu({projectRoot:t.projectRoot??e.cwd,kind:t.kind,publicBaseUrl:t.publicBaseUrl,proxyBaseUrl:t.proxyBaseUrl,proxyBearerToken:t.bearerToken,bridgeScope:t.bridgeScope,launchUrl:t.launchUrl,companionProfileKey:t.companionProfileKey,companionConsumerKey:t.companionConsumerKey,metroPort:t.port,listenHost:t.listenHost,statusHost:t.statusHost,startupTimeoutMs:t.startupTimeoutMs,probeTimeoutMs:t.probeTimeoutMs,reuseExisting:t.reuseExisting,installDependenciesIfNeeded:t.installDependenciesIfNeeded,runtimeFilePath:t.runtimeFilePath,logPath:t.logPath}),reload:async(t={})=>await ec({metroHost:t.metroHost,metroPort:t.metroPort,bundleUrl:t.bundleUrl,runtime:e.runtime,timeoutMs:t.timeoutMs})},capture:{snapshot:async(e={})=>{var t,a,r;let n,s,d,l,c=o(e);return t=await i("snapshot",e),a=c,n=F(t,"appBundleId"),{nodes:q(t.nodes),truncated:!0===t.truncated,appName:F(t,"appName"),appBundleId:n,...(s=tH((r=t).visibility),d=tH(r.unchanged),l=b(r.snapshotDiagnostics),{...s?{visibility:s}:{},...O(r),...d?{unchanged:d}:{},...l?{snapshotDiagnostics:l}:{}}),identifiers:{session:a,appId:n,appBundleId:n}}},screenshot:async(e={})=>{let t=o(e),a=await i("screenshot",e);return{path:R(a,"path"),overlayRefs:es(a),identifiers:{session:t}}},diff:async e=>await i("diff",e)},interactions:{click:async e=>await i("click",e),press:async e=>await i("press",e),longPress:async e=>await i("longpress",e),swipe:async e=>await i("swipe",e),pan:async e=>await i("gesture-pan",e),fling:async e=>await i("gesture-fling",e),swipeGesture:async e=>await i("gesture-swipe",e),focus:async e=>await i("focus",e),type:async e=>await i("type",e),fill:async e=>await i("fill",e),scroll:async e=>await i("scroll",e),pinch:async e=>await i("gesture-pinch",e),rotateGesture:async e=>await i("gesture-rotate",e),transformGesture:async e=>await i("gesture-transform",e),get:async e=>await i("get",e),is:async e=>await i("is",e),find:async e=>await i("find",e)},replay:{run:async e=>await i("replay",e),test:async e=>await i("test",e)},batch:{run:async e=>await i("batch",e)},observability:{perf:async(e={})=>await i("perf",e),logs:async(e={})=>await i("logs",e),network:async(e={})=>await i("network",e)},debug:{symbols:async t=>await tF({cwd:t.cwd??e.cwd,...t})},recording:{record:async e=>await i("record",e),trace:async e=>await i("trace",e)},settings:{update:async e=>await i("settings",e)}}}function tH(e){return"object"==typeof e&&null!==e?e:void 0}function tK(e,t){return{...e,...t}}function tz(e){let t=e.lease;if(!t||"object"!=typeof t||Array.isArray(t))throw Error("Invalid lease response from daemon");return{leaseId:R(t,"leaseId"),tenantId:R(t,"tenantId"),runId:R(t,"runId"),backend:R(t,"backend"),createdAt:"number"==typeof t.createdAt?t.createdAt:void 0,heartbeatAt:"number"==typeof t.heartbeatAt?t.heartbeatAt:void 0,expiresAt:"number"==typeof t.expiresAt?t.expiresAt:void 0}}export{tG as createAgentDeviceClient,eH as formatDurationSeconds,tc as sendToDaemon};
|
package/dist/src/9616.js
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
import
|
|
1
|
+
import{AppError as e}from"./9152.js";let t=["ios","macos","android","linux","apple"],r=["mobile","tv","desktop"];function a(e){return e}function n(e){return"apple"===e||"ios"===e||"macos"===e}function i(e,t){return!t||("apple"===t?n(e):e===t)}function o(e){return"macos"===e||"desktop"===e?"macOS":"tv"===e?"tvOS":"iOS"}function l(e){let{simulatorSetPath:t,platform:r,target:a}=e;if(t&&"macos"!==r&&"desktop"!==a)return t}async function s(t,r,a={}){let o=t,l=e=>e.toLowerCase().replace(/_/g," ").replace(/\s+/g," ").trim();if(r.platform&&(o=o.filter(e=>i(e.platform,r.platform))),r.target&&(o=o.filter(e=>(e.target??"mobile")===r.target)),r.udid){let t=o.find(e=>e.id===r.udid&&n(e.platform));if(!t)throw new e("DEVICE_NOT_FOUND",`No Apple device with UDID ${r.udid}`);return t}if(r.serial){let t=o.find(e=>e.id===r.serial&&"android"===e.platform);if(!t)throw new e("DEVICE_NOT_FOUND",`No Android device with serial ${r.serial}`);return t}if(r.deviceName){let t=l(r.deviceName),a=o.find(e=>l(e.name)===t);if(!a)throw new e("DEVICE_NOT_FOUND",`No device named ${r.deviceName}`);return a}let d=o[0];if(void 0!==d&&1===o.length)return d;if(0===o.length){var c;let t=a.simulatorSetPath;if(t&&(!(c=r.platform)||"apple"===c||"ios"===c))throw new e("DEVICE_NOT_FOUND","No devices found in the scoped simulator set",{simulatorSetPath:t,hint:`The simulator set at "${t}" appears to be empty. Create a simulator first:
|
|
2
|
+
xcrun simctl --set "${t}" create "iPhone 16" com.apple.CoreSimulator.SimDeviceType.iPhone-16 com.apple.CoreSimulator.SimRuntime.iOS-18-0`,selector:r});throw new e("DEVICE_NOT_FOUND","No devices found",{selector:r})}let u=o.filter(e=>"device"!==e.kind);u.length>0&&(o=u);let m=o.filter(e=>e.booted),f=m[0];if(void 0!==f&&1===m.length)return f;let p=m[0]??o[0];if(void 0===p)throw new e("DEVICE_NOT_FOUND","No devices found",{selector:r});return p}function d(e){return e.map((e,t)=>({...e,ref:`e${t+1}`}))}function c(e){let t=e.trim();return t.startsWith("@")?t.slice(1)||null:t.startsWith("e")?t:null}function u(e,t){return e.find(e=>e.ref===t)??null}function m(e){return JSON.stringify({interactiveOnly:e?.interactiveOnly===!0,depth:"number"==typeof e?.depth?e.depth:null,scope:e?.scope?.trim()||null,raw:e?.raw===!0})}function f(e){if(e)return{depth:e.snapshotDepth,interactiveOnly:e.snapshotInteractiveOnly,raw:e.snapshotRaw,scope:e.snapshotScope}}function p(e){return{x:Math.round(e.x+e.width/2),y:Math.round(e.y+e.height/2)}}let h=["reject","strip"],$=["ios-simulator","ios-instance","android-instance"],E=["socket","http","dual"],I=["auto","socket","http"],v=["none","tenant"],S=["summary","headers","body","all"];function N(e){return{parse:t=>e(t,"$")}}function O(e,t){throw Error(`${e}: ${t}`)}function _(e,t){return(!e||"object"!=typeof e||Array.isArray(e))&&O(t,"Expected an object"),e}function g(e,t){return"string"!=typeof e&&O(t,"Expected a string"),e}function y(e,t){let r=g(e,t).trim();return r||O(t,"Expected a non-empty string"),r}function P(e,t){return Number.isInteger(e)||O(t,"Expected an integer"),e}function b(e,t,r){let a=e[t];return void 0===a?void 0:g(a,`${r}.${t}`)}function w(e,t,r){let a=e[t];if(void 0!==a)return"boolean"!=typeof a&&O(`${r}.${t}`,"Expected a boolean"),a}function A(e,t,r){let a=e[t];return void 0===a?void 0:P(a,`${r}.${t}`)}function D(e,t,r){let a=e[t];return void 0===a?void 0:_(a,`${r}.${t}`)}function M(e,t,r,a){let n=e[t];if(void 0!==n)return"string"==typeof n&&r.includes(n)||O(`${a}.${t}`,`Expected one of: ${r.join(", ")}`),n}function R(e,t){let r=_(e,t),a={};for(let[e,n]of Object.entries(r))a[e]=g(n,`${t}.${e}`);return a}let k=N((e,t)=>{let r=_(e,t);return{platform:M(r,"platform",["ios","android"],t),metroHost:b(r,"metroHost",t),metroPort:A(r,"metroPort",t),bundleUrl:b(r,"bundleUrl",t),launchUrl:b(r,"launchUrl",t)}}),x=N((e,r)=>{var a,n;let i=_(e,r),o=(a=i.positionals,n=`${r}.positionals`,Array.isArray(a)||O(n,"Expected an array"),a),l=D(i,"meta",r);return{token:b(i,"token",r),session:b(i,"session",r),command:g(i.command,`${r}.command`),positionals:o.map((e,t)=>g(e,`${r}.positionals[${String(t)}]`)),flags:D(i,"flags",r),runtime:void 0===i.runtime?void 0:k.parse(i.runtime),meta:void 0===l?void 0:{requestId:b(l,"requestId",`${r}.meta`),debug:w(l,"debug",`${r}.meta`),cwd:b(l,"cwd",`${r}.meta`),sessionExplicit:w(l,"sessionExplicit",`${r}.meta`),tenantId:b(l,"tenantId",`${r}.meta`),runId:b(l,"runId",`${r}.meta`),leaseId:b(l,"leaseId",`${r}.meta`),leaseTtlMs:A(l,"leaseTtlMs",`${r}.meta`),leaseBackend:M(l,"leaseBackend",$,`${r}.meta`),sessionIsolation:M(l,"sessionIsolation",v,`${r}.meta`),uploadedArtifactId:b(l,"uploadedArtifactId",`${r}.meta`),clientArtifactPaths:void 0===l.clientArtifactPaths?void 0:R(l.clientArtifactPaths,`${r}.meta.clientArtifactPaths`),installSource:void 0===l.installSource?void 0:function(e,t){let r=_(e,t),a=g(r.kind,`${t}.kind`);if("url"===a){let e=g(r.url,`${t}.url`),n=void 0===r.headers?void 0:R(r.headers,`${t}.headers`);return n?{kind:a,url:e,headers:n}:{kind:a,url:e}}if("path"===a)return{kind:a,path:g(r.path,`${t}.path`)};if("github-actions-artifact"===a){let e,a,n,i,o;return e=y(r.owner,`${t}.owner`),a=y(r.repo,`${t}.repo`),n=void 0!==r.artifactId,i=void 0!==r.runId,o=void 0!==r.artifactName,(n&&(i||o)&&O(`${t}`,"Expected either artifactId or artifactName, not both"),n||!i||o||O(`${t}`,"Expected artifactName when runId is specified"),n||o||O(`${t}`,"Expected artifactId or artifactName"),n)?{kind:"github-actions-artifact",owner:e,repo:a,artifactId:P(r.artifactId,`${t}.artifactId`)}:{kind:"github-actions-artifact",owner:e,repo:a,...i?{runId:P(r.runId,`${t}.runId`)}:{},artifactName:y(r.artifactName,`${t}.artifactName`)}}O(`${t}.kind`,'Expected "url", "path", or "github-actions-artifact"')}(l.installSource,`${r}.meta.installSource`),retainMaterializedPaths:w(l,"retainMaterializedPaths",`${r}.meta`),materializedPathRetentionMs:A(l,"materializedPathRetentionMs",`${r}.meta`),materializationId:b(l,"materializationId",`${r}.meta`),lockPolicy:M(l,"lockPolicy",h,`${r}.meta`),lockPlatform:M(l,"lockPlatform",t,`${r}.meta`)}}});function C(e,t){return{token:b(e,"token",t),session:b(e,"session",t),tenantId:b(e,"tenantId",t),tenant:b(e,"tenant",t),runId:b(e,"runId",t)}}let T=N((e,t)=>{let r=_(e,t);return{...C(r,t),ttlMs:A(r,"ttlMs",t),backend:M(r,"backend",$,t)}}),U=N((e,t)=>{let r,a={record:r=_(e,t),leaseId:b(r,"leaseId",t),ttlMs:A(r,"ttlMs",t)};return{...C(a.record,t),leaseId:a.leaseId,ttlMs:a.ttlMs}}),F=N((e,t)=>{let r=_(e,t);return void 0!==r.ttlMs&&O(`${t}.ttlMs`,"Unexpected field"),{...C(r,t),leaseId:b(r,"leaseId",t)}}),j=N((e,t)=>{let r,a=_(e,t);return{jsonrpc:b(a,"jsonrpc",t),id:(null==(r=a.id)||"string"!=typeof r&&"number"!=typeof r&&O(`${t}.id`,"Expected a string, number, or null"),r),method:b(a,"method",t),params:a.params}});export{h as DAEMON_LOCK_POLICIES,E as DAEMON_SERVER_MODES,I as DAEMON_TRANSPORT_PREFERENCES,r as DEVICE_TARGETS,$ as LEASE_BACKENDS,S as NETWORK_INCLUDE_MODES,t as PLATFORM_SELECTORS,v as SESSION_ISOLATION_MODES,d as attachRefs,m as buildSnapshotPresentationKey,p as centerOfRect,x as daemonCommandRequestSchema,k as daemonRuntimeSchema,u as findNodeByRef,n as isApplePlatform,j as jsonRpcRequestSchema,T as leaseAllocateSchema,U as leaseHeartbeatSchema,F as leaseReleaseSchema,i as matchesPlatformSelector,a as normalizePlatformSelector,c as normalizeRef,o as resolveApplePlatformName,l as resolveAppleSimulatorSetPathForSelector,s as resolveDevice,f as snapshotPresentationOptionsFromFlags};
|
package/dist/src/9818.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{AsyncLocalStorage as t}from"node:async_hooks";import{constants as e}from"node:fs";import{access as r,stat as n}from"node:fs/promises";import
|
|
1
|
+
import{AsyncLocalStorage as t}from"node:async_hooks";import{constants as e}from"node:fs";import{access as r,stat as n}from"node:fs/promises";import o from"node:path";import{spawn as i,spawnSync as u}from"node:child_process";import{Readable as d}from"node:stream";import{pipeline as s}from"node:stream/promises";import{AppError as a}from"./9152.js";let f=/^[A-Za-z0-9][A-Za-z0-9._+-]*$/,c=[".com",".exe",".bat",".cmd"],l=new t;async function m(t,e){return t?await l.run(t,e):await e()}async function p(t){return await l.run(void 0,t)}async function w(t,e,r={}){let n=l.getStore()?.(t,e,r);return n?await n:await v(t,e,r)}async function h(t,e,r={}){let n=l.getStore()?.(t,e,r);return n?await n:await v(t,e,r)}function v(t,e,r={}){let n=O(t);return new Promise((o,u)=>{let d=i(n,e,{cwd:r.cwd,env:r.env,stdio:["pipe","pipe","pipe"],detached:r.detached,windowsHide:!0,shell:!1});r.onSpawn?.(d);let s="",f=r.binaryStdout?[]:void 0,c="",l=!1,m=P(r.timeoutMs),p=m?setTimeout(()=>{l=!0,H(d,r.detached)},m):null,w=B(d,r);r.binaryStdout||d.stdout.setEncoding("utf8"),d.stderr.setEncoding("utf8"),G(d,r.stdin).catch(o=>{var i,s,f,c;w.didAbort||l||(i=o)instanceof Error&&"code"in i&&"EPIPE"===i.code||(u((s=n,f=t,new a("COMMAND_FAILED",`Failed to write stdin for ${s}`,{cmd:f,args:e},(c=o)instanceof Error?c:void 0))),H(d,r.detached))}),d.stdout.on("data",t=>{if(r.binaryStdout)return void f?.push(Buffer.isBuffer(t)?t:Buffer.from(t));let e=String(t);s+=e,r.onStdoutChunk?.(e)}),d.stderr.on("data",t=>{let e=String(t);c+=e,r.onStderrChunk?.(e)}),d.on("error",r=>{p&&clearTimeout(p),w.dispose(),u(L(w,n,t,e,r))}),d.on("close",i=>{p&&clearTimeout(p),w.dispose();let d=i??1;if(!w.didAbort&&l&&m){var h,v,A,S,b,E;return void u((h=n,v=t,A=e,S=m,b=d,E=s,new a("COMMAND_FAILED",`${h} timed out after ${S}ms`,{cmd:v,args:A,stdout:E,stderr:c,exitCode:b,timeoutMs:S})))}let g=N(w,n,t,e,d,r.allowFailure,s,c);g?u(g):o({stdout:s,stderr:c,exitCode:d,stdoutBuffer:f?Buffer.concat(f):void 0})})})}async function A(t){let e=D(t);if(!e)return!1;if(o.isAbsolute(e))return F(e);let r=process.env.PATH;if(!r)return!1;let n=function(){if("win32"!==process.platform)return[""];let t=process.env.PATHEXT;if(!t)return c;let e=t.split(";").map(t=>t.trim().toLowerCase()).filter(t=>t.length>0);return e.length>0?e:c}();for(let t of r.split(o.delimiter)){let r=t.trim();if(r){for(let t of function(t,e){if("win32"!==process.platform)return[t];let r=t.toLowerCase();return e.some(t=>r.endsWith(t))?[t]:e.map(e=>`${t}${e}`)}(e,n))if(await F(o.join(r,t)))return!0}}return!1}async function S(t,e){let r=x(t,e,"executable");if(r){if(!await F(r))throw new a("TOOL_MISSING",`${e} points to a missing or non-executable file: ${r}`,{envName:e,path:r});return r}}async function b(t,e){let r=x(t,e,"file");if(r){if(!await T(r))throw new a("TOOL_MISSING",`${e} points to a missing or non-file path: ${r}`,{envName:e,path:r});return r}}function E(t,e,r={}){let n=O(t),o=u(n,e,{cwd:r.cwd,env:r.env,stdio:["pipe","pipe","pipe"],encoding:r.binaryStdout?void 0:"utf8",input:r.stdin,timeout:P(r.timeoutMs),windowsHide:!0,shell:!1,...void 0!==r.maxBuffer?{maxBuffer:r.maxBuffer}:{}});if(o.error){let i=o.error.code;if("ETIMEDOUT"===i)throw new a("COMMAND_FAILED",`${n} timed out after ${P(r.timeoutMs)}ms`,{cmd:t,args:e,timeoutMs:P(r.timeoutMs)},o.error);if("ENOENT"===i)throw I(n,t,o.error);throw C(n,t,e,o.error)}let i=r.binaryStdout?Buffer.isBuffer(o.stdout)?o.stdout:Buffer.from(o.stdout??""):void 0,d=r.binaryStdout?"":"string"==typeof o.stdout?o.stdout:(o.stdout??"").toString(),s="string"==typeof o.stderr?o.stderr:(o.stderr??"").toString(),f=o.status??1;if(0!==f&&!r.allowFailure)throw $(n,t,e,f,d,s);return{stdout:d,stderr:s,exitCode:f,stdoutBuffer:i}}function g(t,e,r={}){return y(t,e,r).pid}function y(t,e,r={}){let n=i(O(t),e,{cwd:r.cwd,env:r.env,stdio:r.stdio??"ignore",detached:!0,windowsHide:!0,shell:!1}),o=n.pid??0,u=new Promise(t=>{n.once("error",e=>{t({pid:o,error:e.message})}),n.once("exit",(e,r)=>{t({pid:o,..."number"==typeof e?{exitCode:e}:{},...r?{signal:r}:{}})})});return n.unref(),{pid:o,exited:u}}function M(t,e,r={}){let n=O(t),o=i(n,e,{cwd:r.cwd,env:r.env,stdio:r.stdio??["ignore","pipe","pipe"],detached:r.detached,windowsHide:!0,shell:!1}),u="",d="",s=r.captureOutput??!0,a=B(o,r);s&&(o.stdout?.setEncoding("utf8"),o.stderr?.setEncoding("utf8"),o.stdout?.on("data",t=>{u+=t}),o.stderr?.on("data",t=>{d+=t}));let f=new Promise((i,s)=>{o.on("error",r=>{a.dispose(),s(L(a,n,t,e,r))}),o.on("close",o=>{a.dispose();let f=o??1,c=N(a,n,t,e,f,r.allowFailure,u,d);c?s(c):i({stdout:u,stderr:d,exitCode:f})})});return{child:o,wait:f}}function O(t){let e=D(t);if(!e)throw new a("INVALID_ARGS",`Invalid executable command: ${JSON.stringify(t)}`,{cmd:t,hint:"Use a bare command name from PATH or an absolute executable path."});return e}function I(t,e,r){return new a("TOOL_MISSING",`${t} not found in PATH`,{cmd:e},r)}function C(t,e,r,n){return new a("COMMAND_FAILED",`Failed to run ${t}`,{cmd:e,args:r},n)}function _(t,e,r){return new a("COMMAND_FAILED","request canceled",{cmd:e,args:r,executable:t,reason:"request_canceled"})}function $(t,e,r,n,o,i){return new a("COMMAND_FAILED",`${t} exited with code ${n}`,{cmd:e,args:r,stdout:o,stderr:i,exitCode:n,processExitError:!0})}function L(t,e,r,n,o){return t.didAbort?_(e,r,n):"ENOENT"===o.code?I(e,r,o):C(e,r,n,o)}function N(t,e,r,n,o,i,u,d){return t.didAbort?_(e,r,n):0===o||i?null:$(e,r,n,o,u,d)}function x(t,e,r){let n=t?.trim();if(n){if(!o.isAbsolute(n)||n.includes("\0"))throw new a("INVALID_ARGS",`${e} must be an absolute ${r} path, not ${JSON.stringify(t)}`,{envName:e,path:t});return n}}function D(t){let e=t.trim();return!e||e.includes("\0")?null:o.isAbsolute(e)?e:e.includes("/")||e.includes("\\")?null:f.test(e)?e:null}async function F(t){try{if(!await T(t))return!1;return await r(t,"win32"===process.platform?e.F_OK:e.X_OK),!0}catch{return!1}}async function T(t){try{return(await n(t)).isFile()}catch{return!1}}function P(t){if(!Number.isFinite(t))return;let e=Math.floor(t);if(!(e<=0))return e}function B(t,e){let r=!1,n=()=>{r=!0,H(t,e.detached)};return e.signal?.aborted?n():e.signal?.addEventListener("abort",n,{once:!0}),{get didAbort(){return r},dispose:()=>{e.signal?.removeEventListener("abort",n)}}}function H(t,e){if(e&&t.pid&&"win32"!==process.platform)try{process.kill(-t.pid,"SIGKILL");return}catch{}t.kill("SIGKILL")}async function G(t,e){if(t.stdin){if(void 0===e)return void t.stdin?.end();await s(d.from([e]),t.stdin)}}export{F as isExecutablePath,S as resolveExecutableOverridePath,b as resolveFileOverridePath,w as runCmd,M as runCmdBackground,g as runCmdDetached,y as runCmdDetachedMonitored,h as runCmdStreaming,E as runCmdSync,A as whichCmd,m as withCommandExecutorOverride,p as withoutCommandExecutorOverride};
|
package/dist/src/android.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import e from"node:crypto";import t from"node:fs/promises";import r from"node:path";import{promises as i}from"node:fs";import{normalizeError as a,AppError as n}from"./9152.js";import{withDiagnosticTimer as o,emitDiagnostic as s}from"./7599.js";import{readVersion as d,findProjectRoot as l}from"./9671.js";import{resolveAndroidTouchInjector as u,resolveAndroidAdbProvider as c,resolveAndroidAdbExecutor as p,installAndroidAdbPackage as m}from"./9639.js";import{appSwitcherAndroid as h,homeAndroid as f,scrollAndroid as w,longPressAndroid as _,typeAndroid as A,getAndroidScreenSize as g,pressAndroid as y,focusAndroid as N,swipeAndroid as I,rotateAndroid as v,fillAndroid as M,backAndroid as C}from"./input-actions.js";import{requireLocationCoordinates as S}from"./
|
|
2
|
-
${i.stderr}`)}catch(e){if(e instanceof n){if(e.code===
|
|
3
|
-
${r.stderr}`);return i?Number(i[1]):void 0}async function
|
|
4
|
-
${r}`.toLowerCase()).includes("unknown command")||i.includes("can't find service: fingerprint")||i.includes("service fingerprint was not found")||i.includes("fingerprint cmd unavailable")||i.includes("emu command is not supported")||i.includes("emulator console is not running")||i.includes("fingerprint")&&i.includes("not found")}))throw new n("UNSUPPORTED_OPERATION","Android fingerprint simulation is not supported on this target/runtime.",{deviceId:e.id,action:t,hint:"Use an Android emulator with biometric support, or a device/runtime that exposes cmd fingerprint.",attempts:d});throw new n("COMMAND_FAILED","Failed to simulate Android fingerprint.",{deviceId:e.id,action:t,attempts:d})}async function
|
|
5
|
-
${t}`);if(!r)return null;let i=r[1]?.toLowerCase();return"yes"===i?"dark":"no"===i?"light":"auto"===i?"auto":null}(i.stdout,i.stderr);if(!a)throw new n("COMMAND_FAILED","Unable to determine current Android appearance for toggle",{stdout:i.stdout,stderr:i.stderr});return"auto"===a?"dark":"dark"===a?"light":"dark"}async function
|
|
1
|
+
import e from"node:crypto";import t from"node:fs/promises";import r from"node:path";import{promises as i}from"node:fs";import{normalizeError as a,AppError as n}from"./9152.js";import{withDiagnosticTimer as o,emitDiagnostic as s}from"./7599.js";import{readVersion as d,findProjectRoot as l}from"./9671.js";import{resolveAndroidTouchInjector as u,resolveAndroidAdbProvider as c,resolveAndroidAdbExecutor as p,installAndroidAdbPackage as m}from"./9639.js";import{appSwitcherAndroid as h,homeAndroid as f,scrollAndroid as w,longPressAndroid as _,typeAndroid as A,getAndroidScreenSize as g,pressAndroid as y,focusAndroid as N,swipeAndroid as I,rotateAndroid as v,fillAndroid as M,backAndroid as C}from"./input-actions.js";import{requireLocationCoordinates as S,snapshotCaptureAnnotationsFrom as R}from"./6133.js";import{parseAppearanceAction as D,summarizeCommandAttemptFailures as E,parseSettingState as x,parsePermissionTarget as k,parsePermissionAction as b}from"./6629.js";import{openAndroidDevice as O,runAndroidAdb as L,openAndroidApp as F,resolveAndroidApp as P,closeAndroidApp as T}from"./8806.js";import{writeAndroidClipboardText as U,readAndroidClipboardText as $}from"./8133.js";import{snapshotAndroid as G}from"./2415.js";import{sleep as K}from"./4829.js";let V="android-multitouch-helper-v1",H="ANDROID_MULTITOUCH_HELPER_NO_FINAL_RESULT",q="ANDROID_MULTITOUCH_HELPER_REPORTED_FAILURE";async function B(e,t){let r=await Q(e,{kind:"swipe",...t});if(r)return r;try{return await Y(e,{kind:"swipe",...t})}catch(r){return s({level:"warn",phase:"android_swipe_helper_fallback",data:{error:a(r).message}}),await I(e,t.x1,t.y1,t.x2,t.y2,t.durationMs),{backend:"adb-input-swipe-fallback"}}}async function j(e,t){if(!Number.isFinite(t.scale)||t.scale<=0)throw new n("INVALID_ARGS","gesture pinch requires scale > 0");let r=await W(e,t.x,t.y);return await X(e,{kind:"pinch",x:r.x,y:r.y,scale:t.scale,durationMs:t.durationMs})}async function z(e,t){if(!Number.isFinite(t.degrees))throw new n("INVALID_ARGS","gesture rotate requires finite degrees");if(void 0!==t.velocity&&(!Number.isFinite(t.velocity)||0===t.velocity))throw new n("INVALID_ARGS","gesture rotate velocity must be a non-zero number");let r=await W(e,t.x,t.y),i=t.degrees;return await X(e,{kind:"rotate",x:r.x,y:r.y,degrees:i,durationMs:t.durationMs})}async function J(e,t){if(!Number.isFinite(t.scale)||t.scale<=0)throw new n("INVALID_ARGS","gesture transform requires scale > 0");if(!Number.isFinite(t.degrees))throw new n("INVALID_ARGS","gesture transform requires finite degrees");if(![t.x,t.y,t.dx,t.dy].every(Number.isFinite))throw new n("INVALID_ARGS","gesture transform requires finite x y dx dy");return await X(e,{kind:"transform",x:t.x,y:t.y,dx:t.dx,dy:t.dy,scale:t.scale,degrees:t.degrees,durationMs:t.durationMs})}async function W(e,t,r){if(void 0!==t&&void 0!==r)return{x:t,y:r};let i=await g(e);return{x:Math.round(i.width/2),y:Math.round(i.height/2)}}async function X(e,t){let r=await Q(e,t);return r||await Y(e,t)}async function Q(e,t){let r=u(e);if(r)return{backend:"provider-native-touch",...await r(t)??{}}}async function Y(e,t){let r=p(e),i=await et(),a=c(e),n=await o("android_multitouch_helper_install",async()=>{var t;return await er({adb:r,adbProvider:a,artifact:i,deviceKey:(t=e,`${t.platform}:${t.id}`)})},{packageName:i.manifest.packageName,versionCode:i.manifest.versionCode});s({phase:"android_multitouch_helper_install_decision",data:n});let d=await o("android_multitouch_helper_gesture",async()=>await Z({adb:r,request:function(e){var t;let r=Math.round(void 0!==(t=e).durationMs?t.durationMs:"swipe"===t.kind||"pinch"===t.kind?300:Math.min(Math.max(300,16*Math.ceil(Math.abs(t.degrees)/3)),2400));switch(e.kind){case"swipe":return{kind:"swipe",x1:Math.round(e.x1),y1:Math.round(e.y1),x2:Math.round(e.x2),y2:Math.round(e.y2),durationMs:r};case"pinch":return{kind:"pinch",x:Math.round(e.x),y:Math.round(e.y),scale:e.scale,radius:160,durationMs:r};case"rotate":return{kind:"rotate",x:Math.round(e.x),y:Math.round(e.y),degrees:e.degrees,radius:160,durationMs:r};case"transform":return{kind:"transform",x:Math.round(e.x),y:Math.round(e.y),dx:Math.round(e.dx),dy:Math.round(e.dy),scale:e.scale,degrees:e.degrees,durationMs:r}}}(t),packageName:i.manifest.packageName,instrumentationRunner:i.manifest.instrumentationRunner}),{packageName:i.manifest.packageName,version:i.manifest.version});return{backend:"android-multitouch-helper",helperVersion:i.manifest.version,installReason:n.reason,...d}}async function Z(e){let t,r=Buffer.from(JSON.stringify({protocol:V,...e.request})).toString("base64"),i=await e.adb(["shell","am","instrument","-w","-e","payloadBase64",r,e.instrumentationRunner],{allowFailure:!0,timeoutMs:45e3});try{t=function(e){let t=(function(e){let t=[],r=null;for(let i of e.split(/\r?\n/))i.startsWith("INSTRUMENTATION_RESULT: ")?(r??={},function(e,t){let r=e.indexOf("=");r>=0&&(t[e.slice(0,r)]=e.slice(r+1))}(i.slice(24),r)):i.startsWith("INSTRUMENTATION_CODE: ")&&r&&(t.push(r),r=null);return r&&t.push(r),t})(e).find(e=>e.agentDeviceProtocol===V);if(!t)throw new n(H,"Android multi-touch helper did not return a final result");if("true"!==t.ok){var r;throw new n(q,(r=t).message&&"null"!==r.message?r.message:r.errorType||"Android multi-touch helper returned an error",{errorType:t.errorType,helper:t})}return{kind:t.kind,helperApiVersion:t.helperApiVersion,injectedEvents:ee(t.injectedEvents),elapsedMs:ee(t.elapsedMs)}}(`${i.stdout}
|
|
2
|
+
${i.stderr}`)}catch(e){if(e instanceof n){if(e.code===q)throw new n("COMMAND_FAILED",e.message,e.details,e);if(e.code!==H)throw e}throw new n("COMMAND_FAILED",0===i.exitCode?"Android multi-touch helper output could not be parsed":"Android multi-touch helper failed before returning parseable output",{stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode},e)}if(0!==i.exitCode)throw new n("COMMAND_FAILED","Android multi-touch helper failed",{stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode,helper:t});return t}function ee(e){if(void 0===e)return;let t=Number(e);return Number.isFinite(t)?t:void 0}async function et(){let e=d(),i=r.join(l(),"android-multitouch-helper","dist"),o=r.join(i,`agent-device-android-multitouch-helper-${e}.manifest.json`);try{let e=function(e){if(!e||"object"!=typeof e||Array.isArray(e))throw new n("INVALID_ARGS","Android multi-touch helper manifest must be an object.");return{name:ed(e.name,"name","android-multitouch-helper"),version:es(e.version,"version"),assetName:es(e.assetName,"assetName"),sha256:function(e){let t=es(e,"sha256").trim().toLowerCase();if(64!==t.length||!/^[0-9a-f]+$/.test(t))throw new n("INVALID_ARGS","Android multi-touch helper manifest sha256 must be a 64-character hex string.");return t}(e.sha256),packageName:ed(e.packageName,"packageName","com.callstack.agentdevice.multitouchhelper"),versionCode:function(e,t){if(!Number.isInteger(e))throw new n("INVALID_ARGS",`Android multi-touch helper manifest ${t} must be an integer.`);return e}(e.versionCode,"versionCode"),instrumentationRunner:ed(e.instrumentationRunner,"instrumentationRunner","com.callstack.agentdevice.multitouchhelper/.MultiTouchInstrumentation"),statusProtocol:ed(e.statusProtocol,"statusProtocol",V)}}(JSON.parse(await t.readFile(o,"utf8"))),a=r.join(i,e.assetName);return await t.access(a),{apkPath:a,manifest:e}}catch(e){throw new n("UNSUPPORTED_OPERATION","Android touch gestures require the bundled Android touch helper artifact, but it was not found or could not be read",{manifestPath:o,error:a(e).message},e)}}async function er(e){let{adb:t,artifact:r}=e,i=r.manifest.packageName,a=r.manifest.versionCode,o=`${e.deviceKey}\0${i}\0${a}`;if(ei.has(o))return{packageName:i,versionCode:a,installed:!1,reason:"current"};let s=await ea(t,i);if(void 0!==s&&s>=a)return ei.add(o),{packageName:i,versionCode:a,installedVersionCode:s,installed:!1,reason:"current"};await en(r);let d=await m(r.apkPath,{provider:e.adbProvider,replace:!0,allowTestPackages:!0,allowFailure:!0,timeoutMs:3e4});if(0!==d.exitCode)throw new n("COMMAND_FAILED","Failed to install Android multi-touch helper",{packageName:i,versionCode:a,stdout:d.stdout,stderr:d.stderr,exitCode:d.exitCode});return ei.add(o),{packageName:i,versionCode:a,installedVersionCode:s,installed:!0,reason:void 0===s?"missing":"outdated"}}let ei=new Set;async function ea(e,t){let r=await e(["shell","cmd","package","list","packages","--show-versioncode",t],{allowFailure:!0,timeoutMs:5e3});if(0!==r.exitCode)return;let i=RegExp(`package:${t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}(?:\\s|$).*versionCode:(\\d+)`).exec(`${r.stdout}
|
|
3
|
+
${r.stderr}`);return i?Number(i[1]):void 0}async function en(e){let t=await eo(e.apkPath);if(t!==e.manifest.sha256)throw new n("COMMAND_FAILED","Android multi-touch helper APK checksum mismatch",{apkPath:e.apkPath,expectedSha256:e.manifest.sha256,actualSha256:t})}async function eo(r){let i=e.createHash("sha256");return i.update(await t.readFile(r)),i.digest("hex")}function es(e,t){if("string"!=typeof e||0===e.length)throw new n("INVALID_ARGS",`Android multi-touch helper manifest ${t} is required.`);return e}function ed(e,t,r){if(e!==r)throw new n("INVALID_ARGS",`Android multi-touch helper manifest ${t} must be "${r}".`);return r}let el=["window_animation_scale","transition_animation_scale","animator_duration_scale"];async function eu(e,t,r,i,a){switch(t.toLowerCase()){case"wifi":{let t=x(r);await L(e,["shell","svc","wifi",t?"enable":"disable"]);return}case"airplane":{let t=x(r);await L(e,["shell","settings","put","global","airplane_mode_on",t?"1":"0"]),await L(e,["shell","am","broadcast","-a","android.intent.action.AIRPLANE_MODE","--ez","state",t?"true":"false"]);return}case"location":{if("set"===r.toLowerCase()){if("emulator"!==e.kind)throw new n("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:t,longitude:r}=S(a);return await L(e,["emu","geo","fix",String(r),String(t)]),{latitude:t,longitude:r}}let t=x(r);await L(e,["shell","settings","put","secure","location_mode",t?"3":"0"]);return}case"animations":{let t=x(r)?"1":"0";for(let r of el)await L(e,["shell","settings","put","global",r,t]);return{scale:t,keys:[...el]}}case"appearance":{let t=await ep(e,r);await L(e,["shell","cmd","uimode","night","dark"===t?"yes":"no"]);return}case"clear-app-state":{if("clear"!==r.toLowerCase())throw new n("INVALID_ARGS","settings clear-app-state only supports clear.");if(!i)throw new n("INVALID_ARGS","settings clear-app-state requires an app id or an active app session.");let t=await P(e,i);if("intent"===t.type)throw new n("INVALID_ARGS","settings clear-app-state requires a package name, not an intent.");await L(e,["shell","am","force-stop",t.value],{allowFailure:!0});let a=await L(e,["shell","pm","clear",t.value],{allowFailure:!0});if(0!==a.exitCode||!/\bSuccess\b/i.test(a.stdout))throw new n("COMMAND_FAILED",`Failed to clear Android app data for ${t.value}`,{package:t.value,stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode});return{package:t.value,cleared:!0}}case"fingerprint":{let t=function(e){let t=e.trim().toLowerCase();if("match"===t)return"match";if("nonmatch"===t)return"nonmatch";throw new n("INVALID_ARGS",`Invalid fingerprint state: ${e}. Use match|nonmatch.`)}(r);await ec(e,t);return}case"permission":{if(!i)throw new n("INVALID_ARGS","permission setting requires an active app in session");let t=b(r),o=function(e,t){let r=k(e);if(t?.trim())throw new n("INVALID_ARGS",`Permission mode is only supported for photos. Received: ${t}.`);if("camera"===r)return{kind:"pm",value:"android.permission.CAMERA",type:"camera"};if("microphone"===r)return{kind:"pm",value:"android.permission.RECORD_AUDIO",type:"microphone"};if("photos"===r)return{kind:"pm",value:"android.permission.READ_MEDIA_IMAGES",type:"photos"};if("contacts"===r)return{kind:"pm",value:"android.permission.READ_CONTACTS",type:"contacts"};if("notifications"===r)return{kind:"notifications",appOps:"POST_NOTIFICATION",permission:"android.permission.POST_NOTIFICATIONS"};throw new n("INVALID_ARGS",`Unsupported permission target on Android: ${e}. Use camera|microphone|photos|contacts|notifications.`)}(a?.permissionTarget,a?.permissionMode);if("notifications"===o.kind)return void await eh(e,i,t,o);let s="grant"===t?"grant":"revoke";if("photos"===o.type)return void await em(e,i,s);await L(e,["shell","pm",s,i,o.value]);return}default:throw new n("INVALID_ARGS",`Unsupported setting: ${t}`)}}async function ec(e,t){var r;let i,a,o=(r=e,a=[["shell","cmd","fingerprint","touch",i="match"===t?"1":"9999"],["shell","cmd","fingerprint","finger",i]],"emulator"===r.kind&&a.push(["emu","finger","touch",i]),a),s=[];for(let t of o){let r=await L(e,t,{allowFailure:!0});if(0===r.exitCode)return;s.push({args:t,stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode})}let d=E(s);if(s.length>0&&s.every(e=>{var t,r;let i;return t=e.stdout,r=e.stderr,(i=`${t}
|
|
4
|
+
${r}`.toLowerCase()).includes("unknown command")||i.includes("can't find service: fingerprint")||i.includes("service fingerprint was not found")||i.includes("fingerprint cmd unavailable")||i.includes("emu command is not supported")||i.includes("emulator console is not running")||i.includes("fingerprint")&&i.includes("not found")}))throw new n("UNSUPPORTED_OPERATION","Android fingerprint simulation is not supported on this target/runtime.",{deviceId:e.id,action:t,hint:"Use an Android emulator with biometric support, or a device/runtime that exposes cmd fingerprint.",attempts:d});throw new n("COMMAND_FAILED","Failed to simulate Android fingerprint.",{deviceId:e.id,action:t,attempts:d})}async function ep(e,t){let r=D(t);if("toggle"!==r)return r;let i=await L(e,["shell","cmd","uimode","night"],{allowFailure:!0});if(0!==i.exitCode)throw new n("COMMAND_FAILED","Failed to read current Android appearance",{stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode});let a=function(e,t){let r=/night mode:\s*(yes|no|auto)\b/i.exec(`${e}
|
|
5
|
+
${t}`);if(!r)return null;let i=r[1]?.toLowerCase();return"yes"===i?"dark":"no"===i?"light":"auto"===i?"auto":null}(i.stdout,i.stderr);if(!a)throw new n("COMMAND_FAILED","Unable to determine current Android appearance for toggle",{stdout:i.stdout,stderr:i.stderr});return"auto"===a?"dark":"dark"===a?"light":"dark"}async function em(e,t,r){let i=await ef(e),a=[];for(let n of null!==i&&i>=33?["android.permission.READ_MEDIA_IMAGES","android.permission.READ_EXTERNAL_STORAGE"]:["android.permission.READ_EXTERNAL_STORAGE","android.permission.READ_MEDIA_IMAGES"]){let i=await L(e,["shell","pm",r,t,n],{allowFailure:!0});if(0===i.exitCode)return;a.push({permission:n,stderr:i.stderr,exitCode:i.exitCode})}throw new n("COMMAND_FAILED",`Failed to ${r} Android photos permission`,{appPackage:t,sdkInt:i,attempts:a})}async function eh(e,t,r,i){"grant"===r?await L(e,["shell","pm","grant",t,i.permission],{allowFailure:!0}):(await L(e,["shell","pm","revoke",t,i.permission],{allowFailure:!0}),"reset"===r&&(await L(e,["shell","pm","clear-permission-flags",t,i.permission,"user-set"],{allowFailure:!0}),await L(e,["shell","pm","clear-permission-flags",t,i.permission,"user-fixed"],{allowFailure:!0}))),await L(e,["shell","appops","set",t,i.appOps,"grant"===r?"allow":"deny"===r?"deny":"default"])}async function ef(e){let t=await L(e,["shell","getprop","ro.build.version.sdk"],{allowFailure:!0});if(0!==t.exitCode)return null;let r=Number.parseInt(t.stdout.trim(),10);return!Number.isFinite(r)||r<=0?null:r}let ew=Buffer.from([137,80,78,71,13,10,26,10]);async function e_(e,t,r={}){if(!1===r.stabilize)return void await ey(e,t);await eA(e);try{await K(1e3),await ey(e,t)}finally{await eg(e).catch(()=>{})}}async function eA(e){let t=t=>L(e,["shell",t],{allowFailure:!0});await t("settings put global sysui_demo_allowed 1");let r=e=>t(`am broadcast -a com.android.systemui.demo -e command ${e}`);await r("clock -e hhmm 0941"),await r("notifications -e visible false")}async function eg(e){await L(e,["shell","am broadcast -a com.android.systemui.demo -e command exit"],{allowFailure:!0})}async function ey(e,t){let r=await L(e,["exec-out","screencap","-p"],{binaryStdout:!0});if(!r.stdoutBuffer)throw new n("COMMAND_FAILED","Failed to capture screenshot");let a=r.stdoutBuffer.indexOf(ew);if(a<0)throw new n("COMMAND_FAILED","Screenshot data does not contain a valid PNG header");let o=function(e,t){let r=t+ew.length;for(;r+8<=e.length;){let t=e.readUInt32BE(r),i=r+4,a=e.toString("ascii",i,i+4),n=r+12+t;if(n>e.length)break;if("IEND"===a)return n;r=n}return null}(r.stdoutBuffer,a);if(!o)throw new n("COMMAND_FAILED","Screenshot data does not contain a complete PNG payload");await i.writeFile(t,r.stdoutBuffer.subarray(a,o))}function eN(e){return{open:(t,r)=>F(e,t,{activity:r?.activity,appBundleId:r?.appBundleId,launchArgs:r?.launchArgs,url:r?.url}),openDevice:()=>O(e),close:t=>T(e,t),tap:(t,r)=>y(e,t,r),doubleTap:async(t,r)=>{await y(e,t,r),await y(e,t,r)},swipe:(t,r,i,a,n)=>B(e,{x1:t,y1:r,x2:i,y2:a,durationMs:n}),pan:(t,r,i,a,n)=>B(e,{x1:t,y1:r,x2:i,y2:a,durationMs:n}),fling:(t,r,i,a,n)=>B(e,{x1:t,y1:r,x2:i,y2:a,durationMs:n}),longPress:(t,r,i)=>_(e,t,r,i),focus:(t,r)=>N(e,t,r),type:(t,r)=>A(e,t,r),fill:(t,r,i,a)=>M(e,t,r,i,a),scroll:(t,r)=>w(e,t,r),pinch:(t,r,i)=>j(e,{scale:t,x:r,y:i}),screenshot:(t,r)=>e_(e,t,r),snapshot:async t=>{let r=await o("snapshot_capture",async()=>await G(e,{interactiveOnly:t?.interactiveOnly,depth:t?.depth,scope:t?.scope,raw:t?.raw}),{backend:"android"});return{nodes:r.nodes??[],truncated:r.truncated??!1,backend:"android",...R(r)}},back:t=>C(e),home:()=>f(e),rotate:t=>v(e,t),rotateGesture:(t,r,i,a)=>z(e,{degrees:t,x:r,y:i,velocity:a}),transformGesture:t=>J(e,t),appSwitcher:()=>h(e),readClipboard:()=>$(e),writeClipboard:t=>U(e,t),setSetting:(t,r,i,a)=>eu(e,t,r,i,a)}}export{eN as createAndroidInteractor};
|
package/dist/src/apple.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{readSnapshotQualityVerdict as e,assertScrollGestureInput as a,buildScrollGesturePlan as t}from"./6133.js";import{parseRunnerSequenceResult as n,buildRunnerSequenceCommand as d,runMacOsScreenshotAction as o,runIosRunnerCommand as r}from"./2415.js";import{writeIosClipboardText as i,openIosApp as l,openIosDevice as s,screenshotIos as p,closeIosApp as u,setIosSetting as c,readIosClipboardText as m}from"./apps.js";import{withDiagnosticTimer as y}from"./7599.js";import{AppError as f}from"./9152.js";function v(e,a,t,n){return{command:"tap",x:t,y:n,...I(e)?{synthesized:!0}:{},appBundleId:a.appBundleId}}function I(e){return"ios"===e.platform&&"tv"!==e.target}function h(e,a,t,n,d,o,r,i){var l,s;let p="ios"===e.platform&&"tv"!==e.target?(l=r,s=i.defaultDurationMs,void 0===l?s:Math.min(1e4,Math.max(16,Math.round(l)))):r??i.legacyDefaultDurationMs;return{command:"drag",x:t,y:n,x2:d,y2:o,...void 0!==p?{durationMs:p}:{},...!0===i.synthesized?{synthesized:!0}:{},appBundleId:a.appBundleId}}function w(e,a,t){return{command:"remotePress",remoteButton:e,...void 0!==t?{durationMs:t}:{},...void 0!==a?{appBundleId:a}:{}}}async function B(e,n,d,o,r,i){if("tv"===n.target)return x(await e(n,w(r,d.appBundleId),o),i);a(i??{});let l=await e(n,{command:"scroll",direction:r,...i?.amount!==void 0?{amount:i.amount}:{},...i?.pixels!==void 0?{pixels:i.pixels}:{},appBundleId:d.appBundleId},o),s=g(l.referenceWidth),p=g(l.referenceHeight);if(void 0!==s&&void 0!==p){let e=t({direction:r,amount:i?.amount,pixels:i?.pixels,referenceWidth:s,referenceHeight:p});return x(l,{amount:i?.amount,pixels:e.pixels,preferProvidedPixels:!0})}return x(l,{amount:i?.amount})}function g(e){return"number"==typeof e&&Number.isFinite(e)?e:void 0}function x(e,a){var t;let{x1:n,y1:d,x2:o,y2:r}={x1:g((t=e).x),y1:g(t.y),x2:g(t.x2),y2:g(t.y2)},i=g(e.referenceWidth),l=g(e.referenceHeight),s=void 0!==n&&void 0!==o?Math.round(Math.abs(o-n)):void 0,p=void 0!==d&&void 0!==r?Math.round(Math.abs(r-d)):void 0,u=a?.preferProvidedPixels&&void 0!==a.pixels?a.pixels:s&&s>0?s:p&&p>0?p:void 0;return{...void 0!==n?{x1:n}:{},...void 0!==d?{y1:d}:{},...void 0!==o?{x2:o}:{},...void 0!==r?{y2:r}:{},...void 0!==i?{referenceWidth:i}:{},...void 0!==l?{referenceHeight:l}:{},...a?.amount!==void 0?{amount:a.amount}:{},...void 0!==u?{pixels:u}:{}}}function M(a,t){let g,{overrides:x,runnerOpts:M}={runnerOpts:g={verbose:t.verbose,logPath:t.logPath,traceLogPath:t.traceLogPath,requestId:t.requestId},overrides:{tap:async(e,n)=>await r(a,v(a,t,e,n),g),tapElementSelector:async e=>await r(a,{command:"tap",selectorKey:e.key,selectorValue:e.value,allowNonHittableCoordinateFallback:e.allowNonHittableCoordinateFallback,appBundleId:t.appBundleId},g),doubleTap:async(e,o)=>{let i=await r(a,d([{kind:"doubleTap",x:e,y:o}],t.appBundleId),g);return n(i),i},swipe:async(e,n,d,o,i)=>await r(a,h(a,t,e,n,d,o,i,{defaultDurationMs:250,synthesized:I(a)}),g),pan:async(e,n,d,o,i)=>await r(a,h(a,t,e,n,d,o,i,{defaultDurationMs:500,legacyDefaultDurationMs:500,synthesized:I(a)}),g),fling:async(e,n,d,o,i)=>await r(a,h(a,t,e,n,d,o,i,{defaultDurationMs:16,legacyDefaultDurationMs:16,synthesized:I(a)}),g),longPress:async(e,n,d)=>await r(a,{command:"longPress",x:e,y:n,durationMs:d,appBundleId:t.appBundleId},g),focus:async(e,n)=>await r(a,v(a,t,e,n),g),type:async(e,n)=>{await r(a,{command:"type",text:e,delayMs:n,textEntryMode:"\n"===e?void 0:"append",appBundleId:t.appBundleId},g)},fillElementSelector:async(e,n,d)=>await r(a,{command:"type",selectorKey:e.key,selectorValue:e.value,allowNonHittableCoordinateFallback:e.allowNonHittableCoordinateFallback,text:n,delayMs:d,textEntryMode:"replace",appBundleId:t.appBundleId},g),fill:async(e,n,d,o)=>await r(a,{command:"type",x:e,y:n,text:d,delayMs:o,textEntryMode:"replace",appBundleId:t.appBundleId},g),scroll:async(e,n)=>await B(r,a,t,g,e,n),pinch:async(e,n,d)=>{await r(a,{command:"pinch",scale:e,x:n,y:d,appBundleId:t.appBundleId},g)},rotateGesture:async(e,n,d,o)=>{await r(a,{command:"rotateGesture",degrees:e,x:n,y:d,velocity:o,appBundleId:t.appBundleId},g)},transformGesture:async e=>await r(a,{command:"transformGesture",x:e.x,y:e.y,dx:e.dx,dy:e.dy,scale:e.scale,degrees:e.degrees,durationMs:e.durationMs,appBundleId:t.appBundleId},g)}};return{open:(e,t)=>l(a,e,{appBundleId:t?.appBundleId,launchConsole:t?.launchConsole,launchArgs:t?.launchArgs,url:t?.url}),openDevice:()=>s(a),close:e=>u(a,e),screenshot:async(e,t)=>{"macos"===a.platform&&t?.surface&&"app"!==t.surface?await o(e,{surface:t.surface,fullscreen:t.fullscreen}):await p(a,e,t?.appBundleId,t?.fullscreen,M)},snapshot:async t=>{var n;let d={nodes:Array.isArray((n=await y("snapshot_capture",async()=>await r(a,{command:"snapshot",appBundleId:t?.appBundleId,interactiveOnly:t?.interactiveOnly,depth:t?.depth,scope:t?.scope,raw:t?.raw},M),{backend:"xctest"})).nodes)?n.nodes:void 0,truncated:"boolean"==typeof n.truncated?n.truncated:void 0,quality:e(n.snapshotQuality),message:"string"==typeof n.message&&n.message.trim().length>0?n.message:void 0},o=d.nodes??[];if(0===o.length&&"simulator"===a.kind)throw new f("COMMAND_FAILED","XCTest snapshot returned 0 nodes on iOS simulator.");return{nodes:o,truncated:d.truncated??!1,backend:"xctest",...d.quality?{quality:d.quality}:{},...!d.quality&&d.message?{warnings:[d.message]}:{}}},back:async e=>{"tv"===a.target?await r(a,w("menu",t.appBundleId),M):await r(a,{command:"system"===e?"backSystem":"backInApp",appBundleId:t.appBundleId},M)},home:async()=>{"tv"===a.target?await r(a,w("home",t.appBundleId),M):await r(a,{command:"home",appBundleId:t.appBundleId},M)},rotate:async e=>{await r(a,{command:"rotate",orientation:e,appBundleId:t.appBundleId},M)},appSwitcher:async()=>{await r(a,{command:"appSwitcher",appBundleId:t.appBundleId},M)},readClipboard:()=>m(a),writeClipboard:e=>i(a,e),setSetting:(e,t,n,d)=>c(a,e,t,n,d),...x}}export{M as createAppleInteractor};
|