agent-device 0.14.6 → 0.14.8
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 +119 -8
- package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.14.6.apk → agent-device-android-snapshot-helper-0.14.8.apk} +0 -0
- package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.14.8.apk.sha256 +1 -0
- package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.14.6.manifest.json → agent-device-android-snapshot-helper-0.14.8.manifest.json} +6 -6
- package/dist/src/180.js +1 -1
- package/dist/src/1974.js +2 -2
- package/dist/src/208.js +1 -0
- package/dist/src/221.js +3 -3
- package/dist/src/6108.js +26 -0
- package/dist/src/7462.js +1 -0
- package/dist/src/7719.js +1 -0
- package/dist/src/9542.js +2 -2
- package/dist/src/9671.js +1 -0
- package/dist/src/cli.js +82 -0
- package/dist/src/command-schema.js +381 -0
- package/dist/src/index.js +1 -1
- package/dist/src/internal/bin.js +2 -453
- package/dist/src/internal/daemon.js +13 -13
- package/dist/src/io.js +1 -1
- package/dist/src/remote-config.js +1 -1
- package/dist/src/server.js +20 -0
- package/package.json +33 -6
- package/server.json +21 -0
- package/skills/react-devtools/SKILL.md +10 -1
- package/smithery.yaml +1 -0
- package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.14.6.apk.sha256 +0 -1
- package/dist/src/2007.js +0 -26
package/dist/src/7462.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{AppError as t}from"./9152.js";let n="<wifi|airplane|location> <on|off>",e="animations <on|off>",i="appearance <light|dark|toggle>",o="faceid <match|nonmatch|enroll|unenroll>",s="touchid <match|nonmatch|enroll|unenroll>",a="fingerprint <match|nonmatch>",r="permission <grant|deny|reset> <camera|microphone|photos|contacts|contacts-limited|notifications|calendar|location|location-always|media-library|motion|reminders|siri> [full|limited]",c="permission <grant|reset> <accessibility|screen-recording|input-monitoring>",p=`macOS supports only settings ${i} and settings ${c}. wifi|airplane|location|animations remain unsupported on macOS.`,m=`settings ${n} | settings ${e} | settings ${i} | settings ${o} | settings ${s} | settings ${a} | settings ${r} | settings ${c}`,l=`settings requires ${n}, ${e}, ${i}, ${o}, ${s}, ${a}, ${r}, or ${c}`;function g(t){let n=t.trim().toLowerCase();return"appearance"===n||"permission"===n}function S(t){return`Unsupported macOS setting: ${t}. ${p}`}let u=["app","frontmost-app","desktop","menubar"];function $(n){let e=n?.trim().toLowerCase();if("app"===e||"frontmost-app"===e||"desktop"===e||"menubar"===e)return e;throw new t("INVALID_ARGS",`Invalid surface: ${n}. Use ${u.join("|")}.`)}export{u as SESSION_SURFACES,l as SETTINGS_INVALID_ARGS_MESSAGE,m as SETTINGS_USAGE_OVERRIDE,S as getUnsupportedMacOsSettingMessage,g as isMacOsSettingSupported,$ as parseSessionSurface};
|
package/dist/src/7719.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{promises as t}from"node:fs";import e from"node:os";import i from"node:path";import{AppError as a}from"./9152.js";function r(n={}){let l=n.cwd??process.cwd(),c=n.tempDir??e.tmpdir(),p=n.rootDir?o(n.rootDir,l):void 0;return{resolveInput:async t=>{if("uploadedArtifact"===t.kind)throw new a("UNSUPPORTED_OPERATION","Uploaded artifact inputs require a custom artifact adapter");return{path:o(t.path,l,p)}},reserveOutput:async(e,a)=>{let r,n=a.visibility??"client-visible",d=e?.kind==="path"?o(e.path,l,p):i.join(r=await t.mkdtemp(i.join(c,`agent-device-${a.field}-`)),`${a.field}${a.ext}`);return await t.mkdir(i.dirname(d),{recursive:!0}),{path:d,visibility:n,...r?{cleanup:async()=>{await t.rm(r,{recursive:!0,force:!0})}}:{},publish:async()=>e?.kind==="downloadableArtifact"?{kind:"localPath",field:a.field,path:d,fileName:e.fileName??i.basename(e.clientPath??d)}:void 0}},createTempFile:async e=>{let a=await t.mkdtemp(i.join(c,`${e.prefix}-`));return{path:i.join(a,`file${e.ext}`),visibility:"internal",cleanup:async()=>{await t.rm(a,{recursive:!0,force:!0})}}}}}function o(t,e,r){var o,n;let l,c=i.isAbsolute(t)?t:i.resolve(e,t);if(r&&(o=c,n=r,""!==(l=i.relative(n,o))&&(l.startsWith("..")||i.isAbsolute(l))))throw new a("INVALID_ARGS","Local path is outside the artifact adapter root",{path:c,rootDir:r});return c}export{r as createLocalArtifactAdapter};
|
package/dist/src/9542.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import e from"node:net";import t from"node:http";import a from"node:https";import r from"node:fs";import o from"node:path";import{pipeline as n}from"node:stream/promises";import i from"node:os";import{createHash as s,randomUUID as l}from"node:crypto";import{Writable as d}from"node:stream";import{toAppErrorCode as c,AppError as u}from"./9152.js";import{runCmdSync as p,runCmd as m,runCmdDetached as f}from"./9818.js";import{buildDeviceIdentifiers as h,resolveDaemonPaths as y,readVersion as w,findProjectRoot as v,resolveDaemonServerMode as g,computeDaemonCodeSignature as I,resolveDaemonTransportPreference as b,buildAppIdentifiers as A}from"./180.js";import{createRequestId as _,withDiagnosticTimer as M,emitDiagnostic as S}from"./7599.js";import{isAgentDeviceDaemonProcess as k,stopProcessForTakeover as E}from"./8656.js";import{sleep as D}from"./4829.js";import{tryParseSelectorChain as P}from"./940.js";import{reloadMetro as T,prepareMetroRuntime as N}from"./1974.js";let U="sha256";async function x(e){let t=await C(e.localPath,e.platform),a=e.baseUrl.endsWith("/")?e.baseUrl:`${e.baseUrl}/`;try{let r=await F({normalizedBase:a,token:e.token,artifact:t});if(r?.kind==="cache-hit")return r.uploadId;if(r?.kind==="direct-upload")try{return await B(t.payloadPath,r),await j({normalizedBase:a,token:e.token,uploadId:r.uploadId})}catch{}return await L({normalizedBase:a,token:e.token,artifact:t})}finally{t.cleanup()}}async function C(e,t){var a,n,i;let s,l=r.statSync(e),d=o.basename(e),c=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=c?await R(e,p):e,a=r.statSync(t);return{payloadPath:t,fileName:d,artifactType:c?"app-bundle":"file",platform:u,contentType:c?"application/gzip":"application/octet-stream",sha256:await z(t),sizeBytes:a.size,cleanup:()=>O(p)}}catch(e){throw O(p),e}}async function R(e,t){let a=r.mkdtempSync(o.join(i.tmpdir(),`agent-device-upload-${l()}-`));t.push(a);let n=o.join(a,`${o.basename(e)}.tar.gz`);return await m("tar",["czf",n,"-C",o.dirname(e),o.basename(e)]),n}function O(e){for(let t of e)r.rmSync(t,{recursive:!0,force:!0})}async function L(e){let{normalizedBase:t,token:a,artifact:r}=e,o=new URL("upload",t),n={"content-type":r.contentType,"x-artifact-type":r.artifactType,"x-artifact-filename":r.fileName,"x-artifact-hash":r.sha256,"x-artifact-hash-algorithm":U,"transfer-encoding":"chunked"};a&&(n.authorization=`Bearer ${a}`,n["x-agent-device-token"]=a);let i=await q({url:o,method:"POST",headers:n,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 F(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 B(e,t){let a=await q({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 q(e){let o="https:"===e.url.protocol?a:t;return await new Promise((t,a)=>{let i=o.request({protocol:e.url.protocol,host:e.url.hostname,port:e.url.port,method:e.method,path:e.url.pathname+e.url.search,headers:e.headers},e=>{let a="";e.setEncoding("utf8"),e.on("data",e=>{a+=e}),e.on("end",()=>{clearTimeout(s),t({statusCode:e.statusCode??500,statusMessage:e.statusMessage,body:a})})}),s=setTimeout(()=>{i.destroy(),a(new u("COMMAND_FAILED",e.timeoutMessage,{timeoutMs:3e5,...e.timeoutHint?{hint:e.timeoutHint}:{}}))},3e5);i.on("error",t=>{clearTimeout(s),a(new u("COMMAND_FAILED",e.errorMessage,e.errorHint?{hint:e.errorHint}:{},t))}),i.on("close",()=>clearTimeout(s)),n(r.createReadStream(e.payloadPath),i).catch(e=>{i.destroy(),a(new u("COMMAND_FAILED","Failed to read local artifact",{},e instanceof Error?e:Error(String(e))))})})}async function j(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 o=await r.json().catch(()=>void 0);if(!o?.ok||!o.uploadId)throw new u("COMMAND_FAILED","Invalid upload finalize response");return o.uploadId}async function z(e){let t=s(U),a=new d({write(e,a,r){t.update(e),r()}});return await n(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")}let $=eA(),H=function(e=process.env.AGENT_DEVICE_DAEMON_STARTUP_TIMEOUT_MS){if(!e)return 15e3;let t=Number(e);return Number.isFinite(t)?Math.max(1e3,Math.floor(t)):15e3}(),V=function(e=process.env.AGENT_DEVICE_DAEMON_STARTUP_ATTEMPTS){if(!e)return 2;let t=Number(e);return Number.isFinite(t)?Math.min(5,Math.max(1,Math.floor(t))):2}(),G=["xcodebuild .*AgentDeviceRunnerUITests/RunnerTests/testCommand","xcodebuild .*AgentDeviceRunner\\.env\\.session-","xcodebuild build-for-testing .*ios-runner/AgentDeviceRunner/AgentDeviceRunner\\.xcodeproj"],K=new e.BlockList;async function J(t){let a=t.meta?.requestId??_(),r=!!(t.meta?.debug||t.flags?.verbose),o=function(t){let a,r=t.flags?.stateDir??process.env.AGENT_DEVICE_STATE_DIR,o=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(/\/+$/,"")}}(t.flags?.daemonBaseUrl??process.env.AGENT_DEVICE_DAEMON_BASE_URL),n=t.flags?.daemonAuthToken??process.env.AGENT_DEVICE_DAEMON_AUTH_TOKEN;var i=o,s=n;if(!(!i||"localhost"===(a=new URL(i).hostname.trim().toLowerCase().replace(/^\[(.*)\]$/,"$1"))||(e.isIPv4(a)?K.check(a,"ipv4"):!!e.isIPv6(a)&&K.check(a,"ipv6")))&&("string"!=typeof s||!(s.trim().length>0)))throw new u("INVALID_ARGS","Remote daemon base URL for non-loopback hosts requires daemon authentication",{daemonBaseUrl:i,hint:"Provide --daemon-auth-token or AGENT_DEVICE_DAEMON_AUTH_TOKEN when using a non-loopback remote daemon URL."});let l=t.flags?.daemonTransport??process.env.AGENT_DEVICE_DAEMON_TRANSPORT,d=b(l);if(o&&"socket"===d)throw new u("INVALID_ARGS","Remote daemon base URL only supports HTTP transport. Remove --daemon-transport socket.",{daemonBaseUrl:o});let c=g(t.flags?.daemonServerMode??process.env.AGENT_DEVICE_DAEMON_SERVER_MODE??("dual"===l?"dual":void 0));return{paths:y(r),transportPreference:d,serverMode:c,remoteBaseUrl:o,remoteAuthToken:n}}(t),n=function(e,t=process.env.AGENT_DEVICE_DAEMON_TIMEOUT_MS){if("test"!==e)return eA(t)}(t.command),i=await M("daemon_startup",async()=>await Z(o),{requestId:a,session:t.session}),s=await W(t,i),l={...t,positionals:s.positionals,flags:s.flags,token:i.token,meta:{...t.meta??{},requestId:a,debug:r,cwd:t.meta?.cwd,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,...s.uploadedArtifactId?{uploadedArtifactId:s.uploadedArtifactId}:{},...s.clientArtifactPaths?{clientArtifactPaths:s.clientArtifactPaths}:{},...s.installSource?{installSource:s.installSource}:{}}};return S({level:"info",phase:"daemon_request_prepare",data:{requestId:a,command:t.command,session:t.session}}),await M("daemon_request",async()=>await eu(i,l,o.transportPreference,n),{requestId:a,command:t.command})}async function W(e,t){let a,n=[...e.positionals??[]],i=e.flags?{...e.flags}:void 0,s=e.meta?.installSource,l={};if(ev(t)){let r=function(e,t){if("screenshot"===e.command){let a=X(e,"path",".png");return t[0]?{field:"path",localPath:a,positionalIndex:0,positionalPath:Y("screenshot",".png")}:{field:"path",localPath:a,positionalIndex:0,flagPath:Y("screenshot",".png")}}if("record"===e.command&&"start"===(t[0]??"").toLowerCase()){let t=X(e,"outPath",".mp4",1);return{field:"outPath",localPath:t,positionalIndex:1,positionalPath:Y("recording",o.extname(t)||".mp4")}}return null}(e,n);r&&(void 0!==r.positionalPath&&(n[r.positionalIndex]=r.positionalPath),void 0!==r.flagPath&&((i??={}).out=r.flagPath),l[r.field]=r.localPath);let d=await Q(e,t);d&&(s=d.installSource,a=d.uploadedArtifactId??a)}if(!ev(t)||"install"!==e.command&&"reinstall"!==e.command||n.length<2)return{positionals:n,flags:i,installSource:s,uploadedArtifactId:a,...Object.keys(l).length>0?{clientArtifactPaths:l}:{}};let d=n[1];if(d.startsWith("remote:"))return n[1]=d.slice(7),{positionals:n,flags:i,...Object.keys(l).length>0?{clientArtifactPaths:l}:{}};let c=o.isAbsolute(d)?d:o.resolve(e.meta?.cwd??process.cwd(),d);return r.existsSync(c)?{positionals:n,flags:i,installSource:s,uploadedArtifactId:a=await x({localPath:c,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform}),...Object.keys(l).length>0?{clientArtifactPaths:l}:{}}:{positionals:n,flags:i,...Object.keys(l).length>0?{clientArtifactPaths:l}:{}}}async function Q(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 x({localPath:i,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform});return{installSource:{...a,path:i},uploadedArtifactId:s}}function X(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 Y(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 Z(e){let t;if(e.remoteBaseUrl){let t={transport:"http",token:e.remoteAuthToken??"",pid:0,baseUrl:e.remoteBaseUrl};if(await el(t,"http"))return t;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."})}let a=er(e.paths.infoPath),r=w(),o=I((t=ec()).useSrc?t.srcPath:t.distPath,t.root),n=!!a&&await el(a,e.transportPreference);if(a&&a.version===r&&a.codeSignature===o&&n)return a;a&&(a.version!==r||a.codeSignature!==o||!n)&&(await ea(a),es(e.paths.infoPath)),function(e){let t=en(e);if(!t.hasLock||t.hasInfo)return;let a=eo(e.lockPath);if(!a)return es(e.lockPath);k(a.pid,a.processStartTime)||es(e.lockPath)}(e.paths);let i=0;for(let t=1;t<=V;t+=1){await ed(e);let a=await ee(H,e);if(a)return a;if(await et(e.paths)){i+=1;continue}let r=en(e.paths);if(!(t<V))break;if(!r.hasInfo&&!r.hasLock){await D(150);continue}}let s=en(e.paths);throw new u("COMMAND_FAILED","Failed to start daemon",{kind:"daemon_startup_failed",infoPath:e.paths.infoPath,lockPath:e.paths.lockPath,startupTimeoutMs:H,startupAttempts:V,lockRecoveryCount:i,metadataState:s,hint:function(e,t=y(process.env.AGENT_DEVICE_STATE_DIR)){return e.hasLock&&!e.hasInfo?`Detected ${t.lockPath} without ${t.infoPath}. If no agent-device daemon process is running, delete ${t.lockPath} and retry.`:e.hasLock&&e.hasInfo?`Daemon metadata may be stale. If no agent-device daemon process is running, delete ${t.infoPath} and ${t.lockPath}, then retry.`:`Daemon metadata is missing or stale. Delete ${t.infoPath} if present and retry.`}(s,e.paths)})}async function ee(e,t){let a=Date.now();for(;Date.now()-a<e;){let e=er(t.paths.infoPath);if(e&&await el(e,t.transportPreference))return e;await D(100)}return null}async function et(e){let t=en(e);if(!t.hasLock||t.hasInfo)return!1;let a=eo(e.lockPath);return a&&k(a.pid,a.processStartTime)&&await E(a.pid,{termTimeoutMs:3e3,killTimeoutMs:1e3,expectedStartTime:a.processStartTime}),es(e.lockPath),!0}async function ea(e){await E(e.pid,{termTimeoutMs:3e3,killTimeoutMs:1e3,expectedStartTime:e.processStartTime})}function er(e){let t=ei(e);if(!t||"object"!=typeof t)return null;let a="string"==typeof t.token&&t.token.length>0?t.token:null;if(!a)return null;let r=Number.isInteger(t.port)&&Number(t.port)>0,o=Number.isInteger(t.httpPort)&&Number(t.httpPort)>0;if(!r&&!o)return null;let n=t.transport,i="string"==typeof t.version?t.version:void 0,s="string"==typeof t.codeSignature?t.codeSignature:void 0,l="string"==typeof t.processStartTime?t.processStartTime:void 0,d=Number.isInteger(t.pid)&&Number(t.pid)>0;return{token:a,port:r?Number(t.port):void 0,httpPort:o?Number(t.httpPort):void 0,transport:"socket"===n||"http"===n||"dual"===n?n:void 0,pid:d?Number(t.pid):0,version:i,codeSignature:s,processStartTime:l}}function eo(e){let t=ei(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}K.addSubnet("127.0.0.0",8,"ipv4"),K.addAddress("::1","ipv6"),K.addSubnet("::ffff:127.0.0.0",104,"ipv6");function en(e){return{hasInfo:r.existsSync(e.infoPath),hasLock:r.existsSync(e.lockPath)}}function ei(e){if(!r.existsSync(e))return null;try{return JSON.parse(r.readFileSync(e,"utf8"))}catch{return null}}function es(e){try{r.existsSync(e)&&r.unlinkSync(e)}catch{}}async function el(r,o){var n;return"http"===ep(r,o)?await function(e){let r=e.baseUrl?eg(e.baseUrl,"health"):e.httpPort?`http://127.0.0.1:${e.httpPort}/health`:null;if(!r)return Promise.resolve(!1);let o=new URL(r),n="https:"===o.protocol?a:t,i=e.baseUrl?3e3:500;return new Promise(e=>{let t=n.request({protocol:o.protocol,host:o.hostname,port:o.port,path:o.pathname+o.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 ((n=r.port)?new Promise(t=>{let a=e.createConnection({host:"127.0.0.1",port:n},()=>{a.destroy(),t(!0)});a.on("error",()=>{t(!1)})}):Promise.resolve(!1))}async function ed(e){let t=ec(),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 ec(){let e=v(),t=[o.join(e,"dist","src","internal","daemon.js"),o.join(e,"dist","src","daemon.js")],a=t.find(e=>r.existsSync(e))??t[0],n=o.join(e,"src","daemon.ts"),i=t.some(e=>r.existsSync(e)),s=r.existsSync(n);if(!i&&!s)throw new u("COMMAND_FAILED","Daemon entry not found",{distPaths:t,srcPath:n});return{root:e,distPath:a,distPaths:t,srcPath:n,useSrc:process.execArgv.includes("--experimental-strip-types")?s:!i&&s}}async function eu(e,t,a,r){return"http"===ep(e,a)?await ew(e,t,r):await ey(e,t,r)}function ep(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(em(a,r))return r;throw new u("COMMAND_FAILED","http"===r?"Daemon HTTP endpoint is unavailable":"Daemon socket endpoint is unavailable")}let o=("socket"===e.transport||"dual"===e.transport?["socket","http"]:["http","socket"]).find(t=>em(e,t));if(o)return o;throw new u("COMMAND_FAILED","Daemon metadata has no reachable transport")}function em(e,t){return"http"===t?!!e.httpPort:!!e.port}function ef(e,t,a,r,o,n){let i=o?{terminated:0}:function(){let e=0;try{for(let t of G){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=o?{forcedKill:!1}:function(e,t){let a=!1;try{k(e.pid,e.processStartTime)&&(process.kill(e.pid,"SIGKILL"),a=!0)}catch{E(e.pid,{termTimeoutMs:3e3,killTimeoutMs:1e3,expectedStartTime:e.processStartTime})}finally{es(t.infoPath),es(t.lockPath)}return{forcedKill:a}}(e,t);return S({level:"error",phase:"daemon_request_timeout",data:{timeoutMs:n,requestId:a,command:r,timedOutRunnerPidsTerminated:i.terminated,timedOutRunnerCleanupError:i.error,daemonPidReset:o?void 0:e.pid,daemonPidForceKilled:o?void 0:s.forcedKill,daemonBaseUrl:e.baseUrl}}),new u("COMMAND_FAILED","Daemon request timed out",{timeoutMs:n,requestId:a,hint:o?"Retry with --debug and verify the remote daemon URL, auth token, and remote host logs.":"Retry with --debug and check daemon diagnostics logs. Timed-out iOS runner xcodebuild processes were terminated when detected."})}function eh(e,t,a){return S({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 ey(t,a,r){let o=t.port;if(!o)throw new u("COMMAND_FAILED","Daemon socket endpoint is unavailable");return new Promise((n,i)=>{let s=e.createConnection({host:"127.0.0.1",port:o},()=>{s.write(`${JSON.stringify(a)}
|
|
2
|
-
`)}),l=y(a.flags?.stateDir??process.env.AGENT_DEVICE_STATE_DIR),d="number"==typeof r?setTimeout(()=>{s.destroy(),i(ef(t,l,a.meta?.requestId,a.command,!1,r))},r):void 0,c="";s.setEncoding("utf8"),s.on("data",e=>{let t=(c+=e).indexOf("\n");if(-1===t)return;let r=c.slice(0,t).trim();if(r)try{let e=JSON.parse(r);s.end(),d&&clearTimeout(d),n(e)}catch(e){d&&clearTimeout(d),i(new u("COMMAND_FAILED","Invalid daemon response",{requestId:a.meta?.requestId,line:r},e instanceof Error?e:void 0))}}),s.on("error",e=>{d&&clearTimeout(d),i(eh(e,a.meta?.requestId,!1))})})}async function ew(e,r,o){var n,i,s;let l,d=e.baseUrl?new URL(eg(e.baseUrl,"rpc")):e.httpPort?new URL(`http://127.0.0.1:${e.httpPort}/rpc`):null;if(!d)throw new u("COMMAND_FAILED","Daemon HTTP endpoint is unavailable");let p=JSON.stringify((n=r,i={includeTokenParam:!e.baseUrl},l=n.meta?.requestId??_(),"lease_allocate"!==(s=n.command)&&"lease_heartbeat"!==s&&"lease_release"!==s?{jsonrpc:"2.0",id:l,method:"agent_device.command",params:n}:{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"}}(n.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}}}(n,n.command,i)})),m={"content-type":"application/json","content-length":Buffer.byteLength(p)};return e.baseUrl&&e.token&&(m.authorization=`Bearer ${e.token}`,m["x-agent-device-token"]=e.token),await new Promise((n,i)=>{let s=y(r.flags?.stateDir??process.env.AGENT_DEVICE_STATE_DIR),l=("https:"===d.protocol?a:t).request({protocol:d.protocol,host:d.hostname,port:d.port,method:"POST",path:d.pathname+d.search,headers:m},t=>{let a="";t.setEncoding("utf8"),t.on("data",e=>{a+=e}),t.on("end",()=>{h&&clearTimeout(h);try{let t=JSON.parse(a);if(t.error){let e=t.error.data??{};i(new u(c(null!=e.code?String(e.code):void 0,"COMMAND_FAILED"),String(e.message??t.error.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:r.meta?.requestId}));return}if(!t.result||"object"!=typeof t.result)return void i(new u("COMMAND_FAILED","Invalid daemon RPC response",{requestId:r.meta?.requestId}));if(e.baseUrl&&t.result.ok)return void eI(e,r,t.result).then(n).catch(i);n(t.result)}catch(e){h&&clearTimeout(h),i(new u("COMMAND_FAILED","Invalid daemon response",{requestId:r.meta?.requestId,line:a},e instanceof Error?e:void 0))}})}),f=ev(e),h="number"==typeof o?setTimeout(()=>{l.destroy(),i(ef(e,s,r.meta?.requestId,r.command,f,o))},o):void 0;l.on("error",e=>{h&&clearTimeout(h),i(eh(e,r.meta?.requestId,f))}),l.write(p),l.end()})}function ev(e){return"string"==typeof e.baseUrl&&e.baseUrl.length>0}function eg(e,t){return new URL(t,e.endsWith("/")?e:`${e}/`).toString()}async function eI(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=e.fileName?.trim()||`${e.field}-${Date.now()}`;return o.resolve(t.meta?.cwd??process.cwd(),a)}(a,t);await eb({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 eb(e){var i,s;let l,d=new URL((i=e.baseUrl,s=e.artifactId,l=i.endsWith("/")?i:`${i}/`,new URL(`artifacts/${encodeURIComponent(s)}`,l).toString())),c="https:"===d.protocol?a:t;await r.promises.mkdir(o.dirname(e.destinationPath),{recursive:!0}),await new Promise((t,a)=>{let o=!1,i=e.timeoutMs??$,s=n=>{if(!o){if(o=!0,clearTimeout(p),n)return void r.promises.rm(e.destinationPath,{force:!0}).finally(()=>a(n));t()}},l=c.request({protocol:d.protocol,host:d.hostname,port:d.port,method:"GET",path:d.pathname+d.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}))}),n(t,r.createWriteStream(e.destinationPath)).then(()=>s(),e=>s(e instanceof Error?e:Error(String(e))))}),p=setTimeout(()=>{l.destroy(new u("COMMAND_FAILED","Remote artifact download timed out",{artifactId:e.artifactId,requestId:e.requestId,timeoutMs:i}))},i);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:i},t instanceof Error?t:void 0))}),l.end()})}function eA(e=process.env.AGENT_DEVICE_DAEMON_TIMEOUT_MS){if(!e)return 9e4;let t=Number(e);return Number.isFinite(t)?Math.max(1e3,Math.floor(t)):9e4}let e_={alert:"alert",appState:"appstate",appSwitcher:"app-switcher",apps:"apps",back:"back",batch:"batch",boot:"boot",click:"click",clipboard:"clipboard",devices:"devices",diff:"diff",fill:"fill",find:"find",focus:"focus",get:"get",home:"home",is:"is",keyboard:"keyboard",logs:"logs",longPress:"longpress",network:"network",perf:"perf",pinch:"pinch",press:"press",push:"push",record:"record",replay:"replay",rotate:"rotate",scroll:"scroll",screenshot:"screenshot",settings:"settings",snapshot:"snapshot",swipe:"swipe",test:"test",trace:"trace",triggerAppEvent:"trigger-app-event",type:"type",wait:"wait"};function eM(e,t,a,r){let o=a(e[t]);if(void 0===o)throw new u("COMMAND_FAILED",r,{response:e});return o}function eS(e,t){return eM(e,t,eN,`Daemon response is missing "${t}".`)}function ek(e,t){return eN(e[t])}function eE(e,t){var a;let r;return a=eN,null===(r=e[t])?null:a(r)}function eD(e,t){return eM(e,t,ex,`Daemon response has invalid "${t}".`)}function eP(e,t){return function(e){return"tv"===e||"mobile"===e||"desktop"===e?e:void 0}(e[t])??"mobile"}function eT(e,t){let a=e[t];if(!eO(a))return;let r="number"==typeof a.x?a.x:void 0,o="number"==typeof a.y?a.y:void 0,n="number"==typeof a.width?a.width:void 0,i="number"==typeof a.height?a.height:void 0;if(void 0!==r&&void 0!==o&&void 0!==n&&void 0!==i)return{x:r,y:o,width:n,height:i}}function eN(e){return"string"==typeof e&&e.length>0?e:void 0}function eU(e){return"number"==typeof e&&Number.isFinite(e)?e:void 0}function ex(e){return"ios"===e||"macos"===e||"android"===e?e:void 0}function eC(e){return"simulator"===e||"emulator"===e||"device"===e?e:void 0}function eR(e){if(!eO(e))throw new u("COMMAND_FAILED","Daemon returned an unexpected response shape.",{value:e});return e}function eO(e){return"object"==typeof e&&null!==e}function eL(e){let t={};for(let[a,r]of Object.entries(e))void 0!==r&&(t[a]=r);return t}function eF(e,t){let a=ek(e,"bundleId"),r=ek(e,"package");return{app:eS(e,"app"),appPath:eS(e,"appPath"),platform:eD(e,"platform"),appId:a??r,bundleId:a,package:r,identifiers:A({session:t,bundleId:a,packageName:r})}}function eB(e){let t=eR(e),a=eD(t,"platform"),r=eS(t,"id"),o=eS(t,"name");return{platform:a,target:eP(t,"target"),kind:eM(t,"kind",eC,'Daemon response has invalid "kind".'),id:r,name:o,booted:"boolean"==typeof t.booted?t.booted:void 0,identifiers:h(a,r,o),ios:"ios"===a?{udid:r}:void 0,android:"android"===a?{serial:r}:void 0}}function eq(e){let t=eR(e),a=eD(t,"platform"),r=eS(t,"id"),o=eS(t,"name"),n=eP(t,"target"),i=eS(t,"device"),s={session:o,...h(a,r,i)};return{name:o,createdAt:eM(t,"createdAt",eU,'Daemon response is missing numeric "createdAt".'),device:{platform:a,target:n,id:r,name:i,identifiers:s,ios:"ios"===a?{udid:r,simulatorSetPath:eE(t,"ios_simulator_device_set")}:void 0,android:"android"===a?{serial:r}:void 0},identifiers:s}}function ej(e){return e??"default"}function ez(e={},t={}){var a;let r,o=t.transport??J,n=async(t,a=[],r={})=>{var n,i;let s=(n=e,i=r,{...n,...i}),l=await o({session:ej(s.session),command:t,positionals:a,flags:eL({stateDir:s.stateDir,daemonBaseUrl:s.daemonBaseUrl,daemonAuthToken:s.daemonAuthToken,daemonTransport:s.daemonTransport,daemonServerMode:s.daemonServerMode,tenant:s.tenant,sessionIsolation:s.sessionIsolation,runId:s.runId,leaseId:s.leaseId,leaseBackend:s.leaseBackend,platform:s.platform,target:s.target,device:s.device,udid:s.udid,serial:s.serial,iosSimulatorDeviceSet:s.iosSimulatorDeviceSet,androidDeviceAllowlist:s.androidDeviceAllowlist,runtime:s.simulatorRuntimeId,boot:s.boot,reuseExisting:s.reuseExisting,surface:s.surface,activity:s.activity,relaunch:s.relaunch,shutdown:s.shutdown,saveScript:s.saveScript,noRecord:s.noRecord,backMode:s.backMode,metroHost:s.metroHost,metroPort:s.metroPort,bundleUrl:s.bundleUrl,launchUrl:s.launchUrl,snapshotInteractiveOnly:s.interactiveOnly,snapshotCompact:s.compact,snapshotDepth:s.depth,snapshotScope:s.scope,snapshotRaw:s.raw,screenshotFullscreen:s.screenshotFullscreen,screenshotMaxSize:s.screenshotMaxSize,overlayRefs:s.overlayRefs,appsFilter:s.appsFilter,out:s.out,count:s.count,fps:s.fps,quality:s.quality,hideTouches:s.hideTouches,intervalMs:s.intervalMs,delayMs:s.delayMs,holdMs:s.holdMs,jitterPx:s.jitterPx,pixels:s.pixels,doubleTap:s.doubleTap,clickButton:s.clickButton,pauseMs:s.pauseMs,pattern:s.pattern,headless:s.headless,restart:s.restart,replayUpdate:s.replayUpdate,replayEnv:s.replayEnv,replayShellEnv:s.replayShellEnv,failFast:s.failFast,timeoutMs:s.timeoutMs,retries:s.retries,artifactsDir:s.artifactsDir,reportJunit:s.reportJunit,findFirst:s.findFirst,findLast:s.findLast,networkInclude:s.networkInclude,batchOnError:s.batchOnError,batchMaxSteps:s.batchMaxSteps,batchSteps:s.batchSteps,verbose:s.debug}),runtime:s.runtime,meta:eL({requestId:s.requestId,cwd:s.cwd,debug:s.debug,lockPolicy:s.lockPolicy,lockPlatform:s.lockPlatform,tenantId:s.tenant,runId:s.runId,leaseId:s.leaseId,leaseBackend:s.leaseBackend,leaseTtlMs:s.leaseTtlMs,sessionIsolation:s.sessionIsolation,installSource:s.installSource,retainMaterializedPaths:s.retainMaterializedPaths,materializedPathRetentionMs:s.materializedPathRetentionMs,materializationId:s.materializationId})});return l.ok||function(e){throw new u(c(e.code),e.message,{...e.details??{},hint:e.hint,diagnosticId:e.diagnosticId,logPath:e.logPath})}(l.error),l.data??{}},i=async(e={})=>{let t=await n("session_list",[],e);return(Array.isArray(t.sessions)?t.sessions:[]).map(eq)},s=async(e,t=[],a={})=>await n(e,t,a),l=(t={})=>{var a,r;return ej((a=e,r=t,{...a,...r}).session)};return{command:(a=async e=>await n(e.command,e.positionals,e.options),r=async e=>await a(e),{wait:async e=>await r(function(e){if(1!==[void 0!==e.durationMs?"durationMs":void 0,void 0!==e.text?"text":void 0,void 0!==e.ref?"ref":void 0,void 0!==e.selector?"selector":void 0].filter(Boolean).length)throw new u("INVALID_ARGS","wait command requires exactly one of durationMs, text, ref, or selector.");if(void 0!==e.durationMs)return{command:e_.wait,positionals:[String(e.durationMs)],options:e};let t=void 0!==e.timeoutMs?[String(e.timeoutMs)]:[];if(void 0!==e.text)return{command:e_.wait,positionals:["text",e.text,...t],options:e};if(void 0!==e.ref)return{command:e_.wait,positionals:[e.ref,...t],options:e};let a=e.selector;return function(e){if(!P(e))throw new u("INVALID_ARGS",`Invalid wait selector: ${e}`)}(a),{command:e_.wait,positionals:[a,...t],options:e}}(e)),alert:async(e={})=>{var t;let a;return await r((a=(t=e).action??"get",{command:e_.alert,positionals:[a,...void 0!==t.timeoutMs?[String(t.timeoutMs)]:[]],options:t}))},appState:async(e={})=>await r({command:e_.appState,positionals:[],options:e}),back:async(e={})=>await r({command:e_.back,positionals:[],options:{...e,backMode:e.mode}}),home:async(e={})=>await r({command:e_.home,positionals:[],options:e}),rotate:async e=>await r({command:e_.rotate,positionals:[e.orientation],options:e}),appSwitcher:async(e={})=>await r({command:e_.appSwitcher,positionals:[],options:e}),keyboard:async(e={})=>await r({command:e_.keyboard,positionals:e.action?[e.action]:[],options:e}),clipboard:async e=>{var t;return await r("read"===(t=e).action?{command:e_.clipboard,positionals:["read"],options:t}:{command:e_.clipboard,positionals:["write",t.text],options:t})}}),devices:{list:async(e={})=>{let t=await n(e_.devices,[],e);return(Array.isArray(t.devices)?t.devices:[]).map(eB)},boot:async(e={})=>await s(e_.boot,[],e)},sessions:{list:async(e={})=>await i(e),close:async(e={})=>{let t=l(e),a=(await n("close",[],e)).shutdown;return{session:t,shutdown:"object"==typeof a&&null!==a?a:void 0,identifiers:{session:t}}}},simulators:{ensure:async e=>{let{runtime:t,...a}=e,r=await n("ensure-simulator",[],{...a,simulatorRuntimeId:t}),o=eS(r,"udid"),i=eS(r,"device");return{udid:o,device:i,runtime:eS(r,"runtime"),created:!0===r.created,booted:!0===r.booted,iosSimulatorDeviceSet:eE(r,"ios_simulator_device_set"),identifiers:{deviceId:o,deviceName:i,udid:o}}}},apps:{install:async e=>eF(await n("install",[e.app,e.appPath],e),l(e)),reinstall:async e=>eF(await n("reinstall",[e.app,e.appPath],e),l(e)),installFromSource:async e=>(function(e,t){let a=ek(e,"bundleId"),r=ek(e,"packageName"),o=a??r??ek(e,"appId"),n=ek(e,"launchTarget")??r??a??o;if(!n)throw new u("COMMAND_FAILED",'Daemon response is missing "launchTarget".',{response:e});return{appName:ek(e,"appName"),appId:o,bundleId:a,packageName:r,launchTarget:n,installablePath:ek(e,"installablePath"),archivePath:ek(e,"archivePath"),materializationId:ek(e,"materializationId"),materializationExpiresAt:ek(e,"materializationExpiresAt"),identifiers:A({session:t,bundleId:a,packageName:r,appId:o})}})(await n("install_source",[],{...e,installSource:e.source,retainMaterializedPaths:e.retainPaths,materializedPathRetentionMs:e.retentionMs}),l(e)),list:async(e={})=>{let t=await n(e_.apps,[],e);return Array.isArray(t.apps)?t.apps.filter(e=>"string"==typeof e):[]},open:async e=>{let t=l(e),a=e.app?e.url?[e.app,e.url]:[e.app]:[],r=await n("open",a,e),o=function(e){let t=e.platform,a=ek(e,"id"),r=ek(e,"device");if("ios"!==t&&"macos"!==t&&"android"!==t||!a||!r)return;let o=eP(e,"target"),n=h(t,a,r);return{platform:t,target:o,id:a,name:r,identifiers:n,ios:"ios"===t?{udid:ek(e,"device_udid")??a,simulatorSetPath:eE(e,"ios_simulator_device_set")}:void 0,android:"android"===t?{serial:ek(e,"serial")??a}:void 0}}(r),i=ek(r,"appBundleId");return{session:t,appName:ek(r,"appName"),appBundleId:i,appId:i,startup:function(e){if(eO(e)&&"number"==typeof e.durationMs&&"string"==typeof e.measuredAt&&"string"==typeof e.method)return{durationMs:e.durationMs,measuredAt:e.measuredAt,method:e.method,appTarget:ek(e,"appTarget"),appBundleId:ek(e,"appBundleId")}}(r.startup),runtime:function(e){if(!eO(e))return;let t=e.platform,a=ek(e,"metroHost"),r="number"==typeof e.metroPort?e.metroPort:void 0;return{platform:"ios"===t||"android"===t?t:void 0,metroHost:a,metroPort:r,bundleUrl:ek(e,"bundleUrl"),launchUrl:ek(e,"launchUrl")}}(r.runtime),device:o,identifiers:{session:t,deviceId:o?.id,deviceName:o?.name,udid:o?.ios?.udid,serial:o?.android?.serial,appId:i,appBundleId:i}}},close:async(e={})=>{let t=l(e),a=(await n("close",e.app?[e.app]:[],e)).shutdown;return{session:t,closedApp:e.app,shutdown:"object"==typeof a&&null!==a?a:void 0,identifiers:{session:t}}},push:async e=>{var t;return await s(e_.push,[e.app,"string"==typeof(t=e.payload)?t:JSON.stringify(t)],e)},triggerEvent:async e=>{var t;return await s(e_.triggerAppEvent,[(t=e).event,...t.payload?[JSON.stringify(t.payload)]:[]],e)}},materializations:{release:async e=>{var t;return{released:!0===(t=await n("release_materialized_paths",[],{...e,materializationId:e.materializationId})).released,materializationId:eS(t,"materializationId"),identifiers:{}}}},leases:{allocate:async e=>eK(await n("lease_allocate",[],{...e,leaseId:void 0,leaseTtlMs:e.ttlMs})),heartbeat:async e=>eK(await n("lease_heartbeat",[],{...e,leaseTtlMs:e.ttlMs})),release:async e=>({released:!0===(await n("lease_release",[],e)).released})},metro:{prepare:async t=>await N({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 T({metroHost:t.metroHost,metroPort:t.metroPort,bundleUrl:t.bundleUrl,runtime:e.runtime,timeoutMs:t.timeoutMs})},capture:{snapshot:async(e={})=>{var t;let a=l(e),r=await n(e_.snapshot,[],e),o=ek(r,"appBundleId"),i="object"==typeof r.visibility&&null!==r.visibility?r.visibility:void 0,s="object"==typeof r.androidSnapshot&&null!==r.androidSnapshot?r.androidSnapshot:void 0;return{nodes:Array.isArray(t=r.nodes)?t:[],truncated:!0===r.truncated,appName:ek(r,"appName"),appBundleId:o,...i?{visibility:i}:{},...s?{androidSnapshot:s}:{},warnings:Array.isArray(r.warnings)?r.warnings.filter(e=>"string"==typeof e):void 0,identifiers:{session:a,appId:o,appBundleId:o}}},screenshot:async(e={})=>{let t=l(e),a=await n(e_.screenshot,e.path?[e.path]:[],{...e,screenshotFullscreen:e.fullscreen,screenshotMaxSize:e.maxSize});return{path:eS(a,"path"),overlayRefs:function(e){let t=e.overlayRefs;if(!Array.isArray(t))return;let a=[];for(let e of t){if(!eO(e))continue;let t=ek(e,"ref"),r=eT(e,"rect"),o=eT(e,"overlayRect"),n=function(e,t){let a=e[t];if(!eO(a))return;let r="number"==typeof a.x?a.x:void 0,o="number"==typeof a.y?a.y:void 0;if(void 0!==r&&void 0!==o)return{x:r,y:o}}(e,"center");t&&r&&o&&n&&a.push({ref:t,label:ek(e,"label"),rect:r,overlayRect:o,center:n})}return a}(a),identifiers:{session:t}}},diff:async e=>await s(e_.diff,[e.kind],{...e,interactiveOnly:e.interactiveOnly,compact:e.compact,depth:e.depth,scope:e.scope,raw:e.raw})},interactions:{click:async e=>await s(e_.click,e$(e),{...e,clickButton:e.button}),press:async e=>await s(e_.press,e$(e),e),longPress:async e=>await s(e_.longPress,[String(e.x),String(e.y),...eV(e.durationMs)],e),swipe:async e=>await s(e_.swipe,[String(e.from.x),String(e.from.y),String(e.to.x),String(e.to.y),...eV(e.durationMs)],e),focus:async e=>await s(e_.focus,[String(e.x),String(e.y)],e),type:async e=>await s(e_.type,[e.text],e),fill:async e=>await s(e_.fill,[...e$(e),e.text],e),scroll:async e=>await s(e_.scroll,[e.direction,...eV(e.amount)],e),pinch:async e=>await s(e_.pinch,[String(e.scale),...eV(e.x),...eV(e.y)],e),get:async e=>{var t;return await s(e_.get,[e.format,...void 0!==(t=e).ref?[t.ref,...eH(t.label)]:[t.selector]],e)},is:async e=>await s(e_.is,[e.predicate,e.selector,..."text"===e.predicate?[e.value]:[]],e),find:async e=>await s(e_.find,function(e){let t=e.locator&&"any"!==e.locator?[e.locator,e.query]:[e.query];switch(e.action){case void 0:case"click":case"focus":case"exists":return e.action?[...t,e.action]:t;case"getText":return[...t,"get","text"];case"getAttrs":return[...t,"get","attrs"];case"wait":return[...t,"wait",...eV(e.timeoutMs)];case"fill":case"type":return[...t,e.action,e.value]}}(e),{...e,findFirst:e.first,findLast:e.last})},replay:{run:async e=>await s(e_.replay,[e.path],{...e,replayUpdate:e.update,replayEnv:e.env,replayShellEnv:eG(process.env)}),test:async e=>await s(e_.test,e.paths,{...e,replayUpdate:e.update,replayEnv:e.env,replayShellEnv:eG(process.env)})},batch:{run:async e=>await s(e_.batch,[],{...e,batchSteps:e.steps,batchOnError:e.onError,batchMaxSteps:e.maxSteps})},observability:{perf:async(e={})=>await s(e_.perf,[],e),logs:async(e={})=>{var t;return await s(e_.logs,[(t=e).action??"path",...eH(t.message)],e)},network:async(e={})=>{var t;return await s(e_.network,[...(t=e).action?[t.action]:[],...eV(t.limit)],{...e,networkInclude:e.include})}},recording:{record:async e=>await s(e_.record,[e.action,...eH(e.path)],e),trace:async e=>await s(e_.trace,[e.action,...eH(e.path)],e)},settings:{update:async e=>await s(e_.settings,[e.setting,e.state,..."permission"in e?[e.permission]:[],..."mode"in e&&e.mode?[e.mode]:[]],e)}}}function e$(e){return void 0!==e.ref?[e.ref,...eH(e.label)]:void 0!==e.selector?[e.selector]:[String(e.x),String(e.y)]}function eH(e){return void 0===e?[]:[e]}function eV(e){return void 0===e?[]:[String(e)]}function eG(e){let t={};for(let[a,r]of Object.entries(e))"string"==typeof r&&a.startsWith("AD_VAR_")&&(t[a]=r);return t}function eK(e){let t=e.lease;if(!t||"object"!=typeof t||Array.isArray(t))throw Error("Invalid lease response from daemon");return{leaseId:eS(t,"leaseId"),tenantId:eS(t,"tenantId"),runId:eS(t,"runId"),backend:eS(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{e_ as CLIENT_COMMANDS,ez as createAgentDeviceClient,J as sendToDaemon};
|
|
1
|
+
import e from"node:net";import t from"node:http";import a from"node:https";import r from"node:fs";import o from"node:path";import{pipeline as n}from"node:stream/promises";import i from"node:os";import{createHash as s,randomUUID as l}from"node:crypto";import{Writable as d}from"node:stream";import{toAppErrorCode as c,AppError as u}from"./9152.js";import{runCmdSync as p,runCmd as m,runCmdDetached as f}from"./9818.js";import{readVersion as h,findProjectRoot as y}from"./9671.js";import{createRequestId as w,withDiagnosticTimer as v,emitDiagnostic as g}from"./7599.js";import{isAgentDeviceDaemonProcess as I,stopProcessForTakeover as b}from"./8656.js";import{buildAppIdentifiers as A,resolveDaemonServerMode as _,computeDaemonCodeSignature as S,resolveDaemonTransportPreference as M,buildDeviceIdentifiers as k,resolveDaemonPaths as E}from"./180.js";import{sleep as D}from"./4829.js";import{tryParseSelectorChain as P}from"./940.js";import{reloadMetro as T,prepareMetroRuntime as N}from"./1974.js";let U="sha256";async function x(e){let t=await C(e.localPath,e.platform),a=e.baseUrl.endsWith("/")?e.baseUrl:`${e.baseUrl}/`;try{let r=await F({normalizedBase:a,token:e.token,artifact:t});if(r?.kind==="cache-hit")return r.uploadId;if(r?.kind==="direct-upload")try{return await B(t.payloadPath,r),await j({normalizedBase:a,token:e.token,uploadId:r.uploadId})}catch{}return await L({normalizedBase:a,token:e.token,artifact:t})}finally{t.cleanup()}}async function C(e,t){var a,n,i;let s,l=r.statSync(e),d=o.basename(e),c=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=c?await R(e,p):e,a=r.statSync(t);return{payloadPath:t,fileName:d,artifactType:c?"app-bundle":"file",platform:u,contentType:c?"application/gzip":"application/octet-stream",sha256:await z(t),sizeBytes:a.size,cleanup:()=>O(p)}}catch(e){throw O(p),e}}async function R(e,t){let a=r.mkdtempSync(o.join(i.tmpdir(),`agent-device-upload-${l()}-`));t.push(a);let n=o.join(a,`${o.basename(e)}.tar.gz`);return await m("tar",["czf",n,"-C",o.dirname(e),o.basename(e)],{env:{...process.env,COPYFILE_DISABLE:"1"}}),n}function O(e){for(let t of e)r.rmSync(t,{recursive:!0,force:!0})}async function L(e){let{normalizedBase:t,token:a,artifact:r}=e,o=new URL("upload",t),n={"content-type":r.contentType,"x-artifact-type":r.artifactType,"x-artifact-filename":r.fileName,"x-artifact-hash":r.sha256,"x-artifact-hash-algorithm":U,"transfer-encoding":"chunked"};a&&(n.authorization=`Bearer ${a}`,n["x-agent-device-token"]=a);let i=await q({url:o,method:"POST",headers:n,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 F(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 B(e,t){let a=await q({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 q(e){let o="https:"===e.url.protocol?a:t;return await new Promise((t,a)=>{let i=o.request({protocol:e.url.protocol,host:e.url.hostname,port:e.url.port,method:e.method,path:e.url.pathname+e.url.search,headers:e.headers},e=>{let a="";e.setEncoding("utf8"),e.on("data",e=>{a+=e}),e.on("end",()=>{clearTimeout(s),t({statusCode:e.statusCode??500,statusMessage:e.statusMessage,body:a})})}),s=setTimeout(()=>{i.destroy(),a(new u("COMMAND_FAILED",e.timeoutMessage,{timeoutMs:3e5,...e.timeoutHint?{hint:e.timeoutHint}:{}}))},3e5);i.on("error",t=>{clearTimeout(s),a(new u("COMMAND_FAILED",e.errorMessage,e.errorHint?{hint:e.errorHint}:{},t))}),i.on("close",()=>clearTimeout(s)),n(r.createReadStream(e.payloadPath),i).catch(e=>{i.destroy(),a(new u("COMMAND_FAILED","Failed to read local artifact",{},e instanceof Error?e:Error(String(e))))})})}async function j(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 o=await r.json().catch(()=>void 0);if(!o?.ok||!o.uploadId)throw new u("COMMAND_FAILED","Invalid upload finalize response");return o.uploadId}async function z(e){let t=s(U),a=new d({write(e,a,r){t.update(e),r()}});return await n(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")}let $=eA(),H=function(e=process.env.AGENT_DEVICE_DAEMON_STARTUP_TIMEOUT_MS){if(!e)return 15e3;let t=Number(e);return Number.isFinite(t)?Math.max(1e3,Math.floor(t)):15e3}(),K=function(e=process.env.AGENT_DEVICE_DAEMON_STARTUP_ATTEMPTS){if(!e)return 2;let t=Number(e);return Number.isFinite(t)?Math.min(5,Math.max(1,Math.floor(t))):2}(),V=["xcodebuild .*AgentDeviceRunnerUITests/RunnerTests/testCommand","xcodebuild .*AgentDeviceRunner\\.env\\.session-","xcodebuild build-for-testing .*ios-runner/AgentDeviceRunner/AgentDeviceRunner\\.xcodeproj"],G=new e.BlockList;async function J(t){let a=t.meta?.requestId??w(),r=!!(t.meta?.debug||t.flags?.verbose),o=function(t){let a,r=t.flags?.stateDir??process.env.AGENT_DEVICE_STATE_DIR,o=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(/\/+$/,"")}}(t.flags?.daemonBaseUrl??process.env.AGENT_DEVICE_DAEMON_BASE_URL),n=t.flags?.daemonAuthToken??process.env.AGENT_DEVICE_DAEMON_AUTH_TOKEN;var i=o,s=n;if(!(!i||"localhost"===(a=new URL(i).hostname.trim().toLowerCase().replace(/^\[(.*)\]$/,"$1"))||(e.isIPv4(a)?G.check(a,"ipv4"):!!e.isIPv6(a)&&G.check(a,"ipv6")))&&("string"!=typeof s||!(s.trim().length>0)))throw new u("INVALID_ARGS","Remote daemon base URL for non-loopback hosts requires daemon authentication",{daemonBaseUrl:i,hint:"Provide --daemon-auth-token or AGENT_DEVICE_DAEMON_AUTH_TOKEN when using a non-loopback remote daemon URL."});let l=t.flags?.daemonTransport??process.env.AGENT_DEVICE_DAEMON_TRANSPORT,d=M(l);if(o&&"socket"===d)throw new u("INVALID_ARGS","Remote daemon base URL only supports HTTP transport. Remove --daemon-transport socket.",{daemonBaseUrl:o});let c=_(t.flags?.daemonServerMode??process.env.AGENT_DEVICE_DAEMON_SERVER_MODE??("dual"===l?"dual":void 0));return{paths:E(r),transportPreference:d,serverMode:c,remoteBaseUrl:o,remoteAuthToken:n}}(t),n=function(e,t=process.env.AGENT_DEVICE_DAEMON_TIMEOUT_MS){if("test"!==e)return eA(t)}(t.command),i=await v("daemon_startup",async()=>await Z(o),{requestId:a,session:t.session}),s=await W(t,i),l={...t,positionals:s.positionals,flags:s.flags,token:i.token,meta:{...t.meta??{},requestId:a,debug:r,cwd:t.meta?.cwd,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,...s.uploadedArtifactId?{uploadedArtifactId:s.uploadedArtifactId}:{},...s.clientArtifactPaths?{clientArtifactPaths:s.clientArtifactPaths}:{},...s.installSource?{installSource:s.installSource}:{}}};return g({level:"info",phase:"daemon_request_prepare",data:{requestId:a,command:t.command,session:t.session}}),await v("daemon_request",async()=>await eu(i,l,o.transportPreference,n),{requestId:a,command:t.command})}async function W(e,t){let a,n=[...e.positionals??[]],i=e.flags?{...e.flags}:void 0,s=e.meta?.installSource,l={};if(ev(t)){let r=function(e,t){if("screenshot"===e.command){let a=Q(e,"path",".png");return t[0]?{field:"path",localPath:a,positionalIndex:0,positionalPath:X("screenshot",".png")}:{field:"path",localPath:a,positionalIndex:0,flagPath:X("screenshot",".png")}}if("record"===e.command&&"start"===(t[0]??"").toLowerCase()){let t=Q(e,"outPath",".mp4",1);return{field:"outPath",localPath:t,positionalIndex:1,positionalPath:X("recording",o.extname(t)||".mp4")}}return null}(e,n);r&&(void 0!==r.positionalPath&&(n[r.positionalIndex]=r.positionalPath),void 0!==r.flagPath&&((i??={}).out=r.flagPath),l[r.field]=r.localPath);let d=await Y(e,t);d&&(s=d.installSource,a=d.uploadedArtifactId??a)}if(!ev(t)||"install"!==e.command&&"reinstall"!==e.command||n.length<2)return{positionals:n,flags:i,installSource:s,uploadedArtifactId:a,...Object.keys(l).length>0?{clientArtifactPaths:l}:{}};let d=n[1];if(d.startsWith("remote:"))return n[1]=d.slice(7),{positionals:n,flags:i,...Object.keys(l).length>0?{clientArtifactPaths:l}:{}};let c=o.isAbsolute(d)?d:o.resolve(e.meta?.cwd??process.cwd(),d);return r.existsSync(c)?{positionals:n,flags:i,installSource:s,uploadedArtifactId:a=await x({localPath:c,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform}),...Object.keys(l).length>0?{clientArtifactPaths:l}:{}}:{positionals:n,flags:i,...Object.keys(l).length>0?{clientArtifactPaths:l}:{}}}async function Y(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 x({localPath:i,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform});return{installSource:{...a,path:i},uploadedArtifactId:s}}function Q(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 X(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 Z(e){let t;if(e.remoteBaseUrl){let t={transport:"http",token:e.remoteAuthToken??"",pid:0,baseUrl:e.remoteBaseUrl};if(await el(t,"http"))return t;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."})}let a=er(e.paths.infoPath),r=h(),o=S((t=ec()).useSrc?t.srcPath:t.distPath,t.root),n=!!a&&await el(a,e.transportPreference);if(a&&a.version===r&&a.codeSignature===o&&n)return a;a&&(a.version!==r||a.codeSignature!==o||!n)&&(await ea(a),es(e.paths.infoPath)),function(e){let t=en(e);if(!t.hasLock||t.hasInfo)return;let a=eo(e.lockPath);if(!a)return es(e.lockPath);I(a.pid,a.processStartTime)||es(e.lockPath)}(e.paths);let i=0;for(let t=1;t<=K;t+=1){await ed(e);let a=await ee(H,e);if(a)return a;if(await et(e.paths)){i+=1;continue}let r=en(e.paths);if(!(t<K))break;if(!r.hasInfo&&!r.hasLock){await D(150);continue}}let s=en(e.paths);throw new u("COMMAND_FAILED","Failed to start daemon",{kind:"daemon_startup_failed",infoPath:e.paths.infoPath,lockPath:e.paths.lockPath,startupTimeoutMs:H,startupAttempts:K,lockRecoveryCount:i,metadataState:s,hint:function(e,t=E(process.env.AGENT_DEVICE_STATE_DIR)){return e.hasLock&&!e.hasInfo?`Detected ${t.lockPath} without ${t.infoPath}. If no agent-device daemon process is running, delete ${t.lockPath} and retry.`:e.hasLock&&e.hasInfo?`Daemon metadata may be stale. If no agent-device daemon process is running, delete ${t.infoPath} and ${t.lockPath}, then retry.`:`Daemon metadata is missing or stale. Delete ${t.infoPath} if present and retry.`}(s,e.paths)})}async function ee(e,t){let a=Date.now();for(;Date.now()-a<e;){let e=er(t.paths.infoPath);if(e&&await el(e,t.transportPreference))return e;await D(100)}return null}async function et(e){let t=en(e);if(!t.hasLock||t.hasInfo)return!1;let a=eo(e.lockPath);return a&&I(a.pid,a.processStartTime)&&await b(a.pid,{termTimeoutMs:3e3,killTimeoutMs:1e3,expectedStartTime:a.processStartTime}),es(e.lockPath),!0}async function ea(e){await b(e.pid,{termTimeoutMs:3e3,killTimeoutMs:1e3,expectedStartTime:e.processStartTime})}function er(e){let t=ei(e);if(!t||"object"!=typeof t)return null;let a="string"==typeof t.token&&t.token.length>0?t.token:null;if(!a)return null;let r=Number.isInteger(t.port)&&Number(t.port)>0,o=Number.isInteger(t.httpPort)&&Number(t.httpPort)>0;if(!r&&!o)return null;let n=t.transport,i="string"==typeof t.version?t.version:void 0,s="string"==typeof t.codeSignature?t.codeSignature:void 0,l="string"==typeof t.processStartTime?t.processStartTime:void 0,d=Number.isInteger(t.pid)&&Number(t.pid)>0;return{token:a,port:r?Number(t.port):void 0,httpPort:o?Number(t.httpPort):void 0,transport:"socket"===n||"http"===n||"dual"===n?n:void 0,pid:d?Number(t.pid):0,version:i,codeSignature:s,processStartTime:l}}function eo(e){let t=ei(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}G.addSubnet("127.0.0.0",8,"ipv4"),G.addAddress("::1","ipv6"),G.addSubnet("::ffff:127.0.0.0",104,"ipv6");function en(e){return{hasInfo:r.existsSync(e.infoPath),hasLock:r.existsSync(e.lockPath)}}function ei(e){if(!r.existsSync(e))return null;try{return JSON.parse(r.readFileSync(e,"utf8"))}catch{return null}}function es(e){try{r.existsSync(e)&&r.unlinkSync(e)}catch{}}async function el(r,o){var n;return"http"===ep(r,o)?await function(e){let r=e.baseUrl?eg(e.baseUrl,"health"):e.httpPort?`http://127.0.0.1:${e.httpPort}/health`:null;if(!r)return Promise.resolve(!1);let o=new URL(r),n="https:"===o.protocol?a:t,i=e.baseUrl?3e3:500;return new Promise(e=>{let t=n.request({protocol:o.protocol,host:o.hostname,port:o.port,path:o.pathname+o.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 ((n=r.port)?new Promise(t=>{let a=e.createConnection({host:"127.0.0.1",port:n},()=>{a.destroy(),t(!0)});a.on("error",()=>{t(!1)})}):Promise.resolve(!1))}async function ed(e){let t=ec(),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 ec(){let e=y(),t=[o.join(e,"dist","src","internal","daemon.js"),o.join(e,"dist","src","daemon.js")],a=t.find(e=>r.existsSync(e))??t[0],n=o.join(e,"src","daemon.ts"),i=t.some(e=>r.existsSync(e)),s=r.existsSync(n);if(!i&&!s)throw new u("COMMAND_FAILED","Daemon entry not found",{distPaths:t,srcPath:n});return{root:e,distPath:a,distPaths:t,srcPath:n,useSrc:process.execArgv.includes("--experimental-strip-types")?s:!i&&s}}async function eu(e,t,a,r){return"http"===ep(e,a)?await ew(e,t,r):await ey(e,t,r)}function ep(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(em(a,r))return r;throw new u("COMMAND_FAILED","http"===r?"Daemon HTTP endpoint is unavailable":"Daemon socket endpoint is unavailable")}let o=("socket"===e.transport||"dual"===e.transport?["socket","http"]:["http","socket"]).find(t=>em(e,t));if(o)return o;throw new u("COMMAND_FAILED","Daemon metadata has no reachable transport")}function em(e,t){return"http"===t?!!e.httpPort:!!e.port}function ef(e,t,a,r,o,n){let i=o?{terminated:0}:function(){let e=0;try{for(let t of V){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=o?{forcedKill:!1}:function(e,t){let a=!1;try{I(e.pid,e.processStartTime)&&(process.kill(e.pid,"SIGKILL"),a=!0)}catch{b(e.pid,{termTimeoutMs:3e3,killTimeoutMs:1e3,expectedStartTime:e.processStartTime})}finally{es(t.infoPath),es(t.lockPath)}return{forcedKill:a}}(e,t);return g({level:"error",phase:"daemon_request_timeout",data:{timeoutMs:n,requestId:a,command:r,timedOutRunnerPidsTerminated:i.terminated,timedOutRunnerCleanupError:i.error,daemonPidReset:o?void 0:e.pid,daemonPidForceKilled:o?void 0:s.forcedKill,daemonBaseUrl:e.baseUrl}}),new u("COMMAND_FAILED","Daemon request timed out",{timeoutMs:n,requestId:a,hint:o?"Retry with --debug and verify the remote daemon URL, auth token, and remote host logs.":"Retry with --debug and check daemon diagnostics logs. Timed-out iOS runner xcodebuild processes were terminated when detected."})}function eh(e,t,a){return g({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 ey(t,a,r){let o=t.port;if(!o)throw new u("COMMAND_FAILED","Daemon socket endpoint is unavailable");return new Promise((n,i)=>{let s=e.createConnection({host:"127.0.0.1",port:o},()=>{s.write(`${JSON.stringify(a)}
|
|
2
|
+
`)}),l=E(a.flags?.stateDir??process.env.AGENT_DEVICE_STATE_DIR),d="number"==typeof r?setTimeout(()=>{s.destroy(),i(ef(t,l,a.meta?.requestId,a.command,!1,r))},r):void 0,c="";s.setEncoding("utf8"),s.on("data",e=>{let t=(c+=e).indexOf("\n");if(-1===t)return;let r=c.slice(0,t).trim();if(r)try{let e=JSON.parse(r);s.end(),d&&clearTimeout(d),n(e)}catch(e){d&&clearTimeout(d),i(new u("COMMAND_FAILED","Invalid daemon response",{requestId:a.meta?.requestId,line:r},e instanceof Error?e:void 0))}}),s.on("error",e=>{d&&clearTimeout(d),i(eh(e,a.meta?.requestId,!1))})})}async function ew(e,r,o){var n,i,s;let l,d=e.baseUrl?new URL(eg(e.baseUrl,"rpc")):e.httpPort?new URL(`http://127.0.0.1:${e.httpPort}/rpc`):null;if(!d)throw new u("COMMAND_FAILED","Daemon HTTP endpoint is unavailable");let p=JSON.stringify((n=r,i={includeTokenParam:!e.baseUrl},l=n.meta?.requestId??w(),"lease_allocate"!==(s=n.command)&&"lease_heartbeat"!==s&&"lease_release"!==s?{jsonrpc:"2.0",id:l,method:"agent_device.command",params:n}:{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"}}(n.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}}}(n,n.command,i)})),m={"content-type":"application/json","content-length":Buffer.byteLength(p)};return e.baseUrl&&e.token&&(m.authorization=`Bearer ${e.token}`,m["x-agent-device-token"]=e.token),await new Promise((n,i)=>{let s=E(r.flags?.stateDir??process.env.AGENT_DEVICE_STATE_DIR),l=("https:"===d.protocol?a:t).request({protocol:d.protocol,host:d.hostname,port:d.port,method:"POST",path:d.pathname+d.search,headers:m},t=>{let a="";t.setEncoding("utf8"),t.on("data",e=>{a+=e}),t.on("end",()=>{h&&clearTimeout(h);try{let t=JSON.parse(a);if(t.error){let e=t.error.data??{};i(new u(c(null!=e.code?String(e.code):void 0,"COMMAND_FAILED"),String(e.message??t.error.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:r.meta?.requestId}));return}if(!t.result||"object"!=typeof t.result)return void i(new u("COMMAND_FAILED","Invalid daemon RPC response",{requestId:r.meta?.requestId}));if(e.baseUrl&&t.result.ok)return void eI(e,r,t.result).then(n).catch(i);n(t.result)}catch(e){h&&clearTimeout(h),i(new u("COMMAND_FAILED","Invalid daemon response",{requestId:r.meta?.requestId,line:a},e instanceof Error?e:void 0))}})}),f=ev(e),h="number"==typeof o?setTimeout(()=>{l.destroy(),i(ef(e,s,r.meta?.requestId,r.command,f,o))},o):void 0;l.on("error",e=>{h&&clearTimeout(h),i(eh(e,r.meta?.requestId,f))}),l.write(p),l.end()})}function ev(e){return"string"==typeof e.baseUrl&&e.baseUrl.length>0}function eg(e,t){return new URL(t,e.endsWith("/")?e:`${e}/`).toString()}async function eI(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=e.fileName?.trim()||`${e.field}-${Date.now()}`;return o.resolve(t.meta?.cwd??process.cwd(),a)}(a,t);await eb({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 eb(e){var i,s;let l,d=new URL((i=e.baseUrl,s=e.artifactId,l=i.endsWith("/")?i:`${i}/`,new URL(`artifacts/${encodeURIComponent(s)}`,l).toString())),c="https:"===d.protocol?a:t;await r.promises.mkdir(o.dirname(e.destinationPath),{recursive:!0}),await new Promise((t,a)=>{let o=!1,i=e.timeoutMs??$,s=n=>{if(!o){if(o=!0,clearTimeout(p),n)return void r.promises.rm(e.destinationPath,{force:!0}).finally(()=>a(n));t()}},l=c.request({protocol:d.protocol,host:d.hostname,port:d.port,method:"GET",path:d.pathname+d.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}))}),n(t,r.createWriteStream(e.destinationPath)).then(()=>s(),e=>s(e instanceof Error?e:Error(String(e))))}),p=setTimeout(()=>{l.destroy(new u("COMMAND_FAILED","Remote artifact download timed out",{artifactId:e.artifactId,requestId:e.requestId,timeoutMs:i}))},i);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:i},t instanceof Error?t:void 0))}),l.end()})}function eA(e=process.env.AGENT_DEVICE_DAEMON_TIMEOUT_MS){if(!e)return 9e4;let t=Number(e);return Number.isFinite(t)?Math.max(1e3,Math.floor(t)):9e4}let e_={alert:"alert",appState:"appstate",appSwitcher:"app-switcher",apps:"apps",back:"back",batch:"batch",boot:"boot",click:"click",clipboard:"clipboard",devices:"devices",diff:"diff",fill:"fill",find:"find",focus:"focus",get:"get",home:"home",is:"is",keyboard:"keyboard",logs:"logs",longPress:"longpress",network:"network",perf:"perf",pinch:"pinch",press:"press",push:"push",record:"record",replay:"replay",rotate:"rotate",scroll:"scroll",screenshot:"screenshot",settings:"settings",snapshot:"snapshot",swipe:"swipe",test:"test",trace:"trace",triggerAppEvent:"trigger-app-event",type:"type",wait:"wait"};function eS(e,t,a,r){let o=a(e[t]);if(void 0===o)throw new u("COMMAND_FAILED",r,{response:e});return o}function eM(e,t){return eS(e,t,eN,`Daemon response is missing "${t}".`)}function ek(e,t){return eN(e[t])}function eE(e,t){var a;let r;return a=eN,null===(r=e[t])?null:a(r)}function eD(e,t){return eS(e,t,ex,`Daemon response has invalid "${t}".`)}function eP(e,t){return function(e){return"tv"===e||"mobile"===e||"desktop"===e?e:void 0}(e[t])??"mobile"}function eT(e,t){let a=e[t];if(!eO(a))return;let r="number"==typeof a.x?a.x:void 0,o="number"==typeof a.y?a.y:void 0,n="number"==typeof a.width?a.width:void 0,i="number"==typeof a.height?a.height:void 0;if(void 0!==r&&void 0!==o&&void 0!==n&&void 0!==i)return{x:r,y:o,width:n,height:i}}function eN(e){return"string"==typeof e&&e.length>0?e:void 0}function eU(e){return"number"==typeof e&&Number.isFinite(e)?e:void 0}function ex(e){return"ios"===e||"macos"===e||"android"===e?e:void 0}function eC(e){return"simulator"===e||"emulator"===e||"device"===e?e:void 0}function eR(e){if(!eO(e))throw new u("COMMAND_FAILED","Daemon returned an unexpected response shape.",{value:e});return e}function eO(e){return"object"==typeof e&&null!==e}function eL(e){let t={};for(let[a,r]of Object.entries(e))void 0!==r&&(t[a]=r);return t}function eF(e,t){let a=ek(e,"bundleId"),r=ek(e,"package");return{app:eM(e,"app"),appPath:eM(e,"appPath"),platform:eD(e,"platform"),appId:a??r,bundleId:a,package:r,identifiers:A({session:t,bundleId:a,packageName:r})}}function eB(e){let t=eR(e),a=eD(t,"platform"),r=eM(t,"id"),o=eM(t,"name");return{platform:a,target:eP(t,"target"),kind:eS(t,"kind",eC,'Daemon response has invalid "kind".'),id:r,name:o,booted:"boolean"==typeof t.booted?t.booted:void 0,identifiers:k(a,r,o),ios:"ios"===a?{udid:r}:void 0,android:"android"===a?{serial:r}:void 0}}function eq(e){let t=eR(e),a=eD(t,"platform"),r=eM(t,"id"),o=eM(t,"name"),n=eP(t,"target"),i=eM(t,"device"),s={session:o,...k(a,r,i)};return{name:o,createdAt:eS(t,"createdAt",eU,'Daemon response is missing numeric "createdAt".'),device:{platform:a,target:n,id:r,name:i,identifiers:s,ios:"ios"===a?{udid:r,simulatorSetPath:eE(t,"ios_simulator_device_set")}:void 0,android:"android"===a?{serial:r}:void 0},identifiers:s}}function ej(e){return e??"default"}function ez(e={},t={}){var a;let r,o=t.transport??J,n=async(t,a=[],r={})=>{var n,i;let s=(n=e,i=r,{...n,...i}),l=await o({session:ej(s.session),command:t,positionals:a,flags:eL({stateDir:s.stateDir,daemonBaseUrl:s.daemonBaseUrl,daemonAuthToken:s.daemonAuthToken,daemonTransport:s.daemonTransport,daemonServerMode:s.daemonServerMode,tenant:s.tenant,sessionIsolation:s.sessionIsolation,runId:s.runId,leaseId:s.leaseId,leaseBackend:s.leaseBackend,platform:s.platform,target:s.target,device:s.device,udid:s.udid,serial:s.serial,iosSimulatorDeviceSet:s.iosSimulatorDeviceSet,androidDeviceAllowlist:s.androidDeviceAllowlist,runtime:s.simulatorRuntimeId,boot:s.boot,reuseExisting:s.reuseExisting,surface:s.surface,activity:s.activity,relaunch:s.relaunch,shutdown:s.shutdown,saveScript:s.saveScript,noRecord:s.noRecord,backMode:s.backMode,metroHost:s.metroHost,metroPort:s.metroPort,bundleUrl:s.bundleUrl,launchUrl:s.launchUrl,snapshotInteractiveOnly:s.interactiveOnly,snapshotCompact:s.compact,snapshotDepth:s.depth,snapshotScope:s.scope,snapshotRaw:s.raw,screenshotFullscreen:s.screenshotFullscreen,screenshotMaxSize:s.screenshotMaxSize,overlayRefs:s.overlayRefs,appsFilter:s.appsFilter,out:s.out,count:s.count,fps:s.fps,quality:s.quality,hideTouches:s.hideTouches,intervalMs:s.intervalMs,delayMs:s.delayMs,holdMs:s.holdMs,jitterPx:s.jitterPx,pixels:s.pixels,doubleTap:s.doubleTap,clickButton:s.clickButton,pauseMs:s.pauseMs,pattern:s.pattern,headless:s.headless,restart:s.restart,replayUpdate:s.replayUpdate,replayEnv:s.replayEnv,replayShellEnv:s.replayShellEnv,failFast:s.failFast,timeoutMs:s.timeoutMs,retries:s.retries,artifactsDir:s.artifactsDir,reportJunit:s.reportJunit,findFirst:s.findFirst,findLast:s.findLast,networkInclude:s.networkInclude,batchOnError:s.batchOnError,batchMaxSteps:s.batchMaxSteps,batchSteps:s.batchSteps,verbose:s.debug}),runtime:s.runtime,meta:eL({requestId:s.requestId,cwd:s.cwd,debug:s.debug,lockPolicy:s.lockPolicy,lockPlatform:s.lockPlatform,tenantId:s.tenant,runId:s.runId,leaseId:s.leaseId,leaseBackend:s.leaseBackend,leaseTtlMs:s.leaseTtlMs,sessionIsolation:s.sessionIsolation,installSource:s.installSource,retainMaterializedPaths:s.retainMaterializedPaths,materializedPathRetentionMs:s.materializedPathRetentionMs,materializationId:s.materializationId})});return l.ok||function(e){throw new u(c(e.code),e.message,{...e.details??{},hint:e.hint,diagnosticId:e.diagnosticId,logPath:e.logPath})}(l.error),l.data??{}},i=async(e={})=>{let t=await n("session_list",[],e);return(Array.isArray(t.sessions)?t.sessions:[]).map(eq)},s=async(e,t=[],a={})=>await n(e,t,a),l=(t={})=>{var a,r;return ej((a=e,r=t,{...a,...r}).session)};return{command:(a=async e=>await n(e.command,e.positionals,e.options),r=async e=>await a(e),{wait:async e=>await r(function(e){if(1!==[void 0!==e.durationMs?"durationMs":void 0,void 0!==e.text?"text":void 0,void 0!==e.ref?"ref":void 0,void 0!==e.selector?"selector":void 0].filter(Boolean).length)throw new u("INVALID_ARGS","wait command requires exactly one of durationMs, text, ref, or selector.");if(void 0!==e.durationMs)return{command:e_.wait,positionals:[String(e.durationMs)],options:e};let t=void 0!==e.timeoutMs?[String(e.timeoutMs)]:[];if(void 0!==e.text)return{command:e_.wait,positionals:["text",e.text,...t],options:e};if(void 0!==e.ref)return{command:e_.wait,positionals:[e.ref,...t],options:e};let a=e.selector;return function(e){if(!P(e))throw new u("INVALID_ARGS",`Invalid wait selector: ${e}`)}(a),{command:e_.wait,positionals:[a,...t],options:e}}(e)),alert:async(e={})=>{var t;let a;return await r((a=(t=e).action??"get",{command:e_.alert,positionals:[a,...void 0!==t.timeoutMs?[String(t.timeoutMs)]:[]],options:t}))},appState:async(e={})=>await r({command:e_.appState,positionals:[],options:e}),back:async(e={})=>await r({command:e_.back,positionals:[],options:{...e,backMode:e.mode}}),home:async(e={})=>await r({command:e_.home,positionals:[],options:e}),rotate:async e=>await r({command:e_.rotate,positionals:[e.orientation],options:e}),appSwitcher:async(e={})=>await r({command:e_.appSwitcher,positionals:[],options:e}),keyboard:async(e={})=>await r({command:e_.keyboard,positionals:e.action?[e.action]:[],options:e}),clipboard:async e=>{var t;return await r("read"===(t=e).action?{command:e_.clipboard,positionals:["read"],options:t}:{command:e_.clipboard,positionals:["write",t.text],options:t})}}),devices:{list:async(e={})=>{let t=await n(e_.devices,[],e);return(Array.isArray(t.devices)?t.devices:[]).map(eB)},boot:async(e={})=>await s(e_.boot,[],e)},sessions:{list:async(e={})=>await i(e),close:async(e={})=>{let t=l(e),a=(await n("close",[],e)).shutdown;return{session:t,shutdown:"object"==typeof a&&null!==a?a:void 0,identifiers:{session:t}}}},simulators:{ensure:async e=>{let{runtime:t,...a}=e,r=await n("ensure-simulator",[],{...a,simulatorRuntimeId:t}),o=eM(r,"udid"),i=eM(r,"device");return{udid:o,device:i,runtime:eM(r,"runtime"),created:!0===r.created,booted:!0===r.booted,iosSimulatorDeviceSet:eE(r,"ios_simulator_device_set"),identifiers:{deviceId:o,deviceName:i,udid:o}}}},apps:{install:async e=>eF(await n("install",[e.app,e.appPath],e),l(e)),reinstall:async e=>eF(await n("reinstall",[e.app,e.appPath],e),l(e)),installFromSource:async e=>(function(e,t){let a=ek(e,"bundleId"),r=ek(e,"packageName"),o=a??r??ek(e,"appId"),n=ek(e,"launchTarget")??r??a??o;if(!n)throw new u("COMMAND_FAILED",'Daemon response is missing "launchTarget".',{response:e});return{appName:ek(e,"appName"),appId:o,bundleId:a,packageName:r,launchTarget:n,installablePath:ek(e,"installablePath"),archivePath:ek(e,"archivePath"),materializationId:ek(e,"materializationId"),materializationExpiresAt:ek(e,"materializationExpiresAt"),identifiers:A({session:t,bundleId:a,packageName:r,appId:o})}})(await n("install_source",[],{...e,installSource:e.source,retainMaterializedPaths:e.retainPaths,materializedPathRetentionMs:e.retentionMs}),l(e)),list:async(e={})=>{let t=await n(e_.apps,[],e);return Array.isArray(t.apps)?t.apps.filter(e=>"string"==typeof e):[]},open:async e=>{let t=l(e),a=e.app?e.url?[e.app,e.url]:[e.app]:[],r=await n("open",a,e),o=function(e){let t=e.platform,a=ek(e,"id"),r=ek(e,"device");if("ios"!==t&&"macos"!==t&&"android"!==t||!a||!r)return;let o=eP(e,"target"),n=k(t,a,r);return{platform:t,target:o,id:a,name:r,identifiers:n,ios:"ios"===t?{udid:ek(e,"device_udid")??a,simulatorSetPath:eE(e,"ios_simulator_device_set")}:void 0,android:"android"===t?{serial:ek(e,"serial")??a}:void 0}}(r),i=ek(r,"appBundleId");return{session:t,appName:ek(r,"appName"),appBundleId:i,appId:i,startup:function(e){if(eO(e)&&"number"==typeof e.durationMs&&"string"==typeof e.measuredAt&&"string"==typeof e.method)return{durationMs:e.durationMs,measuredAt:e.measuredAt,method:e.method,appTarget:ek(e,"appTarget"),appBundleId:ek(e,"appBundleId")}}(r.startup),runtime:function(e){if(!eO(e))return;let t=e.platform,a=ek(e,"metroHost"),r="number"==typeof e.metroPort?e.metroPort:void 0;return{platform:"ios"===t||"android"===t?t:void 0,metroHost:a,metroPort:r,bundleUrl:ek(e,"bundleUrl"),launchUrl:ek(e,"launchUrl")}}(r.runtime),device:o,identifiers:{session:t,deviceId:o?.id,deviceName:o?.name,udid:o?.ios?.udid,serial:o?.android?.serial,appId:i,appBundleId:i}}},close:async(e={})=>{let t=l(e),a=(await n("close",e.app?[e.app]:[],e)).shutdown;return{session:t,closedApp:e.app,shutdown:"object"==typeof a&&null!==a?a:void 0,identifiers:{session:t}}},push:async e=>{var t;return await s(e_.push,[e.app,"string"==typeof(t=e.payload)?t:JSON.stringify(t)],e)},triggerEvent:async e=>{var t;return await s(e_.triggerAppEvent,[(t=e).event,...t.payload?[JSON.stringify(t.payload)]:[]],e)}},materializations:{release:async e=>{var t;return{released:!0===(t=await n("release_materialized_paths",[],{...e,materializationId:e.materializationId})).released,materializationId:eM(t,"materializationId"),identifiers:{}}}},leases:{allocate:async e=>eG(await n("lease_allocate",[],{...e,leaseId:void 0,leaseTtlMs:e.ttlMs})),heartbeat:async e=>eG(await n("lease_heartbeat",[],{...e,leaseTtlMs:e.ttlMs})),release:async e=>({released:!0===(await n("lease_release",[],e)).released})},metro:{prepare:async t=>await N({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 T({metroHost:t.metroHost,metroPort:t.metroPort,bundleUrl:t.bundleUrl,runtime:e.runtime,timeoutMs:t.timeoutMs})},capture:{snapshot:async(e={})=>{var t;let a=l(e),r=await n(e_.snapshot,[],e),o=ek(r,"appBundleId"),i="object"==typeof r.visibility&&null!==r.visibility?r.visibility:void 0,s="object"==typeof r.androidSnapshot&&null!==r.androidSnapshot?r.androidSnapshot:void 0;return{nodes:Array.isArray(t=r.nodes)?t:[],truncated:!0===r.truncated,appName:ek(r,"appName"),appBundleId:o,...i?{visibility:i}:{},...s?{androidSnapshot:s}:{},warnings:Array.isArray(r.warnings)?r.warnings.filter(e=>"string"==typeof e):void 0,identifiers:{session:a,appId:o,appBundleId:o}}},screenshot:async(e={})=>{let t=l(e),a=await n(e_.screenshot,e.path?[e.path]:[],{...e,screenshotFullscreen:e.fullscreen,screenshotMaxSize:e.maxSize});return{path:eM(a,"path"),overlayRefs:function(e){let t=e.overlayRefs;if(!Array.isArray(t))return;let a=[];for(let e of t){if(!eO(e))continue;let t=ek(e,"ref"),r=eT(e,"rect"),o=eT(e,"overlayRect"),n=function(e,t){let a=e[t];if(!eO(a))return;let r="number"==typeof a.x?a.x:void 0,o="number"==typeof a.y?a.y:void 0;if(void 0!==r&&void 0!==o)return{x:r,y:o}}(e,"center");t&&r&&o&&n&&a.push({ref:t,label:ek(e,"label"),rect:r,overlayRect:o,center:n})}return a}(a),identifiers:{session:t}}},diff:async e=>await s(e_.diff,[e.kind],{...e,interactiveOnly:e.interactiveOnly,compact:e.compact,depth:e.depth,scope:e.scope,raw:e.raw})},interactions:{click:async e=>await s(e_.click,e$(e),{...e,clickButton:e.button}),press:async e=>await s(e_.press,e$(e),e),longPress:async e=>await s(e_.longPress,[String(e.x),String(e.y),...eK(e.durationMs)],e),swipe:async e=>await s(e_.swipe,[String(e.from.x),String(e.from.y),String(e.to.x),String(e.to.y),...eK(e.durationMs)],e),focus:async e=>await s(e_.focus,[String(e.x),String(e.y)],e),type:async e=>await s(e_.type,[e.text],e),fill:async e=>await s(e_.fill,[...e$(e),e.text],e),scroll:async e=>await s(e_.scroll,[e.direction,...eK(e.amount)],e),pinch:async e=>await s(e_.pinch,[String(e.scale),...eK(e.x),...eK(e.y)],e),get:async e=>{var t;return await s(e_.get,[e.format,...void 0!==(t=e).ref?[t.ref,...eH(t.label)]:[t.selector]],e)},is:async e=>await s(e_.is,[e.predicate,e.selector,..."text"===e.predicate?[e.value]:[]],e),find:async e=>await s(e_.find,function(e){let t=e.locator&&"any"!==e.locator?[e.locator,e.query]:[e.query];switch(e.action){case void 0:case"click":case"focus":case"exists":return e.action?[...t,e.action]:t;case"getText":return[...t,"get","text"];case"getAttrs":return[...t,"get","attrs"];case"wait":return[...t,"wait",...eK(e.timeoutMs)];case"fill":case"type":return[...t,e.action,e.value]}}(e),{...e,findFirst:e.first,findLast:e.last})},replay:{run:async e=>await s(e_.replay,[e.path],{...e,replayUpdate:e.update,replayEnv:e.env,replayShellEnv:eV(process.env)}),test:async e=>await s(e_.test,e.paths,{...e,replayUpdate:e.update,replayEnv:e.env,replayShellEnv:eV(process.env)})},batch:{run:async e=>await s(e_.batch,[],{...e,batchSteps:e.steps,batchOnError:e.onError,batchMaxSteps:e.maxSteps})},observability:{perf:async(e={})=>await s(e_.perf,[],e),logs:async(e={})=>{var t;return await s(e_.logs,[(t=e).action??"path",...eH(t.message)],e)},network:async(e={})=>{var t;return await s(e_.network,[...(t=e).action?[t.action]:[],...eK(t.limit)],{...e,networkInclude:e.include})}},recording:{record:async e=>await s(e_.record,[e.action,...eH(e.path)],e),trace:async e=>await s(e_.trace,[e.action,...eH(e.path)],e)},settings:{update:async e=>await s(e_.settings,[e.setting,e.state,..."permission"in e?[e.permission]:[],..."mode"in e&&e.mode?[e.mode]:[]],e)}}}function e$(e){return void 0!==e.ref?[e.ref,...eH(e.label)]:void 0!==e.selector?[e.selector]:[String(e.x),String(e.y)]}function eH(e){return void 0===e?[]:[e]}function eK(e){return void 0===e?[]:[String(e)]}function eV(e){let t={};for(let[a,r]of Object.entries(e))"string"==typeof r&&a.startsWith("AD_VAR_")&&(t[a]=r);return t}function eG(e){let t=e.lease;if(!t||"object"!=typeof t||Array.isArray(t))throw Error("Invalid lease response from daemon");return{leaseId:eM(t,"leaseId"),tenantId:eM(t,"tenantId"),runId:eM(t,"runId"),backend:eM(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{e_ as CLIENT_COMMANDS,ez as createAgentDeviceClient,J as sendToDaemon};
|
package/dist/src/9671.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import r from"node:fs";import e from"node:path";import{fileURLToPath as o}from"node:url";function t(){try{let o=n();return JSON.parse(r.readFileSync(e.join(o,"package.json"),"utf8")).version??"0.0.0"}catch{return"0.0.0"}}function n(){let t=e.dirname(o(import.meta.url)),n=t;for(let o=0;o<6;o+=1){let o=e.join(n,"package.json");if(r.existsSync(o))return n;n=e.dirname(n)}return t}export{n as findProjectRoot,t as readVersion};
|
package/dist/src/cli.js
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import e from"node:path";import{styleText as t}from"node:util";import{pathToFileURL as r}from"node:url";import n from"node:fs";import o from"node:crypto";import{resolveRemoteConfigProfile as s,resolveRemoteConfigPath as i,REMOTE_CONFIG_FIELD_SPECS as a,parseSourceValue as l,buildPrimaryEnvVarName as c}from"./208.js";import{GLOBAL_FLAG_KEYS as u,isStrictFlagModeEnabled as d,getFlagDefinition as f,getCommandSchema as p,buildCommandUsageText as m,buildUsageText as h,getCliCommandNames as g,getFlagDefinitions as w}from"./command-schema.js";import{asAppError as v,normalizeError as y,AppError as I}from"./9152.js";import{buildMobileSnapshotPresentation as A,buildSnapshotDisplayLines as $,createAgentDevice as S,displayNodeLabel as b,localCommandPolicy as D,parseDeviceRotation as _,parseWaitArgs as N,formatSnapshotLine as C}from"./6108.js";import{ensureCompanionTunnel as k,stopCompanionTunnel as R}from"./1974.js";import{REACT_DEVTOOLS_COMPANION_RUN_ARG as x}from"./2301.js";import{createRequestId as E,withDiagnosticsScope as P,getDiagnosticsMeta as L,flushDiagnosticsToSessionFile as T,emitDiagnostic as U}from"./7599.js";import{serializeOpenResult as M,serializeSnapshotResult as O,serializeSessionListEntry as B,serializeDeployResult as V,readCommandMessage as j,serializeCloseResult as G,resolveDaemonPaths as F,serializeEnsureSimulatorResult as K,serializeInstallFromSourceResult as H,serializeDevice as q}from"./180.js";import{stopMetroTunnel as J}from"./metro.js";import{runCmdStreaming as z,runCmd as W}from"./9818.js";import{resolveUserPath as Z,expandUserHomePath as Y}from"./3267.js";import{createLocalArtifactAdapter as X}from"./7719.js";import{createAgentDeviceClient as Q,CLIENT_COMMANDS as ee,sendToDaemon as et}from"./9542.js";import{splitSelectorFromArgs as er}from"./940.js";import{isEnvTruthy as en}from"./8809.js";import{readVersion as eo}from"./9671.js";import{parseBatchStepsJson as es}from"./1231.js";import{maybeRunUpgradeNotifier as ei}from"./113.js";function ea(e,t){for(let[r,n]of Object.entries(t))void 0!==n&&(e[r]=n);return e}let el=new Set(["config","remoteConfig","help","version","batchSteps","githubActionsArtifact"]),ec={iosSimulatorDeviceSet:["IOS_SIMULATOR_DEVICE_SET"],androidDeviceAllowlist:["ANDROID_DEVICE_ALLOWLIST"],metroBearerToken:["AGENT_DEVICE_PROXY_TOKEN"]},eu=function(){let e=new Map;for(let t of w()){let r=e.get(t.key);r?r.push(t):e.set(t.key,[t])}let t=new Map;for(let e of u)t.set(e,new Set(["*"]));for(let e of g()){let r=p(e);if(r)for(let n of r.allowedFlags){let r=t.get(n);r&&r.has("*")||(r?r.add(e):t.set(n,new Set([e])))}}return[...e.entries()].map(([e,r])=>({key:e,flagDefinitions:r,config:{enabled:!el.has(e),key:e},env:{names:[c(e),...ec[e]??[]]},supportsCommand(r){let n=t.get(e);return!!n&&(!!n.has("*")||!!r&&n.has(r))}})).sort((e,t)=>e.key.localeCompare(t.key))}(),ed=new Map(eu.map(e=>[e.key,e]));function ef(e,t){return ed.get(e)?.supportsCommand(t)??!1}function ep(e){let t=e.flagDefinitions.find(e=>void 0===e.setValue);if(t)return t;let r=function(e){let t=e.flagDefinitions[0];if(!t)throw Error(`Missing flag definition for option ${e.key}`);return t}(e);if("enum"===r.type){let t=e.flagDefinitions.map(e=>e.setValue).filter(e=>void 0!==e);return{...r,setValue:void 0,enumValues:t}}return r}function em(e){let t=e.indexOf("=");return -1===t?[e,void 0]:[e.slice(0,t),e.slice(t+1)]}function eh(e){return e.replace(/^-+/,"")}function eg(e){if(!e.startsWith("-")||"-"===e)return!1;let[t]=e.startsWith("--")?em(e):[e,void 0];return void 0!==f(t)}function ew(e){return"long-press"===e?"longpress":"metrics"===e?"perf":e}function ev(e){process.stdout.write(`${JSON.stringify(e,null,2)}
|
|
2
|
+
`)}function ey(e,t={}){let r=e instanceof I?y(e):e;process.stderr.write(`Error (${r.code}): ${r.message}
|
|
3
|
+
`),r.hint&&process.stderr.write(`Hint: ${r.hint}
|
|
4
|
+
`),r.diagnosticId&&process.stderr.write(`Diagnostic ID: ${r.diagnosticId}
|
|
5
|
+
`),r.logPath&&process.stderr.write(`Diagnostics Log: ${r.logPath}
|
|
6
|
+
`),t.showDetails&&r.details&&process.stderr.write(`${JSON.stringify(r.details,null,2)}
|
|
7
|
+
`)}function eI(e){return e&&e.summaryLines.length>0?`
|
|
8
|
+
${e.summaryLines.join("\n")}`:""}function eA(e){return`x=${e.x},y=${e.y},w=${e.width},h=${e.height}`}function e$(e){return e>0?`+${e}`:String(e)}function eS(e){let t=e.nearestText?` near ${JSON.stringify(e.nearestText)}`:"",r=e.regionIndex?` r${e.regionIndex}`:"";return`${e.likelyKind}${t}${r}`}function eb(e){return e.min===e.max?e$(e.min):`${e$(e.min)}..${e$(e.max)}`}function eD(t){let r=process.cwd(),n=e.relative(r,t);return""!==n&&(n.startsWith("..")||e.isAbsolute(n))?t:""===n?".":`.${e.sep}${n}`}function e_(e){return"number"==typeof e&&Number.isFinite(e)?e:0}function eN(){let e=process.env.FORCE_COLOR;return"string"==typeof e?"0"!==e:"string"!=typeof process.env.NO_COLOR&&!!process.stdout.isTTY}function eC(e,r){return r?t("dim",e):e}function ek(e){let t=e.warnings;return Array.isArray(t)?t.filter(e=>"string"==typeof e&&e.length>0):[]}function eR(e,t){var r;let n="scroll-area"===(r=e.type)||"list"===r||"collection"===r||"table"===r?r:null;if(!n)return[];let o=[];if(e.node.hiddenContentAbove&&"below"!==t&&o.push(`[content above ${n} hidden]`),e.node.hiddenContentBelow&&"above"!==t&&o.push(`[content below ${n} hidden]`),0===o.length)return[];let s=" ".repeat(e.depth+1);return o.map(e=>`${s}${e}`)}let ex={slug:"react-devtools-companion",runArg:x,displayName:"React DevTools companion"};async function eE(e){return await k({...e,definition:ex,localBaseUrl:e.localBaseUrl??"http://127.0.0.1:8097",registerPath:"/api/react-devtools/companion/register",unregisterPath:"/api/react-devtools/companion/unregister",devicePort:e.devicePort??8097})}async function eP(e){return await R({...e,definition:ex})}function eL(e){var t;let r,o=eB(e);if(!n.existsSync(o))return null;try{r=JSON.parse(n.readFileSync(o,"utf8"))}catch(t){return eK(e,t),null}return!(!(t=r)||"object"!=typeof t||Array.isArray(t))&&1===t.version&&"string"==typeof t.session&&"string"==typeof t.remoteConfigPath&&"string"==typeof t.remoteConfigHash&&(void 0===t.daemon||"object"==typeof t.daemon&&null!==t.daemon&&!Array.isArray(t.daemon))&&"string"==typeof t.tenant&&"string"==typeof t.runId&&(void 0===t.leaseId||"string"==typeof t.leaseId)&&(void 0===t.leaseBackend||"string"==typeof t.leaseBackend)&&"string"==typeof t.connectedAt&&"string"==typeof t.updatedAt?r:(eK(e),null)}function eT(t){let r=eB({stateDir:t.stateDir,session:t.state.session});n.mkdirSync(e.dirname(r),{recursive:!0}),eF(r,t.state),eF(eV(t.stateDir),{session:t.state.session})}function eU(e){return{baseUrl:function(e){if(!e)return;let t=new URL(e);for(let e of(t.username="",t.password="",[...t.searchParams.keys()]))/(auth|key|password|secret|token)/i.test(e)&&t.searchParams.delete(e);return t.toString().replace(/\/+$/,"")}(e.daemonBaseUrl),transport:e.daemonTransport,serverMode:e.daemonServerMode}}function eM(e){n.rmSync(eB(e),{force:!0});let t=eV(e.stateDir);eG(e.stateDir)===e.session&&n.rmSync(t,{force:!0})}function eO(e){try{return o.createHash("sha256").update(n.readFileSync(e)).digest("hex")}catch(t){throw new I("INVALID_ARGS",`Remote config file not found: ${e}`,{cause:t instanceof Error?t.message:String(t)})}}function eB(t){return e.join(t.stateDir,"remote-connections",`${function(e){let t=e.replaceAll(/[^a-zA-Z0-9._-]/g,"_");if(!t)return"default";if(t===e)return t;let r=o.createHash("sha256").update(e).digest("hex").slice(0,8);return`${t}-${r}`}(t.session)}.json`)}function eV(t){return e.join(t,"remote-connections",".active-session.json")}function ej(e){let t=eG(e.stateDir);return t?eL({stateDir:e.stateDir,session:t}):null}function eG(e){let t=eV(e);if(n.existsSync(t))try{let e=JSON.parse(n.readFileSync(t,"utf8"));return"string"==typeof e.session?e.session:void 0}catch{return}}function eF(e,t){n.writeFileSync(e,`${JSON.stringify(t,null,2)}
|
|
9
|
+
`,{encoding:"utf8",mode:384}),n.chmodSync(e,384)}function eK(e,t){U({level:"warn",phase:"remote_connection_state_invalid",data:{session:e.session,cause:t instanceof Error?t.message:t?String(t):void 0}}),eM(e)}let eH=a.map(e=>e.key);function eq(e){let t={};for(let r of eH){let n=e[r];void 0!==n&&(t[r]=n)}return t}let eJ=new Set(["connect","connection","close","disconnect","ensure-simulator","metro","session"]),ez=new Set(["open"]);async function eW(e){let t,r,{command:n,flags:o,client:i}=e;if(!o.remoteConfig)return{flags:o,runtime:e.runtime};let a=F(o.stateDir).baseDir,l=s({configPath:o.remoteConfig,cwd:process.cwd(),env:process.env}),c={...eq(l.profile),...o,remoteConfig:l.resolvedPath},u=eL({stateDir:a,session:c.session??"default"});if(u&&u.remoteConfigPath!==l.resolvedPath)throw new I("INVALID_ARGS","A different remote connection is already active for this session. Run connect --force or disconnect before using a different --remote-config.",{session:u.session,activeRemoteConfig:u.remoteConfigPath,requestedRemoteConfig:l.resolvedPath});let d=u??function(e,t){if(!e.tenant)throw new I("INVALID_ARGS","remote command requires tenant in remote config or via --tenant <id>.");if(!e.runId)throw new I("INVALID_ARGS","remote command requires runId in remote config or via --run-id <id>.");if(!e.daemonBaseUrl)throw new I("INVALID_ARGS","remote command requires daemonBaseUrl in remote config, config, env, or --daemon-base-url.");let r=new Date().toISOString();return{version:1,session:e.session??"default",remoteConfigPath:t,remoteConfigHash:eO(t),daemon:eU(e),tenant:e.tenant,runId:e.runId,leaseId:e.leaseId,leaseBackend:e.leaseBackend??e0(e),platform:e.platform,target:e.target,connectedAt:r,updatedAt:r}}(c,l.resolvedPath),f={...c,session:d.session},p=function(e,t){if(e)return e2(e,t)?e:void 0}(d.runtime,f.platform)??e.runtime,m=d,h=!u;if(g=n,!eJ.has(g)){let e=d.leaseBackend??function(e,t){let r=e0(e);if(r)return r;throw new I("INVALID_ARGS",`${t} requires --platform ios|android or --lease-backend when the remote connection has not resolved a lease yet.`)}(o,n);var g,w,v,y,A,$=d,S=o,b=e;if($.leaseBackend&&$.leaseBackend!==b)throw new I("INVALID_ARGS","Active remote connection is already bound to a different lease backend. Re-run connect --force to replace it.",{session:$.session,leaseBackend:$.leaseBackend});if($.platform&&S.platform&&$.platform!==S.platform)throw new I("INVALID_ARGS","Active remote connection is already bound to a different platform. Re-run connect --force to replace it.",{session:$.session,platform:$.platform});if($.target&&S.target&&$.target!==S.target)throw new I("INVALID_ARGS","Active remote connection is already bound to a different target. Re-run connect --force to replace it.",{session:$.session,target:$.target});let t=await e3(i,m,e);f.leaseId=t.leaseId,f.leaseBackend=e,f.platform=m.platform??f.platform,f.target=m.target??f.target,(m.leaseId!==t.leaseId||m.leaseBackend!==e)&&(m={...m,leaseId:t.leaseId,leaseBackend:e,platform:m.platform??o.platform,target:m.target??o.target,updatedAt:new Date().toISOString()},h=!0)}if(w=n,v=e.batchSteps,(ez.has(w)||"batch"===w&&v&&v.some(e=>{let t=e.command.trim().toLowerCase();return ez.has(t)&&void 0===e.runtime}))&&e1(f)&&(!m.leaseId&&f.leaseId&&(m={...m,leaseId:f.leaseId,leaseBackend:f.leaseBackend}),e.forceRuntimePrepare||!p||!e2(p,f.platform))){if(!m.leaseId)throw new I("INVALID_ARGS",`${n} requires a resolved remote lease before Metro runtime can be prepared.`);let e=await eZ(f,i,d.remoteConfigPath,d.session,{tenantId:d.tenant,runId:d.runId,leaseId:m.leaseId});p=e.runtime;let o=(y=m.metro,A=e.cleanup,y?.projectRoot!==A?.projectRoot||y?.profileKey!==A?.profileKey||y?.consumerKey!==A?.consumerKey);t=o?m.metro:void 0,r=o?e.cleanup:void 0,m={...m,runtime:e.runtime,metro:e.cleanup,updatedAt:new Date().toISOString()},h=!0}if(h)try{eT({stateDir:a,state:m})}catch(e){throw await eY(r),e}return await eY(t),{flags:{...f,session:m.session,leaseId:m.leaseId,leaseBackend:m.leaseBackend,platform:m.platform??f.platform,target:m.target??f.target},runtime:p}}async function eZ(e,t,r,n,o){if(!e.metroProjectRoot&&!e.metroPublicBaseUrl&&!e.metroProxyBaseUrl)return{};if("ios"!==e.platform&&"android"!==e.platform)throw new I("INVALID_ARGS",'Deferred Metro preparation requires platform "ios" or "android".');if(!e.metroPublicBaseUrl&&!e.metroProxyBaseUrl)throw new I("INVALID_ARGS","Deferred Metro preparation requires metroPublicBaseUrl or metroProxyBaseUrl when Metro settings are provided.");let s=await t.metro.prepare({projectRoot:e.metroProjectRoot,kind:e.metroKind,publicBaseUrl:e.metroPublicBaseUrl,proxyBaseUrl:e.metroProxyBaseUrl,bearerToken:e.metroBearerToken,bridgeScope:o,launchUrl:e.launchUrl,companionProfileKey:r,companionConsumerKey:n,port:e.metroPreparePort,listenHost:e.metroListenHost,statusHost:e.metroStatusHost,startupTimeoutMs:e.metroStartupTimeoutMs,probeTimeoutMs:e.metroProbeTimeoutMs,reuseExisting:!e.metroNoReuseExisting&&void 0,installDependenciesIfNeeded:!e.metroNoInstallDeps&&void 0,runtimeFilePath:e.metroRuntimeFile});return{runtime:"ios"===e.platform?s.iosRuntime:s.androidRuntime,cleanup:e.metroProxyBaseUrl?{projectRoot:s.projectRoot,profileKey:r,consumerKey:n}:void 0}}async function eY(e){if(e)try{await J(e)}catch{}}async function eX(e){try{await eP({projectRoot:process.cwd(),stateDir:e.stateDir,profileKey:e.state.remoteConfigPath,consumerKey:e.state.session})}catch{}}async function eQ(e,t){if(t.leaseId)try{await e.leases.release({tenant:t.tenant,runId:t.runId,leaseId:t.leaseId,daemonBaseUrl:t.daemon?.baseUrl,daemonTransport:t.daemon?.transport,daemonServerMode:t.daemon?.serverMode})}catch{}}function e0(e){return e.leaseBackend?e.leaseBackend:"android"===e.platform?"android-instance":"ios"===e.platform?"ios-instance":void 0}function e1(e){return!!(e.metroPublicBaseUrl||e.metroProxyBaseUrl||e.metroProjectRoot||e.metroKind)}function e2(e,t){return!e.platform||!t||"ios"!==t&&"android"!==t||e.platform===t}async function e3(e,t,r){if(t.leaseId&&t.leaseBackend===r){let n=await e8(e,t.leaseId,{tenant:t.tenant,runId:t.runId,leaseBackend:r});if(n)return n}return await e.leases.allocate({tenant:t.tenant,runId:t.runId,leaseBackend:r})}async function e8(e,t,r){try{return await e.leases.heartbeat({tenant:r.tenant,runId:r.runId,leaseId:t,leaseBackend:r.leaseBackend})}catch(e){var n;if((n=e)instanceof I&&"UNAUTHORIZED"===n.code&&(n.details?.reason==="LEASE_NOT_FOUND"||n.details?.reason==="LEASE_EXPIRED"||n.details?.reason==="LEASE_REVOKED"))return;throw e}}function e4(e){return{platform:e.platform,target:e.target,device:e.device,udid:e.udid,serial:e.serial,iosSimulatorDeviceSet:e.iosSimulatorDeviceSet,androidDeviceAllowlist:e.androidDeviceAllowlist}}function e6(e,t,r){var n;if(e.json)return void ev({success:!0,data:t});let o=r?.();o&&(n=o,process.stdout.write(n.endsWith("\n")?n:`${n}
|
|
10
|
+
`))}function e5(e,t){e6(e,t,()=>j(t))}let e9=async({positionals:e,flags:t,client:r})=>{if("list"!==(e[0]??"list"))throw new I("INVALID_ARGS","session only supports list");let n={sessions:(await r.sessions.list()).map(B)};return e6(t,n,()=>JSON.stringify(n,null,2)),!0},e7=async({flags:e,client:t})=>{let r=await t.devices.list(e4(e));return e6(e,{devices:r.map(q)},()=>r.map(te).join("\n")),!0};function te(e){let t=e.kind?` ${e.kind}`:"",r=e.target?` target=${e.target}`:"",n="boolean"==typeof e.booted?` booted=${e.booted}`:"";return`${e.name} (${e.platform}${t}${r})${n}`}let tt=async({flags:e,client:t})=>{if(!e.device)throw new I("INVALID_ARGS","ensure-simulator requires --device <name>");let r=await t.simulators.ensure({device:e.device,runtime:e.runtime,boot:e.boot,reuseExisting:e.reuseExisting,iosSimulatorDeviceSet:e.iosSimulatorDeviceSet});return e6(e,K(r),()=>{let e=r.created?"Created":"Reused",t=r.booted?" (booted)":"";return r.runtime?`${e}: ${r.device} ${r.udid}${t}
|
|
11
|
+
Runtime: ${r.runtime}`:`${e}: ${r.device} ${r.udid}${t}`}),!0},tr=async({positionals:e,flags:t,client:r})=>{let n=(e[0]??"").toLowerCase();if("reload"===n){let e=await r.metro.reload({metroHost:t.metroHost,metroPort:t.metroPort,bundleUrl:t.bundleUrl,timeoutMs:t.metroProbeTimeoutMs});return e6(t,e,()=>`Reloaded React Native apps via ${e.reloadUrl}`),!0}if("prepare"!==n)throw new I("INVALID_ARGS","metro requires a subcommand: prepare or reload");if(!t.metroPublicBaseUrl&&!t.metroProxyBaseUrl)throw new I("INVALID_ARGS","metro prepare requires --public-base-url <url> or --proxy-base-url <url>.");let o=await r.metro.prepare({projectRoot:t.metroProjectRoot,kind:t.metroKind,port:t.metroPreparePort,listenHost:t.metroListenHost,statusHost:t.metroStatusHost,publicBaseUrl:t.metroPublicBaseUrl,proxyBaseUrl:t.metroProxyBaseUrl,bearerToken:t.metroBearerToken,bridgeScope:t.tenant&&t.runId&&t.leaseId?{tenantId:t.tenant,runId:t.runId,leaseId:t.leaseId}:void 0,startupTimeoutMs:t.metroStartupTimeoutMs,probeTimeoutMs:t.metroProbeTimeoutMs,reuseExisting:!t.metroNoReuseExisting&&void 0,installDependenciesIfNeeded:!t.metroNoInstallDeps&&void 0,runtimeFilePath:t.metroRuntimeFile});return e6(t,o,()=>JSON.stringify(o,null,2)),!0},tn=async({flags:e,client:t})=>{let r=await t.apps.list({...e4(e),appsFilter:e.appsFilter});return e6(e,{apps:r},()=>r.join("\n")),!0};function to(e,t,r,n){var o;return"number"==typeof r||"string"==typeof(o=r)&&/^\d+$/.test(o.trim())?{kind:"github-actions-artifact",owner:e,repo:t,artifactId:function(e,t){let r="number"==typeof e?e:"string"==typeof e?Number(e):NaN;if(!Number.isInteger(r))throw new I("INVALID_ARGS",`${t} must be an integer.`);return r}(r,n)}:{kind:"github-actions-artifact",owner:e,repo:t,artifactName:ti(r,n)}}function ts(e,t){let r=e.indexOf("/");if(r<=0||r===e.length-1||-1!==e.indexOf("/",r+1))throw new I("INVALID_ARGS",`${t} must use owner/repo.`);let n={owner:e.slice(0,r).trim(),repo:e.slice(r+1).trim()};if(!n.owner||!n.repo)throw new I("INVALID_ARGS",`${t} must use owner/repo.`);return n}function ti(e,t){let r="string"==typeof e&&e.trim().length>0?e.trim():void 0;if(!r)throw new I("INVALID_ARGS",`${t} must be a non-empty string.`);return r}let ta=async({positionals:e,flags:t,client:r})=>{let n=V(await tu("install",e,t,r));return e5(t,n),!0},tl=async({positionals:e,flags:t,client:r})=>{let n=V(await tu("reinstall",e,t,r));return e5(t,n),!0},tc=async({positionals:e,flags:t,client:r})=>{let n=H(await td(e,t,r));return e5(t,n),!0};async function tu(e,t,r,n){let o=t[0],s=t[1];if(!o||!s)throw new I("INVALID_ARGS",`${e} requires: ${e} <app> <path-to-app-binary>`);let i={app:o,appPath:s,...e4(r)};return"install"===e?await n.apps.install(i):await n.apps.reinstall(i)}async function td(e,t,r){let n=function(e,t){let r=e[0]?.trim();if(e.length>1)throw new I("INVALID_ARGS","install-from-source accepts either one <url> positional or --github-actions-artifact");let n=t.githubActionsArtifact?function(e,t="--github-actions-artifact"){let r=e.indexOf(":");if(r<=0||r===e.length-1)throw new I("INVALID_ARGS",`${t} must use owner/repo:artifact, for example thymikee/RNCLI83:6635342232`);let{owner:n,repo:o}=ts(e.slice(0,r),t);return to(n,o,e.slice(r+1),`${t} artifact`)}(t.githubActionsArtifact):void 0,o=t.installSource;if(1!=+!!r+ +!!n+ +!!o)throw new I("INVALID_ARGS","install-from-source requires exactly one source: <url>, --github-actions-artifact, or config installSource");return n||o||{kind:"url",url:r,headers:function(e){if(!e||0===e.length)return;let t={};for(let r of e){let e=r.indexOf(":");if(e<=0)throw new I("INVALID_ARGS",`Invalid --header value "${r}". Expected "name:value".`);let n=r.slice(0,e).trim(),o=r.slice(e+1).trim();if(!n)throw new I("INVALID_ARGS",`Invalid --header value "${r}". Header name cannot be empty.`);t[n]=o}return t}(t.header)}}(e,t);if("url"!==n.kind&&t.header&&t.header.length>0)throw new I("INVALID_ARGS","install-from-source --header is only supported for URL sources");return await r.apps.installFromSource({...e4(t),retainPaths:t.retainPaths,retentionMs:t.retentionMs,source:n})}let tf=async({positionals:e,flags:t,client:r})=>{let n=M(await r.apps.open({app:e[0],url:e[1],surface:t.surface,activity:t.activity,relaunch:t.relaunch,saveScript:t.saveScript,noRecord:t.noRecord,...e4(t)}));return e5(t,n),!0},tp=async({positionals:e,flags:t,client:r})=>{let n=G(e[0]?await r.apps.close({app:e[0],shutdown:t.shutdown}):await r.sessions.close({shutdown:t.shutdown}));return e5(t,n),!0};async function tm(e){return await th({command:e.command,flags:e.flags,stateDir:e.stateDir,allowInteractiveLogin:"connect"===e.command&&!e.flags.noLogin,env:e.env})}async function th(e){let t=e.env??e.io?.env??process.env;if(!e.flags.daemonBaseUrl)return{flags:e.flags,source:"none"};if(tk(e.flags.daemonAuthToken))return{flags:e.flags,source:"flag"};if(tk(t.AGENT_DEVICE_DAEMON_AUTH_TOKEN))return{flags:e.flags,source:"env"};if(!function(e,t){if("1"===t.AGENT_DEVICE_CLOUD_AUTH||"true"===t.AGENT_DEVICE_CLOUD_AUTH||tk(t.AGENT_DEVICE_CLOUD_BASE_URL))return!0;try{let t=new URL(e).hostname.toLowerCase();return"agent-device.dev"===t||t.endsWith(".agent-device.dev")}catch{return!1}}(e.flags.daemonBaseUrl,t))return{flags:e.flags,source:"none"};let r=await tI({stateDir:e.stateDir,flags:e.flags,env:t,io:e.io});if(r)return{flags:{...e.flags,daemonAuthToken:r.accessToken},source:"cli-session"};if(!e.allowInteractiveLogin){if(e.flags.noLogin)throw new I("UNAUTHORIZED","Remote daemon authentication is required.",{hint:"Run agent-device auth login, unset --no-login, or set AGENT_DEVICE_DAEMON_AUTH_TOKEN."});throw tb(e.command,t)}let n=await tw({stateDir:e.stateDir,flags:e.flags,env:t,io:e.io});return{flags:{...e.flags,daemonAuthToken:n.accessToken},source:"login"}}async function tg(e){let t=e.env??e.io?.env??process.env;if(tk(e.flags.daemonAuthToken))return{accessToken:e.flags.daemonAuthToken,cloudBaseUrl:tD(t)};if(tk(t.AGENT_DEVICE_DAEMON_AUTH_TOKEN))return{accessToken:t.AGENT_DEVICE_DAEMON_AUTH_TOKEN,cloudBaseUrl:tD(t)};let r=await tI({stateDir:e.stateDir,flags:e.flags,env:t,io:e.io});if(r)return{accessToken:r.accessToken,cloudBaseUrl:r.cloudBaseUrl};if(e.flags.noLogin)throw new I("UNAUTHORIZED","Cloud connection profile authentication is required.",{hint:"Run agent-device auth login, unset --no-login, or set AGENT_DEVICE_DAEMON_AUTH_TOKEN."});let n=await tw({stateDir:e.stateDir,flags:e.flags,env:t,io:e.io,commandLabel:"agent-device connect"});return{accessToken:n.accessToken,cloudBaseUrl:n.session.cloudBaseUrl}}async function tw(t){let r,o,s,i=t.env??t.io?.env??process.env,a=(u=i,d=t.io,r=d?.stdinIsTTY??process.stdin.isTTY,o=d?.stdoutIsTTY??process.stdout.isTTY,"true"!==(f=u).CI&&"true"!==f.GITHUB_ACTIONS&&"true"!==f.BUILDKITE&&r&&o?(p=u).SSH_TTY||p.SSH_CONNECTION||"true"===p.CODESPACES||p.GITPOD_WORKSPACE_ID||"true"===p.REMOTE_CONTAINERS?"device-code":"local-browser":"non-interactive");if("non-interactive"===a)throw tb(t.commandLabel??"agent-device connect",i);let l=tD(i),c=await tS({baseUrl:l,pathName:"/api/control-plane/device-auth/start",body:{client:"agent-device",tenant:t.flags.tenant,runId:t.flags.runId,daemonBaseUrl:t.flags.daemonBaseUrl,session:t.flags.session},fetchImpl:t.io?.fetch});var u,d,f,p,m,h,g=c;if(!tk(g.deviceCode)||!tk(g.userCode)||!tk(g.verificationUri))throw new I("COMMAND_FAILED","Cloud auth start returned an unusable response.");let w=c.verificationUriComplete??c.verificationUri,v="local-browser"===a?c.verificationUri:(m=c.verificationUri,h=c.userCode,(s=new URL(m)).searchParams.set("user_code",h),s.toString());"local-browser"===a?(tN(t.io,`Opening ${c.verificationUri}...
|
|
12
|
+
`),await t_(w,t.io)):tN(t.io,`Open this URL on your machine:
|
|
13
|
+
${v}
|
|
14
|
+
|
|
15
|
+
Waiting for approval for 10 minutes...
|
|
16
|
+
`);let y=await t$({cloudBaseUrl:l,deviceCode:c.deviceCode,expiresIn:c.expiresIn,interval:c.interval,fetchImpl:t.io?.fetch,now:t.io?.now}),A=y.cliSession?.refreshCredential??y.cliSession?.refreshToken;if(!tk(y.accessToken)||!tk(A))throw new I("UNAUTHORIZED","Device authorization did not return CLI credentials.");let $=new Date(t.io?.now?.()??Date.now()).toISOString(),S={version:1,id:y.cliSession?.id??`cli-${Date.now().toString(36)}`,cloudBaseUrl:l,workspaceId:y.cliSession?.workspaceId,accountId:y.cliSession?.accountId,name:y.cliSession?.name,refreshCredential:A,createdAt:$,expiresAt:y.cliSession?.expiresAt};return function(t){let r=ty(t.stateDir);n.mkdirSync(e.dirname(r),{recursive:!0,mode:448}),n.writeFileSync(r,`${JSON.stringify(t.session,null,2)}
|
|
17
|
+
`,{mode:384});try{n.chmodSync(r,384)}catch{}}({stateDir:t.stateDir,session:S}),{accessToken:y.accessToken,expiresAt:y.expiresAt,session:S}}function tv(e){let t=ty(e.stateDir);if(!n.existsSync(t))return null;try{let e=JSON.parse(n.readFileSync(t,"utf8"));if(1!==e.version||!tk(e.id)||!tk(e.cloudBaseUrl)||!tk(e.refreshCredential)||!tk(e.createdAt))return null;return e}catch{return null}}function ty(t){return e.join(t,"auth","cli-session.json")}async function tI(e){let t=tv({stateDir:e.stateDir});return!t||tC(t.expiresAt,e.io?.now)?null:{accessToken:(await tA({session:t,flags:e.flags,env:e.env,io:e.io})).accessToken,cloudBaseUrl:tD(e.env,t.cloudBaseUrl)}}async function tA(e){let t=tD(e.env,e.session.cloudBaseUrl),r=await tS({baseUrl:t,pathName:"/api/control-plane/cli-session/refresh",body:{refreshCredential:e.session.refreshCredential,tenant:e.flags.tenant,runId:e.flags.runId,daemonBaseUrl:e.flags.daemonBaseUrl,session:e.flags.session},fetchImpl:e.io?.fetch});if(tk(r.accessToken))return{accessToken:r.accessToken,expiresAt:r.expiresAt};if("revoked"===r.status||"revoked"===r.error)throw new I("UNAUTHORIZED","Stored cloud CLI session was revoked.",{hint:"Run agent-device auth login again, or set AGENT_DEVICE_DAEMON_AUTH_TOKEN.",status:r.status,error:r.error});throw new I("UNAUTHORIZED","Failed to refresh CLI session.",{hint:"Run agent-device auth login again, or set AGENT_DEVICE_DAEMON_AUTH_TOKEN.",status:r.status,error:r.error})}async function t$(e){let t=e.now??Date.now,r=Math.min((e.expiresIn??600)*1e3,6e5),n=t()+r,o=Math.max(1e3,(e.interval??5)*1e3);for(;t()<n;){let t=await tS({baseUrl:e.cloudBaseUrl,pathName:"/api/control-plane/device-auth/poll",body:{deviceCode:e.deviceCode},fetchImpl:e.fetchImpl});if("approved"===t.status||tk(t.accessToken))return t;if("slow_down"===t.status||"slow_down"===t.error)o+=1e3;else if("authorization_pending"!==t.status&&"authorization_pending"!==t.error)throw new I("UNAUTHORIZED","Device authorization was not approved.",{status:t.status,error:t.error});await tR(o)}throw new I("TIMEOUT","Device authorization expired before approval.")}async function tS(e){let t=e.fetchImpl??fetch,r=await t(new URL(e.pathName,e.baseUrl),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e.body),signal:AbortSignal.timeout(15e3)}),n=await r.text(),o={};if(n.trim().length>0)try{o=JSON.parse(n)}catch(e){throw new I("COMMAND_FAILED",`Cloud auth endpoint returned invalid JSON (${r.status}).`,{status:r.status},e instanceof Error?e:void 0)}if(!r.ok)throw new I("UNAUTHORIZED","Cloud auth endpoint rejected the request.",{status:r.status,response:o});return o}function tb(e,t){let r=tD(t);return new I("UNAUTHORIZED",`${e} cannot perform interactive login in CI or a non-interactive shell.`,{hint:`Create a service/API token: ${new URL("/api-keys",r).toString()} Then set AGENT_DEVICE_DAEMON_AUTH_TOKEN=adc_live_...`})}function tD(e,t){let r=e.AGENT_DEVICE_CLOUD_BASE_URL??t??"https://cloud.agent-device.dev";try{return new URL(r).toString().replace(/\/+$/,"")}catch(e){throw new I("INVALID_ARGS","Invalid AGENT_DEVICE_CLOUD_BASE_URL.",{cloudBaseUrl:r},e instanceof Error?e:void 0)}}async function t_(e,t){if(t?.openBrowser)return void await t.openBrowser(e);let r=process.platform;try{"darwin"===r?await W("open",[e],{allowFailure:!0,timeoutMs:5e3}):"win32"===r?await W("cmd",["/c","start","",e],{allowFailure:!0,timeoutMs:5e3}):await W("xdg-open",[e],{allowFailure:!0,timeoutMs:5e3})}catch{tN(t,`Open this URL on your machine:
|
|
18
|
+
${e}
|
|
19
|
+
`)}}function tN(e,t){(e?.stderr??process.stderr).write(t)}function tC(e,t){if(!e)return!1;let r=Date.parse(e);return!Number.isFinite(r)||r<=(t?.()??Date.now())}function tk(e){return"string"==typeof e&&e.trim().length>0}async function tR(e){await new Promise(t=>setTimeout(t,e))}async function tx(t){let r=await tg({stateDir:t.stateDir,flags:t.flags,env:t.env,io:{env:t.env,fetch:t.fetchImpl}}),i=await tE({cloudBaseUrl:r.cloudBaseUrl,accessToken:r.accessToken,fetchImpl:t.fetchImpl}),a=function(e){try{return s(e)}catch(r){let t=v(r);throw new I("COMMAND_FAILED","Cloud connection profile returned invalid remote config.",{generatedConfigPath:e.configPath,cause:t.message},t)}}({configPath:function(t){var r;let s=function e(t){return Array.isArray(t)?t.map(e):t&&"object"==typeof t?Object.fromEntries(Object.entries(t).filter(([,e])=>void 0!==e).sort(([e],[t])=>e.localeCompare(t)).map(([t,r])=>[t,e(r)])):t}(t.profile),i=e.join(t.stateDir,"remote-connections","generated");n.mkdirSync(i,{recursive:!0,mode:448});let a=e.join(i,`cloud-${(r=s,o.createHash("sha256").update(JSON.stringify(r)).digest("hex").slice(0,16))}.json`);n.writeFileSync(a,`${JSON.stringify(s,null,2)}
|
|
20
|
+
`,{mode:384});try{n.chmodSync(a,384)}catch{}return a}({stateDir:t.stateDir,profile:i}),cwd:t.cwd,env:t.env});return{flags:{...eq(a.profile),...t.flags,remoteConfig:a.resolvedPath,daemonAuthToken:r.accessToken},remoteConfigPath:a.resolvedPath}}async function tE(e){let t=e.fetchImpl??fetch,r=await t(new URL("/api/control-plane/connection-profile",e.cloudBaseUrl),{method:"GET",headers:{authorization:`Bearer ${e.accessToken}`},signal:AbortSignal.timeout(15e3)}),n=await r.text(),o={};if(n.trim())try{o=JSON.parse(n)}catch(e){throw new I("COMMAND_FAILED",`Cloud connection profile endpoint returned invalid JSON (${r.status}).`,{status:r.status},e instanceof Error?e:void 0)}if(!r.ok)throw new I("UNAUTHORIZED","Cloud connection profile endpoint rejected the request.",{status:r.status,response:o});var s=o;if(!s||"object"!=typeof s||Array.isArray(s))throw new I("COMMAND_FAILED","Cloud connection profile response is invalid.");let i=s.connection;if(!i||"object"!=typeof i)throw new I("COMMAND_FAILED","Cloud connection profile response is missing profile.");if(void 0!==i.remoteConfigProfile){var a=i.remoteConfigProfile;if(!a||"object"!=typeof a||Array.isArray(a))throw new I("COMMAND_FAILED","Cloud connection profile remoteConfigProfile is invalid.");if(0===Object.keys(a).length)throw new I("COMMAND_FAILED","Cloud connection profile remoteConfigProfile is empty.");return a}throw new I("COMMAND_FAILED","Cloud connection profile did not include remoteConfigProfile.")}let tP=async({flags:e,client:t})=>{var r,n,i,a;let l=F(e.stateDir).baseDir,c=e.remoteConfig?function(e){if(!e.remoteConfig)throw new I("INVALID_ARGS","connect requires --remote-config <path>.");let t=s({configPath:e.remoteConfig,cwd:process.cwd(),env:process.env});return{flags:e,remoteConfigPath:t.resolvedPath}}(e):await tx({flags:e,stateDir:l,cwd:process.cwd(),env:process.env}),u=c.flags,d=u.tenant,f=u.runId;if(!d)throw new I("INVALID_ARGS","connect requires tenant in remote config or via --tenant <id>.");if(!f)throw new I("INVALID_ARGS","connect requires runId in remote config or via --run-id <id>.");if(!u.daemonBaseUrl)throw new I("INVALID_ARGS","connect requires daemonBaseUrl in remote config, config, env, or --daemon-base-url.");let p=u.session?null:ej({stateDir:l}),m=u.session??p?.session??function(e){for(let t=0;t<8;t+=1){let t=`adc-${o.randomBytes(3).toString("hex")}`;if(!eL({stateDir:e,session:t}))return t}return`adc-${Date.now().toString(36)}-${o.randomBytes(2).toString("hex")}`}(l),h=eO(c.remoteConfigPath),g=eU(u),w=p?.session===m?p:eL({stateDir:l,session:m});if(w&&(r=w,n={flags:u,session:m,remoteConfigPath:c.remoteConfigPath,remoteConfigHash:h,desiredLeaseBackend:e0(u),daemon:g},r.remoteConfigPath!==n.remoteConfigPath||r.remoteConfigHash!==n.remoteConfigHash||r.session!==n.session||r.tenant!==n.flags.tenant||r.runId!==n.flags.runId||void 0!==n.desiredLeaseBackend&&r.leaseBackend!==n.desiredLeaseBackend||void 0!==n.flags.platform&&r.platform!==n.flags.platform||void 0!==n.flags.target&&r.target!==n.flags.target||(i=r.daemon,a=n.daemon,(i?.baseUrl??void 0)!==(a?.baseUrl??void 0)||(i?.transport??void 0)!==(a?.transport??void 0)||(i?.serverMode??void 0)!==(a?.serverMode??void 0)))&&!u.force)throw new I("INVALID_ARGS","A different remote connection is already active for this session. Re-run connect with --force to replace it.",{session:m,remoteConfig:w.remoteConfigPath});let v=new Date().toISOString(),y={version:1,session:m,remoteConfigPath:c.remoteConfigPath,remoteConfigHash:h,daemon:g,tenant:d,runId:f,leaseId:w&&!u.force?w.leaseId:void 0,leaseBackend:w&&!u.force?w.leaseBackend:e0(u),platform:u.platform??(w&&!u.force?w.platform:void 0),target:u.target??(w&&!u.force?w.target:void 0),runtime:w&&!u.force?w.runtime:void 0,metro:w&&!u.force?w.metro:void 0,connectedAt:w&&!u.force?w.connectedAt:v,updatedAt:v};eT({stateDir:l,state:y}),w&&u.force&&(await eY(w.metro),await eX({stateDir:l,state:w}),await eQ(t,w));let A=tU(y),$=function(e,t){if(!t.runtime&&(e1(e)||tO(t.remoteConfigPath)))return tM(t.remoteConfigPath)}(u,y);return e6(u,tB(y,$),()=>[`Connected remote session "${m}" tenant "${d}" run "${f}" ${y.leaseId?`lease ${y.leaseId}`:"lease pending"}`,A?.message,$?.message].filter(e=>!!e).join("\n")),!0},tL=async({flags:e,client:t})=>{let r=e.session??"default",n=F(e.stateDir).baseDir,o=eL({stateDir:n,session:r})??(e.session?null:ej({stateDir:n}));if(!o)return e6(e,{connected:!1,session:r},()=>`No remote connection for "${r}".`),!0;let s=o.session;try{await t.sessions.close({shutdown:e.shutdown})}catch{}await eY(o.metro),await eX({stateDir:n,state:o});let i=!1;if(o.leaseId)try{i=(await t.leases.release({tenant:o.tenant,runId:o.runId,leaseId:o.leaseId})).released}catch{}return eM({stateDir:n,session:s}),e6(e,{connected:!1,session:s,released:i},()=>`Disconnected remote session "${s}".`),!0},tT=async({positionals:e,flags:t})=>{if("status"!==e[0])throw new I("INVALID_ARGS","connection accepts only: status");let r=t.session??"default",n=F(t.stateDir).baseDir,o=eL({stateDir:n,session:r})??(t.session?null:ej({stateDir:n}));if(!o)return e6(t,{connected:!1,session:r},()=>`No remote connection for "${r}".`),!0;let s=tU(o),i=function(e){if(!e.runtime&&tO(e.remoteConfigPath))return tM(e.remoteConfigPath)}(o);return e6(t,tB(o,i),()=>[`Connected remote session "${o.session}".`,`tenant=${o.tenant} runId=${o.runId} leaseId=${o.leaseId??"pending"} backend=${o.leaseBackend??"pending"}`,`remoteConfig=${o.remoteConfigPath}`,o.runtime?"metro=prepared":"metro=not-prepared",s?.message,i?.message].filter(e=>!!e).join("\n")),!0};function tU(e){if(!e.leaseId)return{status:"deferred",nextSteps:["agent-device install-from-source <artifact-url> --platform ios|android","agent-device open <app-id> --relaunch","agent-device snapshot -i","agent-device devices"],message:"Lease allocation is pending; run install-from-source, open, snapshot, or devices when ready to allocate or refresh the lease."+(void 0===e.platform&&void 0===e.leaseBackend?" Add --platform ios|android if the profile does not set a platform.":"")}}function tM(e){let t=`agent-device metro prepare --remote-config ${e}`;return{status:"deferred",nextStep:t,message:`Metro runtime is not prepared yet; it will be prepared automatically on first open, or run "${t}" to inspect it before launch.`}}function tO(e){try{let t=s({configPath:e,cwd:process.cwd(),env:process.env}).profile;return!!(t.metroPublicBaseUrl||t.metroProxyBaseUrl||t.metroProjectRoot||t.metroKind)}catch{return!1}}function tB(e,t){let r=tU(e);return{connected:!0,session:e.session,tenant:e.tenant,runId:e.runId,leaseAllocated:!!e.leaseId,leaseId:e.leaseId,leaseBackend:e.leaseBackend,platform:e.platform,target:e.target,remoteConfig:e.remoteConfigPath,remoteConfigHash:e.remoteConfigHash,daemonBaseUrlFingerprint:function(e){if(e)return o.createHash("sha256").update(e).digest("hex").slice(0,12)}(e.daemon?.baseUrl),metro:e.metro?{prepared:!0,projectRoot:e.metro.projectRoot}:{prepared:!1},...r?{leasePreparation:r}:{},...t?{runtimePreparation:t}:{},connectedAt:e.connectedAt,updatedAt:e.updatedAt}}let tV=async({positionals:e,flags:t})=>{let r=e[0]??"status",o=F(t.stateDir).baseDir;if("status"===r){var s;let e,r=(e=tv({stateDir:(s={stateDir:o}).stateDir}))?{authenticated:!0,source:"cli-session",sessionId:e.id,cloudBaseUrl:e.cloudBaseUrl,workspaceId:e.workspaceId,accountId:e.accountId,name:e.name,createdAt:e.createdAt,expiresAt:e.expiresAt,expired:tC(e.expiresAt,s.now)}:{authenticated:!1,source:"none"};return e6(t,r,()=>{var e;return(e=r).authenticated?["Authenticated with cloud CLI session.",`cloud=${e.cloudBaseUrl}`,`session=${e.sessionId}`,e.workspaceId?`workspace=${e.workspaceId}`:null,e.accountId?`account=${e.accountId}`:null,e.expiresAt?`expiresAt=${e.expiresAt}`:null,e.expired?"status=expired":null].filter(e=>!!e).join("\n"):"Not authenticated."}),!0}if("login"===r){let e=await tw({stateDir:o,flags:t,commandLabel:"agent-device auth login"});return e6(t,{authenticated:!0,source:"cli-session",sessionId:e.session.id,cloudBaseUrl:e.session.cloudBaseUrl,workspaceId:e.session.workspaceId,accountId:e.session.accountId,expiresAt:e.session.expiresAt,agentTokenExpiresAt:e.expiresAt},()=>"Authenticated with cloud CLI session."),!0}if("logout"===r){let e,r=(e=ty({stateDir:o}.stateDir),!!n.existsSync(e)&&(n.rmSync(e,{force:!0}),!0));return e6(t,{authenticated:!1,removed:r},()=>r?"Removed stored cloud CLI session.":"No stored cloud CLI session."),!0}throw new I("INVALID_ARGS","auth accepts only: status, login, logout")},tj=async({flags:e,client:t})=>{let r=O(await t.capture.snapshot({...e4(e),interactiveOnly:e.snapshotInteractiveOnly,compact:e.snapshotCompact,depth:e.snapshotDepth,scope:e.snapshotScope,raw:e.snapshotRaw}));return e6(e,r,()=>(function(e,t={}){var r,n,o,s,i,a;let l,c,u,d,f,p=e.nodes,m=Array.isArray(p)?p:[],h="string"==typeof e.backend?e.backend:void 0,g=t.raw||"macos-helper"===h?null:A(m),w=!!e.truncated,v=g?.nodes??m,y=t.raw||"macos-helper"===h?null:function(e,t,r,n){let o=e.visibility;if(o&&"object"==typeof o&&"boolean"==typeof o.partial&&"number"==typeof o.visibleNodeCount&&"number"==typeof o.totalNodeCount&&Array.isArray(o.reasons))return{partial:o.partial,visibleNodeCount:o.visibleNodeCount,totalNodeCount:o.totalNodeCount,reasons:o.reasons.filter(e=>"string"==typeof e)};let s=t?.hiddenCount??0,i=!!t&&t.nodes.some(e=>e.hiddenContentAbove||e.hiddenContentBelow);return s>0?{partial:!0,visibleNodeCount:r,totalNodeCount:n,reasons:["offscreen-nodes"]}:i?{partial:!0,visibleNodeCount:r,totalNodeCount:r,reasons:[]}:null}(e,g,v.length,m.length),I=(r=m.length,n=y,l=w?" (truncated)":"",n?.partial?n.totalNodeCount>n.visibleNodeCount?`Snapshot: ${n.visibleNodeCount} visible nodes (${n.totalNodeCount} total)${l}`:`Snapshot: ${n.visibleNodeCount} visible nodes${l}`:`Snapshot: ${r} nodes${l}`),S=(c="string"==typeof(o=e).appName?o.appName:void 0,u="string"==typeof o.appBundleId?o.appBundleId:void 0,d=[],c&&d.push(`Page: ${c}`),u&&d.push(`App: ${u}`),d.length>0?`${d.join("\n")}
|
|
21
|
+
`:""),D=(s=e,i=m,a=t,f=ek(s),!a.raw&&function(e){if(e.length<20)return!1;let t=new Map;for(let r of e){let e=(r.type??"").toLowerCase(),n=b(r).trim().toLowerCase();if(!n)continue;let o=`${e}|${n}`;t.set(o,(t.get(o)??0)+1)}let r=0;for(let e of t.values())e>1&&(r+=e);return r>=8}(i)&&f.push("Warning: possible repeated nav subtree detected."),f),_=D.length>0?`${D.join("\n")}
|
|
22
|
+
`:"";return 0===m.length?`${S}${I}
|
|
23
|
+
${_}`:t.raw?`${S}${I}
|
|
24
|
+
${_}${m.map(e=>JSON.stringify(e)).join("\n")}
|
|
25
|
+
`:t.flatten?`${S}${I}
|
|
26
|
+
${_}${$(v,{summarizeTextSurfaces:!0}).flatMap(e=>[C(e.node,0,!1,e.type,{summarizeTextSurfaces:!0}),...eR({...e,depth:0})]).join("\n")}${eI(g)}
|
|
27
|
+
`:`${S}${I}
|
|
28
|
+
${_}${(function(e){let t=[],r=[],n=e=>{for(;r.length>0&&e<=r[r.length-1].depth;)t.push(...eR(r.pop(),"below"))};for(let o of e)n(o.depth),t.push(o.text),t.push(...eR(o,"above")),o.node.hiddenContentBelow&&r.push(o);return n(0),t})($(v,{summarizeTextSurfaces:!0})).join("\n")}${eI(g)}
|
|
29
|
+
`})(r,{raw:e.snapshotRaw,flatten:e.snapshotInteractiveOnly})),!0},tG=async({positionals:e,flags:t,client:r})=>{let n=await r.capture.screenshot({path:e[0]??t.out,overlayRefs:t.overlayRefs,maxSize:t.screenshotMaxSize,...void 0!==t.screenshotFullscreen?{fullscreen:t.screenshotFullscreen}:{}});return e6(t,{path:n.path,...n.overlayRefs?{overlayRefs:n.overlayRefs}:{}},()=>n.overlayRefs?`Annotated ${n.overlayRefs.length} refs onto ${n.path}`:n.path),!0},tF=async({positionals:e,flags:r,client:n})=>{var o;if("snapshot"===e[0]){let e=await n.capture.diff({...e4(r),kind:"snapshot",out:r.out,interactiveOnly:r.snapshotInteractiveOnly,compact:r.snapshotCompact,depth:r.snapshotDepth,scope:r.snapshotScope,raw:r.snapshotRaw});return e6(r,e,()=>(function(e){var r;let n=!0===e.baselineInitialized,o=e.summary??{},s=e_(o.additions),i=e_(o.removals),a=e_(o.unchanged),l=eN(),c=ek(e),u=c.length>0?`${c.join("\n")}
|
|
30
|
+
`:"";if(n)return`${u}Baseline initialized (${a} lines).
|
|
31
|
+
`;let d=(function(e){if(0===e.length)return e;let t=e.map((e,t)=>({index:t,kind:e.kind})).filter(e=>"added"===e.kind||"removed"===e.kind).map(e=>e.index);if(0===t.length)return e;let r=Array(e.length).fill(!1);for(let n of t){let t=Math.max(0,n-1),o=Math.min(e.length-1,n+1);for(let e=t;e<=o;e+=1)r[e]=!0}return e.filter((e,t)=>r[t])})(Array.isArray(e.lines)?e.lines:[]).map(e=>{let r="string"==typeof e.text?e.text:"";if("added"===e.kind){let e=r.startsWith(" ")?`+${r}`:`+ ${r}`;return l?t("green",e):e}if("removed"===e.kind){let e=r.startsWith(" ")?`-${r}`:`- ${r}`;return l?t("red",e):e}return l?t("dim",r):r}),f=d.length>0?`${d.join("\n")}
|
|
32
|
+
`:"";if(!l)return`${u}${f}${s} additions, ${i} removals, ${a} unchanged
|
|
33
|
+
`;let p=`${(r=String(s),t("green",r))} additions, ${t("red",String(i))} removals, ${t("dim",String(a))} unchanged`;return`${u}${f}${p}
|
|
34
|
+
`})(e)),!0}if("screenshot"!==e[0])return!1;let s=r.baseline;if(!s||"string"!=typeof s)throw new I("INVALID_ARGS","diff screenshot requires --baseline <path>");let i=Z(s),a="string"==typeof r.out?Z(r.out):void 0,l=e[1];if(e.length>2)throw new I("INVALID_ARGS","diff screenshot accepts at most one current screenshot path");let c=S({backend:(o=n,{platform:function(e){switch(e.platform){case"android":case"linux":case"macos":return e.platform;default:return"ios"}}(r),captureScreenshot:async(e,t,r)=>{let n=await o.capture.screenshot({path:t,session:e.session,overlayRefs:r?.overlayRefs,fullscreen:r?.fullscreen,surface:r?.surface});return{path:n.path,...n.overlayRefs?{overlayRefs:n.overlayRefs}:{}}}}),artifacts:X(),sessions:{get:e=>({name:e}),set:()=>{}},policy:D()}),u=await c.capture.diffScreenshot({session:r.session,baseline:{kind:"path",path:i},current:l?{kind:"path",path:Z(l)}:{kind:"live"},...a?{out:{kind:"path",path:a}}:{},threshold:function(e){if(null!=e&&""!==e)return Number(e)}(r.threshold),overlayRefs:r.overlayRefs,surface:r.surface});return e6(r,u,()=>{var e,r,n,o;let s,i,a,l,c,d,f,p;return s=eN(),i=!0===u.match,a=u.dimensionMismatch,(l=[]).push(...function(e,r){if(!0===e.match){let e=r?t("green","✓"):"✓";return[`${e} Screenshots match.`]}let n=e.dimensionMismatch,o=r?t("red","✗"):"✗";if(n){let e=n.expected,t=n.actual;return[`${o} Screenshots have different dimensions: expected ${e?.width}x${e?.height}, got ${t?.width}x${t?.height}`]}let s=e_(e.differentPixels),i=e_(e.mismatchPercentage),a=0===i&&s>0?"<0.01":String(i),l=`${a}% pixels differ`;return[`${o} ${r?t("red",l):l}`]}(u,s)),l.push(...function(e,r,n){if(r)return[];let o=[];if(e.diffPath){let r=eD(e.diffPath),s=n?t("dim","Diff image:"):"Diff image:",i=n?t("green",r):r;o.push(` ${s} ${i}`)}if(e.currentOverlayPath){let r=eD(e.currentOverlayPath),s=n?t("dim","Current overlay:"):"Current overlay:",i=n?t("green",r):r,a=e_(e.currentOverlayRefCount),l=a>0?` (${a} refs)`:"";o.push(` ${s} ${i}${l}`)}return o}(u,i,s)),i||a||(l.push(...(e=u,r=s,c=e_(e.differentPixels),d=e_(e.totalPixels),f=r?t("red",String(c)):String(c),[` ${f} different / ${d} total pixels`])),l.push(...(n=u,o=s,0===(p=function(e){let t=[];for(let r of(e.ocr?.movementClusters??[]).slice(0,2))t.push(`text movement cluster: ${function(e){let t=e.slice(0,4).map(e=>JSON.stringify(e)),r=e.length>t.length?` +${e.length-t.length} more`:"";return`${t.join(", ")}${r}`}(r.texts)} dx=${eb(r.xRange)}px dy=${eb(r.yRange)}px`);let r=(e.nonTextDeltas??[]).filter(e=>["icon","toggle","chevron"].includes(e.likelyKind)).slice(0,3);r.length>0&&t.push(`non-text controls: ${r.map(eS).join("; ")}`);let n=(e.nonTextDeltas??[]).filter(e=>"separator"===e.likelyKind).slice(0,2);return n.length>0&&t.push(`non-text boundaries: ${n.map(eS).join("; ")}`),t.slice(0,6)}(n)).length?[]:[` ${eC("Hints:",o)}`,...p.map(e=>` - ${e}`)])),l.push(...function(e,t){let r=Array.isArray(e.regions)?e.regions:[];if(0===r.length)return[];let n=[` ${eC("Changed regions:",t)}`];for(let e of r.slice(0,5))n.push(...function(e){let t=0===e.shareOfDiffPercentage&&e.differentPixels>0?"<0.01":String(e.shareOfDiffPercentage),r=e.rect,n=[` ${e.index}. ${e.location} x=${r.x} y=${r.y} ${r.width}x${r.height}, ${t}% of diff, change=${e.dominantChange}`],o=function(e){let t=[e.size?`size=${e.size}`:null,e.shape?`shape=${e.shape}`:null,"number"==typeof e.densityPercentage?`density=${e.densityPercentage}%`:null,e.averageBaselineColorHex&&e.averageCurrentColorHex?`avgColor=${e.averageBaselineColorHex}->${e.averageCurrentColorHex}`:null,"number"==typeof e.baselineLuminance&&"number"==typeof e.currentLuminance?`luminance=${e.baselineLuminance}->${e.currentLuminance}`:null].filter(e=>null!==e);return t.length>0?t.join(" "):null}(e);o&&n.push(` ${o}`);let s=e.currentOverlayMatches?.[0];if(s){let e=s.label?` "${s.label}"`:"";n.push(` overlaps @${s.ref}${e}, ${s.regionCoveragePercentage}% of region`)}return n}(e));return n}(u,s)),l.push(...function(e,t){let r=e.ocr?.matches??[];if(0===r.length)return[];let n=r.slice(0,8),o=[` ${eC(`OCR text deltas (${e.ocr?.provider}; baselineBlocks=${e.ocr?.baselineBlocks} currentBlocks=${e.ocr?.currentBlocks}; showing ${n.length}/${r.length}; px):`,t)}`,` ${eC("item | text | movePx | sizeDeltaPx | bboxBaseline | bboxCurrent | confidence | issueHint",t)}`];for(let[e,t]of n.entries()){let r=t.delta;o.push(` ${e+1} | ${JSON.stringify(t.text)} | ${e$(r.x)},${e$(r.y)} | ${e$(r.width)},${e$(r.height)} | ${eA(t.baselineRect)} | ${eA(t.currentRect)} | ${t.confidence} | ${t.possibleTextMetricMismatch?"ocr-bbox-size-change":"-"}`)}return o}(u,s)),l.push(...function(e,t){let r=e.nonTextDeltas??[];if(0===r.length)return[];let n=r.slice(0,8),o=[` ${eC(`Non-text visual deltas (showing ${n.length}/${r.length}; px):`,t)}`,` ${eC("item | region | slot | kind | bboxCurrent | nearestText",t)}`];for(let e of n)o.push(` ${e.index} | ${e.regionIndex?`r${e.regionIndex}`:"-"} | ${e.slot} | ${e.likelyKind} | ${eA(e.rect)} | ${e.nearestText?JSON.stringify(e.nearestText):"-"}`);return o}(u,s))),`${l.join("\n")}
|
|
35
|
+
`}),!0},tK={[ee.wait]:async({positionals:e,flags:t,client:r})=>(e5(t,await r.command.wait(function(e,t){let r=N(e);if(!r)throw new I("INVALID_ARGS","wait requires <ms>, text <text>, @ref, or <selector> [timeoutMs].");let n={...e4(t),depth:t.snapshotDepth,scope:t.snapshotScope,raw:t.snapshotRaw};if("sleep"===r.kind)return{...n,durationMs:r.durationMs};if("text"===r.kind){if(!r.text)throw new I("INVALID_ARGS","wait requires text.");return{...n,text:r.text,...tH(r.timeoutMs)}}return"ref"===r.kind?{...n,ref:r.rawRef,...tH(r.timeoutMs)}:{...n,selector:r.selectorExpression,...tH(r.timeoutMs)}}(e,t))),!0),[ee.alert]:async({positionals:e,flags:t,client:r})=>(e5(t,await r.command.alert(function(e,t){if(e.length>2)throw new I("INVALID_ARGS","alert accepts at most action and timeout arguments.");let r=function(e){let t=e?.toLowerCase();if(void 0===t||"get"===t||"accept"===t||"dismiss"===t||"wait"===t)return t;throw new I("INVALID_ARGS","alert action must be get, accept, dismiss, or wait.")}(e[0]),n=function(e,t){if(void 0===e)return;let r=Number(e);if(Number.isFinite(r))return r;throw new I("INVALID_ARGS",`${t} must be a finite number.`)}(e[1],"alert timeout");return{...e4(t),...r?{action:r}:{},...void 0!==n?{timeoutMs:n}:{}}}(e,t))),!0),[ee.appState]:async({flags:e,client:t})=>{let r=await t.command.appState(e4(e));return e6(e,r,()=>(function(e){if("ios"===e.platform){let t=[`Foreground app: ${e.appName??e.appBundleId??"unknown"}`];return e.appBundleId&&t.push(`Bundle: ${e.appBundleId}`),e.source&&t.push(`Source: ${e.source}`),t.join("\n")}if("android"===e.platform){let t=[`Foreground app: ${e.package??"unknown"}`];return e.activity&&t.push(`Activity: ${e.activity}`),t.join("\n")}return null})(r)),!0},[ee.back]:async({flags:e,client:t})=>(e5(e,await t.command.back({...e4(e),mode:e.backMode})),!0),[ee.home]:async({flags:e,client:t})=>(e5(e,await t.command.home(e4(e))),!0),[ee.rotate]:async({positionals:e,flags:t,client:r})=>(e5(t,await r.command.rotate(function(e,t){if(e.length>1)throw new I("INVALID_ARGS","rotate accepts exactly one orientation argument.");return{...e4(t),orientation:_(e[0])}}(e,t))),!0),[ee.appSwitcher]:async({flags:e,client:t})=>(e5(e,await t.command.appSwitcher(e4(e))),!0),[ee.keyboard]:async({positionals:e,flags:t,client:r})=>(e5(t,await r.command.keyboard(function(e,t){if(e.length>1)throw new I("INVALID_ARGS","keyboard accepts at most one action argument.");let r=function(e){let t=e?.toLowerCase();if("get"===t)return"status";if(void 0===t||"status"===t||"dismiss"===t)return t;throw new I("INVALID_ARGS","keyboard action must be status, get, or dismiss.")}(e[0]);return{...e4(t),...r?{action:r}:{}}}(e,t))),!0),[ee.clipboard]:async({positionals:e,flags:t,client:r})=>{var n,o;return n=t,o=await r.command.clipboard(function(e,t){let r=e[0]?.toLowerCase();if("read"!==r&&"write"!==r)throw new I("INVALID_ARGS","clipboard requires a subcommand: read or write.");let n=e4(t);if("read"===r){if(1!==e.length)throw new I("INVALID_ARGS","clipboard read does not accept additional arguments.");return{...n,action:r}}if(e.length<2)throw new I("INVALID_ARGS","clipboard write requires text.");return{...n,action:r,text:e.slice(1).join(" ")}}(e,t)),n.json?e6(n,o):"read"===o.action?process.stdout.write(`${o.text}
|
|
36
|
+
`):e5(n,o),!0}};function tH(e){return null===e?{}:{timeoutMs:e}}function tq(t){let{suite:r,json:o,verbose:s,reportJunit:i}=t;return(i&&function(t,r){let o=e.dirname(t);try{n.mkdirSync(o,{recursive:!0}),n.writeFileSync(t,function(t){let r=['<?xml version="1.0" encoding="UTF-8"?>',"<testsuites>",` <testsuite name="agent-device replay suite" tests="${t.total}" failures="${t.failed}" skipped="${t.skipped}" time="${tW(t.durationMs)}">`];for(let n of t.tests)r.push(...function(t){let r=tZ(e.basename(t.file)),n=tZ("."===e.dirname(t.file)?t.file:e.dirname(t.file)),o=tZ(t.file),s=tW(t.durationMs),i=[` <testcase classname="${n}" name="${r}" file="${o}" time="${s}">`];"failed"===t.status?i.push(` <failure message="${tZ(t.error.message)}">${tZ(function(e){let t=[e.error.message];e.error.hint&&t.push(`hint: ${e.error.hint}`),e.error.diagnosticId&&t.push(`diagnosticId: ${e.error.diagnosticId}`),e.error.logPath&&t.push(`logPath: ${e.error.logPath}`),e.artifactsDir&&t.push(`artifactsDir: ${e.artifactsDir}`);let r=e.error.details?JSON.stringify(e.error.details,null,2):void 0;return r&&t.push(`details: ${r}`),t.join("\n")}(t))}</failure>`):"skipped"===t.status&&i.push(` <skipped message="${tZ(t.message)}" />`);let a=function(e){let t=[`status: ${e.status}`,`durationMs: ${e.durationMs}`];return"attempts"in e&&t.push(`attempts: ${e.attempts}`),"session"in e&&t.push(`session: ${e.session}`),"replayed"in e&&t.push(`replayed: ${e.replayed}`),"healed"in e&&t.push(`healed: ${e.healed}`),"artifactsDir"in e&&e.artifactsDir&&t.push(`artifactsDir: ${e.artifactsDir}`),"passed"===e.status&&e.attempts>1&&t.push("flaky: true"),t.join("\n")}(t);return a&&i.push(` <system-out>${tZ(a)}</system-out>`),i.push(" </testcase>"),i}(n));return r.push(" </testsuite>"),r.push("</testsuites>"),`${r.join("\n")}
|
|
37
|
+
`}(r),"utf8")}catch(r){let e=r instanceof Error?r.message:String(r);throw new I("COMMAND_FAILED",`Failed to write JUnit report to ${t}: ${e}`)}}(i,r),o)?(ev({success:!0,data:r}),function(e){return+(e.failed>0)}(r)):function(e,t={}){let r=e.tests.filter(tz);if(t.verbose)for(let t of e.tests)!function(e){if("failed"===e.status)return tJ(e);let t="passed"===e.status?tz(e)?"FLAKY":"PASS":"skipped"===e.status?"SKIP":"INFO",r="attempts"in e&&e.attempts>1?` after ${e.attempts} attempts`:"",n=e.durationMs>0?` (${e.durationMs}ms)`:"";process.stdout.write(`${t} ${e.file}${r}${n}
|
|
38
|
+
`),"skipped"===e.status&&process.stdout.write(` ${e.message??"skipped"}
|
|
39
|
+
`)}(t);else{for(let t of e.failures)tJ(t);for(let e of r)!function(e){let t=e.durationMs>0?` (${e.durationMs}ms)`:"";process.stdout.write(`FLAKY ${e.file} after ${e.attempts} attempts${t}
|
|
40
|
+
`)}(e)}let n="number"==typeof e.durationMs?e.durationMs:void 0,o=r.length>0?`, ${r.length} flaky`:"";return process.stdout.write(`Test summary: ${e.passed} passed, ${e.failed} failed${o}${void 0!==n?` in ${n}ms`:""}
|
|
41
|
+
`),function(e){return+(e.failed>0)}(e)}(r,{verbose:s})}function tJ(e){let t=e.attempts>1?` after ${e.attempts} attempts`:"",r=e.durationMs>0?` (${e.durationMs}ms)`:"";process.stdout.write(`FAIL ${e.file}${t}${r}
|
|
42
|
+
`),process.stdout.write(` ${e.error?.message??"Unknown test failure"}
|
|
43
|
+
`),e.error?.hint&&process.stdout.write(` hint: ${e.error.hint}
|
|
44
|
+
`),e.artifactsDir&&process.stdout.write(` artifacts: ${e.artifactsDir}
|
|
45
|
+
`),e.error?.logPath&&process.stdout.write(` log: ${e.error.logPath}
|
|
46
|
+
`),e.error?.diagnosticId&&process.stdout.write(` diagnostic: ${e.error.diagnosticId}
|
|
47
|
+
`)}function tz(e){return"passed"===e.status&&e.attempts>1}function tW(e){return(Math.max(0,e)/1e3).toFixed(3)}function tZ(e){return e.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""").replaceAll("'","'")}let tY={[ee.batch]:({data:e})=>{let t="number"==typeof e.total?e.total:0,r="number"==typeof e.executed?e.executed:0,n="number"==typeof e.totalDurationMs?e.totalDurationMs:void 0;for(let o of(process.stdout.write(`Batch completed: ${r}/${t} steps${void 0!==n?` in ${n}ms`:""}
|
|
48
|
+
`),Array.isArray(e.results)?e.results:[])){let e=function(e){var t;let r=tQ(e);if(!r)return;let n="number"==typeof r.step?r.step:void 0,o="string"==typeof r.command?r.command:"step",s=!1!==r.ok,i=tQ(r.data),a=tQ(r.error),l=s?j(i)??o:(t=a,("string"==typeof t?.message&&t.message.length>0?t.message:null)??o),c=void 0!==n?`${n}. `:"- ",u="number"==typeof r.durationMs?r.durationMs:void 0,d=void 0!==u?` (${u}ms)`:"";return`${c}${s?"OK":"FAILED"} ${l}${d}
|
|
49
|
+
`}(o);e&&process.stdout.write(e)}return!0},[ee.get]:({positionals:e,data:t})=>{var r,n;let o;return r=e,n=t,"text"===(o=r[0])?(process.stdout.write(`${"string"==typeof n.text?n.text:""}
|
|
50
|
+
`),!0):"attrs"===o&&(process.stdout.write(`${JSON.stringify(n.node??{},null,2)}
|
|
51
|
+
`),!0)},[ee.find]:({data:e})=>{var t;return"string"==typeof(t=e).text?(process.stdout.write(`${t.text}
|
|
52
|
+
`),!0):"boolean"==typeof t.found?(process.stdout.write(`Found: ${t.found}
|
|
53
|
+
`),!0):!!t.node&&(process.stdout.write(`${JSON.stringify(t.node,null,2)}
|
|
54
|
+
`),!0)},[ee.is]:({data:e})=>(process.stdout.write(`Passed: is ${e.predicate??"assertion"}
|
|
55
|
+
`),!0),[ee.boot]:({data:e})=>{let t=e.platform??"unknown",r=e.device??e.id??"unknown";return process.stdout.write(`Boot ready: ${r} (${t})
|
|
56
|
+
`),!0},[ee.record]:({data:e})=>{let t="string"==typeof e.outPath?e.outPath:"";return t&&process.stdout.write(`${t}
|
|
57
|
+
`),!0},[ee.logs]:({data:e,flags:t})=>((function(e,t){var r;let n="string"==typeof e.path?e.path:"";if(!n)return;process.stdout.write(`${n}
|
|
58
|
+
`);let o=t8(e,["active","state","backend","sizeBytes"]);o&&!t.json&&process.stderr.write(`${o}
|
|
59
|
+
`);let s=(r=e,["started","stopped","marked","cleared","restarted","removedRotatedFiles"].map(e=>{var t,n;return t=e,!0===(n=r[e])?`${t}=true`:"number"==typeof n?`${t}=${n}`:""}).filter(Boolean).join(" "));s&&!t.json&&process.stderr.write(`${s}
|
|
60
|
+
`),e.hint&&!t.json&&process.stderr.write(`${e.hint}
|
|
61
|
+
`),t.json||t4(e.notes)})(e,t),!0),[ee.network]:({data:e})=>((function(e){let t="string"==typeof e.path?e.path:"";t&&process.stdout.write(`${t}
|
|
62
|
+
`);let r=Array.isArray(e.entries)?e.entries:[];if(0===r.length)process.stdout.write("No recent HTTP(s) entries found.\n");else for(let e of r)!function(e){let t="string"==typeof e.method?e.method:"HTTP",r="string"==typeof e.url?e.url:"<unknown-url>",n="number"==typeof e.status?` status=${e.status}`:"",o="string"==typeof e.timestamp?`${e.timestamp} `:"",s="number"==typeof e.durationMs?` durationMs=${e.durationMs}`:"";process.stdout.write(`${o}${t} ${r}${n}${s}
|
|
63
|
+
`),t3("headers",e.headers),t3("request",e.requestBody),t3("response",e.responseBody)}(e);let n=t8(e,["active","state","backend","include","scannedLines","matchedLines"]);n&&process.stderr.write(`${n}
|
|
64
|
+
`),t4(e.notes)})(e),!0),[ee.click]:({data:e})=>tX(e),[ee.press]:({data:e})=>tX(e),[ee.perf]:({data:e})=>((function(e){let t=tQ(e.metrics),r=tQ(t?.fps),n=function(e){let t=[],r=tQ(e?.cpu);if(r?.available===!0){let e=t0(r.usagePercent);void 0!==e&&t.push(`CPU ${t1(e)}`)}let n=tQ(e?.memory);if(n?.available===!0){let e,r=t0(n.residentMemoryKb)??t0(n.totalPssKb)??t0(n.totalRssKb);void 0!==r&&t.push(`memory ${(e=r/1024,`${e>=10?Math.round(e):e.toFixed(1)}MB`)}`)}return t.length>0?t.join(", "):void 0}(t);if(!r)return process.stdout.write(n?`Performance: ${n}
|
|
65
|
+
`:"Frame health: unavailable - missing frame metric\n");if(!1===r.available){if(n)return process.stdout.write(`Performance: ${n}
|
|
66
|
+
`);let e="string"==typeof r.reason&&r.reason.length>0?r.reason:"not available";return process.stdout.write(`Frame health: unavailable - ${e}
|
|
67
|
+
`)}let o=t0(r.droppedFramePercent),s=t0(r.droppedFrameCount),i=t0(r.totalFrameCount);if(void 0===o||void 0===s)return process.stdout.write(n?`Performance: ${n}
|
|
68
|
+
`:"Frame health: unavailable - missing dropped-frame summary\n");let a=[`dropped ${t1(o)}`];void 0!==i?a.push(`(${Math.round(s)}/${Math.round(i)} frames)`):a.push(`(${Math.round(s)} dropped frames)`);let l=t0(r.sampleWindowMs);void 0!==l&&a.push(`window ${t2(l)}`),process.stdout.write(`Frame health: ${a.join(" ")}
|
|
69
|
+
`),function(e){var t;let r=Array.isArray(t=e.worstWindows)?t.filter(e=>!!e&&"object"==typeof e&&!Array.isArray(e)):[];if(0!==r.length)for(let e of(process.stdout.write("Worst windows:\n"),r)){let t=function(e){let t=t0(e.startOffsetMs),r=t0(e.endOffsetMs),n=t0(e.missedDeadlineFrameCount);if(void 0===t||void 0===r||void 0===n)return;let o=t0(e.worstFrameMs),s=void 0===o?"":`, worst ${t2(o)}`;return`- +${t2(t)}-+${t2(r)}: ${Math.round(n)} missed-deadline frames${s}
|
|
70
|
+
`}(e);t&&process.stdout.write(t)}}(r)})(e),!0)};function tX(e){let t=e.ref??"",r=e.x,n=e.y;return!!t&&"number"==typeof r&&"number"==typeof n&&(process.stdout.write(`Tapped @${t} (${r}, ${n})
|
|
71
|
+
`),!0)}function tQ(e){return e&&"object"==typeof e&&!Array.isArray(e)?e:void 0}function t0(e){return"number"==typeof e&&Number.isFinite(e)?e:void 0}function t1(e){return`${Number.isInteger(e)?e:e.toFixed(1)}%`}function t2(e){let t=Math.max(0,Math.round(e));if(t<1e3)return`${t}ms`;let r=Math.round(t/1e3);if(r<60)return`${r}s`;let n=Math.floor(r/60),o=r%60;return o>0?`${n}m ${o}s`:`${n}m`}function t3(e,t){"string"==typeof t&&process.stdout.write(` ${e}: ${t}
|
|
72
|
+
`)}function t8(e,t){return t.map(t=>void 0!==e[t]&&null!==e[t]?`${t}=${e[t]}`:"").filter(Boolean).join(" ")}function t4(e){if(Array.isArray(e))for(let t of e)"string"==typeof t&&t.length>0&&process.stderr.write(`${t}
|
|
73
|
+
`)}let t6={[ee.boot]:t5(ee.boot,({client:e,flags:t})=>e.devices.boot({...e4(t),headless:t.headless})),[ee.push]:t5(ee.push,({client:e,positionals:t,flags:r})=>e.apps.push({...e4(r),app:rt(t[0],"push requires bundleOrPackage"),payload:rt(t[1],"push requires payloadOrJson")})),[ee.perf]:t5(ee.perf,({client:e,flags:t})=>e.observability.perf(e4(t))),[ee.click]:t5(ee.click,({client:e,positionals:t,flags:r})=>e.interactions.click({...t7(t),...t9(r),...e4(r),count:r.count,intervalMs:r.intervalMs,holdMs:r.holdMs,jitterPx:r.jitterPx,doubleTap:r.doubleTap,button:r.clickButton})),[ee.get]:t5(ee.get,({client:e,positionals:t,flags:r})=>e.interactions.get({...function(e){if(e[0]?.startsWith("@"))return{ref:e[0],label:e.slice(1).join(" ")||void 0};let t=e.join(" ").trim();if(!t)throw new I("INVALID_ARGS","get requires @ref or selector expression");return{selector:t}}(t.slice(1)),...t9(r),...e4(r),format:function(e){if("text"===e||"attrs"===e)return e;throw new I("INVALID_ARGS","get only supports text or attrs")}(t[0])})),[ee.replay]:t5(ee.replay,({client:e,positionals:t,flags:r})=>e.replay.run({...e4(r),path:rt(t[0],"replay requires path"),update:r.replayUpdate,env:r.replayEnv})),[ee.test]:t5(ee.test,({client:e,positionals:t,flags:r})=>(({json:r.json}).json||process.stderr.write("Running replay suite...\n"),e.replay.test({...e4(r),paths:t,update:r.replayUpdate,env:r.replayEnv,failFast:r.failFast,timeoutMs:r.timeoutMs,retries:r.retries,artifactsDir:r.artifactsDir,reportJunit:r.reportJunit}))),[ee.batch]:t5(ee.batch,({client:e,flags:t})=>e.batch.run({...e4(t),steps:t.batchSteps??[],onError:t.batchOnError,maxSteps:t.batchMaxSteps,out:t.out})),[ee.press]:t5(ee.press,({client:e,positionals:t,flags:r})=>e.interactions.press({...t7(t),...t9(r),...e4(r),count:r.count,intervalMs:r.intervalMs,holdMs:r.holdMs,jitterPx:r.jitterPx,doubleTap:r.doubleTap})),[ee.longPress]:t5(ee.longPress,({client:e,positionals:t,flags:r})=>e.interactions.longPress({...e4(r),x:Number(t[0]),y:Number(t[1]),durationMs:rr(t[2])})),[ee.swipe]:t5(ee.swipe,({client:e,positionals:t,flags:r})=>e.interactions.swipe({...e4(r),from:{x:Number(t[0]),y:Number(t[1])},to:{x:Number(t[2]),y:Number(t[3])},durationMs:rr(t[4]),count:r.count,pauseMs:r.pauseMs,pattern:r.pattern})),[ee.focus]:t5(ee.focus,({client:e,positionals:t,flags:r})=>e.interactions.focus({...e4(r),x:Number(t[0]),y:Number(t[1])})),[ee.type]:t5(ee.type,({client:e,positionals:t,flags:r})=>e.interactions.type({...e4(r),text:t.join(" "),delayMs:r.delayMs})),[ee.fill]:t5(ee.fill,({client:e,positionals:t,flags:r})=>e.interactions.fill({...function(e){if(e[0]?.startsWith("@")){let t=e.length>=3?e.slice(2).join(" "):e.slice(1).join(" ");return{ref:e[0],label:e.length>=3?e[1]:void 0,text:t}}let t=er(e,{preferTrailingValue:!0});return t?{selector:t.selectorExpression,text:t.rest.join(" ")}:{x:Number(e[0]),y:Number(e[1]),text:e.slice(2).join(" ")}}(t),...t9(r),...e4(r),delayMs:r.delayMs})),[ee.scroll]:t5(ee.scroll,({client:e,positionals:t,flags:r})=>e.interactions.scroll({...e4(r),direction:function(e){if("up"===e||"down"===e||"left"===e||"right"===e)return e;throw new I("INVALID_ARGS",`Unknown direction: ${String(e)}`)}(t[0]),amount:rr(t[1]),pixels:r.pixels})),[ee.pinch]:t5(ee.pinch,({client:e,positionals:t,flags:r})=>e.interactions.pinch({...e4(r),scale:Number(t[0]),x:rr(t[1]),y:rr(t[2])})),[ee.triggerAppEvent]:t5(ee.triggerAppEvent,({client:e,positionals:t,flags:r})=>e.apps.triggerEvent({...e4(r),event:rt(t[0],"trigger-app-event requires event"),payload:t[1]?function(e,t){try{let t=JSON.parse(e);if(t&&"object"==typeof t&&!Array.isArray(t))return t}catch{}throw new I("INVALID_ARGS",`${t} must be a JSON object`)}(t[1],"trigger-app-event payload"):void 0})),[ee.record]:t5(ee.record,({client:e,positionals:t,flags:r})=>e.recording.record({...e4(r),action:re(t[0],"record"),path:t[1],fps:r.fps,quality:r.quality,hideTouches:r.hideTouches})),[ee.trace]:t5(ee.trace,({client:e,positionals:t,flags:r})=>e.recording.trace({...e4(r),action:re(t[0],"trace"),path:t[1]})),[ee.logs]:t5(ee.logs,({client:e,positionals:t,flags:r})=>e.observability.logs({...e4(r),action:function(e){if(void 0!==e){if("path"===e||"start"===e||"stop"===e||"doctor"===e||"mark"===e||"clear"===e)return e;throw new I("INVALID_ARGS","logs requires path, start, stop, doctor, mark, or clear")}}(t[0]),message:t.slice(1).join(" ")||void 0,restart:r.restart})),[ee.network]:t5(ee.network,({client:e,positionals:t,flags:r})=>e.observability.network({...e4(r),action:function(e){if(void 0!==e){if("dump"===e||"log"===e)return e;throw new I("INVALID_ARGS","network requires dump or log")}}(t[0]),limit:rr(t[1]),include:r.networkInclude??function(e){if(void 0!==e){if("summary"===e||"headers"===e||"body"===e||"all"===e)return e;throw new I("INVALID_ARGS","network include mode must be summary, headers, body, or all")}}(t[2])})),[ee.find]:t5(ee.find,({client:e,positionals:t,flags:r})=>{var n;return e.interactions.find({...function(e){let t=function(e){if("text"===e||"label"===e||"value"===e||"role"===e||"id"===e)return e}(e[0]),r=void 0!==t,n=r?e[1]:e[0],o=r?2:1,s=e[o];if(void 0===s)return{locator:t,query:rt(n,"find requires query")};if("get"===s){let r=e[o+1];if("text"===r)return{locator:t,query:rt(n,"find requires query"),action:"getText"};if("attrs"===r)return{locator:t,query:rt(n,"find requires query"),action:"getAttrs"};throw new I("INVALID_ARGS","find get only supports text or attrs")}if("wait"===s)return{locator:t,query:rt(n,"find requires query"),action:"wait",timeoutMs:rr(e[o+1])};if("fill"===s||"type"===s)return{locator:t,query:rt(n,"find requires query"),action:s,value:e.slice(o+1).join(" ")};if("click"===s||"focus"===s||"exists"===s)return{locator:t,query:rt(n,"find requires query"),action:s};throw new I("INVALID_ARGS",`Unsupported find action: ${s}`)}(t),...{depth:(n=r).snapshotDepth,raw:n.snapshotRaw},...e4(r),first:r.findFirst,last:r.findLast})}),[ee.is]:t5(ee.is,({client:e,positionals:t,flags:r})=>e.interactions.is({...function(e){let t=e[0],r=er(e.slice(1),{preferTrailingValue:"text"===t});if(!r)throw new I("INVALID_ARGS","is requires a selector expression");if("text"===t)return{predicate:t,selector:r.selectorExpression,value:r.rest.join(" ")};if("visible"===t||"hidden"===t||"exists"===t||"editable"===t||"selected"===t)return{predicate:t,selector:r.selectorExpression};throw new I("INVALID_ARGS","is requires predicate: visible|hidden|exists|editable|selected|text")}(t),...t9(r),...e4(r)})),[ee.settings]:t5(ee.settings,({client:e,positionals:t,flags:r})=>e.settings.update(function(e,t){let r=e4(t),n=e[0],o=e[1];if(("wifi"===n||"airplane"===n||"location"===n||"animations"===n)&&("on"===o||"off"===o)||"appearance"===n&&("light"===o||"dark"===o||"toggle"===o)||("faceid"===n||"touchid"===n)&&("match"===o||"nonmatch"===o||"enroll"===o||"unenroll"===o)||"fingerprint"===n&&("match"===o||"nonmatch"===o))return{...r,setting:n,state:o};if("permission"===n&&("grant"===o||"deny"===o||"reset"===o))return{...r,setting:n,state:o,permission:function(e){switch(e){case"camera":case"microphone":case"photos":case"contacts":case"contacts-limited":case"notifications":case"calendar":case"location":case"location-always":case"media-library":case"motion":case"reminders":case"siri":case"accessibility":case"screen-recording":case"input-monitoring":return e;default:throw new I("INVALID_ARGS","settings permission requires a permission target.")}}(e[2]),mode:function(e){if(void 0===e||"full"===e||"limited"===e)return e;throw new I("INVALID_ARGS","settings permission mode must be full or limited.")}(e[3])};throw new I("INVALID_ARGS","Invalid settings arguments.")}(t,r)))};function t5(e,t){return async({positionals:r,flags:n,client:o})=>{let s=await t({client:o,positionals:r,flags:n}),i=function(e,t,r,n){if(r.json){var o,s,i;return o=e,s=r,i=n,o===ee.test?tq({suite:i,json:!0,reportJunit:s.reportJunit}):(ev({success:!0,data:i}),0)}if(e===ee.test)return tq({suite:n,verbose:r.verbose,reportJunit:r.reportJunit});let a=tY[e];if(a?.({positionals:t,flags:r,data:n}))return 0;let l=j(n);return l&&process.stdout.write(`${l}
|
|
74
|
+
`),0}(e,r,n,s);return 0!==i&&process.exit(i),!0}}function t9(e){return{depth:e.snapshotDepth,scope:e.snapshotScope,raw:e.snapshotRaw}}function t7(e){if(e[0]?.startsWith("@"))return{ref:e[0],label:e.slice(1).join(" ")||void 0};let t=er(e);return t?{selector:t.selectorExpression}:{x:Number(e[0]),y:Number(e[1])}}function re(e,t){if("start"===e||"stop"===e)return e;throw new I("INVALID_ARGS",`${t} requires start|stop`)}function rt(e,t){if(void 0===e||""===e)throw new I("INVALID_ARGS",t);return e}function rr(e){return void 0===e?void 0:Number(e)}let rn={...{session:e9,[ee.devices]:e7,[ee.apps]:tn,"ensure-simulator":tt,metro:tr,install:ta,reinstall:tl,"install-from-source":tc,connect:tP,disconnect:tL,connection:tT,auth:tV,open:tf,close:tp,[ee.snapshot]:tj,[ee.screenshot]:tG,[ee.diff]:tF},...tK,...t6};async function ro(e){let t=rn[e.command];return!!t&&await t(e)}function rs(e,t,r){return r||(e.push(t),"")}async function ri(e,t,r){let{flags:n}=t,o=function(e){var t;if(!e?.metroProxyBaseUrl||"android-instance"!==(t=e.leaseBackend)&&"ios-instance"!==t)return null;let r=[],n={serverBaseUrl:rs(r,"metroProxyBaseUrl",e.metroProxyBaseUrl),bearerToken:rs(r,"metroBearerToken",e.metroBearerToken),tenantId:rs(r,"tenant",e.tenant),runId:rs(r,"runId",e.runId),leaseId:rs(r,"leaseId",e.leaseId)};if(r.length>0)throw new I("INVALID_ARGS",`react-devtools remote bridge requires ${r.join(", ")}.`,{missing:r});return n}(n);if(!o)return r();let s=t.stateDir??process.cwd(),i=t.session??n?.session??"default",a=n?.remoteConfig??`${o.tenantId}:${o.runId}:${o.leaseId}`;if("stop"===e[0])try{return await r()}finally{await eP({projectRoot:t.cwd??process.cwd(),stateDir:s,profileKey:a,consumerKey:i})}return await eE({projectRoot:t.cwd??process.cwd(),stateDir:s,serverBaseUrl:o.serverBaseUrl,bearerToken:o.bearerToken,bridgeScope:{tenantId:o.tenantId,runId:o.runId,leaseId:o.leaseId},session:i,profileKey:a,consumerKey:i,env:t.env??process.env}),await r()}async function ra(e,t={}){let r=t.cwd??process.cwd(),n=t.env??process.env,o=await ri(e,t,async()=>(await z("npm",["exec","--yes","--package","agent-react-devtools@0.4.0","--","agent-react-devtools",...e],{cwd:r,env:n,allowFailure:!0,onStdoutChunk:e=>{process.stdout.write(e)},onStderrChunk:e=>{process.stderr.write(e)}})).exitCode);var s,i=t.flags;return 0!==o&&"wait"===(s=e)[0]&&s.includes("--connected")&&"ios-instance"===i?.leaseBackend&&process.stderr.write("Hint: Remote iOS React DevTools connects during JavaScript startup.\nIf the app was already open before `agent-device react-devtools start`, relaunch it with `agent-device open <bundle-id> --platform ios --relaunch`, then retry `agent-device react-devtools wait --connected`.\n"),o}function rl(e,t={}){let r=rc(t),n={...e};return r.defaultPlatform&&void 0===n.platform&&(n.platform=r.defaultPlatform),n}function rc(e){var t,r,n,o;let s,i=e.env??process.env,a=e.inheritedPlatform??e.configuredPlatform??function(e){if(void 0===e)return;let t=e.trim().toLowerCase();if(t){if("ios"===t||"android"===t||"apple"===t)return t;throw new I("INVALID_ARGS",`Invalid AGENT_DEVICE_PLATFORM: ${e}. Use ios, android, or apple.`)}}(i.AGENT_DEVICE_PLATFORM),l="string"==typeof(t=e.configuredSession??i.AGENT_DEVICE_SESSION)&&t.trim().length>0;return{defaultPlatform:a,lockPolicy:(r=e.policyOverrides,n=i,o=l,(s=r?.sessionLock??r?.sessionLockConflicts??ru(n.AGENT_DEVICE_SESSION_LOCK)??ru(n.AGENT_DEVICE_SESSION_LOCK_CONFLICTS))||(r?.sessionLocked===!0||en(n.AGENT_DEVICE_SESSION_LOCKED)||o?"reject":void 0))}}function ru(e){if(void 0===e)return;let t=e.trim().toLowerCase();if(t){if("reject"===t||"strip"===t)return t;throw new I("INVALID_ARGS",`Invalid session lock mode: ${e}. Use reject or strip.`)}}let rd={sendToDaemon:et},rf=new Set(["launchUrl","metroBearerToken","metroKind","metroListenHost","metroNoInstallDeps","metroNoReuseExisting","metroPreparePort","metroProbeTimeoutMs","metroProjectRoot","metroProxyBaseUrl","metroPublicBaseUrl","metroRuntimeFile","metroStartupTimeoutMs","metroStatusHost"]),rp=new Set(["connect","connection","close","disconnect","ensure-simulator","metro","session"]);async function rm(t,r=rd){let o=E(),a=eo(),c=t.includes("--debug")||t.includes("--verbose")||t.includes("-v"),u=t.includes("--json"),g=function(e){for(let t=0;t<e.length;t+=1){let r=e[t];if(r.startsWith("--session=")){let e=r.slice(10).trim();return e.length>0?e:null}if("--session"===r){let r=e[t+1]?.trim();if(r&&!r.startsWith("-"))return r;break}}return null}(t)??process.env.AGENT_DEVICE_SESSION??"default";await P({session:g,requestId:o,command:t[0],debug:c},async()=>{var g,w,A,$,S,b,D,_,N,C,k,R,x,E,P,M,O;let B,V,j,G,K,H,q;try{let r,o,i,a,c,u,m,h;g={cwd:process.cwd(),env:process.env},r=function(e){let t={json:!1,help:!1,version:!1},r=null,n=[],o=[],s=!0;for(let l=0;l<e.length;l+=1){var i,a;let c=e[l];if(s&&"--"===c){s=!1;continue}if(!s){r?n.push(c):r=ew(c);continue}let u=c.startsWith("--"),d=c.startsWith("-")&&c.length>1;if(!u&&!d){r?n.push(c):r=ew(c);continue}let[m,h]=u?em(c):[c,void 0],g=f(m);if(i=r,a=g,"react-devtools"===i&&(!a||!ef(a.key,i))){n.push(c);continue}if(!g){if(function(e,t,r){var n;if(n=r,!/^-\d+(\.\d+)?$/.test(n)||!e)return!1;let o=p(e);return!o||!!o.allowsExtraPositionals||0!==o.positionalArgs.length&&(t.length<o.positionalArgs.length||o.positionalArgs.some(e=>e.includes("?")))}(r,n,c)){r?n.push(c):r=c;continue}throw new I("INVALID_ARGS",`Unknown flag: ${m}`)}let w=function(e,t,r,n){if(void 0!==e.setValue){if(void 0!==r)throw new I("INVALID_ARGS",`Flag ${t} does not take a value.`);return{value:e.setValue,consumeNext:!1}}if("boolean"===e.type){if(void 0!==r)throw new I("INVALID_ARGS",`Flag ${t} does not take a value.`);return{value:!0,consumeNext:!1}}if("booleanOrString"===e.type){if(void 0!==r){if(0===r.trim().length)throw new I("INVALID_ARGS",`Flag ${t} requires a non-empty value when provided.`);return{value:r,consumeNext:!1}}return void 0===n||eg(n)||!function(e){let t=e.trim();return!(!t||/^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(t))&&!!(t.startsWith("./")||t.startsWith("../")||t.startsWith("~/")||t.startsWith("/")||t.includes("/")||t.includes("\\"))}(n)?{value:!0,consumeNext:!1}:{value:n,consumeNext:!0}}let o=r??n;if(void 0===o||void 0===r&&eg(o))throw new I("INVALID_ARGS",`Flag ${t} requires a value.`);if("string"===e.type)return{value:o,consumeNext:void 0===r};if("enum"===e.type){if(!e.enumValues?.includes(o))throw new I("INVALID_ARGS",`Invalid ${eh(t)}: ${o}`);return{value:o,consumeNext:void 0===r}}let s=Number(o);if(!Number.isFinite(s)||"number"==typeof e.min&&s<e.min||"number"==typeof e.max&&s>e.max)throw new I("INVALID_ARGS",`Invalid ${eh(t)}: ${o}`);return{value:Math.floor(s),consumeNext:void 0===r}}(g,m,h,e[l+1]);w.consumeNext&&(l+=1);let v=t[g.key];if(g.multiple){let e=Array.isArray(v)?[...v,w.value]:void 0===v?[w.value]:[v,w.value];t[g.key]=e}else t[g.key]=w.value;o.push({key:g.key,token:m})}return{command:r,positionals:n,flags:t,warnings:[],providedFlags:o}}(t),o=g?.env??process.env,i=g?.cwd??process.cwd(),$=r.command,a=null!==$&&(w={remoteConfig:r.flags.remoteConfig,cwd:i,env:o}).remoteConfig?{...eq(s({configPath:w.remoteConfig,cwd:w.cwd,env:w.env}).profile),remoteConfig:w.remoteConfig}:{},m=ea((c=(A={command:r.command,cwd:i,cliFlags:r.flags,env:o}).env??process.env,u=ea({},function(e){let t={};for(let r of e)ea(t,function(e,t){let r,o;if(!n.existsSync(e)){if(t)throw new I("INVALID_ARGS",`Config file not found: ${e}`);return{}}try{r=n.readFileSync(e,"utf8")}catch(t){throw new I("INVALID_ARGS",`Failed to read config file: ${e}`,{cause:t instanceof Error?t.message:String(t)})}try{o=JSON.parse(r)}catch(t){throw new I("INVALID_ARGS",`Invalid JSON in config file: ${e}`,{cause:t instanceof Error?t.message:String(t)})}if(!o||"object"!=typeof o||Array.isArray(o))throw new I("INVALID_ARGS",`Config file must contain a JSON object: ${e}`);return function(e,t){let r={};for(let[n,o]of Object.entries(e)){if("installSource"===n){r.installSource=function(e,t){if(!e||"object"!=typeof e||Array.isArray(e))throw new I("INVALID_ARGS",`${t} installSource must be an object.`);if("github-actions-artifact"!==ti(e.type,`${t} installSource.type`))throw new I("INVALID_ARGS",`${t} installSource.type must be "github-actions-artifact".`);let{owner:r,repo:n}=ts(ti(e.repo,`${t} installSource.repo`),`${t} installSource.repo`);return to(r,n,e.artifact,`${t} installSource.artifact`)}(o,t);continue}let e=ed.get(n);if(!e)throw new I("INVALID_ARGS",`Unknown config key "${n}" in ${t}.`);if(!e.config.enabled)throw new I("INVALID_ARGS",`Unsupported config key "${n}" in ${t}.`);r[n]=l(ep(e),o,t,n)}return r}(o,`config file ${e}`)}(r.path,r.required));return t}((S=A.cwd,b=A.cliFlags.config,D=c,(h=b??D.AGENT_DEVICE_CONFIG)?[{path:(_=h,N=S,C=D,Z(_,{cwd:N,env:C})),required:!0}]:[{path:(k=D,e.join(Y("~",{env:k}),".agent-device","config.json")),required:!1},{path:e.resolve(S,"agent-device.json"),required:!1}]))),ea(u,function(e,t){var r,n,o;let s={};for(let i of eu.filter(e=>e.config.enabled&&e.supportsCommand(t))){if("installSource"===i.key)continue;let t=i.env.names.map(t=>({name:t,value:e[t]})).find(e=>"string"==typeof e.value&&e.value.trim().length>0);t&&(s[i.key]=(r=t.value,n=`environment variable ${t.name}`,o=t.name,l(ep(i),r,n,o)))}return s}(c,A.command))),a),B={...function(e,t){let r=t?.strictFlags??d(process.env.AGENT_DEVICE_STRICT_FLAGS),n=[...e.warnings],o=ea({json:!1,help:!1,version:!1},t?.defaultFlags??{});ea(o,e.flags);let s=p(e.command),i=e.providedFlags.filter(t=>!ef(t.key,e.command));if(i.length>0){var a,l;let t=i.map(e=>e.token),s=(a=e.command,l=t,a?1===l.length?`Flag ${l[0]} is not supported for command ${a}.`:`Flags ${l.join(", ")} are not supported for command ${a}.`:1===l.length?`Flag ${l[0]} requires a command that supports it.`:`Flags ${l.join(", ")} require a command that supports them.`);if(r)throw new I("INVALID_ARGS",s);for(let e of(n.push(`${s} Enable AGENT_DEVICE_STRICT_FLAGS=1 to fail fast.`),i))delete o[e.key]}for(let t of Object.keys(o))void 0!==o[t]&&(ef(t,e.command)||delete o[t]);if(function(e){if("back"===e.command&&!(new Set(e.providedFlags.filter(e=>"backMode"===e.key).map(e=>e.token)).size<=1))throw new I("INVALID_ARGS","back accepts only one explicit mode flag: use either --in-app or --system.")}(e),s?.defaults)for(let[e,t]of Object.entries(s.defaults))void 0===o[e]&&(o[e]=t);if("batch"===e.command&&1!=+!!o.steps+ +!!o.stepsFile)throw new I("INVALID_ARGS","batch requires exactly one step source: --steps or --steps-file.");return function(e){if(e.flags.help)return e;if("snapshot"===e.command&&e.flags.snapshotDiff){let{snapshotDiff:t,...r}=e.flags;return{command:"diff",positionals:["snapshot",...e.positionals],flags:r,warnings:e.warnings}}return e}({command:e.command,positionals:e.positionals,flags:o,warnings:n})}(r,{strictFlags:g?.strictFlags,defaultFlags:m}),providedFlags:r.providedFlags}}catch(t){U({level:"error",phase:"cli_parse_failed",data:{error:t instanceof Error?t.message:String(t)}});let e=y(t,{diagnosticId:L().diagnosticId,logPath:T({force:!0})??void 0});u?ev({success:!1,error:e}):ey(e,{showDetails:c}),process.exit(1);return}for(let e of B.warnings)process.stderr.write(`Warning: ${e}
|
|
75
|
+
`);B.flags.version&&(process.stdout.write(`${a}
|
|
76
|
+
`),process.exit(0));let J="help"===B.command,z=B.flags.help;if(J||z){J&&B.positionals.length>1&&(ey(new I("INVALID_ARGS","help accepts at most one command.")),process.exit(1));let e=J?B.positionals[0]:B.command;e||(process.stdout.write(`${h()}
|
|
77
|
+
`),process.exit(0));let t=m(ew(e));t&&(process.stdout.write(t),process.exit(0)),ey(new I("INVALID_ARGS",`Unknown command: ${e}`)),process.stdout.write(`${h()}
|
|
78
|
+
`),process.exit(1)}B.command||(process.stdout.write(`${h()}
|
|
79
|
+
`),process.exit(1));let{command:W,positionals:X}=B,ee=new Set(B.providedFlags.map(e=>e.key));try{j=(V=rc({policyOverrides:B.flags,configuredPlatform:B.flags.platform,configuredSession:B.flags.session})).lockPolicy?{...B.flags}:rl(B.flags,{policyOverrides:B.flags,configuredPlatform:B.flags.platform,configuredSession:B.flags.session}),G=F(j.stateDir),K=j.session??"default",R={command:W,explicitFlagKeys:ee,stateDir:G.baseDir,session:K,remoteConfig:j.remoteConfig,hasResolvedSession:void 0!==j.session},q=(H="connect"===R.command||"connection"===R.command?null:function(e){let t=e.validateRemoteConfigHash??!0,r=e.remoteConfig?i({configPath:e.remoteConfig,cwd:e.cwd,env:e.env}):void 0,n=eL(e)??(e.allowActiveFallback?ej({stateDir:e.stateDir}):null);if(!n||r&&n.remoteConfigPath!==r)return null;if(t&&eO(n.remoteConfigPath)!==n.remoteConfigHash)throw new I("INVALID_ARGS","Active remote connection config changed. Run agent-device connect --force to refresh it.",{remoteConfig:n.remoteConfigPath});let o=function(e,t){try{return s({configPath:e.remoteConfigPath,cwd:t.cwd,env:t.env}).profile}catch(e){if(!1===t.validateRemoteConfigHash)return{};throw e}}(n,e);return{runtime:n.runtime,flags:{...o,remoteConfig:n.remoteConfigPath,daemonBaseUrl:n.daemon?.baseUrl??o.daemonBaseUrl,daemonTransport:n.daemon?.transport??o.daemonTransport,daemonServerMode:n.daemon?.serverMode??o.daemonServerMode,tenant:n.tenant,sessionIsolation:"tenant",runId:n.runId,leaseId:n.leaseId,leaseBackend:n.leaseBackend,session:n.session,platform:n.platform??o.platform,target:n.target??o.target}}}({stateDir:R.stateDir,session:R.session,remoteConfig:R.remoteConfig,cwd:process.cwd(),env:process.env,allowActiveFallback:!R.explicitFlagKeys.has("session")&&(!R.remoteConfig||"disconnect"===R.command||!R.hasResolvedSession),validateRemoteConfigHash:"disconnect"!==R.command}))?function(e,t,r){let n={...e};for(let[e,o]of Object.entries(t))void 0!==o&&(r.has(e)||(n[e]=o));return n}(j,H.flags,ee):j}catch(t){let e=y(v(t),{diagnosticId:L().diagnosticId,logPath:T({force:!0})??void 0});B.flags.json?ev({success:!1,error:e}):ey(e,{showDetails:B.flags.verbose}),process.exit(1);return}let et=null;try{let e;if("react-devtools"===W){let e=await ra(X,{flags:q,stateDir:G.baseDir,session:q.session??K,cwd:process.cwd(),env:process.env});process.exit(e);return}ei({command:W,currentVersion:a,stateDir:G.baseDir,flags:q});let t=H?.runtime,s=(e,t)=>({session:e.session??K,requestId:o,stateDir:e.stateDir,daemonBaseUrl:e.daemonBaseUrl,daemonAuthToken:e.daemonAuthToken,daemonTransport:e.daemonTransport,daemonServerMode:e.daemonServerMode,tenant:e.tenant,sessionIsolation:e.sessionIsolation,runId:e.runId,leaseId:e.leaseId,leaseBackend:e.leaseBackend,runtime:t,lockPolicy:V.lockPolicy,lockPlatform:V.defaultPlatform,cwd:process.cwd(),debug:!!e.verbose});if("batch"===W){if(X.length>0)throw new I("INVALID_ARGS","batch does not accept positional arguments.");e=function(e){let t="";if(e.steps)t=e.steps;else if(e.stepsFile)try{t=n.readFileSync(e.stepsFile,"utf8")}catch(r){let t=r instanceof Error?r.message:String(r);throw new I("INVALID_ARGS",`Failed to read --steps-file ${e.stepsFile}: ${t}`)}return es(t)}(j)}if(x=W,"auth"!==x&&"connection"!==x&&(q=(await tm({command:W,flags:q,stateDir:G.baseDir,env:process.env})).flags),q.remoteConfig&&(E=W,!rp.has(E))){let n=Q(s(q,t),{transport:r.sendToDaemon}),o=await eW({command:W,flags:q,client:n,runtime:t,batchSteps:e,forceRuntimePrepare:function(e){for(let t of rf)if(e.has(t))return!0;return!1}(ee)});q=o.flags,t=o.runtime}P={command:W,flags:q,runtime:t,explicitFlagKeys:ee,hadConnectionDefaults:!!H},!("open"===P.command&&!P.runtime&&!P.flags.bundleUrl&&!P.flags.metroHost&&!P.flags.metroPort&&!P.flags.remoteConfig&&!P.hadConnectionDefaults&&((M=P.explicitFlagKeys).has("daemonBaseUrl")||M.has("daemonTransport")||M.has("tenant")||M.has("sessionIsolation")||M.has("runId")||M.has("leaseId")||M.has("leaseBackend")))||process.stderr.write("Warning: open is using explicit remote daemon or tenant flags without saved Metro runtime hints. React Native apps may launch without bundle/runtime hints; prefer connect --remote-config <path> first or pass --remote-config <path> on this command.\n");let i=q.daemonBaseUrl;et=!q.verbose||q.json||i?null:function(e){try{let t=0,r=!1,o=setInterval(()=>{if(!r&&n.existsSync(e))try{let r=n.statSync(e);if(r.size<t&&(t=0),r.size<=t)return;let o=n.openSync(e,"r");try{let e=Buffer.alloc(r.size-t);n.readSync(o,e,0,e.length,t),t=r.size,e.length>0&&process.stdout.write(e.toString("utf8"))}finally{n.closeSync(o)}}catch{}},200);return()=>{r=!0,clearInterval(o)}}catch{return null}}(G.logPath);let l=Q(s(q,t),{transport:r.sendToDaemon});if("batch"===W){if(!e)throw new I("INVALID_ARGS","batch requires --steps or --steps-file.");let t=e.map((e,t)=>({...e,flags:V.lockPolicy&&void 0===j.platform?{...e.flags??{}}:rl(e.flags??{},{policyOverrides:q,configuredPlatform:q.platform,configuredSession:q.session,inheritedPlatform:q.platform})}));if(await ro({command:W,positionals:X,flags:{...q,batchSteps:t},client:l}))return}else if("runtime"===W)throw new I("INVALID_ARGS","runtime command was removed. Use connect --remote-config <path> for remote runs, or metro prepare --remote-config <path> for inspection.");else if(await ro({command:W,positionals:X,flags:q,client:l}))return;throw new I("INVALID_ARGS",`Unknown command: ${W}`)}catch(r){let e=v(r),t=y(e,{diagnosticId:L().diagnosticId,logPath:T({force:!0})??void 0});if("close"===W&&"COMMAND_FAILED"===(O=e).code&&(O.details?.kind==="daemon_startup_failed"||O.message.toLowerCase().includes("failed to start daemon")&&("string"==typeof O.details?.infoPath||"string"==typeof O.details?.lockPath))){q.json&&ev({success:!0,data:{closed:"session",source:"no-daemon"}});return}if(q.json)ev({success:!1,error:t});else if(ey(t,{showDetails:q.verbose}),q.verbose)try{let e=G.logPath;if(n.existsSync(e)){let t=n.readFileSync(e,"utf8").split("\n"),r=t.slice(Math.max(0,t.length-200)).join("\n");r.trim().length>0&&process.stderr.write(`
|
|
80
|
+
[daemon log]
|
|
81
|
+
${r}
|
|
82
|
+
`)}}catch{}et&&et(),process.exit(1)}finally{et&&et()}})}r(process.argv[1]??"").href===import.meta.url&&rm(process.argv.slice(2)).catch(e=>{ey(y(v(e)),{showDetails:!0}),process.exit(1)});export{rm as runCli};
|