agent-device 0.17.0 → 0.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.17.0.apk → agent-device-android-multitouch-helper-0.17.1.apk} +0 -0
- package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.17.1.apk.sha256 +1 -0
- package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.17.0.manifest.json → agent-device-android-multitouch-helper-0.17.1.manifest.json} +4 -4
- package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.17.0.apk → agent-device-android-snapshot-helper-0.17.1.apk} +0 -0
- package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.17.1.apk.sha256 +1 -0
- package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.17.0.manifest.json → agent-device-android-snapshot-helper-0.17.1.manifest.json} +6 -6
- package/dist/src/1352.js +1 -1
- package/dist/src/2415.js +29 -29
- package/dist/src/8699.js +1 -1
- package/dist/src/9238.js +3 -3
- package/dist/src/9542.js +3 -3
- package/dist/src/apple.js +1 -1
- package/dist/src/apps.js +1 -1
- package/dist/src/args.js +1 -1
- package/dist/src/command-metadata.js +1 -1
- package/dist/src/generic.js +13 -11
- package/dist/src/index.d.ts +1 -0
- package/dist/src/interaction.js +1 -1
- package/dist/src/record-trace-recording.js +26 -0
- package/dist/src/record-trace.js +1 -26
- package/dist/src/session.js +10 -10
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +6 -2
- package/package.json +2 -2
- package/server.json +2 -2
- package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.17.0.apk.sha256 +0 -1
- package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.17.0.apk.sha256 +0 -1
package/dist/src/8699.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{screenshotFlagsFromOptions as e}from"./5310.js";import{AppError as t}from"./9152.js";import{readRequiredString as r,readRequiredPlatform as i,readRequiredDeviceKind as a,readNullableString as n,readDeviceTarget as o,readRect as s,asRecord as l,stripUndefined as u,isRecord as c,readRequiredNumber as d,readPoint as p,readOptionalString as f}from"./7455.js";import{buildAppIdentifiers as m,buildDeviceIdentifiers as h}from"./6232.js";import{INTERNAL_COMMANDS as g,BATCH_COMMAND_NAMES as y,PUBLIC_COMMANDS as v}from"./5792.js";import{assertResolvedAppsFilter as S}from"./1393.js";import{request as w,selectorSnapshotOptionsFromFlags as A,direct as b,requiredString as I,commonInputFromFlags as _,optionalString as N,readJsonObject as R,optionalNumber as M,optionalCliNumber as x,selectionOptionsFromFlags as k,commandNameSet as D,captureDaemonWriters as L,requiredDaemonString as C,splitRequiredSelector as P}from"./6085.js";import{isPerfAction as q,PERF_AREA_ERROR_MESSAGE as V,PERF_ACTION_ERROR_MESSAGE as G,isPerfArea as E}from"./8020.js";import{parseDeviceRotation as U}from"./1998.js";import{compactRecord as $}from"./9404.js";import{interactionDaemonWriters as z}from"./8502.js";function K(e,t){let a=f(e,"bundleId"),n=f(e,"package");return{app:r(e,"app"),appPath:r(e,"appPath"),platform:i(e,"platform"),appId:a??n,bundleId:a,package:n,identifiers:m({session:t,bundleId:a,packageName:n})}}function T(e,r){let i=f(e,"bundleId"),a=f(e,"packageName"),n=i??a??f(e,"appId"),o=f(e,"launchTarget")??a??i??n;if(!o)throw new t("COMMAND_FAILED",'Daemon response is missing "launchTarget".',{response:e});return{appName:f(e,"appName"),appId:n,bundleId:i,packageName:a,launchTarget:o,installablePath:f(e,"installablePath"),archivePath:f(e,"archivePath"),materializationId:f(e,"materializationId"),materializationExpiresAt:f(e,"materializationExpiresAt"),identifiers:m({session:r,bundleId:i,packageName:a,appId:n})}}function F(e){return{released:!0===e.released,materializationId:r(e,"materializationId"),identifiers:{}}}function B(e){let{record:t,platform:r,id:i,name:n,target:o}=H(e,"name");return{platform:r,target:o,kind:a(t,"kind"),id:i,name:n,booted:"boolean"==typeof t.booted?t.booted:void 0,identifiers:h(r,i,n),...j(r,i)}}function O(e){let{record:t,platform:i,id:a,name:o,target:s}=H(e,"name"),l=r(t,"device"),u={session:o,...h(i,a,l)};return{name:o,createdAt:d(t,"createdAt"),sessionStateDir:f(t,"sessionStateDir"),runnerLogPath:f(t,"runnerLogPath"),device:{platform:i,target:s,id:a,name:l,identifiers:u,...j(i,a,n(t,"ios_simulator_device_set"))},identifiers:u}}function H(e,t){let a=l(e);return{record:a,platform:i(a,"platform"),id:r(a,"id"),name:r(a,t),target:o(a,"target")}}function j(e,t,r){return{ios:"ios"===e?{udid:t,...void 0!==r?{simulatorSetPath:r}:{}}:void 0,android:"android"===e?{serial:t}:void 0}}function J(e){if(!c(e))return;let t=e.platform,r=f(e,"metroHost"),i="number"==typeof e.metroPort?e.metroPort:void 0;return{platform:"ios"===t||"android"===t?t:void 0,metroHost:r,metroPort:i,bundleUrl:f(e,"bundleUrl"),launchUrl:f(e,"launchUrl")}}function W(e){let t=e.platform,r=f(e,"id"),i=f(e,"device");if("ios"!==t&&"macos"!==t&&"android"!==t&&"linux"!==t||!r||!i)return;let a=o(e,"target"),s=h(t,r,i);return{platform:t,target:a,id:r,name:i,identifiers:s,ios:"ios"===t?{udid:f(e,"device_udid")??r,simulatorSetPath:n(e,"ios_simulator_device_set")}:void 0,android:"android"===t?{serial:f(e,"serial")??r}:void 0}}function Q(e){if(c(e)&&"number"==typeof e.durationMs&&"string"==typeof e.measuredAt&&"string"==typeof e.method)return{durationMs:e.durationMs,measuredAt:e.measuredAt,method:e.method,appTarget:f(e,"appTarget"),appBundleId:f(e,"appBundleId")}}function X(e){return Array.isArray(e)?e:[]}function Y(e){let t=e.overlayRefs;if(!Array.isArray(t))return;let r=[];for(let e of t){if(!c(e))continue;let t=f(e,"ref"),i=s(e,"rect"),a=s(e,"overlayRect"),n=p(e,"center");t&&i&&a&&n&&r.push({ref:t,label:f(e,"label"),rect:i,overlayRect:a,center:n})}return r}function Z(t){return u({stateDir:t.stateDir,daemonBaseUrl:t.daemonBaseUrl,daemonAuthToken:t.daemonAuthToken,daemonTransport:t.daemonTransport,daemonServerMode:t.daemonServerMode,tenant:t.tenant,sessionIsolation:t.sessionIsolation,runId:t.runId,leaseId:t.leaseId,leaseBackend:t.leaseBackend,platform:t.platform,target:t.target,device:t.device,udid:t.udid,serial:t.serial,iosSimulatorDeviceSet:t.iosSimulatorDeviceSet,androidDeviceAllowlist:t.androidDeviceAllowlist,surface:t.surface,activity:t.activity,launchConsole:t.launchConsole,launchArgs:t.launchArgs,relaunch:t.relaunch,shutdown:t.shutdown,saveScript:t.saveScript,noRecord:t.noRecord,backMode:t.backMode,metroHost:t.metroHost,metroPort:t.metroPort,bundleUrl:t.bundleUrl,launchUrl:t.launchUrl,snapshotInteractiveOnly:t.interactiveOnly,snapshotCompact:t.compact,snapshotDepth:t.depth,snapshotScope:t.scope,snapshotRaw:t.raw,snapshotForceFull:t.forceFull,...e(t),appsFilter:t.appsFilter,out:t.out,count:t.count,fps:t.fps,quality:t.quality,hideTouches:t.hideTouches,intervalMs:t.intervalMs,delayMs:t.delayMs,holdMs:t.holdMs,jitterPx:t.jitterPx,pixels:t.pixels,doubleTap:t.doubleTap,clickButton:t.clickButton,pauseMs:t.pauseMs,pattern:t.pattern,headless:t.headless,restart:t.restart,replayUpdate:t.replayUpdate,replayBackend:t.replayBackend,replayEnv:t.replayEnv,replayShellEnv:t.replayShellEnv,failFast:t.failFast,timeoutMs:t.timeoutMs,retries:t.retries,artifactsDir:t.artifactsDir,reportJunit:t.reportJunit,shardAll:t.shardAll,shardSplit:t.shardSplit,findFirst:t.findFirst,findLast:t.findLast,networkInclude:t.networkInclude,batchOnError:t.batchOnError,batchMaxSteps:t.batchMaxSteps,batchSteps:t.batchSteps,verbose:t.debug})}function ee(e){return u({requestId:e.requestId,cwd:e.cwd,sessionExplicit:void 0!==e.session,debug:e.debug,lockPolicy:e.lockPolicy,lockPlatform:e.lockPlatform,tenantId:e.tenant,runId:e.runId,leaseId:e.leaseId,leaseBackend:e.leaseBackend,leaseTtlMs:e.leaseTtlMs,sessionIsolation:e.sessionIsolation,installSource:e.installSource,retainMaterializedPaths:e.retainMaterializedPaths,materializedPathRetentionMs:e.materializedPathRetentionMs,materializationId:e.materializationId})}function et(e){return e??"default"}function er(e,r){if(!e||"object"!=typeof e||Array.isArray(e))throw new t("INVALID_ARGS",`${r} installSource must be an object.`);if("github-actions-artifact"!==en(e.type,`${r} installSource.type`))throw new t("INVALID_ARGS",`${r} installSource.type must be "github-actions-artifact".`);let{owner:i,repo:a}=ea(en(e.repo,`${r} installSource.repo`),`${r} installSource.repo`);return ei(i,a,e.artifact,`${r} installSource.artifact`)}function ei(e,r,i,a){var n;return"number"==typeof i||"string"==typeof(n=i)&&/^\d+$/.test(n.trim())?{kind:"github-actions-artifact",owner:e,repo:r,artifactId:function(e,r){let i="number"==typeof e?e:"string"==typeof e?Number(e):NaN;if(!Number.isInteger(i))throw new t("INVALID_ARGS",`${r} must be an integer.`);return i}(i,a)}:{kind:"github-actions-artifact",owner:e,repo:r,artifactName:en(i,a)}}function ea(e,r){let i=e.indexOf("/");if(i<=0||i===e.length-1||-1!==e.indexOf("/",i+1))throw new t("INVALID_ARGS",`${r} must use owner/repo.`);let a={owner:e.slice(0,i).trim(),repo:e.slice(i+1).trim()};if(!a.owner||!a.repo)throw new t("INVALID_ARGS",`${r} must use owner/repo.`);return a}function en(e,r){let i="string"==typeof e&&e.trim().length>0?e.trim():void 0;if(!i)throw new t("INVALID_ARGS",`${r} must be a non-empty string.`);return i}let eo={devices:(e,t)=>_(t),apps:(e,t)=>({..._(t),appsFilter:S(t.appsFilter)}),session:(e,r)=>({..._(r),action:function(e){let r=e??"list";if("list"===r)return r;throw new t("INVALID_ARGS","session only supports list")}(e[0])}),boot:(e,t)=>({..._(t),headless:t.headless}),prepare:(e,t)=>({..._(t),action:I(e[0],"prepare requires subcommand"),timeoutMs:t.timeoutMs}),open:(e,t)=>({..._(t),app:e[0],url:e[1],surface:t.surface,activity:t.activity,launchConsole:t.launchConsole,launchArgs:t.launchArgs,relaunch:t.relaunch,saveScript:t.saveScript,noRecord:t.noRecord}),close:(e,t)=>({..._(t),app:e[0],shutdown:t.shutdown,saveScript:t.saveScript}),install:el,reinstall:el,"install-from-source":(e,r)=>({..._(r),source:function(e,r){let i=e[0]?.trim();if(e.length>1)throw new t("INVALID_ARGS","install-from-source accepts either one <url> positional or --github-actions-artifact");let a=r.githubActionsArtifact?function(e,r="--github-actions-artifact"){let i=e.indexOf(":");if(i<=0||i===e.length-1)throw new t("INVALID_ARGS",`${r} must use owner/repo:artifact, for example thymikee/RNCLI83:6635342232`);let{owner:a,repo:n}=ea(e.slice(0,i),r);return ei(a,n,e.slice(i+1),`${r} artifact`)}(r.githubActionsArtifact):void 0,n=r.installSource;if(1!=+!!i+ +!!a+ +!!n)throw new t("INVALID_ARGS","install-from-source requires exactly one source: <url>, --github-actions-artifact, or config installSource");if(!i&&r.header&&r.header.length>0)throw new t("INVALID_ARGS","install-from-source --header is only supported for URL sources");return a||n||{kind:"url",url:i,headers:function(e){if(!e||0===e.length)return;let r={};for(let i of e){let e=i.indexOf(":");if(e<=0)throw new t("INVALID_ARGS",`Invalid --header value "${i}". Expected "name:value".`);let a=i.slice(0,e).trim(),n=i.slice(e+1).trim();if(!a)throw new t("INVALID_ARGS",`Invalid --header value "${i}". Header name cannot be empty.`);r[a]=n}return r}(r.header)}}(e,r),retainPaths:r.retainPaths,retentionMs:r.retentionMs}),push:(e,t)=>({..._(t),app:I(e[0],"push requires bundleOrPackage"),payload:I(e[1],"push requires payloadOrJson")}),"trigger-app-event":(e,t)=>({..._(t),event:I(e[0],"trigger-app-event requires event"),payload:e[1]?R(e[1],"trigger-app-event payload"):void 0})},es={devices:b(v.devices),boot:b(v.boot),prepare:b(v.prepare,e=>[C(e.action,"prepare requires subcommand")]),apps:b(v.apps),open:b(v.open,function(e){return e.app?e.url?[e.app,e.url]:[e.app]:[]}),close:b(v.close,e=>N(e.app)),install:b(v.install,e=>eu(e.app,e.appPath)),reinstall:b(v.reinstall,e=>eu(e.app,e.appPath)),"install-from-source":e=>w(g.installSource,[],{...e,installSource:e.source,retainMaterializedPaths:e.retainPaths,materializedPathRetentionMs:e.retentionMs}),push:b(v.push,e=>{var t;return[(t=e).app,"string"==typeof t.payload?t.payload:JSON.stringify(t.payload)]}),"trigger-app-event":b(v.triggerAppEvent,e=>{var t;return[(t=e).event,...t.payload?[JSON.stringify(t.payload)]:[]]})};function el(e,t,r="install"){return{..._(t),app:I(e[0],`${r} requires app`),appPath:I(e[1],`${r} requires path`)}}function eu(e,t){return[C(e,"missing first positional"),C(t,"missing second positional")]}let ec={gesture:function(e,r){let i=e[0],a=e.slice(1),n=_(r);switch(i){case"pan":return{...n,kind:i,origin:{x:Number(a[0]),y:Number(a[1])},delta:{x:Number(a[2]),y:Number(a[3])},durationMs:x(a[4])};case"fling":return{...n,kind:i,direction:a[0],origin:{x:Number(a[1]),y:Number(a[2])},distance:x(a[3]),durationMs:x(a[4])};case"swipe":return{...n,kind:i,preset:a[0],durationMs:x(a[1])};case"pinch":return{...n,kind:i,scale:Number(a[0]),origin:void 0===a[1]||void 0===a[2]?void 0:{x:Number(a[1]),y:Number(a[2])}};case"rotate":return{...n,kind:i,degrees:Number(a[0]),origin:void 0===a[1]||void 0===a[2]?void 0:{x:Number(a[1]),y:Number(a[2])},velocity:x(a[3])};case"transform":return{...n,kind:i,origin:{x:Number(a[0]),y:Number(a[1])},delta:{x:Number(a[2]),y:Number(a[3])},scale:Number(a[4]),degrees:Number(a[5]),durationMs:x(a[6])};default:throw new t("INVALID_ARGS","gesture requires pan, fling, swipe, pinch, rotate, or transform")}}},ed={gesture:b(v.gesture,function(e){switch(e.kind){case"pan":return["pan",String(e.origin?.x),String(e.origin?.y),String(e.delta?.x),String(e.delta?.y),...M(e.durationMs)];case"fling":return["fling",C(e.direction,"gesture fling requires direction"),String(e.origin?.x),String(e.origin?.y),...M(e.distance),...M(e.durationMs)];case"swipe":return ep(e);case"pinch":return["pinch",String(e.scale),...M(e.origin?.x),...M(e.origin?.y)];case"rotate":return["rotate",String(e.degrees),...M(e.origin?.x),...M(e.origin?.y),...M(e.velocity)];case"transform":return["transform",String(e.origin?.x),String(e.origin?.y),String(e.delta?.x),String(e.delta?.y),String(e.scale),String(e.degrees),...M(e.durationMs)];default:throw new t("INVALID_ARGS","gesture requires pan, fling, swipe, pinch, rotate, or transform")}}),"gesture-pan":b(v.gesture,function(e){return["pan",String(e.x),String(e.y),String(e.dx),String(e.dy),...M(e.durationMs)]}),"gesture-fling":b(v.gesture,e=>{var t;let r;return r=void 0!==(t=e).durationMs?t.distance??180:t.distance,["fling",t.direction,String(t.x),String(t.y),...M(r),...M(t.durationMs)]}),"gesture-swipe":b(v.gesture,ep),"gesture-pinch":b(v.gesture,function(e){return["pinch",String(e.scale),...M(e.x),...M(e.y)]}),"gesture-rotate":b(v.gesture,e=>(function(e){var r=e;if(void 0===r.x&&void 0!==r.y||void 0!==r.x&&void 0===r.y)throw new t("INVALID_ARGS","gesture rotate center requires both x and y");let i=void 0===e.x||void 0===e.y?[]:[String(e.x),String(e.y)];return["rotate",String(e.degrees),...i,...M(e.velocity)]})(e)),"gesture-transform":b(v.gesture,function(e){return["transform",String(e.x),String(e.y),String(e.dx),String(e.dy),String(e.scale),String(e.degrees),...M(e.durationMs)]})};function ep(e){return["swipe",C(e.preset,"gesture swipe requires preset"),...M(e.durationMs)]}let ef={perf:(e,r)=>({..._(r),...function(e){if(void 0!==e[0]&&void 0===e[1]){let t=ey(e[0],{allowUndefined:!0});if(t)return{action:t}}return{area:function(e){if(void 0===e)return;let r=e.toLowerCase();if(E(r))return r;throw new t("INVALID_ARGS",V)}(e[0]),action:ey(e[1])}}(e)}),logs:(e,r)=>({..._(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 t("INVALID_ARGS","logs requires path, start, stop, doctor, mark, or clear")}}(e[0]),message:e.slice(1).join(" ")||void 0,restart:r.restart}),network:(e,r)=>({..._(r),action:function(e){if(void 0!==e){if("dump"===e||"log"===e)return e;throw new t("INVALID_ARGS","network requires dump or log")}}(e[0]),limit:x(e[1]),include:r.networkInclude??function(e){if(void 0!==e){if("summary"===e||"headers"===e||"body"===e||"all"===e)return e;throw new t("INVALID_ARGS","network include mode must be summary, headers, body, or all")}}(e[2])}),record:(e,t)=>({..._(t),action:eg(e[0],"record"),path:e[1],fps:t.fps,quality:t.quality,hideTouches:t.hideTouches}),trace:(e,t)=>({..._(t),action:eg(e[0],"trace"),path:e[1]})},em={perf:b(v.perf,e=>{var t;return[...N((t=e).area??(t.action?"metrics":void 0)),...N(t.action)]}),logs:b(v.logs,e=>{var t;return[(t=e).action??"path",...N(t.message)]}),network:e=>{var t;return w(v.network,[...(t=e).action?[t.action]:[],...M(t.limit)],{...e,networkInclude:e.include})},record:b(v.record,e=>eh(e)),trace:b(v.trace,e=>eh(e))};function eh(e){return[e.action,...N(e.path)]}function eg(e,r){if("start"===e||"stop"===e)return e;throw new t("INVALID_ARGS",`${r} requires start|stop`)}function ey(e,r={}){if(void 0===e)return;let i=e.toLowerCase();if(q(i))return i;if(!r.allowUndefined)throw new t("INVALID_ARGS",G)}let ev={replay:(e,t)=>({..._(t),path:I(e[0],"replay requires path"),update:t.replayUpdate,backend:t.replayMaestro?"maestro":void 0,env:t.replayEnv}),test:(e,t)=>({..._(t),paths:e,update:t.replayUpdate,backend:t.replayMaestro?"maestro":void 0,env:t.replayEnv,failFast:t.failFast,timeoutMs:t.timeoutMs,retries:t.retries,artifactsDir:t.artifactsDir,reportJunit:t.reportJunit,shardAll:t.shardAll,shardSplit:t.shardSplit})};function eS(e){return e.backend??(!0===e.maestro?"maestro":void 0)}function ew(e){let t={};for(let[r,i]of Object.entries(e))"string"==typeof i&&r.startsWith("AD_VAR_")&&(t[r]=i);return t}let eA={find:(e,r)=>(function(e,r){var i;let a={...{depth:(i=r).snapshotDepth,raw:i.snapshotRaw},...k(r),first:r.findFirst,last:r.findLast},n=function(e){if("text"===e||"label"===e||"value"===e||"role"===e||"id"===e)return e}(e[0]),o=void 0!==n,s=o?e[1]:e[0],l=o?2:1,u=e[l];if(void 0===u)return{...a,locator:n,query:eI(s)};if("get"===u){let r=e[l+1];if("text"===r)return{...a,locator:n,query:eI(s),action:"getText"};if("attrs"===r)return{...a,locator:n,query:eI(s),action:"getAttrs"};throw new t("INVALID_ARGS","find get only supports text or attrs")}if("wait"===u)return{...a,locator:n,query:eI(s),action:"wait",timeoutMs:x(e[l+1])};if("fill"===u||"type"===u)return{...a,locator:n,query:eI(s),action:u,value:e.slice(l+1).join(" ")};if("click"===u||"focus"===u||"exists"===u)return{...a,locator:n,query:eI(s),action:u};throw new t("INVALID_ARGS",`Unsupported find action: ${u}`)})(e,r),is:(e,r)=>(function(e,r){let i={...A(r),...k(r)},a=e[0],n=P(e.slice(1),{preferTrailingValue:"text"===a});if("text"===a)return{...i,predicate:a,selector:n.selectorExpression,value:n.rest.join(" ")};if("visible"===a||"hidden"===a||"exists"===a||"editable"===a||"selected"===a)return{...i,predicate:a,selector:n.selectorExpression};throw new t("INVALID_ARGS","is requires predicate: visible|hidden|exists|editable|selected|text")})(e,r)},eb={is:b(v.is,e=>{var t;return[(t=e).predicate,t.selector,..."text"===t.predicate?[t.value]:[]]}),find:e=>w(v.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",...M(e.timeoutMs)];case"fill":case"type":return[...t,e.action,e.value]}}(e),{...e,findFirst:e.first,findLast:e.last})};function eI(e){if(void 0===e||""===e)throw new t("INVALID_ARGS","find requires query");return e}let e_={appstate:(e,t)=>_(t),home:(e,t)=>_(t),"app-switcher":(e,t)=>_(t),back:(e,t)=>({..._(t),mode:t.backMode}),rotate:(e,t)=>({..._(t),orientation:U(e[0])}),keyboard:(e,r)=>({..._(r),...function(e){if(e.length>1)throw new t("INVALID_ARGS","keyboard accepts at most one action argument.");return $({action:function(e){let r=e?.toLowerCase();if("get"===r)return"status";if(void 0===r||"status"===r||"dismiss"===r||"enter"===r||"return"===r)return r;throw new t("INVALID_ARGS","keyboard action must be status, get, dismiss, enter, or return.")}(e[0])})}(e)}),clipboard:(e,r)=>({..._(r),...function(e){let r=e[0]?.toLowerCase();if("read"!==r&&"write"!==r)throw new t("INVALID_ARGS","clipboard requires a subcommand: read or write.");if("read"===r){if(1!==e.length)throw new t("INVALID_ARGS","clipboard read does not accept additional arguments.");return{action:r}}if(e.length<2)throw new t("INVALID_ARGS","clipboard write requires text.");return{action:r,text:e.slice(1).join(" ")}}(e)}),"react-native":(e,r)=>({..._(r),action:function(e){if("dismiss-overlay"===e)return e;throw new t("INVALID_ARGS","react-native supports only: dismiss-overlay")}(e[0])})},eN={appstate:b(v.appState),back:e=>{var t;return w(v.back,[],{...e,backMode:"in-app"===(t=e.mode)||"system"===t?t:void 0})},home:b(v.home),rotate:b(v.rotate,e=>[C(e.orientation,"rotate requires orientation")]),"app-switcher":b(v.appSwitcher),keyboard:b(v.keyboard,e=>N(e.action)),clipboard:b(v.clipboard,e=>{var t;return"read"===(t=e).action?["read"]:["write",t.text]}),"react-native":b(v.reactNative,e=>[C(e.action,"react-native requires action")])},eR={...es,...L,...z,...ed,...eb,...em,replay:e=>w(v.replay,[C(e.path,"replay requires path")],{...e,replayUpdate:e.update,replayBackend:eS(e),replayEnv:e.env,replayShellEnv:ew(process.env)}),test:e=>w(v.test,e.paths??[],{...e,replayUpdate:e.update,replayBackend:eS(e),replayEnv:e.env,replayShellEnv:ew(process.env)}),...eN,batch:e=>w(v.batch,[],{...e,batchSteps:function(e){if(!Array.isArray(e)||0===e.length)throw new t("INVALID_ARGS","batch requires a non-empty steps array.");return e.map((e,r)=>{var i;let a,n,o,s,l,u;return o=function(e,r){let i="string"==typeof e.command?e.command.trim().toLowerCase():"";if(ex.has(i))return i;throw new t("INVALID_ARGS",`Batch step ${r} command is not available through command batch: ${String(e.command)}`)}(n=function(e,r){if(!e||"object"!=typeof e||Array.isArray(e))throw new t("INVALID_ARGS",`Invalid batch step ${r}.`);return e}(e,i=r+1),i),s=function(e,r){let i=e.input;if(!i||"object"!=typeof i||Array.isArray(i))throw new t("INVALID_ARGS",`Batch step ${r} input must be an object.`);return i}(n,i),l=function(e,r){let i=e.runtime;if(void 0!==i&&(!i||"object"!=typeof i||Array.isArray(i)))throw new t("INVALID_ARGS",`Batch step ${r} runtime must be an object.`);return i}(n,i),{...u={command:(a=ek(o,s)).command,positionals:a.positionals,flags:Z(a.options),runtime:a.options.runtime},runtime:l??u.runtime}})}(e.steps),batchOnError:e.onError,batchMaxSteps:e.maxSteps})},eM=y,ex=D(eM);function ek(e,t){return eR[e](t)}export{eo as appCliReaders,eM as batchCommandNames,Z as buildFlags,ee as buildMeta,ec as gestureCliReaders,K as normalizeDeployResult,B as normalizeDevice,T as normalizeInstallFromSourceResult,F as normalizeMaterializationReleaseResult,W as normalizeOpenDevice,J as normalizeRuntimeHints,O as normalizeSession,Q as normalizeStartupSample,ef as observabilityCliReaders,er as parseInstallSourceConfig,ek as prepareDaemonCommandRequest,Y as readScreenshotOverlayRefs,X as readSnapshotNodes,ev as replayCliReaders,et as resolveSessionName,eA as selectorCliReaders,e_ as systemCliReaders};
|
|
1
|
+
import{screenshotFlagsFromOptions as e}from"./5310.js";import{AppError as t}from"./9152.js";import{readRequiredString as r,readRequiredPlatform as i,readRequiredDeviceKind as a,readNullableString as n,readDeviceTarget as o,readRect as s,asRecord as l,stripUndefined as u,isRecord as c,readRequiredNumber as d,readPoint as p,readOptionalString as f}from"./7455.js";import{buildAppIdentifiers as m,buildDeviceIdentifiers as h}from"./6232.js";import{INTERNAL_COMMANDS as g,BATCH_COMMAND_NAMES as y,PUBLIC_COMMANDS as v}from"./5792.js";import{assertResolvedAppsFilter as S}from"./1393.js";import{request as w,selectorSnapshotOptionsFromFlags as A,direct as b,requiredString as I,commonInputFromFlags as _,optionalString as N,readJsonObject as R,optionalNumber as M,optionalCliNumber as x,selectionOptionsFromFlags as k,commandNameSet as D,captureDaemonWriters as L,requiredDaemonString as C,splitRequiredSelector as P}from"./6085.js";import{isPerfAction as V,PERF_AREA_ERROR_MESSAGE as q,PERF_ACTION_ERROR_MESSAGE as G,isPerfArea as E}from"./8020.js";import{parseDeviceRotation as U}from"./1998.js";import{compactRecord as $}from"./9404.js";import{interactionDaemonWriters as z}from"./8502.js";function K(e,t){let a=f(e,"bundleId"),n=f(e,"package");return{app:r(e,"app"),appPath:r(e,"appPath"),platform:i(e,"platform"),appId:a??n,bundleId:a,package:n,identifiers:m({session:t,bundleId:a,packageName:n})}}function T(e,r){let i=f(e,"bundleId"),a=f(e,"packageName"),n=i??a??f(e,"appId"),o=f(e,"launchTarget")??a??i??n;if(!o)throw new t("COMMAND_FAILED",'Daemon response is missing "launchTarget".',{response:e});return{appName:f(e,"appName"),appId:n,bundleId:i,packageName:a,launchTarget:o,installablePath:f(e,"installablePath"),archivePath:f(e,"archivePath"),materializationId:f(e,"materializationId"),materializationExpiresAt:f(e,"materializationExpiresAt"),identifiers:m({session:r,bundleId:i,packageName:a,appId:n})}}function F(e){return{released:!0===e.released,materializationId:r(e,"materializationId"),identifiers:{}}}function B(e){let{record:t,platform:r,id:i,name:n,target:o}=H(e,"name");return{platform:r,target:o,kind:a(t,"kind"),id:i,name:n,booted:"boolean"==typeof t.booted?t.booted:void 0,identifiers:h(r,i,n),...j(r,i)}}function O(e){let{record:t,platform:i,id:a,name:o,target:s}=H(e,"name"),l=r(t,"device"),u={session:o,...h(i,a,l)};return{name:o,createdAt:d(t,"createdAt"),sessionStateDir:f(t,"sessionStateDir"),runnerLogPath:f(t,"runnerLogPath"),device:{platform:i,target:s,id:a,name:l,identifiers:u,...j(i,a,n(t,"ios_simulator_device_set"))},identifiers:u}}function H(e,t){let a=l(e);return{record:a,platform:i(a,"platform"),id:r(a,"id"),name:r(a,t),target:o(a,"target")}}function j(e,t,r){return{ios:"ios"===e?{udid:t,...void 0!==r?{simulatorSetPath:r}:{}}:void 0,android:"android"===e?{serial:t}:void 0}}function J(e){if(!c(e))return;let t=e.platform,r=f(e,"metroHost"),i="number"==typeof e.metroPort?e.metroPort:void 0;return{platform:"ios"===t||"android"===t?t:void 0,metroHost:r,metroPort:i,bundleUrl:f(e,"bundleUrl"),launchUrl:f(e,"launchUrl")}}function W(e){let t=e.platform,r=f(e,"id"),i=f(e,"device");if("ios"!==t&&"macos"!==t&&"android"!==t&&"linux"!==t||!r||!i)return;let a=o(e,"target"),s=h(t,r,i);return{platform:t,target:a,id:r,name:i,identifiers:s,ios:"ios"===t?{udid:f(e,"device_udid")??r,simulatorSetPath:n(e,"ios_simulator_device_set")}:void 0,android:"android"===t?{serial:f(e,"serial")??r}:void 0}}function Q(e){if(c(e)&&"number"==typeof e.durationMs&&"string"==typeof e.measuredAt&&"string"==typeof e.method)return{durationMs:e.durationMs,measuredAt:e.measuredAt,method:e.method,appTarget:f(e,"appTarget"),appBundleId:f(e,"appBundleId")}}function X(e){return Array.isArray(e)?e:[]}function Y(e){let t=e.overlayRefs;if(!Array.isArray(t))return;let r=[];for(let e of t){if(!c(e))continue;let t=f(e,"ref"),i=s(e,"rect"),a=s(e,"overlayRect"),n=p(e,"center");t&&i&&a&&n&&r.push({ref:t,label:f(e,"label"),rect:i,overlayRect:a,center:n})}return r}function Z(t){return u({stateDir:t.stateDir,daemonBaseUrl:t.daemonBaseUrl,daemonAuthToken:t.daemonAuthToken,daemonTransport:t.daemonTransport,daemonServerMode:t.daemonServerMode,tenant:t.tenant,sessionIsolation:t.sessionIsolation,runId:t.runId,leaseId:t.leaseId,leaseBackend:t.leaseBackend,platform:t.platform,target:t.target,device:t.device,udid:t.udid,serial:t.serial,iosSimulatorDeviceSet:t.iosSimulatorDeviceSet,androidDeviceAllowlist:t.androidDeviceAllowlist,surface:t.surface,activity:t.activity,launchConsole:t.launchConsole,launchArgs:t.launchArgs,relaunch:t.relaunch,shutdown:t.shutdown,saveScript:t.saveScript,noRecord:t.noRecord,backMode:t.backMode,metroHost:t.metroHost,metroPort:t.metroPort,bundleUrl:t.bundleUrl,launchUrl:t.launchUrl,snapshotInteractiveOnly:t.interactiveOnly,snapshotCompact:t.compact,snapshotDepth:t.depth,snapshotScope:t.scope,snapshotRaw:t.raw,snapshotForceFull:t.forceFull,...e(t),appsFilter:t.appsFilter,out:t.out,count:t.count,fps:t.fps,quality:t.quality,hideTouches:t.hideTouches,intervalMs:t.intervalMs,delayMs:t.delayMs,holdMs:t.holdMs,jitterPx:t.jitterPx,pixels:t.pixels,doubleTap:t.doubleTap,clickButton:t.clickButton,pauseMs:t.pauseMs,pattern:t.pattern,headless:t.headless,restart:t.restart,replayUpdate:t.replayUpdate,replayBackend:t.replayBackend,replayEnv:t.replayEnv,replayShellEnv:t.replayShellEnv,failFast:t.failFast,timeoutMs:t.timeoutMs,retries:t.retries,recordVideo:t.recordVideo,artifactsDir:t.artifactsDir,reportJunit:t.reportJunit,shardAll:t.shardAll,shardSplit:t.shardSplit,findFirst:t.findFirst,findLast:t.findLast,networkInclude:t.networkInclude,batchOnError:t.batchOnError,batchMaxSteps:t.batchMaxSteps,batchSteps:t.batchSteps,verbose:t.debug})}function ee(e){return u({requestId:e.requestId,cwd:e.cwd,sessionExplicit:void 0!==e.session,debug:e.debug,lockPolicy:e.lockPolicy,lockPlatform:e.lockPlatform,tenantId:e.tenant,runId:e.runId,leaseId:e.leaseId,leaseBackend:e.leaseBackend,leaseTtlMs:e.leaseTtlMs,sessionIsolation:e.sessionIsolation,installSource:e.installSource,retainMaterializedPaths:e.retainMaterializedPaths,materializedPathRetentionMs:e.materializedPathRetentionMs,materializationId:e.materializationId})}function et(e){return e??"default"}function er(e,r){if(!e||"object"!=typeof e||Array.isArray(e))throw new t("INVALID_ARGS",`${r} installSource must be an object.`);if("github-actions-artifact"!==en(e.type,`${r} installSource.type`))throw new t("INVALID_ARGS",`${r} installSource.type must be "github-actions-artifact".`);let{owner:i,repo:a}=ea(en(e.repo,`${r} installSource.repo`),`${r} installSource.repo`);return ei(i,a,e.artifact,`${r} installSource.artifact`)}function ei(e,r,i,a){var n;return"number"==typeof i||"string"==typeof(n=i)&&/^\d+$/.test(n.trim())?{kind:"github-actions-artifact",owner:e,repo:r,artifactId:function(e,r){let i="number"==typeof e?e:"string"==typeof e?Number(e):NaN;if(!Number.isInteger(i))throw new t("INVALID_ARGS",`${r} must be an integer.`);return i}(i,a)}:{kind:"github-actions-artifact",owner:e,repo:r,artifactName:en(i,a)}}function ea(e,r){let i=e.indexOf("/");if(i<=0||i===e.length-1||-1!==e.indexOf("/",i+1))throw new t("INVALID_ARGS",`${r} must use owner/repo.`);let a={owner:e.slice(0,i).trim(),repo:e.slice(i+1).trim()};if(!a.owner||!a.repo)throw new t("INVALID_ARGS",`${r} must use owner/repo.`);return a}function en(e,r){let i="string"==typeof e&&e.trim().length>0?e.trim():void 0;if(!i)throw new t("INVALID_ARGS",`${r} must be a non-empty string.`);return i}let eo={devices:(e,t)=>_(t),apps:(e,t)=>({..._(t),appsFilter:S(t.appsFilter)}),session:(e,r)=>({..._(r),action:function(e){let r=e??"list";if("list"===r)return r;throw new t("INVALID_ARGS","session only supports list")}(e[0])}),boot:(e,t)=>({..._(t),headless:t.headless}),prepare:(e,t)=>({..._(t),action:I(e[0],"prepare requires subcommand"),timeoutMs:t.timeoutMs}),open:(e,t)=>({..._(t),app:e[0],url:e[1],surface:t.surface,activity:t.activity,launchConsole:t.launchConsole,launchArgs:t.launchArgs,relaunch:t.relaunch,saveScript:t.saveScript,noRecord:t.noRecord}),close:(e,t)=>({..._(t),app:e[0],shutdown:t.shutdown,saveScript:t.saveScript}),install:el,reinstall:el,"install-from-source":(e,r)=>({..._(r),source:function(e,r){let i=e[0]?.trim();if(e.length>1)throw new t("INVALID_ARGS","install-from-source accepts either one <url> positional or --github-actions-artifact");let a=r.githubActionsArtifact?function(e,r="--github-actions-artifact"){let i=e.indexOf(":");if(i<=0||i===e.length-1)throw new t("INVALID_ARGS",`${r} must use owner/repo:artifact, for example thymikee/RNCLI83:6635342232`);let{owner:a,repo:n}=ea(e.slice(0,i),r);return ei(a,n,e.slice(i+1),`${r} artifact`)}(r.githubActionsArtifact):void 0,n=r.installSource;if(1!=+!!i+ +!!a+ +!!n)throw new t("INVALID_ARGS","install-from-source requires exactly one source: <url>, --github-actions-artifact, or config installSource");if(!i&&r.header&&r.header.length>0)throw new t("INVALID_ARGS","install-from-source --header is only supported for URL sources");return a||n||{kind:"url",url:i,headers:function(e){if(!e||0===e.length)return;let r={};for(let i of e){let e=i.indexOf(":");if(e<=0)throw new t("INVALID_ARGS",`Invalid --header value "${i}". Expected "name:value".`);let a=i.slice(0,e).trim(),n=i.slice(e+1).trim();if(!a)throw new t("INVALID_ARGS",`Invalid --header value "${i}". Header name cannot be empty.`);r[a]=n}return r}(r.header)}}(e,r),retainPaths:r.retainPaths,retentionMs:r.retentionMs}),push:(e,t)=>({..._(t),app:I(e[0],"push requires bundleOrPackage"),payload:I(e[1],"push requires payloadOrJson")}),"trigger-app-event":(e,t)=>({..._(t),event:I(e[0],"trigger-app-event requires event"),payload:e[1]?R(e[1],"trigger-app-event payload"):void 0})},es={devices:b(v.devices),boot:b(v.boot),prepare:b(v.prepare,e=>[C(e.action,"prepare requires subcommand")]),apps:b(v.apps),open:b(v.open,function(e){return e.app?e.url?[e.app,e.url]:[e.app]:[]}),close:b(v.close,e=>N(e.app)),install:b(v.install,e=>eu(e.app,e.appPath)),reinstall:b(v.reinstall,e=>eu(e.app,e.appPath)),"install-from-source":e=>w(g.installSource,[],{...e,installSource:e.source,retainMaterializedPaths:e.retainPaths,materializedPathRetentionMs:e.retentionMs}),push:b(v.push,e=>{var t;return[(t=e).app,"string"==typeof t.payload?t.payload:JSON.stringify(t.payload)]}),"trigger-app-event":b(v.triggerAppEvent,e=>{var t;return[(t=e).event,...t.payload?[JSON.stringify(t.payload)]:[]]})};function el(e,t,r="install"){return{..._(t),app:I(e[0],`${r} requires app`),appPath:I(e[1],`${r} requires path`)}}function eu(e,t){return[C(e,"missing first positional"),C(t,"missing second positional")]}let ec={gesture:function(e,r){let i=e[0],a=e.slice(1),n=_(r);switch(i){case"pan":return{...n,kind:i,origin:{x:Number(a[0]),y:Number(a[1])},delta:{x:Number(a[2]),y:Number(a[3])},durationMs:x(a[4])};case"fling":return{...n,kind:i,direction:a[0],origin:{x:Number(a[1]),y:Number(a[2])},distance:x(a[3]),durationMs:x(a[4])};case"swipe":return{...n,kind:i,preset:a[0],durationMs:x(a[1])};case"pinch":return{...n,kind:i,scale:Number(a[0]),origin:void 0===a[1]||void 0===a[2]?void 0:{x:Number(a[1]),y:Number(a[2])}};case"rotate":return{...n,kind:i,degrees:Number(a[0]),origin:void 0===a[1]||void 0===a[2]?void 0:{x:Number(a[1]),y:Number(a[2])},velocity:x(a[3])};case"transform":return{...n,kind:i,origin:{x:Number(a[0]),y:Number(a[1])},delta:{x:Number(a[2]),y:Number(a[3])},scale:Number(a[4]),degrees:Number(a[5]),durationMs:x(a[6])};default:throw new t("INVALID_ARGS","gesture requires pan, fling, swipe, pinch, rotate, or transform")}}},ed={gesture:b(v.gesture,function(e){switch(e.kind){case"pan":return["pan",String(e.origin?.x),String(e.origin?.y),String(e.delta?.x),String(e.delta?.y),...M(e.durationMs)];case"fling":return["fling",C(e.direction,"gesture fling requires direction"),String(e.origin?.x),String(e.origin?.y),...M(e.distance),...M(e.durationMs)];case"swipe":return ep(e);case"pinch":return["pinch",String(e.scale),...M(e.origin?.x),...M(e.origin?.y)];case"rotate":return["rotate",String(e.degrees),...M(e.origin?.x),...M(e.origin?.y),...M(e.velocity)];case"transform":return["transform",String(e.origin?.x),String(e.origin?.y),String(e.delta?.x),String(e.delta?.y),String(e.scale),String(e.degrees),...M(e.durationMs)];default:throw new t("INVALID_ARGS","gesture requires pan, fling, swipe, pinch, rotate, or transform")}}),"gesture-pan":b(v.gesture,function(e){return["pan",String(e.x),String(e.y),String(e.dx),String(e.dy),...M(e.durationMs)]}),"gesture-fling":b(v.gesture,e=>{var t;let r;return r=void 0!==(t=e).durationMs?t.distance??180:t.distance,["fling",t.direction,String(t.x),String(t.y),...M(r),...M(t.durationMs)]}),"gesture-swipe":b(v.gesture,ep),"gesture-pinch":b(v.gesture,function(e){return["pinch",String(e.scale),...M(e.x),...M(e.y)]}),"gesture-rotate":b(v.gesture,e=>(function(e){var r=e;if(void 0===r.x&&void 0!==r.y||void 0!==r.x&&void 0===r.y)throw new t("INVALID_ARGS","gesture rotate center requires both x and y");let i=void 0===e.x||void 0===e.y?[]:[String(e.x),String(e.y)];return["rotate",String(e.degrees),...i,...M(e.velocity)]})(e)),"gesture-transform":b(v.gesture,function(e){return["transform",String(e.x),String(e.y),String(e.dx),String(e.dy),String(e.scale),String(e.degrees),...M(e.durationMs)]})};function ep(e){return["swipe",C(e.preset,"gesture swipe requires preset"),...M(e.durationMs)]}let ef={perf:(e,r)=>({..._(r),...function(e){if(void 0!==e[0]&&void 0===e[1]){let t=ey(e[0],{allowUndefined:!0});if(t)return{action:t}}return{area:function(e){if(void 0===e)return;let r=e.toLowerCase();if(E(r))return r;throw new t("INVALID_ARGS",q)}(e[0]),action:ey(e[1])}}(e)}),logs:(e,r)=>({..._(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 t("INVALID_ARGS","logs requires path, start, stop, doctor, mark, or clear")}}(e[0]),message:e.slice(1).join(" ")||void 0,restart:r.restart}),network:(e,r)=>({..._(r),action:function(e){if(void 0!==e){if("dump"===e||"log"===e)return e;throw new t("INVALID_ARGS","network requires dump or log")}}(e[0]),limit:x(e[1]),include:r.networkInclude??function(e){if(void 0!==e){if("summary"===e||"headers"===e||"body"===e||"all"===e)return e;throw new t("INVALID_ARGS","network include mode must be summary, headers, body, or all")}}(e[2])}),record:(e,t)=>({..._(t),action:eg(e[0],"record"),path:e[1],fps:t.fps,quality:t.quality,hideTouches:t.hideTouches}),trace:(e,t)=>({..._(t),action:eg(e[0],"trace"),path:e[1]})},em={perf:b(v.perf,e=>{var t;return[...N((t=e).area??(t.action?"metrics":void 0)),...N(t.action)]}),logs:b(v.logs,e=>{var t;return[(t=e).action??"path",...N(t.message)]}),network:e=>{var t;return w(v.network,[...(t=e).action?[t.action]:[],...M(t.limit)],{...e,networkInclude:e.include})},record:b(v.record,e=>eh(e)),trace:b(v.trace,e=>eh(e))};function eh(e){return[e.action,...N(e.path)]}function eg(e,r){if("start"===e||"stop"===e)return e;throw new t("INVALID_ARGS",`${r} requires start|stop`)}function ey(e,r={}){if(void 0===e)return;let i=e.toLowerCase();if(V(i))return i;if(!r.allowUndefined)throw new t("INVALID_ARGS",G)}let ev={replay:(e,t)=>({..._(t),path:I(e[0],"replay requires path"),update:t.replayUpdate,backend:t.replayMaestro?"maestro":void 0,env:t.replayEnv}),test:(e,t)=>({..._(t),paths:e,update:t.replayUpdate,backend:t.replayMaestro?"maestro":void 0,env:t.replayEnv,failFast:t.failFast,timeoutMs:t.timeoutMs,retries:t.retries,recordVideo:t.recordVideo,artifactsDir:t.artifactsDir,reportJunit:t.reportJunit,shardAll:t.shardAll,shardSplit:t.shardSplit})};function eS(e){return e.backend??(!0===e.maestro?"maestro":void 0)}function ew(e){let t={};for(let[r,i]of Object.entries(e))"string"==typeof i&&r.startsWith("AD_VAR_")&&(t[r]=i);return t}let eA={find:(e,r)=>(function(e,r){var i;let a={...{depth:(i=r).snapshotDepth,raw:i.snapshotRaw},...k(r),first:r.findFirst,last:r.findLast},n=function(e){if("text"===e||"label"===e||"value"===e||"role"===e||"id"===e)return e}(e[0]),o=void 0!==n,s=o?e[1]:e[0],l=o?2:1,u=e[l];if(void 0===u)return{...a,locator:n,query:eI(s)};if("get"===u){let r=e[l+1];if("text"===r)return{...a,locator:n,query:eI(s),action:"getText"};if("attrs"===r)return{...a,locator:n,query:eI(s),action:"getAttrs"};throw new t("INVALID_ARGS","find get only supports text or attrs")}if("wait"===u)return{...a,locator:n,query:eI(s),action:"wait",timeoutMs:x(e[l+1])};if("fill"===u||"type"===u)return{...a,locator:n,query:eI(s),action:u,value:e.slice(l+1).join(" ")};if("click"===u||"focus"===u||"exists"===u)return{...a,locator:n,query:eI(s),action:u};throw new t("INVALID_ARGS",`Unsupported find action: ${u}`)})(e,r),is:(e,r)=>(function(e,r){let i={...A(r),...k(r)},a=e[0],n=P(e.slice(1),{preferTrailingValue:"text"===a});if("text"===a)return{...i,predicate:a,selector:n.selectorExpression,value:n.rest.join(" ")};if("visible"===a||"hidden"===a||"exists"===a||"editable"===a||"selected"===a)return{...i,predicate:a,selector:n.selectorExpression};throw new t("INVALID_ARGS","is requires predicate: visible|hidden|exists|editable|selected|text")})(e,r)},eb={is:b(v.is,e=>{var t;return[(t=e).predicate,t.selector,..."text"===t.predicate?[t.value]:[]]}),find:e=>w(v.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",...M(e.timeoutMs)];case"fill":case"type":return[...t,e.action,e.value]}}(e),{...e,findFirst:e.first,findLast:e.last})};function eI(e){if(void 0===e||""===e)throw new t("INVALID_ARGS","find requires query");return e}let e_={appstate:(e,t)=>_(t),home:(e,t)=>_(t),"app-switcher":(e,t)=>_(t),back:(e,t)=>({..._(t),mode:t.backMode}),rotate:(e,t)=>({..._(t),orientation:U(e[0])}),keyboard:(e,r)=>({..._(r),...function(e){if(e.length>1)throw new t("INVALID_ARGS","keyboard accepts at most one action argument.");return $({action:function(e){let r=e?.toLowerCase();if("get"===r)return"status";if(void 0===r||"status"===r||"dismiss"===r||"enter"===r||"return"===r)return r;throw new t("INVALID_ARGS","keyboard action must be status, get, dismiss, enter, or return.")}(e[0])})}(e)}),clipboard:(e,r)=>({..._(r),...function(e){let r=e[0]?.toLowerCase();if("read"!==r&&"write"!==r)throw new t("INVALID_ARGS","clipboard requires a subcommand: read or write.");if("read"===r){if(1!==e.length)throw new t("INVALID_ARGS","clipboard read does not accept additional arguments.");return{action:r}}if(e.length<2)throw new t("INVALID_ARGS","clipboard write requires text.");return{action:r,text:e.slice(1).join(" ")}}(e)}),"react-native":(e,r)=>({..._(r),action:function(e){if("dismiss-overlay"===e)return e;throw new t("INVALID_ARGS","react-native supports only: dismiss-overlay")}(e[0])})},eN={appstate:b(v.appState),back:e=>{var t;return w(v.back,[],{...e,backMode:"in-app"===(t=e.mode)||"system"===t?t:void 0})},home:b(v.home),rotate:b(v.rotate,e=>[C(e.orientation,"rotate requires orientation")]),"app-switcher":b(v.appSwitcher),keyboard:b(v.keyboard,e=>N(e.action)),clipboard:b(v.clipboard,e=>{var t;return"read"===(t=e).action?["read"]:["write",t.text]}),"react-native":b(v.reactNative,e=>[C(e.action,"react-native requires action")])},eR={...es,...L,...z,...ed,...eb,...em,replay:e=>w(v.replay,[C(e.path,"replay requires path")],{...e,replayUpdate:e.update,replayBackend:eS(e),replayEnv:e.env,replayShellEnv:ew(process.env)}),test:e=>w(v.test,e.paths??[],{...e,replayUpdate:e.update,replayBackend:eS(e),replayEnv:e.env,replayShellEnv:ew(process.env)}),...eN,batch:e=>w(v.batch,[],{...e,batchSteps:function(e){if(!Array.isArray(e)||0===e.length)throw new t("INVALID_ARGS","batch requires a non-empty steps array.");return e.map((e,r)=>{var i;let a,n,o,s,l,u;return o=function(e,r){let i="string"==typeof e.command?e.command.trim().toLowerCase():"";if(ex.has(i))return i;throw new t("INVALID_ARGS",`Batch step ${r} command is not available through command batch: ${String(e.command)}`)}(n=function(e,r){if(!e||"object"!=typeof e||Array.isArray(e))throw new t("INVALID_ARGS",`Invalid batch step ${r}.`);return e}(e,i=r+1),i),s=function(e,r){let i=e.input;if(!i||"object"!=typeof i||Array.isArray(i))throw new t("INVALID_ARGS",`Batch step ${r} input must be an object.`);return i}(n,i),l=function(e,r){let i=e.runtime;if(void 0!==i&&(!i||"object"!=typeof i||Array.isArray(i)))throw new t("INVALID_ARGS",`Batch step ${r} runtime must be an object.`);return i}(n,i),{...u={command:(a=ek(o,s)).command,positionals:a.positionals,flags:Z(a.options),runtime:a.options.runtime},runtime:l??u.runtime}})}(e.steps),batchOnError:e.onError,batchMaxSteps:e.maxSteps})},eM=y,ex=D(eM);function ek(e,t){return eR[e](t)}export{eo as appCliReaders,eM as batchCommandNames,Z as buildFlags,ee as buildMeta,ec as gestureCliReaders,K as normalizeDeployResult,B as normalizeDevice,T as normalizeInstallFromSourceResult,F as normalizeMaterializationReleaseResult,W as normalizeOpenDevice,J as normalizeRuntimeHints,O as normalizeSession,Q as normalizeStartupSample,ef as observabilityCliReaders,er as parseInstallSourceConfig,ek as prepareDaemonCommandRequest,Y as readScreenshotOverlayRefs,X as readSnapshotNodes,ev as replayCliReaders,et as resolveSessionName,eA as selectorCliReaders,e_ as systemCliReaders};
|
package/dist/src/9238.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import e from"node:path";import t from"node:crypto";import n from"node:fs";import{resolveUserPath as
|
|
1
|
+
import e from"node:path";import t from"node:crypto";import n from"node:fs";import{resolveUserPath as o,expandUserHomePath as r}from"./3267.js";import{findProjectRoot as s}from"./9671.js";function i(e,t){let n=[],o=e+t.toString(),r=o.indexOf("\n");for(;-1!==r;){let e=o.slice(0,r).trim();o=o.slice(r+1),e&&n.push(e),r=o.indexOf("\n")}return{lines:n,buffer:o}}function l(t){let n,s=(n=(t??"").trim())?o(n):e.join(r("~"),".agent-device");return{baseDir:s,infoPath:e.join(s,"daemon.json"),lockPath:e.join(s,"daemon.lock"),logPath:e.join(s,"daemon.log"),sessionsDir:e.join(s,"sessions")}}function u(e){let t=(e??"").trim().toLowerCase();return"http"===t?"http":"dual"===t?"dual":"socket"}function a(e){let t=(e??"").trim().toLowerCase();return"auto"===t?"auto":"socket"===t?"socket":"http"===t?"http":"auto"}function f(e){return"tenant"===(e??"").trim().toLowerCase()?"tenant":"none"}function c(e){if(!e)return;let t=e.trim();if(t&&/^[a-zA-Z0-9._-]{1,128}$/.test(t))return t}let p=/(?:^|[^\w$.])(?:import|export)\s+(?:type\s+)?(?:[^'"`]*?\s+from\s+)?['"]([^'"]+)['"]/gm,m=/import\(\s*['"]([^'"]+)['"]\s*\)/gm,d=[".ts",".tsx",".js",".jsx",".mjs",".cjs"];function h(){let e=process.argv[1];return e?g(e):"unknown"}function g(o,r=s()){try{let s=e.resolve(r),i=[e.resolve(o)],l=new Set,u=[];for(;i.length>0;){let t=i.pop();if(!t||l.has(t))continue;l.add(t);let o=n.statSync(t);if(!o.isFile())continue;let r=e.relative(s,t)||t;u.push(`${r}:${o.size}:${Math.trunc(o.mtimeMs)}`);let a=n.readFileSync(t,"utf8");for(let n of function(e){let t=new Set;return v(e,p,t),v(e,m,t),[...t]}(a)){let o=function(t,n){let o=e.resolve(e.dirname(t),n),r=y(o);if(r)return r;for(let e of d){let t=y(`${o}${e}`);if(t)return t}for(let t of d){let n=y(e.join(o,`index${t}`));if(n)return n}return null}(t,n);o&&i.push(o)}}let a=u.sort().join("|"),f=t.createHash("sha1").update(a).digest("hex");return`graph:${u.length}:${f}`}catch{return"unknown"}}function v(e,t,n){t.lastIndex=0;let o=null;for(;null!==(o=t.exec(e));){let e=o[1]?.trim();e?.startsWith(".")&&n.add(e)}}function y(e){try{return n.statSync(e).isFile()?e:null}catch{return null}}let S=/^[A-Za-z0-9_@%+=:,./-]+$/;function $(e){return`'${e.replaceAll("'","'\\''")}'`}function j(e){return S.test(e)?e:$(e)}function _(e){return e.meta?.requestProgress==="replay-test"}function x(e){return!!e&&"object"==typeof e&&"progress"===e.type&&!!e.event}function D(e){return!!e&&"object"==typeof e&&"response"===e.type&&!!e.response}function P(e){return`${JSON.stringify({type:"progress",event:e})}
|
|
2
2
|
`}function C(e){return`${JSON.stringify({type:"response",response:e})}
|
|
3
|
-
`}function
|
|
4
|
-
`}
|
|
3
|
+
`}function w(e){return`${JSON.stringify({type:"response",response:e})}
|
|
4
|
+
`}export{g as computeDaemonCodeSignature,i as consumeTextLines,x as isDaemonProgressEnvelope,D as isDaemonResponseEnvelope,c as normalizeTenantId,h as resolveDaemonCodeSignature,l as resolveDaemonPaths,u as resolveDaemonServerMode,a as resolveDaemonTransportPreference,f as resolveSessionIsolationMode,P as serializeDaemonProgressEnvelope,C as serializeDaemonResponseEnvelope,w as serializeDaemonRpcResponseEnvelope,$ as shellQuote,j as shellQuoteIfNeeded,_ as shouldStreamRequestProgress};
|
package/dist/src/9542.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import e from"node:net";import t from"node:http";import a from"node:https";import r from"node:fs";import n from"node:os";import o from"node:path";import{pipeline as i}from"node:stream/promises";import{createHash as s,randomUUID as l}from"node:crypto";import{Writable as c}from"node:stream";import{toAppErrorCode as d,AppError as u}from"./9152.js";import{runCmdSync as p,runCmd as m,runCmdDetached as f}from"./9818.js";import{
|
|
2
|
-
`)}let ep=["xcodebuild .*AgentDeviceRunnerUITests/RunnerTests/testCommand","xcodebuild .*AgentDeviceRunner\\.env\\.session-","xcodebuild build-for-testing .*ios-runner/AgentDeviceRunner/AgentDeviceRunner\\.xcodeproj"],em=new e.BlockList;async function ef(t){var a,i,s,l,c,d;let p,m,f,h,y,w,g,I=t.meta?.requestId??D(),v=!!(t.meta?.debug||t.flags?.verbose),P=(h=(i=a=t,i.flags?.stateDir??process.env.AGENT_DEVICE_STATE_DIR),y=(s=a,m=function(e){let t;if(e){try{t=new URL(e)}catch(t){throw new u("INVALID_ARGS","Invalid daemon base URL",{daemonBaseUrl:e},t instanceof Error?t:void 0)}if("http:"!==t.protocol&&"https:"!==t.protocol)throw new u("INVALID_ARGS","Daemon base URL must use http or https",{daemonBaseUrl:e});return t.toString().replace(/\/+$/,"")}}(p=s.flags?.daemonBaseUrl??process.env.AGENT_DEVICE_DAEMON_BASE_URL),function(t,a){let r;if(!(!t||"localhost"===(r=new URL(t).hostname.trim().toLowerCase().replace(/^\[(.*)\]$/,"$1"))||(e.isIPv4(r)?em.check(r,"ipv4"):!!e.isIPv6(r)&&em.check(r,"ipv6")))&&("string"!=typeof a||!(a.trim().length>0)))throw new u("INVALID_ARGS","Remote daemon base URL for non-loopback hosts requires daemon authentication",{daemonBaseUrl:t,hint:"Provide --daemon-auth-token or AGENT_DEVICE_DAEMON_AUTH_TOKEN when using a non-loopback remote daemon URL."})}(m,f=s.flags?.daemonAuthToken??process.env.AGENT_DEVICE_DAEMON_AUTH_TOKEN),{rawBaseUrl:p,remoteBaseUrl:m,authToken:f}),w=function(e,t){let a=e.flags?.daemonTransport??process.env.AGENT_DEVICE_DAEMON_TRANSPORT,r=k(a);if(t&&"socket"===r)throw new u("INVALID_ARGS","Remote daemon base URL only supports HTTP transport. Remove --daemon-transport socket.",{daemonBaseUrl:t});return{preference:r,serverMode:_(e.flags?.daemonServerMode??process.env.AGENT_DEVICE_DAEMON_SERVER_MODE??("dual"===a?"dual":void 0))}}(a,y.remoteBaseUrl),{paths:A((g=(l=a,c=h,d=y.rawBaseUrl,eS(l.command)&&!c&&!d))?r.mkdtempSync(o.join(n.tmpdir(),"agent-device-replay-daemon-")):h),transportPreference:w.preference,serverMode:w.serverMode,ownedStateDir:g,remoteBaseUrl:y.remoteBaseUrl,remoteAuthToken:y.authToken}),b=function(e){if(e.command!==U.test){var t;return"number"==typeof e.flags?.timeoutMs&&((t=e.command)===U.prepare||t===U.replay||t===U.snapshot)?e.flags.timeoutMs:e.command===U.prepare?24e4:9e4}}(t),S=await E("daemon_startup",async()=>await eA(P),{requestId:I,session:t.session}),T=S.info,C=await eh(t,T),N={...t,positionals:C.positionals,flags:C.flags,token:T.token,meta:{...t.meta??{},requestId:I,debug:v,cwd:t.meta?.cwd,sessionExplicit:t.meta?.sessionExplicit,tenantId:t.meta?.tenantId??t.flags?.tenant,runId:t.meta?.runId??t.flags?.runId,leaseId:t.meta?.leaseId??t.flags?.leaseId,sessionIsolation:t.meta?.sessionIsolation??t.flags?.sessionIsolation,lockPolicy:t.meta?.lockPolicy,lockPlatform:t.meta?.lockPlatform,...C.uploadedArtifactId?{uploadedArtifactId:C.uploadedArtifactId}:{},...C.clientArtifactPaths?{clientArtifactPaths:C.clientArtifactPaths}:{},...C.installSource?{installSource:C.installSource}:{}}};M({level:"info",phase:"daemon_request_prepare",data:{requestId:I,command:t.command,session:t.session}});try{return await E("daemon_request",async()=>await e$(T,N,P.transportPreference,b),{requestId:I,command:t.command})}finally{await eb(t,S,P)}}async function eh(e,t){let a,r=[...e.positionals??[]],n=e.flags?{...e.flags}:void 0,i=e.meta?.installSource,s={};if(!eY(t))return ew({positionals:r,flags:n,installSource:i,uploadedArtifactId:a,clientArtifactPaths:s});n=function(e,t,a,r){var n,i;let s=function(e,t){if("screenshot"===e.command){let a=eI(e,"path",".png");return t[0]?{field:"path",localPath:a,positionalIndex:0,positionalPath:ev("screenshot",".png")}:{field:"path",localPath:a,positionalIndex:0,flagPath:ev("screenshot",".png")}}if("record"===e.command&&"start"===(t[0]??"").toLowerCase()){let t=eI(e,"outPath",".mp4",1);return{field:"outPath",localPath:t,positionalIndex:1,positionalPath:ev("recording",o.extname(t)||".mp4")}}return null}(e,t);if(!s)return a;void 0!==s.positionalPath&&(t[s.positionalIndex]=s.positionalPath);let l=(n=a,void 0===(i=s.flagPath)?n:{...n??{},out:i});return r[s.field]=s.localPath,l}(e,r,n,s);let l=await eg(e,t);l&&(i=l.installSource,a=l.uploadedArtifactId??a);let c=()=>ew({positionals:r,flags:n,installSource:i,uploadedArtifactId:a,clientArtifactPaths:s});return"install"!==e.command&&"reinstall"!==e.command||(a=await ey(e,t,r)??a),c()}async function ey(e,t,a){var n,i;let s,l=a[1];if(void 0===l)return;if(l.startsWith("remote:")){a[1]=l.slice(7);return}let c=(n=l,i=e.meta?.cwd,s=o.isAbsolute(n)?n:o.resolve(i??process.cwd(),n),r.existsSync(s)?s:void 0);if(c)return await et({localPath:c,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform})}function ew(e){return{positionals:e.positionals,flags:e.flags,installSource:e.installSource,uploadedArtifactId:e.uploadedArtifactId,...Object.keys(e.clientArtifactPaths).length>0?{clientArtifactPaths:e.clientArtifactPaths}:{}}}async function eg(e,t){let a=e.meta?.installSource;if("install_source"!==e.command||!a||"path"!==a.kind)return null;let n=a.path.trim();if(!n)return{installSource:a};if(n.startsWith("remote:"))return{installSource:{...a,path:n.slice(7)}};let i=o.isAbsolute(n)?n:o.resolve(e.meta?.cwd??process.cwd(),n);if(!r.existsSync(i))return{installSource:{...a,path:i}};let s=await et({localPath:i,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform});return{installSource:{...a,path:i},uploadedArtifactId:s}}function eI(e,t,a,r=0){let n=e.positionals?.[r]??e.flags?.out,i=`${"path"===t?"screenshot":"recording"}-${Date.now()}${a}`,s=n&&n.trim().length>0?n:i;return o.isAbsolute(s)?s:o.resolve(e.meta?.cwd??process.cwd(),s)}function ev(e,t){let a=t.startsWith(".")?t:`.${t}`;return o.posix.join("/tmp",`agent-device-${e}-${Date.now()}-${Math.random().toString(36).slice(2,8)}${a}`)}async function eA(e){if(e.remoteBaseUrl)return await e_(e);let t=await eP(e);return t?{info:t,startedByClient:!1}:(function(e){let t=eR(e);if(!t.hasLock||t.hasInfo)return;let a=eU(e.lockPath);if(!a)return ex(e.lockPath);T(a.pid,a.processStartTime)||ex(e.lockPath)}(e.paths),await ek(e))}async function e_(e){let t={transport:"http",token:e.remoteAuthToken??"",pid:0,baseUrl:e.remoteBaseUrl};if(await eF(t,"http"))return{info:t,startedByClient:!1};throw new u("COMMAND_FAILED","Remote daemon is unavailable",{daemonBaseUrl:e.remoteBaseUrl,hint:"Verify AGENT_DEVICE_DAEMON_BASE_URL points to a reachable daemon with GET /health and POST /rpc."})}async function eP(e){var t,a;let r,n=eT(e.paths.infoPath);if(!n)return null;let o=await eF(n,e.transportPreference);return(t=n,a=o,t.version===b()&&t.codeSignature===P((r=eB()).useSrc?r.srcPath:r.distPath,r.root)&&a)?n:(await eM(n),ex(e.paths.infoPath),null)}async function ek(e){let t,a=0,r=[];for(let n=1;n<=2;n+=1){try{await eq(e)}catch(a){if(t=a instanceof Error?a.message:String(a),r.push(await eL(e.paths,"start_error")),n<2){await L(150);continue}break}let o=await eD(15e3,e);if(o)return{info:o,startedByClient:!0};if(await eE(e.paths)){a+=1;continue}let i=eR(e.paths),s=n<2,l=await eL(e.paths,"startup_timeout",{stopLiveProcesses:!1});if(r.push(l),l.retainedInfoProcess||l.retainedLockProcess){let t=await eD(15e3,e);if(t)return{info:t,startedByClient:!0};break}if(!s)break;i.hasInfo||i.hasLock||await L(150)}let n=eR(e.paths);throw new u("COMMAND_FAILED","Failed to start daemon",{kind:"daemon_startup_failed",infoPath:e.paths.infoPath,lockPath:e.paths.lockPath,startupTimeoutMs:15e3,startupAttempts:2,lockRecoveryCount:a,cleanupResults:r,startError:t,metadataState:n,hint:function(e,t=A(process.env.AGENT_DEVICE_STATE_DIR)){var a;let r=(a=t,`rm -f ${w(a.infoPath)} ${w(a.lockPath)}`);return e.hasLock&&!e.hasInfo?`agent-device attempted to clean stale daemon metadata automatically, but ${t.lockPath} still exists without ${t.infoPath}. Retry with --debug; if this persists after confirming no agent-device daemon process is running, run: ${r}`:e.hasLock&&e.hasInfo?`agent-device attempted to clean stale daemon metadata automatically, but ${t.infoPath} and ${t.lockPath} still remain. Retry with --debug; if this persists after confirming no agent-device daemon process is running, run: ${r}`:e.hasInfo?`agent-device did not observe reachable daemon metadata after retrying, and ${t.infoPath} still remains. Stale metadata was cleaned automatically when safe; retry with --debug. If this persists after confirming no agent-device daemon process is running, run: ${r}`:`agent-device did not observe reachable daemon metadata after retrying. Stale metadata was cleaned automatically when safe; retry with --debug and check daemon diagnostics logs. If stale metadata returns after confirming no agent-device daemon process is running, run: ${r}`}(n,e.paths)})}async function eb(e,t,a){if(!eS(e.command)||!t.startedByClient&&!a.ownedStateDir||eY(t.info))return;let n={pid:t.info.pid,removedInfo:!1,removedLock:!1,removedStateDir:!1,error:void 0};try{await eM(t.info)}catch(e){n.error=e instanceof Error?e.message:String(e)}finally{let e=r.existsSync(a.paths.infoPath);ex(a.paths.infoPath),n.removedInfo=e&&!r.existsSync(a.paths.infoPath);let t=r.existsSync(a.paths.lockPath);ex(a.paths.lockPath),n.removedLock=t&&!r.existsSync(a.paths.lockPath),a.ownedStateDir&&(r.rmSync(a.paths.baseDir,{recursive:!0,force:!0}),n.removedStateDir=!r.existsSync(a.paths.baseDir))}M({level:n.error?"warn":"info",phase:"daemon_replay_cleanup",data:n})}function eS(e){return e===U.replay||e===U.test}async function eD(e,t){let a=Date.now();for(;Date.now()-a<e;){let e=eT(t.paths.infoPath);if(e&&await eF(e,t.transportPreference))return e;await L(100)}return null}async function eE(e){let t=eR(e);if(!t.hasLock||t.hasInfo)return!1;let a=eU(e.lockPath);return!(a&&T(a.pid,a.processStartTime))&&(ex(e.lockPath),!0)}async function eM(e){await C(e.pid,{termTimeoutMs:3e3,killTimeoutMs:1e3,expectedStartTime:e.processStartTime})}function eT(e){var t,a,r;let n,o,i=eO(e);if(!i||"object"!=typeof i)return null;let s="string"==typeof(t=i).token&&t.token.length>0?t.token:null;if(!s)return null;let l=(n=eN((a=i).port),o=eN(a.httpPort),void 0===n&&void 0===o?null:{port:n,httpPort:o});return l?{token:s,...l,transport:"socket"===(r=i.transport)||"http"===r||"dual"===r?r:void 0,pid:eN(i.pid)??0,version:eC(i.version),codeSignature:eC(i.codeSignature),processStartTime:eC(i.processStartTime)}:null}function eC(e){return"string"==typeof e?e:void 0}function eN(e){return Number.isInteger(e)&&Number(e)>0?Number(e):void 0}function eU(e){let t=eO(e);return t&&"object"==typeof t&&Number.isInteger(t.pid)&&Number(t.pid)>0?{pid:Number(t.pid),processStartTime:"string"==typeof t.processStartTime?t.processStartTime:void 0,startedAt:"number"==typeof t.startedAt?t.startedAt:void 0}:null}em.addSubnet("127.0.0.0",8,"ipv4"),em.addAddress("::1","ipv6"),em.addSubnet("::ffff:127.0.0.0",104,"ipv6");async function eL(e,t,a={}){let n=a.stopLiveProcesses??!0,o={reason:t,removedInfo:!1,removedLock:!1,stoppedInfoProcess:!1,stoppedLockProcess:!1};try{var i,s,l,c;let t=r.existsSync(e.infoPath),a=eT(e.infoPath);if(a){let t=T(a.pid,a.processStartTime);t&&!n?o.retainedInfoProcess=!0:(t&&(await eM(a),o.stoppedInfoProcess=!0),i=e.infoPath,ex(i),o.removedInfo=!0)}else t&&(s=e.infoPath,ex(s),o.removedInfo=!0);let d=r.existsSync(e.lockPath),u=eU(e.lockPath);if(u){let t=T(u.pid,u.processStartTime);t&&!n?o.retainedLockProcess=!0:(t&&(await C(u.pid,{termTimeoutMs:3e3,killTimeoutMs:1e3,expectedStartTime:u.processStartTime}),o.stoppedLockProcess=!0),l=e.lockPath,ex(l),o.removedLock=!0)}else d&&(c=e.lockPath,ex(c),o.removedLock=!0)}catch(e){o.error=e instanceof Error?e.message:String(e)}return M({level:o.error?"warn":"info",phase:"daemon_startup_metadata_cleanup",data:o}),o}function eR(e){return{hasInfo:r.existsSync(e.infoPath),hasLock:r.existsSync(e.lockPath)}}function eO(e){if(!r.existsSync(e))return null;try{return JSON.parse(r.readFileSync(e,"utf8"))}catch{return null}}function ex(e){try{r.existsSync(e)&&r.unlinkSync(e)}catch{}}async function eF(r,n){var o;return"http"===ej(r,n)?await function(e){let r=e.baseUrl?eQ(e.baseUrl,"health"):e.httpPort?`http://127.0.0.1:${e.httpPort}/health`:null;if(!r)return Promise.resolve(!1);let n=new URL(r),o="https:"===n.protocol?a:t,i=e.baseUrl?3e3:500;return new Promise(e=>{let t=o.request({protocol:n.protocol,host:n.hostname,port:n.port,path:n.pathname+n.search,method:"GET",timeout:i},t=>{t.resume(),e((t.statusCode??500)<500)});t.on("timeout",()=>{t.destroy(),e(!1)}),t.on("error",()=>{e(!1)}),t.end()})}(r):await ((o=r.port)?new Promise(t=>{let a=!1,r=e.createConnection({host:"127.0.0.1",port:o},()=>{n(!0)}),n=e=>{a||(a=!0,r.destroy(),t(e))};r.setTimeout(500),r.on("timeout",()=>{n(!1)}),r.on("error",()=>{n(!1)})}):Promise.resolve(!1))}async function eq(e){let t=eB(),a=t.useSrc?["--experimental-strip-types",t.srcPath]:[t.distPath],r={...process.env,AGENT_DEVICE_STATE_DIR:e.paths.baseDir,AGENT_DEVICE_DAEMON_SERVER_MODE:e.serverMode};f(process.execPath,a,{env:r})}function eB(){let e=S(),t=[o.join(e,"dist","src","internal","daemon.js"),o.join(e,"dist","src","daemon.js")],a=t[0];if(void 0===a)throw new u("COMMAND_FAILED","Daemon dist path list is empty");let n=t.find(e=>r.existsSync(e))??a,i=o.join(e,"src","daemon.ts"),s=t.some(e=>r.existsSync(e)),l=r.existsSync(i);if(!s&&!l)throw new u("COMMAND_FAILED","Daemon entry not found",{distPaths:t,srcPath:i});return{root:e,distPath:n,distPaths:t,srcPath:i,useSrc:process.execArgv.includes("--experimental-strip-types")?l:!s&&l}}async function e$(e,t,a,r){return"http"===ej(e,a)?await eV(e,t,r):await ez(e,t,r)}function ej(e,t){if(e.baseUrl){if("socket"===t)throw new u("COMMAND_FAILED","Remote daemon endpoint only supports HTTP transport",{daemonBaseUrl:e.baseUrl});return"http"}if("http"===t||"socket"===t){var a=e,r=t;if(eH(a,r))return r;throw new u("COMMAND_FAILED","http"===r?"Daemon HTTP endpoint is unavailable":"Daemon socket endpoint is unavailable")}let n=("socket"===e.transport||"dual"===e.transport?["socket","http"]:["http","socket"]).find(t=>eH(e,t));if(n)return n;throw new u("COMMAND_FAILED","Daemon metadata has no reachable transport")}function eH(e,t){return"http"===t?!!e.httpPort:!!e.port}function eK(e,t,a,r,n,o){let i=n?{terminated:0}:function(){let e=0;try{for(let t of ep){let a=p("pkill",["-f",t],{allowFailure:!0});0===a.exitCode&&(e+=1)}return{terminated:e}}catch(t){return{terminated:e,error:t instanceof Error?t.message:String(t)}}}(),s=!n&&"snapshot"!==r,l=s?function(e,t){let a=!1;try{T(e.pid,e.processStartTime)&&(process.kill(e.pid,"SIGKILL"),a=!0)}catch{C(e.pid,{termTimeoutMs:3e3,killTimeoutMs:1e3,expectedStartTime:e.processStartTime})}finally{ex(t.infoPath),ex(t.lockPath)}return{forcedKill:a}}(e,t):{forcedKill:!1};return M({level:"error",phase:"daemon_request_timeout",data:{timeoutMs:o,requestId:a,command:r,timedOutRunnerPidsTerminated:i.terminated,timedOutRunnerCleanupError:i.error,daemonPidReset:s?e.pid:void 0,daemonPidForceKilled:s?l.forcedKill:void 0,daemonPreservedAfterTimeout:!n&&!s,daemonBaseUrl:e.baseUrl}}),new u("COMMAND_FAILED","Daemon request timed out",{timeoutMs:o,requestId:a,hint:function(e){let{remote:t,resetDaemon:a,command:r}=e;if(t)return"Retry with --debug and verify the remote daemon URL, auth token, and remote host logs.";if(!a){let e=r===U.snapshot?" If this was the first Apple-platform snapshot on the device, run agent-device prepare ios-runner with the same --platform before snapshot/test so runner startup is handled explicitly.":"";return`Retry with --debug and check daemon diagnostics logs. The timed-out ${r??"request"} request was canceled and Apple runner work was aborted when detected; the daemon was kept alive so the session can still be closed or inspected.${e}`}return"Retry with --debug and check daemon diagnostics logs. Timed-out Apple runner xcodebuild processes were terminated when detected."}({remote:n,resetDaemon:s,command:r})})}function eG(e,t,a){return M({level:"error",phase:"daemon_request_socket_error",data:{requestId:t,message:e instanceof Error?e.message:String(e)}}),new u("COMMAND_FAILED","Failed to communicate with daemon",{requestId:t,hint:a?"Retry command. If this persists, verify the remote daemon URL, auth token, and remote host reachability.":"Retry command. If this persists, clean stale daemon metadata and start a fresh session."},e instanceof Error?e:void 0)}async function ez(t,a,r){let n=t.port;if(!n)throw new u("COMMAND_FAILED","Daemon socket endpoint is unavailable");return new Promise((o,i)=>{let s=e.createConnection({host:"127.0.0.1",port:n},()=>{s.write(`${JSON.stringify(a)}
|
|
3
|
-
`)}),l=A(a.flags?.stateDir??process.env.AGENT_DEVICE_STATE_DIR),c=!1,d="number"==typeof r?setTimeout(()=>{c=!0,s.destroy(),i(eK(t,l,a.meta?.requestId,a.command,!1,r))},r):void 0,p="";s.setEncoding("utf8"),s.on("data",e=>{if(c)return;let t=y(p,e);for(let e of(p=t.buffer,t.lines))try{let t=JSON.parse(e);if(v(t)){eu(t.event);continue}let a=I(t)?t.response:t;c=!0,s.end(),d&&clearTimeout(d),o(a);return}catch(t){c=!0,d&&clearTimeout(d),i(new u("COMMAND_FAILED","Invalid daemon response",{requestId:a.meta?.requestId,line:e},t instanceof Error?t:void 0));return}}),s.on("error",e=>{c||(c=!0,d&&clearTimeout(d),i(eG(e,a.meta?.requestId,!1)))})})}async function eV(e,r,n){var o,i,s;let l,c=e.baseUrl?new URL(eQ(e.baseUrl,"rpc")):e.httpPort?new URL(`http://127.0.0.1:${e.httpPort}/rpc`):null;if(!c)throw new u("COMMAND_FAILED","Daemon HTTP endpoint is unavailable");let d=JSON.stringify((o=r,i={includeTokenParam:!e.baseUrl},l=o.meta?.requestId??D(),"lease_allocate"!==(s=o.command)&&"lease_heartbeat"!==s&&"lease_release"!==s?{jsonrpc:"2.0",id:l,method:"agent_device.command",params:o}:{jsonrpc:"2.0",id:l,method:function(e){switch(e){case"lease_allocate":return"agent_device.lease.allocate";case"lease_heartbeat":return"agent_device.lease.heartbeat";case"lease_release":return"agent_device.lease.release"}}(o.command),params:function(e,t,a){let r={...a.includeTokenParam?{token:e.token}:{},session:e.session,tenantId:e.meta?.tenantId,runId:e.meta?.runId};switch(t){case"lease_allocate":return{...r,ttlMs:e.meta?.leaseTtlMs,backend:e.meta?.leaseBackend};case"lease_heartbeat":return{...r,leaseId:e.meta?.leaseId,ttlMs:e.meta?.leaseTtlMs};case"lease_release":return{...r,leaseId:e.meta?.leaseId}}}(o,o.command,i)})),p={"content-type":"application/json","content-length":Buffer.byteLength(d)};return e.baseUrl&&e.token&&(p.authorization=`Bearer ${e.token}`,p["x-agent-device-token"]=e.token),await new Promise((o,i)=>{let s=A(r.flags?.stateDir??process.env.AGENT_DEVICE_STATE_DIR),l=("https:"===c.protocol?a:t).request({protocol:c.protocol,host:c.hostname,port:c.port,method:"POST",path:c.pathname+c.search,headers:p},t=>{var a;(a=t.headers?.["content-type"],g(r)&&String(Array.isArray(a)?a.join(","):a??"").includes("application/x-ndjson"))?function(e,t){let{req:a,handleResponseBody:r,reject:n,clearTimeout:o}=t,i="",s=!1,l=e=>{try{let t=JSON.parse(e);if(v(t))return eu(t.event),!1;if(I(t))return s=!0,o(),r(JSON.stringify(t.response)),!0;throw Error("Missing daemon progress response envelope")}catch(t){return s=!0,o(),n(new u("COMMAND_FAILED","Invalid daemon response",{requestId:a.meta?.requestId,line:e},t instanceof Error?t:void 0)),!0}};e.setEncoding("utf8"),e.on("data",e=>{if(s)return;let t=y(i,e);for(let e of(i=t.buffer,t.lines))if(e&&l(e))return}),e.on("end",()=>{if(s)return;let e=i.trim();e&&l(e)||(s=!0,o(),n(new u("COMMAND_FAILED","Invalid daemon response",{requestId:a.meta?.requestId,line:e})))}),e.on("error",e=>{s||(s=!0,o(),n(new u("COMMAND_FAILED","Failed to read daemon response",{requestId:a.meta?.requestId},e instanceof Error?e:void 0)))})}(t,{req:r,reject:i,clearTimeout:()=>{f&&clearTimeout(f)},handleResponseBody:t=>eW(t,{info:e,req:r,resolve:o,reject:i})}):Z(t).then(t=>{f&&clearTimeout(f),eW(t,{info:e,req:r,resolve:o,reject:i})}).catch(e=>{f&&clearTimeout(f),i(new u("COMMAND_FAILED","Failed to read daemon response",{requestId:r.meta?.requestId},e instanceof Error?e:void 0))})}),m=eY(e),f="number"==typeof n?setTimeout(()=>{l.destroy(),i(eK(e,s,r.meta?.requestId,r.command,m,n))},n):void 0;l.on("error",e=>{f&&clearTimeout(f),i(eG(e,r.meta?.requestId,m))}),l.write(d),l.end()})}function eW(e,t){let{info:a,req:r,resolve:n,reject:o}=t;try{var i,s,l;let t=(i=e,JSON.parse(i));if(t.error){let e;return void o((s=t.error,l=r.meta?.requestId,e=s.data??{},new u(d(null!=e.code?String(e.code):void 0,"COMMAND_FAILED"),String(e.message??s.message??"Daemon RPC request failed"),{..."object"==typeof e.details&&e.details?e.details:{},hint:"string"==typeof e.hint?e.hint:void 0,diagnosticId:"string"==typeof e.diagnosticId?e.diagnosticId:void 0,logPath:"string"==typeof e.logPath?e.logPath:void 0,requestId:l})))}if(!t.result||"object"!=typeof t.result)return void o(new u("COMMAND_FAILED","Invalid daemon RPC response",{requestId:r.meta?.requestId}));eJ(a,r,t.result,n,o)}catch(t){o(new u("COMMAND_FAILED","Invalid daemon response",{requestId:r.meta?.requestId,line:e},t instanceof Error?t:void 0))}}async function eJ(e,t,a,r,n){try{r(e.baseUrl&&a.ok?await eX(e,t,a):a)}catch(e){n(e)}}function eY(e){return"string"==typeof e.baseUrl&&e.baseUrl.length>0}function eQ(e,t){return new URL(t,e.endsWith("/")?e:`${e}/`).toString()}async function eX(e,t,a){let r=Array.isArray(a.data?.artifacts)?a.data.artifacts:[];if(0===r.length||!e.baseUrl)return a;let n=a.data?{...a.data}:{},i=[];for(let a of r){if(!a||"object"!=typeof a||"string"!=typeof a.artifactId){i.push(a);continue}let r=function(e,t){if(e.localPath&&e.localPath.trim().length>0)return e.localPath;let a=t.meta?.clientArtifactPaths?.[e.field];if(a&&a.trim().length>0)return a;let r=e.fileName?.trim()||`${e.field}-${Date.now()}`;return o.resolve(t.meta?.cwd??process.cwd(),r)}(a,t);await eZ({baseUrl:e.baseUrl,token:e.token,artifactId:a.artifactId,destinationPath:r,requestId:t.meta?.requestId}),n[a.field]=r,i.push({...a,localPath:r})}return n.artifacts=i,{ok:!0,data:n}}async function eZ(e){var n,s;let l,c=new URL((n=e.baseUrl,s=e.artifactId,l=n.endsWith("/")?n:`${n}/`,new URL(`artifacts/${encodeURIComponent(s)}`,l).toString())),d="https:"===c.protocol?a:t;await r.promises.mkdir(o.dirname(e.destinationPath),{recursive:!0}),await new Promise((t,a)=>{let n=!1,o=e.timeoutMs??9e4,s=o=>{if(!n){if(n=!0,clearTimeout(p),o)return void r.promises.rm(e.destinationPath,{force:!0}).finally(()=>a(o));t()}},l=d.request({protocol:c.protocol,host:c.hostname,port:c.port,method:"GET",path:c.pathname+c.search,headers:e.token?{authorization:`Bearer ${e.token}`,"x-agent-device-token":e.token}:void 0},t=>{if((t.statusCode??500)>=400){let a="";t.setEncoding("utf8"),t.on("data",e=>{a+=e}),t.on("end",()=>{s(new u("COMMAND_FAILED","Failed to download remote artifact",{artifactId:e.artifactId,statusCode:t.statusCode,requestId:e.requestId,body:a}))});return}t.on("aborted",()=>{s(new u("COMMAND_FAILED","Remote artifact download was interrupted",{artifactId:e.artifactId,requestId:e.requestId}))}),i(t,r.createWriteStream(e.destinationPath)).then(()=>s(),e=>s(e instanceof Error?e:Error(String(e))))}),p=setTimeout(()=>{let t=new u("COMMAND_FAILED","Remote artifact download timed out",{artifactId:e.artifactId,requestId:e.requestId,timeoutMs:o});s(t),l.destroy(t)},o);l.on("error",t=>{t instanceof u?s(t):s(new u("COMMAND_FAILED","Failed to download remote artifact",{artifactId:e.artifactId,requestId:e.requestId,timeoutMs:o},t instanceof Error?t:void 0))}),l.end()})}function e0(e={},t={}){let a=t.transport??ef,r=async(t,r=[],n={})=>{var o,i;let s=(o=e,i=n,{...o,...i}),l=await a({session:F(s.session),command:t,positionals:r,flags:q(s),runtime:s.runtime,meta:J(s)});return l.ok||function(e){throw new u(d(e.code),e.message,{...e.details??{},hint:e.hint,diagnosticId:e.diagnosticId,logPath:e.logPath})}(l.error),l.data??{}},n=async(e={})=>{let t=await r(N.sessionList,[],e);return(Array.isArray(t.sessions)?t.sessions:[]).map(x)},o=async(e,t={})=>{let a=H(e,t);return await r(a.command,a.positionals,a.options)},i=(t={})=>{var a,r;return F((a=e,r=t,{...a,...r}).session)};return{command:{wait:async e=>await o("wait",e),alert:async(e={})=>await o("alert",e),appState:async(e={})=>await o("appstate",e),back:async(e={})=>await o("back",e),home:async(e={})=>await o("home",e),rotate:async e=>await o("rotate",e),appSwitcher:async(e={})=>await o("app-switcher",e),keyboard:async(e={})=>await o("keyboard",e),clipboard:async e=>await o("clipboard",e),reactNative:async e=>await o("react-native",e),prepare:async e=>await o("prepare",e)},devices:{list:async(e={})=>{let t=await o("devices",e);return(Array.isArray(t.devices)?t.devices:[]).map(Y)},boot:async(e={})=>await o("boot",e)},sessions:{list:async(e={})=>await n(e),close:async(e={})=>{let t=i(e),a=(await o("close",e)).shutdown;return{session:t,shutdown:"object"==typeof a&&null!==a?a:void 0,identifiers:{session:t}}}},apps:{install:async e=>z(await o("install",e),i(e)),reinstall:async e=>z(await o("reinstall",e),i(e)),installFromSource:async e=>$(await o("install-from-source",e),i(e)),list:async(e={})=>{let t=await o("apps",e);return Array.isArray(t.apps)?t.apps.filter(e=>"string"==typeof e):[]},open:async e=>{let t=i(e),a=await o("open",e),r=V(a),n=X(a,"appBundleId");return{session:t,sessionStateDir:X(a,"sessionStateDir"),appName:X(a,"appName"),appBundleId:n,appId:n,startup:B(a.startup),runtime:G(a.runtime),device:r,identifiers:{session:t,deviceId:r?.id,deviceName:r?.name,udid:r?.ios?.udid,serial:r?.android?.serial,appId:n,appBundleId:n}}},close:async(e={})=>{let t=i(e),a=(await o("close",e)).shutdown;return{session:t,closedApp:e.app,shutdown:"object"==typeof a&&null!==a?a:void 0,identifiers:{session:t}}},push:async e=>await o("push",e),triggerEvent:async e=>await o("trigger-app-event",e)},materializations:{release:async e=>j(await r(N.releaseMaterializedPaths,[],{...e,materializationId:e.materializationId}))},leases:{allocate:async e=>e5(await r(N.leaseAllocate,[],{...e,leaseId:void 0,leaseTtlMs:e.ttlMs})),heartbeat:async e=>e5(await r(N.leaseHeartbeat,[],{...e,leaseTtlMs:e.ttlMs})),release:async e=>({released:!0===(await r(N.leaseRelease,[],e)).released})},metro:{prepare:async t=>await O({projectRoot:t.projectRoot??e.cwd,kind:t.kind,publicBaseUrl:t.publicBaseUrl,proxyBaseUrl:t.proxyBaseUrl,proxyBearerToken:t.bearerToken,bridgeScope:t.bridgeScope,launchUrl:t.launchUrl,companionProfileKey:t.companionProfileKey,companionConsumerKey:t.companionConsumerKey,metroPort:t.port,listenHost:t.listenHost,statusHost:t.statusHost,startupTimeoutMs:t.startupTimeoutMs,probeTimeoutMs:t.probeTimeoutMs,reuseExisting:t.reuseExisting,installDependenciesIfNeeded:t.installDependenciesIfNeeded,runtimeFilePath:t.runtimeFilePath,logPath:t.logPath}),reload:async(t={})=>await R({metroHost:t.metroHost,metroPort:t.metroPort,bundleUrl:t.bundleUrl,runtime:e.runtime,timeoutMs:t.timeoutMs})},capture:{snapshot:async(e={})=>{var t,a,r;let n,s,l,c,d,u=i(e);return t=await o("snapshot",e),a=u,n=X(t,"appBundleId"),{nodes:K(t.nodes),truncated:!0===t.truncated,appName:X(t,"appName"),appBundleId:n,...(s=e1((r=t).visibility),l=e1(r.androidSnapshot),c=e1(r.unchanged),d=Array.isArray(r.warnings)?r.warnings.filter(e=>"string"==typeof e):void 0,{...s?{visibility:s}:{},...l?{androidSnapshot:l}:{},...c?{unchanged:c}:{},...d?{warnings:d}:{}}),identifiers:{session:a,appId:n,appBundleId:n}}},screenshot:async(e={})=>{let t=i(e),a=await o("screenshot",e);return{path:Q(a,"path"),overlayRefs:W(a),identifiers:{session:t}}},diff:async e=>await o("diff",e)},interactions:{click:async e=>await o("click",e),press:async e=>await o("press",e),longPress:async e=>await o("longpress",e),swipe:async e=>await o("swipe",e),pan:async e=>await o("gesture-pan",e),fling:async e=>await o("gesture-fling",e),swipeGesture:async e=>await o("gesture-swipe",e),focus:async e=>await o("focus",e),type:async e=>await o("type",e),fill:async e=>await o("fill",e),scroll:async e=>await o("scroll",e),pinch:async e=>await o("gesture-pinch",e),rotateGesture:async e=>await o("gesture-rotate",e),transformGesture:async e=>await o("gesture-transform",e),get:async e=>await o("get",e),is:async e=>await o("is",e),find:async e=>await o("find",e)},replay:{run:async e=>await o("replay",e),test:async e=>await o("test",e)},batch:{run:async e=>await o("batch",e)},observability:{perf:async(e={})=>await o("perf",e),logs:async(e={})=>await o("logs",e),network:async(e={})=>await o("network",e)},recording:{record:async e=>await o("record",e),trace:async e=>await o("trace",e)},settings:{update:async e=>await o("settings",e)}}}function e1(e){return"object"==typeof e&&null!==e?e:void 0}function e5(e){let t=e.lease;if(!t||"object"!=typeof t||Array.isArray(t))throw Error("Invalid lease response from daemon");return{leaseId:Q(t,"leaseId"),tenantId:Q(t,"tenantId"),runId:Q(t,"runId"),backend:Q(t,"backend"),createdAt:"number"==typeof t.createdAt?t.createdAt:void 0,heartbeatAt:"number"==typeof t.heartbeatAt?t.heartbeatAt:void 0,expiresAt:"number"==typeof t.expiresAt?t.expiresAt:void 0}}export{e0 as createAgentDeviceClient,ef as sendToDaemon};
|
|
1
|
+
import e from"node:net";import t from"node:http";import a from"node:https";import r from"node:fs";import n from"node:os";import o from"node:path";import{pipeline as i}from"node:stream/promises";import{createHash as s,randomUUID as l}from"node:crypto";import{Writable as c}from"node:stream";import{toAppErrorCode as d,AppError as u}from"./9152.js";import{runCmdSync as p,runCmd as m,runCmdDetached as f}from"./9818.js";import{consumeTextLines as h,shellQuote as y,shouldStreamRequestProgress as w,isDaemonResponseEnvelope as g,resolveDaemonPaths as I,isDaemonProgressEnvelope as v,resolveDaemonServerMode as A,computeDaemonCodeSignature as _,resolveDaemonTransportPreference as P}from"./9238.js";import{readVersion as k,findProjectRoot as S}from"./9671.js";import{createRequestId as b,withDiagnosticTimer as D,emitDiagnostic as E}from"./7599.js";import{isAgentDeviceDaemonProcess as M,stopProcessForTakeover as T}from"./8656.js";import{INTERNAL_COMMANDS as N,PUBLIC_COMMANDS as C}from"./5792.js";import{sleep as L}from"./4829.js";import{reloadMetro as U,prepareMetroRuntime as R}from"./1974.js";import{normalizeSession as x,resolveSessionName as O,buildFlags as $,normalizeStartupSample as F,normalizeInstallFromSourceResult as B,normalizeMaterializationReleaseResult as q,prepareDaemonCommandRequest as j,readSnapshotNodes as K,normalizeRuntimeHints as H,normalizeDeployResult as G,normalizeOpenDevice as z,readScreenshotOverlayRefs as V,buildMeta as J,normalizeDevice as W}from"./8699.js";import{readRequiredString as Y,readOptionalString as Q}from"./7455.js";function X(e){return new Promise((t,a)=>{let r="";e.setEncoding("utf8"),e.on("data",e=>{r+=e}),e.on("end",()=>t(r)),e.on("error",a)})}let Z="sha256";async function ee(e){let t=await et(e.localPath,e.platform),a=e.baseUrl.endsWith("/")?e.baseUrl:`${e.baseUrl}/`;try{let r=await eo({normalizedBase:a,token:e.token,artifact:t});if(r?.kind==="cache-hit")return r.uploadId;if(r?.kind==="direct-upload")try{return await ei(t.payloadPath,r),await el({normalizedBase:a,token:e.token,uploadId:r.uploadId})}catch{}return await en({normalizedBase:a,token:e.token,artifact:t})}finally{t.cleanup()}}async function et(e,t){var a,n,i;let s,l=r.statSync(e),c=o.basename(e),d=l.isDirectory(),u=("ios"===(a=t)||"android"===a?a:void 0)??(n=e,i=l,s=n.toLowerCase(),i.isDirectory()&&s.endsWith(".app")||s.endsWith(".ipa")?"ios":s.endsWith(".apk")||s.endsWith(".aab")?"android":void 0),p=[];try{let t=d?await ea(e,p):e,a=r.statSync(t);return{payloadPath:t,fileName:c,artifactType:d?"app-bundle":"file",platform:u,contentType:d?"application/gzip":"application/octet-stream",sha256:await ec(t),sizeBytes:a.size,cleanup:()=>er(p)}}catch(e){throw er(p),e}}async function ea(e,t){let a=r.mkdtempSync(o.join(n.tmpdir(),`agent-device-upload-${l()}-`));t.push(a);let i=o.join(a,`${o.basename(e)}.tar.gz`);return await m("tar",["czf",i,"-C",o.dirname(e),o.basename(e)],{env:{...process.env,COPYFILE_DISABLE:"1"}}),i}function er(e){for(let t of e)r.rmSync(t,{recursive:!0,force:!0})}async function en(e){let{normalizedBase:t,token:a,artifact:r}=e,n=new URL("upload",t),o={"content-type":r.contentType,"x-artifact-type":r.artifactType,"x-artifact-filename":r.fileName,"x-artifact-hash":r.sha256,"x-artifact-hash-algorithm":Z,"transfer-encoding":"chunked"};a&&(o.authorization=`Bearer ${a}`,o["x-agent-device-token"]=a);let i=await es({url:n,method:"POST",headers:o,payloadPath:r.payloadPath,timeoutMessage:"Artifact upload timed out",timeoutHint:"The upload to the remote daemon exceeded the 5-minute timeout.",errorMessage:"Failed to upload artifact to remote daemon",errorHint:"Verify the remote daemon is reachable and supports artifact uploads."});try{let e=JSON.parse(i.body);if(!e.ok||!e.uploadId)throw new u("COMMAND_FAILED",`Upload failed: ${i.body}`);return e.uploadId}catch(e){if(e instanceof u)throw e;throw new u("COMMAND_FAILED",`Invalid upload response: ${i.body}`)}}async function eo(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 ei(e,t){let a=await es({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 es(e){let n="https:"===e.url.protocol?a:t;return await new Promise((t,a)=>{let o=n.request({protocol:e.url.protocol,host:e.url.hostname,port:e.url.port,method:e.method,path:e.url.pathname+e.url.search,headers:e.headers},e=>{X(e).then(a=>{clearTimeout(s),t({statusCode:e.statusCode??500,statusMessage:e.statusMessage,body:a})}).catch(a)}),s=setTimeout(()=>{o.destroy(),a(new u("COMMAND_FAILED",e.timeoutMessage,{timeoutMs:3e5,...e.timeoutHint?{hint:e.timeoutHint}:{}}))},3e5);o.on("error",t=>{clearTimeout(s),a(new u("COMMAND_FAILED",e.errorMessage,e.errorHint?{hint:e.errorHint}:{},t))}),o.on("close",()=>clearTimeout(s)),i(r.createReadStream(e.payloadPath),o).catch(e=>{o.destroy(),a(new u("COMMAND_FAILED","Failed to read local artifact",{},e instanceof Error?e:Error(String(e))))})})}async function el(e){let t=new URL("upload/finalize",e.normalizedBase),a={"content-type":"application/json"};e.token&&(a.authorization=`Bearer ${e.token}`,a["x-agent-device-token"]=e.token);let r=await fetch(t,{method:"POST",headers:a,signal:AbortSignal.timeout(3e4),body:JSON.stringify({uploadId:e.uploadId})}).catch(e=>{throw new u("COMMAND_FAILED","Failed to finalize direct artifact upload",{},e)});if(!r.ok)throw new u("COMMAND_FAILED","Direct artifact upload finalize failed",{status:r.status,statusText:r.statusText});let n=await r.json().catch(()=>void 0);if(!n?.ok||!n.uploadId)throw new u("COMMAND_FAILED","Invalid upload finalize response");return n.uploadId}async function ec(e){let t=s(Z),a=new c({write(e,a,r){t.update(e),r()}});return await i(r.createReadStream(e),a).catch(e=>{throw new u("COMMAND_FAILED","Failed to read local artifact",{},e instanceof Error?e:void 0)}),t.digest("hex")}function ed(e){let t=Math.max(0,e)/1e3;return t>=10?`${t.toFixed(1)}s`:t>=1?`${t.toFixed(2)}s`:`${t.toFixed(3).replace(/0+$/,"").replace(/\.$/,"")}s`}function eu(e){let t=function(e){var t,a,r;let n,i;if("replay-test"!==e.type||"pass"===e.status||"fail"===e.status&&!e.retrying)return;let s=(t=e,(n=t.title?.trim())?JSON.stringify(n):o.basename(t.file)),l=void 0!==e.durationMs?` (${i=ed((a=e).durationMs??0),a.attempt&&a.attempt>1&&!a.retrying?`total ${i}`:i})`:"",c=void 0===(r=e).attempt?"":"fail"===r.status&&r.retrying&&void 0!==r.maxAttempts?` attempt ${r.attempt}/${r.maxAttempts} retrying`:r.attempt>1?` after ${r.attempt} attempts`:"",d=e.message?.replace(/\s+/g," ").trim();return"skip"===e.status?[`SKIP ${s}`,d?` ${d}`:""].filter(Boolean).join("\n"):[`FAIL ${s}${c}${l}`,d?` ${d}`:"",e.artifactsDir?` artifacts: ${e.artifactsDir}`:""].filter(Boolean).join("\n")}(e);t&&process.stderr.write(`${t}
|
|
2
|
+
`)}let ep=["xcodebuild .*AgentDeviceRunnerUITests/RunnerTests/testCommand","xcodebuild .*AgentDeviceRunner\\.env\\.session-","xcodebuild build-for-testing .*ios-runner/AgentDeviceRunner/AgentDeviceRunner\\.xcodeproj"],em=new e.BlockList;async function ef(t){var a,i,s,l,c,d;let p,m,f,h,y,w,g,v=t.meta?.requestId??b(),_=!!(t.meta?.debug||t.flags?.verbose),k=(h=(i=a=t,i.flags?.stateDir??process.env.AGENT_DEVICE_STATE_DIR),y=(s=a,m=function(e){let t;if(e){try{t=new URL(e)}catch(t){throw new u("INVALID_ARGS","Invalid daemon base URL",{daemonBaseUrl:e},t instanceof Error?t:void 0)}if("http:"!==t.protocol&&"https:"!==t.protocol)throw new u("INVALID_ARGS","Daemon base URL must use http or https",{daemonBaseUrl:e});return t.toString().replace(/\/+$/,"")}}(p=s.flags?.daemonBaseUrl??process.env.AGENT_DEVICE_DAEMON_BASE_URL),function(t,a){let r;if(!(!t||"localhost"===(r=new URL(t).hostname.trim().toLowerCase().replace(/^\[(.*)\]$/,"$1"))||(e.isIPv4(r)?em.check(r,"ipv4"):!!e.isIPv6(r)&&em.check(r,"ipv6")))&&("string"!=typeof a||!(a.trim().length>0)))throw new u("INVALID_ARGS","Remote daemon base URL for non-loopback hosts requires daemon authentication",{daemonBaseUrl:t,hint:"Provide --daemon-auth-token or AGENT_DEVICE_DAEMON_AUTH_TOKEN when using a non-loopback remote daemon URL."})}(m,f=s.flags?.daemonAuthToken??process.env.AGENT_DEVICE_DAEMON_AUTH_TOKEN),{rawBaseUrl:p,remoteBaseUrl:m,authToken:f}),w=function(e,t){let a=e.flags?.daemonTransport??process.env.AGENT_DEVICE_DAEMON_TRANSPORT,r=P(a);if(t&&"socket"===r)throw new u("INVALID_ARGS","Remote daemon base URL only supports HTTP transport. Remove --daemon-transport socket.",{daemonBaseUrl:t});return{preference:r,serverMode:A(e.flags?.daemonServerMode??process.env.AGENT_DEVICE_DAEMON_SERVER_MODE??("dual"===a?"dual":void 0))}}(a,y.remoteBaseUrl),{paths:I((g=(l=a,c=h,d=y.rawBaseUrl,eb(l.command)&&!c&&!d))?r.mkdtempSync(o.join(n.tmpdir(),"agent-device-replay-daemon-")):h),transportPreference:w.preference,serverMode:w.serverMode,ownedStateDir:g,remoteBaseUrl:y.remoteBaseUrl,remoteAuthToken:y.authToken}),S=function(e){if(e.command!==C.test){var t;return"number"==typeof e.flags?.timeoutMs&&((t=e.command)===C.prepare||t===C.replay||t===C.snapshot)?e.flags.timeoutMs:e.command===C.prepare?24e4:9e4}}(t),M=await D("daemon_startup",async()=>await eA(k),{requestId:v,session:t.session}),T=M.info,N=await eh(t,T),L={...t,positionals:N.positionals,flags:N.flags,token:T.token,meta:{...t.meta??{},requestId:v,debug:_,cwd:t.meta?.cwd,sessionExplicit:t.meta?.sessionExplicit,tenantId:t.meta?.tenantId??t.flags?.tenant,runId:t.meta?.runId??t.flags?.runId,leaseId:t.meta?.leaseId??t.flags?.leaseId,sessionIsolation:t.meta?.sessionIsolation??t.flags?.sessionIsolation,lockPolicy:t.meta?.lockPolicy,lockPlatform:t.meta?.lockPlatform,...N.uploadedArtifactId?{uploadedArtifactId:N.uploadedArtifactId}:{},...N.clientArtifactPaths?{clientArtifactPaths:N.clientArtifactPaths}:{},...N.installSource?{installSource:N.installSource}:{}}};E({level:"info",phase:"daemon_request_prepare",data:{requestId:v,command:t.command,session:t.session}});try{return await D("daemon_request",async()=>await eq(T,L,k.transportPreference,S),{requestId:v,command:t.command})}finally{await eS(t,M,k)}}async function eh(e,t){let a,r=[...e.positionals??[]],n=e.flags?{...e.flags}:void 0,i=e.meta?.installSource,s={};if(!eY(t))return ew({positionals:r,flags:n,installSource:i,uploadedArtifactId:a,clientArtifactPaths:s});n=function(e,t,a,r){var n,i;let s=function(e,t){if("screenshot"===e.command){let a=eI(e,"path",".png");return t[0]?{field:"path",localPath:a,positionalIndex:0,positionalPath:ev("screenshot",".png")}:{field:"path",localPath:a,positionalIndex:0,flagPath:ev("screenshot",".png")}}if("record"===e.command&&"start"===(t[0]??"").toLowerCase()){let t=eI(e,"outPath",".mp4",1);return{field:"outPath",localPath:t,positionalIndex:1,positionalPath:ev("recording",o.extname(t)||".mp4")}}return null}(e,t);if(!s)return a;void 0!==s.positionalPath&&(t[s.positionalIndex]=s.positionalPath);let l=(n=a,void 0===(i=s.flagPath)?n:{...n??{},out:i});return r[s.field]=s.localPath,l}(e,r,n,s);let l=await eg(e,t);l&&(i=l.installSource,a=l.uploadedArtifactId??a);let c=()=>ew({positionals:r,flags:n,installSource:i,uploadedArtifactId:a,clientArtifactPaths:s});return"install"!==e.command&&"reinstall"!==e.command||(a=await ey(e,t,r)??a),c()}async function ey(e,t,a){var n,i;let s,l=a[1];if(void 0===l)return;if(l.startsWith("remote:")){a[1]=l.slice(7);return}let c=(n=l,i=e.meta?.cwd,s=o.isAbsolute(n)?n:o.resolve(i??process.cwd(),n),r.existsSync(s)?s:void 0);if(c)return await ee({localPath:c,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform})}function ew(e){return{positionals:e.positionals,flags:e.flags,installSource:e.installSource,uploadedArtifactId:e.uploadedArtifactId,...Object.keys(e.clientArtifactPaths).length>0?{clientArtifactPaths:e.clientArtifactPaths}:{}}}async function eg(e,t){let a=e.meta?.installSource;if("install_source"!==e.command||!a||"path"!==a.kind)return null;let n=a.path.trim();if(!n)return{installSource:a};if(n.startsWith("remote:"))return{installSource:{...a,path:n.slice(7)}};let i=o.isAbsolute(n)?n:o.resolve(e.meta?.cwd??process.cwd(),n);if(!r.existsSync(i))return{installSource:{...a,path:i}};let s=await ee({localPath:i,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform});return{installSource:{...a,path:i},uploadedArtifactId:s}}function eI(e,t,a,r=0){let n=e.positionals?.[r]??e.flags?.out,i=`${"path"===t?"screenshot":"recording"}-${Date.now()}${a}`,s=n&&n.trim().length>0?n:i;return o.isAbsolute(s)?s:o.resolve(e.meta?.cwd??process.cwd(),s)}function ev(e,t){let a=t.startsWith(".")?t:`.${t}`;return o.posix.join("/tmp",`agent-device-${e}-${Date.now()}-${Math.random().toString(36).slice(2,8)}${a}`)}async function eA(e){if(e.remoteBaseUrl)return await e_(e);let t=await eP(e);return t?{info:t,startedByClient:!1}:(function(e){let t=eR(e);if(!t.hasLock||t.hasInfo)return;let a=eL(e.lockPath);if(!a)return eO(e.lockPath);M(a.pid,a.processStartTime)||eO(e.lockPath)}(e.paths),await ek(e))}async function e_(e){let t={transport:"http",token:e.remoteAuthToken??"",pid:0,baseUrl:e.remoteBaseUrl};if(await e$(t,"http"))return{info:t,startedByClient:!1};throw new u("COMMAND_FAILED","Remote daemon is unavailable",{daemonBaseUrl:e.remoteBaseUrl,hint:"Verify AGENT_DEVICE_DAEMON_BASE_URL points to a reachable daemon with GET /health and POST /rpc."})}async function eP(e){var t,a;let r,n=eT(e.paths.infoPath);if(!n)return null;let o=await e$(n,e.transportPreference);return(t=n,a=o,t.version===k()&&t.codeSignature===_((r=eB()).useSrc?r.srcPath:r.distPath,r.root)&&a)?n:(await eM(n),eO(e.paths.infoPath),null)}async function ek(e){let t,a=0,r=[];for(let n=1;n<=2;n+=1){try{await eF(e)}catch(a){if(t=a instanceof Error?a.message:String(a),r.push(await eU(e.paths,"start_error")),n<2){await L(150);continue}break}let o=await eD(15e3,e);if(o)return{info:o,startedByClient:!0};if(await eE(e.paths)){a+=1;continue}let i=eR(e.paths),s=n<2,l=await eU(e.paths,"startup_timeout",{stopLiveProcesses:!1});if(r.push(l),l.retainedInfoProcess||l.retainedLockProcess){let t=await eD(15e3,e);if(t)return{info:t,startedByClient:!0};break}if(!s)break;i.hasInfo||i.hasLock||await L(150)}let n=eR(e.paths);throw new u("COMMAND_FAILED","Failed to start daemon",{kind:"daemon_startup_failed",infoPath:e.paths.infoPath,lockPath:e.paths.lockPath,startupTimeoutMs:15e3,startupAttempts:2,lockRecoveryCount:a,cleanupResults:r,startError:t,metadataState:n,hint:function(e,t=I(process.env.AGENT_DEVICE_STATE_DIR)){var a;let r=(a=t,`rm -f ${y(a.infoPath)} ${y(a.lockPath)}`);return e.hasLock&&!e.hasInfo?`agent-device attempted to clean stale daemon metadata automatically, but ${t.lockPath} still exists without ${t.infoPath}. Retry with --debug; if this persists after confirming no agent-device daemon process is running, run: ${r}`:e.hasLock&&e.hasInfo?`agent-device attempted to clean stale daemon metadata automatically, but ${t.infoPath} and ${t.lockPath} still remain. Retry with --debug; if this persists after confirming no agent-device daemon process is running, run: ${r}`:e.hasInfo?`agent-device did not observe reachable daemon metadata after retrying, and ${t.infoPath} still remains. Stale metadata was cleaned automatically when safe; retry with --debug. If this persists after confirming no agent-device daemon process is running, run: ${r}`:`agent-device did not observe reachable daemon metadata after retrying. Stale metadata was cleaned automatically when safe; retry with --debug and check daemon diagnostics logs. If stale metadata returns after confirming no agent-device daemon process is running, run: ${r}`}(n,e.paths)})}async function eS(e,t,a){if(!eb(e.command)||!t.startedByClient&&!a.ownedStateDir||eY(t.info))return;let n={pid:t.info.pid,removedInfo:!1,removedLock:!1,removedStateDir:!1,error:void 0};try{await eM(t.info)}catch(e){n.error=e instanceof Error?e.message:String(e)}finally{let e=r.existsSync(a.paths.infoPath);eO(a.paths.infoPath),n.removedInfo=e&&!r.existsSync(a.paths.infoPath);let t=r.existsSync(a.paths.lockPath);eO(a.paths.lockPath),n.removedLock=t&&!r.existsSync(a.paths.lockPath),a.ownedStateDir&&(r.rmSync(a.paths.baseDir,{recursive:!0,force:!0}),n.removedStateDir=!r.existsSync(a.paths.baseDir))}E({level:n.error?"warn":"info",phase:"daemon_replay_cleanup",data:n})}function eb(e){return e===C.replay||e===C.test}async function eD(e,t){let a=Date.now();for(;Date.now()-a<e;){let e=eT(t.paths.infoPath);if(e&&await e$(e,t.transportPreference))return e;await L(100)}return null}async function eE(e){let t=eR(e);if(!t.hasLock||t.hasInfo)return!1;let a=eL(e.lockPath);return!(a&&M(a.pid,a.processStartTime))&&(eO(e.lockPath),!0)}async function eM(e){await T(e.pid,{termTimeoutMs:3e3,killTimeoutMs:1e3,expectedStartTime:e.processStartTime})}function eT(e){var t,a,r;let n,o,i=ex(e);if(!i||"object"!=typeof i)return null;let s="string"==typeof(t=i).token&&t.token.length>0?t.token:null;if(!s)return null;let l=(n=eC((a=i).port),o=eC(a.httpPort),void 0===n&&void 0===o?null:{port:n,httpPort:o});return l?{token:s,...l,transport:"socket"===(r=i.transport)||"http"===r||"dual"===r?r:void 0,pid:eC(i.pid)??0,version:eN(i.version),codeSignature:eN(i.codeSignature),processStartTime:eN(i.processStartTime)}:null}function eN(e){return"string"==typeof e?e:void 0}function eC(e){return Number.isInteger(e)&&Number(e)>0?Number(e):void 0}function eL(e){let t=ex(e);return t&&"object"==typeof t&&Number.isInteger(t.pid)&&Number(t.pid)>0?{pid:Number(t.pid),processStartTime:"string"==typeof t.processStartTime?t.processStartTime:void 0,startedAt:"number"==typeof t.startedAt?t.startedAt:void 0}:null}em.addSubnet("127.0.0.0",8,"ipv4"),em.addAddress("::1","ipv6"),em.addSubnet("::ffff:127.0.0.0",104,"ipv6");async function eU(e,t,a={}){let n=a.stopLiveProcesses??!0,o={reason:t,removedInfo:!1,removedLock:!1,stoppedInfoProcess:!1,stoppedLockProcess:!1};try{var i,s,l,c;let t=r.existsSync(e.infoPath),a=eT(e.infoPath);if(a){let t=M(a.pid,a.processStartTime);t&&!n?o.retainedInfoProcess=!0:(t&&(await eM(a),o.stoppedInfoProcess=!0),i=e.infoPath,eO(i),o.removedInfo=!0)}else t&&(s=e.infoPath,eO(s),o.removedInfo=!0);let d=r.existsSync(e.lockPath),u=eL(e.lockPath);if(u){let t=M(u.pid,u.processStartTime);t&&!n?o.retainedLockProcess=!0:(t&&(await T(u.pid,{termTimeoutMs:3e3,killTimeoutMs:1e3,expectedStartTime:u.processStartTime}),o.stoppedLockProcess=!0),l=e.lockPath,eO(l),o.removedLock=!0)}else d&&(c=e.lockPath,eO(c),o.removedLock=!0)}catch(e){o.error=e instanceof Error?e.message:String(e)}return E({level:o.error?"warn":"info",phase:"daemon_startup_metadata_cleanup",data:o}),o}function eR(e){return{hasInfo:r.existsSync(e.infoPath),hasLock:r.existsSync(e.lockPath)}}function ex(e){if(!r.existsSync(e))return null;try{return JSON.parse(r.readFileSync(e,"utf8"))}catch{return null}}function eO(e){try{r.existsSync(e)&&r.unlinkSync(e)}catch{}}async function e$(r,n){var o;return"http"===ej(r,n)?await function(e){let r=e.baseUrl?eQ(e.baseUrl,"health"):e.httpPort?`http://127.0.0.1:${e.httpPort}/health`:null;if(!r)return Promise.resolve(!1);let n=new URL(r),o="https:"===n.protocol?a:t,i=e.baseUrl?3e3:500;return new Promise(e=>{let t=o.request({protocol:n.protocol,host:n.hostname,port:n.port,path:n.pathname+n.search,method:"GET",timeout:i},t=>{t.resume(),e((t.statusCode??500)<500)});t.on("timeout",()=>{t.destroy(),e(!1)}),t.on("error",()=>{e(!1)}),t.end()})}(r):await ((o=r.port)?new Promise(t=>{let a=!1,r=e.createConnection({host:"127.0.0.1",port:o},()=>{n(!0)}),n=e=>{a||(a=!0,r.destroy(),t(e))};r.setTimeout(500),r.on("timeout",()=>{n(!1)}),r.on("error",()=>{n(!1)})}):Promise.resolve(!1))}async function eF(e){let t=eB(),a=t.useSrc?["--experimental-strip-types",t.srcPath]:[t.distPath],r={...process.env,AGENT_DEVICE_STATE_DIR:e.paths.baseDir,AGENT_DEVICE_DAEMON_SERVER_MODE:e.serverMode};f(process.execPath,a,{env:r})}function eB(){let e=S(),t=[o.join(e,"dist","src","internal","daemon.js"),o.join(e,"dist","src","daemon.js")],a=t[0];if(void 0===a)throw new u("COMMAND_FAILED","Daemon dist path list is empty");let n=t.find(e=>r.existsSync(e))??a,i=o.join(e,"src","daemon.ts"),s=t.some(e=>r.existsSync(e)),l=r.existsSync(i);if(!s&&!l)throw new u("COMMAND_FAILED","Daemon entry not found",{distPaths:t,srcPath:i});return{root:e,distPath:n,distPaths:t,srcPath:i,useSrc:process.execArgv.includes("--experimental-strip-types")?l:!s&&l}}async function eq(e,t,a,r){return"http"===ej(e,a)?await eV(e,t,r):await ez(e,t,r)}function ej(e,t){if(e.baseUrl){if("socket"===t)throw new u("COMMAND_FAILED","Remote daemon endpoint only supports HTTP transport",{daemonBaseUrl:e.baseUrl});return"http"}if("http"===t||"socket"===t){var a=e,r=t;if(eK(a,r))return r;throw new u("COMMAND_FAILED","http"===r?"Daemon HTTP endpoint is unavailable":"Daemon socket endpoint is unavailable")}let n=("socket"===e.transport||"dual"===e.transport?["socket","http"]:["http","socket"]).find(t=>eK(e,t));if(n)return n;throw new u("COMMAND_FAILED","Daemon metadata has no reachable transport")}function eK(e,t){return"http"===t?!!e.httpPort:!!e.port}function eH(e,t,a,r,n,o){let i=n?{terminated:0}:function(){let e=0;try{for(let t of ep){let a=p("pkill",["-f",t],{allowFailure:!0});0===a.exitCode&&(e+=1)}return{terminated:e}}catch(t){return{terminated:e,error:t instanceof Error?t.message:String(t)}}}(),s=!n&&"snapshot"!==r,l=s?function(e,t){let a=!1;try{M(e.pid,e.processStartTime)&&(process.kill(e.pid,"SIGKILL"),a=!0)}catch{T(e.pid,{termTimeoutMs:3e3,killTimeoutMs:1e3,expectedStartTime:e.processStartTime})}finally{eO(t.infoPath),eO(t.lockPath)}return{forcedKill:a}}(e,t):{forcedKill:!1};return E({level:"error",phase:"daemon_request_timeout",data:{timeoutMs:o,requestId:a,command:r,timedOutRunnerPidsTerminated:i.terminated,timedOutRunnerCleanupError:i.error,daemonPidReset:s?e.pid:void 0,daemonPidForceKilled:s?l.forcedKill:void 0,daemonPreservedAfterTimeout:!n&&!s,daemonBaseUrl:e.baseUrl}}),new u("COMMAND_FAILED","Daemon request timed out",{timeoutMs:o,requestId:a,hint:function(e){let{remote:t,resetDaemon:a,command:r}=e;if(t)return"Retry with --debug and verify the remote daemon URL, auth token, and remote host logs.";if(!a){let e=r===C.snapshot?" If this was the first Apple-platform snapshot on the device, run agent-device prepare ios-runner with the same --platform before snapshot/test so runner startup is handled explicitly.":"";return`Retry with --debug and check daemon diagnostics logs. The timed-out ${r??"request"} request was canceled and Apple runner work was aborted when detected; the daemon was kept alive so the session can still be closed or inspected.${e}`}return"Retry with --debug and check daemon diagnostics logs. Timed-out Apple runner xcodebuild processes were terminated when detected."}({remote:n,resetDaemon:s,command:r})})}function eG(e,t,a){return E({level:"error",phase:"daemon_request_socket_error",data:{requestId:t,message:e instanceof Error?e.message:String(e)}}),new u("COMMAND_FAILED","Failed to communicate with daemon",{requestId:t,hint:a?"Retry command. If this persists, verify the remote daemon URL, auth token, and remote host reachability.":"Retry command. If this persists, clean stale daemon metadata and start a fresh session."},e instanceof Error?e:void 0)}async function ez(t,a,r){let n=t.port;if(!n)throw new u("COMMAND_FAILED","Daemon socket endpoint is unavailable");return new Promise((o,i)=>{let s=e.createConnection({host:"127.0.0.1",port:n},()=>{s.write(`${JSON.stringify(a)}
|
|
3
|
+
`)}),l=I(a.flags?.stateDir??process.env.AGENT_DEVICE_STATE_DIR),c=!1,d="number"==typeof r?setTimeout(()=>{c=!0,s.destroy(),i(eH(t,l,a.meta?.requestId,a.command,!1,r))},r):void 0,p="";s.setEncoding("utf8"),s.on("data",e=>{if(c)return;let t=h(p,e);for(let e of(p=t.buffer,t.lines))try{let t=JSON.parse(e);if(v(t)){eu(t.event);continue}let a=g(t)?t.response:t;c=!0,s.end(),d&&clearTimeout(d),o(a);return}catch(t){c=!0,d&&clearTimeout(d),i(new u("COMMAND_FAILED","Invalid daemon response",{requestId:a.meta?.requestId,line:e},t instanceof Error?t:void 0));return}}),s.on("error",e=>{c||(c=!0,d&&clearTimeout(d),i(eG(e,a.meta?.requestId,!1)))})})}async function eV(e,r,n){var o,i,s;let l,c=e.baseUrl?new URL(eQ(e.baseUrl,"rpc")):e.httpPort?new URL(`http://127.0.0.1:${e.httpPort}/rpc`):null;if(!c)throw new u("COMMAND_FAILED","Daemon HTTP endpoint is unavailable");let d=JSON.stringify((o=r,i={includeTokenParam:!e.baseUrl},l=o.meta?.requestId??b(),"lease_allocate"!==(s=o.command)&&"lease_heartbeat"!==s&&"lease_release"!==s?{jsonrpc:"2.0",id:l,method:"agent_device.command",params:o}:{jsonrpc:"2.0",id:l,method:function(e){switch(e){case"lease_allocate":return"agent_device.lease.allocate";case"lease_heartbeat":return"agent_device.lease.heartbeat";case"lease_release":return"agent_device.lease.release"}}(o.command),params:function(e,t,a){let r={...a.includeTokenParam?{token:e.token}:{},session:e.session,tenantId:e.meta?.tenantId,runId:e.meta?.runId};switch(t){case"lease_allocate":return{...r,ttlMs:e.meta?.leaseTtlMs,backend:e.meta?.leaseBackend};case"lease_heartbeat":return{...r,leaseId:e.meta?.leaseId,ttlMs:e.meta?.leaseTtlMs};case"lease_release":return{...r,leaseId:e.meta?.leaseId}}}(o,o.command,i)})),p={"content-type":"application/json","content-length":Buffer.byteLength(d)};return e.baseUrl&&e.token&&(p.authorization=`Bearer ${e.token}`,p["x-agent-device-token"]=e.token),await new Promise((o,i)=>{let s=I(r.flags?.stateDir??process.env.AGENT_DEVICE_STATE_DIR),l=("https:"===c.protocol?a:t).request({protocol:c.protocol,host:c.hostname,port:c.port,method:"POST",path:c.pathname+c.search,headers:p},t=>{var a;(a=t.headers?.["content-type"],w(r)&&String(Array.isArray(a)?a.join(","):a??"").includes("application/x-ndjson"))?function(e,t){let{req:a,handleResponseBody:r,reject:n,clearTimeout:o}=t,i="",s=!1,l=e=>{try{let t=JSON.parse(e);if(v(t))return eu(t.event),!1;if(g(t))return s=!0,o(),r(JSON.stringify(t.response)),!0;throw Error("Missing daemon progress response envelope")}catch(t){return s=!0,o(),n(new u("COMMAND_FAILED","Invalid daemon response",{requestId:a.meta?.requestId,line:e},t instanceof Error?t:void 0)),!0}};e.setEncoding("utf8"),e.on("data",e=>{if(s)return;let t=h(i,e);for(let e of(i=t.buffer,t.lines))if(e&&l(e))return}),e.on("end",()=>{if(s)return;let e=i.trim();e&&l(e)||(s=!0,o(),n(new u("COMMAND_FAILED","Invalid daemon response",{requestId:a.meta?.requestId,line:e})))}),e.on("error",e=>{s||(s=!0,o(),n(new u("COMMAND_FAILED","Failed to read daemon response",{requestId:a.meta?.requestId},e instanceof Error?e:void 0)))})}(t,{req:r,reject:i,clearTimeout:()=>{f&&clearTimeout(f)},handleResponseBody:t=>eJ(t,{info:e,req:r,resolve:o,reject:i})}):X(t).then(t=>{f&&clearTimeout(f),eJ(t,{info:e,req:r,resolve:o,reject:i})}).catch(e=>{f&&clearTimeout(f),i(new u("COMMAND_FAILED","Failed to read daemon response",{requestId:r.meta?.requestId},e instanceof Error?e:void 0))})}),m=eY(e),f="number"==typeof n?setTimeout(()=>{l.destroy(),i(eH(e,s,r.meta?.requestId,r.command,m,n))},n):void 0;l.on("error",e=>{f&&clearTimeout(f),i(eG(e,r.meta?.requestId,m))}),l.write(d),l.end()})}function eJ(e,t){let{info:a,req:r,resolve:n,reject:o}=t;try{var i,s,l;let t=(i=e,JSON.parse(i));if(t.error){let e;return void o((s=t.error,l=r.meta?.requestId,e=s.data??{},new u(d(null!=e.code?String(e.code):void 0,"COMMAND_FAILED"),String(e.message??s.message??"Daemon RPC request failed"),{..."object"==typeof e.details&&e.details?e.details:{},hint:"string"==typeof e.hint?e.hint:void 0,diagnosticId:"string"==typeof e.diagnosticId?e.diagnosticId:void 0,logPath:"string"==typeof e.logPath?e.logPath:void 0,requestId:l})))}if(!t.result||"object"!=typeof t.result)return void o(new u("COMMAND_FAILED","Invalid daemon RPC response",{requestId:r.meta?.requestId}));eW(a,r,t.result,n,o)}catch(t){o(new u("COMMAND_FAILED","Invalid daemon response",{requestId:r.meta?.requestId,line:e},t instanceof Error?t:void 0))}}async function eW(e,t,a,r,n){try{r(e.baseUrl&&a.ok?await eX(e,t,a):a)}catch(e){n(e)}}function eY(e){return"string"==typeof e.baseUrl&&e.baseUrl.length>0}function eQ(e,t){return new URL(t,e.endsWith("/")?e:`${e}/`).toString()}async function eX(e,t,a){let r=Array.isArray(a.data?.artifacts)?a.data.artifacts:[];if(0===r.length||!e.baseUrl)return a;let n=a.data?{...a.data}:{},i=[];for(let a of r){if(!a||"object"!=typeof a||"string"!=typeof a.artifactId){i.push(a);continue}let r=function(e,t){if(e.localPath&&e.localPath.trim().length>0)return e.localPath;let a=t.meta?.clientArtifactPaths?.[e.field];if(a&&a.trim().length>0)return a;let r=e.fileName?.trim()||`${e.field}-${Date.now()}`;return o.resolve(t.meta?.cwd??process.cwd(),r)}(a,t);await eZ({baseUrl:e.baseUrl,token:e.token,artifactId:a.artifactId,destinationPath:r,requestId:t.meta?.requestId}),n[a.field]=r,i.push({...a,localPath:r})}return n.artifacts=i,{ok:!0,data:n}}async function eZ(e){var n,s;let l,c=new URL((n=e.baseUrl,s=e.artifactId,l=n.endsWith("/")?n:`${n}/`,new URL(`artifacts/${encodeURIComponent(s)}`,l).toString())),d="https:"===c.protocol?a:t;await r.promises.mkdir(o.dirname(e.destinationPath),{recursive:!0}),await new Promise((t,a)=>{let n=!1,o=e.timeoutMs??9e4,s=o=>{if(!n){if(n=!0,clearTimeout(p),o)return void r.promises.rm(e.destinationPath,{force:!0}).finally(()=>a(o));t()}},l=d.request({protocol:c.protocol,host:c.hostname,port:c.port,method:"GET",path:c.pathname+c.search,headers:e.token?{authorization:`Bearer ${e.token}`,"x-agent-device-token":e.token}:void 0},t=>{if((t.statusCode??500)>=400){let a="";t.setEncoding("utf8"),t.on("data",e=>{a+=e}),t.on("end",()=>{s(new u("COMMAND_FAILED","Failed to download remote artifact",{artifactId:e.artifactId,statusCode:t.statusCode,requestId:e.requestId,body:a}))});return}t.on("aborted",()=>{s(new u("COMMAND_FAILED","Remote artifact download was interrupted",{artifactId:e.artifactId,requestId:e.requestId}))}),i(t,r.createWriteStream(e.destinationPath)).then(()=>s(),e=>s(e instanceof Error?e:Error(String(e))))}),p=setTimeout(()=>{let t=new u("COMMAND_FAILED","Remote artifact download timed out",{artifactId:e.artifactId,requestId:e.requestId,timeoutMs:o});s(t),l.destroy(t)},o);l.on("error",t=>{t instanceof u?s(t):s(new u("COMMAND_FAILED","Failed to download remote artifact",{artifactId:e.artifactId,requestId:e.requestId,timeoutMs:o},t instanceof Error?t:void 0))}),l.end()})}function e0(e={},t={}){let a=t.transport??ef,r=async(t,r=[],n={})=>{var o,i;let s=(o=e,i=n,{...o,...i}),l=await a({session:O(s.session),command:t,positionals:r,flags:$(s),runtime:s.runtime,meta:J(s)});return l.ok||function(e){throw new u(d(e.code),e.message,{...e.details??{},hint:e.hint,diagnosticId:e.diagnosticId,logPath:e.logPath})}(l.error),l.data??{}},n=async(e={})=>{let t=await r(N.sessionList,[],e);return(Array.isArray(t.sessions)?t.sessions:[]).map(x)},o=async(e,t={})=>{let a=j(e,t);return await r(a.command,a.positionals,a.options)},i=(t={})=>{var a,r;return O((a=e,r=t,{...a,...r}).session)};return{command:{wait:async e=>await o("wait",e),alert:async(e={})=>await o("alert",e),appState:async(e={})=>await o("appstate",e),back:async(e={})=>await o("back",e),home:async(e={})=>await o("home",e),rotate:async e=>await o("rotate",e),appSwitcher:async(e={})=>await o("app-switcher",e),keyboard:async(e={})=>await o("keyboard",e),clipboard:async e=>await o("clipboard",e),reactNative:async e=>await o("react-native",e),prepare:async e=>await o("prepare",e)},devices:{list:async(e={})=>{let t=await o("devices",e);return(Array.isArray(t.devices)?t.devices:[]).map(W)},boot:async(e={})=>await o("boot",e)},sessions:{list:async(e={})=>await n(e),close:async(e={})=>{let t=i(e),a=(await o("close",e)).shutdown;return{session:t,shutdown:"object"==typeof a&&null!==a?a:void 0,identifiers:{session:t}}}},apps:{install:async e=>G(await o("install",e),i(e)),reinstall:async e=>G(await o("reinstall",e),i(e)),installFromSource:async e=>B(await o("install-from-source",e),i(e)),list:async(e={})=>{let t=await o("apps",e);return Array.isArray(t.apps)?t.apps.filter(e=>"string"==typeof e):[]},open:async e=>{let t=i(e),a=await o("open",e),r=z(a),n=Q(a,"appBundleId");return{session:t,sessionStateDir:Q(a,"sessionStateDir"),appName:Q(a,"appName"),appBundleId:n,appId:n,startup:F(a.startup),runtime:H(a.runtime),device:r,identifiers:{session:t,deviceId:r?.id,deviceName:r?.name,udid:r?.ios?.udid,serial:r?.android?.serial,appId:n,appBundleId:n}}},close:async(e={})=>{let t=i(e),a=(await o("close",e)).shutdown;return{session:t,closedApp:e.app,shutdown:"object"==typeof a&&null!==a?a:void 0,identifiers:{session:t}}},push:async e=>await o("push",e),triggerEvent:async e=>await o("trigger-app-event",e)},materializations:{release:async e=>q(await r(N.releaseMaterializedPaths,[],{...e,materializationId:e.materializationId}))},leases:{allocate:async e=>e2(await r(N.leaseAllocate,[],{...e,leaseId:void 0,leaseTtlMs:e.ttlMs})),heartbeat:async e=>e2(await r(N.leaseHeartbeat,[],{...e,leaseTtlMs:e.ttlMs})),release:async e=>({released:!0===(await r(N.leaseRelease,[],e)).released})},metro:{prepare:async t=>await R({projectRoot:t.projectRoot??e.cwd,kind:t.kind,publicBaseUrl:t.publicBaseUrl,proxyBaseUrl:t.proxyBaseUrl,proxyBearerToken:t.bearerToken,bridgeScope:t.bridgeScope,launchUrl:t.launchUrl,companionProfileKey:t.companionProfileKey,companionConsumerKey:t.companionConsumerKey,metroPort:t.port,listenHost:t.listenHost,statusHost:t.statusHost,startupTimeoutMs:t.startupTimeoutMs,probeTimeoutMs:t.probeTimeoutMs,reuseExisting:t.reuseExisting,installDependenciesIfNeeded:t.installDependenciesIfNeeded,runtimeFilePath:t.runtimeFilePath,logPath:t.logPath}),reload:async(t={})=>await U({metroHost:t.metroHost,metroPort:t.metroPort,bundleUrl:t.bundleUrl,runtime:e.runtime,timeoutMs:t.timeoutMs})},capture:{snapshot:async(e={})=>{var t,a,r;let n,s,l,c,d,u=i(e);return t=await o("snapshot",e),a=u,n=Q(t,"appBundleId"),{nodes:K(t.nodes),truncated:!0===t.truncated,appName:Q(t,"appName"),appBundleId:n,...(s=e1((r=t).visibility),l=e1(r.androidSnapshot),c=e1(r.unchanged),d=Array.isArray(r.warnings)?r.warnings.filter(e=>"string"==typeof e):void 0,{...s?{visibility:s}:{},...l?{androidSnapshot:l}:{},...c?{unchanged:c}:{},...d?{warnings:d}:{}}),identifiers:{session:a,appId:n,appBundleId:n}}},screenshot:async(e={})=>{let t=i(e),a=await o("screenshot",e);return{path:Y(a,"path"),overlayRefs:V(a),identifiers:{session:t}}},diff:async e=>await o("diff",e)},interactions:{click:async e=>await o("click",e),press:async e=>await o("press",e),longPress:async e=>await o("longpress",e),swipe:async e=>await o("swipe",e),pan:async e=>await o("gesture-pan",e),fling:async e=>await o("gesture-fling",e),swipeGesture:async e=>await o("gesture-swipe",e),focus:async e=>await o("focus",e),type:async e=>await o("type",e),fill:async e=>await o("fill",e),scroll:async e=>await o("scroll",e),pinch:async e=>await o("gesture-pinch",e),rotateGesture:async e=>await o("gesture-rotate",e),transformGesture:async e=>await o("gesture-transform",e),get:async e=>await o("get",e),is:async e=>await o("is",e),find:async e=>await o("find",e)},replay:{run:async e=>await o("replay",e),test:async e=>await o("test",e)},batch:{run:async e=>await o("batch",e)},observability:{perf:async(e={})=>await o("perf",e),logs:async(e={})=>await o("logs",e),network:async(e={})=>await o("network",e)},recording:{record:async e=>await o("record",e),trace:async e=>await o("trace",e)},settings:{update:async e=>await o("settings",e)}}}function e1(e){return"object"==typeof e&&null!==e?e:void 0}function e2(e){let t=e.lease;if(!t||"object"!=typeof t||Array.isArray(t))throw Error("Invalid lease response from daemon");return{leaseId:Y(t,"leaseId"),tenantId:Y(t,"tenantId"),runId:Y(t,"runId"),backend:Y(t,"backend"),createdAt:"number"==typeof t.createdAt?t.createdAt:void 0,heartbeatAt:"number"==typeof t.heartbeatAt?t.heartbeatAt:void 0,expiresAt:"number"==typeof t.expiresAt?t.expiresAt:void 0}}export{e0 as createAgentDeviceClient,ed as formatDurationSeconds,ef as sendToDaemon};
|
package/dist/src/apple.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{AppError as e}from"./9152.js";import{
|
|
1
|
+
import{AppError as e}from"./9152.js";import{buildScrollGesturePlan as a}from"./9533.js";import{runMacOsScreenshotAction as t,runIosRunnerCommand as n}from"./2415.js";import{writeIosClipboardText as d,openIosApp as o,openIosDevice as r,screenshotIos as i,closeIosApp as p,setIosSetting as l,readIosClipboardText as u}from"./apps.js";import{withDiagnosticTimer as c}from"./7599.js";function s(e,a,t,n){return{command:"tap",x:t,y:n,..."ios"===e.platform&&"tv"!==e.target?{synthesized:!0}:{},appBundleId:a.appBundleId}}function m(e,a,t,n,d,o,r,i){var p,l;let u="ios"===e.platform&&"tv"!==e.target?(p=r,l=i.defaultDurationMs,void 0===p?l:Math.min(1e4,Math.max(16,Math.round(p)))):r??i.legacyDefaultDurationMs;return{command:"drag",x:t,y:n,x2:d,y2:o,...void 0!==u?{durationMs:u}:{},appBundleId:a.appBundleId}}function y(e,a,t){return{command:"remotePress",remoteButton:e,...void 0!==t?{durationMs:t}:{},...void 0!==a?{appBundleId:a}:{}}}async function f(e,t,n,d,o,r,i){if("tv"===t.target)return w(await e(t,y(o,n.appBundleId),d),r);let p=i??await I(e,t,n,d),l=a({direction:o,amount:r?.amount,pixels:r?.pixels,referenceWidth:p.referenceWidth,referenceHeight:p.referenceHeight});return w(await e(t,m(t,n,p.originX+l.x1,p.originY+l.y1,p.originX+l.x2,p.originY+l.y2,void 0,{defaultDurationMs:250}),d),{amount:l.amount,pixels:l.pixels,preferProvidedPixels:!0})}async function I(a,t,n,d){let o=await a(t,{command:"interactionFrame",appBundleId:n.appBundleId},d),r=v(o.x),i=v(o.y),p=v(o.referenceWidth),l=v(o.referenceHeight);if(void 0===r||void 0===i||void 0===p||void 0===l)throw new e("COMMAND_FAILED","interactionFrame did not return a usable frame");return{originX:r,originY:i,referenceWidth:p,referenceHeight:l}}function v(e){return"number"==typeof e&&Number.isFinite(e)?e:void 0}function w(e,a){var t;let{x1:n,y1:d,x2:o,y2:r}={x1:v((t=e).x),y1:v(t.y),x2:v(t.x2),y2:v(t.y2)},i=v(e.referenceWidth),p=v(e.referenceHeight),l=void 0!==n&&void 0!==o?Math.round(Math.abs(o-n)):void 0,u=void 0!==d&&void 0!==r?Math.round(Math.abs(r-d)):void 0,c=a?.preferProvidedPixels&&void 0!==a.pixels?a.pixels:l&&l>0?l:u&&u>0?u:void 0;return{...void 0!==n?{x1:n}:{},...void 0!==d?{y1:d}:{},...void 0!==o?{x2:o}:{},...void 0!==r?{y2:r}:{},...void 0!==i?{referenceWidth:i}:{},...void 0!==p?{referenceHeight:p}:{},...a?.amount!==void 0?{amount:a.amount}:{},...void 0!==c?{pixels:c}:{}}}function B(a,I){let v,{overrides:w,runnerOpts:B}={runnerOpts:v={verbose:I.verbose,logPath:I.logPath,traceLogPath:I.traceLogPath,requestId:I.requestId},overrides:{tap:async(e,t)=>await n(a,s(a,I,e,t),v),tapElementSelector:async e=>await n(a,{command:"tap",selectorKey:e.key,selectorValue:e.value,allowNonHittableCoordinateFallback:e.allowNonHittableCoordinateFallback,appBundleId:I.appBundleId},v),doubleTap:async(e,t)=>await n(a,{command:"tapSeries",x:e,y:t,count:1,intervalMs:0,doubleTap:!0,appBundleId:I.appBundleId},v),swipe:async(e,t,d,o,r)=>await n(a,m(a,I,e,t,d,o,r,{defaultDurationMs:250}),v),pan:async(e,t,d,o,r)=>await n(a,m(a,I,e,t,d,o,r,{defaultDurationMs:500,legacyDefaultDurationMs:500}),v),fling:async(e,t,d,o,r)=>await n(a,{command:"drag",x:e,y:t,x2:d,y2:o,durationMs:r??16,appBundleId:I.appBundleId},v),longPress:async(e,t,d)=>await n(a,{command:"longPress",x:e,y:t,durationMs:d,appBundleId:I.appBundleId},v),focus:async(e,t)=>await n(a,s(a,I,e,t),v),type:async(e,t)=>{await n(a,{command:"type",text:e,delayMs:t,textEntryMode:"\n"===e?void 0:"append",appBundleId:I.appBundleId},v)},fillElementSelector:async(e,t,d)=>await n(a,{command:"type",selectorKey:e.key,selectorValue:e.value,allowNonHittableCoordinateFallback:e.allowNonHittableCoordinateFallback,text:t,delayMs:d,textEntryMode:"replace",appBundleId:I.appBundleId},v),fill:async(e,t,d,o)=>await n(a,{command:"type",x:e,y:t,text:d,delayMs:o,textEntryMode:"replace",appBundleId:I.appBundleId},v),scroll:async(e,t)=>await f(n,a,I,v,e,t),pinch:async(e,t,d)=>{await n(a,{command:"pinch",scale:e,x:t,y:d,appBundleId:I.appBundleId},v)},rotateGesture:async(e,t,d,o)=>{await n(a,{command:"rotateGesture",degrees:e,x:t,y:d,velocity:o,appBundleId:I.appBundleId},v)},transformGesture:async e=>await n(a,{command:"transformGesture",x:e.x,y:e.y,dx:e.dx,dy:e.dy,scale:e.scale,degrees:e.degrees,durationMs:e.durationMs,appBundleId:I.appBundleId},v)}};return{open:(e,t)=>o(a,e,{appBundleId:t?.appBundleId,launchConsole:t?.launchConsole,launchArgs:t?.launchArgs,url:t?.url}),openDevice:()=>r(a),close:e=>p(a,e),screenshot:async(e,n)=>{"macos"===a.platform&&n?.surface&&"app"!==n.surface?await t(e,{surface:n.surface,fullscreen:n.fullscreen}):await i(a,e,n?.appBundleId,n?.fullscreen,B)},snapshot:async t=>{var d;let o={nodes:Array.isArray((d=await c("snapshot_capture",async()=>await n(a,{command:"snapshot",appBundleId:t?.appBundleId,interactiveOnly:t?.interactiveOnly,compact:t?.compact,depth:t?.depth,scope:t?.scope,raw:t?.raw},B),{backend:"xctest"})).nodes)?d.nodes:void 0,truncated:"boolean"==typeof d.truncated?d.truncated:void 0},r=o.nodes??[];if(0===r.length&&"simulator"===a.kind)throw new e("COMMAND_FAILED","XCTest snapshot returned 0 nodes on iOS simulator.");return{nodes:r,truncated:o.truncated??!1,backend:"xctest"}},back:async e=>{"tv"===a.target?await n(a,y("menu",I.appBundleId),B):await n(a,{command:"system"===e?"backSystem":"backInApp",appBundleId:I.appBundleId},B)},home:async()=>{"tv"===a.target?await n(a,y("home",I.appBundleId),B):await n(a,{command:"home",appBundleId:I.appBundleId},B)},rotate:async e=>{await n(a,{command:"rotate",orientation:e,appBundleId:I.appBundleId},B)},appSwitcher:async()=>{await n(a,{command:"appSwitcher",appBundleId:I.appBundleId},B)},readClipboard:()=>u(a),writeClipboard:e=>d(a,e),setSetting:(e,t,n,d)=>l(a,e,t,n,d),...w}}export{B as createAppleInteractor};
|
package/dist/src/apps.js
CHANGED
|
@@ -3,7 +3,7 @@ ${i}
|
|
|
3
3
|
${a}`.toLowerCase();return r.includes("unknown option '--device'")||r.includes("unknown subcommand")&&r.includes("screenshot")||r.includes("unrecognized subcommand")&&r.includes("screenshot")}(t))throw t;eP(e,"devicectl_screenshot",t)}await eL(e,t,i,a,r)}async function eN(e,t,i,a,r=eC,o){if("simulator"!==e.kind)throw new n("UNSUPPORTED_OPERATION","Simulator screenshot fallback flow supports only iOS simulators");let l="object"==typeof a&&null!==a?a:r;await l.ensureBooted(e);let s=async()=>{};try{s=await l.prepareStatusBarForScreenshot(e)}catch(t){ex(e,"prepare_failed",t)}try{try{await l.captureWithRetry(e,t);return}catch(t){if(!l.shouldFallbackToRunner(t))throw t;eP(e,"simctl_screenshot",t)}await l.captureWithRunner(e,t,i,"boolean"==typeof a?a:void 0,o)}finally{await s().catch(t=>ex(e,"restore_failed",t))}}async function eS(e,t){let i=G.fromTimeoutMs(2e4);await B(async({deadline:i})=>{var a;await (a=["io",e.id,"screenshot",t],p(e,a,{timeoutMs:Math.max(1e3,i?.remainingMs()??2e4)}))},{maxAttempts:5,baseDelayMs:1e3,maxDelayMs:5e3,jitter:.2,shouldRetry:e=>eF(e)},{deadline:i,phase:"ios_simulator_screenshot"})}async function eL(e,i,a,r,o){let l=(await u(e,{command:"screenshot",appBundleId:a,fullscreen:r},o)).message;if(!l)throw new n("COMMAND_FAILED","Failed to capture iOS screenshot: runner returned no file path");"macos"===e.platform?await t.copyFile(l,i):"simulator"===e.kind?await eM(e,l,i):await eD(e,l,i)}async function eD(e,t,i){let a=G.fromTimeoutMs(2e4),r={exitCode:1,stdout:"",stderr:""};for(let n of l)if(0===(r=await o(["devicectl","device","copy","from","--device",e.id,"--source",t,"--destination",i,"--domain-type","appDataContainer","--domain-identifier",n],{allowFailure:!0,timeoutMs:eO(a,2e4,"runner screenshot copy")})).exitCode)return;let s=r.stderr.trim()||r.stdout.trim()||`devicectl exited with code ${r.exitCode}`;throw new n("COMMAND_FAILED",`Failed to capture iOS screenshot: ${s}`)}async function eM(e,i,r){let o=G.fromTimeoutMs(2e4),s="Unable to locate runner container for simulator screenshot";for(let n of l){var d;let l=await (d=["get_app_container",e.id,n,"data"],p(e,d,{allowFailure:!0,timeoutMs:eO(o,2e4,"runner screenshot container lookup")}));if(0!==l.exitCode){let e=l.stderr.trim();e&&(s=e);continue}let u=l.stdout.trim();if(!u){s="simctl get_app_container returned empty output";continue}for(let e of function(e,t){let i=a.resolve(e),r=t.trim();if(!r)return[];let n=[],o=new Set,l=e=>{let t=a.normalize(e);o.has(t)||(o.add(t),n.push(t))},s=r.replace(/^\/+/,""),d=s.replace(/\\/g,"/");if(s&&l(a.join(i,s)),a.isAbsolute(r)&&l(a.normalize(r)),d.startsWith("tmp/"))l(a.join(i,d));else{let e=d.lastIndexOf("/tmp/");if(e>=0){let t=d.slice(e+1);l(a.join(i,t))}}let u=a.basename(r);return u&&l(a.join(i,"tmp",u)),n}(u,i))try{await t.copyFile(e,r);return}catch(e){s=e instanceof Error?e.message:String(e)}}throw new n("COMMAND_FAILED",`Failed to capture iOS screenshot: ${s}`)}function eO(e,t,i){let a=e.remainingMs();if(a>0)return a;throw new n("COMMAND_FAILED",`iOS ${i} timed out after ${t}ms`,{timeoutMs:t,step:i})}function eP(e,t,i){let a=ep(i);V({level:"warn",phase:"ios_screenshot_fallback",data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,from:t,to:"runner",...a}})}function ex(e,t,i){V({level:"warn",phase:`ios_screenshot_status_bar_${t}`,data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,...ep(i)}})}function eF(e){if(!(e instanceof n)||"COMMAND_FAILED"!==e.code)return!1;let t=e.details??{},i="string"==typeof t.stdout?t.stdout:"",a="string"==typeof t.stderr?t.stderr:"",r=Array.isArray(t.args)?t.args.filter(e=>"string"==typeof e).join(" "):"",o=`${e.message}
|
|
4
4
|
${i}
|
|
5
5
|
${a}
|
|
6
|
-
${r}`.toLowerCase();return o.includes("timeout waiting for screen surfaces")||o.includes("nsposixerrordomain")&&o.includes("code=60")&&o.includes("screenshot")||o.includes("timed out")&&o.includes("screenshot")}let eR={settings:"com.apple.Preferences"},e$=E(),eE=null;function ek(e){return{platform:"ios",deviceId:e.id,variant:e.kind}}function eT(e,t,i){return o(m(e,t),i)}function eU(e){return e.includes("not installed")||e.includes("not found")||e.includes("no such file")}async function eB(e,t){if("macos"===e.platform)return await ea(t);let i=t.trim();if(i.includes("."))return i;let a=eR[i.toLowerCase()];if(a)return a;let r=ek(e),o=e$.get(r,i);if(o)return o;let l=("simulator"===e.kind?await e2(e):await v(e,"all")).filter(e=>e.name.toLowerCase()===i.toLowerCase()),s=l[0];if(void 0!==s&&1===l.length)return e$.set(r,i,s.bundleId);if(l.length>1)throw new n("INVALID_ARGS",`Multiple apps matched "${t}"`,{matches:l});throw new n("APP_NOT_INSTALLED",`No app found matching "${t}"`)}async function eG(e,t){var i;let r;if("ios"!==e.platform||"simulator"!==e.kind)return;let n=(i=t,r=/^([A-Za-z][A-Za-z0-9+.-]*):/.exec(i.trim()),r?.[1]?.toLowerCase());if(!n)return;let o=await e3(e),l=[];for(let e of o)!e.bundleId.startsWith("com.callstack.agentdevice.runner")&&e.path&&(await e5(a.join(e.path,"Info.plist"))).has(n)&&l.push(e);let s=l.filter(e=>"User"===e.applicationType);return 1===s.length?s[0]?.bundleId:s.length>1?void 0:1===l.length?l[0]?.bundleId:void 0}async function eV(e,t,i){let a=i?.launchConsole?.trim(),r=i?.launchArgs;if(a&&("ios"!==e.platform||"simulator"!==e.kind))throw new n("UNSUPPORTED_OPERATION",S);if("macos"===e.platform){if(r&&r.length>0)throw new n("UNSUPPORTED_OPERATION","--launch-args is not supported on macOS; launch arguments are currently iOS-only.");await er(e,t,i);return}let o=i?.url?.trim();if(o){if(a)throw new n("INVALID_ARGS",d);if(!k(o))throw new n("INVALID_ARGS","open <app> <url> requires a valid URL target");if("simulator"===e.kind)
|
|
6
|
+
${r}`.toLowerCase();return o.includes("timeout waiting for screen surfaces")||o.includes("nsposixerrordomain")&&o.includes("code=60")&&o.includes("screenshot")||o.includes("timed out")&&o.includes("screenshot")}let eR={settings:"com.apple.Preferences"},e$=E(),eE=null;function ek(e){return{platform:"ios",deviceId:e.id,variant:e.kind}}function eT(e,t,i){return o(m(e,t),i)}function eU(e){return e.includes("not installed")||e.includes("not found")||e.includes("no such file")}async function eB(e,t){if("macos"===e.platform)return await ea(t);let i=t.trim();if(i.includes("."))return i;let a=eR[i.toLowerCase()];if(a)return a;let r=ek(e),o=e$.get(r,i);if(o)return o;let l=("simulator"===e.kind?await e2(e):await v(e,"all")).filter(e=>e.name.toLowerCase()===i.toLowerCase()),s=l[0];if(void 0!==s&&1===l.length)return e$.set(r,i,s.bundleId);if(l.length>1)throw new n("INVALID_ARGS",`Multiple apps matched "${t}"`,{matches:l});throw new n("APP_NOT_INSTALLED",`No app found matching "${t}"`)}async function eG(e,t){var i;let r;if("ios"!==e.platform||"simulator"!==e.kind)return;let n=(i=t,r=/^([A-Za-z][A-Za-z0-9+.-]*):/.exec(i.trim()),r?.[1]?.toLowerCase());if(!n)return;let o=await e3(e),l=[];for(let e of o)!e.bundleId.startsWith("com.callstack.agentdevice.runner")&&e.path&&(await e5(a.join(e.path,"Info.plist"))).has(n)&&l.push(e);let s=l.filter(e=>"User"===e.applicationType);return 1===s.length?s[0]?.bundleId:s.length>1?void 0:1===l.length?l[0]?.bundleId:void 0}async function eV(e,t,i){let a=i?.launchConsole?.trim(),r=i?.launchArgs;if(a&&("ios"!==e.platform||"simulator"!==e.kind))throw new n("UNSUPPORTED_OPERATION",S);if("macos"===e.platform){if(r&&r.length>0)throw new n("UNSUPPORTED_OPERATION","--launch-args is not supported on macOS; launch arguments are currently iOS-only.");await er(e,t,i);return}let o=i?.url?.trim();if(o){if(a)throw new n("INVALID_ARGS",d);if(!k(o))throw new n("INVALID_ARGS","open <app> <url> requires a valid URL target");if("simulator"===e.kind){let a=i?.appBundleId??await eB(e,t);await tt(e,a,{...r?{launchArgs:r}:{}}),await ej(e,o,void 0);return}let l=U(i?.appBundleId??await eB(e,t),o);if(!l)throw new n("INVALID_ARGS","Deep link open on iOS devices requires an active app bundle ID. Open the app first, then open the URL.");await tr(e,l,{payloadUrl:o,launchArgs:r});return}let l=t.trim();if(k(l)){if(a)throw new n("INVALID_ARGS",d);if("simulator"===e.kind)return void await ej(e,l,r);let t=U(i?.appBundleId,l);if(!t)throw new n("INVALID_ARGS","Deep link open on iOS devices requires an active app bundle ID. Open the app first, then open the URL.");return void await tr(e,t,{payloadUrl:l,launchArgs:r})}let s=i?.appBundleId??await eB(e,t);"simulator"===e.kind?await tt(e,s,{...a?{launchConsole:a}:{},...r?{launchArgs:r}:{}}):await tr(e,s,{launchArgs:r})}async function ej(e,t,i){if(i&&i.length>0)throw new n("INVALID_ARGS","--launch-args is not supported with iOS simulator URL opens (simctl openurl ignores launch args). Launch the app first with --launch-args, then issue the URL open in a separate call.");await b(e),await eT(e,["openurl",e.id,t])}async function eW(e){"macos"===e.platform||"simulator"!==e.kind||"Booted"!==await L(e)&&await b(e)}async function eK(e,t){if("macos"===e.platform)return void await en(e,t);let i=await eB(e,t);if("simulator"===e.kind){await b(e);let t=m(e,["terminate",e.id,i]),a=await o(t,{allowFailure:!0,timeoutMs:15e3});if(0!==a.exitCode){if(a.stderr.toLowerCase().includes("found nothing to terminate"))return;throw new n("COMMAND_FAILED",`xcrun exited with code ${a.exitCode}`,{cmd:"xcrun",args:t,stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode})}return}await A(["device","process","terminate","--device",e.id,i],{action:"terminate iOS app",deviceId:e.id})}async function eH(e,i){if("ios"!==e.platform||"simulator"!==e.kind)throw new n("UNSUPPORTED_OPERATION","Clearing app state is currently supported only on iOS simulators.");let r=await eB(e,i);await b(e),await eK(e,r);let o=await eT(e,["get_app_container",e.id,r,"data"],{allowFailure:!0});if(0!==o.exitCode)throw new n("COMMAND_FAILED",`simctl get_app_container failed for ${r}`,{stdout:o.stdout,stderr:o.stderr,exitCode:o.exitCode});let l=o.stdout.trim();if(!l)throw new n("COMMAND_FAILED",`simctl get_app_container returned an empty data container path for ${r}`);let s=await t.readdir(l);return await Promise.all(s.map(e=>t.rm(a.join(l,e),{recursive:!0,force:!0}))),{bundleId:r,containerPath:l}}async function ez(e,t){return await e$.invalidateWhile(ek(e),async()=>{let i=await eB(e,t);if("simulator"!==e.kind){let t=["devicectl","device","uninstall","app","--device",e.id,i],a=await o(t,{allowFailure:!0,timeoutMs:2e4});if(0!==a.exitCode){let r=String(a.stdout??""),o=String(a.stderr??"");if(!eU(`${r}
|
|
7
7
|
${o}`.toLowerCase()))throw new n("COMMAND_FAILED",`Failed to uninstall iOS app ${i}`,{cmd:"xcrun",args:t,exitCode:a.exitCode,stdout:r,stderr:o,deviceId:e.id,hint:s(r,o)??f})}return{bundleId:i}}await b(e);let a=await eT(e,["uninstall",e.id,i],{allowFailure:!0});if(0!==a.exitCode&&!eU(`${a.stdout}
|
|
8
8
|
${a.stderr}`.toLowerCase()))throw new n("COMMAND_FAILED",`simctl uninstall failed for ${i}`,{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode});return{bundleId:i}})}async function eq(e,t,i){let a=await q({kind:"path",path:t},i);try{return await eZ(e,a.installablePath),{archivePath:a.archivePath,installablePath:a.installablePath,bundleId:a.bundleId,appName:a.appName,launchTarget:a.bundleId}}finally{await a.cleanup()}}async function eJ(e,t,i){return await e$.invalidateWhile(ek(e),async()=>{let{bundleId:a}=await ez(e,t);return await eq(e,i,{appIdentifierHint:t}),{bundleId:a}})}async function eZ(e,t){await e$.invalidateWhile(ek(e),async()=>{"simulator"!==e.kind?await A(["device","install","app","--device",e.id,t],{action:"install iOS app",deviceId:e.id}):(await b(e),await eT(e,["install",e.id,t]))})}async function eQ(e){if("macos"===e.platform)return await eo();w(e,"clipboard"),await b(e);let t=await eT(e,["pbpaste",e.id],{allowFailure:!0});if(0!==t.exitCode)throw new n("COMMAND_FAILED","Failed to read iOS simulator clipboard",{stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode});return t.stdout.replace(/\r\n/g,"\n").replace(/\n$/,"")}async function eX(e,t){if("macos"===e.platform)return void await el(t);w(e,"clipboard"),await b(e);let i=await eT(e,["pbcopy",e.id],{allowFailure:!0,stdin:t});if(0!==i.exitCode)throw new n("COMMAND_FAILED","Failed to write iOS simulator clipboard",{stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode})}async function eY(e,r,n){w(e,"push"),await b(e);let o=await t.mkdtemp(a.join(i.tmpdir(),"agent-device-ios-push-")),l=a.join(o,"payload.apns");try{await t.writeFile(l,`${JSON.stringify(n)}
|
|
9
9
|
`,"utf8"),await eT(e,["push",e.id,r,l])}finally{await t.rm(o,{recursive:!0,force:!0})}}async function e0(e,t,i,a,r){if("macos"===e.platform){let e=t.toLowerCase();if("appearance"===e)return void await ed(i);if("permission"===e){let e=$(i);if("deny"===e)throw new n("INVALID_ARGS",W("permission"));let t=function(e){let t=e?.trim().toLowerCase();if("accessibility"===t||"screen-recording"===t||"input-monitoring"===t)return t;throw new n("INVALID_ARGS","Unsupported macOS permission target. Use accessibility|screen-recording|input-monitoring.")}(r?.permissionTarget);return await h(e,t)}throw new n("INVALID_ARGS",W(t))}w(e,"settings"),await b(e);let o=t.toLowerCase();switch(o){case"clear-app-state":{if("clear"!==i.toLowerCase())throw new n("INVALID_ARGS","settings clear-app-state only supports clear.");if(!a)throw new n("INVALID_ARGS","settings clear-app-state requires an app id or an active app session.");let t=await eH(e,a);return{bundleId:t.bundleId,containerPath:t.containerPath,cleared:!0}}case"wifi":{let t=F(i);await eT(e,["status_bar",e.id,"override","--wifiMode",t?"active":"failed"]);return}case"airplane":return void(F(i)?await eT(e,["status_bar",e.id,"override","--dataNetwork","hide","--wifiMode","failed","--wifiBars","0","--cellularMode","failed","--cellularBars","0","--operatorName",""]):await eT(e,["status_bar",e.id,"clear"]));case"location":{if("set"===i.toLowerCase()){let{latitude:t,longitude:i}=j(r);return await eT(e,["location",e.id,"set",`${t},${i}`]),{latitude:t,longitude:i}}let t=F(i);if(!a)throw new n("INVALID_ARGS","location setting requires an active app in session");await eT(e,["privacy",e.id,t?"grant":"revoke","location",a]);return}case"faceid":case"touchid":{let t=e9[o],a=function(e,t){let i=e.trim().toLowerCase();if("match"===i)return"match";if("nonmatch"===i)return"nonmatch";if("enroll"===i)return"enroll";if("unenroll"===i)return"unenroll";throw new n("INVALID_ARGS",`Invalid ${t} state: ${e}. Use match|nonmatch|enroll|unenroll.`)}(i,o);await te(e,a,{settingName:o,label:t.label,modalityAliases:t.modalityAliases});return}case"appearance":{let t=await e4(e,i);await eT(e,["ui",e.id,"appearance",t]);return}case"permission":{var l;if(!a)throw new n("INVALID_ARGS","permission setting requires an active app in session");let t="deny"===(l=$(i))?"revoke":l,o=function(e,t){let i=R(e);if("photos"!==i&&t?.trim())throw new n("INVALID_ARGS",`Permission mode is only supported for photos. Received: ${t}.`);if("camera"===i)return"camera";if("microphone"===i)return"microphone";if("contacts"===i)return"contacts";if("contacts-limited"===i)return"contacts-limited";if("notifications"===i)return"notifications";if("calendar"===i)return"calendar";if("location"===i)return"location";if("location-always"===i)return"location-always";if("media-library"===i)return"media-library";if("motion"===i)return"motion";if("reminders"===i)return"reminders";if("siri"===i)return"siri";if("photos"===i){let e=t?.trim().toLowerCase();if(!e||"full"===e)return"photos";if("limited"===e)return"photos-add";throw new n("INVALID_ARGS",`Invalid photos mode: ${t}. Use full|limited.`)}throw new n("INVALID_ARGS",`Unsupported permission target: ${e}. Use camera|microphone|photos|contacts|contacts-limited|notifications|calendar|location|location-always|media-library|motion|reminders|siri.`)}(r?.permissionTarget,r?.permissionMode);await e8(e,t,o,a);return}default:throw new n("INVALID_ARGS",`Unsupported setting: ${t}`)}}async function e1(e,t){return"macos"===e.platform?await eu(t):"simulator"===e.kind?I(await e2(e),t):await v(e,t)}async function e2(e){return(await e3(e)).map(e=>({bundleId:e.bundleId,name:e.name}))}async function e3(e){let t=(await eT(e,["listapps",e.id],{allowFailure:!0})).stdout.trim();if(!t)return[];let i=null;if(t.startsWith("{"))try{i=JSON.parse(t)}catch{i=null}if(!i&&t.startsWith("{"))try{let e=await g("plutil",["-convert","json","-o","-","-"],{allowFailure:!0,stdin:t});0===e.exitCode&&e.stdout.trim().startsWith("{")&&(i=JSON.parse(e.stdout))}catch{i=null}return i?Object.entries(i).map(([e,t])=>{let i=function(e){if(e.Path)return e.Path;if(e.Bundle)try{return r(e.Bundle)}catch{return}}(t);return{bundleId:e,name:t.CFBundleDisplayName??t.CFBundleName??e,...i?{path:i}:{},...t.ApplicationType?{applicationType:t.ApplicationType}:{}}}):[]}async function e5(e){let t=await g("plutil",["-convert","json","-o","-",e],{allowFailure:!0});if(0!==t.exitCode)return new Set;try{let e=JSON.parse(t.stdout),i=new Set;for(let t of e.CFBundleURLTypes??[])if(Array.isArray(t.CFBundleURLSchemes))for(let e of t.CFBundleURLSchemes)"string"==typeof e&&e.trim()&&i.add(e.trim().toLowerCase());return i}catch{return new Set}}async function e4(e,t){let i=P(t);if("toggle"!==i)return i;let a=await eT(e,["ui",e.id,"appearance"],{allowFailure:!0});if(0!==a.exitCode)throw new n("COMMAND_FAILED","Failed to read current iOS appearance",{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode});let r=function(e,t){let i=/\b(light|dark|unsupported|unknown)\b/i.exec(`${e}
|
package/dist/src/args.js
CHANGED
|
@@ -27,7 +27,7 @@ Bootstrap:
|
|
|
27
27
|
agent-device prepare ios-runner --platform ios --timeout 240000
|
|
28
28
|
If app id is unknown, plan devices, apps, then open <discovered-app-id>. Discovery is not enough when the task asks to open/start the app.
|
|
29
29
|
Install arguments are app/package id then artifact path. If the task says install, use install; use reinstall only when explicitly requested. Fresh runtime state is open --relaunch after install.
|
|
30
|
-
In Apple CI, run prepare ios-runner after boot/install and before replay/test. prepare ios-runner builds/reuses the XCTest runner, health-checks it with a lightweight command, and retries one stuck/non-connecting runner launch before the first snapshot pays that setup cost.
|
|
30
|
+
In Apple CI, run prepare ios-runner after boot/install and before replay/test. prepare ios-runner builds/reuses the XCTest runner, health-checks it with a lightweight command, and retries one stuck/non-connecting runner launch before the first snapshot pays that setup cost. If the replay/test step starts a separate daemon, run clean:daemon after prepare so the prepared runner does not keep a live lease owned by the prepare daemon.
|
|
31
31
|
CI may cache ~/.agent-device/ios-runner/derived with an exact key that includes the agent-device package and Xcode version. Avoid broad restore-key fallbacks; prepare ios-runner already recovers bad restored runner artifacts and one retryable non-connecting runner launch. Runner build/start output is written to the session's runner.log; daemon.log is for daemon lifecycle/startup issues.
|
|
32
32
|
Do not open artifact paths or invent package ids. If apps lookup misses the target and no URL/artifact is provided, ask or stop.
|
|
33
33
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{listMcpExposedCommandNames as t,BATCH_COMMAND_NAMES as e}from"./5792.js";import{readInputRecord as a,selectorSnapshotFields as r,elementTargetField as i,stringSchema as o,stringArrayField as n,jsonSchemaField as s,booleanSchema as p,integerSchema as c,integerField as d,customField as u,assertAllowedKeys as l,booleanField as m,enumField as h,requiredEnum as f,looseObjectField as g,readPoint as y,requiredField as b,pointField as w,readFieldInput as M,stringField as v,interactionTargetField as x,fieldsInputSchema as S,requiredNumber as P,readCommonInput as k,repeatedFields as _,looseObjectSchema as C,numberField as A,optionalInteger as E}from"./9404.js";import{PERF_AREA_VALUES as j,PERF_ACTION_VALUES as I}from"./8020.js";import{requireCommandDescription as R}from"./2805.js";function U(t,e){return{...t,run:e,invoke:async(a,r)=>await e(a,t.readInput(r))}}function O(t=e){var a;let r={steps:b(u({type:"array",description:"Structured batch steps. Each step uses a command name and the same input object as that command tool.",items:{type:"object",properties:{command:{type:"string",enum:a=t,description:"Command name to run with structured input."},input:{type:"object",additionalProperties:!0,description:"Structured command input for the nested command. Use the matching MCP tool schema for this object."},runtime:{type:"object",additionalProperties:!0,description:"Optional per-step runtime payload."}},required:["command","input"],additionalProperties:!1}},(t,e)=>(function(t,e){if(!Array.isArray(t))throw Error("Expected steps to be an array.");return t.map((t,a)=>{var r,i,o;let n;return r=t,i=a+1,o=e,l(n=function(t,e){if(!t||"object"!=typeof t||Array.isArray(t))throw Error(`Invalid batch step ${e}.`);return t}(r,i),["command","input","runtime"],`Batch step ${i}`),{command:f(n,"command",o),input:function(t,e){let a=t.input;if(!a||"object"!=typeof a||Array.isArray(a))throw Error(`Batch step ${e} input must be an object.`);return a}(n,i),...function(t,e){let a=t.runtime;if(void 0!==a&&(!a||"object"!=typeof a||Array.isArray(a)))throw Error(`Batch step ${e} runtime must be an object.`);return void 0===a?{}:{runtime:a}}(n,i)}})})(t[e],a))),onError:h(["stop"],"Batch failure policy."),maxSteps:d("Maximum number of steps accepted for this batch.",{min:1,max:1e3}),out:v("Optional output path for command artifacts.")};return{name:"batch",description:"Run multiple structured command steps in one daemon request.",inputSchema:S(r),readInput:t=>(function(t,e){let a=M(t,e),r=a.maxSteps??100;if(!Number.isInteger(r)||r<1||r>1e3)throw Error(`Invalid batch maxSteps: ${String(a.maxSteps)}`);if(a.steps.length>r)throw Error(`batch has ${a.steps.length} steps; max allowed is ${r}.`);return{...a}})(t,r)}}function B(t,e,a){return{name:t,description:e,inputSchema:S(a),readInput:t=>M(t,a)}}let K=["app","frontmost-app","desktop","menubar"],N=["start","stop"],$=[F("devices",{}),F("boot",{headless:m("Boot without showing simulator UI when supported.")}),F("prepare",{action:b(h(["ios-runner"])),timeoutMs:d("Maximum wall-clock time for the prepare command.")}),F("apps",{appsFilter:h(["user-installed","all"])}),F("session",{action:h(["list"])}),F("open",{app:v("App name, bundle id, package, or URL."),url:v("Optional URL passed with an app shell."),surface:h(K),activity:v("Android activity name."),launchConsole:v("Launch console mode."),launchArgs:n("Launch arguments forwarded verbatim to the platform launch command."),relaunch:m("Force relaunch."),saveScript:s({oneOf:[p(),o()]}),noRecord:m("Do not record this action.")}),F("close",{app:v("Optional app to close."),shutdown:m("Shutdown the session/device where supported."),saveScript:s({oneOf:[p(),o()]})}),F("install",{app:b(v()),appPath:b(v("Path to app binary."))}),F("reinstall",{app:b(v()),appPath:b(v("Path to app binary."))}),F("install-from-source",{source:b(s(C("Install source object."))),retainPaths:m(),retentionMs:d()}),F("push",{app:b(v()),payload:b(s({oneOf:[o(),C()]}))}),F("trigger-app-event",{event:b(v()),payload:g()}),F("snapshot",{interactiveOnly:m(),compact:m(),depth:d(),scope:v(),raw:m(),forceFull:m(),timeoutMs:d("Maximum wall-clock time for the snapshot command.")}),F("screenshot",{path:v("Output path."),overlayRefs:m(),fullscreen:m(),maxSize:d(),stabilize:m(),surface:h(K)}),F("diff",{kind:b(s({type:"string",const:"snapshot"})),out:v(),interactiveOnly:m(),compact:m(),depth:d(),scope:v(),raw:m()}),F("wait",{kind:h(["duration","text","ref","selector"]),durationMs:d(),text:v(),ref:v(),selector:v(),timeoutMs:d(),depth:d(),scope:v(),raw:m()}),F("alert",{action:h(["get","accept","dismiss","wait"]),timeoutMs:d()}),F("appstate",{}),F("back",{mode:h(["in-app","system"])}),F("home",{}),F("rotate",{orientation:b(h(["portrait","portrait-upside-down","landscape-left","landscape-right"]))}),F("app-switcher",{}),F("keyboard",{action:h(["status","dismiss"])}),F("clipboard",{action:b(h(["read","write"])),text:v()}),F("react-native",{action:b(h(["dismiss-overlay"]))}),F("replay",{path:b(v()),update:m(),backend:v(),maestro:m(),env:n()}),F("test",{paths:b(n()),update:m(),backend:v(),maestro:m(),env:n(),failFast:m(),timeoutMs:d(),retries:d(),artifactsDir:v(),reportJunit:v(),shardAll:d(),shardSplit:d()}),F("perf",{area:h(j),action:h(I)}),F("logs",{action:h(["path","start","stop","doctor","mark","clear"]),message:v(),restart:m()}),F("network",{action:h(["dump","log"]),limit:d(),include:h(["summary","headers","body","all"])}),F("record",{action:b(h(N)),path:v(),fps:d(),quality:s(c()),hideTouches:m()}),F("trace",{action:b(h(N)),path:v()}),F("settings",{setting:b(v()),state:b(v()),app:v(),latitude:A(),longitude:A(),permission:v(),mode:h(["full","limited"])}),F("metro",{action:b(h(["prepare","reload"])),projectRoot:v(),kind:s(o()),publicBaseUrl:v(),proxyBaseUrl:v(),bearerToken:v(),bridgeScope:s({type:"object",additionalProperties:!0}),launchUrl:v(),port:d(),listenHost:v(),statusHost:v(),startupTimeoutMs:d(),probeTimeoutMs:d(),reuseExisting:m(),installDependenciesIfNeeded:m(),runtimeFilePath:v(),logPath:v(),metroHost:v(),metroPort:d(),bundleUrl:v(),timeoutMs:d()})];function F(t,e){return B(t,R(t),e)}let H=["pan","fling","swipe","pinch","rotate","transform"],T=["up","down","left","right"],D=["left","right","left-edge","right-edge"],L={target:b(x()),button:h(["primary","secondary","middle"],"Pointer button for platforms that support mouse buttons."),...r(),..._()},q={target:b(x()),...r(),..._()},G={target:b(x()),text:b(v("Text to enter into the target.")),delayMs:d("Delay between typed characters.",{min:0}),...r()},z={target:b(x()),durationMs:d("Long press duration in milliseconds.",{min:0}),...r()},J={from:b(w("Swipe start point.")),to:b(w("Swipe end point.")),durationMs:d("Swipe duration in milliseconds.",{min:0}),count:d("Number of swipe repetitions.",{min:1}),pauseMs:d("Pause between repeated swipes.",{min:0}),pattern:h(["one-way","ping-pong"])},
|
|
1
|
+
import{listMcpExposedCommandNames as t,BATCH_COMMAND_NAMES as e}from"./5792.js";import{readInputRecord as a,selectorSnapshotFields as r,elementTargetField as i,stringSchema as o,stringArrayField as n,jsonSchemaField as s,booleanSchema as p,integerSchema as c,integerField as d,customField as u,assertAllowedKeys as l,booleanField as m,enumField as h,requiredEnum as f,looseObjectField as g,readPoint as y,requiredField as b,pointField as w,readFieldInput as M,stringField as v,interactionTargetField as x,fieldsInputSchema as S,requiredNumber as P,readCommonInput as k,repeatedFields as _,looseObjectSchema as C,numberField as A,optionalInteger as E}from"./9404.js";import{PERF_AREA_VALUES as j,PERF_ACTION_VALUES as I}from"./8020.js";import{requireCommandDescription as R}from"./2805.js";function U(t,e){return{...t,run:e,invoke:async(a,r)=>await e(a,t.readInput(r))}}function O(t=e){var a;let r={steps:b(u({type:"array",description:"Structured batch steps. Each step uses a command name and the same input object as that command tool.",items:{type:"object",properties:{command:{type:"string",enum:a=t,description:"Command name to run with structured input."},input:{type:"object",additionalProperties:!0,description:"Structured command input for the nested command. Use the matching MCP tool schema for this object."},runtime:{type:"object",additionalProperties:!0,description:"Optional per-step runtime payload."}},required:["command","input"],additionalProperties:!1}},(t,e)=>(function(t,e){if(!Array.isArray(t))throw Error("Expected steps to be an array.");return t.map((t,a)=>{var r,i,o;let n;return r=t,i=a+1,o=e,l(n=function(t,e){if(!t||"object"!=typeof t||Array.isArray(t))throw Error(`Invalid batch step ${e}.`);return t}(r,i),["command","input","runtime"],`Batch step ${i}`),{command:f(n,"command",o),input:function(t,e){let a=t.input;if(!a||"object"!=typeof a||Array.isArray(a))throw Error(`Batch step ${e} input must be an object.`);return a}(n,i),...function(t,e){let a=t.runtime;if(void 0!==a&&(!a||"object"!=typeof a||Array.isArray(a)))throw Error(`Batch step ${e} runtime must be an object.`);return void 0===a?{}:{runtime:a}}(n,i)}})})(t[e],a))),onError:h(["stop"],"Batch failure policy."),maxSteps:d("Maximum number of steps accepted for this batch.",{min:1,max:1e3}),out:v("Optional output path for command artifacts.")};return{name:"batch",description:"Run multiple structured command steps in one daemon request.",inputSchema:S(r),readInput:t=>(function(t,e){let a=M(t,e),r=a.maxSteps??100;if(!Number.isInteger(r)||r<1||r>1e3)throw Error(`Invalid batch maxSteps: ${String(a.maxSteps)}`);if(a.steps.length>r)throw Error(`batch has ${a.steps.length} steps; max allowed is ${r}.`);return{...a}})(t,r)}}function B(t,e,a){return{name:t,description:e,inputSchema:S(a),readInput:t=>M(t,a)}}let K=["app","frontmost-app","desktop","menubar"],N=["start","stop"],$=[F("devices",{}),F("boot",{headless:m("Boot without showing simulator UI when supported.")}),F("prepare",{action:b(h(["ios-runner"])),timeoutMs:d("Maximum wall-clock time for the prepare command.")}),F("apps",{appsFilter:h(["user-installed","all"])}),F("session",{action:h(["list"])}),F("open",{app:v("App name, bundle id, package, or URL."),url:v("Optional URL passed with an app shell."),surface:h(K),activity:v("Android activity name."),launchConsole:v("Launch console mode."),launchArgs:n("Launch arguments forwarded verbatim to the platform launch command."),relaunch:m("Force relaunch."),saveScript:s({oneOf:[p(),o()]}),noRecord:m("Do not record this action.")}),F("close",{app:v("Optional app to close."),shutdown:m("Shutdown the session/device where supported."),saveScript:s({oneOf:[p(),o()]})}),F("install",{app:b(v()),appPath:b(v("Path to app binary."))}),F("reinstall",{app:b(v()),appPath:b(v("Path to app binary."))}),F("install-from-source",{source:b(s(C("Install source object."))),retainPaths:m(),retentionMs:d()}),F("push",{app:b(v()),payload:b(s({oneOf:[o(),C()]}))}),F("trigger-app-event",{event:b(v()),payload:g()}),F("snapshot",{interactiveOnly:m(),compact:m(),depth:d(),scope:v(),raw:m(),forceFull:m(),timeoutMs:d("Maximum wall-clock time for the snapshot command.")}),F("screenshot",{path:v("Output path."),overlayRefs:m(),fullscreen:m(),maxSize:d(),stabilize:m(),surface:h(K)}),F("diff",{kind:b(s({type:"string",const:"snapshot"})),out:v(),interactiveOnly:m(),compact:m(),depth:d(),scope:v(),raw:m()}),F("wait",{kind:h(["duration","text","ref","selector"]),durationMs:d(),text:v(),ref:v(),selector:v(),timeoutMs:d(),depth:d(),scope:v(),raw:m()}),F("alert",{action:h(["get","accept","dismiss","wait"]),timeoutMs:d()}),F("appstate",{}),F("back",{mode:h(["in-app","system"])}),F("home",{}),F("rotate",{orientation:b(h(["portrait","portrait-upside-down","landscape-left","landscape-right"]))}),F("app-switcher",{}),F("keyboard",{action:h(["status","dismiss"])}),F("clipboard",{action:b(h(["read","write"])),text:v()}),F("react-native",{action:b(h(["dismiss-overlay"]))}),F("replay",{path:b(v()),update:m(),backend:v(),maestro:m(),env:n()}),F("test",{paths:b(n()),update:m(),backend:v(),maestro:m(),env:n(),failFast:m(),timeoutMs:d(),retries:d(),recordVideo:m(),artifactsDir:v(),reportJunit:v(),shardAll:d(),shardSplit:d()}),F("perf",{area:h(j),action:h(I)}),F("logs",{action:h(["path","start","stop","doctor","mark","clear"]),message:v(),restart:m()}),F("network",{action:h(["dump","log"]),limit:d(),include:h(["summary","headers","body","all"])}),F("record",{action:b(h(N)),path:v(),fps:d(),quality:s(c()),hideTouches:m()}),F("trace",{action:b(h(N)),path:v()}),F("settings",{setting:b(v()),state:b(v()),app:v(),latitude:A(),longitude:A(),permission:v(),mode:h(["full","limited"])}),F("metro",{action:b(h(["prepare","reload"])),projectRoot:v(),kind:s(o()),publicBaseUrl:v(),proxyBaseUrl:v(),bearerToken:v(),bridgeScope:s({type:"object",additionalProperties:!0}),launchUrl:v(),port:d(),listenHost:v(),statusHost:v(),startupTimeoutMs:d(),probeTimeoutMs:d(),reuseExisting:m(),installDependenciesIfNeeded:m(),runtimeFilePath:v(),logPath:v(),metroHost:v(),metroPort:d(),bundleUrl:v(),timeoutMs:d()})];function F(t,e){return B(t,R(t),e)}let H=["pan","fling","swipe","pinch","rotate","transform"],T=["up","down","left","right"],D=["left","right","left-edge","right-edge"],L={target:b(x()),button:h(["primary","secondary","middle"],"Pointer button for platforms that support mouse buttons."),...r(),..._()},q={target:b(x()),...r(),..._()},G={target:b(x()),text:b(v("Text to enter into the target.")),delayMs:d("Delay between typed characters.",{min:0}),...r()},z={target:b(x()),durationMs:d("Long press duration in milliseconds.",{min:0}),...r()},J={from:b(w("Swipe start point.")),to:b(w("Swipe end point.")),durationMs:d("Swipe duration in milliseconds.",{min:0}),count:d("Number of swipe repetitions.",{min:1}),pauseMs:d("Pause between repeated swipes.",{min:0}),pattern:h(["one-way","ping-pong"])},V={x:b(A("X coordinate.")),y:b(A("Y coordinate."))},X={text:b(v("Text to type.")),delayMs:d("Delay between typed characters.",{min:0})},Y={direction:b(h(["up","down","left","right","top","bottom"])),amount:A("Platform scroll amount."),pixels:d("Pixel scroll amount.",{min:0})},Q={format:b(h(["text","attrs"])),target:b(i()),...r()},W={predicate:b(h(["visible","hidden","exists","editable","selected","text"])),selector:b(v()),value:v(),...r()},Z={locator:h(["any","text","label","value","role","id"]),query:b(v()),action:h(["click","focus","exists","getText","getAttrs","wait","fill","type"]),value:v(),timeoutMs:d(),first:m(),last:m(),depth:d(),raw:m()},tt={kind:b(h(H,"Gesture variant.")),direction:h(T,"Fling direction."),preset:h(D,"Swipe preset."),origin:w("Gesture origin point."),delta:w("Movement delta for pan or transform gestures."),distance:d("Fling distance.",{min:0}),scale:A("Pinch or transform scale."),degrees:A("Rotation in degrees."),velocity:d("Rotate gesture velocity.",{min:0}),durationMs:d("Gesture duration in milliseconds.",{min:0})},te=[{name:"click",description:R("click"),inputSchema:S(L),readInput:t=>M(t,L)},{name:"press",description:R("press"),inputSchema:S(q),readInput:t=>M(t,q)},{name:"fill",description:R("fill"),inputSchema:S(G),readInput:t=>M(t,G)},ta("longpress",z),ta("swipe",J),ta("focus",V),ta("type",X),ta("scroll",Y),ta("get",Q),ta("is",W),ta("find",Z),{name:"gesture",description:R("gesture"),inputSchema:S(tt),readInput:function(t){let e=a(t),r=k(e),i=f(e,"kind",H);return"pan"===i?{...r,kind:i,origin:y(e,"origin"),delta:y(e,"delta"),durationMs:E(e,"durationMs",{min:0})}:"fling"===i?{...r,kind:i,direction:f(e,"direction",T),origin:y(e,"origin"),distance:E(e,"distance",{min:0}),durationMs:E(e,"durationMs",{min:0})}:"swipe"===i?{...r,kind:i,preset:f(e,"preset",D),durationMs:E(e,"durationMs",{min:0})}:"pinch"===i?{...r,kind:i,scale:P(e,"scale"),origin:tr(e,"origin")}:"rotate"===i?{...r,kind:i,degrees:P(e,"degrees"),origin:tr(e,"origin"),velocity:E(e,"velocity",{min:0})}:{...r,kind:i,origin:y(e,"origin"),delta:y(e,"delta"),scale:P(e,"scale"),degrees:P(e,"degrees"),durationMs:E(e,"durationMs",{min:0})}}}];function ta(t,e){return B(t,R(t),e)}function tr(t,e){return void 0===t[e]?void 0:y(t,e)}let ti=new Map([...te,...$,O(e)].map(t=>[t.name,t]));function to(){return t().map(t=>{var e;if(!tn(t))throw Error(`Missing command metadata for MCP-exposed command: ${t}`);return e=t,ti.get(e)})}function tn(t){return ti.has(t)}export{$ as clientCommandMetadata,O as createBatchCommandMetadata,U as defineExecutableCommand,te as interactionCommandMetadata,tn as isCommandName,to as listMcpCommandMetadata};
|