agent-device 0.16.4 → 0.16.6

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.
Files changed (75) hide show
  1. package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.16.4.apk → agent-device-android-multitouch-helper-0.16.6.apk} +0 -0
  2. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.16.6.apk.sha256 +1 -0
  3. package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.16.4.manifest.json → agent-device-android-multitouch-helper-0.16.6.manifest.json} +4 -4
  4. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.16.6.apk +0 -0
  5. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.16.6.apk.sha256 +1 -0
  6. package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.16.4.manifest.json → agent-device-android-snapshot-helper-0.16.6.manifest.json} +6 -6
  7. package/dist/src/1010.js +1 -0
  8. package/dist/src/1231.js +1 -1
  9. package/dist/src/1352.js +1 -0
  10. package/dist/src/1998.js +1 -0
  11. package/dist/src/208.js +1 -1
  12. package/dist/src/221.js +6 -6
  13. package/dist/src/2415.js +31 -0
  14. package/dist/src/2805.js +1 -0
  15. package/dist/src/5186.js +1 -0
  16. package/dist/src/5310.js +1 -0
  17. package/dist/src/5792.js +1 -0
  18. package/dist/src/6085.js +1 -0
  19. package/dist/src/6629.js +1 -0
  20. package/dist/src/8114.js +4 -0
  21. package/dist/src/8133.js +1 -0
  22. package/dist/src/8502.js +1 -0
  23. package/dist/src/8699.js +1 -0
  24. package/dist/src/8806.js +7 -0
  25. package/dist/src/940.js +1 -1
  26. package/dist/src/9404.js +1 -0
  27. package/dist/src/9471.js +1 -0
  28. package/dist/src/9533.js +1 -0
  29. package/dist/src/9542.js +3 -3
  30. package/dist/src/9639.js +1 -1
  31. package/dist/src/9671.js +1 -0
  32. package/dist/src/android-adb.js +1 -1
  33. package/dist/src/android-snapshot-helper.d.ts +2 -1
  34. package/dist/src/android-snapshot-helper.js +1 -1
  35. package/dist/src/android.js +5 -0
  36. package/dist/src/apple.js +1 -0
  37. package/dist/src/apps.js +13 -0
  38. package/dist/src/args.js +449 -0
  39. package/dist/src/batch.js +1 -1
  40. package/dist/src/cli.js +36 -492
  41. package/dist/src/command-metadata.js +1 -0
  42. package/dist/src/command-surface.js +1 -0
  43. package/dist/src/contracts.d.ts +1 -0
  44. package/dist/src/devices.js +1 -0
  45. package/dist/src/devices~1.js +1 -0
  46. package/dist/src/devices~2.js +1 -0
  47. package/dist/src/find.js +1 -0
  48. package/dist/src/finders.d.ts +1 -0
  49. package/dist/src/generic.js +9 -0
  50. package/dist/src/index.d.ts +12 -0
  51. package/dist/src/input-actions.js +1 -0
  52. package/dist/src/input-actions~1.js +1 -0
  53. package/dist/src/interaction.js +1 -0
  54. package/dist/src/internal/bin.js +5 -2
  55. package/dist/src/internal/daemon.js +1 -100
  56. package/dist/src/lease.js +1 -0
  57. package/dist/src/linux.js +1 -0
  58. package/dist/src/notifications.js +1 -0
  59. package/dist/src/react-native.js +1 -0
  60. package/dist/src/record-trace.js +26 -0
  61. package/dist/src/recording-provider.js +1 -0
  62. package/dist/src/selector-runtime.js +1 -0
  63. package/dist/src/selectors.d.ts +1 -0
  64. package/dist/src/server.js +1 -1
  65. package/dist/src/session.js +29 -0
  66. package/dist/src/snapshot.js +2 -0
  67. package/package.json +4 -1
  68. package/server.json +2 -2
  69. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.16.4.apk.sha256 +0 -1
  70. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.16.4.apk +0 -0
  71. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.16.4.apk.sha256 +0 -1
  72. package/dist/src/1769.js +0 -7
  73. package/dist/src/6277.js +0 -4
  74. package/dist/src/7519.js +0 -1
  75. package/dist/src/89.js +0 -1
