agent-device 0.17.0 → 0.17.2
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 +1 -1
- package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.17.0.apk → agent-device-android-multitouch-helper-0.17.2.apk} +0 -0
- package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.17.2.apk.sha256 +1 -0
- package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.17.0.manifest.json → agent-device-android-multitouch-helper-0.17.2.manifest.json} +4 -4
- package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.17.0.apk → agent-device-android-snapshot-helper-0.17.2.apk} +0 -0
- package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.17.2.apk.sha256 +1 -0
- package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.17.0.manifest.json → agent-device-android-snapshot-helper-0.17.2.manifest.json} +6 -6
- package/dist/src/123.js +1 -0
- package/dist/src/1352.js +1 -1
- package/dist/src/1534.js +1 -0
- package/dist/src/1620.js +1 -0
- package/dist/src/1644.js +2 -0
- package/dist/src/2284.js +1 -0
- package/dist/src/2403.js +3 -0
- package/dist/src/2415.js +28 -29
- package/dist/src/2474.js +1 -0
- package/dist/src/2672.js +1 -0
- package/dist/src/3393.js +1 -0
- package/dist/src/4778.js +1 -1
- package/dist/src/5898.js +1 -0
- package/dist/src/7556.js +1 -1
- package/dist/src/7847.js +1 -1
- package/dist/src/8173.js +27 -0
- package/dist/src/8407.js +1 -0
- package/dist/src/8699.js +1 -1
- package/dist/src/8806.js +3 -3
- package/dist/src/9010.js +1 -0
- package/dist/src/9238.js +3 -3
- package/dist/src/9471.js +1 -1
- package/dist/src/9542.js +3 -3
- package/dist/src/9616.js +1 -0
- package/dist/src/9673.js +1 -0
- package/dist/src/9974.js +1 -0
- package/dist/src/android-adb.d.ts +12 -6
- package/dist/src/android-adb.js +1 -1
- package/dist/src/android-snapshot-helper.d.ts +15 -7
- package/dist/src/android.js +1 -1
- package/dist/src/apple.js +1 -1
- package/dist/src/apps.js +2 -2
- package/dist/src/args.js +2 -2
- package/dist/src/batch.d.ts +16 -4
- package/dist/src/cli.js +18 -42
- package/dist/src/command-surface.js +1 -1
- package/dist/src/contracts.d.ts +28 -4
- package/dist/src/contracts.js +1 -1
- package/dist/src/find.js +1 -1
- package/dist/src/finders.d.ts +3 -1
- package/dist/src/generic.js +13 -11
- package/dist/src/index.d.ts +142 -73
- 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/internal/png-worker.d.ts +26 -0
- package/dist/src/internal/png-worker.js +1 -0
- package/dist/src/metro.d.ts +3 -1
- package/dist/src/react-native.js +1 -1
- package/dist/src/record-trace-recording.js +26 -0
- package/dist/src/record-trace.js +1 -26
- package/dist/src/remote-config.d.ts +33 -7
- package/dist/src/selector-runtime.js +1 -1
- package/dist/src/selectors.d.ts +3 -3
- package/dist/src/selectors.js +1 -1
- package/dist/src/server.js +2 -2
- package/dist/src/session.js +10 -11
- package/dist/src/snapshot.js +1 -1
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +6 -2
- package/package.json +7 -4
- package/server.json +2 -2
- package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.17.0.apk.sha256 +0 -1
- package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.17.0.apk.sha256 +0 -1
- package/dist/src/1998.js +0 -1
- package/dist/src/2805.js +0 -1
- package/dist/src/4057.js +0 -1
- package/dist/src/5792.js +0 -1
- package/dist/src/6085.js +0 -1
- package/dist/src/6232.js +0 -1
- package/dist/src/8020.js +0 -1
- package/dist/src/8502.js +0 -1
- package/dist/src/940.js +0 -1
- package/dist/src/9404.js +0 -1
- package/dist/src/9533.js +0 -1
- package/dist/src/command-metadata.js +0 -1
- /package/dist/src/{1393.js → 3675.js} +0 -0
- /package/dist/src/{5310.js → 695.js} +0 -0
package/dist/src/9542.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
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{
|
|
2
|
-
`)}let ep=["xcodebuild .*AgentDeviceRunnerUITests/RunnerTests/testCommand","xcodebuild .*AgentDeviceRunner\\.env\\.session-","xcodebuild build-for-testing .*ios-runner/AgentDeviceRunner/AgentDeviceRunner\\.xcodeproj"],em=new e.BlockList;async function ef(t){var a,i,s,l,c,d;let p,m,f,h,y,w,g,I=t.meta?.requestId??D(),v=!!(t.meta?.debug||t.flags?.verbose),P=(h=(i=a=t,i.flags?.stateDir??process.env.AGENT_DEVICE_STATE_DIR),y=(s=a,m=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)?em.check(r,"ipv4"):!!e.isIPv6(r)&&em.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."})}(m,f=s.flags?.daemonAuthToken??process.env.AGENT_DEVICE_DAEMON_AUTH_TOKEN),{rawBaseUrl:p,remoteBaseUrl:m,authToken:f}),w=function(e,t){let a=e.flags?.daemonTransport??process.env.AGENT_DEVICE_DAEMON_TRANSPORT,r=k(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:_(e.flags?.daemonServerMode??process.env.AGENT_DEVICE_DAEMON_SERVER_MODE??("dual"===a?"dual":void 0))}}(a,y.remoteBaseUrl),{paths:A((g=(l=a,c=h,d=y.rawBaseUrl,eS(l.command)&&!c&&!d))?r.mkdtempSync(o.join(n.tmpdir(),"agent-device-replay-daemon-")):h),transportPreference:w.preference,serverMode:w.serverMode,ownedStateDir:g,remoteBaseUrl:y.remoteBaseUrl,remoteAuthToken:y.authToken}),b=function(e){if(e.command!==U.test){var t;return"number"==typeof e.flags?.timeoutMs&&((t=e.command)===U.prepare||t===U.replay||t===U.snapshot)?e.flags.timeoutMs:e.command===U.prepare?24e4:9e4}}(t),S=await E("daemon_startup",async()=>await eA(P),{requestId:I,session:t.session}),T=S.info,C=await eh(t,T),N={...t,positionals:C.positionals,flags:C.flags,token:T.token,meta:{...t.meta??{},requestId:I,debug:v,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,...C.uploadedArtifactId?{uploadedArtifactId:C.uploadedArtifactId}:{},...C.clientArtifactPaths?{clientArtifactPaths:C.clientArtifactPaths}:{},...C.installSource?{installSource:C.installSource}:{}}};M({level:"info",phase:"daemon_request_prepare",data:{requestId:I,command:t.command,session:t.session}});try{return await E("daemon_request",async()=>await e$(T,N,P.transportPreference,b),{requestId:I,command:t.command})}finally{await eb(t,S,P)}}async function eh(e,t){let a,r=[...e.positionals??[]],n=e.flags?{...e.flags}:void 0,i=e.meta?.installSource,s={};if(!eY(t))return ew({positionals:r,flags:n,installSource:i,uploadedArtifactId:a,clientArtifactPaths:s});n=function(e,t,a,r){var n,i;let s=function(e,t){if("screenshot"===e.command){let a=eI(e,"path",".png");return t[0]?{field:"path",localPath:a,positionalIndex:0,positionalPath:ev("screenshot",".png")}:{field:"path",localPath:a,positionalIndex:0,flagPath:ev("screenshot",".png")}}if("record"===e.command&&"start"===(t[0]??"").toLowerCase()){let t=eI(e,"outPath",".mp4",1);return{field:"outPath",localPath:t,positionalIndex:1,positionalPath:ev("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,r,n,s);let l=await eg(e,t);l&&(i=l.installSource,a=l.uploadedArtifactId??a);let c=()=>ew({positionals:r,flags:n,installSource:i,uploadedArtifactId:a,clientArtifactPaths:s});return"install"!==e.command&&"reinstall"!==e.command||(a=await ey(e,t,r)??a),c()}async function ey(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 et({localPath:c,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform})}function ew(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 eg(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 et({localPath:i,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform});return{installSource:{...a,path:i},uploadedArtifactId:s}}function eI(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 ev(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 eA(e){if(e.remoteBaseUrl)return await e_(e);let t=await eP(e);return t?{info:t,startedByClient:!1}:(function(e){let t=eR(e);if(!t.hasLock||t.hasInfo)return;let a=eU(e.lockPath);if(!a)return ex(e.lockPath);T(a.pid,a.processStartTime)||ex(e.lockPath)}(e.paths),await ek(e))}async function e_(e){let t={transport:"http",token:e.remoteAuthToken??"",pid:0,baseUrl:e.remoteBaseUrl};if(await eF(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 eP(e){var t,a;let r,n=eT(e.paths.infoPath);if(!n)return null;let o=await eF(n,e.transportPreference);return(t=n,a=o,t.version===b()&&t.codeSignature===P((r=eB()).useSrc?r.srcPath:r.distPath,r.root)&&a)?n:(await eM(n),ex(e.paths.infoPath),null)}async function ek(e){let t,a=0,r=[];for(let n=1;n<=2;n+=1){try{await eq(e)}catch(a){if(t=a instanceof Error?a.message:String(a),r.push(await eL(e.paths,"start_error")),n<2){await L(150);continue}break}let o=await eD(15e3,e);if(o)return{info:o,startedByClient:!0};if(await eE(e.paths)){a+=1;continue}let i=eR(e.paths),s=n<2,l=await eL(e.paths,"startup_timeout",{stopLiveProcesses:!1});if(r.push(l),l.retainedInfoProcess||l.retainedLockProcess){let t=await eD(15e3,e);if(t)return{info:t,startedByClient:!0};break}if(!s)break;i.hasInfo||i.hasLock||await L(150)}let n=eR(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=A(process.env.AGENT_DEVICE_STATE_DIR)){var a;let r=(a=t,`rm -f ${w(a.infoPath)} ${w(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 eb(e,t,a){if(!eS(e.command)||!t.startedByClient&&!a.ownedStateDir||eY(t.info))return;let n={pid:t.info.pid,removedInfo:!1,removedLock:!1,removedStateDir:!1,error:void 0};try{await eM(t.info)}catch(e){n.error=e instanceof Error?e.message:String(e)}finally{let e=r.existsSync(a.paths.infoPath);ex(a.paths.infoPath),n.removedInfo=e&&!r.existsSync(a.paths.infoPath);let t=r.existsSync(a.paths.lockPath);ex(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 eS(e){return e===U.replay||e===U.test}async function eD(e,t){let a=Date.now();for(;Date.now()-a<e;){let e=eT(t.paths.infoPath);if(e&&await eF(e,t.transportPreference))return e;await L(100)}return null}async function eE(e){let t=eR(e);if(!t.hasLock||t.hasInfo)return!1;let a=eU(e.lockPath);return!(a&&T(a.pid,a.processStartTime))&&(ex(e.lockPath),!0)}async function eM(e){await C(e.pid,{termTimeoutMs:3e3,killTimeoutMs:1e3,expectedStartTime:e.processStartTime})}function eT(e){var t,a,r;let n,o,i=eO(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=eN((a=i).port),o=eN(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:eN(i.pid)??0,version:eC(i.version),codeSignature:eC(i.codeSignature),processStartTime:eC(i.processStartTime)}:null}function eC(e){return"string"==typeof e?e:void 0}function eN(e){return Number.isInteger(e)&&Number(e)>0?Number(e):void 0}function eU(e){let t=eO(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}em.addSubnet("127.0.0.0",8,"ipv4"),em.addAddress("::1","ipv6"),em.addSubnet("::ffff:127.0.0.0",104,"ipv6");async function eL(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=eT(e.infoPath);if(a){let t=T(a.pid,a.processStartTime);t&&!n?o.retainedInfoProcess=!0:(t&&(await eM(a),o.stoppedInfoProcess=!0),i=e.infoPath,ex(i),o.removedInfo=!0)}else t&&(s=e.infoPath,ex(s),o.removedInfo=!0);let d=r.existsSync(e.lockPath),u=eU(e.lockPath);if(u){let t=T(u.pid,u.processStartTime);t&&!n?o.retainedLockProcess=!0:(t&&(await C(u.pid,{termTimeoutMs:3e3,killTimeoutMs:1e3,expectedStartTime:u.processStartTime}),o.stoppedLockProcess=!0),l=e.lockPath,ex(l),o.removedLock=!0)}else d&&(c=e.lockPath,ex(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 eR(e){return{hasInfo:r.existsSync(e.infoPath),hasLock:r.existsSync(e.lockPath)}}function eO(e){if(!r.existsSync(e))return null;try{return JSON.parse(r.readFileSync(e,"utf8"))}catch{return null}}function ex(e){try{r.existsSync(e)&&r.unlinkSync(e)}catch{}}async function eF(r,n){var o;return"http"===ej(r,n)?await function(e){let r=e.baseUrl?eQ(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 eq(e){let t=eB(),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};f(process.execPath,a,{env:r})}function eB(){let e=S(),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 e$(e,t,a,r){return"http"===ej(e,a)?await eV(e,t,r):await ez(e,t,r)}function ej(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(eH(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=>eH(e,t));if(n)return n;throw new u("COMMAND_FAILED","Daemon metadata has no reachable transport")}function eH(e,t){return"http"===t?!!e.httpPort:!!e.port}function eK(e,t,a,r,n,o){let i=n?{terminated:0}:function(){let e=0;try{for(let t of ep){let a=p("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{T(e.pid,e.processStartTime)&&(process.kill(e.pid,"SIGKILL"),a=!0)}catch{C(e.pid,{termTimeoutMs:3e3,killTimeoutMs:1e3,expectedStartTime:e.processStartTime})}finally{ex(t.infoPath),ex(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===U.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 eG(e,t,a){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",{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=e.createConnection({host:"127.0.0.1",port:n},()=>{s.write(`${JSON.stringify(a)}
|
|
3
|
-
`)}),l=A(a.flags?.stateDir??process.env.AGENT_DEVICE_STATE_DIR),c=!1,d="number"==typeof r?setTimeout(()=>{c=!0,s.destroy(),i(eK(t,l,a.meta?.requestId,a.command,!1,r))},r):void 0,p="";s.setEncoding("utf8"),s.on("data",e=>{if(c)return;let t=y(p,e);for(let e of(p=t.buffer,t.lines))try{let t=JSON.parse(e);if(v(t)){eu(t.event);continue}let a=I(t)?t.response:t;c=!0,s.end(),d&&clearTimeout(d),o(a);return}catch(t){c=!0,d&&clearTimeout(d),i(new u("COMMAND_FAILED","Invalid daemon response",{requestId:a.meta?.requestId,line:e},t instanceof Error?t:void 0));return}}),s.on("error",e=>{c||(c=!0,d&&clearTimeout(d),i(eG(e,a.meta?.requestId,!1)))})})}async function eV(e,r,n){var o,i,s;let l,c=e.baseUrl?new URL(eQ(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??D(),"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)})),p={"content-type":"application/json","content-length":Buffer.byteLength(d)};return e.baseUrl&&e.token&&(p.authorization=`Bearer ${e.token}`,p["x-agent-device-token"]=e.token),await new Promise((o,i)=>{let s=A(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:p},t=>{var a;(a=t.headers?.["content-type"],g(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(v(t))return eu(t.event),!1;if(I(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=y(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:()=>{f&&clearTimeout(f)},handleResponseBody:t=>eW(t,{info:e,req:r,resolve:o,reject:i})}):Z(t).then(t=>{f&&clearTimeout(f),eW(t,{info:e,req:r,resolve:o,reject:i})}).catch(e=>{f&&clearTimeout(f),i(new u("COMMAND_FAILED","Failed to read daemon response",{requestId:r.meta?.requestId},e instanceof Error?e:void 0))})}),m=eY(e),f="number"==typeof n?setTimeout(()=>{l.destroy(),i(eK(e,s,r.meta?.requestId,r.command,m,n))},n):void 0;l.on("error",e=>{f&&clearTimeout(f),i(eG(e,r.meta?.requestId,m))}),l.write(d),l.end()})}function eW(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}));eJ(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 eJ(e,t,a,r,n){try{r(e.baseUrl&&a.ok?await eX(e,t,a):a)}catch(e){n(e)}}function eY(e){return"string"==typeof e.baseUrl&&e.baseUrl.length>0}function eQ(e,t){return new URL(t,e.endsWith("/")?e:`${e}/`).toString()}async function eX(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 eZ({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 eZ(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()})}function e0(e={},t={}){let a=t.transport??ef,r=async(t,r=[],n={})=>{var o,i;let s=(o=e,i=n,{...o,...i}),l=await a({session:F(s.session),command:t,positionals:r,flags:q(s),runtime:s.runtime,meta:J(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(x)},o=async(e,t={})=>{let a=H(e,t);return await r(a.command,a.positionals,a.options)},i=(t={})=>{var a,r;return F((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(Y)},boot:async(e={})=>await o("boot",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=>$(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=V(a),n=X(a,"appBundleId");return{session:t,sessionStateDir:X(a,"sessionStateDir"),appName:X(a,"appName"),appBundleId:n,appId:n,startup:B(a.startup),runtime:G(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=>j(await r(N.releaseMaterializedPaths,[],{...e,materializationId:e.materializationId}))},leases:{allocate:async e=>e5(await r(N.leaseAllocate,[],{...e,leaseId:void 0,leaseTtlMs:e.ttlMs})),heartbeat:async e=>e5(await r(N.leaseHeartbeat,[],{...e,leaseTtlMs:e.ttlMs})),release:async e=>({released:!0===(await r(N.leaseRelease,[],e)).released})},metro:{prepare:async t=>await O({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 R({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=X(t,"appBundleId"),{nodes:K(t.nodes),truncated:!0===t.truncated,appName:X(t,"appName"),appBundleId:n,...(s=e1((r=t).visibility),l=e1(r.androidSnapshot),c=e1(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:Q(a,"path"),overlayRefs:W(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 e1(e){return"object"==typeof e&&null!==e?e:void 0}function e5(e){let t=e.lease;if(!t||"object"!=typeof t||Array.isArray(t))throw Error("Invalid lease response from daemon");return{leaseId:Q(t,"leaseId"),tenantId:Q(t,"tenantId"),runId:Q(t,"runId"),backend:Q(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{e0 as createAgentDeviceClient,ef as sendToDaemon};
|
|
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};
|
package/dist/src/9616.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./9152.js";import{PLATFORM_SELECTORS as t}from"./1644.js";let e=["reject","strip"],a=["ios-simulator","ios-instance","android-instance"],n=["socket","http","dual"],r=["auto","socket","http"],i=["none","tenant"],o=["summary","headers","body","all"];function s(t){return{parse:e=>t(e,"$")}}function d(t,e){throw Error(`${t}: ${e}`)}function l(t,e){return(!t||"object"!=typeof t||Array.isArray(t))&&d(e,"Expected an object"),t}function c(t,e){return"string"!=typeof t&&d(e,"Expected a string"),t}function u(t,e){let a=c(t,e).trim();return a||d(e,"Expected a non-empty string"),a}function m(t,e){return Number.isInteger(t)||d(e,"Expected an integer"),t}function f(t,e,a){let n=t[e];return void 0===n?void 0:c(n,`${a}.${e}`)}function $(t,e,a){let n=t[e];if(void 0!==n)return"boolean"!=typeof n&&d(`${a}.${e}`,"Expected a boolean"),n}function p(t,e,a){let n=t[e];return void 0===n?void 0:m(n,`${a}.${e}`)}function I(t,e,a){let n=t[e];return void 0===n?void 0:l(n,`${a}.${e}`)}function h(t,e,a,n){let r=t[e];if(void 0!==r)return"string"==typeof r&&a.includes(r)||d(`${n}.${e}`,`Expected one of: ${a.join(", ")}`),r}function E(t,e){let a=l(t,e),n={};for(let[t,r]of Object.entries(a))n[t]=c(r,`${e}.${t}`);return n}let S=s((t,e)=>{let a=l(t,e);return{platform:h(a,"platform",["ios","android"],e),metroHost:f(a,"metroHost",e),metroPort:p(a,"metroPort",e),bundleUrl:f(a,"bundleUrl",e),launchUrl:f(a,"launchUrl",e)}}),v=s((n,r)=>{var o,s;let v=l(n,r),M=(o=v.positionals,s=`${r}.positionals`,Array.isArray(o)||d(s,"Expected an array"),o),b=I(v,"meta",r);return{token:f(v,"token",r),session:f(v,"session",r),command:c(v.command,`${r}.command`),positionals:M.map((t,e)=>c(t,`${r}.positionals[${String(e)}]`)),flags:I(v,"flags",r),runtime:void 0===v.runtime?void 0:S.parse(v.runtime),meta:void 0===b?void 0:{requestId:f(b,"requestId",`${r}.meta`),debug:$(b,"debug",`${r}.meta`),cwd:f(b,"cwd",`${r}.meta`),sessionExplicit:$(b,"sessionExplicit",`${r}.meta`),tenantId:f(b,"tenantId",`${r}.meta`),runId:f(b,"runId",`${r}.meta`),leaseId:f(b,"leaseId",`${r}.meta`),leaseTtlMs:p(b,"leaseTtlMs",`${r}.meta`),leaseBackend:h(b,"leaseBackend",a,`${r}.meta`),sessionIsolation:h(b,"sessionIsolation",i,`${r}.meta`),uploadedArtifactId:f(b,"uploadedArtifactId",`${r}.meta`),clientArtifactPaths:void 0===b.clientArtifactPaths?void 0:E(b.clientArtifactPaths,`${r}.meta.clientArtifactPaths`),installSource:void 0===b.installSource?void 0:function(t,e){let a=l(t,e),n=c(a.kind,`${e}.kind`);if("url"===n){let t=c(a.url,`${e}.url`),r=void 0===a.headers?void 0:E(a.headers,`${e}.headers`);return r?{kind:n,url:t,headers:r}:{kind:n,url:t}}if("path"===n)return{kind:n,path:c(a.path,`${e}.path`)};if("github-actions-artifact"===n){let t,n,r,i,o;return t=u(a.owner,`${e}.owner`),n=u(a.repo,`${e}.repo`),r=void 0!==a.artifactId,i=void 0!==a.runId,o=void 0!==a.artifactName,(r&&(i||o)&&d(`${e}`,"Expected either artifactId or artifactName, not both"),r||!i||o||d(`${e}`,"Expected artifactName when runId is specified"),r||o||d(`${e}`,"Expected artifactId or artifactName"),r)?{kind:"github-actions-artifact",owner:t,repo:n,artifactId:m(a.artifactId,`${e}.artifactId`)}:{kind:"github-actions-artifact",owner:t,repo:n,...i?{runId:m(a.runId,`${e}.runId`)}:{},artifactName:u(a.artifactName,`${e}.artifactName`)}}d(`${e}.kind`,'Expected "url", "path", or "github-actions-artifact"')}(b.installSource,`${r}.meta.installSource`),retainMaterializedPaths:$(b,"retainMaterializedPaths",`${r}.meta`),materializedPathRetentionMs:p(b,"materializedPathRetentionMs",`${r}.meta`),materializationId:f(b,"materializationId",`${r}.meta`),lockPolicy:h(b,"lockPolicy",e,`${r}.meta`),lockPlatform:h(b,"lockPlatform",t,`${r}.meta`)}}});function M(t,e){return{token:f(t,"token",e),session:f(t,"session",e),tenantId:f(t,"tenantId",e),tenant:f(t,"tenant",e),runId:f(t,"runId",e)}}let b=s((t,e)=>{let n=l(t,e);return{...M(n,e),ttlMs:p(n,"ttlMs",e),backend:h(n,"backend",a,e)}}),_=s((t,e)=>{let a,n={record:a=l(t,e),leaseId:f(a,"leaseId",e),ttlMs:p(a,"ttlMs",e)};return{...M(n.record,e),leaseId:n.leaseId,ttlMs:n.ttlMs}}),A=s((t,e)=>{let a=l(t,e);return void 0!==a.ttlMs&&d(`${e}.ttlMs`,"Unexpected field"),{...M(a,e),leaseId:f(a,"leaseId",e)}}),N=s((t,e)=>{let a,n=l(t,e);return{jsonrpc:f(n,"jsonrpc",e),id:(null==(a=n.id)||"string"!=typeof a&&"number"!=typeof a&&d(`${e}.id`,"Expected a string, number, or null"),a),method:f(n,"method",e),params:n.params}});export{e as DAEMON_LOCK_POLICIES,n as DAEMON_SERVER_MODES,r as DAEMON_TRANSPORT_PREFERENCES,a as LEASE_BACKENDS,o as NETWORK_INCLUDE_MODES,i as SESSION_ISOLATION_MODES,v as daemonCommandRequestSchema,S as daemonRuntimeSchema,N as jsonRpcRequestSchema,b as leaseAllocateSchema,_ as leaseHeartbeatSchema,A as leaseReleaseSchema};
|
package/dist/src/9673.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./3675.js";import{AppError as t}from"./9152.js";function e(e,i){if(void 0===e||""===e.trim())throw new t("INVALID_ARGS",`settings location set requires ${i}`);return o(Number(e),i)}function i(t){return{latitude:o(t?.latitude,"latitude"),longitude:o(t?.longitude,"longitude")}}function o(e,i){let o="latitude"===i?-90:-180,r="latitude"===i?90:180;if("number"!=typeof e||!Number.isFinite(e)||e<o||e>r)throw new t("INVALID_ARGS",`${i} must be a number from ${o} to ${r}`);return e}export{e as readLocationCoordinate,i as requireLocationCoordinates};
|
package/dist/src/9974.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{PLATFORM_SELECTORS as e,DEVICE_TARGETS as t}from"./1644.js";import"./2672.js";let r=["ref","selector","point"];function i(e){return{type:"string",...e?{description:e}:{}}}function n(e){return{type:"integer",...e?{description:e}:{}}}function o(e){return{type:"boolean",...e?{description:e}:{}}}function s(e){return{type:"object",additionalProperties:!0,...e?{description:e}:{}}}function a(e){return{...e,required:!0}}function d(e){return K(i(e),k)}function c(e){return K({type:"number",...e?{description:e}:{}},$)}function l(e,t={}){var r,i;return K((r=e,i=t,{...n(r),...void 0===i.min?{}:{minimum:i.min},...void 0===i.max?{}:{maximum:i.max}}),(e,r)=>F(e,r,t))}function u(e){return K(o(e),D)}function p(e,t){return K({type:"string",enum:e,...t?{description:t}:{}},(t,r)=>P(t,r,e))}function f(e){return K(s(e),H)}function m(e){return K({type:"array",items:{type:"string"},...e?{description:e}:{}},L)}function b(e){return K(e,(e,t)=>e[t])}function g(e,t){return K(e,t)}function y(){return K({oneOf:[...z(),{type:"object",properties:{kind:{type:"string",const:"point"},x:{type:"number"},y:{type:"number"}},required:["kind","x","y"],additionalProperties:!1}],description:"UI target. This is separate from deviceTarget, which selects the device form."},(e,t)=>void 0===e[t]?void 0:function(e,t){let i=W(e,t),n=U(i,"kind",r);switch(n){case"ref":return{kind:n,ref:T(i,"ref"),label:k(i,"label")};case"selector":return{kind:n,selector:T(i,"selector")};case"point":return{kind:n,x:O(i,"x"),y:O(i,"y")}}}(e,t))}function h(){return K({oneOf:z(),description:"UI element target by snapshot ref or selector expression."},(e,t)=>{let r,i;return void 0===e[t]?void 0:"ref"===(i=U(r=W(e,t),"kind",["ref","selector"]))?{kind:i,ref:T(r,"ref"),label:k(r,"label")}:{kind:i,selector:T(r,"selector")}})}function v(e){return K({type:"object",description:e,properties:{x:{type:"number"},y:{type:"number"}},required:["x","y"],additionalProperties:!1},(e,t)=>void 0===e[t]?void 0:I(e,t))}function w(){return{depth:l("Snapshot traversal depth.",{min:0}),scope:d("Snapshot scope selector used before resolution."),raw:u("Use raw snapshot data during selector resolution.")}}function E(){return{count:l("Number of press/click repetitions.",{min:1}),intervalMs:l("Delay between repeated press/click actions.",{min:0}),holdMs:l("Hold duration for each action.",{min:0}),jitterPx:l("Randomization radius in pixels.",{min:0}),doubleTap:u("Request a double-tap action.")}}function x(r){return function(r,i=[]){return{type:"object",properties:{session:{type:"string",description:"Agent-device session name."},platform:{type:"string",enum:e,description:"Platform selector used to resolve a device."},deviceTarget:{type:"string",enum:t,description:"Device target form. Maps to the CLI --target flag."},target:{type:"string",enum:t,description:"Alias for deviceTarget on commands without a UI target field. Interaction commands reserve target for the UI element."},device:{type:"string",description:"Device name selector."},udid:{type:"string",description:"iOS device UDID selector."},serial:{type:"string",description:"Android serial selector."},iosSimulatorDeviceSet:{type:"string",description:"iOS simulator device-set path used for device resolution."},androidDeviceAllowlist:{type:"string",description:"Android serial allowlist used for device resolution."},daemonBaseUrl:{type:"string",description:"Remote daemon base URL."},daemonAuthToken:{type:"string",description:"Remote daemon auth token."},tenant:{type:"string",description:"Remote tenant identifier."},runId:{type:"string",description:"Lease run identifier."},leaseId:{type:"string",description:"Existing lease identifier."},cwd:{type:"string",description:"Working directory for command execution."},debug:{type:"boolean",description:"Enable debug diagnostics."},...r},...i.length>0?{required:i}:{},additionalProperties:!1}}(Object.fromEntries(Object.entries(r).map(([e,t])=>[e,t.schema])),Object.entries(r).flatMap(([e,t])=>t.required?[e]:[]))}function j(e,t){let r=A(e),i=Object.fromEntries(Object.entries(t).flatMap(([e,t])=>{let i=t.read(r,e);if(t.required&&void 0===i)throw Error(`Expected ${e} to be set.`);return void 0===i?[]:[[e,i]]})),n=S(r,{readTargetAlias:!Object.hasOwn(t,"target")});return B({...n,...q(n),...i})}function A(e){if(null==e)return{};if(!e||"object"!=typeof e||Array.isArray(e))throw Error("Expected object arguments.");return e}function S(r,i={}){return{session:k(r,"session"),platform:P(r,"platform",e),deviceTarget:function(e,r){let i=P(e,"deviceTarget",t);if(!1===r.readTargetAlias||void 0===e.target)return i;let n=P(e,"target",t);if(void 0!==i&&n!==i)throw Error("Expected target alias to match deviceTarget when both are set.");return i??n}(r,i),device:k(r,"device"),udid:k(r,"udid"),serial:k(r,"serial"),iosSimulatorDeviceSet:k(r,"iosSimulatorDeviceSet"),androidDeviceAllowlist:k(r,"androidDeviceAllowlist"),daemonBaseUrl:k(r,"daemonBaseUrl"),daemonAuthToken:k(r,"daemonAuthToken"),tenant:k(r,"tenant"),runId:k(r,"runId"),leaseId:k(r,"leaseId"),cwd:k(r,"cwd"),debug:D(r,"debug")}}function I(e,t){let r=W(e,t);return{x:O(r,"x"),y:O(r,"y")}}function T(e,t){let r=e[t];if("string"!=typeof r||0===r.length)throw Error(`Expected ${t} to be a non-empty string.`);return r}function k(e,t){let r=e[t];if(void 0!==r){if("string"!=typeof r||0===r.length)throw Error(`Expected ${t} to be a non-empty string.`);return r}}function O(e,t){let r=e[t];if("number"!=typeof r||!Number.isFinite(r))throw Error(`Expected ${t} to be a finite number.`);return r}function $(e,t){let r=e[t];if(void 0!==r){if("number"!=typeof r||!Number.isFinite(r))throw Error(`Expected ${t} to be a finite number.`);return r}}function F(e,t,r={}){let i=e[t];if(void 0!==i){if(!Number.isInteger(i))throw Error(`Expected ${t} to be an integer.`);if(void 0!==r.min&&i<r.min)throw Error(`Expected ${t} to be at least ${r.min}.`);if(void 0!==r.max&&i>r.max)throw Error(`Expected ${t} to be at most ${r.max}.`);return i}}function D(e,t){let r=e[t];if(void 0!==r){if("boolean"!=typeof r)throw Error(`Expected ${t} to be a boolean.`);return r}}function U(e,t,r){let i=e[t];if("string"!=typeof i||!r.includes(i))throw Error(`Expected ${t} to be one of: ${r.join(", ")}.`);return i}function P(e,t,r){let i=e[t];if(void 0!==i){if("string"!=typeof i||!r.includes(i))throw Error(`Expected ${t} to be one of: ${r.join(", ")}.`);return i}}function q(e){return B({session:e.session,platform:e.platform,target:e.deviceTarget,device:e.device,udid:e.udid,serial:e.serial,iosSimulatorDeviceSet:e.iosSimulatorDeviceSet,androidDeviceAllowlist:e.androidDeviceAllowlist,daemonBaseUrl:e.daemonBaseUrl,daemonAuthToken:e.daemonAuthToken,tenant:e.tenant,runId:e.runId,leaseId:e.leaseId,cwd:e.cwd,debug:e.debug})}function M(e){switch(e.kind){case"ref":return{ref:e.ref,label:e.label};case"selector":return{selector:e.selector};case"point":return{x:e.x,y:e.y}}}function R(e){switch(e.kind){case"ref":return{ref:e.ref,label:e.label};case"selector":return{selector:e.selector}}}function _(e){return{count:e.count,intervalMs:e.intervalMs,holdMs:e.holdMs,jitterPx:e.jitterPx,doubleTap:e.doubleTap}}function C(e){return{depth:e.depth,scope:e.scope,raw:e.raw}}function N(e,t,r){let i=new Set(t),n=Object.keys(e).filter(e=>!i.has(e));if(n.length>0)throw Error(`${r} has unknown field(s): ${n.join(", ")}.`)}function B(e){return Object.fromEntries(Object.entries(e).filter(([,e])=>void 0!==e))}function K(e,t){return{schema:e,required:!1,read:t}}function H(e,t){let r=e[t];if(void 0!==r){if(!r||"object"!=typeof r||Array.isArray(r))throw Error(`Expected ${t} to be an object.`);return r}}function L(e,t){let r=e[t];if(void 0!==r){if(!Array.isArray(r)||r.some(e=>"string"!=typeof e))throw Error(`Expected ${t} to be an array of strings.`);return r}}function z(){return[{type:"object",properties:{kind:{type:"string",const:"ref"},ref:{type:"string",description:"Snapshot element ref such as @e12."},label:{type:"string",description:"Optional human label for the ref."}},required:["kind","ref"],additionalProperties:!1},{type:"object",properties:{kind:{type:"string",const:"selector"},selector:{type:"string",description:"Agent-device selector expression."}},required:["kind","selector"],additionalProperties:!1}]}function W(e,t){let r=e[t];if(!r||"object"!=typeof r||Array.isArray(r))throw Error(`Expected ${t} to be an object.`);return r}export{N as assertAllowedKeys,u as booleanField,o as booleanSchema,q as commonToClientOptions,B as compactRecord,g as customField,h as elementTargetField,p as enumField,x as fieldsInputSchema,l as integerField,n as integerSchema,y as interactionTargetField,b as jsonSchemaField,f as looseObjectField,s as looseObjectSchema,c as numberField,P as optionalEnum,F as optionalInteger,v as pointField,S as readCommonInput,j as readFieldInput,A as readInputRecord,I as readPoint,E as repeatedFields,U as requiredEnum,a as requiredField,O as requiredNumber,w as selectorSnapshotFields,m as stringArrayField,d as stringField,i as stringSchema,R as toClientElementTarget,M as toClientInteractionTarget,_ as toRepeatedOptions,C as toSelectorSnapshotOptions};
|
|
@@ -135,7 +135,7 @@ export declare type AndroidPortReverseProvider = {
|
|
|
135
135
|
};
|
|
136
136
|
|
|
137
137
|
export declare type AndroidTextInjectionRequest = {
|
|
138
|
-
action:
|
|
138
|
+
action: AndroidTextInputAction;
|
|
139
139
|
text: string;
|
|
140
140
|
delayMs?: number;
|
|
141
141
|
/**
|
|
@@ -150,6 +150,8 @@ export declare type AndroidTextInjectionRequest = {
|
|
|
150
150
|
|
|
151
151
|
export declare type AndroidTextInjector = (request: AndroidTextInjectionRequest) => Promise<void>;
|
|
152
152
|
|
|
153
|
+
declare type AndroidTextInputAction = 'type' | 'fill';
|
|
154
|
+
|
|
153
155
|
declare type AndroidTouchGestureRequest = {
|
|
154
156
|
kind: 'swipe';
|
|
155
157
|
x1: number;
|
|
@@ -182,8 +184,6 @@ declare type AndroidTouchGestureRequest = {
|
|
|
182
184
|
|
|
183
185
|
declare type AndroidTouchInjector = (request: AndroidTouchGestureRequest) => Promise<Record<string, unknown> | void>;
|
|
184
186
|
|
|
185
|
-
declare type ApplePlatform = 'ios' | 'macos';
|
|
186
|
-
|
|
187
187
|
declare type AppsFilter = 'user-installed' | 'all';
|
|
188
188
|
|
|
189
189
|
export declare function captureAndroidLogcatWithAdb(adb: AndroidAdbExecutor, options?: AndroidLogcatCaptureOptions): Promise<string>;
|
|
@@ -192,6 +192,10 @@ export declare function createAndroidPortReverseManager(provider: AndroidAdbProv
|
|
|
192
192
|
|
|
193
193
|
export declare function createLocalAndroidAdbProvider(device: DeviceInfo): AndroidAdbProvider;
|
|
194
194
|
|
|
195
|
+
declare const DEVICE_KINDS: readonly ["simulator", "emulator", "device"];
|
|
196
|
+
|
|
197
|
+
declare const DEVICE_TARGETS: readonly ["mobile", "tv", "desktop"];
|
|
198
|
+
|
|
195
199
|
declare type DeviceInfo = {
|
|
196
200
|
platform: Platform;
|
|
197
201
|
id: string;
|
|
@@ -202,9 +206,9 @@ declare type DeviceInfo = {
|
|
|
202
206
|
simulatorSetPath?: string;
|
|
203
207
|
};
|
|
204
208
|
|
|
205
|
-
declare type DeviceKind =
|
|
209
|
+
declare type DeviceKind = (typeof DEVICE_KINDS)[number];
|
|
206
210
|
|
|
207
|
-
declare type DeviceTarget =
|
|
211
|
+
declare type DeviceTarget = (typeof DEVICE_TARGETS)[number];
|
|
208
212
|
|
|
209
213
|
export declare function dismissAndroidKeyboardWithAdb(adb: AndroidAdbExecutor): Promise<AndroidKeyboardDismissResult>;
|
|
210
214
|
|
|
@@ -250,7 +254,9 @@ export declare function listAndroidAppsWithAdb(adb: AndroidAdbExecutor, options?
|
|
|
250
254
|
|
|
251
255
|
export declare function openAndroidAppWithAdb(adb: AndroidAdbExecutor, packageName: string, options?: AndroidOpenAppWithAdbOptions): Promise<void>;
|
|
252
256
|
|
|
253
|
-
declare type Platform =
|
|
257
|
+
declare type Platform = (typeof PLATFORMS)[number];
|
|
258
|
+
|
|
259
|
+
declare const PLATFORMS: readonly ["ios", "macos", "android", "linux"];
|
|
254
260
|
|
|
255
261
|
export declare function readAndroidClipboardWithAdb(adb: AndroidAdbExecutor): Promise<string>;
|
|
256
262
|
|
package/dist/src/android-adb.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{AppError as t}from"./9152.js";import{resolveAppsFilter as e}from"./
|
|
1
|
+
import{AppError as t}from"./9152.js";import{resolveAppsFilter as e}from"./3675.js";import{parseAndroidForegroundApp as i,parseAndroidLaunchablePackages as a,parseAndroidUserInstalledPackages as r,inferAndroidAppName as o,parseAndroidLaunchComponent as n,isAmStartError as d}from"./8806.js";let l="android.intent.category.LAUNCHER",s="android.intent.category.LEANBACK_LAUNCHER";async function c(t,i={}){let a=await A(t,i.target??"auto");return("user-installed"===e(i.filter)?(await p(t)).filter(t=>a.has(t)):Array.from(a)).map(t=>({package:t,name:o(t)})).sort((t,e)=>t.package.localeCompare(e.package))}async function u(t){let e=await f(t,[["shell","dumpsys","window","windows"],["shell","dumpsys","window"]]);if(e)return e;let i=await f(t,[["shell","dumpsys","activity","activities"],["shell","dumpsys","activity"]]);return i||{}}async function A(t,e){return new Set((await Promise.all((function(t){switch(t){case"mobile":return[l];case"tv":return[s];default:return[l,s]}})(e).map(async e=>{var i;let r=await t(["shell","cmd","package","query-activities","--brief","-a","android.intent.action.MAIN","-c",e],{allowFailure:!0});return 0===r.exitCode?0===(i=r.stdout).trim().length?[]:a(i):[]}))).flat())}async function p(e){let i=await e(["shell","pm","list","packages","-3"],{allowFailure:!0});if(0!==i.exitCode)throw new t("COMMAND_FAILED","Failed to list Android user-installed apps",{stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode});return r(i.stdout)}async function f(t,e){for(let a of e){let e=i((await t(a,{allowFailure:!0})).stdout??"");if(e)return e}return null}let _="android.intent.category.LAUNCHER",m="android.intent.category.DEFAULT";async function w(t,e){await t(["shell","am","force-stop",e])}async function h(t,e,i=[_]){for(let a of i){let i=await t(["shell","cmd","package","resolve-activity","--brief","-a","android.intent.action.MAIN","-c",a,e],{allowFailure:!0});if(0!==i.exitCode)continue;let r=n(i.stdout);if(r)return r}return null}async function C(e,i,a={}){let r=a.category??_;if(a.activity){var o,n;return void await e(["shell","am","start","-W","-a","android.intent.action.MAIN","-c",m,"-c",r,"-n",(o=i,(n=a.activity).includes("/")?n:`${o}/${n.startsWith(".")?n:`.${n}`}`)])}let l=await e(["shell","am","start","-W","-a","android.intent.action.MAIN","-c",m,"-c",r,"-p",i],{allowFailure:!0});if(0===l.exitCode&&!d(l.stdout,l.stderr))return;let s=await h(e,i,[r]);if(!s)throw new t("COMMAND_FAILED",`Failed to resolve Android launch component for ${i}`,{stdout:l.stdout,stderr:l.stderr,exitCode:l.exitCode});await e(["shell","am","start","-W","-a","android.intent.action.MAIN","-c",m,"-c",r,"-n",s])}export{captureAndroidLogcatWithAdb,streamAndroidLogcatWithAdb}from"./8806.js";export{createAndroidPortReverseManager,createLocalAndroidAdbProvider}from"./9639.js";export{dismissAndroidKeyboardWithAdb,getAndroidKeyboardStatusWithAdb,readAndroidClipboardWithAdb,writeAndroidClipboardWithAdb}from"./8133.js";export{w as forceStopAndroidAppWithAdb,u as getAndroidAppStateWithAdb,c as listAndroidAppsWithAdb,C as openAndroidAppWithAdb,h as resolveAndroidLaunchComponentWithAdb};
|
|
@@ -103,23 +103,25 @@ export declare type AndroidSnapshotBackendMetadata = {
|
|
|
103
103
|
backend: 'android-helper' | 'uiautomator-dump';
|
|
104
104
|
helperVersion?: string;
|
|
105
105
|
helperApiVersion?: string;
|
|
106
|
-
helperTransport?:
|
|
106
|
+
helperTransport?: AndroidSnapshotHelperTransport;
|
|
107
107
|
helperSessionReused?: boolean;
|
|
108
108
|
fallbackReason?: string;
|
|
109
|
-
installReason?:
|
|
109
|
+
installReason?: AndroidSnapshotHelperInstallReason;
|
|
110
110
|
waitForIdleTimeoutMs?: number;
|
|
111
111
|
waitForIdleQuietMs?: number;
|
|
112
112
|
timeoutMs?: number;
|
|
113
113
|
maxDepth?: number;
|
|
114
114
|
maxNodes?: number;
|
|
115
115
|
rootPresent?: boolean;
|
|
116
|
-
captureMode?:
|
|
116
|
+
captureMode?: AndroidSnapshotCaptureMode;
|
|
117
117
|
windowCount?: number;
|
|
118
118
|
nodeCount?: number;
|
|
119
119
|
helperTruncated?: boolean;
|
|
120
120
|
elapsedMs?: number;
|
|
121
121
|
};
|
|
122
122
|
|
|
123
|
+
declare type AndroidSnapshotCaptureMode = 'interactive-windows' | 'active-window';
|
|
124
|
+
|
|
123
125
|
export declare type AndroidSnapshotHelperArtifact = {
|
|
124
126
|
apkPath: string;
|
|
125
127
|
manifest: AndroidSnapshotHelperManifest;
|
|
@@ -145,12 +147,14 @@ export declare type AndroidSnapshotHelperCaptureOptions = {
|
|
|
145
147
|
|
|
146
148
|
export declare type AndroidSnapshotHelperInstallPolicy = 'missing-or-outdated' | 'always' | 'never';
|
|
147
149
|
|
|
150
|
+
declare type AndroidSnapshotHelperInstallReason = 'missing' | 'outdated' | 'forced' | 'current' | 'skipped';
|
|
151
|
+
|
|
148
152
|
export declare type AndroidSnapshotHelperInstallResult = {
|
|
149
153
|
packageName: string;
|
|
150
154
|
versionCode: number;
|
|
151
155
|
installedVersionCode?: number;
|
|
152
156
|
installed: boolean;
|
|
153
|
-
reason:
|
|
157
|
+
reason: AndroidSnapshotHelperInstallReason;
|
|
154
158
|
};
|
|
155
159
|
|
|
156
160
|
export declare type AndroidSnapshotHelperManifest = {
|
|
@@ -180,12 +184,12 @@ export declare type AndroidSnapshotHelperMetadata = {
|
|
|
180
184
|
maxDepth?: number;
|
|
181
185
|
maxNodes?: number;
|
|
182
186
|
rootPresent?: boolean;
|
|
183
|
-
captureMode?:
|
|
187
|
+
captureMode?: AndroidSnapshotCaptureMode;
|
|
184
188
|
windowCount?: number;
|
|
185
189
|
nodeCount?: number;
|
|
186
190
|
truncated?: boolean;
|
|
187
191
|
elapsedMs?: number;
|
|
188
|
-
transport?:
|
|
192
|
+
transport?: AndroidSnapshotHelperTransport;
|
|
189
193
|
sessionReused?: boolean;
|
|
190
194
|
};
|
|
191
195
|
|
|
@@ -205,8 +209,10 @@ export declare type AndroidSnapshotHelperPreparedArtifact = AndroidSnapshotHelpe
|
|
|
205
209
|
cleanup?: () => Promise<void>;
|
|
206
210
|
};
|
|
207
211
|
|
|
212
|
+
declare type AndroidSnapshotHelperTransport = 'instrumentation' | 'persistent-session';
|
|
213
|
+
|
|
208
214
|
declare type AndroidTextInjectionRequest = {
|
|
209
|
-
action:
|
|
215
|
+
action: AndroidTextInputAction;
|
|
210
216
|
text: string;
|
|
211
217
|
delayMs?: number;
|
|
212
218
|
/**
|
|
@@ -221,6 +227,8 @@ declare type AndroidTextInjectionRequest = {
|
|
|
221
227
|
|
|
222
228
|
declare type AndroidTextInjector = (request: AndroidTextInjectionRequest) => Promise<void>;
|
|
223
229
|
|
|
230
|
+
declare type AndroidTextInputAction = 'type' | 'fill';
|
|
231
|
+
|
|
224
232
|
declare type AndroidTouchGestureRequest = {
|
|
225
233
|
kind: 'swipe';
|
|
226
234
|
x1: number;
|
package/dist/src/android.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
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"./
|
|
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"./9673.js";import{parseAppearanceAction as R,summarizeCommandAttemptFailures as D,parseSettingState as E,parsePermissionTarget as x,parsePermissionAction as k}from"./6629.js";import{openAndroidDevice as b,runAndroidAdb as O,openAndroidApp as L,resolveAndroidApp as F,closeAndroidApp as P}from"./8806.js";import{writeAndroidClipboardText as T,readAndroidClipboardText as U}from"./8133.js";import{snapshotAndroid as $}from"./2415.js";import{sleep as G}from"./4829.js";let K="android-multitouch-helper-v1",V="ANDROID_MULTITOUCH_HELPER_NO_FINAL_RESULT",H="ANDROID_MULTITOUCH_HELPER_REPORTED_FAILURE";async function q(e,t){let r=await X(e,{kind:"swipe",...t});if(r)return r;try{return await Q(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 B(e,t){if(!Number.isFinite(t.scale)||t.scale<=0)throw new n("INVALID_ARGS","gesture pinch requires scale > 0");let r=await J(e,t.x,t.y);return await W(e,{kind:"pinch",x:r.x,y:r.y,scale:t.scale,durationMs:t.durationMs})}async function j(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 J(e,t.x,t.y),i=t.degrees;return await W(e,{kind:"rotate",x:r.x,y:r.y,degrees:i,durationMs:t.durationMs})}async function z(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 W(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 J(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 W(e,t){let r=await X(e,t);return r||await Q(e,t)}async function X(e,t){let r=u(e);if(r)return{backend:"provider-native-touch",...await r(t)??{}}}async function Q(e,t){let r=p(e),i=await ee(),a=c(e),n=await o("android_multitouch_helper_install",async()=>{var t;return await et({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 Y({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 Y(e){let t,r=Buffer.from(JSON.stringify({protocol:K,...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===K);if(!t)throw new n(V,"Android multi-touch helper did not return a final result");if("true"!==t.ok){var r;throw new n(H,(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:Z(t.injectedEvents),elapsedMs:Z(t.elapsedMs)}}(`${i.stdout}
|
|
2
2
|
${i.stderr}`)}catch(e){if(e instanceof n){if(e.code===H)throw new n("COMMAND_FAILED",e.message,e.details,e);if(e.code!==V)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 Z(e){if(void 0===e)return;let t=Number(e);return Number.isFinite(t)?t:void 0}async function ee(){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:es(e.name,"name","android-multitouch-helper"),version:eo(e.version,"version"),assetName:eo(e.assetName,"assetName"),sha256:function(e){let t=eo(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:es(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:es(e.instrumentationRunner,"instrumentationRunner","com.callstack.agentdevice.multitouchhelper/.MultiTouchInstrumentation"),statusProtocol:es(e.statusProtocol,"statusProtocol",K)}}(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 et(e){let{adb:t,artifact:r}=e,i=r.manifest.packageName,a=r.manifest.versionCode,o=`${e.deviceKey}\0${i}\0${a}`;if(er.has(o))return{packageName:i,versionCode:a,installed:!1,reason:"current"};let s=await ei(t,i);if(void 0!==s&&s>=a)return er.add(o),{packageName:i,versionCode:a,installedVersionCode:s,installed:!1,reason:"current"};await ea(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 er.add(o),{packageName:i,versionCode:a,installedVersionCode:s,installed:!0,reason:void 0===s?"missing":"outdated"}}let er=new Set;async function ei(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
3
|
${r.stderr}`);return i?Number(i[1]):void 0}async function ea(e){let t=await en(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 en(r){let i=e.createHash("sha256");return i.update(await t.readFile(r)),i.digest("hex")}function eo(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 es(e,t,r){if(e!==r)throw new n("INVALID_ARGS",`Android multi-touch helper manifest ${t} must be "${r}".`);return r}let ed=["window_animation_scale","transition_animation_scale","animator_duration_scale"];async function el(e,t,r,i,a){switch(t.toLowerCase()){case"wifi":{let t=E(r);await O(e,["shell","svc","wifi",t?"enable":"disable"]);return}case"airplane":{let t=E(r);await O(e,["shell","settings","put","global","airplane_mode_on",t?"1":"0"]),await O(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 O(e,["emu","geo","fix",String(r),String(t)]),{latitude:t,longitude:r}}let t=E(r);await O(e,["shell","settings","put","secure","location_mode",t?"3":"0"]);return}case"animations":{let t=E(r)?"1":"0";for(let r of ed)await O(e,["shell","settings","put","global",r,t]);return{scale:t,keys:[...ed]}}case"appearance":{let t=await ec(e,r);await O(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 F(e,i);if("intent"===t.type)throw new n("INVALID_ARGS","settings clear-app-state requires a package name, not an intent.");await O(e,["shell","am","force-stop",t.value],{allowFailure:!0});let a=await O(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 eu(e,t);return}case"permission":{if(!i)throw new n("INVALID_ARGS","permission setting requires an active app in session");let t=k(r),o=function(e,t){let r=x(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 em(e,i,t,o);let s="grant"===t?"grant":"revoke";if("photos"===o.type)return void await ep(e,i,s);await O(e,["shell","pm",s,i,o.value]);return}default:throw new n("INVALID_ARGS",`Unsupported setting: ${t}`)}}async function eu(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 O(e,t,{allowFailure:!0});if(0===r.exitCode)return;s.push({args:t,stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode})}let d=D(s);if(s.length>0&&s.every(e=>{var t,r;let i;return t=e.stdout,r=e.stderr,(i=`${t}
|
|
4
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 ec(e,t){let r=R(t);if("toggle"!==r)return r;let i=await O(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}
|
package/dist/src/apple.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{AppError as e}from"./9152.js";import{
|
|
1
|
+
import{AppError as e}from"./9152.js";import{buildScrollGesturePlan as a}from"./1620.js";import{runMacOsScreenshotAction as t,runIosRunnerCommand as n}from"./2415.js";import{writeIosClipboardText as d,openIosApp as o,openIosDevice as r,screenshotIos as i,closeIosApp as p,setIosSetting as l,readIosClipboardText as u}from"./apps.js";import{withDiagnosticTimer as c}from"./7599.js";function s(e,a,t,n){return{command:"tap",x:t,y:n,..."ios"===e.platform&&"tv"!==e.target?{synthesized:!0}:{},appBundleId:a.appBundleId}}function m(e,a,t,n,d,o,r,i){var p,l;let u="ios"===e.platform&&"tv"!==e.target?(p=r,l=i.defaultDurationMs,void 0===p?l:Math.min(1e4,Math.max(16,Math.round(p)))):r??i.legacyDefaultDurationMs;return{command:"drag",x:t,y:n,x2:d,y2:o,...void 0!==u?{durationMs:u}:{},appBundleId:a.appBundleId}}function y(e,a,t){return{command:"remotePress",remoteButton:e,...void 0!==t?{durationMs:t}:{},...void 0!==a?{appBundleId:a}:{}}}async function f(e,t,n,d,o,r,i){if("tv"===t.target)return w(await e(t,y(o,n.appBundleId),d),r);let p=i??await I(e,t,n,d),l=a({direction:o,amount:r?.amount,pixels:r?.pixels,referenceWidth:p.referenceWidth,referenceHeight:p.referenceHeight});return w(await e(t,m(t,n,p.originX+l.x1,p.originY+l.y1,p.originX+l.x2,p.originY+l.y2,void 0,{defaultDurationMs:250}),d),{amount:l.amount,pixels:l.pixels,preferProvidedPixels:!0})}async function I(a,t,n,d){let o=await a(t,{command:"interactionFrame",appBundleId:n.appBundleId},d),r=v(o.x),i=v(o.y),p=v(o.referenceWidth),l=v(o.referenceHeight);if(void 0===r||void 0===i||void 0===p||void 0===l)throw new e("COMMAND_FAILED","interactionFrame did not return a usable frame");return{originX:r,originY:i,referenceWidth:p,referenceHeight:l}}function v(e){return"number"==typeof e&&Number.isFinite(e)?e:void 0}function w(e,a){var t;let{x1:n,y1:d,x2:o,y2:r}={x1:v((t=e).x),y1:v(t.y),x2:v(t.x2),y2:v(t.y2)},i=v(e.referenceWidth),p=v(e.referenceHeight),l=void 0!==n&&void 0!==o?Math.round(Math.abs(o-n)):void 0,u=void 0!==d&&void 0!==r?Math.round(Math.abs(r-d)):void 0,c=a?.preferProvidedPixels&&void 0!==a.pixels?a.pixels:l&&l>0?l:u&&u>0?u: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!==p?{referenceHeight:p}:{},...a?.amount!==void 0?{amount:a.amount}:{},...void 0!==c?{pixels:c}:{}}}function B(a,I){let v,{overrides:w,runnerOpts:B}={runnerOpts:v={verbose:I.verbose,logPath:I.logPath,traceLogPath:I.traceLogPath,requestId:I.requestId},overrides:{tap:async(e,t)=>await n(a,s(a,I,e,t),v),tapElementSelector:async e=>await n(a,{command:"tap",selectorKey:e.key,selectorValue:e.value,allowNonHittableCoordinateFallback:e.allowNonHittableCoordinateFallback,appBundleId:I.appBundleId},v),doubleTap:async(e,t)=>await n(a,{command:"tapSeries",x:e,y:t,count:1,intervalMs:0,doubleTap:!0,appBundleId:I.appBundleId},v),swipe:async(e,t,d,o,r)=>await n(a,m(a,I,e,t,d,o,r,{defaultDurationMs:250}),v),pan:async(e,t,d,o,r)=>await n(a,m(a,I,e,t,d,o,r,{defaultDurationMs:500,legacyDefaultDurationMs:500}),v),fling:async(e,t,d,o,r)=>await n(a,{command:"drag",x:e,y:t,x2:d,y2:o,durationMs:r??16,appBundleId:I.appBundleId},v),longPress:async(e,t,d)=>await n(a,{command:"longPress",x:e,y:t,durationMs:d,appBundleId:I.appBundleId},v),focus:async(e,t)=>await n(a,s(a,I,e,t),v),type:async(e,t)=>{await n(a,{command:"type",text:e,delayMs:t,textEntryMode:"\n"===e?void 0:"append",appBundleId:I.appBundleId},v)},fillElementSelector:async(e,t,d)=>await n(a,{command:"type",selectorKey:e.key,selectorValue:e.value,allowNonHittableCoordinateFallback:e.allowNonHittableCoordinateFallback,text:t,delayMs:d,textEntryMode:"replace",appBundleId:I.appBundleId},v),fill:async(e,t,d,o)=>await n(a,{command:"type",x:e,y:t,text:d,delayMs:o,textEntryMode:"replace",appBundleId:I.appBundleId},v),scroll:async(e,t)=>await f(n,a,I,v,e,t),pinch:async(e,t,d)=>{await n(a,{command:"pinch",scale:e,x:t,y:d,appBundleId:I.appBundleId},v)},rotateGesture:async(e,t,d,o)=>{await n(a,{command:"rotateGesture",degrees:e,x:t,y:d,velocity:o,appBundleId:I.appBundleId},v)},transformGesture:async e=>await n(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:I.appBundleId},v)}};return{open:(e,t)=>o(a,e,{appBundleId:t?.appBundleId,launchConsole:t?.launchConsole,launchArgs:t?.launchArgs,url:t?.url}),openDevice:()=>r(a),close:e=>p(a,e),screenshot:async(e,n)=>{"macos"===a.platform&&n?.surface&&"app"!==n.surface?await t(e,{surface:n.surface,fullscreen:n.fullscreen}):await i(a,e,n?.appBundleId,n?.fullscreen,B)},snapshot:async t=>{var d;let o={nodes:Array.isArray((d=await c("snapshot_capture",async()=>await n(a,{command:"snapshot",appBundleId:t?.appBundleId,interactiveOnly:t?.interactiveOnly,compact:t?.compact,depth:t?.depth,scope:t?.scope,raw:t?.raw},B),{backend:"xctest"})).nodes)?d.nodes:void 0,truncated:"boolean"==typeof d.truncated?d.truncated:void 0},r=o.nodes??[];if(0===r.length&&"simulator"===a.kind)throw new e("COMMAND_FAILED","XCTest snapshot returned 0 nodes on iOS simulator.");return{nodes:r,truncated:o.truncated??!1,backend:"xctest"}},back:async e=>{"tv"===a.target?await n(a,y("menu",I.appBundleId),B):await n(a,{command:"system"===e?"backSystem":"backInApp",appBundleId:I.appBundleId},B)},home:async()=>{"tv"===a.target?await n(a,y("home",I.appBundleId),B):await n(a,{command:"home",appBundleId:I.appBundleId},B)},rotate:async e=>{await n(a,{command:"rotate",orientation:e,appBundleId:I.appBundleId},B)},appSwitcher:async()=>{await n(a,{command:"appSwitcher",appBundleId:I.appBundleId},B)},readClipboard:()=>u(a),writeClipboard:e=>d(a,e),setSetting:(e,t,n,d)=>l(a,e,t,n,d),...w}}export{B as createAppleInteractor};
|