agent-device 0.16.0 → 0.16.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.16.0.apk → agent-device-android-multitouch-helper-0.16.2.apk} +0 -0
- package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.16.2.apk.sha256 +1 -0
- package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.16.0.manifest.json → agent-device-android-multitouch-helper-0.16.2.manifest.json} +4 -4
- package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.16.0.apk → agent-device-android-snapshot-helper-0.16.2.apk} +0 -0
- package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.16.2.apk.sha256 +1 -0
- package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.16.0.manifest.json → agent-device-android-snapshot-helper-0.16.2.manifest.json} +6 -6
- package/dist/src/1769.js +7 -7
- package/dist/src/6277.js +4 -0
- package/dist/src/7519.js +1 -1
- package/dist/src/89.js +1 -1
- package/dist/src/9542.js +3 -2
- package/dist/src/batch.d.ts +1 -0
- package/dist/src/cli.js +8 -11
- package/dist/src/contracts.d.ts +1 -0
- package/dist/src/contracts.js +1 -1
- package/dist/src/index.d.ts +1 -0
- package/dist/src/internal/daemon.js +51 -50
- package/dist/src/server.js +1 -1
- package/package.json +1 -4
- package/server.json +2 -2
- package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.16.0.apk.sha256 +0 -1
- package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.16.0.apk.sha256 +0 -1
- package/dist/src/2099.js +0 -1
package/dist/src/89.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var t;let e;import{DEFAULT_BATCH_MAX_STEPS as r}from"./1231.js";import{jsonSchemaField as a,stringField as i,batchCommandNames as n,toSelectorSnapshotOptions as o,booleanSchema as s,integerSchema as p,assertAllowedKeys as c,requiredEnum as d,looseObjectField as l,requiredField as u,listMcpExposedCommandNames as m,readFieldInput as h,commonToClientOptions as g,integerField as f,numberField as y,booleanField as b,readInputRecord as v,repeatedFields as w,stringSchema as x,stringArrayField as M,toClientElementTarget as S,customField as k,optionalEnum as I,enumField as P,toRepeatedOptions as R,pointField as U,command_input_readPoint as C,toClientInteractionTarget as E,interactionTargetField as T,fieldsInputSchema as j,requiredNumber as A,selectorSnapshotFields as F,elementTargetField as N,readCommonInput as O,looseObjectSchema as B,optionalInteger as H}from"./2099.js";function D(t){return{...t,invoke:async(e,r)=>await t.run(e,t.readInput(r))}}function L(t,e,r,a){return D({name:t,description:e,inputSchema:j(r),readInput:t=>h(t,r),run:a})}let _=["app","frontmost-app","desktop","menubar"],$=["duration","text","ref","selector"],G=["start","stop"],q=[L("devices","List available devices.",{},(t,e)=>t.devices.list(e)),L("boot","Boot or prepare a selected device without using CLI positional arguments.",{headless:b("Boot without showing simulator UI when supported.")},(t,e)=>t.devices.boot(e)),L("apps","List installed apps.",{appsFilter:P(["user-installed","all"])},(t,e)=>t.apps.list(e)),L("session","List active sessions.",{action:P(["list"])},async(t,{action:e,...r})=>({sessions:await t.sessions.list(r)})),L("open","Open an app, deep link, URL, or platform surface.",{app:i("App name, bundle id, package, or URL."),url:i("Optional URL passed with an app shell."),surface:P(_),activity:i("Android activity name."),launchConsole:i("Launch console mode."),relaunch:b("Force relaunch."),saveScript:a({oneOf:[s(),x()]}),noRecord:b("Do not record this action.")},(t,e)=>t.apps.open(e)),L("close","Close an app or end the active session.",{app:i("Optional app to close."),shutdown:b("Shutdown the session/device where supported."),saveScript:a({oneOf:[s(),x()]})},(t,e)=>e.app?t.apps.close(e):t.sessions.close(function(t){let{app:e,...r}=t;return r}(e))),L("install","Install an app binary.",{app:u(i()),appPath:u(i("Path to app binary."))},(t,e)=>t.apps.install(e)),L("reinstall","Reinstall an app binary.",{app:u(i()),appPath:u(i("Path to app binary."))},(t,e)=>t.apps.reinstall(e)),L("install-from-source","Install an app from a structured source.",{source:u(a(B("Install source object."))),retainPaths:b(),retentionMs:f()},(t,e)=>t.apps.installFromSource(e)),L("push","Deliver a push payload.",{app:u(i()),payload:u(a({oneOf:[x(),B()]}))},(t,e)=>t.apps.push(e)),L("trigger-app-event","Trigger an app-defined event.",{event:u(i()),payload:l()},(t,e)=>t.apps.triggerEvent(e)),L("snapshot","Capture an accessibility snapshot.",{interactiveOnly:b(),compact:b(),depth:f(),scope:i(),raw:b(),forceFull:b()},(t,e)=>t.capture.snapshot(e)),L("screenshot","Capture a screenshot.",{path:i("Output path."),overlayRefs:b(),fullscreen:b(),maxSize:f(),stabilize:b(),surface:P(_)},(t,e)=>t.capture.screenshot(e)),L("diff","Diff accessibility snapshots.",{kind:u(a({type:"string",const:"snapshot"})),out:i(),interactiveOnly:b(),compact:b(),depth:f(),scope:i(),raw:b()},(t,e)=>t.capture.diff(e)),L("wait","Wait for duration, text, ref, or selector.",{kind:P($),durationMs:f(),text:i(),ref:i(),selector:i(),timeoutMs:f(),depth:f(),scope:i(),raw:b()},(t,e)=>{var r;let a;return t.command.wait((I(r=e,"kind",$),a={...r},delete a.kind,a))}),L("alert","Inspect or handle platform alerts.",{action:P(["get","accept","dismiss","wait"]),timeoutMs:f()},(t,e)=>t.command.alert(e)),L("appstate","Show foreground app or activity.",{},(t,e)=>t.command.appState(e)),L("back","Navigate back.",{mode:P(["in-app","system"])},(t,e)=>t.command.back(e)),L("home","Go to the home screen.",{},(t,e)=>t.command.home(e)),L("rotate","Rotate device orientation.",{orientation:u(P(["portrait","portrait-upside-down","landscape-left","landscape-right"]))},(t,e)=>t.command.rotate(e)),L("app-switcher","Open the app switcher.",{},(t,e)=>t.command.appSwitcher(e)),L("keyboard","Inspect or dismiss the keyboard.",{action:P(["status","dismiss"])},(t,e)=>t.command.keyboard(e)),L("clipboard","Read or write clipboard text.",{action:u(P(["read","write"])),text:i()},(t,e)=>t.command.clipboard(e)),L("react-native","Run supported React Native app automation helpers.",{action:u(P(["dismiss-overlay"]))},(t,e)=>t.command.reactNative(e)),L("replay","Replay a recorded session.",{path:u(i()),update:b(),backend:i(),env:M()},(t,e)=>t.replay.run(e)),L("test","Run one or more .ad scripts.",{paths:u(M()),update:b(),env:M(),failFast:b(),timeoutMs:f(),retries:f(),artifactsDir:i(),reportJunit:i()},(t,e)=>t.replay.test(e)),L("perf","Show session performance metrics.",{},(t,e)=>t.observability.perf(e)),L("logs","Manage session app logs.",{action:P(["path","start","stop","doctor","mark","clear"]),message:i(),restart:b()},(t,e)=>t.observability.logs(e)),L("network","Show recent HTTP traffic.",{action:P(["dump","log"]),limit:f(),include:P(["summary","headers","body","all"])},(t,e)=>t.observability.network(e)),L("record","Start or stop screen recording.",{action:u(P(G)),path:i(),fps:f(),quality:a(p()),hideTouches:b()},(t,e)=>t.recording.record(e)),L("trace","Start or stop trace capture.",{action:u(P(G)),path:i()},(t,e)=>t.recording.trace(e)),L("settings","Change OS settings and app permissions.",{setting:u(i()),state:u(i()),latitude:y(),longitude:y(),permission:i(),mode:P(["full","limited"])},(t,e)=>t.settings.update(e)),L("metro","Prepare Metro runtime or reload React Native apps.",{action:u(P(["prepare","reload"])),projectRoot:i(),kind:a(x()),publicBaseUrl:i(),proxyBaseUrl:i(),bearerToken:i(),bridgeScope:a({type:"object",additionalProperties:!0}),launchUrl:i(),port:f(),listenHost:i(),statusHost:i(),startupTimeoutMs:f(),probeTimeoutMs:f(),reuseExisting:b(),installDependenciesIfNeeded:b(),runtimeFilePath:i(),logPath:i(),metroHost:i(),metroPort:f(),bundleUrl:i(),timeoutMs:f()},async(t,e)=>{var r,a,i;return"prepare"===e.action?await t.metro.prepare({projectRoot:(r=e).projectRoot,kind:r.kind,publicBaseUrl:r.publicBaseUrl,proxyBaseUrl:r.proxyBaseUrl,bearerToken:r.bearerToken,bridgeScope:r.bridgeScope??((a=r).tenant&&a.runId&&a.leaseId?{tenantId:a.tenant,runId:a.runId,leaseId:a.leaseId}:void 0),port:r.port,listenHost:r.listenHost,statusHost:r.statusHost,startupTimeoutMs:r.startupTimeoutMs,probeTimeoutMs:r.probeTimeoutMs,reuseExisting:r.reuseExisting,installDependenciesIfNeeded:r.installDependenciesIfNeeded,runtimeFilePath:r.runtimeFilePath}):await t.metro.reload({metroHost:(i=e).metroHost,metroPort:i.metroPort,bundleUrl:i.bundleUrl,timeoutMs:i.timeoutMs})})],K=["pan","fling","pinch","rotate","transform"],z=["up","down","left","right"],J={target:u(T()),button:P(["primary","secondary","middle"],"Pointer button for platforms that support mouse buttons."),...F(),...w()},W={target:u(T()),...F(),...w()},X={target:u(T()),text:u(i("Text to enter into the target.")),delayMs:f("Delay between typed characters.",{min:0}),...F()},Y={target:u(T()),durationMs:f("Long press duration in milliseconds.",{min:0}),...F()},Q={from:u(U("Swipe start point.")),to:u(U("Swipe end point.")),durationMs:f("Swipe duration in milliseconds.",{min:0}),count:f("Number of swipe repetitions.",{min:1}),pauseMs:f("Pause between repeated swipes.",{min:0}),pattern:P(["one-way","ping-pong"])},V={x:u(y("X coordinate.")),y:u(y("Y coordinate."))},Z={text:u(i("Text to type.")),delayMs:f("Delay between typed characters.",{min:0})},tt={direction:u(P(["up","down","left","right","top","bottom"])),amount:y("Platform scroll amount."),pixels:f("Pixel scroll amount.",{min:0})},te={format:u(P(["text","attrs"])),target:u(N()),...F()},tr={predicate:u(P(["visible","hidden","exists","editable","selected","text"])),selector:u(i()),value:i(),...F()},ta={locator:P(["any","text","label","value","role","id"]),query:u(i()),action:P(["click","focus","exists","getText","getAttrs","wait","fill","type"]),value:i(),timeoutMs:f(),first:b(),last:b(),depth:f(),raw:b()},ti={kind:u(P(K,"Gesture variant.")),direction:P(z,"Fling direction."),origin:U("Gesture origin point."),delta:U("Movement delta for pan or transform gestures."),distance:f("Fling distance.",{min:0}),scale:y("Pinch or transform scale."),degrees:y("Rotation in degrees."),velocity:f("Rotate gesture velocity.",{min:0}),durationMs:f("Gesture duration in milliseconds.",{min:0})};function tn(t,e){return void 0===t[e]?void 0:C(t,e)}let to=[D({name:"click",description:"Click or tap a semantic UI target by ref, selector, or point.",inputSchema:j(J),readInput:t=>h(t,J),run:(t,e)=>{var r;return t.interactions.click({...g(r=e),...E(r.target),...o(r),...R(r),button:r.button})}}),D({name:"press",description:"Press a semantic UI target by ref, selector, or point.",inputSchema:j(W),readInput:t=>h(t,W),run:(t,e)=>{var r;return t.interactions.press({...g(r=e),...E(r.target),...o(r),...R(r)})}}),D({name:"fill",description:"Fill text into a semantic UI target by ref, selector, or point.",inputSchema:j(X),readInput:t=>h(t,X),run:(t,e)=>{var r;return t.interactions.fill({...g(r=e),...E(r.target),...o(r),text:r.text,delayMs:r.delayMs})}}),L("longpress","Long press by ref, selector, or point.",Y,(t,e)=>{var r;return t.interactions.longPress({...g(r=e),...E(r.target),...o(r),durationMs:r.durationMs})}),L("swipe","Swipe between two points.",Q,(t,e)=>t.interactions.swipe(e)),L("focus","Focus input at coordinates.",V,(t,e)=>t.interactions.focus(e)),L("type","Type text in the focused field.",Z,(t,e)=>t.interactions.type(e)),L("scroll","Scroll in a direction or to an edge.",tt,(t,e)=>t.interactions.scroll(e)),L("get","Get element text or attributes.",te,(t,e)=>{var r;return t.interactions.get({...g(r=e),...S(r.target),...o(r),format:r.format})}),L("is","Assert UI state.",tr,(t,e)=>t.interactions.is(e)),L("find","Find an element and optionally act on it.",ta,(t,e)=>t.interactions.find(e)),D({name:"gesture",description:"Run a structured gesture.",inputSchema:j(ti),readInput:function(t){let e=v(t),r=O(e),a=d(e,"kind",K);return"pan"===a?{...r,kind:a,origin:C(e,"origin"),delta:C(e,"delta"),durationMs:H(e,"durationMs",{min:0})}:"fling"===a?{...r,kind:a,direction:d(e,"direction",z),origin:C(e,"origin"),distance:H(e,"distance",{min:0}),durationMs:H(e,"durationMs",{min:0})}:"pinch"===a?{...r,kind:a,scale:A(e,"scale"),origin:tn(e,"origin")}:"rotate"===a?{...r,kind:a,degrees:A(e,"degrees"),origin:tn(e,"origin"),velocity:H(e,"velocity",{min:0})}:{...r,kind:a,origin:C(e,"origin"),delta:C(e,"delta"),scale:A(e,"scale"),degrees:A(e,"degrees"),durationMs:H(e,"durationMs",{min:0})}},run:async(t,e)=>{var r,a,i,n,o;switch(e.kind){case"pan":return await t.interactions.pan({...g(r=e),x:r.origin.x,y:r.origin.y,dx:r.delta.x,dy:r.delta.y,durationMs:r.durationMs});case"fling":return await t.interactions.fling({...g(a=e),direction:a.direction,x:a.origin.x,y:a.origin.y,distance:a.distance,durationMs:a.durationMs});case"pinch":return await t.interactions.pinch({...g(i=e),scale:i.scale,x:i.origin?.x,y:i.origin?.y});case"rotate":return await t.interactions.rotateGesture({...g(n=e),degrees:n.degrees,x:n.origin?.x,y:n.origin?.y,velocity:n.velocity});case"transform":return await t.interactions.transformGesture({...g(o=e),x:o.origin.x,y:o.origin.y,dx:o.delta.x,dy:o.delta.y,scale:o.scale,degrees:o.degrees,durationMs:o.durationMs})}}}),...q,D({name:"batch",description:"Run multiple structured command steps in one daemon request.",inputSchema:j(e={steps:u(k({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:t=n,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}},(e,r)=>(function(t,e){if(!Array.isArray(t))throw Error("Expected steps to be an array.");return t.map((t,r)=>{var a,i,n;let o;return a=t,i=r+1,n=e,c(o=function(t,e){if(!t||"object"!=typeof t||Array.isArray(t))throw Error(`Invalid batch step ${e}.`);return t}(a,i),["command","input","runtime"],`Batch step ${i}`),{command:d(o,"command",n),input:function(t,e){let r=t.input;if(!r||"object"!=typeof r||Array.isArray(r))throw Error(`Batch step ${e} input must be an object.`);return r}(o,i),...function(t,e){let r=t.runtime;if(void 0!==r&&(!r||"object"!=typeof r||Array.isArray(r)))throw Error(`Batch step ${e} runtime must be an object.`);return void 0===r?{}:{runtime:r}}(o,i)}})})(e[r],t))),onError:P(["stop"],"Batch failure policy."),maxSteps:f("Maximum number of steps accepted for this batch.",{min:1,max:1e3}),out:i("Optional output path for command artifacts.")}),readInput:t=>(function(t,e){let a=h(t,e),i=a.maxSteps??r;if(!Number.isInteger(i)||i<1||i>1e3)throw Error(`Invalid batch maxSteps: ${String(a.maxSteps)}`);if(a.steps.length>i)throw Error(`batch has ${a.steps.length} steps; max allowed is ${i}.`);return{...a}})(t,e),run:(t,e)=>{var r;return t.batch.run({...g(r=e),steps:r.steps,onError:r.onError,maxSteps:r.maxSteps,out:r.out})}})],ts=new Map(to.map(t=>[t.name,t]));function tp(){return m().map(t=>{var e;if(!tl(t))throw Error(`Missing command for MCP-exposed command: ${t}`);return e=t,ts.get(e)})}function tc(){return to.map(t=>t.name)}function td(){return[...to]}function tl(t){return ts.has(t)}async function tu(t,e,r){var a;return await (a=e,ts.get(a)).invoke(t,r)}export{tl as isCommandName,td as listCommandDefinitions,tc as listCommandNames,tp as listMcpToolDefinitions,tu as runCommand};
|
|
1
|
+
var t;let e;import{DEFAULT_BATCH_MAX_STEPS as r}from"./1231.js";import{jsonSchemaField as a,stringField as i,batchCommandNames as n,toSelectorSnapshotOptions as o,booleanSchema as s,integerSchema as p,assertAllowedKeys as c,requiredEnum as d,looseObjectField as l,requiredField as u,listMcpExposedCommandNames as m,readFieldInput as h,commonToClientOptions as g,integerField as f,numberField as y,booleanField as b,readInputRecord as v,repeatedFields as w,stringSchema as x,stringArrayField as M,toClientElementTarget as S,customField as k,optionalEnum as I,enumField as P,toRepeatedOptions as R,pointField as U,command_input_readPoint as C,toClientInteractionTarget as E,interactionTargetField as T,fieldsInputSchema as j,requiredNumber as A,selectorSnapshotFields as F,elementTargetField as N,readCommonInput as O,looseObjectSchema as B,optionalInteger as H}from"./6277.js";function D(t){return{...t,invoke:async(e,r)=>await t.run(e,t.readInput(r))}}function L(t,e,r,a){return D({name:t,description:e,inputSchema:j(r),readInput:t=>h(t,r),run:a})}let _=["app","frontmost-app","desktop","menubar"],$=["duration","text","ref","selector"],G=["start","stop"],q=[L("devices","List available devices.",{},(t,e)=>t.devices.list(e)),L("boot","Boot or prepare a selected device without using CLI positional arguments.",{headless:b("Boot without showing simulator UI when supported.")},(t,e)=>t.devices.boot(e)),L("apps","List installed apps.",{appsFilter:P(["user-installed","all"])},(t,e)=>t.apps.list(e)),L("session","List active sessions.",{action:P(["list"])},async(t,{action:e,...r})=>({sessions:await t.sessions.list(r)})),L("open","Open an app, deep link, URL, or platform surface.",{app:i("App name, bundle id, package, or URL."),url:i("Optional URL passed with an app shell."),surface:P(_),activity:i("Android activity name."),launchConsole:i("Launch console mode."),relaunch:b("Force relaunch."),saveScript:a({oneOf:[s(),x()]}),noRecord:b("Do not record this action.")},(t,e)=>t.apps.open(e)),L("close","Close an app or end the active session.",{app:i("Optional app to close."),shutdown:b("Shutdown the session/device where supported."),saveScript:a({oneOf:[s(),x()]})},(t,e)=>e.app?t.apps.close(e):t.sessions.close(function(t){let{app:e,...r}=t;return r}(e))),L("install","Install an app binary.",{app:u(i()),appPath:u(i("Path to app binary."))},(t,e)=>t.apps.install(e)),L("reinstall","Reinstall an app binary.",{app:u(i()),appPath:u(i("Path to app binary."))},(t,e)=>t.apps.reinstall(e)),L("install-from-source","Install an app from a structured source.",{source:u(a(B("Install source object."))),retainPaths:b(),retentionMs:f()},(t,e)=>t.apps.installFromSource(e)),L("push","Deliver a push payload.",{app:u(i()),payload:u(a({oneOf:[x(),B()]}))},(t,e)=>t.apps.push(e)),L("trigger-app-event","Trigger an app-defined event.",{event:u(i()),payload:l()},(t,e)=>t.apps.triggerEvent(e)),L("snapshot","Capture an accessibility snapshot.",{interactiveOnly:b(),compact:b(),depth:f(),scope:i(),raw:b(),forceFull:b()},(t,e)=>t.capture.snapshot(e)),L("screenshot","Capture a screenshot.",{path:i("Output path."),overlayRefs:b(),fullscreen:b(),maxSize:f(),stabilize:b(),surface:P(_)},(t,e)=>t.capture.screenshot(e)),L("diff","Diff accessibility snapshots.",{kind:u(a({type:"string",const:"snapshot"})),out:i(),interactiveOnly:b(),compact:b(),depth:f(),scope:i(),raw:b()},(t,e)=>t.capture.diff(e)),L("wait","Wait for duration, text, ref, or selector.",{kind:P($),durationMs:f(),text:i(),ref:i(),selector:i(),timeoutMs:f(),depth:f(),scope:i(),raw:b()},(t,e)=>{var r;let a;return t.command.wait((I(r=e,"kind",$),a={...r},delete a.kind,a))}),L("alert","Inspect or handle platform alerts.",{action:P(["get","accept","dismiss","wait"]),timeoutMs:f()},(t,e)=>t.command.alert(e)),L("appstate","Show foreground app or activity.",{},(t,e)=>t.command.appState(e)),L("back","Navigate back.",{mode:P(["in-app","system"])},(t,e)=>t.command.back(e)),L("home","Go to the home screen.",{},(t,e)=>t.command.home(e)),L("rotate","Rotate device orientation.",{orientation:u(P(["portrait","portrait-upside-down","landscape-left","landscape-right"]))},(t,e)=>t.command.rotate(e)),L("app-switcher","Open the app switcher.",{},(t,e)=>t.command.appSwitcher(e)),L("keyboard","Inspect or dismiss the keyboard.",{action:P(["status","dismiss"])},(t,e)=>t.command.keyboard(e)),L("clipboard","Read or write clipboard text.",{action:u(P(["read","write"])),text:i()},(t,e)=>t.command.clipboard(e)),L("react-native","Run supported React Native app automation helpers.",{action:u(P(["dismiss-overlay"]))},(t,e)=>t.command.reactNative(e)),L("replay","Replay a recorded session.",{path:u(i()),update:b(),backend:i(),maestro:b(),env:M()},(t,e)=>t.replay.run(e)),L("test","Run one or more replay scripts.",{paths:u(M()),update:b(),backend:i(),maestro:b(),env:M(),failFast:b(),timeoutMs:f(),retries:f(),artifactsDir:i(),reportJunit:i()},(t,e)=>t.replay.test(e)),L("perf","Show session performance metrics.",{},(t,e)=>t.observability.perf(e)),L("logs","Manage session app logs.",{action:P(["path","start","stop","doctor","mark","clear"]),message:i(),restart:b()},(t,e)=>t.observability.logs(e)),L("network","Show recent HTTP traffic.",{action:P(["dump","log"]),limit:f(),include:P(["summary","headers","body","all"])},(t,e)=>t.observability.network(e)),L("record","Start or stop screen recording.",{action:u(P(G)),path:i(),fps:f(),quality:a(p()),hideTouches:b()},(t,e)=>t.recording.record(e)),L("trace","Start or stop trace capture.",{action:u(P(G)),path:i()},(t,e)=>t.recording.trace(e)),L("settings","Change OS settings and app permissions.",{setting:u(i()),state:u(i()),latitude:y(),longitude:y(),permission:i(),mode:P(["full","limited"])},(t,e)=>t.settings.update(e)),L("metro","Prepare Metro runtime or reload React Native apps.",{action:u(P(["prepare","reload"])),projectRoot:i(),kind:a(x()),publicBaseUrl:i(),proxyBaseUrl:i(),bearerToken:i(),bridgeScope:a({type:"object",additionalProperties:!0}),launchUrl:i(),port:f(),listenHost:i(),statusHost:i(),startupTimeoutMs:f(),probeTimeoutMs:f(),reuseExisting:b(),installDependenciesIfNeeded:b(),runtimeFilePath:i(),logPath:i(),metroHost:i(),metroPort:f(),bundleUrl:i(),timeoutMs:f()},async(t,e)=>{var r,a,i;return"prepare"===e.action?await t.metro.prepare({projectRoot:(r=e).projectRoot,kind:r.kind,publicBaseUrl:r.publicBaseUrl,proxyBaseUrl:r.proxyBaseUrl,bearerToken:r.bearerToken,bridgeScope:r.bridgeScope??((a=r).tenant&&a.runId&&a.leaseId?{tenantId:a.tenant,runId:a.runId,leaseId:a.leaseId}:void 0),port:r.port,listenHost:r.listenHost,statusHost:r.statusHost,startupTimeoutMs:r.startupTimeoutMs,probeTimeoutMs:r.probeTimeoutMs,reuseExisting:r.reuseExisting,installDependenciesIfNeeded:r.installDependenciesIfNeeded,runtimeFilePath:r.runtimeFilePath}):await t.metro.reload({metroHost:(i=e).metroHost,metroPort:i.metroPort,bundleUrl:i.bundleUrl,timeoutMs:i.timeoutMs})})],K=["pan","fling","pinch","rotate","transform"],z=["up","down","left","right"],J={target:u(T()),button:P(["primary","secondary","middle"],"Pointer button for platforms that support mouse buttons."),...F(),...w()},W={target:u(T()),...F(),...w()},X={target:u(T()),text:u(i("Text to enter into the target.")),delayMs:f("Delay between typed characters.",{min:0}),...F()},Y={target:u(T()),durationMs:f("Long press duration in milliseconds.",{min:0}),...F()},Q={from:u(U("Swipe start point.")),to:u(U("Swipe end point.")),durationMs:f("Swipe duration in milliseconds.",{min:0}),count:f("Number of swipe repetitions.",{min:1}),pauseMs:f("Pause between repeated swipes.",{min:0}),pattern:P(["one-way","ping-pong"])},V={x:u(y("X coordinate.")),y:u(y("Y coordinate."))},Z={text:u(i("Text to type.")),delayMs:f("Delay between typed characters.",{min:0})},tt={direction:u(P(["up","down","left","right","top","bottom"])),amount:y("Platform scroll amount."),pixels:f("Pixel scroll amount.",{min:0})},te={format:u(P(["text","attrs"])),target:u(N()),...F()},tr={predicate:u(P(["visible","hidden","exists","editable","selected","text"])),selector:u(i()),value:i(),...F()},ta={locator:P(["any","text","label","value","role","id"]),query:u(i()),action:P(["click","focus","exists","getText","getAttrs","wait","fill","type"]),value:i(),timeoutMs:f(),first:b(),last:b(),depth:f(),raw:b()},ti={kind:u(P(K,"Gesture variant.")),direction:P(z,"Fling direction."),origin:U("Gesture origin point."),delta:U("Movement delta for pan or transform gestures."),distance:f("Fling distance.",{min:0}),scale:y("Pinch or transform scale."),degrees:y("Rotation in degrees."),velocity:f("Rotate gesture velocity.",{min:0}),durationMs:f("Gesture duration in milliseconds.",{min:0})};function tn(t,e){return void 0===t[e]?void 0:C(t,e)}let to=[D({name:"click",description:"Click or tap a semantic UI target by ref, selector, or point.",inputSchema:j(J),readInput:t=>h(t,J),run:(t,e)=>{var r;return t.interactions.click({...g(r=e),...E(r.target),...o(r),...R(r),button:r.button})}}),D({name:"press",description:"Press a semantic UI target by ref, selector, or point.",inputSchema:j(W),readInput:t=>h(t,W),run:(t,e)=>{var r;return t.interactions.press({...g(r=e),...E(r.target),...o(r),...R(r)})}}),D({name:"fill",description:"Fill text into a semantic UI target by ref, selector, or point.",inputSchema:j(X),readInput:t=>h(t,X),run:(t,e)=>{var r;return t.interactions.fill({...g(r=e),...E(r.target),...o(r),text:r.text,delayMs:r.delayMs})}}),L("longpress","Long press by ref, selector, or point.",Y,(t,e)=>{var r;return t.interactions.longPress({...g(r=e),...E(r.target),...o(r),durationMs:r.durationMs})}),L("swipe","Swipe between two points.",Q,(t,e)=>t.interactions.swipe(e)),L("focus","Focus input at coordinates.",V,(t,e)=>t.interactions.focus(e)),L("type","Type text in the focused field.",Z,(t,e)=>t.interactions.type(e)),L("scroll","Scroll in a direction or to an edge.",tt,(t,e)=>t.interactions.scroll(e)),L("get","Get element text or attributes.",te,(t,e)=>{var r;return t.interactions.get({...g(r=e),...S(r.target),...o(r),format:r.format})}),L("is","Assert UI state.",tr,(t,e)=>t.interactions.is(e)),L("find","Find an element and optionally act on it.",ta,(t,e)=>t.interactions.find(e)),D({name:"gesture",description:"Run a structured gesture.",inputSchema:j(ti),readInput:function(t){let e=v(t),r=O(e),a=d(e,"kind",K);return"pan"===a?{...r,kind:a,origin:C(e,"origin"),delta:C(e,"delta"),durationMs:H(e,"durationMs",{min:0})}:"fling"===a?{...r,kind:a,direction:d(e,"direction",z),origin:C(e,"origin"),distance:H(e,"distance",{min:0}),durationMs:H(e,"durationMs",{min:0})}:"pinch"===a?{...r,kind:a,scale:A(e,"scale"),origin:tn(e,"origin")}:"rotate"===a?{...r,kind:a,degrees:A(e,"degrees"),origin:tn(e,"origin"),velocity:H(e,"velocity",{min:0})}:{...r,kind:a,origin:C(e,"origin"),delta:C(e,"delta"),scale:A(e,"scale"),degrees:A(e,"degrees"),durationMs:H(e,"durationMs",{min:0})}},run:async(t,e)=>{var r,a,i,n,o;switch(e.kind){case"pan":return await t.interactions.pan({...g(r=e),x:r.origin.x,y:r.origin.y,dx:r.delta.x,dy:r.delta.y,durationMs:r.durationMs});case"fling":return await t.interactions.fling({...g(a=e),direction:a.direction,x:a.origin.x,y:a.origin.y,distance:a.distance,durationMs:a.durationMs});case"pinch":return await t.interactions.pinch({...g(i=e),scale:i.scale,x:i.origin?.x,y:i.origin?.y});case"rotate":return await t.interactions.rotateGesture({...g(n=e),degrees:n.degrees,x:n.origin?.x,y:n.origin?.y,velocity:n.velocity});case"transform":return await t.interactions.transformGesture({...g(o=e),x:o.origin.x,y:o.origin.y,dx:o.delta.x,dy:o.delta.y,scale:o.scale,degrees:o.degrees,durationMs:o.durationMs})}}}),...q,D({name:"batch",description:"Run multiple structured command steps in one daemon request.",inputSchema:j(e={steps:u(k({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:t=n,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}},(e,r)=>(function(t,e){if(!Array.isArray(t))throw Error("Expected steps to be an array.");return t.map((t,r)=>{var a,i,n;let o;return a=t,i=r+1,n=e,c(o=function(t,e){if(!t||"object"!=typeof t||Array.isArray(t))throw Error(`Invalid batch step ${e}.`);return t}(a,i),["command","input","runtime"],`Batch step ${i}`),{command:d(o,"command",n),input:function(t,e){let r=t.input;if(!r||"object"!=typeof r||Array.isArray(r))throw Error(`Batch step ${e} input must be an object.`);return r}(o,i),...function(t,e){let r=t.runtime;if(void 0!==r&&(!r||"object"!=typeof r||Array.isArray(r)))throw Error(`Batch step ${e} runtime must be an object.`);return void 0===r?{}:{runtime:r}}(o,i)}})})(e[r],t))),onError:P(["stop"],"Batch failure policy."),maxSteps:f("Maximum number of steps accepted for this batch.",{min:1,max:1e3}),out:i("Optional output path for command artifacts.")}),readInput:t=>(function(t,e){let a=h(t,e),i=a.maxSteps??r;if(!Number.isInteger(i)||i<1||i>1e3)throw Error(`Invalid batch maxSteps: ${String(a.maxSteps)}`);if(a.steps.length>i)throw Error(`batch has ${a.steps.length} steps; max allowed is ${i}.`);return{...a}})(t,e),run:(t,e)=>{var r;return t.batch.run({...g(r=e),steps:r.steps,onError:r.onError,maxSteps:r.maxSteps,out:r.out})}})],ts=new Map(to.map(t=>[t.name,t]));function tp(){return m().map(t=>{var e;if(!tl(t))throw Error(`Missing command for MCP-exposed command: ${t}`);return e=t,ts.get(e)})}function tc(){return to.map(t=>t.name)}function td(){return[...to]}function tl(t){return ts.has(t)}async function tu(t,e,r){var a;return await (a=e,ts.get(a)).invoke(t,r)}export{tl as isCommandName,td as listCommandDefinitions,tc as listCommandNames,tp as listMcpToolDefinitions,tu as runCommand};
|
package/dist/src/9542.js
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import e from"node:net";import t from"node:http";import a from"node:https";import r from"node:fs";import o from"node:os";import n 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{normalizeSession as h,readRequiredString as y,PUBLIC_COMMANDS as w,normalizeMaterializationReleaseResult as g,readVersion as I,readSnapshotNodes as v,findProjectRoot as A,computeDaemonCodeSignature as k,resolveDaemonTransportPreference as b,prepareDaemonCommandRequest as P,normalizeDeployResult as _,normalizeOpenDevice as S,buildMeta as D,resolveSessionName as E,buildFlags as T,readOptionalString as M,resolveDaemonPaths as N,INTERNAL_COMMANDS as C,resolveDaemonServerMode as L,normalizeRuntimeHints as U,normalizeDevice as R,readScreenshotOverlayRefs as O,normalizeStartupSample as x,normalizeInstallFromSourceResult as F}from"./2099.js";import{createRequestId as B,withDiagnosticTimer as q,emitDiagnostic as $}from"./3622.js";import{isAgentDeviceDaemonProcess as j,stopProcessForTakeover as H}from"./8656.js";import{sleep as K}from"./4829.js";import{reloadMetro as z,prepareMetroRuntime as G}from"./1974.js";function V(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 W="sha256";async function J(e){let t=await Y(e.localPath,e.platform),a=e.baseUrl.endsWith("/")?e.baseUrl:`${e.baseUrl}/`;try{let r=await ee({normalizedBase:a,token:e.token,artifact:t});if(r?.kind==="cache-hit")return r.uploadId;if(r?.kind==="direct-upload")try{return await et(t.payloadPath,r),await er({normalizedBase:a,token:e.token,uploadId:r.uploadId})}catch{}return await Z({normalizedBase:a,token:e.token,artifact:t})}finally{t.cleanup()}}async function Y(e,t){var a,o,i;let s,l=r.statSync(e),c=n.basename(e),d=l.isDirectory(),u=("ios"===(a=t)||"android"===a?a:void 0)??(o=e,i=l,s=o.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 Q(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 eo(t),sizeBytes:a.size,cleanup:()=>X(p)}}catch(e){throw X(p),e}}async function Q(e,t){let a=r.mkdtempSync(n.join(o.tmpdir(),`agent-device-upload-${l()}-`));t.push(a);let i=n.join(a,`${n.basename(e)}.tar.gz`);return await m("tar",["czf",i,"-C",n.dirname(e),n.basename(e)],{env:{...process.env,COPYFILE_DISABLE:"1"}}),i}function X(e){for(let t of e)r.rmSync(t,{recursive:!0,force:!0})}async function Z(e){let{normalizedBase:t,token:a,artifact:r}=e,o=new URL("upload",t),n={"content-type":r.contentType,"x-artifact-type":r.artifactType,"x-artifact-filename":r.fileName,"x-artifact-hash":r.sha256,"x-artifact-hash-algorithm":W,"transfer-encoding":"chunked"};a&&(n.authorization=`Bearer ${a}`,n["x-agent-device-token"]=a);let i=await ea({url:o,method:"POST",headers:n,payloadPath:r.payloadPath,timeoutMessage:"Artifact upload timed out",timeoutHint:"The upload to the remote daemon exceeded the 5-minute timeout.",errorMessage:"Failed to upload artifact to remote daemon",errorHint:"Verify the remote daemon is reachable and supports artifact uploads."});try{let e=JSON.parse(i.body);if(!e.ok||!e.uploadId)throw new u("COMMAND_FAILED",`Upload failed: ${i.body}`);return e.uploadId}catch(e){if(e instanceof u)throw e;throw new u("COMMAND_FAILED",`Invalid upload response: ${i.body}`)}}async function ee(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 et(e,t){let a=await ea({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 ea(e){let o="https:"===e.url.protocol?a:t;return await new Promise((t,a)=>{let n=o.request({protocol:e.url.protocol,host:e.url.hostname,port:e.url.port,method:e.method,path:e.url.pathname+e.url.search,headers:e.headers},e=>{V(e).then(a=>{clearTimeout(s),t({statusCode:e.statusCode??500,statusMessage:e.statusMessage,body:a})}).catch(a)}),s=setTimeout(()=>{n.destroy(),a(new u("COMMAND_FAILED",e.timeoutMessage,{timeoutMs:3e5,...e.timeoutHint?{hint:e.timeoutHint}:{}}))},3e5);n.on("error",t=>{clearTimeout(s),a(new u("COMMAND_FAILED",e.errorMessage,e.errorHint?{hint:e.errorHint}:{},t))}),n.on("close",()=>clearTimeout(s)),i(r.createReadStream(e.payloadPath),n).catch(e=>{n.destroy(),a(new u("COMMAND_FAILED","Failed to read local artifact",{},e instanceof Error?e:Error(String(e))))})})}async function er(e){let t=new URL("upload/finalize",e.normalizedBase),a={"content-type":"application/json"};e.token&&(a.authorization=`Bearer ${e.token}`,a["x-agent-device-token"]=e.token);let r=await fetch(t,{method:"POST",headers:a,signal:AbortSignal.timeout(3e4),body:JSON.stringify({uploadId:e.uploadId})}).catch(e=>{throw new u("COMMAND_FAILED","Failed to finalize direct artifact upload",{},e)});if(!r.ok)throw new u("COMMAND_FAILED","Direct artifact upload finalize failed",{status:r.status,statusText:r.statusText});let o=await r.json().catch(()=>void 0);if(!o?.ok||!o.uploadId)throw new u("COMMAND_FAILED","Invalid upload finalize response");return o.uploadId}async function eo(e){let t=s(W),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")}let en=["xcodebuild .*AgentDeviceRunnerUITests/RunnerTests/testCommand","xcodebuild .*AgentDeviceRunner\\.env\\.session-","xcodebuild build-for-testing .*ios-runner/AgentDeviceRunner/AgentDeviceRunner\\.xcodeproj"],ei=new e.BlockList;async function es(t){let a=t.meta?.requestId??B(),i=!!(t.meta?.debug||t.flags?.verbose),s=function(t){let a,i=t.flags?.stateDir??process.env.AGENT_DEVICE_STATE_DIR,s=t.flags?.daemonBaseUrl??process.env.AGENT_DEVICE_DAEMON_BASE_URL,l=eg(t.command)&&!i&&!s,c=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(/\/+$/,"")}}(s),d=t.flags?.daemonAuthToken??process.env.AGENT_DEVICE_DAEMON_AUTH_TOKEN;var p=c,m=d;if(!(!p||"localhost"===(a=new URL(p).hostname.trim().toLowerCase().replace(/^\[(.*)\]$/,"$1"))||(e.isIPv4(a)?ei.check(a,"ipv4"):!!e.isIPv6(a)&&ei.check(a,"ipv6")))&&("string"!=typeof m||!(m.trim().length>0)))throw new u("INVALID_ARGS","Remote daemon base URL for non-loopback hosts requires daemon authentication",{daemonBaseUrl:p,hint:"Provide --daemon-auth-token or AGENT_DEVICE_DAEMON_AUTH_TOKEN when using a non-loopback remote daemon URL."});let f=t.flags?.daemonTransport??process.env.AGENT_DEVICE_DAEMON_TRANSPORT,h=b(f);if(c&&"socket"===h)throw new u("INVALID_ARGS","Remote daemon base URL only supports HTTP transport. Remove --daemon-transport socket.",{daemonBaseUrl:c});let y=L(t.flags?.daemonServerMode??process.env.AGENT_DEVICE_DAEMON_SERVER_MODE??("dual"===f?"dual":void 0));return{paths:N(l?r.mkdtempSync(n.join(o.tmpdir(),"agent-device-replay-daemon-")):i),transportPreference:h,serverMode:y,ownedStateDir:l,remoteBaseUrl:c,remoteAuthToken:d}}(t),l=function(e){if(e.command!==w.test)return e.command===w.replay&&"number"==typeof e.flags?.timeoutMs?e.flags.timeoutMs:9e4}(t),c=await q("daemon_startup",async()=>await em(s),{requestId:a,session:t.session}),d=c.info,p=await el(t,d),m={...t,positionals:p.positionals,flags:p.flags,token:d.token,meta:{...t.meta??{},requestId:a,debug:i,cwd:t.meta?.cwd,tenantId:t.meta?.tenantId??t.flags?.tenant,runId:t.meta?.runId??t.flags?.runId,leaseId:t.meta?.leaseId??t.flags?.leaseId,sessionIsolation:t.meta?.sessionIsolation??t.flags?.sessionIsolation,lockPolicy:t.meta?.lockPolicy,lockPlatform:t.meta?.lockPlatform,...p.uploadedArtifactId?{uploadedArtifactId:p.uploadedArtifactId}:{},...p.clientArtifactPaths?{clientArtifactPaths:p.clientArtifactPaths}:{},...p.installSource?{installSource:p.installSource}:{}}};$({level:"info",phase:"daemon_request_prepare",data:{requestId:a,command:t.command,session:t.session}});try{return await q("daemon_request",async()=>await eL(d,m,s.transportPreference,l),{requestId:a,command:t.command})}finally{await ew(t,c,s)}}async function el(e,t){var a,o;let i,s,l=[...e.positionals??[]],c=e.flags?{...e.flags}:void 0,d=e.meta?.installSource,u={};if(e$(t)){c=function(e,t,a,r){var o,i;let s=function(e,t){if("screenshot"===e.command){let a=eu(e,"path",".png");return t[0]?{field:"path",localPath:a,positionalIndex:0,positionalPath:ep("screenshot",".png")}:{field:"path",localPath:a,positionalIndex:0,flagPath:ep("screenshot",".png")}}if("record"===e.command&&"start"===(t[0]??"").toLowerCase()){let t=eu(e,"outPath",".mp4",1);return{field:"outPath",localPath:t,positionalIndex:1,positionalPath:ep("recording",n.extname(t)||".mp4")}}return null}(e,t);if(!s)return a;void 0!==s.positionalPath&&(t[s.positionalIndex]=s.positionalPath);let l=(o=a,void 0===(i=s.flagPath)?o:{...o??{},out:i});return r[s.field]=s.localPath,l}(e,l,c,u);let a=await ed(e,t);a&&(d=a.installSource,s=a.uploadedArtifactId??s)}let p=()=>ec({positionals:l,flags:c,installSource:d,uploadedArtifactId:s,clientArtifactPaths:u});if(!e$(t)||"install"!==e.command&&"reinstall"!==e.command)return p();let m=l[1];if(void 0===m)return p();if(m.startsWith("remote:"))return l[1]=m.slice(7),ec({positionals:l,flags:c,clientArtifactPaths:u});let f=(a=m,o=e.meta?.cwd,i=n.isAbsolute(a)?a:n.resolve(o??process.cwd(),a),r.existsSync(i)?i:void 0);return f?(s=await J({localPath:f,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform}),p()):ec({positionals:l,flags:c,clientArtifactPaths:u})}function ec(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 ed(e,t){let a=e.meta?.installSource;if("install_source"!==e.command||!a||"path"!==a.kind)return null;let o=a.path.trim();if(!o)return{installSource:a};if(o.startsWith("remote:"))return{installSource:{...a,path:o.slice(7)}};let i=n.isAbsolute(o)?o:n.resolve(e.meta?.cwd??process.cwd(),o);if(!r.existsSync(i))return{installSource:{...a,path:i}};let s=await J({localPath:i,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform});return{installSource:{...a,path:i},uploadedArtifactId:s}}function eu(e,t,a,r=0){let o=e.positionals?.[r]??e.flags?.out,i=`${"path"===t?"screenshot":"recording"}-${Date.now()}${a}`,s=o&&o.trim().length>0?o:i;return n.isAbsolute(s)?s:n.resolve(e.meta?.cwd??process.cwd(),s)}function ep(e,t){let a=t.startsWith(".")?t:`.${t}`;return n.posix.join("/tmp",`agent-device-${e}-${Date.now()}-${Math.random().toString(36).slice(2,8)}${a}`)}async function em(e){if(e.remoteBaseUrl)return await ef(e);let t=await eh(e);return t?{info:t,startedByClient:!1}:(function(e){let t=eD(e);if(!t.hasLock||t.hasInfo)return;let a=e_(e.lockPath);if(!a)return eT(e.lockPath);j(a.pid,a.processStartTime)||eT(e.lockPath)}(e.paths),await ey(e))}async function ef(e){let t={transport:"http",token:e.remoteAuthToken??"",pid:0,baseUrl:e.remoteBaseUrl};if(await eM(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 eh(e){var t,a;let r,o=ek(e.paths.infoPath);if(!o)return null;let n=await eM(o,e.transportPreference);return(t=o,a=n,t.version===I()&&t.codeSignature===k((r=eC()).useSrc?r.srcPath:r.distPath,r.root)&&a)?o:(await eA(o),eT(e.paths.infoPath),null)}async function ey(e){let t,a=0,r=[];for(let o=1;o<=2;o+=1){try{await eN(e)}catch(a){if(t=a instanceof Error?a.message:String(a),r.push(await eS(e.paths,"start_error")),o<2){await K(150);continue}break}let n=await eI(15e3,e);if(n)return{info:n,startedByClient:!0};if(await ev(e.paths)){a+=1;continue}let i=eD(e.paths),s=o<2,l=await eS(e.paths,"startup_timeout",{stopLiveProcesses:!1});if(r.push(l),l.retainedInfoProcess||l.retainedLockProcess){let t=await eI(15e3,e);if(t)return{info:t,startedByClient:!0};break}if(!s)break;i.hasInfo||i.hasLock||await K(150)}let o=eD(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:o,hint:function(e,t=N(process.env.AGENT_DEVICE_STATE_DIR)){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, remove ${t.lockPath} after confirming no agent-device daemon process is running.`: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, remove both files after confirming no agent-device daemon process is running.`:"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."}(o,e.paths)})}async function ew(e,t,a){if(!eg(e.command)||!t.startedByClient&&!a.ownedStateDir||e$(t.info))return;let o={pid:t.info.pid,removedInfo:!1,removedLock:!1,removedStateDir:!1,error:void 0};try{await eA(t.info)}catch(e){o.error=e instanceof Error?e.message:String(e)}finally{let e=r.existsSync(a.paths.infoPath);eT(a.paths.infoPath),o.removedInfo=e&&!r.existsSync(a.paths.infoPath);let t=r.existsSync(a.paths.lockPath);eT(a.paths.lockPath),o.removedLock=t&&!r.existsSync(a.paths.lockPath),a.ownedStateDir&&(r.rmSync(a.paths.baseDir,{recursive:!0,force:!0}),o.removedStateDir=!r.existsSync(a.paths.baseDir))}$({level:o.error?"warn":"info",phase:"daemon_replay_cleanup",data:o})}function eg(e){return e===w.replay||e===w.test}async function eI(e,t){let a=Date.now();for(;Date.now()-a<e;){let e=ek(t.paths.infoPath);if(e&&await eM(e,t.transportPreference))return e;await K(100)}return null}async function ev(e){let t=eD(e);if(!t.hasLock||t.hasInfo)return!1;let a=e_(e.lockPath);return!(a&&j(a.pid,a.processStartTime))&&(eT(e.lockPath),!0)}async function eA(e){await H(e.pid,{termTimeoutMs:3e3,killTimeoutMs:1e3,expectedStartTime:e.processStartTime})}function ek(e){var t,a,r;let o,n,i=eE(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=(o=eP((a=i).port),n=eP(a.httpPort),void 0===o&&void 0===n?null:{port:o,httpPort:n});return l?{token:s,...l,transport:"socket"===(r=i.transport)||"http"===r||"dual"===r?r:void 0,pid:eP(i.pid)??0,version:eb(i.version),codeSignature:eb(i.codeSignature),processStartTime:eb(i.processStartTime)}:null}function eb(e){return"string"==typeof e?e:void 0}function eP(e){return Number.isInteger(e)&&Number(e)>0?Number(e):void 0}function e_(e){let t=eE(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}ei.addSubnet("127.0.0.0",8,"ipv4"),ei.addAddress("::1","ipv6"),ei.addSubnet("::ffff:127.0.0.0",104,"ipv6");async function eS(e,t,a={}){let o=a.stopLiveProcesses??!0,n={reason:t,removedInfo:!1,removedLock:!1,stoppedInfoProcess:!1,stoppedLockProcess:!1};try{var i,s,l,c;let t=r.existsSync(e.infoPath),a=ek(e.infoPath);if(a){let t=j(a.pid,a.processStartTime);t&&!o?n.retainedInfoProcess=!0:(t&&(await eA(a),n.stoppedInfoProcess=!0),i=e.infoPath,eT(i),n.removedInfo=!0)}else t&&(s=e.infoPath,eT(s),n.removedInfo=!0);let d=r.existsSync(e.lockPath),u=e_(e.lockPath);if(u){let t=j(u.pid,u.processStartTime);t&&!o?n.retainedLockProcess=!0:(t&&(await H(u.pid,{termTimeoutMs:3e3,killTimeoutMs:1e3,expectedStartTime:u.processStartTime}),n.stoppedLockProcess=!0),l=e.lockPath,eT(l),n.removedLock=!0)}else d&&(c=e.lockPath,eT(c),n.removedLock=!0)}catch(e){n.error=e instanceof Error?e.message:String(e)}return $({level:n.error?"warn":"info",phase:"daemon_startup_metadata_cleanup",data:n}),n}function eD(e){return{hasInfo:r.existsSync(e.infoPath),hasLock:r.existsSync(e.lockPath)}}function eE(e){if(!r.existsSync(e))return null;try{return JSON.parse(r.readFileSync(e,"utf8"))}catch{return null}}function eT(e){try{r.existsSync(e)&&r.unlinkSync(e)}catch{}}async function eM(r,o){var n;return"http"===eU(r,o)?await function(e){let r=e.baseUrl?ej(e.baseUrl,"health"):e.httpPort?`http://127.0.0.1:${e.httpPort}/health`:null;if(!r)return Promise.resolve(!1);let o=new URL(r),n="https:"===o.protocol?a:t,i=e.baseUrl?3e3:500;return new Promise(e=>{let t=n.request({protocol:o.protocol,host:o.hostname,port:o.port,path:o.pathname+o.search,method:"GET",timeout:i},t=>{t.resume(),e((t.statusCode??500)<500)});t.on("timeout",()=>{t.destroy(),e(!1)}),t.on("error",()=>{e(!1)}),t.end()})}(r):await ((n=r.port)?new Promise(t=>{let a=!1,r=e.createConnection({host:"127.0.0.1",port:n},()=>{o(!0)}),o=e=>{a||(a=!0,r.destroy(),t(e))};r.setTimeout(500),r.on("timeout",()=>{o(!1)}),r.on("error",()=>{o(!1)})}):Promise.resolve(!1))}async function eN(e){let t=eC(),a=t.useSrc?["--experimental-strip-types",t.srcPath]:[t.distPath],r={...process.env,AGENT_DEVICE_STATE_DIR:e.paths.baseDir,AGENT_DEVICE_DAEMON_SERVER_MODE:e.serverMode};f(process.execPath,a,{env:r})}function eC(){let e=A(),t=[n.join(e,"dist","src","internal","daemon.js"),n.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 o=t.find(e=>r.existsSync(e))??a,i=n.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:o,distPaths:t,srcPath:i,useSrc:process.execArgv.includes("--experimental-strip-types")?l:!s&&l}}async function eL(e,t,a,r){return"http"===eU(e,a)?await eB(e,t,r):await eF(e,t,r)}function eU(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(eR(a,r))return r;throw new u("COMMAND_FAILED","http"===r?"Daemon HTTP endpoint is unavailable":"Daemon socket endpoint is unavailable")}let o=("socket"===e.transport||"dual"===e.transport?["socket","http"]:["http","socket"]).find(t=>eR(e,t));if(o)return o;throw new u("COMMAND_FAILED","Daemon metadata has no reachable transport")}function eR(e,t){return"http"===t?!!e.httpPort:!!e.port}function eO(e,t,a,r,o,n){let i=o?{terminated:0}:function(){let e=0;try{for(let t of en){let a=p("pkill",["-f",t],{allowFailure:!0});0===a.exitCode&&(e+=1)}return{terminated:e}}catch(t){return{terminated:e,error:t instanceof Error?t.message:String(t)}}}(),s=!o&&"snapshot"!==r,l=s?function(e,t){let a=!1;try{j(e.pid,e.processStartTime)&&(process.kill(e.pid,"SIGKILL"),a=!0)}catch{H(e.pid,{termTimeoutMs:3e3,killTimeoutMs:1e3,expectedStartTime:e.processStartTime})}finally{eT(t.infoPath),eT(t.lockPath)}return{forcedKill:a}}(e,t):{forcedKill:!1};return $({level:"error",phase:"daemon_request_timeout",data:{timeoutMs:n,requestId:a,command:r,timedOutRunnerPidsTerminated:i.terminated,timedOutRunnerCleanupError:i.error,daemonPidReset:s?e.pid:void 0,daemonPidForceKilled:s?l.forcedKill:void 0,daemonPreservedAfterTimeout:!o&&!s,daemonBaseUrl:e.baseUrl}}),new u("COMMAND_FAILED","Daemon request timed out",{timeoutMs:n,requestId:a,hint:function(e){let{remote:t,resetDaemon:a,command:r}=e;return t?"Retry with --debug and verify the remote daemon URL, auth token, and remote host logs.":a?"Retry with --debug and check daemon diagnostics logs. Timed-out iOS runner xcodebuild processes were terminated when detected.":`Retry with --debug and check daemon diagnostics logs. The timed-out ${r??"request"} request was canceled and iOS runner work was aborted when detected; the daemon was kept alive so the session can still be closed or inspected.`}({remote:o,resetDaemon:s,command:r})})}function ex(e,t,a){return $({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 eF(t,a,r){let o=t.port;if(!o)throw new u("COMMAND_FAILED","Daemon socket endpoint is unavailable");return new Promise((n,i)=>{let s=e.createConnection({host:"127.0.0.1",port:o},()=>{s.write(`${JSON.stringify(a)}
|
|
2
|
-
`)}),l=N(a.flags?.stateDir??process.env.AGENT_DEVICE_STATE_DIR),c="number"==typeof r?setTimeout(()=>{s.destroy(),i(eO(t,l,a.meta?.requestId,a.command,!1,r))},r):void 0,d="";s.setEncoding("utf8"),s.on("data",e=>{let t=(d+=e).indexOf("\n");if(-1===t)return;let r=d.slice(0,t).trim();if(r)try{let e=JSON.parse(r);s.end(),c&&clearTimeout(c),n(e)}catch(e){c&&clearTimeout(c),i(new u("COMMAND_FAILED","Invalid daemon response",{requestId:a.meta?.requestId,line:r},e instanceof Error?e:void 0))}}),s.on("error",e=>{c&&clearTimeout(c),i(ex(e,a.meta?.requestId,!1))})})}async function eB(e,r,o){var n,i,s;let l,c=e.baseUrl?new URL(ej(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 p=JSON.stringify((n=r,i={includeTokenParam:!e.baseUrl},l=n.meta?.requestId??B(),"lease_allocate"!==(s=n.command)&&"lease_heartbeat"!==s&&"lease_release"!==s?{jsonrpc:"2.0",id:l,method:"agent_device.command",params:n}:{jsonrpc:"2.0",id:l,method:function(e){switch(e){case"lease_allocate":return"agent_device.lease.allocate";case"lease_heartbeat":return"agent_device.lease.heartbeat";case"lease_release":return"agent_device.lease.release"}}(n.command),params:function(e,t,a){let r={...a.includeTokenParam?{token:e.token}:{},session:e.session,tenantId:e.meta?.tenantId,runId:e.meta?.runId};switch(t){case"lease_allocate":return{...r,ttlMs:e.meta?.leaseTtlMs,backend:e.meta?.leaseBackend};case"lease_heartbeat":return{...r,leaseId:e.meta?.leaseId,ttlMs:e.meta?.leaseTtlMs};case"lease_release":return{...r,leaseId:e.meta?.leaseId}}}(n,n.command,i)})),m={"content-type":"application/json","content-length":Buffer.byteLength(p)};return e.baseUrl&&e.token&&(m.authorization=`Bearer ${e.token}`,m["x-agent-device-token"]=e.token),await new Promise((n,i)=>{let s=N(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:m},t=>{V(t).then(t=>{h&&clearTimeout(h),function(e,t){let{info:a,req:r,resolve:o,reject:n}=t;try{var i,s,l;let t=(i=e,JSON.parse(i));if(t.error){let e;return void n((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 n(new u("COMMAND_FAILED","Invalid daemon RPC response",{requestId:r.meta?.requestId}));eq(a,r,t.result,o,n)}catch(t){n(new u("COMMAND_FAILED","Invalid daemon response",{requestId:r.meta?.requestId,line:e},t instanceof Error?t:void 0))}}(t,{info:e,req:r,resolve:n,reject:i})}).catch(e=>{h&&clearTimeout(h),i(new u("COMMAND_FAILED","Failed to read daemon response",{requestId:r.meta?.requestId},e instanceof Error?e:void 0))})}),f=e$(e),h="number"==typeof o?setTimeout(()=>{l.destroy(),i(eO(e,s,r.meta?.requestId,r.command,f,o))},o):void 0;l.on("error",e=>{h&&clearTimeout(h),i(ex(e,r.meta?.requestId,f))}),l.write(p),l.end()})}async function eq(e,t,a,r,o){try{r(e.baseUrl&&a.ok?await eH(e,t,a):a)}catch(e){o(e)}}function e$(e){return"string"==typeof e.baseUrl&&e.baseUrl.length>0}function ej(e,t){return new URL(t,e.endsWith("/")?e:`${e}/`).toString()}async function eH(e,t,a){let r=Array.isArray(a.data?.artifacts)?a.data.artifacts:[];if(0===r.length||!e.baseUrl)return a;let o=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 n.resolve(t.meta?.cwd??process.cwd(),r)}(a,t);await eK({baseUrl:e.baseUrl,token:e.token,artifactId:a.artifactId,destinationPath:r,requestId:t.meta?.requestId}),o[a.field]=r,i.push({...a,localPath:r})}return o.artifacts=i,{ok:!0,data:o}}async function eK(e){var o,s;let l,c=new URL((o=e.baseUrl,s=e.artifactId,l=o.endsWith("/")?o:`${o}/`,new URL(`artifacts/${encodeURIComponent(s)}`,l).toString())),d="https:"===c.protocol?a:t;await r.promises.mkdir(n.dirname(e.destinationPath),{recursive:!0}),await new Promise((t,a)=>{let o=!1,n=e.timeoutMs??9e4,s=n=>{if(!o){if(o=!0,clearTimeout(p),n)return void r.promises.rm(e.destinationPath,{force:!0}).finally(()=>a(n));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:n});s(t),l.destroy(t)},n);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:n},t instanceof Error?t:void 0))}),l.end()})}function ez(e={},t={}){let a=t.transport??es,r=async(t,r=[],o={})=>{var n,i;let s=(n=e,i=o,{...n,...i}),l=await a({session:E(s.session),command:t,positionals:r,flags:T(s),runtime:s.runtime,meta:D(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??{}},o=async(e={})=>{let t=await r(C.sessionList,[],e);return(Array.isArray(t.sessions)?t.sessions:[]).map(h)},n=async(e,t={})=>{let a=P(e,t);return await r(a.command,a.positionals,a.options)},i=(t={})=>{var a,r;return E((a=e,r=t,{...a,...r}).session)};return{command:{wait:async e=>await n("wait",e),alert:async(e={})=>await n("alert",e),appState:async(e={})=>await n("appstate",e),back:async(e={})=>await n("back",e),home:async(e={})=>await n("home",e),rotate:async e=>await n("rotate",e),appSwitcher:async(e={})=>await n("app-switcher",e),keyboard:async(e={})=>await n("keyboard",e),clipboard:async e=>await n("clipboard",e),reactNative:async e=>await n("react-native",e)},devices:{list:async(e={})=>{let t=await n("devices",e);return(Array.isArray(t.devices)?t.devices:[]).map(R)},boot:async(e={})=>await n("boot",e)},sessions:{list:async(e={})=>await o(e),close:async(e={})=>{let t=i(e),a=(await n("close",e)).shutdown;return{session:t,shutdown:"object"==typeof a&&null!==a?a:void 0,identifiers:{session:t}}}},apps:{install:async e=>_(await n("install",e),i(e)),reinstall:async e=>_(await n("reinstall",e),i(e)),installFromSource:async e=>F(await n("install-from-source",e),i(e)),list:async(e={})=>{let t=await n("apps",e);return Array.isArray(t.apps)?t.apps.filter(e=>"string"==typeof e):[]},open:async e=>{let t=i(e),a=await n("open",e),r=S(a),o=M(a,"appBundleId");return{session:t,appName:M(a,"appName"),appBundleId:o,appId:o,startup:x(a.startup),runtime:U(a.runtime),device:r,identifiers:{session:t,deviceId:r?.id,deviceName:r?.name,udid:r?.ios?.udid,serial:r?.android?.serial,appId:o,appBundleId:o}}},close:async(e={})=>{let t=i(e),a=(await n("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 n("push",e),triggerEvent:async e=>await n("trigger-app-event",e)},materializations:{release:async e=>g(await r(C.releaseMaterializedPaths,[],{...e,materializationId:e.materializationId}))},leases:{allocate:async e=>eV(await r(C.leaseAllocate,[],{...e,leaseId:void 0,leaseTtlMs:e.ttlMs})),heartbeat:async e=>eV(await r(C.leaseHeartbeat,[],{...e,leaseTtlMs:e.ttlMs})),release:async e=>({released:!0===(await r(C.leaseRelease,[],e)).released})},metro:{prepare:async t=>await G({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 z({metroHost:t.metroHost,metroPort:t.metroPort,bundleUrl:t.bundleUrl,runtime:e.runtime,timeoutMs:t.timeoutMs})},capture:{snapshot:async(e={})=>{var t,a,r;let o,s,l,c,d,u=i(e);return t=await n("snapshot",e),a=u,o=M(t,"appBundleId"),{nodes:v(t.nodes),truncated:!0===t.truncated,appName:M(t,"appName"),appBundleId:o,...(s=eG((r=t).visibility),l=eG(r.androidSnapshot),c=eG(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:o,appBundleId:o}}},screenshot:async(e={})=>{let t=i(e),a=await n("screenshot",e);return{path:y(a,"path"),overlayRefs:O(a),identifiers:{session:t}}},diff:async e=>await n("diff",e)},interactions:{click:async e=>await n("click",e),press:async e=>await n("press",e),longPress:async e=>await n("longpress",e),swipe:async e=>await n("swipe",e),pan:async e=>await n("gesture-pan",e),fling:async e=>await n("gesture-fling",e),focus:async e=>await n("focus",e),type:async e=>await n("type",e),fill:async e=>await n("fill",e),scroll:async e=>await n("scroll",e),pinch:async e=>await n("gesture-pinch",e),rotateGesture:async e=>await n("gesture-rotate",e),transformGesture:async e=>await n("gesture-transform",e),get:async e=>await n("get",e),is:async e=>await n("is",e),find:async e=>await n("find",e)},replay:{run:async e=>await n("replay",e),test:async e=>await n("test",e)},batch:{run:async e=>await n("batch",e)},observability:{perf:async(e={})=>await n("perf",e),logs:async(e={})=>await n("logs",e),network:async(e={})=>await n("network",e)},recording:{record:async e=>await n("record",e),trace:async e=>await n("trace",e)},settings:{update:async e=>await n("settings",e)}}}function eG(e){return"object"==typeof e&&null!==e?e:void 0}function eV(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{ez as createAgentDeviceClient,es as sendToDaemon};
|
|
1
|
+
import e from"node:net";import t from"node:http";import a from"node:https";import r from"node:fs";import o from"node:os";import n 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{normalizeSession as h,consumeTextLines as y,PUBLIC_COMMANDS as w,isDaemonResponseEnvelope as I,isDaemonProgressEnvelope as g,prepareDaemonCommandRequest as v,readSnapshotNodes as A,normalizeMaterializationReleaseResult as k,computeDaemonCodeSignature as b,resolveDaemonTransportPreference as P,normalizeDeployResult as _,buildMeta as S,buildFlags as D,readOptionalString as E,resolveSessionName as M,formatRequestProgressEvent as T,shouldStreamRequestProgress as N,INTERNAL_COMMANDS as C,normalizeDevice as L,readRequiredString as U,readVersion as R,findProjectRoot as O,normalizeOpenDevice as x,resolveDaemonPaths as F,resolveDaemonServerMode as q,normalizeRuntimeHints as B,normalizeStartupSample as $,readScreenshotOverlayRefs as j,normalizeInstallFromSourceResult as H}from"./6277.js";import{createRequestId as K,withDiagnosticTimer as z,emitDiagnostic as G}from"./3622.js";import{isAgentDeviceDaemonProcess as V,stopProcessForTakeover as W}from"./8656.js";import{sleep as J}from"./4829.js";import{reloadMetro as Y,prepareMetroRuntime as Q}from"./1974.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 en({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 eo({normalizedBase:a,token:e.token,artifact:t})}finally{t.cleanup()}}async function et(e,t){var a,o,i;let s,l=r.statSync(e),c=n.basename(e),d=l.isDirectory(),u=("ios"===(a=t)||"android"===a?a:void 0)??(o=e,i=l,s=o.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(n.join(o.tmpdir(),`agent-device-upload-${l()}-`));t.push(a);let i=n.join(a,`${n.basename(e)}.tar.gz`);return await m("tar",["czf",i,"-C",n.dirname(e),n.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 eo(e){let{normalizedBase:t,token:a,artifact:r}=e,o=new URL("upload",t),n={"content-type":r.contentType,"x-artifact-type":r.artifactType,"x-artifact-filename":r.fileName,"x-artifact-hash":r.sha256,"x-artifact-hash-algorithm":Z,"transfer-encoding":"chunked"};a&&(n.authorization=`Bearer ${a}`,n["x-agent-device-token"]=a);let i=await es({url:o,method:"POST",headers:n,payloadPath:r.payloadPath,timeoutMessage:"Artifact upload timed out",timeoutHint:"The upload to the remote daemon exceeded the 5-minute timeout.",errorMessage:"Failed to upload artifact to remote daemon",errorHint:"Verify the remote daemon is reachable and supports artifact uploads."});try{let e=JSON.parse(i.body);if(!e.ok||!e.uploadId)throw new u("COMMAND_FAILED",`Upload failed: ${i.body}`);return e.uploadId}catch(e){if(e instanceof u)throw e;throw new u("COMMAND_FAILED",`Invalid upload response: ${i.body}`)}}async function en(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 o="https:"===e.url.protocol?a:t;return await new Promise((t,a)=>{let n=o.request({protocol:e.url.protocol,host:e.url.hostname,port:e.url.port,method:e.method,path:e.url.pathname+e.url.search,headers:e.headers},e=>{X(e).then(a=>{clearTimeout(s),t({statusCode:e.statusCode??500,statusMessage:e.statusMessage,body:a})}).catch(a)}),s=setTimeout(()=>{n.destroy(),a(new u("COMMAND_FAILED",e.timeoutMessage,{timeoutMs:3e5,...e.timeoutHint?{hint:e.timeoutHint}:{}}))},3e5);n.on("error",t=>{clearTimeout(s),a(new u("COMMAND_FAILED",e.errorMessage,e.errorHint?{hint:e.errorHint}:{},t))}),n.on("close",()=>clearTimeout(s)),i(r.createReadStream(e.payloadPath),n).catch(e=>{n.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 o=await r.json().catch(()=>void 0);if(!o?.ok||!o.uploadId)throw new u("COMMAND_FAILED","Invalid upload finalize response");return o.uploadId}async function 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=T(e);t&&process.stderr.write(`${t}
|
|
2
|
+
`)}let eu=["xcodebuild .*AgentDeviceRunnerUITests/RunnerTests/testCommand","xcodebuild .*AgentDeviceRunner\\.env\\.session-","xcodebuild build-for-testing .*ios-runner/AgentDeviceRunner/AgentDeviceRunner\\.xcodeproj"],ep=new e.BlockList;async function em(t){var a,i,s,l,c,d;let p,m,f,h,y,I,g,v=t.meta?.requestId??K(),A=!!(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)?ep.check(r,"ipv4"):!!e.isIPv6(r)&&ep.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}),I=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:q(e.flags?.daemonServerMode??process.env.AGENT_DEVICE_DAEMON_SERVER_MODE??("dual"===a?"dual":void 0))}}(a,y.remoteBaseUrl),{paths:F((g=(l=a,c=h,d=y.rawBaseUrl,e_(l.command)&&!c&&!d))?r.mkdtempSync(n.join(o.tmpdir(),"agent-device-replay-daemon-")):h),transportPreference:I.preference,serverMode:I.serverMode,ownedStateDir:g,remoteBaseUrl:y.remoteBaseUrl,remoteAuthToken:y.authToken}),b=function(e){if(e.command!==w.test)return e.command===w.replay&&"number"==typeof e.flags?.timeoutMs?e.flags.timeoutMs:9e4}(t),_=await z("daemon_startup",async()=>await ev(k),{requestId:v,session:t.session}),S=_.info,D=await ef(t,S),E={...t,positionals:D.positionals,flags:D.flags,token:S.token,meta:{...t.meta??{},requestId:v,debug:A,cwd:t.meta?.cwd,tenantId:t.meta?.tenantId??t.flags?.tenant,runId:t.meta?.runId??t.flags?.runId,leaseId:t.meta?.leaseId??t.flags?.leaseId,sessionIsolation:t.meta?.sessionIsolation??t.flags?.sessionIsolation,lockPolicy:t.meta?.lockPolicy,lockPlatform:t.meta?.lockPlatform,...D.uploadedArtifactId?{uploadedArtifactId:D.uploadedArtifactId}:{},...D.clientArtifactPaths?{clientArtifactPaths:D.clientArtifactPaths}:{},...D.installSource?{installSource:D.installSource}:{}}};G({level:"info",phase:"daemon_request_prepare",data:{requestId:v,command:t.command,session:t.session}});try{return await z("daemon_request",async()=>await eB(S,E,k.transportPreference,b),{requestId:v,command:t.command})}finally{await eP(t,_,k)}}async function ef(e,t){let a,r=[...e.positionals??[]],o=e.flags?{...e.flags}:void 0,i=e.meta?.installSource,s={};if(!eJ(t))return ey({positionals:r,flags:o,installSource:i,uploadedArtifactId:a,clientArtifactPaths:s});o=function(e,t,a,r){var o,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:eg("screenshot",".png")}:{field:"path",localPath:a,positionalIndex:0,flagPath:eg("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:eg("recording",n.extname(t)||".mp4")}}return null}(e,t);if(!s)return a;void 0!==s.positionalPath&&(t[s.positionalIndex]=s.positionalPath);let l=(o=a,void 0===(i=s.flagPath)?o:{...o??{},out:i});return r[s.field]=s.localPath,l}(e,r,o,s);let l=await ew(e,t);l&&(i=l.installSource,a=l.uploadedArtifactId??a);let c=()=>ey({positionals:r,flags:o,installSource:i,uploadedArtifactId:a,clientArtifactPaths:s});return"install"!==e.command&&"reinstall"!==e.command||(a=await eh(e,t,r)??a),c()}async function eh(e,t,a){var o,i;let s,l=a[1];if(void 0===l)return;if(l.startsWith("remote:")){a[1]=l.slice(7);return}let c=(o=l,i=e.meta?.cwd,s=n.isAbsolute(o)?o:n.resolve(i??process.cwd(),o),r.existsSync(s)?s:void 0);if(c)return await ee({localPath:c,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform})}function ey(e){return{positionals:e.positionals,flags:e.flags,installSource:e.installSource,uploadedArtifactId:e.uploadedArtifactId,...Object.keys(e.clientArtifactPaths).length>0?{clientArtifactPaths:e.clientArtifactPaths}:{}}}async function ew(e,t){let a=e.meta?.installSource;if("install_source"!==e.command||!a||"path"!==a.kind)return null;let o=a.path.trim();if(!o)return{installSource:a};if(o.startsWith("remote:"))return{installSource:{...a,path:o.slice(7)}};let i=n.isAbsolute(o)?o:n.resolve(e.meta?.cwd??process.cwd(),o);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 o=e.positionals?.[r]??e.flags?.out,i=`${"path"===t?"screenshot":"recording"}-${Date.now()}${a}`,s=o&&o.trim().length>0?o:i;return n.isAbsolute(s)?s:n.resolve(e.meta?.cwd??process.cwd(),s)}function eg(e,t){let a=t.startsWith(".")?t:`.${t}`;return n.posix.join("/tmp",`agent-device-${e}-${Date.now()}-${Math.random().toString(36).slice(2,8)}${a}`)}async function ev(e){if(e.remoteBaseUrl)return await eA(e);let t=await ek(e);return t?{info:t,startedByClient:!1}:(function(e){let t=eU(e);if(!t.hasLock||t.hasInfo)return;let a=eC(e.lockPath);if(!a)return eO(e.lockPath);V(a.pid,a.processStartTime)||eO(e.lockPath)}(e.paths),await eb(e))}async function eA(e){let t={transport:"http",token:e.remoteAuthToken??"",pid:0,baseUrl:e.remoteBaseUrl};if(await ex(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 ek(e){var t,a;let r,o=eM(e.paths.infoPath);if(!o)return null;let n=await ex(o,e.transportPreference);return(t=o,a=n,t.version===R()&&t.codeSignature===b((r=eq()).useSrc?r.srcPath:r.distPath,r.root)&&a)?o:(await eE(o),eO(e.paths.infoPath),null)}async function eb(e){let t,a=0,r=[];for(let o=1;o<=2;o+=1){try{await eF(e)}catch(a){if(t=a instanceof Error?a.message:String(a),r.push(await eL(e.paths,"start_error")),o<2){await J(150);continue}break}let n=await eS(15e3,e);if(n)return{info:n,startedByClient:!0};if(await eD(e.paths)){a+=1;continue}let i=eU(e.paths),s=o<2,l=await eL(e.paths,"startup_timeout",{stopLiveProcesses:!1});if(r.push(l),l.retainedInfoProcess||l.retainedLockProcess){let t=await eS(15e3,e);if(t)return{info:t,startedByClient:!0};break}if(!s)break;i.hasInfo||i.hasLock||await J(150)}let o=eU(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:o,hint:function(e,t=F(process.env.AGENT_DEVICE_STATE_DIR)){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, remove ${t.lockPath} after confirming no agent-device daemon process is running.`: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, remove both files after confirming no agent-device daemon process is running.`:"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."}(o,e.paths)})}async function eP(e,t,a){if(!e_(e.command)||!t.startedByClient&&!a.ownedStateDir||eJ(t.info))return;let o={pid:t.info.pid,removedInfo:!1,removedLock:!1,removedStateDir:!1,error:void 0};try{await eE(t.info)}catch(e){o.error=e instanceof Error?e.message:String(e)}finally{let e=r.existsSync(a.paths.infoPath);eO(a.paths.infoPath),o.removedInfo=e&&!r.existsSync(a.paths.infoPath);let t=r.existsSync(a.paths.lockPath);eO(a.paths.lockPath),o.removedLock=t&&!r.existsSync(a.paths.lockPath),a.ownedStateDir&&(r.rmSync(a.paths.baseDir,{recursive:!0,force:!0}),o.removedStateDir=!r.existsSync(a.paths.baseDir))}G({level:o.error?"warn":"info",phase:"daemon_replay_cleanup",data:o})}function e_(e){return e===w.replay||e===w.test}async function eS(e,t){let a=Date.now();for(;Date.now()-a<e;){let e=eM(t.paths.infoPath);if(e&&await ex(e,t.transportPreference))return e;await J(100)}return null}async function eD(e){let t=eU(e);if(!t.hasLock||t.hasInfo)return!1;let a=eC(e.lockPath);return!(a&&V(a.pid,a.processStartTime))&&(eO(e.lockPath),!0)}async function eE(e){await W(e.pid,{termTimeoutMs:3e3,killTimeoutMs:1e3,expectedStartTime:e.processStartTime})}function eM(e){var t,a,r;let o,n,i=eR(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=(o=eN((a=i).port),n=eN(a.httpPort),void 0===o&&void 0===n?null:{port:o,httpPort:n});return l?{token:s,...l,transport:"socket"===(r=i.transport)||"http"===r||"dual"===r?r:void 0,pid:eN(i.pid)??0,version:eT(i.version),codeSignature:eT(i.codeSignature),processStartTime:eT(i.processStartTime)}:null}function eT(e){return"string"==typeof e?e:void 0}function eN(e){return Number.isInteger(e)&&Number(e)>0?Number(e):void 0}function eC(e){let t=eR(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}ep.addSubnet("127.0.0.0",8,"ipv4"),ep.addAddress("::1","ipv6"),ep.addSubnet("::ffff:127.0.0.0",104,"ipv6");async function eL(e,t,a={}){let o=a.stopLiveProcesses??!0,n={reason:t,removedInfo:!1,removedLock:!1,stoppedInfoProcess:!1,stoppedLockProcess:!1};try{var i,s,l,c;let t=r.existsSync(e.infoPath),a=eM(e.infoPath);if(a){let t=V(a.pid,a.processStartTime);t&&!o?n.retainedInfoProcess=!0:(t&&(await eE(a),n.stoppedInfoProcess=!0),i=e.infoPath,eO(i),n.removedInfo=!0)}else t&&(s=e.infoPath,eO(s),n.removedInfo=!0);let d=r.existsSync(e.lockPath),u=eC(e.lockPath);if(u){let t=V(u.pid,u.processStartTime);t&&!o?n.retainedLockProcess=!0:(t&&(await W(u.pid,{termTimeoutMs:3e3,killTimeoutMs:1e3,expectedStartTime:u.processStartTime}),n.stoppedLockProcess=!0),l=e.lockPath,eO(l),n.removedLock=!0)}else d&&(c=e.lockPath,eO(c),n.removedLock=!0)}catch(e){n.error=e instanceof Error?e.message:String(e)}return G({level:n.error?"warn":"info",phase:"daemon_startup_metadata_cleanup",data:n}),n}function eU(e){return{hasInfo:r.existsSync(e.infoPath),hasLock:r.existsSync(e.lockPath)}}function eR(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 ex(r,o){var n;return"http"===e$(r,o)?await function(e){let r=e.baseUrl?eY(e.baseUrl,"health"):e.httpPort?`http://127.0.0.1:${e.httpPort}/health`:null;if(!r)return Promise.resolve(!1);let o=new URL(r),n="https:"===o.protocol?a:t,i=e.baseUrl?3e3:500;return new Promise(e=>{let t=n.request({protocol:o.protocol,host:o.hostname,port:o.port,path:o.pathname+o.search,method:"GET",timeout:i},t=>{t.resume(),e((t.statusCode??500)<500)});t.on("timeout",()=>{t.destroy(),e(!1)}),t.on("error",()=>{e(!1)}),t.end()})}(r):await ((n=r.port)?new Promise(t=>{let a=!1,r=e.createConnection({host:"127.0.0.1",port:n},()=>{o(!0)}),o=e=>{a||(a=!0,r.destroy(),t(e))};r.setTimeout(500),r.on("timeout",()=>{o(!1)}),r.on("error",()=>{o(!1)})}):Promise.resolve(!1))}async function eF(e){let t=eq(),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 eq(){let e=O(),t=[n.join(e,"dist","src","internal","daemon.js"),n.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 o=t.find(e=>r.existsSync(e))??a,i=n.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:o,distPaths:t,srcPath:i,useSrc:process.execArgv.includes("--experimental-strip-types")?l:!s&&l}}async function eB(e,t,a,r){return"http"===e$(e,a)?await eG(e,t,r):await ez(e,t,r)}function e$(e,t){if(e.baseUrl){if("socket"===t)throw new u("COMMAND_FAILED","Remote daemon endpoint only supports HTTP transport",{daemonBaseUrl:e.baseUrl});return"http"}if("http"===t||"socket"===t){var a=e,r=t;if(ej(a,r))return r;throw new u("COMMAND_FAILED","http"===r?"Daemon HTTP endpoint is unavailable":"Daemon socket endpoint is unavailable")}let o=("socket"===e.transport||"dual"===e.transport?["socket","http"]:["http","socket"]).find(t=>ej(e,t));if(o)return o;throw new u("COMMAND_FAILED","Daemon metadata has no reachable transport")}function ej(e,t){return"http"===t?!!e.httpPort:!!e.port}function eH(e,t,a,r,o,n){let i=o?{terminated:0}:function(){let e=0;try{for(let t of eu){let a=p("pkill",["-f",t],{allowFailure:!0});0===a.exitCode&&(e+=1)}return{terminated:e}}catch(t){return{terminated:e,error:t instanceof Error?t.message:String(t)}}}(),s=!o&&"snapshot"!==r,l=s?function(e,t){let a=!1;try{V(e.pid,e.processStartTime)&&(process.kill(e.pid,"SIGKILL"),a=!0)}catch{W(e.pid,{termTimeoutMs:3e3,killTimeoutMs:1e3,expectedStartTime:e.processStartTime})}finally{eO(t.infoPath),eO(t.lockPath)}return{forcedKill:a}}(e,t):{forcedKill:!1};return G({level:"error",phase:"daemon_request_timeout",data:{timeoutMs:n,requestId:a,command:r,timedOutRunnerPidsTerminated:i.terminated,timedOutRunnerCleanupError:i.error,daemonPidReset:s?e.pid:void 0,daemonPidForceKilled:s?l.forcedKill:void 0,daemonPreservedAfterTimeout:!o&&!s,daemonBaseUrl:e.baseUrl}}),new u("COMMAND_FAILED","Daemon request timed out",{timeoutMs:n,requestId:a,hint:function(e){let{remote:t,resetDaemon:a,command:r}=e;return t?"Retry with --debug and verify the remote daemon URL, auth token, and remote host logs.":a?"Retry with --debug and check daemon diagnostics logs. Timed-out iOS runner xcodebuild processes were terminated when detected.":`Retry with --debug and check daemon diagnostics logs. The timed-out ${r??"request"} request was canceled and iOS runner work was aborted when detected; the daemon was kept alive so the session can still be closed or inspected.`}({remote:o,resetDaemon:s,command:r})})}function eK(e,t,a){return G({level:"error",phase:"daemon_request_socket_error",data:{requestId:t,message:e instanceof Error?e.message:String(e)}}),new u("COMMAND_FAILED","Failed to communicate with daemon",{requestId:t,hint:a?"Retry command. If this persists, verify the remote daemon URL, auth token, and remote host reachability.":"Retry command. If this persists, clean stale daemon metadata and start a fresh session."},e instanceof Error?e:void 0)}async function ez(t,a,r){let o=t.port;if(!o)throw new u("COMMAND_FAILED","Daemon socket endpoint is unavailable");return new Promise((n,i)=>{let s=e.createConnection({host:"127.0.0.1",port:o},()=>{s.write(`${JSON.stringify(a)}
|
|
3
|
+
`)}),l=F(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=y(p,e);for(let e of(p=t.buffer,t.lines))try{let t=JSON.parse(e);if(g(t)){ed(t.event);continue}let a=I(t)?t.response:t;c=!0,s.end(),d&&clearTimeout(d),n(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(eK(e,a.meta?.requestId,!1)))})})}async function eG(e,r,o){var n,i,s;let l,c=e.baseUrl?new URL(eY(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((n=r,i={includeTokenParam:!e.baseUrl},l=n.meta?.requestId??K(),"lease_allocate"!==(s=n.command)&&"lease_heartbeat"!==s&&"lease_release"!==s?{jsonrpc:"2.0",id:l,method:"agent_device.command",params:n}:{jsonrpc:"2.0",id:l,method:function(e){switch(e){case"lease_allocate":return"agent_device.lease.allocate";case"lease_heartbeat":return"agent_device.lease.heartbeat";case"lease_release":return"agent_device.lease.release"}}(n.command),params:function(e,t,a){let r={...a.includeTokenParam?{token:e.token}:{},session:e.session,tenantId:e.meta?.tenantId,runId:e.meta?.runId};switch(t){case"lease_allocate":return{...r,ttlMs:e.meta?.leaseTtlMs,backend:e.meta?.leaseBackend};case"lease_heartbeat":return{...r,leaseId:e.meta?.leaseId,ttlMs:e.meta?.leaseTtlMs};case"lease_release":return{...r,leaseId:e.meta?.leaseId}}}(n,n.command,i)})),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((n,i)=>{let s=F(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"],N(r)&&String(Array.isArray(a)?a.join(","):a??"").includes("application/x-ndjson"))?function(e,t){let{req:a,handleResponseBody:r,reject:o,clearTimeout:n}=t,i="",s=!1,l=e=>{try{let t=JSON.parse(e);if(g(t))return ed(t.event),!1;if(I(t))return s=!0,n(),r(JSON.stringify(t.response)),!0;throw Error("Missing daemon progress response envelope")}catch(t){return s=!0,n(),o(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,n(),o(new u("COMMAND_FAILED","Invalid daemon response",{requestId:a.meta?.requestId,line:e})))}),e.on("error",e=>{s||(s=!0,n(),o(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=>eV(t,{info:e,req:r,resolve:n,reject:i})}):X(t).then(t=>{f&&clearTimeout(f),eV(t,{info:e,req:r,resolve:n,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=eJ(e),f="number"==typeof o?setTimeout(()=>{l.destroy(),i(eH(e,s,r.meta?.requestId,r.command,m,o))},o):void 0;l.on("error",e=>{f&&clearTimeout(f),i(eK(e,r.meta?.requestId,m))}),l.write(d),l.end()})}function eV(e,t){let{info:a,req:r,resolve:o,reject:n}=t;try{var i,s,l;let t=(i=e,JSON.parse(i));if(t.error){let e;return void n((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 n(new u("COMMAND_FAILED","Invalid daemon RPC response",{requestId:r.meta?.requestId}));eW(a,r,t.result,o,n)}catch(t){n(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,o){try{r(e.baseUrl&&a.ok?await eQ(e,t,a):a)}catch(e){o(e)}}function eJ(e){return"string"==typeof e.baseUrl&&e.baseUrl.length>0}function eY(e,t){return new URL(t,e.endsWith("/")?e:`${e}/`).toString()}async function eQ(e,t,a){let r=Array.isArray(a.data?.artifacts)?a.data.artifacts:[];if(0===r.length||!e.baseUrl)return a;let o=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 n.resolve(t.meta?.cwd??process.cwd(),r)}(a,t);await eX({baseUrl:e.baseUrl,token:e.token,artifactId:a.artifactId,destinationPath:r,requestId:t.meta?.requestId}),o[a.field]=r,i.push({...a,localPath:r})}return o.artifacts=i,{ok:!0,data:o}}async function eX(e){var o,s;let l,c=new URL((o=e.baseUrl,s=e.artifactId,l=o.endsWith("/")?o:`${o}/`,new URL(`artifacts/${encodeURIComponent(s)}`,l).toString())),d="https:"===c.protocol?a:t;await r.promises.mkdir(n.dirname(e.destinationPath),{recursive:!0}),await new Promise((t,a)=>{let o=!1,n=e.timeoutMs??9e4,s=n=>{if(!o){if(o=!0,clearTimeout(p),n)return void r.promises.rm(e.destinationPath,{force:!0}).finally(()=>a(n));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:n});s(t),l.destroy(t)},n);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:n},t instanceof Error?t:void 0))}),l.end()})}function eZ(e={},t={}){let a=t.transport??em,r=async(t,r=[],o={})=>{var n,i;let s=(n=e,i=o,{...n,...i}),l=await a({session:M(s.session),command:t,positionals:r,flags:D(s),runtime:s.runtime,meta:S(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??{}},o=async(e={})=>{let t=await r(C.sessionList,[],e);return(Array.isArray(t.sessions)?t.sessions:[]).map(h)},n=async(e,t={})=>{let a=v(e,t);return await r(a.command,a.positionals,a.options)},i=(t={})=>{var a,r;return M((a=e,r=t,{...a,...r}).session)};return{command:{wait:async e=>await n("wait",e),alert:async(e={})=>await n("alert",e),appState:async(e={})=>await n("appstate",e),back:async(e={})=>await n("back",e),home:async(e={})=>await n("home",e),rotate:async e=>await n("rotate",e),appSwitcher:async(e={})=>await n("app-switcher",e),keyboard:async(e={})=>await n("keyboard",e),clipboard:async e=>await n("clipboard",e),reactNative:async e=>await n("react-native",e)},devices:{list:async(e={})=>{let t=await n("devices",e);return(Array.isArray(t.devices)?t.devices:[]).map(L)},boot:async(e={})=>await n("boot",e)},sessions:{list:async(e={})=>await o(e),close:async(e={})=>{let t=i(e),a=(await n("close",e)).shutdown;return{session:t,shutdown:"object"==typeof a&&null!==a?a:void 0,identifiers:{session:t}}}},apps:{install:async e=>_(await n("install",e),i(e)),reinstall:async e=>_(await n("reinstall",e),i(e)),installFromSource:async e=>H(await n("install-from-source",e),i(e)),list:async(e={})=>{let t=await n("apps",e);return Array.isArray(t.apps)?t.apps.filter(e=>"string"==typeof e):[]},open:async e=>{let t=i(e),a=await n("open",e),r=x(a),o=E(a,"appBundleId");return{session:t,appName:E(a,"appName"),appBundleId:o,appId:o,startup:$(a.startup),runtime:B(a.runtime),device:r,identifiers:{session:t,deviceId:r?.id,deviceName:r?.name,udid:r?.ios?.udid,serial:r?.android?.serial,appId:o,appBundleId:o}}},close:async(e={})=>{let t=i(e),a=(await n("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 n("push",e),triggerEvent:async e=>await n("trigger-app-event",e)},materializations:{release:async e=>k(await r(C.releaseMaterializedPaths,[],{...e,materializationId:e.materializationId}))},leases:{allocate:async e=>e1(await r(C.leaseAllocate,[],{...e,leaseId:void 0,leaseTtlMs:e.ttlMs})),heartbeat:async e=>e1(await r(C.leaseHeartbeat,[],{...e,leaseTtlMs:e.ttlMs})),release:async e=>({released:!0===(await r(C.leaseRelease,[],e)).released})},metro:{prepare:async t=>await Q({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 Y({metroHost:t.metroHost,metroPort:t.metroPort,bundleUrl:t.bundleUrl,runtime:e.runtime,timeoutMs:t.timeoutMs})},capture:{snapshot:async(e={})=>{var t,a,r;let o,s,l,c,d,u=i(e);return t=await n("snapshot",e),a=u,o=E(t,"appBundleId"),{nodes:A(t.nodes),truncated:!0===t.truncated,appName:E(t,"appName"),appBundleId:o,...(s=e0((r=t).visibility),l=e0(r.androidSnapshot),c=e0(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:o,appBundleId:o}}},screenshot:async(e={})=>{let t=i(e),a=await n("screenshot",e);return{path:U(a,"path"),overlayRefs:j(a),identifiers:{session:t}}},diff:async e=>await n("diff",e)},interactions:{click:async e=>await n("click",e),press:async e=>await n("press",e),longPress:async e=>await n("longpress",e),swipe:async e=>await n("swipe",e),pan:async e=>await n("gesture-pan",e),fling:async e=>await n("gesture-fling",e),focus:async e=>await n("focus",e),type:async e=>await n("type",e),fill:async e=>await n("fill",e),scroll:async e=>await n("scroll",e),pinch:async e=>await n("gesture-pinch",e),rotateGesture:async e=>await n("gesture-rotate",e),transformGesture:async e=>await n("gesture-transform",e),get:async e=>await n("get",e),is:async e=>await n("is",e),find:async e=>await n("find",e)},replay:{run:async e=>await n("replay",e),test:async e=>await n("test",e)},batch:{run:async e=>await n("batch",e)},observability:{perf:async(e={})=>await n("perf",e),logs:async(e={})=>await n("logs",e),network:async(e={})=>await n("network",e)},recording:{record:async e=>await n("record",e),trace:async e=>await n("trace",e)},settings:{update:async e=>await n("settings",e)}}}function e0(e){return"object"==typeof e&&null!==e?e:void 0}function e1(e){let t=e.lease;if(!t||"object"!=typeof t||Array.isArray(t))throw Error("Invalid lease response from daemon");return{leaseId:U(t,"leaseId"),tenantId:U(t,"tenantId"),runId:U(t,"runId"),backend:U(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{eZ as createAgentDeviceClient,em as sendToDaemon};
|
package/dist/src/batch.d.ts
CHANGED
package/dist/src/cli.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import e from"node:path";import{styleText as t}from"node:util";import{pathToFileURL as n}from"node:url";import o from"node:fs";import r from"node:crypto";import{interactionCliReaders as s,serializeSessionListEntry as a,serializeSnapshotResult as i,gestureCliReaders as l,observabilityCliReaders as c,serializeCloseResult as d,parseInstallSourceConfig as u,listCliCommandNames as p,readVersion as f,captureCliReaders as m,serializeOpenResult as h,replayCliReaders as g,serializeDeployResult as v,readCommandMessage as w,resolveDaemonPaths as y,appCliReaders as b,commonInputFromFlags as I,serializeInstallFromSourceResult as x,selectorCliReaders as A,serializeDevice as $,systemCliReaders as k}from"./
|
|
1
|
+
import e from"node:path";import{styleText as t}from"node:util";import{pathToFileURL as n}from"node:url";import o from"node:fs";import r from"node:crypto";import{interactionCliReaders as s,serializeSessionListEntry as a,serializeSnapshotResult as i,gestureCliReaders as l,observabilityCliReaders as c,serializeCloseResult as d,parseInstallSourceConfig as u,listCliCommandNames as p,readVersion as f,captureCliReaders as m,serializeOpenResult as h,replayCliReaders as g,serializeDeployResult as v,readCommandMessage as w,resolveDaemonPaths as y,appCliReaders as b,commonInputFromFlags as I,serializeInstallFromSourceResult as x,selectorCliReaders as A,serializeDevice as $,systemCliReaders as k}from"./6277.js";import{buildMobileSnapshotPresentation as S,formatSnapshotLine as C,GLOBAL_FLAG_KEYS as D,getFlagDefinition as N,createAgentDevice as R,getCliCommandSchema as U,getCommandSchema as _,applyCommandDefaults as E,displayNodeLabel as P,localCommandPolicy as O,getFlagDefinitions as L,buildSnapshotDisplayLines as T}from"./7519.js";import{resolveRemoteConfigProfile as M,resolveRemoteConfigPath as B,REMOTE_CONFIG_FIELD_SPECS as j,parseSourceValue as F,buildPrimaryEnvVarName as G}from"./208.js";import{asAppError as V,normalizeError as H,AppError as K}from"./9152.js";import{ensureCompanionTunnel as q,stopCompanionTunnel as z}from"./1974.js";import{REACT_DEVTOOLS_COMPANION_RUN_ARG as J}from"./2301.js";import{createRequestId as W,withDiagnosticsScope as Z,getDiagnosticsMeta as X,flushDiagnosticsToSessionFile as Y,emitDiagnostic as Q}from"./3622.js";import{stopMetroTunnel as ee}from"./metro.js";import{runCmdStreaming as et,runCmd as en}from"./9818.js";import{listCommandNames as eo,isCommandName as er,runCommand as es}from"./89.js";import{resolveUserPath as ea,expandUserHomePath as ei}from"./3267.js";import{createLocalArtifactAdapter as el}from"./7719.js";import{createAgentDeviceClient as ec,sendToDaemon as ed}from"./9542.js";import{maybeRunUpgradeNotifier as eu}from"./113.js";function ep(e,t){for(let[n,o]of Object.entries(t))void 0!==o&&(e[n]=o);return e}let ef=[{label:"help workflow",description:"Normal bootstrap, exploration, and validation loop"},{label:"help debugging",description:"Logs, network, alerts, diagnostics, and traces"},{label:"help react-native",description:"React Native app automation hazards, overlays, Metro, and routing"},{label:"help react-devtools",description:"React Native performance, profiling, component tree, and renders"},{label:"help remote",description:"Remote/cloud config, tenants, leases, and local service tunnels"},{label:"help macos",description:"Desktop, frontmost-app, and menu bar surfaces"},{label:"help dogfood",description:"Exploratory QA report workflow"}],em=["Default loop: devices/apps -> open -> snapshot -i -> press/fill/get/is/wait/find -> verify -> close.",'Use selectors or refs as positional targets: id="submit", label="Allow", or @e12 from snapshot -i.',"Plain snapshot reads state; snapshot -i refreshes current interactive refs only.","Default snapshot text is an agent-facing, token-efficient view for planning and targeting actions.","Read-only visible/state question: use snapshot/get/is/find; use snapshot -i only when refs are needed.","Anti-pattern: snapshot -i followed by snapshot -i | grep ...; prior refs stay valid until app state changes, and --force-full is the explicit full re-read.","Truncated text/input preview: expand first with snapshot -s @e12, not get text.","React Native apps: read help react-native for Metro, DevTools routing, and RN-specific blockers; use react-native dismiss-overlay for LogBox/RedBox overlays.","Android RN/Expo Metro: direct Android localhost URL opens with a port auto-configure host reachability.",'Expo Go/dev clients: use the provided URL when given; on iOS prefer open "Expo Go" <url>; Android URL opens infer the foreground package for logs/perf when possible.',"Install flows: install/install-from-source first, then open the installed id with --relaunch.",'Text: fill \'id="field-email"\' "qa@example.com" replaces; type appends after press.','Clearing text: do not use fill <target> ""; use a visible clear/reset control or report that clearing is unsupported.',"Android IME capture: if fill says input was captured by the keyboard/IME, inspect keyboard state and switch/disable handwriting before retrying; do not loop fill/type.","Run mutating commands serially against one session; parallelize only read-only commands or separate sessions.","Before taking over a shared device, run session list and reuse the active session name when one already owns the device.","Clipboard limits: iOS Allow Paste cannot be automated through XCUITest; prefill with clipboard write. Android non-ASCII should use fill/type, not raw adb input.","After mutation: refs are stale. If the next target is known, use its selector directly; otherwise refresh with snapshot -i, scoped with -s when a stable container is known.","Raw coordinates are fallback-only: use snapshot -i -c --json rects when iOS refs no-op or child refs are missing.",'Batch JSON steps use "command" and structured "input"; legacy "positionals"/"flags" steps still run in CLI but are deprecated until the next major version.',"Navigation: app-owned back uses back; system back uses back --system.","Verification commands must name the expected text/selector; bare screenshots/snapshots are not enough.","Debug evidence: logs clear --restart/mark/path; trace start ./path; trace stop ./path; network dump --include headers.","Use agent-device commands in final plans; raw platform tools, pseudo commands, and helper prose are wrong.","Full operating guide: agent-device help workflow. Exploratory QA: agent-device help dogfood."],eh=["Default config files: ~/.agent-device/config.json, ./agent-device.json","Use --config <path> or AGENT_DEVICE_CONFIG to load one explicit config file."],eg=[{label:"AGENT_DEVICE_SESSION",description:"Default session name"},{label:"AGENT_DEVICE_PLATFORM",description:"Default platform binding"},{label:"AGENT_DEVICE_SESSION_LOCK",description:"Bound-session conflict mode"},{label:"AGENT_DEVICE_DAEMON_BASE_URL",description:"Connect to remote daemon"},{label:"AGENT_DEVICE_DAEMON_AUTH_TOKEN",description:"Remote daemon service/API token"},{label:"AGENT_DEVICE_CLOUD_BASE_URL",description:"Bridge/control-plane API origin for cloud auth and /api-keys"}],ev=["agent-device open Settings --platform ios","agent-device open TextEdit --platform macos","agent-device snapshot -i","agent-device react-devtools get tree --depth 3",'agent-device fill @e3 "test@example.com"',"agent-device replay ./session.ad","agent-device test ./suite --platform android"],ew={workflow:{summary:"Normal agent-device bootstrap, exploration, and validation loop",body:`agent-device help workflow
|
|
2
2
|
|
|
3
3
|
Version-matched operating guide for normal agent-device work.
|
|
4
4
|
|
|
@@ -467,18 +467,15 @@ ${v}${(function(e){let t=[],n=[],o=new Map(e.map(e=>[e.node.index,e.node])),r=e=
|
|
|
467
467
|
`:"";if(!l)return`${d}${p}${s} additions, ${a} removals, ${i} unchanged
|
|
468
468
|
`;let f=`${(n=String(s),t("green",n))} additions, ${t("red",String(a))} removals, ${t("dim",String(i))} unchanged`;return`${d}${p}${f}
|
|
469
469
|
`})(r)),!0}if("screenshot"!==e[0])return!1;let s=n.baseline;if(!s||"string"!=typeof s)throw new K("INVALID_ARGS","diff screenshot requires --baseline <path>");let a=ea(s),i="string"==typeof n.out?ea(n.out):void 0,l=e[1];if(e.length>2)throw new K("INVALID_ARGS","diff screenshot accepts at most one current screenshot path");let c=R({backend:(r=o,{platform:function(e){switch(e.platform){case"android":case"linux":case"macos":return e.platform;default:return"ios"}}(n),captureScreenshot:async(e,t,n)=>{let o=await r.capture.screenshot({path:t,session:e.session,overlayRefs:n?.overlayRefs,fullscreen:n?.fullscreen,stabilize:n?.stabilize,surface:n?.surface});return{path:o.path,...o.overlayRefs?{overlayRefs:o.overlayRefs}:{}}}}),artifacts:el(),sessions:{get:e=>({name:e}),set:()=>{}},policy:O()}),d=await c.capture.diffScreenshot({session:n.session,baseline:{kind:"path",path:a},current:l?{kind:"path",path:ea(l)}:{kind:"live"},...i?{out:{kind:"path",path:i}}:{},threshold:function(e){if(null!=e&&""!==e)return Number(e)}(n.threshold),overlayRefs:n.overlayRefs,surface:n.surface});return tz(n,d,()=>{var e,n,o,r;let s,a,i,l,c,u,p,f;return s=e4(),a=!0===d.match,i=d.dimensionMismatch,(l=[]).push(...function(e,n){if(!0===e.match){let e=n?t("green","✓"):"✓";return[`${e} Screenshots match.`]}let o=e.dimensionMismatch,r=n?t("red","✗"):"✗";if(o){let e=o.expected,t=o.actual;return[`${r} Screenshots have different dimensions: expected ${e?.width}x${e?.height}, got ${t?.width}x${t?.height}`]}let s=e5(e.differentPixels),a=e5(e.mismatchPercentage),i=0===a&&s>0?"<0.01":String(a),l=`${i}% pixels differ`;return[`${r} ${n?t("red",l):l}`]}(d,s)),l.push(...function(e,n,o){if(n)return[];let r=[];if(e.diffPath){let n=e8(e.diffPath),s=o?t("dim","Diff image:"):"Diff image:",a=o?t("green",n):n;r.push(` ${s} ${a}`)}if(e.currentOverlayPath){let n=e8(e.currentOverlayPath),s=o?t("dim","Current overlay:"):"Current overlay:",a=o?t("green",n):n,i=e5(e.currentOverlayRefCount),l=i>0?` (${i} refs)`:"";r.push(` ${s} ${a}${l}`)}return r}(d,a,s)),a||i||(l.push(...(e=d,n=s,c=e5(e.differentPixels),u=e5(e.totalPixels),p=n?t("red",String(c)):String(c),[` ${p} different / ${u} total pixels`])),l.push(...(o=d,r=s,0===(f=function(e){let t=[];for(let n of(e.ocr?.movementClusters??[]).slice(0,2))t.push(`text movement cluster: ${function(e){let t=e.slice(0,4).map(e=>JSON.stringify(e)),n=e.length>t.length?` +${e.length-t.length} more`:"";return`${t.join(", ")}${n}`}(n.texts)} dx=${e3(n.xRange)}px dy=${e3(n.yRange)}px`);let n=(e.nonTextDeltas??[]).filter(e=>["icon","toggle","chevron"].includes(e.likelyKind)).slice(0,3);n.length>0&&t.push(`non-text controls: ${n.map(e2).join("; ")}`);let o=(e.nonTextDeltas??[]).filter(e=>"separator"===e.likelyKind).slice(0,2);return o.length>0&&t.push(`non-text boundaries: ${o.map(e2).join("; ")}`),t.slice(0,6)}(o)).length?[]:[` ${e6("Hints:",r)}`,...f.map(e=>` - ${e}`)])),l.push(...function(e,t){let n=Array.isArray(e.regions)?e.regions:[];if(0===n.length)return[];let o=[` ${e6("Changed regions:",t)}`];for(let e of n.slice(0,5))o.push(...function(e){let t=0===e.shareOfDiffPercentage&&e.differentPixels>0?"<0.01":String(e.shareOfDiffPercentage),n=e.rect,o=[` ${e.index}. ${e.location} x=${n.x} y=${n.y} ${n.width}x${n.height}, ${t}% of diff, change=${e.dominantChange}`],r=function(e){let t=[e.size?`size=${e.size}`:null,e.shape?`shape=${e.shape}`:null,"number"==typeof e.densityPercentage?`density=${e.densityPercentage}%`:null,e.averageBaselineColorHex&&e.averageCurrentColorHex?`avgColor=${e.averageBaselineColorHex}->${e.averageCurrentColorHex}`:null,"number"==typeof e.baselineLuminance&&"number"==typeof e.currentLuminance?`luminance=${e.baselineLuminance}->${e.currentLuminance}`:null].filter(e=>null!==e);return t.length>0?t.join(" "):null}(e);r&&o.push(` ${r}`);let s=e.currentOverlayMatches?.[0];if(s){let e=s.label?` "${s.label}"`:"";o.push(` overlaps @${s.ref}${e}, ${s.regionCoveragePercentage}% of region`)}return o}(e));return o}(d,s)),l.push(...function(e,t){let n=e.ocr?.matches??[];if(0===n.length)return[];let o=n.slice(0,8),r=[` ${e6(`OCR text deltas (${e.ocr?.provider}; baselineBlocks=${e.ocr?.baselineBlocks} currentBlocks=${e.ocr?.currentBlocks}; showing ${o.length}/${n.length}; px):`,t)}`,` ${e6("item | text | movePx | sizeDeltaPx | bboxBaseline | bboxCurrent | confidence | issueHint",t)}`];for(let[e,t]of o.entries()){let n=t.delta;r.push(` ${e+1} | ${JSON.stringify(t.text)} | ${e1(n.x)},${e1(n.y)} | ${e1(n.width)},${e1(n.height)} | ${e0(t.baselineRect)} | ${e0(t.currentRect)} | ${t.confidence} | ${t.possibleTextMetricMismatch?"ocr-bbox-size-change":"-"}`)}return r}(d,s)),l.push(...function(e,t){let n=e.nonTextDeltas??[];if(0===n.length)return[];let o=n.slice(0,8),r=[` ${e6(`Non-text visual deltas (showing ${o.length}/${n.length}; px):`,t)}`,` ${e6("item | region | slot | kind | bboxCurrent | nearestText",t)}`];for(let e of o)r.push(` ${e.index} | ${e.regionIndex?`r${e.regionIndex}`:"-"} | ${e.slot} | ${e.likelyKind} | ${e0(e.rect)} | ${e.nearestText?JSON.stringify(e.nearestText):"-"}`);return r}(d,s))),`${l.join("\n")}
|
|
470
|
-
`}),!0};function nf(e){let
|
|
470
|
+
`}),!0};function nf(e){var t;let n=e.attempts>1?` after ${e.attempts} attempts`:"",o=e.durationMs>0?` (${e.durationMs}ms)`:"";for(let r of(process.stdout.write(`FAIL ${e.file}${n}${o}
|
|
471
471
|
`),process.stdout.write(` ${e.error?.message??"Unknown test failure"}
|
|
472
|
-
`),e.error?.hint
|
|
473
|
-
`),e.
|
|
474
|
-
`),e.
|
|
475
|
-
`),e.error?.diagnosticId&&process.stdout.write(` diagnostic: ${e.error.diagnosticId}
|
|
476
|
-
`)}function nm(e){return"passed"===e.status&&e.attempts>1}function nh(e){return(Math.max(0,e)/1e3).toFixed(3)}function ng(e){return e.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""").replaceAll("'","'")}let nv=Object.fromEntries(Object.keys(ni).map(e=>{var t;return[e,(t=e,async({positionals:e,flags:n,client:o})=>{var r,s;let{cliOutput:a}=await nd({client:o,command:t,positionals:e,flags:n});if(!a)throw Error(`Missing CLI output formatter for command: ${t}`);return r=n,s=a,!r.json&&s.stderr&&process.stderr.write(s.stderr),tz(r,r.json?s.jsonData??s.data:s.data,()=>s.text),!0})]})),nw=Object.fromEntries(Object.entries(Object.fromEntries(eo().filter(function(e){return!(e in nv)&&"screenshot"!==e&&"diff"!==e}).map(e=>[e,async({client:t,positionals:n,flags:o})=>("test"===e&&(({json:o.json}).json||process.stderr.write("Running replay suite...\n")),await nc({client:t,command:e,positionals:n,flags:o}))]))).map(([t,n])=>{var r,s;return[t,(r=t,s=n,async({positionals:t,flags:n,client:a})=>{var i,l,c;let d=await s({client:a,positionals:t,flags:n}),u=(i=r,l=n,c=d,"test"===i?function(t){let{suite:n,json:r,verbose:s,reportJunit:a}=t;return(a&&function(t,n){let r=e.dirname(t);try{o.mkdirSync(r,{recursive:!0}),o.writeFileSync(t,function(t){let n=['<?xml version="1.0" encoding="UTF-8"?>',"<testsuites>",` <testsuite name="agent-device replay suite" tests="${t.total}" failures="${t.failed}" skipped="${t.skipped}" time="${nh(t.durationMs)}">`];for(let o of t.tests)n.push(...function(t){let n=ng(e.basename(t.file)),o=ng("."===e.dirname(t.file)?t.file:e.dirname(t.file)),r=ng(t.file),s=nh(t.durationMs),a=[` <testcase classname="${o}" name="${n}" file="${r}" time="${s}">`];"failed"===t.status?a.push(` <failure message="${ng(t.error.message)}">${ng(function(e){let t=[e.error.message];e.error.hint&&t.push(`hint: ${e.error.hint}`),e.error.diagnosticId&&t.push(`diagnosticId: ${e.error.diagnosticId}`),e.error.logPath&&t.push(`logPath: ${e.error.logPath}`),e.artifactsDir&&t.push(`artifactsDir: ${e.artifactsDir}`);let n=e.error.details?JSON.stringify(e.error.details,null,2):void 0;return n&&t.push(`details: ${n}`),t.join("\n")}(t))}</failure>`):"skipped"===t.status&&a.push(` <skipped message="${ng(t.message)}" />`);let i=function(e){let t=[`status: ${e.status}`,`durationMs: ${e.durationMs}`];return"attempts"in e&&t.push(`attempts: ${e.attempts}`),"session"in e&&t.push(`session: ${e.session}`),"replayed"in e&&t.push(`replayed: ${e.replayed}`),"healed"in e&&t.push(`healed: ${e.healed}`),"artifactsDir"in e&&e.artifactsDir&&t.push(`artifactsDir: ${e.artifactsDir}`),"passed"===e.status&&e.attempts>1&&t.push("flaky: true"),t.join("\n")}(t);return i&&a.push(` <system-out>${ng(i)}</system-out>`),a.push(" </testcase>"),a}(o));return n.push(" </testsuite>"),n.push("</testsuites>"),`${n.join("\n")}
|
|
477
|
-
`}(n),"utf8")}catch(n){let e=n instanceof Error?n.message:String(n);throw new K("COMMAND_FAILED",`Failed to write JUnit report to ${t}: ${e}`)}}(a,n),r)?(eX({success:!0,data:n}),+(n.failed>0)):function(e,t={}){let n=e.tests.filter(nm);if(t.verbose)for(let t of e.tests)!function(e){if("failed"===e.status)return nf(e);let t="passed"===e.status?nm(e)?"FLAKY":"PASS":"skipped"===e.status?"SKIP":"INFO",n="attempts"in e&&e.attempts>1?` after ${e.attempts} attempts`:"",o=e.durationMs>0?` (${e.durationMs}ms)`:"";process.stdout.write(`${t} ${e.file}${n}${o}
|
|
472
|
+
`),t=e,[t.error?.hint?`hint: ${t.error.hint}`:"",t.artifactsDir?`artifacts: ${t.artifactsDir}`:"",t.error?.logPath?`log: ${t.error.logPath}`:"",t.error?.diagnosticId?`diagnostic: ${t.error.diagnosticId}`:""].filter(Boolean)))process.stdout.write(` ${r}
|
|
473
|
+
`)}function nm(e){return"passed"===e.status&&e.attempts>1}function nh(e,t,n={}){n.includeMessage&&e.push(`errorMessage: ${t.message}`),t.hint&&e.push(`hint: ${t.hint}`),t.diagnosticId&&e.push(`diagnosticId: ${t.diagnosticId}`),t.logPath&&e.push(`logPath: ${t.logPath}`),!1!==n.includeDetails&&ng(e,t,n.detailsIndent)}function ng(e,t,n){let o=t.details?JSON.stringify(t.details,null,n):void 0;o&&e.push(`details: ${o}`)}function nv(e,t){t&&e.push(t)}function nw(e){return(Math.max(0,e)/1e3).toFixed(3)}function ny(e){return e.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""").replaceAll("'","'")}let nb=Object.fromEntries(Object.keys(ni).map(e=>{var t;return[e,(t=e,async({positionals:e,flags:n,client:o})=>{var r,s;let{cliOutput:a}=await nd({client:o,command:t,positionals:e,flags:n});if(!a)throw Error(`Missing CLI output formatter for command: ${t}`);return r=n,s=a,!r.json&&s.stderr&&process.stderr.write(s.stderr),tz(r,r.json?s.jsonData??s.data:s.data,()=>s.text),!0})]})),nI=Object.fromEntries(Object.entries(Object.fromEntries(eo().filter(function(e){return!(e in nb)&&"screenshot"!==e&&"diff"!==e}).map(e=>[e,async({client:t,positionals:n,flags:o})=>("test"===e&&(({json:o.json}).json||process.stderr.write("Running replay suite...\n")),await nc({client:t,command:e,positionals:n,flags:o}))]))).map(([t,n])=>{var r,s;return[t,(r=t,s=n,async({positionals:t,flags:n,client:a})=>{var i,l,c;let d=await s({client:a,positionals:t,flags:n}),u=(i=r,l=n,c=d,"test"===i?function(t){let{suite:n,json:r,verbose:s,reportJunit:a}=t;return(a&&function(t,n){let r=e.dirname(t);try{o.mkdirSync(r,{recursive:!0}),o.writeFileSync(t,function(t){let n=['<?xml version="1.0" encoding="UTF-8"?>',"<testsuites>",` <testsuite name="agent-device replay suite" tests="${t.total}" failures="${t.failed}" skipped="${t.skipped}" time="${nw(t.durationMs)}">`];for(let o of t.tests)n.push(...function(t){let n=ny(e.basename(t.file)),o=ny("."===e.dirname(t.file)?t.file:e.dirname(t.file)),r=ny(t.file),s=nw(t.durationMs),a=[` <testcase classname="${o}" name="${n}" file="${r}" time="${s}">`];"failed"===t.status?a.push(` <failure message="${ny(t.error.message)}">${ny(function(e){let t=[e.error.message];return nh(t,e.error,{includeDetails:!1}),e.artifactsDir&&t.push(`artifactsDir: ${e.artifactsDir}`),ng(t,e.error,2),t.join("\n")}(t))}</failure>`):"skipped"===t.status&&a.push(` <skipped message="${ny(t.message)}" />`);let i=function(e){let t=[`status: ${e.status}`,`durationMs: ${e.durationMs}`];return function(e,t){var n,o;nv(e,"attempts"in t?`attempts: ${t.attempts}`:void 0),nv(e,"session"in t?`session: ${t.session}`:void 0),nv(e,"replayed"in t?`replayed: ${t.replayed}`:void 0),nv(e,"healed"in t?`healed: ${t.healed}`:void 0),nv(e,"artifactsDir"in t&&t.artifactsDir?`artifactsDir: ${t.artifactsDir}`:void 0),"failed"===t.status&&(n=e,o=t,n.push(`errorCode: ${o.error.code}`),nh(n,o.error,{includeMessage:!0})),nv(e,nm(t)?"flaky: true":void 0)}(t,e),t.join("\n")}(t);return i&&a.push(` <system-out>${ny(i)}</system-out>`),a.push(" </testcase>"),a}(o));return n.push(" </testsuite>"),n.push("</testsuites>"),`${n.join("\n")}
|
|
474
|
+
`}(n),"utf8")}catch(n){let e=n instanceof Error?n.message:String(n);throw new K("COMMAND_FAILED",`Failed to write JUnit report to ${t}: ${e}`)}}(a,n),r)?(eX({success:!0,data:n}),+(n.failed>0)):function(e,t={}){let n=e.tests.filter(nm);if(t.verbose)for(let t of e.tests)!function(e){var t;if("failed"===e.status)return nf(e);let n="passed"===(t=e).status?t.attempts>1?"FLAKY":"PASS":"skipped"===t.status?"SKIP":"INFO",o="attempts"in e&&e.attempts>1?` after ${e.attempts} attempts`:"",r=e.durationMs>0?` (${e.durationMs}ms)`:"";process.stdout.write(`${n} ${e.file}${o}${r}
|
|
478
475
|
`),"skipped"===e.status&&process.stdout.write(` ${e.message??"skipped"}
|
|
479
476
|
`)}(t);else{for(let t of e.failures)nf(t);for(let e of n)!function(e){let t=e.durationMs>0?` (${e.durationMs}ms)`:"";process.stdout.write(`FLAKY ${e.file} after ${e.attempts} attempts${t}
|
|
480
477
|
`)}(e)}let o="number"==typeof e.durationMs?e.durationMs:void 0,r=n.length>0?`, ${n.length} flaky`:"";return process.stdout.write(`Test summary: ${e.passed} passed, ${e.failed} failed${r}${void 0!==o?` in ${o}ms`:""}
|
|
481
|
-
`),+(e.failed>0)}(n,{verbose:s})}({suite:c,verbose:l.verbose,json:l.json,reportJunit:l.reportJunit}):(tz(l,c,()=>w(c)),0));return 0!==u&&process.exit(u),!0})]})),
|
|
478
|
+
`),+(e.failed>0)}(n,{verbose:s})}({suite:c,verbose:l.verbose,json:l.json,reportJunit:l.reportJunit}):(tz(l,c,()=>w(c)),0));return 0!==u&&process.exit(u),!0})]})),nx={connect:tJ,disconnect:tW,connection:tZ,auth:t1,screenshot:nu,diff:np,...nb,...nI};async function nA(e){let t=nx[e.command];if(!t)return!1;let n={...e.flags};return E(e.command,n),await t({...e,flags:n})}function n$(e,t,n){return n||(e.push(t),"")}async function nk(e,t,n){let{flags:o}=t,r=function(e){var t;if(!e?.metroProxyBaseUrl||"android-instance"!==(t=e.leaseBackend)&&"ios-instance"!==t)return null;let n=[],o={serverBaseUrl:n$(n,"metroProxyBaseUrl",e.metroProxyBaseUrl),bearerToken:n$(n,"metroBearerToken",e.metroBearerToken),tenantId:n$(n,"tenant",e.tenant),runId:n$(n,"runId",e.runId),leaseId:n$(n,"leaseId",e.leaseId)};if(n.length>0)throw new K("INVALID_ARGS",`react-devtools remote bridge requires ${n.join(", ")}.`,{missing:n});return o}(o);if(!r)return n();let s=t.stateDir??process.cwd(),a=t.session??o?.session??"default",i=o?.remoteConfig??`${r.tenantId}:${r.runId}:${r.leaseId}`;if("stop"===e[0])try{return await n()}finally{await tn({projectRoot:t.cwd??process.cwd(),stateDir:s,profileKey:i,consumerKey:a})}return await tt({projectRoot:t.cwd??process.cwd(),stateDir:s,serverBaseUrl:r.serverBaseUrl,bearerToken:r.bearerToken,bridgeScope:{tenantId:r.tenantId,runId:r.runId,leaseId:r.leaseId},session:a,profileKey:i,consumerKey:a,env:t.env??process.env}),await n()}async function nS(e,t={}){let n=t.cwd??process.cwd(),o=t.env??process.env,r=await nk(e,t,async()=>(await et("npm",["exec","--yes","--package","agent-react-devtools@0.4.0","--","agent-react-devtools",...e],{cwd:n,env:o,allowFailure:!0,onStdoutChunk:e=>{process.stdout.write(e)},onStderrChunk:e=>{process.stderr.write(e)}})).exitCode);var s,a=t.flags;return 0!==r&&"wait"===(s=e)[0]&&s.includes("--connected")&&"ios-instance"===a?.leaseBackend&&process.stderr.write("Hint: Remote iOS React DevTools connects during JavaScript startup.\nIf the app was already open before `agent-device react-devtools start`, relaunch it with `agent-device open <bundle-id> --platform ios --relaunch`, then retry `agent-device react-devtools wait --connected`.\n"),r}function nC(e,t={}){let n=nD(t),o={...e};return n.defaultPlatform&&void 0===o.platform&&(o.platform=n.defaultPlatform),o}function nD(e){var t,n,o,r;let s,a=e.env??process.env,i=e.inheritedPlatform??e.configuredPlatform??function(e){if(void 0===e)return;let t=e.trim().toLowerCase();if(t){if("ios"===t||"android"===t||"apple"===t)return t;throw new K("INVALID_ARGS",`Invalid AGENT_DEVICE_PLATFORM: ${e}. Use ios, android, or apple.`)}}(a.AGENT_DEVICE_PLATFORM),l="string"==typeof(t=e.configuredSession??a.AGENT_DEVICE_SESSION)&&t.trim().length>0;return{defaultPlatform:i,lockPolicy:(n=e.policyOverrides,o=a,r=l,(s=n?.sessionLock??n?.sessionLockConflicts??function(e){if(void 0===e)return;let t=e.trim().toLowerCase();if(t){if("reject"===t||"strip"===t)return t;throw new K("INVALID_ARGS",`Invalid session lock mode: ${e}. Use reject or strip.`)}}(o.AGENT_DEVICE_SESSION_LOCK))||(n?.sessionLocked===!0||r?"reject":void 0))}}let nN={sendToDaemon:ed},nR=new Set(["launchUrl","metroBearerToken","metroKind","metroListenHost","metroNoInstallDeps","metroNoReuseExisting","metroPreparePort","metroProbeTimeoutMs","metroProjectRoot","metroProxyBaseUrl","metroPublicBaseUrl","metroRuntimeFile","metroStartupTimeoutMs","metroStatusHost"]),nU=new Set(["connect","connection","close","disconnect","metro","session"]);async function n_(t,n=nN){let r=W(),s=f(),a=t.includes("--debug")||t.includes("--verbose")||t.includes("-v"),i=t.includes("--json"),l=function(e){for(let t=0;t<e.length;t+=1){let n=e[t];if(n.startsWith("--session=")){let e=n.slice(10).trim();return e.length>0?e:null}if("--session"===n){let n=e[t+1]?.trim();if(n&&!n.startsWith("-"))return n;break}}return null}(t)??process.env.AGENT_DEVICE_SESSION??"default";await Z({session:l,requestId:r,command:t[0],debug:a},async()=>{var l,c,d,p,f,m,h,g,v,w,b,I,x,A,$,k,S;let C,R,U,P,O,T,j;try{let n,r,s,a,i,y,I,x;l={cwd:process.cwd(),env:process.env},n=function(e){let t={json:!1,help:!1,version:!1},n=null,o=[],r=[],s=!0;for(let l=0;l<e.length;l+=1){var a,i;let c=e[l];if(s&&"--"===c){s=!1;continue}if(!s){n?o.push(c):n=eP(c);continue}let d=c.startsWith("--"),u=c.startsWith("-")&&c.length>1;if(!d&&!u){n?o.push(c):n=eP(c);continue}let[p,f]=d?eR(c):[c,void 0],m=N(p);if(a=n,i=m,"react-devtools"===a&&(!i||!eD(i.key,a))){o.push(c);continue}if(!m){if(function(e,t,n){var o;if(o=n,!/^-\d+(\.\d+)?$/.test(o)||!e)return!1;let r=_(e);if(!r||r.allowsExtraPositionals)return!0;let s=r.positionalArgs??[];return 0!==s.length&&(t.length<s.length||s.some(e=>e.includes("?")))}(n,o,c)){n?o.push(c):n=c;continue}throw new K("INVALID_ARGS",`Unknown flag: ${p}`)}let h=function(e,t,n,o){if(void 0!==e.setValue){if(void 0!==n)throw new K("INVALID_ARGS",`Flag ${t} does not take a value.`);return{value:e.setValue,consumeNext:!1}}if("boolean"===e.type){if(void 0!==n)throw new K("INVALID_ARGS",`Flag ${t} does not take a value.`);return{value:!0,consumeNext:!1}}if("booleanOrString"===e.type){if(void 0!==n){if(0===n.trim().length)throw new K("INVALID_ARGS",`Flag ${t} requires a non-empty value when provided.`);return{value:n,consumeNext:!1}}return void 0===o||e_(o)||!function(e){let t=e.trim();return!(!t||/^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(t))&&!!(t.startsWith("./")||t.startsWith("../")||t.startsWith("~/")||t.startsWith("/")||t.includes("/")||t.includes("\\"))}(o)?{value:!0,consumeNext:!1}:{value:o,consumeNext:!0}}let r=n??o;if(void 0===r||void 0===n&&e_(r))throw new K("INVALID_ARGS",`Flag ${t} requires a value.`);if("string"===e.type)return{value:r,consumeNext:void 0===n};if("enum"===e.type){if(!e.enumValues?.includes(r))throw new K("INVALID_ARGS",`Invalid ${eU(t)}: ${r}`);return{value:r,consumeNext:void 0===n}}let s=Number(r);if(!Number.isFinite(s)||"number"==typeof e.min&&s<e.min||"number"==typeof e.max&&s>e.max)throw new K("INVALID_ARGS",`Invalid ${eU(t)}: ${r}`);return{value:Math.floor(s),consumeNext:void 0===n}}(m,p,f,e[l+1]);h.consumeNext&&(l+=1);let g=t[m.key];if(m.multiple){let e=Array.isArray(g)?[...g,h.value]:void 0===g?[h.value]:[g,h.value];t[m.key]=e}else t[m.key]=h.value;r.push({key:m.key,token:p})}return{command:n,positionals:o,flags:t,warnings:[],providedFlags:r}}(t),r=l?.env??process.env,s=l?.cwd??process.cwd(),p=n.command,a=null!==p&&(c={remoteConfig:n.flags.remoteConfig,cwd:s,env:r}).remoteConfig?{...th(M({configPath:c.remoteConfig,cwd:c.cwd,env:c.env}).profile),remoteConfig:c.remoteConfig}:{},I=ep((i=(d={command:n.command,cwd:s,cliFlags:n.flags,env:r}).env??process.env,y=ep({},function(e){let t={};for(let n of e)ep(t,function(e,t){let n,r;if(!o.existsSync(e)){if(t)throw new K("INVALID_ARGS",`Config file not found: ${e}`);return{}}try{n=o.readFileSync(e,"utf8")}catch(t){throw new K("INVALID_ARGS",`Failed to read config file: ${e}`,{cause:t instanceof Error?t.message:String(t)})}try{r=JSON.parse(n)}catch(t){throw new K("INVALID_ARGS",`Invalid JSON in config file: ${e}`,{cause:t instanceof Error?t.message:String(t)})}if(!r||"object"!=typeof r||Array.isArray(r))throw new K("INVALID_ARGS",`Config file must contain a JSON object: ${e}`);return function(e,t){let n={};for(let[o,r]of Object.entries(e)){if("installSource"===o){n.installSource=u(r,t);continue}let e=eC.get(o);if(!e)throw new K("INVALID_ARGS",`Unknown config key "${o}" in ${t}.`);if(!e.config.enabled)throw new K("INVALID_ARGS",`Unsupported config key "${o}" in ${t}.`);n[o]=F(eN(e),r,t,o)}return n}(r,`config file ${e}`)}(n.path,n.required));return t}((f=d.cwd,m=d.cliFlags.config,h=i,(x=m??h.AGENT_DEVICE_CONFIG)?[{path:(g=x,v=f,w=h,ea(g,{cwd:v,env:w})),required:!0}]:[{path:(b=h,e.join(ei("~",{env:b}),".agent-device","config.json")),required:!1},{path:e.resolve(f,"agent-device.json"),required:!1}]))),ep(y,function(e,t){var n,o,r;let s={};for(let a of eS.filter(e=>e.config.enabled&&e.supportsCommand(t))){if("installSource"===a.key)continue;let t=a.env.names.map(t=>({name:t,value:e[t]})).find(e=>"string"==typeof e.value&&e.value.trim().length>0);t&&(s[a.key]=(n=t.value,o=`environment variable ${t.name}`,r=t.name,F(eN(a),n,o,r)))}return s}(i,d.command))),a),C={...function(e,t){let n=t?.strictFlags??!0,o=[...e.warnings],r=ep({json:!1,help:!1,version:!1},t?.defaultFlags??{});ep(r,e.flags);let s=e.providedFlags.filter(t=>!eD(t.key,e.command));if(s.length>0){var a,i;let t=s.map(e=>e.token),l=(a=e.command,i=t,a?1===i.length?`Flag ${i[0]} is not supported for command ${a}.`:`Flags ${i.join(", ")} are not supported for command ${a}.`:1===i.length?`Flag ${i[0]} requires a command that supports it.`:`Flags ${i.join(", ")} require a command that supports them.`);if(n)throw new K("INVALID_ARGS",l);for(let e of(o.push(l),s))delete r[e.key]}for(let t of Object.keys(r))void 0!==r[t]&&(eD(t,e.command)||delete r[t]);if(function(e){if("back"===e.command&&!(new Set(e.providedFlags.filter(e=>"backMode"===e.key).map(e=>e.token)).size<=1))throw new K("INVALID_ARGS","back accepts only one explicit mode flag: use either --in-app or --system.")}(e),E(e.command,r),"batch"===e.command&&1!=+!!r.steps+ +!!r.stepsFile)throw new K("INVALID_ARGS","batch requires exactly one step source: --steps or --steps-file.");return function(e){if(e.flags.help)return e;if("snapshot"===e.command&&e.flags.snapshotDiff){let{snapshotDiff:t,...n}=e.flags;return{command:"diff",positionals:["snapshot",...e.positionals],flags:n,warnings:e.warnings}}return e}({command:e.command,positionals:e.positionals,flags:r,warnings:o})}(n,{strictFlags:l?.strictFlags,defaultFlags:I}),providedFlags:n.providedFlags}}catch(t){Q({level:"error",phase:"cli_parse_failed",data:{error:t instanceof Error?t.message:String(t)}});let e=H(t,{diagnosticId:X().diagnosticId,logPath:Y({force:!0})??void 0});i?eX({success:!1,error:e}):eY(e,{showDetails:a}),process.exit(1);return}for(let e of C.warnings)process.stderr.write(`Warning: ${e}
|
|
482
479
|
`);C.flags.version&&(process.stdout.write(`${s}
|
|
483
480
|
`),process.exit(0));let G="help"===C.command,q=C.flags.help;if(G||q){G&&C.positionals.length>1&&(eY(new K("INVALID_ARGS","help accepts at most one command.")),process.exit(1));let e=G?C.positionals[0]:C.command;e||(process.stdout.write(`${eE()}
|
|
484
481
|
`),process.exit(0));let t=function(e){var t,n;let o,r=(o=ew[e])?`${o.body}
|
|
@@ -497,7 +494,7 @@ Usage:
|
|
|
497
494
|
${c.join("\n\n")}
|
|
498
495
|
`}(eP(e));t&&(process.stdout.write(t),process.exit(0)),eY(new K("INVALID_ARGS",`Unknown command: ${e}`)),process.stdout.write(`${eE()}
|
|
499
496
|
`),process.exit(1)}C.command||(process.stdout.write(`${eE()}
|
|
500
|
-
`),process.exit(1));let{command:z,positionals:J}=C,W=new Set(C.providedFlags.map(e=>e.key));try{U=(R=
|
|
497
|
+
`),process.exit(1));let{command:z,positionals:J}=C,W=new Set(C.providedFlags.map(e=>e.key));try{U=(R=nD({policyOverrides:C.flags,configuredPlatform:C.flags.platform,configuredSession:C.flags.session})).lockPolicy?{...C.flags}:nC(C.flags,{policyOverrides:C.flags,configuredPlatform:C.flags.platform,configuredSession:C.flags.session}),P=y(U.stateDir),O=U.session??"default",I={command:z,explicitFlagKeys:W,stateDir:P.baseDir,session:O,remoteConfig:U.remoteConfig,hasResolvedSession:void 0!==U.session},j=(T="connect"===I.command||"connection"===I.command?null:function(e){let t=e.validateRemoteConfigHash??!0,n=e.remoteConfig?B({configPath:e.remoteConfig,cwd:e.cwd,env:e.env}):void 0,o=to(e)??(e.allowActiveFallback?td({stateDir:e.stateDir}):null);if(!o||n&&o.remoteConfigPath!==n)return null;if(t&&ti(o.remoteConfigPath)!==o.remoteConfigHash)throw new K("INVALID_ARGS","Active remote connection config changed. Run agent-device connect --force to refresh it.",{remoteConfig:o.remoteConfigPath});let r=function(e,t){try{return M({configPath:e.remoteConfigPath,cwd:t.cwd,env:t.env}).profile}catch(e){if(!1===t.validateRemoteConfigHash)return{};throw e}}(o,e);return{runtime:o.runtime,flags:{...r,remoteConfig:o.remoteConfigPath,daemonBaseUrl:o.daemon?.baseUrl??r.daemonBaseUrl,daemonTransport:o.daemon?.transport??r.daemonTransport,daemonServerMode:o.daemon?.serverMode??r.daemonServerMode,tenant:o.tenant,sessionIsolation:"tenant",runId:o.runId,leaseId:o.leaseId,leaseBackend:o.leaseBackend,session:o.session,platform:o.platform??r.platform,target:o.target??r.target}}}({stateDir:I.stateDir,session:I.session,remoteConfig:I.remoteConfig,cwd:process.cwd(),env:process.env,allowActiveFallback:!I.explicitFlagKeys.has("session")&&(!I.remoteConfig||"disconnect"===I.command||!I.hasResolvedSession),validateRemoteConfigHash:"disconnect"!==I.command}))?function(e,t,n){let o={...e};for(let[e,r]of Object.entries(t))void 0!==r&&(n.has(e)||(o[e]=r));return o}(U,T.flags,W):U}catch(t){let e=H(V(t),{diagnosticId:X().diagnosticId,logPath:Y({force:!0})??void 0});C.flags.json?eX({success:!1,error:e}):eY(e,{showDetails:C.flags.verbose}),process.exit(1);return}let Z=null;try{let e;if("react-devtools"===z){let e=await nS(J,{flags:j,stateDir:P.baseDir,session:j.session??O,cwd:process.cwd(),env:process.env});process.exit(e);return}eu({command:z,currentVersion:s,stateDir:P.baseDir,flags:j});let t=T?.runtime,a=(e,t)=>({session:e.session??O,requestId:r,stateDir:e.stateDir,daemonBaseUrl:e.daemonBaseUrl,daemonAuthToken:e.daemonAuthToken,daemonTransport:e.daemonTransport,daemonServerMode:e.daemonServerMode,tenant:e.tenant,sessionIsolation:e.sessionIsolation,runId:e.runId,leaseId:e.leaseId,leaseBackend:e.leaseBackend,runtime:t,lockPolicy:R.lockPolicy,lockPlatform:R.defaultPlatform,cwd:process.cwd(),debug:!!e.verbose});if("batch"===z){if(J.length>0)throw new K("INVALID_ARGS","batch does not accept positional arguments.");e=function(e){let t,n,r,s="";if(e.steps)s=e.steps;else if(e.stepsFile)try{s=o.readFileSync(e.stepsFile,"utf8")}catch(n){let t=n instanceof Error?n.message:String(n);throw new K("INVALID_ARGS",`Failed to read --steps-file ${e.stepsFile}: ${t}`)}var a,i=s;try{r=JSON.parse(i)}catch{throw new K("INVALID_ARGS","Batch steps must be valid JSON.")}if(!Array.isArray(r)||0===r.length)throw new K("INVALID_ARGS","Batch steps must be a non-empty JSON array.");return a=r,t=!1,n=a.map((e,n)=>{var o,r,s,a,i,l;let c;if(o=e,null!==o&&"object"==typeof o&&!Array.isArray(o)&&"input"in o&&!("positionals"in o)&&!("flags"in o))return e;let d=function(e,t){if(!e||"object"!=typeof e||Array.isArray(e))throw new K("INVALID_ARGS",`Invalid batch step ${t}.`);var n=e,o=t;let r=Object.keys(n).filter(e=>!["command","positionals","flags","runtime"].includes(e));if(r.length>0)throw new K("INVALID_ARGS",`Batch step ${o} has unknown legacy field(s): ${r.join(", ")}.`);let s=function(e,t){let n="string"==typeof e?e.trim().toLowerCase():"";if(!n)throw new K("INVALID_ARGS",`Batch step ${t} requires command.`);if(er(n))return n;throw new K("INVALID_ARGS",`Batch step ${t} command is not available through command batch: ${String(e)}`)}(e.command,t),a=function(e,t){if(void 0!==e){if(!Array.isArray(e)||e.some(e=>"string"!=typeof e))throw new K("INVALID_ARGS",`Batch step ${t} positionals must contain only strings.`);return e}}(e.positionals,t),i=function(e,t){if(void 0!==e){if(!e||"object"!=typeof e||Array.isArray(e))throw new K("INVALID_ARGS",`Batch step ${t} flags must be an object.`);return e}}(e.flags,t);return{command:s,...void 0===a?{}:{positionals:a},...void 0===i?{}:{flags:i},...void 0===e.runtime?{}:{runtime:e.runtime}}}(e,n+1);return t=!0,c=(s=(r=d).command,a=r.positionals??[],l=r.flags,i={json:!1,help:!1,version:!1,...l},nl[s](a,i)),{command:r.command,input:c,...void 0===r.runtime?{}:{runtime:r.runtime}}}),t&&process.stderr.write('Warning: batch steps using positionals/flags are deprecated and will be removed in the next major version. Use {"command":"...","input":{...}} steps instead.\n'),n}(U)}if(x=z,"auth"!==x&&"connection"!==x&&(j=(await tD({command:z,flags:j,stateDir:P.baseDir,env:process.env})).flags),j.remoteConfig&&(A=z,!nU.has(A))){let o=ec(a(j,t),{transport:n.sendToDaemon}),r=await tw({command:z,flags:j,client:o,runtime:t,batchSteps:e,forceRuntimePrepare:function(e){for(let t of nR)if(e.has(t))return!0;return!1}(W)});j=r.flags,t=r.runtime}$={command:z,flags:j,runtime:t,explicitFlagKeys:W,hadConnectionDefaults:!!T},!("open"===$.command&&!$.runtime&&!$.flags.bundleUrl&&!$.flags.metroHost&&!$.flags.metroPort&&!$.flags.remoteConfig&&!$.hadConnectionDefaults&&((k=$.explicitFlagKeys).has("daemonBaseUrl")||k.has("daemonTransport")||k.has("tenant")||k.has("sessionIsolation")||k.has("runId")||k.has("leaseId")||k.has("leaseBackend")))||process.stderr.write("Warning: open is using explicit remote daemon or tenant flags without saved Metro runtime hints. React Native apps may launch without bundle/runtime hints; prefer connect --remote-config <path> first or pass --remote-config <path> on this command.\n");let i=j.daemonBaseUrl;Z=!j.verbose||j.json||i?null:function(e){try{let t=o.existsSync(e)?o.statSync(e).size:0,n=!1,r=setInterval(()=>{if(!n&&o.existsSync(e))try{let n=o.statSync(e);if(n.size<t&&(t=0),n.size<=t)return;let r=o.openSync(e,"r");try{let e=Buffer.alloc(n.size-t);o.readSync(r,e,0,e.length,t),t=n.size,e.length>0&&process.stdout.write(e.toString("utf8"))}finally{o.closeSync(r)}}catch{}},200);return()=>{n=!0,clearInterval(r)}}catch{return null}}(P.logPath);let l=ec(a(j,t),{transport:function(e){let{command:t,flags:n,transport:o}=e;return"test"!==t||n.json?o:async e=>await o({...e,meta:{...e.meta,requestProgress:"replay-test"}})}({command:z,flags:j,transport:n.sendToDaemon})});if("batch"===z){if(!e)throw new K("INVALID_ARGS","batch requires --steps or --steps-file.");let t=e.map((e,t)=>({...e,input:R.lockPolicy&&void 0===U.platform?{...e.input}:nC(e.input,{policyOverrides:j,configuredPlatform:j.platform,configuredSession:j.session,inheritedPlatform:j.platform})}));if(await nA({command:z,positionals:J,flags:{...j,batchSteps:t},client:l}))return}else if("runtime"===z)throw new K("INVALID_ARGS","runtime command was removed. Use connect --remote-config <path> for remote runs, or metro prepare --remote-config <path> for inspection.");else if(await nA({command:z,positionals:J,flags:j,client:l}))return;throw new K("INVALID_ARGS",`Unknown command: ${z}`)}catch(n){let e=V(n),t=H(e,{diagnosticId:X().diagnosticId,logPath:Y({force:!0})??void 0});if("close"===z&&"COMMAND_FAILED"===(S=e).code&&(S.details?.kind==="daemon_startup_failed"||S.message.toLowerCase().includes("failed to start daemon")&&("string"==typeof S.details?.infoPath||"string"==typeof S.details?.lockPath))){j.json&&eX({success:!0,data:{closed:"session",source:"no-daemon"}});return}if(j.json)eX({success:!1,error:t});else if(eY(t,{showDetails:j.verbose}),j.verbose)try{let e=P.logPath;if(o.existsSync(e)){let t=o.readFileSync(e,"utf8").split("\n"),n=t.slice(Math.max(0,t.length-200)).join("\n");n.trim().length>0&&process.stderr.write(`
|
|
501
498
|
[daemon log]
|
|
502
499
|
${n}
|
|
503
|
-
`)}}catch{}Z&&Z(),process.exit(1)}finally{Z&&Z()}})}n(process.argv[1]??"").href===import.meta.url&&
|
|
500
|
+
`)}}catch{}Z&&Z(),process.exit(1)}finally{Z&&Z()}})}n(process.argv[1]??"").href===import.meta.url&&n_(process.argv.slice(2)).catch(e=>{eY(H(V(e)),{showDetails:!0}),process.exit(1)});export{n_ as runCli};
|
package/dist/src/contracts.d.ts
CHANGED
package/dist/src/contracts.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
function t(t){return{parse:e=>t(e,"$")}}function e(t,e){throw Error(`${t}: ${e}`)}function
|
|
1
|
+
function t(t){return{parse:e=>t(e,"$")}}function e(t,e){throw Error(`${t}: ${e}`)}function a(t,a){return(!t||"object"!=typeof t||Array.isArray(t))&&e(a,"Expected an object"),t}function n(t,a){return"string"!=typeof t&&e(a,"Expected a string"),t}function r(t,a){let r=n(t,a).trim();return r||e(a,"Expected a non-empty string"),r}function i(t,a){return Number.isInteger(t)||e(a,"Expected an integer"),t}function o(t,e,a){let r=t[e];return void 0===r?void 0:n(r,`${a}.${e}`)}function d(t,a,n){let r=t[a];if(void 0!==r)return"boolean"!=typeof r&&e(`${n}.${a}`,"Expected a boolean"),r}function s(t,e,a){let n=t[e];return void 0===n?void 0:i(n,`${a}.${e}`)}function l(t,e,n){let r=t[e];return void 0===r?void 0:a(r,`${n}.${e}`)}function c(t,a,n,r){let i=t[a];if(void 0!==i)return"string"==typeof i&&n.includes(i)||e(`${r}.${a}`,`Expected one of: ${n.join(", ")}`),i}function u(t,e){let r=a(t,e),i={};for(let[t,a]of Object.entries(r))i[t]=n(a,`${e}.${t}`);return i}let m=t((t,e)=>{let n=a(t,e);return{platform:c(n,"platform",["ios","android"],e),metroHost:o(n,"metroHost",e),metroPort:s(n,"metroPort",e),bundleUrl:o(n,"bundleUrl",e),launchUrl:o(n,"launchUrl",e)}}),f=t((t,f)=>{var $,p;let I=a(t,f),h=($=I.positionals,p=`${f}.positionals`,Array.isArray($)||e(p,"Expected an array"),$),v=l(I,"meta",f);return{token:o(I,"token",f),session:o(I,"session",f),command:n(I.command,`${f}.command`),positionals:h.map((t,e)=>n(t,`${f}.positionals[${String(e)}]`)),flags:l(I,"flags",f),runtime:void 0===I.runtime?void 0:m.parse(I.runtime),meta:void 0===v?void 0:{requestId:o(v,"requestId",`${f}.meta`),debug:d(v,"debug",`${f}.meta`),cwd:o(v,"cwd",`${f}.meta`),tenantId:o(v,"tenantId",`${f}.meta`),runId:o(v,"runId",`${f}.meta`),leaseId:o(v,"leaseId",`${f}.meta`),leaseTtlMs:s(v,"leaseTtlMs",`${f}.meta`),leaseBackend:c(v,"leaseBackend",["ios-simulator","ios-instance","android-instance"],`${f}.meta`),sessionIsolation:c(v,"sessionIsolation",["none","tenant"],`${f}.meta`),uploadedArtifactId:o(v,"uploadedArtifactId",`${f}.meta`),clientArtifactPaths:void 0===v.clientArtifactPaths?void 0:u(v.clientArtifactPaths,`${f}.meta.clientArtifactPaths`),installSource:void 0===v.installSource?void 0:function(t,o){let d=a(t,o),s=n(d.kind,`${o}.kind`);if("url"===s){let t=n(d.url,`${o}.url`),e=void 0===d.headers?void 0:u(d.headers,`${o}.headers`);return e?{kind:s,url:t,headers:e}:{kind:s,url:t}}if("path"===s)return{kind:s,path:n(d.path,`${o}.path`)};if("github-actions-artifact"===s){let t,a,n,s,l;return t=r(d.owner,`${o}.owner`),a=r(d.repo,`${o}.repo`),n=void 0!==d.artifactId,s=void 0!==d.runId,l=void 0!==d.artifactName,(n&&(s||l)&&e(`${o}`,"Expected either artifactId or artifactName, not both"),n||!s||l||e(`${o}`,"Expected artifactName when runId is specified"),n||l||e(`${o}`,"Expected artifactId or artifactName"),n)?{kind:"github-actions-artifact",owner:t,repo:a,artifactId:i(d.artifactId,`${o}.artifactId`)}:{kind:"github-actions-artifact",owner:t,repo:a,...s?{runId:i(d.runId,`${o}.runId`)}:{},artifactName:r(d.artifactName,`${o}.artifactName`)}}e(`${o}.kind`,'Expected "url", "path", or "github-actions-artifact"')}(v.installSource,`${f}.meta.installSource`),retainMaterializedPaths:d(v,"retainMaterializedPaths",`${f}.meta`),materializedPathRetentionMs:s(v,"materializedPathRetentionMs",`${f}.meta`),materializationId:o(v,"materializationId",`${f}.meta`),lockPolicy:c(v,"lockPolicy",["reject","strip"],`${f}.meta`),lockPlatform:c(v,"lockPlatform",["ios","macos","android","linux","apple"],`${f}.meta`)}}});function $(t,e){return{token:o(t,"token",e),session:o(t,"session",e),tenantId:o(t,"tenantId",e),tenant:o(t,"tenant",e),runId:o(t,"runId",e)}}let p=t((t,e)=>{let n=a(t,e);return{...$(n,e),ttlMs:s(n,"ttlMs",e),backend:c(n,"backend",["ios-simulator","ios-instance","android-instance"],e)}}),I=t((t,e)=>{let n,r={record:n=a(t,e),leaseId:o(n,"leaseId",e),ttlMs:s(n,"ttlMs",e)};return{...$(r.record,e),leaseId:r.leaseId,ttlMs:r.ttlMs}}),h=t((t,n)=>{let r=a(t,n);return void 0!==r.ttlMs&&e(`${n}.ttlMs`,"Unexpected field"),{...$(r,n),leaseId:o(r,"leaseId",n)}}),v=t((t,n)=>{let r,i=a(t,n);return{jsonrpc:o(i,"jsonrpc",n),id:(null==(r=i.id)||"string"!=typeof r&&"number"!=typeof r&&e(`${n}.id`,"Expected a string, number, or null"),r),method:o(i,"method",n),params:i.params}});export{centerOfRect}from"./4057.js";export{defaultHintForCode,normalizeError}from"./9152.js";export{f as daemonCommandRequestSchema,m as daemonRuntimeSchema,v as jsonRpcRequestSchema,p as leaseAllocateSchema,I as leaseHeartbeatSchema,h as leaseReleaseSchema};
|
package/dist/src/index.d.ts
CHANGED