@@ -0,0 +1 @@
1
+ import{listMcpExposedCommandNames as t,BATCH_COMMAND_NAMES as e}from"./5792.js";import{readInputRecord as a,selectorSnapshotFields as r,elementTargetField as i,stringSchema as n,stringArrayField as o,jsonSchemaField as s,booleanSchema as p,integerSchema as c,integerField as d,customField as u,assertAllowedKeys as l,booleanField as m,enumField as h,requiredEnum as f,looseObjectField as g,readPoint as y,requiredField as b,pointField as w,readFieldInput as M,stringField as v,interactionTargetField as x,fieldsInputSchema as S,requiredNumber as P,readCommonInput as k,repeatedFields as C,looseObjectSchema as A,numberField as E,optionalInteger as _}from"./9404.js";import{requireCommandDescription as j}from"./5186.js";function I(t,e){return{...t,run:e,invoke:async(a,r)=>await e(a,t.readInput(r))}}function R(t=e){var a;let r={steps:b(u({type:"array",description:"Structured batch steps. Each step uses a command name and the same input object as that command tool.",items:{type:"object",properties:{command:{type:"string",enum:a=t,description:"Command name to run with structured input."},input:{type:"object",additionalProperties:!0,description:"Structured command input for the nested command. Use the matching MCP tool schema for this object."},runtime:{type:"object",additionalProperties:!0,description:"Optional per-step runtime payload."}},required:["command","input"],additionalProperties:!1}},(t,e)=>(function(t,e){if(!Array.isArray(t))throw Error("Expected steps to be an array.");return t.map((t,a)=>{var r,i,n;let o;return r=t,i=a+1,n=e,l(o=function(t,e){if(!t||"object"!=typeof t||Array.isArray(t))throw Error(`Invalid batch step ${e}.`);return t}(r,i),["command","input","runtime"],`Batch step ${i}`),{command:f(o,"command",n),input:function(t,e){let a=t.input;if(!a||"object"!=typeof a||Array.isArray(a))throw Error(`Batch step ${e} input must be an object.`);return a}(o,i),...function(t,e){let a=t.runtime;if(void 0!==a&&(!a||"object"!=typeof a||Array.isArray(a)))throw Error(`Batch step ${e} runtime must be an object.`);return void 0===a?{}:{runtime:a}}(o,i)}})})(t[e],a))),onError:h(["stop"],"Batch failure policy."),maxSteps:d("Maximum number of steps accepted for this batch.",{min:1,max:1e3}),out:v("Optional output path for command artifacts.")};return{name:"batch",description:"Run multiple structured command steps in one daemon request.",inputSchema:S(r),readInput:t=>(function(t,e){let a=M(t,e),r=a.maxSteps??100;if(!Number.isInteger(r)||r<1||r>1e3)throw Error(`Invalid batch maxSteps: ${String(a.maxSteps)}`);if(a.steps.length>r)throw Error(`batch has ${a.steps.length} steps; max allowed is ${r}.`);return{...a}})(t,r)}}function U(t,e,a){return{name:t,description:e,inputSchema:S(a),readInput:t=>M(t,a)}}let O=["app","frontmost-app","desktop","menubar"],B=["start","stop"],$=[F("devices",{}),F("boot",{headless:m("Boot without showing simulator UI when supported.")}),F("apps",{appsFilter:h(["user-installed","all"])}),F("session",{action:h(["list"])}),F("open",{app:v("App name, bundle id, package, or URL."),url:v("Optional URL passed with an app shell."),surface:h(O),activity:v("Android activity name."),launchConsole:v("Launch console mode."),launchArgs:o("Launch arguments forwarded verbatim to the platform launch command."),relaunch:m("Force relaunch."),saveScript:s({oneOf:[p(),n()]}),noRecord:m("Do not record this action.")}),F("close",{app:v("Optional app to close."),shutdown:m("Shutdown the session/device where supported."),saveScript:s({oneOf:[p(),n()]})}),F("install",{app:b(v()),appPath:b(v("Path to app binary."))}),F("reinstall",{app:b(v()),appPath:b(v("Path to app binary."))}),F("install-from-source",{source:b(s(A("Install source object."))),retainPaths:m(),retentionMs:d()}),F("push",{app:b(v()),payload:b(s({oneOf:[n(),A()]}))}),F("trigger-app-event",{event:b(v()),payload:g()}),F("snapshot",{interactiveOnly:m(),compact:m(),depth:d(),scope:v(),raw:m(),forceFull:m()}),F("screenshot",{path:v("Output path."),overlayRefs:m(),fullscreen:m(),maxSize:d(),stabilize:m(),surface:h(O)}),F("diff",{kind:b(s({type:"string",const:"snapshot"})),out:v(),interactiveOnly:m(),compact:m(),depth:d(),scope:v(),raw:m()}),F("wait",{kind:h(["duration","text","ref","selector"]),durationMs:d(),text:v(),ref:v(),selector:v(),timeoutMs:d(),depth:d(),scope:v(),raw:m()}),F("alert",{action:h(["get","accept","dismiss","wait"]),timeoutMs:d()}),F("appstate",{}),F("back",{mode:h(["in-app","system"])}),F("home",{}),F("rotate",{orientation:b(h(["portrait","portrait-upside-down","landscape-left","landscape-right"]))}),F("app-switcher",{}),F("keyboard",{action:h(["status","dismiss"])}),F("clipboard",{action:b(h(["read","write"])),text:v()}),F("react-native",{action:b(h(["dismiss-overlay"]))}),F("replay",{path:b(v()),update:m(),backend:v(),maestro:m(),env:o()}),F("test",{paths:b(o()),update:m(),backend:v(),maestro:m(),env:o(),failFast:m(),timeoutMs:d(),retries:d(),artifactsDir:v(),reportJunit:v()}),F("perf",{}),F("logs",{action:h(["path","start","stop","doctor","mark","clear"]),message:v(),restart:m()}),F("network",{action:h(["dump","log"]),limit:d(),include:h(["summary","headers","body","all"])}),F("record",{action:b(h(B)),path:v(),fps:d(),quality:s(c()),hideTouches:m()}),F("trace",{action:b(h(B)),path:v()}),F("settings",{setting:b(v()),state:b(v()),latitude:E(),longitude:E(),permission:v(),mode:h(["full","limited"])}),F("metro",{action:b(h(["prepare","reload"])),projectRoot:v(),kind:s(n()),publicBaseUrl:v(),proxyBaseUrl:v(),bearerToken:v(),bridgeScope:s({type:"object",additionalProperties:!0}),launchUrl:v(),port:d(),listenHost:v(),statusHost:v(),startupTimeoutMs:d(),probeTimeoutMs:d(),reuseExisting:m(),installDependenciesIfNeeded:m(),runtimeFilePath:v(),logPath:v(),metroHost:v(),metroPort:d(),bundleUrl:v(),timeoutMs:d()})];function F(t,e){return U(t,j(t),e)}let N=["pan","fling","swipe","pinch","rotate","transform"],T=["up","down","left","right"],H=["left","right","left-edge","right-edge"],K={target:b(x()),button:h(["primary","secondary","middle"],"Pointer button for platforms that support mouse buttons."),...r(),...C()},D={target:b(x()),...r(),...C()},L={target:b(x()),text:b(v("Text to enter into the target.")),delayMs:d("Delay between typed characters.",{min:0}),...r()},q={target:b(x()),durationMs:d("Long press duration in milliseconds.",{min:0}),...r()},G={from:b(w("Swipe start point.")),to:b(w("Swipe end point.")),durationMs:d("Swipe duration in milliseconds.",{min:0}),count:d("Number of swipe repetitions.",{min:1}),pauseMs:d("Pause between repeated swipes.",{min:0}),pattern:h(["one-way","ping-pong"])},z={x:b(E("X coordinate.")),y:b(E("Y coordinate."))},J={text:b(v("Text to type.")),delayMs:d("Delay between typed characters.",{min:0})},X={direction:b(h(["up","down","left","right","top","bottom"])),amount:E("Platform scroll amount."),pixels:d("Pixel scroll amount.",{min:0})},Y={format:b(h(["text","attrs"])),target:b(i()),...r()},Q={predicate:b(h(["visible","hidden","exists","editable","selected","text"])),selector:b(v()),value:v(),...r()},V={locator:h(["any","text","label","value","role","id"]),query:b(v()),action:h(["click","focus","exists","getText","getAttrs","wait","fill","type"]),value:v(),timeoutMs:d(),first:m(),last:m(),depth:d(),raw:m()},W={kind:b(h(N,"Gesture variant.")),direction:h(T,"Fling direction."),preset:h(H,"Swipe preset."),origin:w("Gesture origin point."),delta:w("Movement delta for pan or transform gestures."),distance:d("Fling distance.",{min:0}),scale:E("Pinch or transform scale."),degrees:E("Rotation in degrees."),velocity:d("Rotate gesture velocity.",{min:0}),durationMs:d("Gesture duration in milliseconds.",{min:0})},Z=[{name:"click",description:j("click"),inputSchema:S(K),readInput:t=>M(t,K)},{name:"press",description:j("press"),inputSchema:S(D),readInput:t=>M(t,D)},{name:"fill",description:j("fill"),inputSchema:S(L),readInput:t=>M(t,L)},tt("longpress",q),tt("swipe",G),tt("focus",z),tt("type",J),tt("scroll",X),tt("get",Y),tt("is",Q),tt("find",V),{name:"gesture",description:j("gesture"),inputSchema:S(W),readInput:function(t){let e=a(t),r=k(e),i=f(e,"kind",N);return"pan"===i?{...r,kind:i,origin:y(e,"origin"),delta:y(e,"delta"),durationMs:_(e,"durationMs",{min:0})}:"fling"===i?{...r,kind:i,direction:f(e,"direction",T),origin:y(e,"origin"),distance:_(e,"distance",{min:0}),durationMs:_(e,"durationMs",{min:0})}:"swipe"===i?{...r,kind:i,preset:f(e,"preset",H),durationMs:_(e,"durationMs",{min:0})}:"pinch"===i?{...r,kind:i,scale:P(e,"scale"),origin:te(e,"origin")}:"rotate"===i?{...r,kind:i,degrees:P(e,"degrees"),origin:te(e,"origin"),velocity:_(e,"velocity",{min:0})}:{...r,kind:i,origin:y(e,"origin"),delta:y(e,"delta"),scale:P(e,"scale"),degrees:P(e,"degrees"),durationMs:_(e,"durationMs",{min:0})}}}];function tt(t,e){return U(t,j(t),e)}function te(t,e){return void 0===t[e]?void 0:y(t,e)}let ta=new Map([...Z,...$,R(e)].map(t=>[t.name,t]));function tr(){return t().map(t=>{var e;if(!ti(t))throw Error(`Missing command metadata for MCP-exposed command: ${t}`);return e=t,ta.get(e)})}function ti(t){return ta.has(t)}export{$ as clientCommandMetadata,R as createBatchCommandMetadata,I as defineExecutableCommand,Z as interactionCommandMetadata,ti as isCommandName,tr as listMcpCommandMetadata};
@@ -0,0 +1 @@
1
+ import{createBatchCommandMetadata as e,defineExecutableCommand as t,clientCommandMetadata as r,interactionCommandMetadata as a}from"./command-metadata.js";import{commonToClientOptions as n,optionalEnum as i,toClientElementTarget as s,toSelectorSnapshotOptions as o,toRepeatedOptions as c,toClientInteractionTarget as p}from"./9404.js";import{batchCommandNames as d}from"./8699.js";let l=["duration","text","ref","selector"],u=[t(m("devices"),(e,t)=>e.devices.list(t)),t(m("boot"),(e,t)=>e.devices.boot(t)),t(m("apps"),(e,t)=>e.apps.list(t)),t(m("session"),async(e,{action:t,...r})=>({sessions:await e.sessions.list(r)})),t(m("open"),(e,t)=>e.apps.open(t)),t(m("close"),(e,t)=>t.app?e.apps.close(t):e.sessions.close(function(e){let{app:t,...r}=e;return r}(t))),t(m("install"),(e,t)=>e.apps.install(t)),t(m("reinstall"),(e,t)=>e.apps.reinstall(t)),t(m("install-from-source"),(e,t)=>e.apps.installFromSource(t)),t(m("push"),(e,t)=>e.apps.push(t)),t(m("trigger-app-event"),(e,t)=>e.apps.triggerEvent(t)),t(m("snapshot"),(e,t)=>e.capture.snapshot(t)),t(m("screenshot"),(e,t)=>e.capture.screenshot(t)),t(m("diff"),(e,t)=>e.capture.diff(t)),t(m("wait"),(e,t)=>{var r;let a;return e.command.wait((i(r=t,"kind",l),a={...r},delete a.kind,a))}),t(m("alert"),(e,t)=>e.command.alert(t)),t(m("appstate"),(e,t)=>e.command.appState(t)),t(m("back"),(e,t)=>e.command.back(t)),t(m("home"),(e,t)=>e.command.home(t)),t(m("rotate"),(e,t)=>e.command.rotate(t)),t(m("app-switcher"),(e,t)=>e.command.appSwitcher(t)),t(m("keyboard"),(e,t)=>e.command.keyboard(t)),t(m("clipboard"),(e,t)=>e.command.clipboard(t)),t(m("react-native"),(e,t)=>e.command.reactNative(t)),t(m("replay"),(e,t)=>e.replay.run(t)),t(m("test"),(e,t)=>e.replay.test(t)),t(m("perf"),(e,t)=>e.observability.perf(t)),t(m("logs"),(e,t)=>e.observability.logs(t)),t(m("network"),(e,t)=>e.observability.network(t)),t(m("record"),(e,t)=>e.recording.record(t)),t(m("trace"),(e,t)=>e.recording.trace(t)),t(m("settings"),(e,t)=>e.settings.update(t)),t(m("metro"),async(e,t)=>{var r,a,n;return"prepare"===t.action?await e.metro.prepare({projectRoot:(r=t).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 e.metro.reload({metroHost:(n=t).metroHost,metroPort:n.metroPort,bundleUrl:n.bundleUrl,timeoutMs:n.timeoutMs})})];function m(e){let t=r.find(t=>t.name===e);if(!t)throw Error(`Missing client command metadata for ${e}`);return t}function g(e){let t=a.find(t=>t.name===e);if(!t)throw Error(`Missing interaction command metadata for ${e}`);return t}let f=new Map([t(g("click"),(e,t)=>{var r;return e.interactions.click({...n(r=t),...p(r.target),...o(r),...c(r),button:r.button})}),t(g("press"),(e,t)=>{var r;return e.interactions.press({...n(r=t),...p(r.target),...o(r),...c(r)})}),t(g("fill"),(e,t)=>{var r;return e.interactions.fill({...n(r=t),...p(r.target),...o(r),text:r.text,delayMs:r.delayMs})}),t(g("longpress"),(e,t)=>{var r;return e.interactions.longPress({...n(r=t),...p(r.target),...o(r),durationMs:r.durationMs})}),t(g("swipe"),(e,t)=>e.interactions.swipe(t)),t(g("focus"),(e,t)=>e.interactions.focus(t)),t(g("type"),(e,t)=>e.interactions.type(t)),t(g("scroll"),(e,t)=>e.interactions.scroll(t)),t(g("get"),(e,t)=>{var r;return e.interactions.get({...n(r=t),...s(r.target),...o(r),format:r.format})}),t(g("is"),(e,t)=>e.interactions.is(t)),t(g("find"),(e,t)=>e.interactions.find(t)),t(g("gesture"),async(e,t)=>{var r,a,i,s,o,c;switch(t.kind){case"pan":return await e.interactions.pan({...n(r=t),x:r.origin.x,y:r.origin.y,dx:r.delta.x,dy:r.delta.y,durationMs:r.durationMs});case"fling":return await e.interactions.fling({...n(a=t),direction:a.direction,x:a.origin.x,y:a.origin.y,distance:a.distance,durationMs:a.durationMs});case"swipe":return await e.interactions.swipeGesture({...n(i=t),preset:i.preset,durationMs:i.durationMs});case"pinch":return await e.interactions.pinch({...n(s=t),scale:s.scale,x:s.origin?.x,y:s.origin?.y});case"rotate":return await e.interactions.rotateGesture({...n(o=t),degrees:o.degrees,x:o.origin?.x,y:o.origin?.y,velocity:o.velocity});case"transform":return await e.interactions.transformGesture({...n(c=t),x:c.origin.x,y:c.origin.y,dx:c.delta.x,dy:c.delta.y,scale:c.scale,degrees:c.degrees,durationMs:c.durationMs})}}),...u,t(e(d),(e,t)=>{var r;return e.batch.run({...n(r=t),steps:r.steps,onError:r.onError,maxSteps:r.maxSteps,out:r.out})})].map(e=>[e.name,e]));async function y(e,t,r){var a;return await (a=t,f.get(a)).invoke(e,r)}export{y as runCommand};
@@ -171,6 +171,7 @@ declare type RawSnapshotNode = {
171
171
  enabled?: boolean;
172
172
  selected?: boolean;
173
173
  focused?: boolean;
174
+ visibleToUser?: boolean;
174
175
  hittable?: boolean;
175
176
  depth?: number;
176
177
  parentIndex?: number;
@@ -0,0 +1 @@
1
+ import{promises as t}from"node:fs";import e from"node:os";import i from"node:path";import{AppError as r}from"./9152.js";import{buildHostMacDevice as o}from"./devices~2.js";import{runXcrun as n,resolveAppleToolProvider as l,buildSimctlArgs as a}from"./2415.js";import{resolveIosSimulatorDeviceSetPath as u}from"./8806.js";let s=/^(iphone|ipad|ipod|appletv)/i,c=/\b(iphone|ipad|ipod)\b/i,d=/^appletv/i,p=["apple tv","appletv","tvos"],f=/^==\s*(.+?)\s*==$/,m=/^(?<name>.+?)\s+\[(?<id>[^[\]]+)\]\s*$/;function v(t){return(t??"").trim().toLowerCase()}function h(t){return v(t.hardwareProperties?.platform)}function w(t){return t.includes("tvos")}function _(t){let e=v(t);return p.some(t=>e.includes(t))}function S(t){return[t.name??"",t.deviceProperties?.name??"",t.deviceProperties?.deviceType??""]}function P(t){return t.hardwareProperties?.productType??t.deviceProperties?.productType??""}async function b(t={}){let e,i,r=u(t.simulatorSetPath),o=t.target;try{e=await n(a(["list","devices","-j"],{simulatorSetPath:r}))}catch{return null}try{i=JSON.parse(e.stdout)}catch{return null}let l=y(i,r),s=null,c=null,d=null;for(let t of l)o&&t.target!==o||(t.booted&&(s=s??t),"mobile"===t.target&&(c=c??t),d=d??t);return s??c??d}function y(t,e){let i=[];for(let[r,o]of Object.entries(t.devices))if(function(t){let e=v(t);return e.includes("ios")||e.includes("tvos")}(r))for(let t of o)t.isAvailable&&i.push({platform:"ios",id:t.udid,name:t.name,kind:"simulator",target:w(v(r))?"tv":"mobile",booted:"Booted"===t.state,...e?{simulatorSetPath:e}:{}});return i}function C(t,e){let i=new Set(t.map(t=>t.id)),r=[...t];for(let t of e)i.has(t.id)||(i.add(t.id),r.push(t));return r}async function A(){let r=null;try{r=i.join(e.tmpdir(),`agent-device-devicectl-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);let o=await n(["devicectl","list","devices","--json-output",r],{allowFailure:!0,timeoutMs:8e3});if(0!==o.exitCode)return[];let l=await t.readFile(r,"utf8");return function(t){let e=[];for(let i of t.result?.devices??[]){if(!function(t){var e;let i=h(t);return!!(i.includes("ios")||i.includes("tvos"))||(e=P(t),!!s.test(e.trim())||S(t).some(_))}(i))continue;let t=i.hardwareProperties?.udid??i.identifier??"",r=i.name??i.deviceProperties?.name??t;t&&e.push({platform:"ios",id:t,name:r,kind:"device",target:function(t){var e;return w(h(t))?"tv":(e=P(t),d.test(e.trim())||S(t).some(_))?"tv":"mobile"}(i),booted:!0})}return e}(JSON.parse(l))}catch{return[]}finally{r&&await t.rm(r,{force:!0}).catch(()=>{})}}async function N(){try{let t=await n(["xctrace","list","devices"],{allowFailure:!0});if(0!==t.exitCode)return[];return function(t){let e=[],i=null;for(let r of t.split(/\r?\n/)){let t=r.trim();if(!t)continue;let o=f.exec(t);if(o){i=o[1]?.trim()??null;continue}if("Devices"!==i)continue;let n=m.exec(t),l=n?.groups?.id?.trim()??"",a=n?.groups?.name?.trim()??"";if(!l||!a)continue;let u=function(t){return _(t)?"tv":c.test(t.trim())?"mobile":null}(a);u&&e.push({platform:"ios",id:l,name:a,kind:"device",target:u,booted:!0})}return e}(t.stdout)}catch{return[]}}async function O(t={}){if("darwin"!==process.platform)throw new r("UNSUPPORTED_PLATFORM","Apple tools are only available on macOS");if(!await l().whichCommand("xcrun"))throw new r("TOOL_MISSING","xcrun not found in PATH");let e=u(t.simulatorSetPath),i=await n(a(["list","devices","-j"],{simulatorSetPath:e})),s=[];try{let t=JSON.parse(i.stdout);s=y(t,e)}catch(t){throw new r("COMMAND_FAILED","Failed to parse simctl devices JSON",void 0,t)}if(s.push(o()),t.udid&&s.some(e=>"ios"===e.platform&&e.id===t.udid)||e)return s;let[c,d]=await Promise.all([A(),N()]);return s=C(s,c),C(s,d)}export{b as findBootableIosSimulator,O as listAppleDevices};
@@ -0,0 +1 @@
1
+ import{hostname as o}from"node:os";async function e(){return"linux"!==process.platform?[]:[{platform:"linux",id:"local",name:o(),kind:"device",target:"desktop",booted:!0}]}export{e as listLinuxDevices};
@@ -0,0 +1 @@
1
+ import o from"node:os";function e(){return{platform:"macos",id:"host-macos-local",name:o.hostname(),kind:"device",target:"desktop",booted:!0}}async function t(){return[e()]}export{e as buildHostMacDevice,t as listMacosDevices};
@@ -0,0 +1 @@
1
+ import{setSessionSnapshot as t,captureSnapshot as e,dispatchCommand as r,errorResponse as n,ensureDeviceReady as o,getActiveAndroidSnapshotFreshness as a,resolveTargetDevice as i,context_contextFromFlags as s}from"./2415.js";import{findBestMatchesByLocator as l,parseFindArgs as c}from"./7556.js";import{dispatchFindReadOnlyViaRuntime as f,readTextForNode as u}from"./selector-runtime.js";import{PUBLIC_COMMANDS as d}from"./5792.js";import{centerOfRect as _}from"./4057.js";import{resolveActionableTouchResolution as p,resolveActionableTouchNode as g}from"./9533.js";import{sleep as m}from"./4829.js";import{extractNodeText as h}from"./940.js";let A={[d.find]:!0};async function w(r){var s,u;let{req:d,sessionName:m,logPath:A,sessionStore:w,invoke:K}=r,E=d.command;if("find"!==E)return null;let F=d.positionals??[];if(0===F.length)return n("INVALID_ARGS","find requires a locator or text");let{locator:P,query:U,action:L,value:v,timeoutMs:H}=c(F);if(!U)return n("INVALID_ARGS","find requires a value");if(d.flags?.findFirst&&d.flags?.findLast)return n("INVALID_ARGS","find accepts only one of --first or --last");let O=await f({req:d,sessionName:m,logPath:A,sessionStore:w});if(O)return O;let $=w.get(m),b="exists"===(s=L)||"wait"===s||"get_text"===s||"get_attrs"===s;if(!$&&!b)return n("SESSION_NOT_FOUND","No active session. Run open first.");let q=$?.device??await i(d.flags??{});$||await o(q);let G="click"===(u=L)||"focus"===u||"fill"===u||"type"===u,B="role"===P||G?void 0:U,V=0,T=null,j=async()=>{let r=Date.now();if(T&&r-V<750&&!a($))return{nodes:T};let{snapshot:n}=await e({device:q,session:$,flags:{...d.flags,snapshotInteractiveOnly:G,snapshotCompact:G},outPath:d.flags?.out,logPath:A,snapshotScope:B}),o=n.nodes;return V=r,T=o,$&&(t($,n),w.set(m,$)),{nodes:o,truncated:n.truncated,backend:n.backend}},z={req:d,sessionName:m,logPath:A,sessionStore:w,invoke:K,session:$,device:q,command:E,locator:P,query:U};if("wait"===L)return C(z,j,P,U,H);let{nodes:J}=await j(),Q=function(t){let{nodes:e,locator:r,query:o,requiresRect:a,flags:i}=t,s=l(e,r,o,{requireRect:a});if(a&&(s.matches=function(t,e){var r,n;let o=e[0]?.rect;if(!o)return t;let a=t.filter(t=>{if(!t.rect)return!1;let e=_(t.rect);return e.x>=o.x&&e.x<=o.x+o.width&&e.y>=o.y&&e.y<=o.y+o.height});return r=a.length>0?a:t,n=e,r.length<2?r:r.map((t,e)=>{var r,o;let a;return{node:t,index:e,score:(r=t,"semantic-target"===(a=p(o=n,r)).reason&&a.node.rect||"same-rect-descendant"===a.reason&&a.node.rect?4:"hittable-ancestor"===a.reason&&a.node.rect&&!y(a.node,o[0])?2:r.hittable&&r.rect&&!y(r,o[0])?3:+!!r.rect)}}).sort((t,e)=>e.score!==t.score?e.score-t.score:S(t.node)-S(e.node)||t.index-e.index).map(t=>t.node)}(s.matches,e)),a&&s.matches.length>1)if(i?.findFirst)s.matches=[s.matches[0]];else{if(!i?.findLast){var c,f,u;let t;return{ok:!1,response:(c=s.matches,f=r,u=o,t=c.slice(0,8).map(t=>{let e=h(t)||t.label||t.identifier||t.type||"";return`@${t.ref}${e?`(${e})`:""}`}),n("AMBIGUOUS_MATCH",`find matched ${c.length} elements for ${f} "${u}". Use a more specific locator or selector.`,{locator:f,query:u,matches:c.length,candidates:t}))}}s.matches=[s.matches[s.matches.length-1]]}let d=s.matches[0]??null;return d?{ok:!0,node:d}:{ok:!1,response:n("COMMAND_FAILED","find did not match any element")}}({nodes:J,locator:P,query:U,requiresRect:G,flags:d.flags});if(!Q.ok)return Q.response;let W=Q.node,X=G?g(J,W):W,Y=`@${X.ref}`,Z={node:W,resolvedNode:X,ref:Y,nodes:J,actionFlags:{...d.flags??{},noRecord:!0}},tt={exists:()=>N(z),get_text:()=>k(z,Z),get_attrs:()=>x(z,Z),click:()=>I(z,Z),fill:()=>M(z,Z,v),focus:()=>D(z,Z),type:()=>R(z,Z,v)}[L];return tt?tt():null}function S(t){return t.rect?t.rect.width*t.rect.height:1/0}function y(t,e){if(!e?.rect||!t.rect)return!1;let r=t.type?.toLowerCase()??"";return(!!r.includes("application")||!!r.includes("window"))&&t.rect.x===e.rect.x&&t.rect.y===e.rect.y&&t.rect.width===e.rect.width&&t.rect.height===e.rect.height}async function C(t,e,r,o,a){let{req:i,sessionStore:s,session:c,command:f}=t,u=a??1e4,d=Date.now();for(;Date.now()-d<u;){let{nodes:t}=await e();if(l(t,r,o,{requireRect:!1}).matches[0])return c&&s.recordAction(c,{command:f,positionals:i.positionals??[],flags:i.flags??{},result:{found:!0,waitedMs:Date.now()-d}}),{ok:!0,data:{found:!0,waitedMs:Date.now()-d}};await m(300)}return n("COMMAND_FAILED","find wait timed out")}async function N(t){let{req:e,sessionStore:r,session:n,command:o}=t;return n&&r.recordAction(n,{command:o,positionals:e.positionals??[],flags:e.flags??{},result:{found:!0}}),{ok:!0,data:{found:!0}}}async function k(t,e){let{req:r,sessionStore:n,session:o,command:a,device:i,logPath:l}=t,c=await u({device:i,node:e.node,flags:r.flags,appBundleId:o?.appBundleId,traceOutPath:o?.trace?.outPath,surface:o?.surface,contextFromFlags:(t,e,r)=>s(l,t,e,r)});return o&&n.recordAction(o,{command:a,positionals:r.positionals??[],flags:r.flags??{},result:{ref:e.ref,action:"get text",text:c}}),{ok:!0,data:{ref:e.ref,text:c,node:e.node}}}async function x(t,e){let{req:r,sessionStore:n,session:o,command:a}=t;return o&&n.recordAction(o,{command:a,positionals:r.positionals??[],flags:r.flags??{},result:{ref:e.ref,action:"get attrs"}}),{ok:!0,data:{ref:e.ref,node:e.node}}}async function I(t,e){let{req:r,sessionName:n,sessionStore:o,session:a,invoke:i,command:s,locator:l,query:c}=t,f=await i({token:r.token,session:n,command:"click",positionals:[e.ref],flags:e.actionFlags});if(!f.ok)return f;let u=e.resolvedNode.rect?_(e.resolvedNode.rect):e.node.rect?_(e.node.rect):null,d={ref:e.ref,locator:l,query:c};return u&&(d.x=u.x,d.y=u.y),a&&o.recordAction(a,{command:s,positionals:r.positionals??[],flags:r.flags??{},result:{ref:e.ref,action:"click",locator:l,query:c}}),{ok:!0,data:d}}async function M(t,e,r){let{req:o,sessionName:a,sessionStore:i,session:s,invoke:l,command:c}=t;if(!r)return n("INVALID_ARGS","find fill requires text");let f=await l({token:o.token,session:a,command:"fill",positionals:[e.ref,r],flags:e.actionFlags});return f.ok&&s&&i.recordAction(s,{command:c,positionals:o.positionals??[],flags:o.flags??{},result:{ref:e.ref,action:"fill"}}),f}async function D(t,e){let r=await K(t,e);return r.ok&&E(t,e,"focus"),r}async function R(t,e,o){let{req:a,device:i,logPath:l,session:c}=t;if(!o)return n("INVALID_ARGS","find type requires text");let f=await K(t,e);if(!f.ok)return f;let u=await r(i,"type",[o],a.flags?.out,{...s(l,a.flags,c?.appBundleId,c?.trace?.outPath)});return E(t,e,"type"),{ok:!0,data:u??{ref:e.ref}}}async function K(t,e){let{req:o,device:a,logPath:i,session:l}=t,c=e.node.rect?_(e.node.rect):null;return c?{ok:!0,data:await r(a,"focus",[String(c.x),String(c.y)],o.flags?.out,{...s(i,o.flags,l?.appBundleId,l?.trace?.outPath)})??{ref:e.ref}}:n("COMMAND_FAILED","matched element has no bounds")}function E(t,e,r){let{req:n,sessionStore:o,session:a,command:i}=t;a&&o.recordAction(a,{command:i,positionals:n.positionals??[],flags:n.flags??{},result:{ref:e.ref,action:r}})}export{parseFindArgs}from"./7556.js";export{A as FIND_COMMAND_HANDLERS,w as handleFindCommands};
@@ -54,6 +54,7 @@ declare type RawSnapshotNode = {
54
54
  enabled?: boolean;
55
55
  selected?: boolean;
56
56
  focused?: boolean;
57
+ visibleToUser?: boolean;
57
58
  hittable?: boolean;
58
59
  depth?: number;
59
60
  parentIndex?: number;
@@ -0,0 +1,9 @@
1
+ import t from"node:fs";import e from"node:path";import{AppError as s}from"./9152.js";import{runCliCommandWithOutput as r,printJson as i,writeCommandOutput as a}from"./cli.js";import{readCommandMessage as o}from"./1998.js";function n(t){var e;let s=t.attempts>1?` after ${t.attempts} attempts`:"",r=t.durationMs>0?` (${t.durationMs}ms)`:"";for(let i of(process.stdout.write(`FAIL ${t.file}${s}${r}
2
+ `),process.stdout.write(` ${t.error?.message??"Unknown test failure"}
3
+ `),e=t,[e.error?.hint?`hint: ${e.error.hint}`:"",e.artifactsDir?`artifacts: ${e.artifactsDir}`:"",e.error?.logPath?`log: ${e.error.logPath}`:"",e.error?.diagnosticId?`diagnostic: ${e.error.diagnosticId}`:""].filter(Boolean)))process.stdout.write(` ${i}
4
+ `)}function u(t){return"passed"===t.status&&t.attempts>1}function l(t,e,s={}){s.includeMessage&&t.push(`errorMessage: ${e.message}`),e.hint&&t.push(`hint: ${e.hint}`),e.diagnosticId&&t.push(`diagnosticId: ${e.diagnosticId}`),e.logPath&&t.push(`logPath: ${e.logPath}`),!1!==s.includeDetails&&d(t,e,s.detailsIndent)}function d(t,e,s){let r=e.details?JSON.stringify(e.details,null,s):void 0;r&&t.push(`details: ${r}`)}function f(t,e){e&&t.push(e)}function p(t){return(Math.max(0,t)/1e3).toFixed(3)}function c(t){return t.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;").replaceAll("'","&apos;")}async function m({command:$,positionals:h,flags:g,client:M}){var v,y,_,w,A;"test"===$&&(({json:g.json}).json||process.stderr.write("Running replay suite...\n"));let{result:D,cliOutput:S}=await r({client:M,command:$,positionals:h,flags:g});if(S){v=g,y=S,!v.json&&y.stderr&&process.stderr.write(y.stderr),a(v,v.json?y.jsonData??y.data:y.data,()=>y.text)}else{let r=(_=$,w=g,A=D,"test"===_?function(r){let{suite:a,json:o,verbose:m,reportJunit:$}=r;return($&&function(r,i){let a=e.dirname(r);try{t.mkdirSync(a,{recursive:!0}),t.writeFileSync(r,function(t){let s=['<?xml version="1.0" encoding="UTF-8"?>',"<testsuites>",` <testsuite name="agent-device replay suite" tests="${t.total}" failures="${t.failed}" skipped="${t.skipped}" time="${p(t.durationMs)}">`];for(let r of t.tests)s.push(...function(t){let s=c(e.basename(t.file)),r=c("."===e.dirname(t.file)?t.file:e.dirname(t.file)),i=c(t.file),a=p(t.durationMs),o=[` <testcase classname="${r}" name="${s}" file="${i}" time="${a}">`];"failed"===t.status?o.push(` <failure message="${c(t.error.message)}">${c(function(t){let e=[t.error.message];return l(e,t.error,{includeDetails:!1}),t.artifactsDir&&e.push(`artifactsDir: ${t.artifactsDir}`),d(e,t.error,2),e.join("\n")}(t))}</failure>`):"skipped"===t.status&&o.push(` <skipped message="${c(t.message)}" />`);let n=function(t){let e=[`status: ${t.status}`,`durationMs: ${t.durationMs}`];return function(t,e){var s,r;f(t,"attempts"in e?`attempts: ${e.attempts}`:void 0),f(t,"session"in e?`session: ${e.session}`:void 0),f(t,"replayed"in e?`replayed: ${e.replayed}`:void 0),f(t,"healed"in e?`healed: ${e.healed}`:void 0),f(t,"artifactsDir"in e&&e.artifactsDir?`artifactsDir: ${e.artifactsDir}`:void 0),"failed"===e.status&&(s=t,r=e,s.push(`errorCode: ${r.error.code}`),l(s,r.error,{includeMessage:!0})),f(t,u(e)?"flaky: true":void 0)}(e,t),e.join("\n")}(t);return n&&o.push(` <system-out>${c(n)}</system-out>`),o.push(" </testcase>"),o}(r));return s.push(" </testsuite>"),s.push("</testsuites>"),`${s.join("\n")}
5
+ `}(i),"utf8")}catch(e){let t=e instanceof Error?e.message:String(e);throw new s("COMMAND_FAILED",`Failed to write JUnit report to ${r}: ${t}`)}}($,a),o)?(i({success:!0,data:a}),+(a.failed>0)):function(t,e={}){let s=t.tests.filter(u);if(e.verbose)for(let e of t.tests)!function(t){var e;if("failed"===t.status)return n(t);let s="passed"===(e=t).status?e.attempts>1?"FLAKY":"PASS":"skipped"===e.status?"SKIP":"INFO",r="attempts"in t&&t.attempts>1?` after ${t.attempts} attempts`:"",i=t.durationMs>0?` (${t.durationMs}ms)`:"";process.stdout.write(`${s} ${t.file}${r}${i}
6
+ `),"skipped"===t.status&&process.stdout.write(` ${t.message??"skipped"}
7
+ `)}(e);else{for(let e of t.failures)n(e);for(let t of s)!function(t){let e=t.durationMs>0?` (${t.durationMs}ms)`:"";process.stdout.write(`FLAKY ${t.file} after ${t.attempts} attempts${e}
8
+ `)}(t)}let r="number"==typeof t.durationMs?t.durationMs:void 0,i=s.length>0?`, ${s.length} flaky`:"";return process.stdout.write(`Test summary: ${t.passed} passed, ${t.failed} failed${i}${void 0!==r?` in ${r}ms`:""}
9
+ `),+(t.failed>0)}(a,{verbose:m})}({suite:A,verbose:w.verbose,json:w.json,reportJunit:w.reportJunit}):(a(w,A,()=>o(A)),0));0!==r&&process.exit(r)}return!0}export{m as runGenericClientBackedCommand};
@@ -46,6 +46,7 @@ export declare type AgentDeviceClient = {
46
46
  swipe: (options: SwipeOptions) => Promise<CommandRequestResult>;
47
47
  pan: (options: PanOptions) => Promise<CommandRequestResult>;
48
48
  fling: (options: FlingOptions) => Promise<CommandRequestResult>;
49
+ swipeGesture: (options: SwipeGestureOptions) => Promise<CommandRequestResult>;
49
50
  focus: (options: FocusOptions_2) => Promise<CommandRequestResult>;
50
51
  type: (options: TypeTextOptions) => Promise<CommandRequestResult>;
51
52
  fill: (options: FillOptions) => Promise<CommandRequestResult>;
@@ -302,6 +303,7 @@ export declare type AppOpenOptions = AgentDeviceRequestOverrides & AgentDeviceSe
302
303
  surface?: 'app' | 'frontmost-app' | 'desktop' | 'menubar';
303
304
  activity?: string;
304
305
  launchConsole?: string;
306
+ launchArgs?: string[];
305
307
  relaunch?: boolean;
306
308
  saveScript?: boolean | string;
307
309
  noRecord?: boolean;
@@ -880,6 +882,7 @@ declare type RawSnapshotNode = {
880
882
  enabled?: boolean;
881
883
  selected?: boolean;
882
884
  focused?: boolean;
885
+ visibleToUser?: boolean;
883
886
  hittable?: boolean;
884
887
  depth?: number;
885
888
  parentIndex?: number;
@@ -1044,6 +1047,10 @@ declare type SessionRuntimeHints = {
1044
1047
  };
1045
1048
 
1046
1049
  export declare type SettingsUpdateOptions = (ClientCommandBaseOptions & {
1050
+ setting: 'clear-app-state';
1051
+ state: 'clear';
1052
+ app?: string;
1053
+ }) | (ClientCommandBaseOptions & {
1047
1054
  setting: 'wifi' | 'airplane' | 'location';
1048
1055
  state: 'on' | 'off';
1049
1056
  }) | (ClientCommandBaseOptions & {
@@ -1098,6 +1105,11 @@ export declare type StartupPerfSample = {
1098
1105
  appBundleId?: string;
1099
1106
  };
1100
1107
 
1108
+ declare type SwipeGestureOptions = ClientCommandBaseOptions & {
1109
+ preset: 'left' | 'right' | 'left-edge' | 'right-edge';
1110
+ durationMs?: number;
1111
+ };
1112
+
1101
1113
  export declare type SwipeOptions = ClientCommandBaseOptions & {
1102
1114
  from: {
1103
1115
  x: number;
@@ -0,0 +1 @@
1
+ import{emitDiagnostic as t}from"./7599.js";import{runAndroidAdb as e}from"./8806.js";import{getAndroidKeyboardState as n,isAndroidInputMethodOwnedNode as r}from"./8133.js";import{captureAndroidUiHierarchyXml as a}from"./2415.js";import{androidUiNodes as i}from"./221.js";import{AppError as o}from"./9152.js";import{buildScrollGesturePlan as l}from"./9533.js";import{resolveAndroidTextInjector as u}from"./9639.js";import{sleep as c}from"./4829.js";function s(t){var e;return!!t&&(!!t.password||!!(e=t.text)&&Array.from(e).every(f))}function d(t){if(!t)return null;let e=s(t);return{...t,text:e?null:t.text,...e?{textRedacted:!0}:{}}}function f(t){return"•"===t||"*"===t||"●"===t}async function p(t,e,n,r){let a=null,i=null,o=await y(t);for(let l of[0,150,350]){l>0&&await c(l);let u=await g(t,e,n,r,o);if(a=u,"ime_capture"===u.reason)return u;i=u.ok?u:null}return i??a??{ok:!1,actual:null,reason:"text_mismatch",targetInput:null,actualInput:null}}async function h(t,e,n){var r,i,o;return r=await a(t),i=e,o=n,w(r,i,o).actualInput?.text??null}async function g(t,e,n,r,i){return function(t,e,n,r,a={}){var i,o;let l,u=w(t,e,n,a);return!function(t){let{targetInput:e,actualInput:n}=t;return!!e&&!!n&&n!==e&&n.inputMethodOwned&&!e.inputMethodOwned}(u)?function(t,e){let n=t.actualInput;if(!n||!s(n))return null;let r=n.text??null,a=Array.from(r??"").length,i=Array.from(e).length,o=null!==r&&a>0&&i>0&&a===i;return{ok:o,actual:r,reason:o?void 0:"masked_unverified",masked:!0,targetInput:t.targetInput,actualInput:n}}(u,r)??(i=u,o=r,{ok:function(t,e){if(t===e)return!0;let n=m(t),r=m(e);return!!n&&!!r&&!!(n===r||function(t,e){if(t.length!==e.length||0===t.length||t.slice(1)!==e.slice(1))return!1;let n=t[0],r=e[0];return!!n&&!!r&&r.toLowerCase()===r&&n===r.toUpperCase()}(n,r))}(l=i.actualInput?.text??null,o),actual:l,reason:"text_mismatch",targetInput:i.targetInput,actualInput:i.actualInput}):{ok:!1,actual:u.actualInput?.text??null,reason:"ime_capture",targetInput:u.targetInput,actualInput:u.actualInput}}(await a(t),e,n,r,i)}function w(t,e,n,a={}){var o;let l,u={focusedEdit:null,editAtPoint:null,anyAtPoint:null};for(let o of i(t)){let t=function(t,e){if(!t.rect)return null;let n=t.text??"",a=Math.max(1,t.rect.width*t.rect.height);return{text:n||null,className:t.className,resourceId:t.resourceId,packageName:t.packageName,rect:t.rect,focused:t.focused??!1,password:!0===t.password,inputMethodOwned:r({packageName:t.packageName,resourceId:t.resourceId,activeInputMethodPackage:e.activeInputMethodPackage}),area:a,editText:function(t){let e=t.toLowerCase();return e.includes("edittext")||e.includes("textfield")}(t.className??"")}}(o,a);t&&function(t,e,n,r){var a,i,o;let l=(a=e.rect,i=n,o=r,i>=a.x&&i<=a.x+a.width&&o>=a.y&&o<=a.y+a.height);if(l&&e.editText&&(t.editAtPoint=_(t.editAtPoint,e)),e.focused&&e.editText){t.focusedEdit=_(t.focusedEdit,e);return}l&&e.text&&(t.anyAtPoint=_(t.anyAtPoint,e))}(u,t,e,n)}return{targetInput:l=(o=u).editAtPoint??o.anyAtPoint,actualInput:(o.focusedEdit?.text?o.focusedEdit:null)??l}}function m(t){return(t??"").replace(/\s+/g," ").trim()}async function y(e){try{return{activeInputMethodPackage:(await n(e)).inputMethodPackage}}catch(e){return t({level:"warn",phase:"android_fill_verification_input_method_probe_failed",data:{error:e instanceof Error?e.message:String(e)}}),{}}}function _(t,e){return t&&t.area<e.area?t:e}async function A(t,n,r){await e(t,["shell","input","tap",String(n),String(r)])}async function x(t,n,r,a,i,o=250){await e(t,["shell","input","swipe",String(n),String(r),String(a),String(i),String(o)])}async function I(t){await e(t,["shell","input","keyevent","4"])}async function S(t){await e(t,["shell","input","keyevent","3"])}async function M(t){await e(t,["shell","input","keyevent","ENTER"])}async function k(t,n){let r=function(t){switch(t){case"portrait":return"0";case"landscape-left":return"1";case"portrait-upside-down":return"2";case"landscape-right":return"3";default:throw new o("INVALID_ARGS",`Unsupported Android rotation: ${t}`)}}(n);await e(t,["shell","settings","put","system","accelerometer_rotation","0"]),await e(t,["shell","settings","put","system","user_rotation",r])}async function E(t){await e(t,["shell","input","keyevent","187"])}async function v(t,n,r,a=800){await e(t,["shell","input","swipe",String(n),String(r),String(n),String(r),String(a)])}async function C(t,e,n=0){let r=u(t);if(r){await r({action:"type",text:e,delayMs:n}),F("type","provider-native",e);return}(H(e),await D(t,"type"),n>0&&Array.from(e).length>1)?await U(t,{action:"type",text:e,chunkSize:1,delayMs:n}):await U(t,{action:"type",text:e,chunkSize:L,delayMs:0})}async function P(t,e,n){await A(t,e,n)}async function N(t,e,n,r,a=0){let i=u(t);if(i){await i({action:"fill",target:{x:e,y:n},text:r,delayMs:a}),F("fill","provider-native",r);let o=await p(t,e,n,r);if(o.ok)return;b(r,o)}H(r);let o=Array.from(r).length,l=null;for(let i of[{clearPadding:12,minClear:8,maxClear:48,chunkSize:a>0?1:L,inputDelayMs:a},{clearPadding:24,minClear:16,maxClear:96,chunkSize:a>0?1:4,inputDelayMs:a>0?a:15}]){var c,s;await P(t,e,n),await D(t,"fill");let a=(c=o+i.clearPadding,s=i.minClear,Math.max(s,Math.min(i.maxClear,c)));await Y(t,a),await U(t,{action:"fill",text:r,chunkSize:i.chunkSize,delayMs:i.inputDelayMs});let u=await p(t,e,n,r);if(l=u,u.ok)return;"ime_capture"===u.reason&&b(r,u)}b(r,l)}function b(t,e){let n;throw new o("COMMAND_FAILED",e?.reason==="ime_capture"?"Android fill input was captured by the active keyboard instead of the app field":e?.reason==="masked_unverified"?"Android fill verification could not confirm masked text value":"Android fill verification failed",(n=function(t,e){var n;if(!e)return{expected:t,actual:null,failureReason:"text_mismatch",targetInput:null,actualInput:null};let r=!0===(n=e).masked||s(n.targetInput)||s(n.actualInput),a={failureReason:e.reason??"text_mismatch",targetInput:d(e.targetInput),actualInput:d(e.actualInput)};return r?{...a,expectedLength:Array.from(t).length,actual:null,masked:!0,actualLength:Array.from(e.actual??"").length}:{...a,expected:t,actual:e.actual}}(t,e),e?.reason==="ime_capture"&&(n.hint="The focused input belongs to the Android keyboard/IME, not the app field. Disable handwriting/stylus input or switch to a standard IME, then retry fill."),n))}async function K(t,n,r){let a=await O(t),i=l({direction:n,amount:r?.amount,pixels:r?.pixels,referenceWidth:a.width,referenceHeight:a.height});return await e(t,["shell","input","swipe",String(i.x1),String(i.y1),String(i.x2),String(i.y2),"300"]),i}async function D(e,r){let a;try{a=await n(e)}catch(e){t({level:"warn",phase:"android_input_ownership_probe_failed",data:{action:r,error:e instanceof Error?e.message:String(e)}});return}if("ime"===a.inputOwner)throw new o("COMMAND_FAILED","KEYBOARD_OVERLAY_BLOCKING: Android text input is blocked because the focused input belongs to the active keyboard/IME.",{failureReason:"ime_capture",action:r,inputOwner:a.inputOwner,inputType:a.inputType,type:a.type,inputMethodPackage:a.inputMethodPackage,focusedPackage:a.focusedPackage,focusedResourceId:a.focusedResourceId,nextAction:"Focused input appears to be owned by the keyboard/IME; dismiss or change the IME before retrying text entry."})}async function R(t){let n=(await e(t,["shell","wm","size"])).stdout.match(/Physical size:\s*(\d+)x(\d+)/);if(!n)throw new o("COMMAND_FAILED","Unable to read screen size");return{width:Number(n[1]),height:Number(n[2])}}async function O(e){try{let t=await a(e),n=function(t){let e=null;for(let n of i(t)){let t=n.rect;if(!t||t.width<=0||t.height<=0)continue;let r=t.width*t.height;(!e||r>e.area)&&(e={width:t.x+t.width,height:t.y+t.height,area:r})}return e?{width:e.width,height:e.height}:null}(t);if(n)return n}catch(e){t({level:"warn",phase:"android_gesture_viewport_probe_failed",data:{error:e instanceof Error?e.message:String(e)}})}return await R(e)}let L=8;async function U(t,n){let r=n.text.split("\n");for(let[a,i]of r.entries()){let o=function(t,e){let n=Math.max(1,Math.floor(e)),r=[],a=Array.from(t);for(let t=0;t<a.length;t+=n)r.push(a.slice(t,t+n).join(""));return r.length>0?r:[""]}(i,n.chunkSize);for(let[e,i]of o.entries())await z(t,i),n.delayMs>0&&(e+1<o.length||a+1<r.length)&&await c(n.delayMs);a+1<r.length&&await e(t,["shell","input","keyevent","ENTER"])}F(n.action,"adb-shell",n.text)}async function z(t,n){if(n)try{await e(t,["shell","input","text",n.replace(/ /g,"%s")])}catch(t){if(function(t){if(!(t instanceof o)||"COMMAND_FAILED"!==t.code)return!1;let e=t.details?.stderr,n=("string"==typeof e?e:"").toLowerCase();return!!(n.includes("exception occurred while executing 'text'")||n.includes("nullpointerexception")&&n.includes("inputshellcommand.sendtext"))}(t))throw T(n,t);throw t}}function H(t){if(!function(t){for(let e of t){let t=e.codePointAt(0);if(void 0!==t&&"\n"!==e&&(t<32||t>126))return!1}return!0}(t))throw T(t)}function T(t,e){return new o("COMMAND_FAILED","Android text input requires provider-native text injection for non-ASCII/control characters; the current adb-shell fallback supports ASCII text only.",{backend:"adb-shell",textLength:Array.from(t).length,textPreview:t.slice(0,32)},e instanceof Error?e:void 0)}function F(e,n,r){t({phase:"android_text_injection",data:{action:e,backend:n,textLength:Array.from(r).length}})}async function Y(t,n){let r=Math.max(0,n);await e(t,["shell","input","keyevent","KEYCODE_MOVE_END"],{allowFailure:!0});for(let n=0;n<r;n+=24){let a=Math.min(24,r-n);await e(t,["shell","input","keyevent",...Array(a).fill("KEYCODE_DEL")],{allowFailure:!0})}}export{E as appSwitcherAndroid,I as backAndroid,N as fillAndroid,P as focusAndroid,R as getAndroidScreenSize,S as homeAndroid,v as longPressAndroid,A as pressAndroid,M as pressAndroidEnter,h as readAndroidTextAtPoint,k as rotateAndroid,K as scrollAndroid,x as swipeAndroid,C as typeAndroid};
@@ -0,0 +1 @@
1
+ import{AppError as a}from"./9152.js";import{resolveLinuxToolProvider as t}from"./2415.js";import{sleep as i}from"./4829.js";let o=null;async function n(){let i=t();if(o?.provider===i)return o;let n=process.env.WAYLAND_DISPLAY||"wayland"===process.env.XDG_SESSION_TYPE?"wayland":"x11";if("wayland"===n){if(await i.whichCommand("ydotool"))return o={tool:"ydotool",display:n,provider:i};throw new a("TOOL_MISSING","ydotool is required for input synthesis on Wayland (xdotool does not work on Wayland). Install it via your package manager.")}if(await i.whichCommand("xdotool"))return o={tool:"xdotool",display:n,provider:i};throw new a("TOOL_MISSING","xdotool is required for input synthesis on X11. Install it via your package manager.")}async function e(...a){await t().runCommand("xdotool",a,{allowFailure:!1,timeoutMs:1e4})}async function l(...a){await t().runCommand("ydotool",a,{allowFailure:!1,timeoutMs:1e4})}function u(){return t().input}async function r(a,t){let{tool:i}=await n();"xdotool"===i?await e("mousemove","--sync",String(a),String(t)):await l("mousemove","--absolute","-x",String(a),"-y",String(t))}async function w(a,t){let i=u();if(i)return void await i.key(a,t);let{tool:o}=await n();"xdotool"===o?await e("key","--clearmodifiers",a):await l("key",...t)}async function c(a,t,i,o){await r(a,t);let{tool:u}=await n();"xdotool"===u?await e("click",i):await l("click",o)}async function s(a,t,i,o,n){let e=u();e?await e.click(a,t,i):await c(a,t,o,n)}async function d(a,t){await s(a,t,"primary","1","0xC0")}async function y(a,t){await s(a,t,"secondary","3","0xC1")}async function x(a,t){await s(a,t,"middle","2","0xC2")}async function m(a,t){let i=u();if(i)return void await i.doubleClick(a,t);let{tool:o}=await n();await r(a,t),"xdotool"===o?await e("click","--repeat","2","1"):(await l("click","0xC0"),await l("click","0xC0"))}async function f(a,t,o=800){let w=u();if(w)return void await w.longPress(a,t,o);let{tool:c}=await n();await r(a,t),"xdotool"===c?(await e("mousedown","1"),await i(o),await e("mouseup","1")):(await l("click","--down","0xC0"),await i(o),await l("click","--up","0xC0"))}async function p(a,t){await d(a,t)}async function S(a,t,o,w,c=300){let s=u();if(s)return void await s.drag(a,t,o,w,c);let{tool:d}=await n();await r(a,t),"xdotool"===d?(await e("mousedown","1"),await e("mousemove","--sync",String(o),String(w)),await i(c),await e("mouseup","1")):(await l("click","--down","0xC0"),await l("mousemove","--absolute","-x",String(o),"-y",String(w)),await i(c),await l("click","--up","0xC0"))}async function C(a,t){let i=u();if(i)return void await i.scroll(a,t);let{tool:o}=await n(),r=5;if(t?.pixels!=null?r="xdotool"===o?Math.max(1,Math.round(t.pixels/15)):Math.max(1,Math.round(t.pixels/40)):t?.amount!=null&&(r=Math.max(1,Math.round(5*(t.amount/.6)))),"xdotool"===o)await e("click","--repeat",String(r),"up"===a?"4":"down"===a?"5":"left"===a?"6":"7");else if("up"===a||"down"===a){let t="up"===a?String(-r):String(r);await l("mousemove","--wheel","-y",t)}else{let t="left"===a?String(-r):String(r);await l("mousemove","--wheel","-x",t)}}async function g(a,t=0){let i=u();if(i)return void await i.typeText(a,{delayMs:t});let{tool:o}=await n();if("xdotool"===o){let i=["type"];t>0&&i.push("--delay",String(t)),i.push("--clearmodifiers","--",a),await e(...i)}else await l("type","--",a)}async function k(a,t,o,n=0){await d(a,t),await i(100),await w("ctrl+a",["29:1","30:1","30:0","29:0"]),await i(50),await g(o,n)}export{m as doubleClickLinux,k as fillLinux,p as focusLinux,f as longPressLinux,x as middleClickLinux,d as pressLinux,y as rightClickLinux,C as scrollLinux,w as sendKey,S as swipeLinux,g as typeLinux};
@@ -0,0 +1 @@
1
+ import{__webpack_require__ as e}from"./rslib-runtime.js";import{createDaemonRuntimeSessionStore as t,setSessionSnapshot as r,dispatchCommand as a,getClickButtonValidationError as n,ensureAndroidBlockingSystemDialogReady as s,isCommandSupportedOnDevice as o,buttonTag as i,resolveClickButton as l,errorResponse as c,recoverAndroidBlockingSystemDialog as u,getActiveAndroidSnapshotFreshness as f}from"./2415.js";import{createAgentDevice as d}from"./9533.js";import{asAppError as p,normalizeError as g,AppError as m}from"./9152.js";import{dispatchGetViaRuntime as S,isAndroidEscapeError as _,createDaemonRuntimePolicy as k,assertAndroidPressStayedInApp as h,dispatchIsViaRuntime as y,isDirectIosSelectorFallbackError as w,refSnapshotFlagGuardResponse as b,readSimpleIosSelectorTarget as N}from"./selector-runtime.js";import{readInteractionTargetFromPositionals as v,readFillTargetFromPositionals as x}from"./8502.js";import{interaction_snapshot_captureSnapshotForSession as F,readSnapshotNodesReferenceFrame as P,resolveDirectTouchReferenceFrameSafely as R,buildTouchVisualizationResult as M,finalizeTouchInteraction as O}from"./9471.js";import{emitDiagnostic as C}from"./7599.js";import{PUBLIC_COMMANDS as I}from"./5792.js";import{successText as A}from"./1998.js";var E={};function q(e,t){return"macos"!==e.device.platform||"desktop"!==e.surface&&"menubar"!==e.surface||"menubar"===e.surface&&("click"===t||"press"===t)?null:c("UNSUPPORTED_OPERATION",`${t} is not supported on macOS ${e.surface} sessions yet. Open an app session to act, or use the ${e.surface} surface to inspect.`)}function D(e){let n=e.sessionStore.get(e.sessionName);if(!n)throw new m("SESSION_NOT_FOUND","No active session. Run open first.");return d({backend:function(e){let{req:t,session:r}=e;return{platform:r.device.platform,captureSnapshot:async(a,n)=>({snapshot:await e.captureSnapshotForSession(r,t.flags,e.sessionStore,e.contextFromFlags,{interactiveOnly:n?.interactiveOnly===!0})}),tap:async(n,s)=>U(await a(r.device,"press",[String(s.x),String(s.y)],t.flags?.out,e.contextFromFlags(t.flags,r.appBundleId,r.trace?.outPath))),fill:async(n,s,o)=>U(await a(r.device,"fill",[String(s.x),String(s.y),o],t.flags?.out,e.contextFromFlags(t.flags,r.appBundleId,r.trace?.outPath))),longPress:async(n,s,o)=>U(await a(r.device,"longpress",[String(s.x),String(s.y),...o?.durationMs===void 0?[]:[String(o.durationMs)]],t.flags?.out,e.contextFromFlags(t.flags,r.appBundleId,r.trace?.outPath))),typeText:async(n,s)=>U(await a(r.device,"type",[s],t.flags?.out,e.contextFromFlags(t.flags,r.appBundleId,r.trace?.outPath)))}}({...e,session:n}),...k("interaction commands",{plural:!0}),sessions:t({sessionName:e.sessionName,getSession:()=>n,recordOptions:{includeSnapshot:!0},setRecord:t=>{t.snapshot&&(r(n,t.snapshot),e.sessionStore.set(e.sessionName,n))}})})}function U(e){return e&&"object"==typeof e?e:void 0}function T(e){if(e.length<2)return null;let t=Number(e[0]),r=Number(e[1]);return Number.isFinite(t)&&Number.isFinite(r)?{x:t,y:r}:null}function H(e,t){let r=T(e);if(r)return{ok:!0,target:{kind:"point",x:r.x,y:r.y}};let a=e[0]??"";if(a.startsWith("@"))return{ok:!0,target:{kind:"ref",ref:a,fallbackLabel:v(e).label??""}};let n=e.join(" ").trim();return n?{ok:!0,target:{kind:"selector",selector:n}}:{ok:!1,response:c("INVALID_ARGS",`${t} requires @ref, selector expression, or x y coordinates`)}}function K(e){return"ref"===e.kind?{ref:L(e.target?.kind==="ref"?e.target.ref:void 0),refLabel:e.refLabel,selectorChain:e.selectorChain}:"selector"===e.kind?{selector:e.target?.kind==="selector"?e.target.selector:void 0,selectorChain:e.selectorChain,refLabel:e.refLabel}:{}}function L(e){return e?.startsWith("@")?e.slice(1):e}async function j(e){switch(e.req.command){case"press":return await B(e,"press");case"click":return await B(e,"click");case"longpress":return await B(e,"longpress");case"fill":return await X(e);default:return null}}async function B(e,t){let r,{req:a,sessionName:s,sessionStore:u}=e,f=u.get(s);if(!f)return c("SESSION_NOT_FOUND","No active session. Run open first.");let d="click"===t?"click":t,p="longpress"===t?"longpress":"press",g=q(f,d);if(g)return g;if(!o(p,f.device))return c("UNSUPPORTED_OPERATION",`${p} is not supported on this device`);let m=l(a.flags),S=i(m);if("longpress"!==t&&"primary"!==m){let e=n({commandLabel:d,platform:f.device.platform,button:m,count:a.flags?.count,intervalMs:a.flags?.intervalMs,holdMs:a.flags?.holdMs,jitterPx:a.flags?.jitterPx,doubleTap:a.flags?.doubleTap});if(e)return c(e.code,e.message,e.details)}let _="longpress"===t?function(e){var t,r,a;let n,s=T(e);if(s){return{ok:!0,target:{kind:"point",x:s.x,y:s.y},...void 0===(t=e[2])?{}:{durationMs:Number(t)}}}let o=(n=(r=e).at(-1),r.length>1&&void 0!==(a=n)&&""!==a.trim()&&Number.isFinite(Number(a))?{targetPositionals:r.slice(0,-1),duration:{durationMs:Number(n)}}:{targetPositionals:r,duration:{}}),i=H(o.targetPositionals,"longpress");return i.ok?{ok:!0,target:i.target,...o.duration}:i}(a.positionals??[]):H(a.positionals??[],d);if(!_.ok)return _.response;if("ref"===_.target.kind){let n=e.refSnapshotFlagGuardResponse("longpress"===t?"longpress":"press",a.flags);if(n)return n;r=await J(e,f)}let k=function(e){var t;let{session:r,commandLabel:a,target:n,flags:s}=e;if("click"!==a||"selector"!==n.kind||(t=s,t?.count!==void 0||t?.intervalMs!==void 0||t?.holdMs!==void 0||t?.jitterPx!==void 0||t?.doubleTap!==void 0||t?.clickButton!==void 0&&"primary"!==t.clickButton))return null;let o=N({session:r,selectorExpression:n.selector});return o?{...o,...s?.maestro?.allowNonHittableCoordinateFallback?{allowNonHittableCoordinateFallback:!0}:{}}:null}({session:f,commandLabel:d,target:_.target,flags:a.flags});if(k){let t=await $(e,f,k);if(t)return t}let y="longpress"===t?_.durationMs:void 0;return await z(e,{androidFreshnessBaseline:r,run:async e=>await G({runtime:e,command:t,target:_.target,sessionName:s,requestId:a.meta?.requestId,clickButton:m,flags:a.flags,durationMs:y}),afterRun:async e=>{var t;await h(f,(t=_.target,"point"===t.kind?"coordinate tap":"ref"===e.kind&&e.target?.kind==="ref"?e.target.ref:"selector"===e.kind&&e.target?.kind==="selector"?e.target.selector:"target"))},buildPayloads:async r=>{var a;let n="durationMs"in(a=r)?a.durationMs:void 0,s=await W({params:e,session:f,result:r,extra:"longpress"===t?{...void 0!==n?{durationMs:n}:{},gesture:"longpress"}:S});return{result:s,responseData:s}}})}async function G(e){let{runtime:t,command:r,target:a,sessionName:n,requestId:s,flags:o}=e;if("longpress"===r)return await t.interactions.longPress(a,{session:n,requestId:s,durationMs:e.durationMs});let i={session:n,requestId:s,button:e.clickButton,count:o?.count,intervalMs:o?.intervalMs,holdMs:o?.holdMs,jitterPx:o?.jitterPx,doubleTap:o?.doubleTap};return"click"===r?await t.interactions.click(a,i):await t.interactions.press(a,i)}async function W(e){let{params:t,session:r,result:a,extra:n}=e,s="point"===a.kind?await R({session:r,flags:t.req.flags,sessionStore:t.sessionStore,contextFromFlags:t.contextFromFlags,captureSnapshotForSession:t.captureSnapshotForSession}):P(r.snapshot?.nodes??[]);return M({data:a.backendResult,fallbackX:a.point.x,fallbackY:a.point.y,referenceFrame:s,extra:{...K(a),...n}})}async function $(e,t,r){return await V({params:e,session:t,selector:r,command:"press",positionals:[],extra:{selector:r.raw},fallbackPhase:"ios_direct_selector_tap_fallback"})}async function V(e){let{params:t,session:r,selector:n,command:s,positionals:o,extra:i,fallbackPhase:l}=e,c=Date.now();try{var u,f;let e,l,d=await a(r.device,s,o,t.req.flags?.out,{...t.contextFromFlags(t.req.flags,r.appBundleId,r.trace?.outPath),directElementSelector:n,surface:r.surface})??{},p=Date.now(),g=(u=d,e="number"==typeof u.x?u.x:void 0,l="number"==typeof u.y?u.y:void 0,void 0!==e&&void 0!==l?{x:e,y:l}:{x:0,y:0}),m=M({data:d,fallbackX:g.x,fallbackY:g.y,referenceFrame:(f=d,"number"==typeof f.referenceWidth&&"number"==typeof f.referenceHeight?{referenceWidth:f.referenceWidth,referenceHeight:f.referenceHeight}:void 0),extra:{...i,...function(e,t){if(!e.allowNonHittableCoordinateFallback)return{};let r="tapped via non-hittable coordinate fallback"===t.message;return{maestroNonHittableCoordinateFallbackAllowed:!0,maestroNonHittableCoordinateFallbackUsed:r,...r?{maestroFallbackReason:"non-hittable-coordinate"}:{}}}(n,d)}});return O({session:r,sessionStore:t.sessionStore,command:t.req.command,positionals:t.req.positionals??[],flags:t.req.flags,result:m,responseData:m,actionStartedAt:c,actionFinishedAt:p})}catch(e){if(!w(e))return{ok:!1,error:g(e)};return C({level:"debug",phase:l,data:{selector:n.raw,error:e instanceof Error?e.message:String(e)}}),null}}async function X(e){let{req:t,sessionName:r,sessionStore:a}=e,n=a.get(r);if(n){let e=q(n,"fill");if(e)return e}if(n&&!o("fill",n.device))return c("UNSUPPORTED_OPERATION","fill is not supported on this device");if(!n)return c("SESSION_NOT_FOUND","No active session. Run open first.");let s=function(e){let t=e[0]??"";if(t.startsWith("@")){var r;let a=x(e).text;return a?{ok:!0,target:{kind:"ref",ref:t,fallbackLabel:(r=e).length>=3&&r[1]?.trim()||""},text:a}:{ok:!1,response:c("INVALID_ARGS","fill requires text after ref")}}let a=T(e);if(a){let t=e.slice(2).join(" ");return t?{ok:!0,target:{kind:"point",x:a.x,y:a.y},text:t}:{ok:!1,response:c("INVALID_ARGS","fill requires text after coordinates")}}let n=x(e);return"selector"!==n.kind?{ok:!1,response:c("INVALID_ARGS","fill requires x y text, @ref text, or selector text")}:n.text.trim()?{ok:!0,target:{kind:"selector",selector:n.target.selector},text:n.text}:{ok:!1,response:c("INVALID_ARGS","fill requires text after selector")}}(t.positionals??[]);if(!s.ok)return s.response;if("ref"===s.target.kind){let r=e.refSnapshotFlagGuardResponse("fill",t.flags);if(r)return r;await J(e,n)}let i=function(e){let{session:t,target:r,flags:a}=e;if("selector"!==r.kind)return null;let n=N({session:t,selectorExpression:r.selector});return n?{...n,...a?.maestro?.allowNonHittableCoordinateFallback?{allowNonHittableCoordinateFallback:!0}:{}}:null}({session:n,target:s.target,flags:t.flags});if(i){let t=await Y(e,n,i,s.text);if(t)return t}return await z(e,{run:async e=>await e.interactions.fill(s.target,s.text,{session:r,requestId:t.meta?.requestId,delayMs:t.flags?.delayMs}),buildPayloads:e=>{let t="point"===e.kind?void 0:P(n.snapshot?.nodes??[]),r=M({data:e.backendResult,fallbackX:e.point.x,fallbackY:e.point.y,referenceFrame:t,extra:{...K(e),text:s.text}});e.warning&&(r.warning=e.warning);let a="ref"===e.kind?{...e.backendResult??{ref:L(e.target?.kind==="ref"?e.target.ref:void 0),x:e.point.x,y:e.point.y}}:r;return e.warning&&(a.warning=e.warning),{result:r,responseData:a}}})}async function Y(e,t,r,a){return await V({params:e,session:t,selector:r,command:"fill",positionals:[a],extra:{selector:r.raw,text:a},fallbackPhase:"ios_direct_selector_fill_fallback"})}async function z(e,t){let r=e.sessionStore.get(e.sessionName);if(!r)return c("SESSION_NOT_FOUND","No active session. Run open first.");let a=D(e),n=Date.now();try{let o=await s({session:r,command:e.req.command,phase:"before-command"}),i=await t.run(a);await t.afterRun?.(i),await s({session:r,command:e.req.command,phase:"after-command"});let l=Date.now(),{result:c,responseData:u}=await t.buildPayloads(i);return"recovered"===o.status&&(c.warning=o.warning,u.warning=o.warning),O({session:r,sessionStore:e.sessionStore,command:e.req.command,positionals:e.req.positionals??[],flags:e.req.flags,result:c,responseData:u,actionStartedAt:n,actionFinishedAt:l,androidFreshnessBaseline:t.androidFreshnessBaseline})}catch(t){let e=p(t);if(_(e))throw e;return{ok:!1,error:g(t)}}}async function J(e,t){if(!f(t))return;let r=t.snapshot?.comparisonSafe===!0?t.snapshot:void 0;try{await e.captureSnapshotForSession(t,e.req.flags,e.sessionStore,e.contextFromFlags,{interactiveOnly:!0,androidFreshnessMode:"ref-refresh"})}catch(t){C({level:"warn",phase:"android_ref_snapshot_refresh_failed",data:{command:e.req.command,error:t instanceof Error?t.message:String(t)}})}return r}e.r(E),e.d(E,{INTERACTION_COMMAND_HANDLERS:()=>Q,handleInteractionCommands:()=>Z});let Q={[I.click]:!0,[I.fill]:!0,[I.get]:!0,[I.is]:!0,[I.longPress]:!0,[I.press]:!0,[I.type]:!0};async function Z(e){let t=await j({...e,captureSnapshotForSession:F,refSnapshotFlagGuardResponse:b});if(t)return t;switch(e.req.command){case I.type:return await ee({...e,captureSnapshotForSession:F});case"get":return await S(e);case"is":return await y(e);default:return null}}async function ee(e){let{sessionName:t,sessionStore:r}=e,a=r.get(t);if(!a)return c("SESSION_NOT_FOUND","No active session. Run open first.");if(!o(I.type,a.device))return c("UNSUPPORTED_OPERATION","type is not supported on this device");let n=await et(a);return n||await er(e,a)}async function et(e){return"android"===e.device.platform&&e.recording&&"failed"===await u({session:e})?c("COMMAND_FAILED","Android system dialog blocked the recording session"):null}async function er(e,t){let{req:r,sessionName:a,sessionStore:n}=e,o=(r.positionals??[]).join(" "),i=D(e),l=Date.now();try{let e=await s({session:t,command:r.command,phase:"before-command"}),c=await i.interactions.typeText(o,{session:a,requestId:r.meta?.requestId,delayMs:r.flags?.delayMs});await s({session:t,command:r.command,phase:"after-command"});let u=Date.now(),f={...c.backendResult??{},text:c.text,delayMs:c.delayMs,...A(c.message??`Typed ${Array.from(c.text).length} chars`)};return"recovered"===e.status&&(f.warning=e.warning),O({session:t,sessionStore:n,command:r.command,positionals:r.positionals??[],flags:r.flags,result:f,responseData:f,actionStartedAt:l,actionFinishedAt:u})}catch(e){return{ok:!1,error:g(e)}}}export{E as interaction_namespaceObject};
@@ -1,2 +1,5 @@
1
- let e=process.argv.slice(2);function c(e){process.stderr.write(`${e instanceof Error?e.message:String(e)}
2
- `),process.exit(1)}"mcp"!==e[0]||e.includes("--help")||e.includes("-h")?import("../cli.js").then(({runCli:c})=>c(e)).catch(c):import("../server.js").then(({runAgentDeviceMcpServer:e})=>e()).catch(c);
1
+ var t,e,r,s;let c,n=process.argv.slice(2);function i(t){return"--help"===t||"-h"===t}function o(t){import("../cli.js").then(({runCli:e})=>e(t)).catch(_)}function _(t){process.stderr.write(`${t instanceof Error?t.message:String(t)}
2
+ `),process.exit(1)}1===(e=t=n).length&&("--version"===(r=e[0])||"-V"===r)&&(import("../9671.js").then(({readVersion:t})=>{process.stdout.write(`${t()}
3
+ `)}).catch(_),1)||0===t.length&&(import("../args.js").then(({usage:t})=>{process.stdout.write(`${t()}
4
+ `),process.exit(1)}).catch(_),1)||void 0!==(c=function(t){var e,r,s,c;switch(t.length){case 1:return"help"===(e=t[0])||i(e)?null:void 0;case 2:return r=t[0],s=t[1],"help"===r?s:(c=r,i(s)?c:void 0);default:return}}(s=t))&&(import("../args.js").then(({usage:t,usageForCommand:e})=>{if(null===c)return void process.stdout.write(`${t()}
5
+ `);let r=e(c);r?process.stdout.write(r):o(s)}).catch(_),1)||("mcp"!==n[0]||n.includes("--help")||n.includes("-h")?o(n):import("../server.js").then(({runAgentDeviceMcpServer:t})=>t()).catch(_));