agent-device 0.17.5 → 0.17.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.
- package/README.md +2 -2
- package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.17.5.apk → agent-device-android-multitouch-helper-0.17.6.apk} +0 -0
- package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.17.6.apk.sha256 +1 -0
- package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.17.5.manifest.json → agent-device-android-multitouch-helper-0.17.6.manifest.json} +4 -4
- package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.17.5.apk → agent-device-android-snapshot-helper-0.17.6.apk} +0 -0
- package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.17.6.apk.sha256 +1 -0
- package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.17.5.manifest.json → agent-device-android-snapshot-helper-0.17.6.manifest.json} +6 -6
- package/dist/src/2133.js +1 -0
- package/dist/src/2748.js +1 -0
- package/dist/src/{4012.js → 2892.js} +1 -1
- package/dist/src/2948.js +1 -0
- package/dist/src/2954.js +2 -0
- package/dist/src/{7651.js → 3006.js} +1 -1
- package/dist/src/314.js +1 -0
- package/dist/src/{8806.js → 3340.js} +5 -5
- package/dist/src/4291.js +2 -0
- package/dist/src/{7599.js → 432.js} +1 -1
- package/dist/src/4418.js +1 -0
- package/dist/src/{2403.js → 4428.js} +1 -1
- package/dist/src/4723.js +1 -0
- package/dist/src/5299.js +1 -0
- package/dist/src/{113.js → 5448.js} +1 -1
- package/dist/src/5484.js +1 -0
- package/dist/src/5628.js +1 -0
- package/dist/src/587.js +1 -0
- package/dist/src/6311.js +27 -0
- package/dist/src/6918.js +1 -0
- package/dist/src/7244.js +1 -0
- package/dist/src/7394.js +6 -0
- package/dist/src/8184.js +1 -0
- package/dist/src/8225.js +1 -0
- package/dist/src/{1974.js → 8275.js} +1 -1
- package/dist/src/8875.js +1 -0
- package/dist/src/{1352.js → 9581.js} +1 -1
- package/dist/src/9624.js +1 -0
- package/dist/src/9722.js +38 -0
- package/dist/src/9836.js +1 -0
- package/dist/src/9873.js +1 -0
- package/dist/src/9919.js +6 -0
- package/dist/src/android-adb.d.ts +3 -3
- package/dist/src/android-adb.js +1 -1
- package/dist/src/android-snapshot-helper.js +1 -1
- package/dist/src/android.js +1 -1
- package/dist/src/apple.js +1 -1
- package/dist/src/apps.js +6 -6
- package/dist/src/artifacts.js +1 -1
- package/dist/src/batch.d.ts +4 -4
- package/dist/src/batch.js +1 -1
- package/dist/src/{args.js → cli-help.js} +18 -18
- package/dist/src/cli-output.js +4 -30
- package/dist/src/cli.js +17 -17
- package/dist/src/command-surface.js +1 -1
- package/dist/src/contracts.d.ts +6 -6
- package/dist/src/contracts.js +1 -1
- package/dist/src/devices.js +1 -1
- package/dist/src/find.js +1 -1
- package/dist/src/finders.d.ts +1 -1
- package/dist/src/finders.js +1 -1
- package/dist/src/generic.js +8 -14
- package/dist/src/index.d.ts +28 -25
- package/dist/src/index.js +1 -1
- package/dist/src/input-actions.js +1 -1
- package/dist/src/input-actions~1.js +1 -1
- package/dist/src/install-source.js +1 -1
- package/dist/src/interaction.js +1 -1
- package/dist/src/internal/bin.js +5 -5
- package/dist/src/internal/companion-tunnel.js +1 -1
- package/dist/src/internal/daemon.js +1 -1
- package/dist/src/internal/png-worker.js +1 -1
- package/dist/src/internal/update-check-entry.js +1 -1
- package/dist/src/io.js +1 -1
- package/dist/src/lease.js +1 -1
- package/dist/src/linux.js +1 -1
- package/dist/src/metro.js +1 -1
- package/dist/src/notifications.js +1 -1
- package/dist/src/react-native.js +1 -1
- package/dist/src/record-trace-recording.js +2 -2
- package/dist/src/record-trace.js +1 -1
- package/dist/src/recording-provider.js +1 -1
- package/dist/src/remote-config.d.ts +5 -5
- package/dist/src/remote-config.js +1 -1
- package/dist/src/rslib-runtime.js +1 -1
- package/dist/src/selector-runtime.js +1 -1
- package/dist/src/selectors.d.ts +1 -1
- package/dist/src/selectors.js +1 -1
- package/dist/src/server.js +1 -1
- package/dist/src/session.js +7 -7
- package/dist/src/snapshot.js +2 -2
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +5 -0
- package/package.json +14 -13
- package/server.json +3 -3
- package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.17.5.apk.sha256 +0 -1
- package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.17.5.apk.sha256 +0 -1
- package/dist/src/1010.js +0 -1
- package/dist/src/123.js +0 -1
- package/dist/src/1231.js +0 -1
- package/dist/src/208.js +0 -1
- package/dist/src/221.js +0 -6
- package/dist/src/2415.js +0 -38
- package/dist/src/3675.js +0 -1
- package/dist/src/5611.js +0 -1
- package/dist/src/5827.js +0 -1
- package/dist/src/6088.js +0 -1
- package/dist/src/6133.js +0 -1
- package/dist/src/6629.js +0 -1
- package/dist/src/7556.js +0 -1
- package/dist/src/7719.js +0 -1
- package/dist/src/7847.js +0 -1
- package/dist/src/8133.js +0 -1
- package/dist/src/8656.js +0 -1
- package/dist/src/9010.js +0 -1
- package/dist/src/9471.js +0 -1
- package/dist/src/9542.js +0 -6
- package/dist/src/9616.js +0 -2
- package/dist/src/9639.js +0 -2
- package/dist/src/9671.js +0 -1
- package/dist/src/9818.js +0 -1
- package/dist/src/989.js +0 -1
- /package/dist/src/{2301.js → 4069.js} +0 -0
- /package/dist/src/{4829.js → 5560.js} +0 -0
- /package/dist/src/{4778.js → 6024.js} +0 -0
- /package/dist/src/{9152.js → 733.js} +0 -0
- /package/dist/src/{3267.js → 9612.js} +0 -0
package/dist/src/devices.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{promises as t}from"node:fs";import e from"node:os";import i from"node:path";import{AppError as r}from"./
|
|
1
|
+
import{promises as t}from"node:fs";import e from"node:os";import i from"node:path";import{AppError as r}from"./733.js";import{buildHostMacDevice as o}from"./devices~2.js";import{runXcrun as n,resolveAppleToolProvider as l,buildSimctlArgs as a}from"./9722.js";import{resolveIosSimulatorDeviceSetPath as u}from"./3340.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};
|
package/dist/src/find.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{context_contextFromFlags as t,setSessionSnapshot as e,captureSnapshot as n,dispatchCommand as r,errorResponse as a,ensureDeviceReady as o,getActiveAndroidSnapshotFreshness as i,resolveTargetDevice as s,stripInternalInteractionFlags as l}from"./
|
|
1
|
+
import{context_contextFromFlags as t,setSessionSnapshot as e,captureSnapshot as n,dispatchCommand as r,errorResponse as a,ensureDeviceReady as o,getActiveAndroidSnapshotFreshness as i,resolveTargetDevice as s,stripInternalInteractionFlags as l}from"./9722.js";import{findBestMatchesByLocator as c,parseFindArgs as f}from"./587.js";import{dispatchFindReadOnlyViaRuntime as u,readTextForNode as d}from"./selector-runtime.js";import{resolveActionableTouchResolution as p,isSparseSnapshotQualityVerdict as h,isSnapshotNodeInteractionBlocked as g,resolveActionableTouchNode as _}from"./9873.js";import{centerOfRect as y}from"./4291.js";import{sleep as m}from"./5560.js";import{extractNodeText as w}from"./9836.js";async function A(t){var r,d,g,m;let A,{req:E,sessionName:U,logPath:P,sessionStore:O,invoke:H}=t,$=E.command;if("find"!==$)return null;let q=E.positionals??[];if(0===q.length)return a("INVALID_ARGS","find requires a locator or text");let{locator:B,query:Q,action:G,value:V,timeoutMs:T}=f(q);if(!Q)return a("INVALID_ARGS","find requires a value");if(E.flags?.findFirst&&E.flags?.findLast)return a("INVALID_ARGS","find accepts only one of --first or --last");let j=await u({req:E,sessionName:U,logPath:P,sessionStore:O});if(j)return j;let z=O.get(U),J="exists"===(r=G)||"wait"===r||"get_text"===r||"get_attrs"===r;if(!z&&!J)return a("SESSION_NOT_FOUND","No active session. Run open first.");let W=z?.device??await s(E.flags??{});z||await o(W);let X="click"===(d=G)||"focus"===d||"fill"===d||"type"===d,Y=L(B)&&!X?Q:void 0,Z=function(t){let{device:r,session:a,req:o,logPath:s,locator:l,query:c,scope:f,interactiveOnly:u}=t,{sessionStore:d,sessionName:p}=t,g=0,_=null,y=async(t,e)=>{let{snapshot:i}=await n({device:r,session:a,flags:{...o.flags,snapshotInteractiveOnly:e},outPath:o.flags?.out,logPath:s,snapshotScope:t});return i};return async()=>{var t;let n=Date.now();if(_&&n-g<750&&!i(a))return _;let r=await y(f,u);u&&!(t=r).snapshotQuality&&"xctest"===t.backend&&1===t.nodes.length&&t.nodes[0]?.type==="Application"?r=await N({capture:y,locator:l,query:c,scope:f}):u&&h(r.snapshotQuality)&&L(l)&&(r=await k({capture:y,query:c,snapshot:r}));let o={nodes:r.nodes,truncated:r.truncated,backend:r.backend,snapshotQuality:r.snapshotQuality};return g=n,_=o,a&&!h(r.snapshotQuality)&&(e(a,r),d.set(p,a)),o}}({device:W,session:z,req:E,logPath:P,locator:B,query:Q,scope:Y,interactiveOnly:X,sessionStore:O,sessionName:U}),tt={req:E,sessionName:U,logPath:P,sessionStore:O,invoke:H,session:z,device:W,command:$,locator:B,query:Q,publicFlags:{...l(E.flags)??{}}};if("wait"===G)return x(tt,Z,B,Q,T);let te=await Z();if(h(te.snapshotQuality))return S(te.snapshotQuality);let{nodes:tn}=te,tr=function(t){let{nodes:e,locator:n,query:r,requiresRect:o,flags:i}=t,s=c(o?e.filter(t=>!C(t,e[0])):e,n,r,{requireRect:o});if(o&&(s.matches=function(t,e){var n,r;let a=e[0]?.rect;if(!a)return t;let o=t.filter(t=>{if(!t.rect)return!1;let e=y(t.rect);return e.x>=a.x&&e.x<=a.x+a.width&&e.y>=a.y&&e.y<=a.y+a.height});return n=o.length>0?o:t,r=e,n.length<2?n:n.map((t,e)=>({node:t,index:e,score:function(t,e){var n,r;let a=p(e,t);if("covered"===a.reason)return 0;let o=(n=a,r=e[0],n.node.rect?"semantic-target"===n.reason||"same-rect-descendant"===n.reason?4:2*!("hittable-ancestor"!==n.reason||C(n.node,r)):0);return o>0?o:t.hittable&&t.rect&&!C(t,e[0])?3:+!!t.rect}(t,r)})).sort((t,e)=>e.score!==t.score?e.score-t.score:v(t.node)-v(e.node)||t.index-e.index).map(t=>t.node)}(s.matches,e)),o&&s.matches.length>1){var l,f,u,d,h;let t=(l=s.matches,f=i,f?.findFirst?[l[0]]:f?.findLast?[l[l.length-1]]:null);if(!t){let t;return{ok:!1,response:(u=s.matches,d=n,h=r,t=u.slice(0,8).map(t=>{let e=w(t)||t.label||t.identifier||t.type||"";return`@${t.ref}${e?`(${e})`:""}`}),a("AMBIGUOUS_MATCH",`find matched ${u.length} elements for ${d} "${h}". Use a more specific locator or selector.`,{locator:d,query:h,matches:u.length,candidates:t}))}}s.matches=t}let g=s.matches[0]??null;return g?{ok:!0,node:g}:{ok:!1,response:a("COMMAND_FAILED","find did not match any element")}}({nodes:tn,locator:B,query:Q,requiresRect:X,flags:E.flags});if(!tr.ok)return tr.response;let ta=tr.node,to=X?C(A=_(g=tn,m=ta),g[0])&&m.rect?m:A:ta,ti=`@${to.ref}`,ts={node:ta,resolvedNode:to,ref:ti,nodes:tn,actionFlags:{...E.flags??{},noRecord:!0}},tl={exists:()=>M(tt),get_text:()=>I(tt,ts),get_attrs:()=>D(tt,ts),click:()=>R(tt,ts),fill:()=>F(tt,ts,V),focus:()=>K(tt,ts),type:()=>b(tt,ts,V)}[G];return tl?tl():null}async function k(t){let{capture:e,query:n,snapshot:r}=t;try{return await e(n,!1)}catch{return r}}async function N(t){let{capture:e,locator:n,query:r,scope:a}=t;try{return await e(a,!1)}catch(t){if(!L(n))throw t;return await e(r,!1)}}function S(t){return a("COMMAND_FAILED","find could not read the current accessibility tree",{reason:t.reason,hint:"The snapshot quality verdict is sparse. Use screenshot as visual truth, navigate with coordinates if needed, then retry find after reaching a readable screen."})}function v(t){return t.rect?t.rect.width*t.rect.height:1/0}function C(t,e){var n,r;if(!e?.rect||!t.rect)return!1;let a=t.type?.toLowerCase()??"";return(!!a.includes("application")||!!a.includes("window"))&&(n=t.rect,r=e.rect,n.x===r.x&&n.y===r.y&&n.width===r.width&&n.height===r.height)}async function x(t,e,n,r,o){let i,{req:s,sessionStore:l,session:f,command:u,publicFlags:d}=t,p=o??1e4,g=Date.now();for(;Date.now()-g<p;){let{nodes:t,snapshotQuality:a}=await e();if(h(a)){i=a,await m(300);continue}if(c(t,n,r,{requireRect:!1}).matches[0])return f&&l.recordAction(f,{command:u,positionals:s.positionals??[],flags:d,result:{found:!0,waitedMs:Date.now()-g}}),{ok:!0,data:{found:!0,waitedMs:Date.now()-g}};await m(300)}return i?S(i):a("COMMAND_FAILED","find wait timed out")}async function M(t){let{req:e,sessionStore:n,session:r,command:a,publicFlags:o}=t;return r&&n.recordAction(r,{command:a,positionals:e.positionals??[],flags:o,result:{found:!0}}),{ok:!0,data:{found:!0}}}async function I(e,n){let{req:r,sessionStore:a,session:o,command:i,device:s,logPath:l,publicFlags:c}=e,f=await d({device:s,node:n.node,flags:r.flags,appBundleId:o?.appBundleId,traceOutPath:o?.trace?.outPath,surface:o?.surface,contextFromFlags:(e,n,r)=>t(l,e,n,r)});return o&&a.recordAction(o,{command:i,positionals:r.positionals??[],flags:c,result:{ref:n.ref,action:"get text",text:f}}),{ok:!0,data:{ref:n.ref,text:f,node:n.node}}}async function D(t,e){let{req:n,sessionStore:r,session:a,command:o,publicFlags:i}=t;return a&&r.recordAction(a,{command:o,positionals:n.positionals??[],flags:i,result:{ref:e.ref,action:"get attrs"}}),{ok:!0,data:{ref:e.ref,node:e.node}}}async function R(t,e){let{req:n,sessionName:r,sessionStore:a,session:o,invoke:i,command:s,locator:l,query:c,publicFlags:f}=t,u=await i({token:n.token,session:r,command:"click",positionals:[e.ref],flags:e.actionFlags});if(!u.ok)return u;let d=e.resolvedNode.rect?y(e.resolvedNode.rect):e.node.rect?y(e.node.rect):null,p={ref:e.ref,locator:l,query:c};return d&&(p.x=d.x,p.y=d.y),o&&a.recordAction(o,{command:s,positionals:n.positionals??[],flags:f,result:{ref:e.ref,action:"click",locator:l,query:c}}),{ok:!0,data:p}}async function F(t,e,n){let{req:r,sessionName:o,sessionStore:i,session:s,invoke:l,command:c,publicFlags:f}=t;if(!n)return a("INVALID_ARGS","find fill requires text");let u=await l({token:r.token,session:o,command:"fill",positionals:[e.ref,n],flags:e.actionFlags});return u.ok&&s&&i.recordAction(s,{command:c,positionals:r.positionals??[],flags:f,result:{ref:e.ref,action:"fill"}}),u}async function K(t,e){let n=await E(t,e);return n.ok&&U(t,e,"focus"),n}async function b(e,n,o){let{req:i,device:s,logPath:l,session:c}=e;if(!o)return a("INVALID_ARGS","find type requires text");let f=await E(e,n);if(!f.ok)return f;let u=await r(s,"type",[o],i.flags?.out,{...t(l,i.flags,c?.appBundleId,c?.trace?.outPath)});return U(e,n,"type"),{ok:!0,data:u??{ref:n.ref}}}async function E(e,n){var o;let i,{req:s,device:l,logPath:c,session:f}=e,u=(i=[(o=n).resolvedNode,o.node].find(g))?a("COMMAND_FAILED",`Matched element ${o.ref} is covered by another visible element and cannot be focused safely`,{ref:`@${i.ref}`,interactionBlocked:i.interactionBlocked,hint:"Use a different visible target, scroll it clear of the overlay, or inspect with snapshot/screenshot before retrying."}):null;if(u)return u;let d=n.resolvedNode.rect?y(n.resolvedNode.rect):null;return d?{ok:!0,data:await r(l,"focus",[String(d.x),String(d.y)],s.flags?.out,{...t(c,s.flags,f?.appBundleId,f?.trace?.outPath)})??{ref:n.ref}}:a("COMMAND_FAILED","matched element has no bounds")}function U(t,e,n){let{req:r,sessionStore:a,session:o,command:i,publicFlags:s}=t;o&&a.recordAction(o,{command:i,positionals:r.positionals??[],flags:s,result:{ref:e.ref,action:n}})}function L(t){return"role"!==t}export{parseFindArgs}from"./587.js";export{A as handleFindCommands};
|
package/dist/src/finders.d.ts
CHANGED
package/dist/src/finders.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{findBestMatchesByLocator as e}from"./
|
|
1
|
+
import{findBestMatchesByLocator as e}from"./587.js";function o(o,r,t,_){return e(o,r,t,"boolean"==typeof _?{requireRect:_}:_)}export{normalizeRole,normalizeText,parseFindArgs}from"./587.js";export{o as findBestMatchesByLocator};
|
package/dist/src/generic.js
CHANGED
|
@@ -1,15 +1,9 @@
|
|
|
1
|
-
import t from"node:fs";import e from"node:path";import{formatDurationSeconds as r}from"./
|
|
2
|
-
`),process.stdout.write(
|
|
3
|
-
`),
|
|
4
|
-
`);for(let e of
|
|
5
|
-
`)
|
|
6
|
-
`
|
|
7
|
-
`),"
|
|
8
|
-
`),D(t)))process.stdout.write(` ${s}
|
|
9
|
-
`);for(let e of u(t))process.stdout.write(` ${e}
|
|
10
|
-
`)}(e);else for(let e of t.tests)!function(t){if("failed"===t.status)return m(t);if("passed"===t.status)for(let e of(process.stdout.write(`PASS ${g(t)}${y(t)}
|
|
11
|
-
`),D(t)))process.stdout.write(` ${e}
|
|
12
|
-
`)}(e);let n="number"==typeof t.durationMs?t.durationMs:void 0,i=s.length>0?`, ${s.length} flaky`:"",o=void 0!==n?` in ${r(n)}`:"";return process.stdout.write(`Test summary: ${t.passed} passed, ${t.failed} failed${i}${o}
|
|
13
|
-
`),function(t){if(0!==t.length)for(let e of(process.stdout.write("Flaky tests:\n"),t))for(let t of(process.stdout.write(` PASS ${g(e)} after ${e.attempts} attempts${v(e)}
|
|
1
|
+
import t from"node:fs";import e from"node:path";import{formatDurationSeconds as r,replayTestFailureStepLines as s}from"./9919.js";import{AppError as i}from"./733.js";import{colorize as n,printJson as o,supportsColor as a}from"./6311.js";import{runCliCommandWithOutput as u,writeCommandOutput as d}from"./cli.js";import{readCommandMessage as l}from"./9873.js";function f(t){return"failed"===t.status}function c(t){return"passed"===t.status&&t.attempts>1}function p(t){let r=$(t),s=e.basename(t.file),i=r&&r.length>0?`${JSON.stringify(r)} in ${s}`:s;return`${i}${m(t)}`}function $(t){let e=t.title?.trim();return e&&e.length>0?e:void 0}function m(t){if(!("shardIndex"in t)||"number"!=typeof t.shardIndex)return"";let e="number"==typeof t.shardCount?t.shardCount:"?",r="string"==typeof t.deviceId?` ${t.deviceId}`:"";return` [shard ${t.shardIndex+1}/${e}${r}]`}function h(t,e,r={}){r.includeMessage&&t.push(`errorMessage: ${e.message}`),w(t,y(e)),w(t,_(e,"diagnosticId")),w(t,M(e,"logPath")),!1!==r.includeDetails&&g(t,e,r.detailsIndent)}function g(t,e,r){let s=e.details?JSON.stringify(e.details,null,r):void 0;s&&t.push(`details: ${s}`)}function v(t,e){return"artifactsDir"in t&&t.artifactsDir?`${e}: ${t.artifactsDir}`:void 0}function y(t){return t.hint?`hint: ${t.hint}`:void 0}function _(t,e){return t.diagnosticId?`${e}: ${t.diagnosticId}`:void 0}function M(t,e){return t.logPath?`${e}: ${t.logPath}`:void 0}function w(t,e){e&&t.push(e)}function C(t){return void 0!==t}function I(t){return(Math.max(0,t)/1e3).toFixed(3)}function b(t){return t.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""").replaceAll("'","'")}async function S({command:A,positionals:x,flags:D,client:k,debug:K}){let{result:j,cliOutput:F}=await u({client:k,command:A,positionals:x,flags:D});if(F){var N,P;N=D,P=F,!N.json&&P.stderr&&process.stderr.write(P.stderr),d(N,N.json?P.jsonData??P.data:P.data,()=>P.text)}else{let u=function(u,S,A,x={}){return"test"===u?function(u){let{suite:d,json:l,debug:S,reportJunit:A}=u;return(A&&function(r,s){let n=e.dirname(r);try{t.mkdirSync(n,{recursive:!0}),t.writeFileSync(r,function(t){let r=['<?xml version="1.0" encoding="UTF-8"?>',"<testsuites>",` <testsuite name="agent-device replay suite" tests="${t.total}" failures="${t.failed}" skipped="${t.skipped}" time="${I(t.durationMs)}">`];for(let s of t.tests)r.push(...function(t){let r=b(`${$(t)??e.basename(t.file)}${m(t)}`),s=b(`${"."===e.dirname(t.file)?t.file:e.dirname(t.file)}${m(t)}`),i=b(t.file),n=I(t.durationMs),o=[` <testcase classname="${s}" name="${r}" file="${i}" time="${n}">`];"failed"===t.status?o.push(` <failure message="${b(t.error.message)}">${b(function(t){let e=[t.error.message];return h(e,t.error,{includeDetails:!1}),w(e,v(t,"artifactsDir")),g(e,t.error,2),e.join("\n")}(t))}</failure>`):"skipped"===t.status&&o.push(` <skipped message="${b(t.message)}" />`);let a=function(t){let e=[`status: ${t.status}`,`durationMs: ${t.durationMs}`];return function(t,e){var r,s,i,n,o;for(let s of(w(t,"attempts"in e?`attempts: ${e.attempts}`:void 0),w(t,"session"in e?`session: ${e.session}`:void 0),w(t,"replayed"in e?`replayed: ${e.replayed}`:void 0),w(t,"healed"in e?`healed: ${e.healed}`:void 0),r=e,"passed"!==r.status?[]:(r.warnings??[]).map(t=>`warning: ${t}`)))t.push(s);w(t,v(e,"artifactsDir")),s=t,i=e,"shardIndex"in i&&"number"==typeof i.shardIndex&&(s.push(`shardIndex: ${i.shardIndex}`),w(s,"number"==typeof i.shardCount?`shardCount: ${i.shardCount}`:void 0),w(s,"string"==typeof i.deviceId?`deviceId: ${i.deviceId}`:void 0)),"failed"===e.status&&(n=t,o=e,n.push(`errorCode: ${o.error.code}`),h(n,o.error,{includeMessage:!0})),w(t,c(e)?"flaky: true":void 0)}(e,t),e.join("\n")}(t);return a&&o.push(` <system-out>${b(a)}</system-out>`),o.push(" </testcase>"),o}(s));return r.push(" </testsuite>"),r.push("</testsuites>"),`${r.join("\n")}
|
|
2
|
+
`}(s),"utf8")}catch(e){let t=e instanceof Error?e.message:String(e);throw new i("COMMAND_FAILED",`Failed to write JUnit report to ${r}: ${t}`)}}(A,d),l)?(o({success:!0,data:d}),+(d.failed>0)):function(t,e={}){var i,o;let u,d,l,$=t.tests.filter(c);return process.stdout.write(`${(i=t,o=$.length,u="number"==typeof i.durationMs?i.durationMs:void 0,d=o>0?`, ${o} flaky`:"",l=void 0!==u?` in ${r(u)}`:"",`Test summary: ${i.passed} passed, ${i.failed} failed${d}${l}`)}
|
|
3
|
+
`),function(t,e={}){if(0!==t.length)for(let r of(process.stdout.write("\n"),process.stdout.write("Failures:\n"),t))process.stdout.write(` ${p(r)}
|
|
4
|
+
`),function(t,e){let{debug:r,indent:i}=e;for(let e of(process.stdout.write(`${i}${t.error?.message??"Unknown test failure"}
|
|
5
|
+
`),[y(t.error),v(t,"artifacts"),M(t.error,"log"),_(t.error,"diagnostic")].filter(C)))process.stdout.write(`${i}${e}
|
|
6
|
+
`);if(r)for(let e of s(t))process.stdout.write(`${i}${e}
|
|
7
|
+
`)}(r,{debug:e.debug,indent:" "})}(t.tests.filter(f),{debug:e.debug}),function(t){if(0!==t.length)for(let e of(process.stdout.write("\n"),process.stdout.write("Flaky tests:\n"),t))for(let t of(process.stdout.write(` ${a()?n("✓","yellow"):"✓"} ${p(e)} after ${e.attempts} attempts${function(t){let e=["number"==typeof t.finalAttemptDurationMs?`passed attempt ${r(t.finalAttemptDurationMs)}`:"",t.durationMs>0?`total ${r(t.durationMs)}`:""].filter(Boolean);return e.length>0?` (${e.join(", ")})`:""}(e)}
|
|
14
8
|
`),e.attemptFailures??[])){let e="number"==typeof t.durationMs?` (${r(t.durationMs)})`:"";process.stdout.write(` attempt ${t.attempt} failed${e}: ${t.message}
|
|
15
|
-
`)}}(
|
|
9
|
+
`)}}($),+(t.failed>0)}(d,{debug:S})}({suite:A,debug:x.debug,json:S.json,reportJunit:S.reportJunit}):(d(S,A,()=>l(A)),0)}(A,D,j,{debug:K});0!==u&&process.exit(u)}return!0}export{S as runGenericClientBackedCommand};
|
package/dist/src/index.d.ts
CHANGED
|
@@ -102,6 +102,9 @@ export declare type AgentDeviceClientConfig = {
|
|
|
102
102
|
runtime?: SessionRuntimeHints;
|
|
103
103
|
cwd?: string;
|
|
104
104
|
debug?: boolean;
|
|
105
|
+
iosXctestrunFile?: string;
|
|
106
|
+
iosXctestDerivedDataPath?: string;
|
|
107
|
+
iosXctestEnvDir?: string;
|
|
105
108
|
};
|
|
106
109
|
|
|
107
110
|
export declare type AgentDeviceCommandClient = {
|
|
@@ -147,7 +150,7 @@ export declare type AgentDeviceIdentifiers = {
|
|
|
147
150
|
package?: string;
|
|
148
151
|
};
|
|
149
152
|
|
|
150
|
-
export declare type AgentDeviceRequestOverrides = Pick<AgentDeviceClientConfig, 'session' | 'lockPolicy' | 'lockPlatform' | 'requestId' | 'daemonBaseUrl' | 'daemonAuthToken' | 'daemonTransport' | 'daemonServerMode' | 'tenant' | 'sessionIsolation' | 'runId' | 'leaseId' | 'leaseBackend' | 'cwd' | 'debug'>;
|
|
153
|
+
export declare type AgentDeviceRequestOverrides = Pick<AgentDeviceClientConfig, 'session' | 'lockPolicy' | 'lockPlatform' | 'requestId' | 'daemonBaseUrl' | 'daemonAuthToken' | 'daemonTransport' | 'daemonServerMode' | 'tenant' | 'sessionIsolation' | 'runId' | 'leaseId' | 'leaseBackend' | 'cwd' | 'debug' | 'iosXctestrunFile' | 'iosXctestDerivedDataPath' | 'iosXctestEnvDir'>;
|
|
151
154
|
|
|
152
155
|
export declare type AgentDeviceSelectionOptions = {
|
|
153
156
|
platform?: PlatformSelector;
|
|
@@ -183,7 +186,7 @@ export declare type AgentDeviceSessionDevice = {
|
|
|
183
186
|
};
|
|
184
187
|
};
|
|
185
188
|
|
|
186
|
-
declare const ALERT_ACTIONS: readonly [
|
|
189
|
+
declare const ALERT_ACTIONS: readonly ['get', 'accept', 'dismiss', 'wait'];
|
|
187
190
|
|
|
188
191
|
export declare type AlertAction = (typeof ALERT_ACTIONS)[number];
|
|
189
192
|
|
|
@@ -389,7 +392,7 @@ export declare type ArtifactDescriptor = {
|
|
|
389
392
|
metadata?: Record<string, unknown>;
|
|
390
393
|
};
|
|
391
394
|
|
|
392
|
-
declare const BACK_MODES: readonly [
|
|
395
|
+
declare const BACK_MODES: readonly ['in-app', 'system'];
|
|
393
396
|
|
|
394
397
|
export declare type BackCommandOptions = DeviceCommandBaseOptions & {
|
|
395
398
|
mode?: BackMode;
|
|
@@ -456,7 +459,7 @@ export declare type CaptureSnapshotResult = {
|
|
|
456
459
|
|
|
457
460
|
export declare function centerOfRect(rect: Rect): Point;
|
|
458
461
|
|
|
459
|
-
declare const CLICK_BUTTONS: readonly [
|
|
462
|
+
declare const CLICK_BUTTONS: readonly ['primary', 'secondary', 'middle'];
|
|
460
463
|
|
|
461
464
|
declare type ClickButton = (typeof CLICK_BUTTONS)[number];
|
|
462
465
|
|
|
@@ -502,11 +505,11 @@ export declare type CreateTempFileOptions = {
|
|
|
502
505
|
ext: string;
|
|
503
506
|
};
|
|
504
507
|
|
|
505
|
-
declare const DAEMON_LOCK_POLICIES: readonly [
|
|
508
|
+
declare const DAEMON_LOCK_POLICIES: readonly ['reject', 'strip'];
|
|
506
509
|
|
|
507
|
-
declare const DAEMON_SERVER_MODES: readonly [
|
|
510
|
+
declare const DAEMON_SERVER_MODES: readonly ['socket', 'http', 'dual'];
|
|
508
511
|
|
|
509
|
-
declare const DAEMON_TRANSPORT_PREFERENCES: readonly [
|
|
512
|
+
declare const DAEMON_TRANSPORT_PREFERENCES: readonly ['auto', 'socket', 'http'];
|
|
510
513
|
|
|
511
514
|
declare type DaemonArtifact = {
|
|
512
515
|
field: string;
|
|
@@ -647,11 +650,11 @@ declare type DebugSymbolsResult = {
|
|
|
647
650
|
message: string;
|
|
648
651
|
};
|
|
649
652
|
|
|
650
|
-
declare const DEVICE_KINDS: readonly [
|
|
653
|
+
declare const DEVICE_KINDS: readonly ['simulator', 'emulator', 'device'];
|
|
651
654
|
|
|
652
|
-
declare const DEVICE_ROTATIONS: readonly [
|
|
655
|
+
declare const DEVICE_ROTATIONS: readonly ['portrait', 'portrait-upside-down', 'landscape-left', 'landscape-right'];
|
|
653
656
|
|
|
654
|
-
declare const DEVICE_TARGETS: readonly [
|
|
657
|
+
declare const DEVICE_TARGETS: readonly ['mobile', 'tv', 'desktop'];
|
|
655
658
|
|
|
656
659
|
export declare type DeviceBootOptions = DeviceCommandBaseOptions & {
|
|
657
660
|
headless?: boolean;
|
|
@@ -691,7 +694,7 @@ export declare type FillOptions = DeviceCommandBaseOptions & SelectorSnapshotCom
|
|
|
691
694
|
delayMs?: number;
|
|
692
695
|
};
|
|
693
696
|
|
|
694
|
-
declare const FIND_LOCATORS: readonly [
|
|
697
|
+
declare const FIND_LOCATORS: readonly ['any', 'text', 'label', 'value', 'role', 'id'];
|
|
695
698
|
|
|
696
699
|
declare type FindBaseOptions = DeviceCommandBaseOptions & FindSnapshotCommandOptions & {
|
|
697
700
|
locator?: FindLocator;
|
|
@@ -785,7 +788,7 @@ declare type Lease = {
|
|
|
785
788
|
expiresAt?: number;
|
|
786
789
|
};
|
|
787
790
|
|
|
788
|
-
declare const LEASE_BACKENDS: readonly [
|
|
791
|
+
declare const LEASE_BACKENDS: readonly ['ios-simulator', 'ios-instance', 'android-instance'];
|
|
789
792
|
|
|
790
793
|
declare type LeaseAllocateOptions = LeaseOptions & {
|
|
791
794
|
tenant: string;
|
|
@@ -811,7 +814,7 @@ export declare type LocalArtifactAdapterOptions = {
|
|
|
811
814
|
rootDir?: string;
|
|
812
815
|
};
|
|
813
816
|
|
|
814
|
-
declare const LOG_ACTION_VALUES: readonly [
|
|
817
|
+
declare const LOG_ACTION_VALUES: readonly ['path', 'start', 'stop', 'doctor', 'mark', 'clear'];
|
|
815
818
|
|
|
816
819
|
declare type LogAction = (typeof LOG_ACTION_VALUES)[number];
|
|
817
820
|
|
|
@@ -895,7 +898,7 @@ export declare type MetroReloadResult = ReloadMetroResult;
|
|
|
895
898
|
/** Re-export of {@link SessionRuntimeHints} under the Metro-specific alias used by public API consumers. */
|
|
896
899
|
declare type MetroRuntimeHints = SessionRuntimeHints;
|
|
897
900
|
|
|
898
|
-
declare const NETWORK_INCLUDE_MODES: readonly [
|
|
901
|
+
declare const NETWORK_INCLUDE_MODES: readonly ['summary', 'headers', 'body', 'all'];
|
|
899
902
|
|
|
900
903
|
declare type NetworkIncludeMode = (typeof NETWORK_INCLUDE_MODES)[number];
|
|
901
904
|
|
|
@@ -929,13 +932,13 @@ declare type PanOptions = DeviceCommandBaseOptions & {
|
|
|
929
932
|
durationMs?: number;
|
|
930
933
|
};
|
|
931
934
|
|
|
932
|
-
declare const PERF_ACTION_VALUES: readonly [
|
|
935
|
+
declare const PERF_ACTION_VALUES: readonly ['sample', 'snapshot', 'start', 'stop', 'report'];
|
|
933
936
|
|
|
934
|
-
declare const PERF_AREA_VALUES: readonly [
|
|
937
|
+
declare const PERF_AREA_VALUES: readonly ['metrics', 'frames', 'memory', 'cpu', 'trace'];
|
|
935
938
|
|
|
936
|
-
declare const PERF_KIND_VALUES: readonly [
|
|
939
|
+
declare const PERF_KIND_VALUES: readonly ['xctrace', 'simpleperf', 'perfetto', 'android-hprof', 'memgraph'];
|
|
937
940
|
|
|
938
|
-
declare const PERF_SUBJECT_VALUES: readonly [
|
|
941
|
+
declare const PERF_SUBJECT_VALUES: readonly ['profile'];
|
|
939
942
|
|
|
940
943
|
declare type PerfAction = (typeof PERF_ACTION_VALUES)[number];
|
|
941
944
|
|
|
@@ -967,7 +970,7 @@ declare type Platform = (typeof PLATFORMS)[number];
|
|
|
967
970
|
|
|
968
971
|
declare const PLATFORM_SELECTORS: readonly ["ios", "macos", "android", "linux", "apple"];
|
|
969
972
|
|
|
970
|
-
declare const PLATFORMS: readonly [
|
|
973
|
+
declare const PLATFORMS: readonly ['ios', 'macos', 'android', 'linux'];
|
|
971
974
|
|
|
972
975
|
declare type PlatformSelector = (typeof PLATFORM_SELECTORS)[number];
|
|
973
976
|
|
|
@@ -1158,9 +1161,9 @@ export declare type ScreenshotOverlayRef = {
|
|
|
1158
1161
|
center: Point;
|
|
1159
1162
|
};
|
|
1160
1163
|
|
|
1161
|
-
declare const SCROLL_DIRECTIONS: readonly [
|
|
1164
|
+
declare const SCROLL_DIRECTIONS: readonly ['up', 'down', 'left', 'right'];
|
|
1162
1165
|
|
|
1163
|
-
declare const SCROLL_INPUT_DIRECTIONS: readonly [
|
|
1166
|
+
declare const SCROLL_INPUT_DIRECTIONS: readonly ['up', 'down', 'left', 'right', 'top', 'bottom'];
|
|
1164
1167
|
|
|
1165
1168
|
declare type ScrollDirection = (typeof SCROLL_DIRECTIONS)[number];
|
|
1166
1169
|
|
|
@@ -1183,9 +1186,9 @@ declare type SelectorTarget = {
|
|
|
1183
1186
|
label?: never;
|
|
1184
1187
|
};
|
|
1185
1188
|
|
|
1186
|
-
declare const SESSION_ISOLATION_MODES: readonly [
|
|
1189
|
+
declare const SESSION_ISOLATION_MODES: readonly ['none', 'tenant'];
|
|
1187
1190
|
|
|
1188
|
-
declare const SESSION_SURFACES: readonly [
|
|
1191
|
+
declare const SESSION_SURFACES: readonly ['app', 'frontmost-app', 'desktop', 'menubar'];
|
|
1189
1192
|
|
|
1190
1193
|
export declare type SessionCloseResult = {
|
|
1191
1194
|
session: string;
|
|
@@ -1312,9 +1315,9 @@ export declare type StartupPerfSample = {
|
|
|
1312
1315
|
appBundleId?: string;
|
|
1313
1316
|
};
|
|
1314
1317
|
|
|
1315
|
-
declare const SWIPE_PATTERNS: readonly [
|
|
1318
|
+
declare const SWIPE_PATTERNS: readonly ['one-way', 'ping-pong'];
|
|
1316
1319
|
|
|
1317
|
-
declare const SWIPE_PRESETS: readonly [
|
|
1320
|
+
declare const SWIPE_PRESETS: readonly ['left', 'right', 'left-edge', 'right-edge'];
|
|
1318
1321
|
|
|
1319
1322
|
declare type SwipeGestureOptions = DeviceCommandBaseOptions & {
|
|
1320
1323
|
preset: SwipePreset;
|
package/dist/src/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{AppError,isAgentDeviceError,normalizeAgentDeviceError}from"./
|
|
1
|
+
export{AppError,isAgentDeviceError,normalizeAgentDeviceError}from"./733.js";export{centerOfRect}from"./4291.js";export{createAgentDeviceClient}from"./9919.js";export{createLocalArtifactAdapter}from"./314.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{emitDiagnostic as t}from"./
|
|
1
|
+
import{emitDiagnostic as t}from"./432.js";import{runAndroidAdb as e}from"./3340.js";import{getAndroidKeyboardState as n,isAndroidInputMethodOwnedNode as a}from"./9624.js";import{captureAndroidUiHierarchyXml as r}from"./9722.js";import{androidUiNodes as i}from"./7394.js";import{AppError as o}from"./733.js";import{buildScrollGesturePlan as u}from"./9873.js";import{resolveAndroidTextInjector as l}from"./2954.js";import{sleep as c}from"./5560.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,a){let r=null,i=null,o=await y(t);for(let u of[0,150,350]){u>0&&await c(u);let l=await g(t,e,n,a,o);if(r=l,"ime_capture"===l.reason)return l;i=l.ok?l:null}return i??r??{ok:!1,actual:null,reason:"text_mismatch",targetInput:null,actualInput:null}}async function h(t,e,n){var a,i,o;return a=await r(t),i=e,o=n,m(a,i,o).actualInput?.text??null}async function g(t,e,n,a,i){return function(t,e,n,a,r={}){var i,o;let u,l=m(t,e,n,r);return!function(t){let{targetInput:e,actualInput:n}=t;return!!e&&!!n&&n!==e&&n.inputMethodOwned&&!e.inputMethodOwned}(l)?function(t,e){let n=t.actualInput;if(!n||!s(n))return null;let a=n.text??null,r=Array.from(a??"").length,i=Array.from(e).length,o=null!==a&&r>0&&i>0&&r===i;return{ok:o,actual:a,reason:o?void 0:"masked_unverified",masked:!0,targetInput:t.targetInput,actualInput:n}}(l,a)??(i=l,o=a,{ok:function(t,e){if(t===e)return!0;let n=w(t),a=w(e);return!!n&&!!a&&!!(n===a||function(t,e){if(t.length!==e.length||0===t.length||t.slice(1)!==e.slice(1))return!1;let n=t[0],a=e[0];return!!n&&!!a&&a.toLowerCase()===a&&n===a.toUpperCase()}(n,a))}(u=i.actualInput?.text??null,o),actual:u,reason:"text_mismatch",targetInput:i.targetInput,actualInput:i.actualInput}):{ok:!1,actual:l.actualInput?.text??null,reason:"ime_capture",targetInput:l.targetInput,actualInput:l.actualInput}}(await r(t),e,n,a,i)}function m(t,e,n,r={}){var o;let u,l={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??"",r=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:a({packageName:t.packageName,resourceId:t.resourceId,activeInputMethodPackage:e.activeInputMethodPackage}),area:r,editText:function(t){let e=t.toLowerCase();return e.includes("edittext")||e.includes("textfield")}(t.className??"")}}(o,r);t&&function(t,e,n,a){var r,i,o;let u=(r=e.rect,i=n,o=a,i>=r.x&&i<=r.x+r.width&&o>=r.y&&o<=r.y+r.height);if(u&&e.editText&&(t.editAtPoint=_(t.editAtPoint,e)),e.focused&&e.editText){t.focusedEdit=_(t.focusedEdit,e);return}u&&e.text&&(t.anyAtPoint=_(t.anyAtPoint,e))}(l,t,e,n)}return{targetInput:u=(o=l).editAtPoint??o.anyAtPoint,actualInput:(o.focusedEdit?.text?o.focusedEdit:null)??u}}function w(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,a){await e(t,["shell","input","tap",String(n),String(a)])}async function x(t,n,a,r,i,o=250){await e(t,["shell","input","swipe",String(n),String(a),String(r),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 a=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",a])}async function E(t){await e(t,["shell","input","keyevent","187"])}async function v(t,n,a,r=800){await e(t,["shell","input","swipe",String(n),String(a),String(n),String(a),String(r)])}async function C(t,e,n=0){let a=l(t);if(a){await a({action:"type",text:e,delayMs:n}),T("type","provider-native",e);return}(z(e),await D(t,"type"),n>0&&Array.from(e).length>1)?await L(t,{action:"type",text:e,chunkSize:1,delayMs:n}):await L(t,{action:"type",text:e,chunkSize:O,delayMs:0})}async function P(t,e,n){await A(t,e,n)}async function N(t,e,n,a,r=0){let i=l(t);if(i){await i({action:"fill",target:{x:e,y:n},text:a,delayMs:r}),T("fill","provider-native",a);let o=await p(t,e,n,a);if(o.ok)return;b(a,o)}z(a);let o=Array.from(a).length,u=null;for(let i of[{clearPadding:12,minClear:8,maxClear:48,chunkSize:r>0?1:O,inputDelayMs:r},{clearPadding:24,minClear:16,maxClear:96,chunkSize:r>0?1:4,inputDelayMs:r>0?r:15}]){var c,s;await P(t,e,n),await D(t,"fill");let r=(c=o+i.clearPadding,s=i.minClear,Math.max(s,Math.min(i.maxClear,c)));await F(t,r),await L(t,{action:"fill",text:a,chunkSize:i.chunkSize,delayMs:i.inputDelayMs});let l=await p(t,e,n,a);if(u=l,l.ok)return;"ime_capture"===l.reason&&b(a,l)}b(a,u)}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 a=!0===(n=e).masked||s(n.targetInput)||s(n.actualInput),r={failureReason:e.reason??"text_mismatch",targetInput:d(e.targetInput),actualInput:d(e.actualInput)};return a?{...r,expectedLength:Array.from(t).length,actual:null,masked:!0,actualLength:Array.from(e.actual??"").length}:{...r,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,a){let r=await R(t),i=u({direction:n,amount:a?.amount,pixels:a?.pixels,referenceWidth:r.width,referenceHeight:r.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,a){let r;try{r=await n(e)}catch(e){t({level:"warn",phase:"android_input_ownership_probe_failed",data:{action:a,error:e instanceof Error?e.message:String(e)}});return}if("ime"===r.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:a,inputOwner:r.inputOwner,inputType:r.inputType,type:r.type,inputMethodPackage:r.inputMethodPackage,focusedPackage:r.focusedPackage,focusedResourceId:r.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])}}let O=8;async function L(t,n){let a=n.text.split("\n");for(let[r,i]of a.entries()){let o=function(t,e){let n=Math.max(1,Math.floor(e)),a=[],r=Array.from(t);for(let t=0;t<r.length;t+=n)a.push(r.slice(t,t+n).join(""));return a.length>0?a:[""]}(i,n.chunkSize);for(let[e,i]of o.entries())await U(t,i),n.delayMs>0&&(e+1<o.length||r+1<a.length)&&await c(n.delayMs);r+1<a.length&&await e(t,["shell","input","keyevent","ENTER"])}T(n.action,"adb-shell",n.text)}async function U(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 H(n,t);throw t}}function z(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 H(t)}function H(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 T(e,n,a){t({phase:"android_text_injection",data:{action:e,backend:n,textLength:Array.from(a).length}})}async function F(t,n){let a=Math.max(0,n);await e(t,["shell","input","keyevent","KEYCODE_MOVE_END"],{allowFailure:!0});for(let n=0;n<a;n+=24){let r=Math.min(24,a-n);await e(t,["shell","input","keyevent",...Array(r).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};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{AppError as a}from"./
|
|
1
|
+
import{AppError as a}from"./733.js";import{resolveLinuxToolProvider as t}from"./9722.js";import{sleep as i}from"./5560.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};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export{ARCHIVE_EXTENSIONS,isBlockedIpAddress,isBlockedSourceHostname,isTrustedInstallSourceUrl,materializeInstallablePath,validateDownloadSourceUrl}from"./
|
|
1
|
+
export{ARCHIVE_EXTENSIONS,isBlockedIpAddress,isBlockedSourceHostname,isTrustedInstallSourceUrl,materializeInstallablePath,validateDownloadSourceUrl}from"./5484.js";
|
package/dist/src/interaction.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{__webpack_require__ as e}from"./rslib-runtime.js";import{createDaemonRuntimeSessionStore as t,setSessionSnapshot as r,dispatchCommand as a,ensureAndroidBlockingSystemDialogReady as n,isCommandSupportedOnDevice as s,errorResponse as o,recoverAndroidBlockingSystemDialog as i,getActiveAndroidSnapshotFreshness as l}from"./2415.js";import{createAgentDevice as c}from"./123.js";import{asAppError as u,normalizeError as f,AppError as d}from"./9152.js";import{dispatchGetViaRuntime as p,isAndroidEscapeError as g,createDaemonRuntimePolicy as m,assertAndroidPressStayedInApp as S,dispatchIsViaRuntime as k,isDirectIosSelectorFallbackError as y,refSnapshotFlagGuardResponse as _,readSimpleIosSelectorTarget as h}from"./selector-runtime.js";import{buttonTag as w,resolveClickButton as b,readFillTargetFromPositionals as v,getClickButtonValidationError as x,successText as N}from"./6133.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 I}from"./7599.js";import{PUBLIC_COMMANDS as C}from"./6088.js";var A={};function E(e,t){return"macos"!==e.device.platform||"desktop"!==e.surface&&"menubar"!==e.surface||"menubar"===e.surface&&("click"===t||"press"===t)?null:o("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 q(e){let n=e.sessionStore.get(e.sessionName);if(!n)throw new d("SESSION_NOT_FOUND","No active session. Run open first.");return c({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}),...m("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 D(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 T(e,t){let r=D(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:e.slice(1).join(" ").trim()}};let n=e.join(" ").trim();return n?{ok:!0,target:{kind:"selector",selector:n}}:{ok:!1,response:o("INVALID_ARGS",`${t} requires @ref, selector expression, or x y coordinates`)}}function H(e){return"ref"===e.kind?{ref:K(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 K(e){return e?.startsWith("@")?e.slice(1):e}async function L(e){switch(e.req.command){case"press":return await j(e,"press");case"click":return await j(e,"click");case"longpress":return await j(e,"longpress");case"fill":return await V(e);default:return null}}async function j(e,t){let r,{req:a,sessionName:n,sessionStore:i}=e,l=i.get(n);if(!l)return o("SESSION_NOT_FOUND","No active session. Run open first.");let c="click"===t?"click":t,u="longpress"===t?"longpress":"press",f=E(l,c);if(f)return f;if(!s(u,l.device))return o("UNSUPPORTED_OPERATION",`${u} is not supported on this device`);let d=b(a.flags),p=w(d);if("longpress"!==t&&"primary"!==d){let e=x({commandLabel:c,platform:l.device.platform,button:d,count:a.flags?.count,intervalMs:a.flags?.intervalMs,holdMs:a.flags?.holdMs,jitterPx:a.flags?.jitterPx,doubleTap:a.flags?.doubleTap});if(e)return o(e.code,e.message,e.details)}let g="longpress"===t?function(e){var t,r,a;let n,s=D(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=T(o.targetPositionals,"longpress");return i.ok?{ok:!0,target:i.target,...o.duration}:i}(a.positionals??[]):T(a.positionals??[],c);if(!g.ok)return g.response;if("ref"===g.target.kind){let n=e.refSnapshotFlagGuardResponse("longpress"===t?"longpress":"press",a.flags);if(n)return n;r=await z(e,l)}let m=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=h({session:r,selectorExpression:n.selector});return o?{...o,...s?.maestro?.allowNonHittableCoordinateFallback?{allowNonHittableCoordinateFallback:!0}:{}}:null}({session:l,commandLabel:c,target:g.target,flags:a.flags});if(m){let t=await W(e,l,m);if(t)return t}let k="longpress"===t?g.durationMs:void 0;return await Y(e,{androidFreshnessBaseline:r,run:async e=>await B({runtime:e,command:t,target:g.target,sessionName:n,requestId:a.meta?.requestId,clickButton:d,flags:a.flags,durationMs:k}),afterRun:async e=>{var t;await S(l,(t=g.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 G({params:e,session:l,result:r,extra:"longpress"===t?{...void 0!==n?{durationMs:n}:{},gesture:"longpress"}:p});return{result:s,responseData:s}}})}async function B(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 G(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:{...H(a),...n}})}async function W(e,t,r){return await $({params:e,session:t,selector:r,command:"press",positionals:[],extra:{selector:r.raw},fallbackPhase:"ios_direct_selector_tap_fallback"})}async function $(e){let{params:t,session:r,selector:n,command:s,positionals:o,extra:i,fallbackPhase:l}=e,c=Date.now();try{var u,d;let e,l,f=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=f,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:f,fallbackX:g.x,fallbackY:g.y,referenceFrame:(d=f,"number"==typeof d.referenceWidth&&"number"==typeof d.referenceHeight?{referenceWidth:d.referenceWidth,referenceHeight:d.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,f)}});return O({session:r,sessionStore:t.sessionStore,command:t.req.command,positionals:t.req.positionals??[],retryPositionals:J(g),flags:t.req.flags,result:m,responseData:m,actionStartedAt:c,actionFinishedAt:p})}catch(e){if(!y(e))return{ok:!1,error:f(e)};return I({level:"debug",phase:l,data:{selector:n.raw,error:e instanceof Error?e.message:String(e)}}),null}}async function V(e){let{req:t,sessionName:r,sessionStore:a}=e,n=a.get(r);if(n){let e=E(n,"fill");if(e)return e}if(n&&!s("fill",n.device))return o("UNSUPPORTED_OPERATION","fill is not supported on this device");if(!n)return o("SESSION_NOT_FOUND","No active session. Run open first.");let i=function(e){let t=e[0]??"";if(t.startsWith("@")){var r;let a=v(e).text;return a?{ok:!0,target:{kind:"ref",ref:t,fallbackLabel:(r=e).length>=3&&r[1]?.trim()||""},text:a}:{ok:!1,response:o("INVALID_ARGS","fill requires text after ref")}}let a=D(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:o("INVALID_ARGS","fill requires text after coordinates")}}let n=v(e);return"selector"!==n.kind?{ok:!1,response:o("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:o("INVALID_ARGS","fill requires text after selector")}}(t.positionals??[]);if(!i.ok)return i.response;if("ref"===i.target.kind){let r=e.refSnapshotFlagGuardResponse("fill",t.flags);if(r)return r;await z(e,n)}let l=function(e){let{session:t,target:r,flags:a}=e;if("selector"!==r.kind)return null;let n=h({session:t,selectorExpression:r.selector});return n?{...n,...a?.maestro?.allowNonHittableCoordinateFallback?{allowNonHittableCoordinateFallback:!0}:{}}:null}({session:n,target:i.target,flags:t.flags});if(l){let t=await X(e,n,l,i.text);if(t)return t}return await Y(e,{run:async e=>await e.interactions.fill(i.target,i.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:{...H(e),text:i.text}});e.warning&&(r.warning=e.warning);let a="ref"===e.kind?{...e.backendResult??{ref:K(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 X(e,t,r,a){return await $({params:e,session:t,selector:r,command:"fill",positionals:[a],extra:{selector:r.raw,text:a},fallbackPhase:"ios_direct_selector_fill_fallback"})}async function Y(e,t){let r=e.sessionStore.get(e.sessionName);if(!r)return o("SESSION_NOT_FOUND","No active session. Run open first.");let a=q(e),s=Date.now();try{let o=await n({session:r,command:e.req.command,phase:"before-command"}),i=await t.run(a);await t.afterRun?.(i),await n({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??[],retryPositionals:function(e,t){if("click"===e||"press"===e)return J(t.point)}(e.req.command,i),flags:e.req.flags,result:c,responseData:u,actionStartedAt:s,actionFinishedAt:l,androidFreshnessBaseline:t.androidFreshnessBaseline})}catch(t){let e=u(t);if(g(e))throw e;return{ok:!1,error:f(t)}}}async function z(e,t){if(!l(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){I({level:"warn",phase:"android_ref_snapshot_refresh_failed",data:{command:e.req.command,error:t instanceof Error?t.message:String(t)}})}return r}function J(e){return[String(e.x),String(e.y)]}async function Q(e){let t=await L({...e,captureSnapshotForSession:F,refSnapshotFlagGuardResponse:_});if(t)return t;switch(e.req.command){case C.type:return await Z({...e,captureSnapshotForSession:F});case"get":return await p(e);case"is":return await k(e);default:return null}}async function Z(e){let{sessionName:t,sessionStore:r}=e,a=r.get(t);if(!a)return o("SESSION_NOT_FOUND","No active session. Run open first.");if(!s(C.type,a.device))return o("UNSUPPORTED_OPERATION","type is not supported on this device");let n=await ee(a);return n||await et(e,a)}async function ee(e){return"android"===e.device.platform&&e.recording&&"failed"===(await i({session:e})).status?o("COMMAND_FAILED","Android system dialog blocked the recording session"):null}async function et(e,t){let{req:r,sessionName:a,sessionStore:s}=e,o=(r.positionals??[]).join(" "),i=q(e),l=Date.now();try{let e=await n({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 n({session:t,command:r.command,phase:"after-command"});let u=Date.now(),f={...c.backendResult??{},text:c.text,delayMs:c.delayMs,...N(c.message??`Typed ${Array.from(c.text).length} chars`)};return"recovered"===e.status&&(f.warning=e.warning),O({session:t,sessionStore:s,command:r.command,positionals:r.positionals??[],flags:r.flags,result:f,responseData:f,actionStartedAt:l,actionFinishedAt:u})}catch(e){return{ok:!1,error:f(e)}}}e.r(A),e.d(A,{handleInteractionCommands:()=>Q});export{A as interaction_namespaceObject};
|
|
1
|
+
import{__webpack_require__ as e}from"./rslib-runtime.js";import{createDaemonRuntimeSessionStore as t,setSessionSnapshot as r,dispatchCommand as a,ensureAndroidBlockingSystemDialogReady as n,isCommandSupportedOnDevice as s,errorResponse as o,recoverAndroidBlockingSystemDialog as i,getActiveAndroidSnapshotFreshness as l}from"./9722.js";import{createAgentDevice as c}from"./5299.js";import{asAppError as u,normalizeError as f,AppError as d}from"./733.js";import{dispatchGetViaRuntime as p,isAndroidEscapeError as g,createDaemonRuntimePolicy as m,assertAndroidPressStayedInApp as S,dispatchIsViaRuntime as k,isDirectIosSelectorFallbackError as y,refSnapshotFlagGuardResponse as _,readSimpleIosSelectorTarget as h}from"./selector-runtime.js";import{buttonTag as w,resolveClickButton as b,readFillTargetFromPositionals as v,getClickButtonValidationError as x,successText as N}from"./9873.js";import{interaction_snapshot_captureSnapshotForSession as F,readSnapshotNodesReferenceFrame as P,resolveDirectTouchReferenceFrameSafely as R,buildTouchVisualizationResult as M,finalizeTouchInteraction as O}from"./8184.js";import{emitDiagnostic as I}from"./432.js";import{PUBLIC_COMMANDS as C}from"./2133.js";var A={};function E(e,t){return"macos"!==e.device.platform||"desktop"!==e.surface&&"menubar"!==e.surface||"menubar"===e.surface&&("click"===t||"press"===t)?null:o("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 q(e){let n=e.sessionStore.get(e.sessionName);if(!n)throw new d("SESSION_NOT_FOUND","No active session. Run open first.");return c({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}),...m("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 D(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 T(e,t){let r=D(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:e.slice(1).join(" ").trim()}};let n=e.join(" ").trim();return n?{ok:!0,target:{kind:"selector",selector:n}}:{ok:!1,response:o("INVALID_ARGS",`${t} requires @ref, selector expression, or x y coordinates`)}}function H(e){return"ref"===e.kind?{ref:K(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 K(e){return e?.startsWith("@")?e.slice(1):e}async function L(e){switch(e.req.command){case"press":return await j(e,"press");case"click":return await j(e,"click");case"longpress":return await j(e,"longpress");case"fill":return await V(e);default:return null}}async function j(e,t){let r,{req:a,sessionName:n,sessionStore:i}=e,l=i.get(n);if(!l)return o("SESSION_NOT_FOUND","No active session. Run open first.");let c="click"===t?"click":t,u="longpress"===t?"longpress":"press",f=E(l,c);if(f)return f;if(!s(u,l.device))return o("UNSUPPORTED_OPERATION",`${u} is not supported on this device`);let d=b(a.flags),p=w(d);if("longpress"!==t&&"primary"!==d){let e=x({commandLabel:c,platform:l.device.platform,button:d,count:a.flags?.count,intervalMs:a.flags?.intervalMs,holdMs:a.flags?.holdMs,jitterPx:a.flags?.jitterPx,doubleTap:a.flags?.doubleTap});if(e)return o(e.code,e.message,e.details)}let g="longpress"===t?function(e){var t,r,a;let n,s=D(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=T(o.targetPositionals,"longpress");return i.ok?{ok:!0,target:i.target,...o.duration}:i}(a.positionals??[]):T(a.positionals??[],c);if(!g.ok)return g.response;if("ref"===g.target.kind){let n=e.refSnapshotFlagGuardResponse("longpress"===t?"longpress":"press",a.flags);if(n)return n;r=await z(e,l)}let m=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=h({session:r,selectorExpression:n.selector});return o?{...o,...s?.maestro?.allowNonHittableCoordinateFallback?{allowNonHittableCoordinateFallback:!0}:{}}:null}({session:l,commandLabel:c,target:g.target,flags:a.flags});if(m){let t=await W(e,l,m);if(t)return t}let k="longpress"===t?g.durationMs:void 0;return await Y(e,{androidFreshnessBaseline:r,run:async e=>await B({runtime:e,command:t,target:g.target,sessionName:n,requestId:a.meta?.requestId,clickButton:d,flags:a.flags,durationMs:k}),afterRun:async e=>{var t;await S(l,(t=g.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 G({params:e,session:l,result:r,extra:"longpress"===t?{...void 0!==n?{durationMs:n}:{},gesture:"longpress"}:p});return{result:s,responseData:s}}})}async function B(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 G(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:{...H(a),...n}})}async function W(e,t,r){return await $({params:e,session:t,selector:r,command:"press",positionals:[],extra:{selector:r.raw},fallbackPhase:"ios_direct_selector_tap_fallback"})}async function $(e){let{params:t,session:r,selector:n,command:s,positionals:o,extra:i,fallbackPhase:l}=e,c=Date.now();try{var u,d;let e,l,f=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=f,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:f,fallbackX:g.x,fallbackY:g.y,referenceFrame:(d=f,"number"==typeof d.referenceWidth&&"number"==typeof d.referenceHeight?{referenceWidth:d.referenceWidth,referenceHeight:d.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,f)}});return O({session:r,sessionStore:t.sessionStore,command:t.req.command,positionals:t.req.positionals??[],retryPositionals:J(g),flags:t.req.flags,result:m,responseData:m,actionStartedAt:c,actionFinishedAt:p})}catch(e){if(!y(e))return{ok:!1,error:f(e)};return I({level:"debug",phase:l,data:{selector:n.raw,error:e instanceof Error?e.message:String(e)}}),null}}async function V(e){let{req:t,sessionName:r,sessionStore:a}=e,n=a.get(r);if(n){let e=E(n,"fill");if(e)return e}if(n&&!s("fill",n.device))return o("UNSUPPORTED_OPERATION","fill is not supported on this device");if(!n)return o("SESSION_NOT_FOUND","No active session. Run open first.");let i=function(e){let t=e[0]??"";if(t.startsWith("@")){var r;let a=v(e).text;return a?{ok:!0,target:{kind:"ref",ref:t,fallbackLabel:(r=e).length>=3&&r[1]?.trim()||""},text:a}:{ok:!1,response:o("INVALID_ARGS","fill requires text after ref")}}let a=D(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:o("INVALID_ARGS","fill requires text after coordinates")}}let n=v(e);return"selector"!==n.kind?{ok:!1,response:o("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:o("INVALID_ARGS","fill requires text after selector")}}(t.positionals??[]);if(!i.ok)return i.response;if("ref"===i.target.kind){let r=e.refSnapshotFlagGuardResponse("fill",t.flags);if(r)return r;await z(e,n)}let l=function(e){let{session:t,target:r,flags:a}=e;if("selector"!==r.kind)return null;let n=h({session:t,selectorExpression:r.selector});return n?{...n,...a?.maestro?.allowNonHittableCoordinateFallback?{allowNonHittableCoordinateFallback:!0}:{}}:null}({session:n,target:i.target,flags:t.flags});if(l){let t=await X(e,n,l,i.text);if(t)return t}return await Y(e,{run:async e=>await e.interactions.fill(i.target,i.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:{...H(e),text:i.text}});e.warning&&(r.warning=e.warning);let a="ref"===e.kind?{...e.backendResult??{ref:K(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 X(e,t,r,a){return await $({params:e,session:t,selector:r,command:"fill",positionals:[a],extra:{selector:r.raw,text:a},fallbackPhase:"ios_direct_selector_fill_fallback"})}async function Y(e,t){let r=e.sessionStore.get(e.sessionName);if(!r)return o("SESSION_NOT_FOUND","No active session. Run open first.");let a=q(e),s=Date.now();try{let o=await n({session:r,command:e.req.command,phase:"before-command"}),i=await t.run(a);await t.afterRun?.(i),await n({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??[],retryPositionals:function(e,t){if("click"===e||"press"===e)return J(t.point)}(e.req.command,i),flags:e.req.flags,result:c,responseData:u,actionStartedAt:s,actionFinishedAt:l,androidFreshnessBaseline:t.androidFreshnessBaseline})}catch(t){let e=u(t);if(g(e))throw e;return{ok:!1,error:f(t)}}}async function z(e,t){if(!l(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){I({level:"warn",phase:"android_ref_snapshot_refresh_failed",data:{command:e.req.command,error:t instanceof Error?t.message:String(t)}})}return r}function J(e){return[String(e.x),String(e.y)]}async function Q(e){let t=await L({...e,captureSnapshotForSession:F,refSnapshotFlagGuardResponse:_});if(t)return t;switch(e.req.command){case C.type:return await Z({...e,captureSnapshotForSession:F});case"get":return await p(e);case"is":return await k(e);default:return null}}async function Z(e){let{sessionName:t,sessionStore:r}=e,a=r.get(t);if(!a)return o("SESSION_NOT_FOUND","No active session. Run open first.");if(!s(C.type,a.device))return o("UNSUPPORTED_OPERATION","type is not supported on this device");let n=await ee(a);return n||await et(e,a)}async function ee(e){return"android"===e.device.platform&&e.recording&&"failed"===(await i({session:e})).status?o("COMMAND_FAILED","Android system dialog blocked the recording session"):null}async function et(e,t){let{req:r,sessionName:a,sessionStore:s}=e,o=(r.positionals??[]).join(" "),i=q(e),l=Date.now();try{let e=await n({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 n({session:t,command:r.command,phase:"after-command"});let u=Date.now(),f={...c.backendResult??{},text:c.text,delayMs:c.delayMs,...N(c.message??`Typed ${Array.from(c.text).length} chars`)};return"recovered"===e.status&&(f.warning=e.warning),O({session:t,sessionStore:s,command:r.command,positionals:r.positionals??[],flags:r.flags,result:f,responseData:f,actionStartedAt:l,actionFinishedAt:u})}catch(e){return{ok:!1,error:f(e)}}}e.r(A),e.d(A,{handleInteractionCommands:()=>Q});export{A as interaction_namespaceObject};
|
package/dist/src/internal/bin.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
var t,
|
|
2
|
-
`),process.exit(1)}1===(e=
|
|
3
|
-
`)
|
|
4
|
-
`),process.exit(1)}).catch(
|
|
5
|
-
`);let
|
|
1
|
+
var e,t,r,s;let n,o=process.argv.slice(2);function c(e){return"--help"===e||"-h"===e}function i(e){import("../cli.js").then(({runCli:t})=>t(e)).catch(p)}function p(e){process.stderr.write(`${e instanceof Error?e.message:String(e)}
|
|
2
|
+
`),process.exit(1)}1===(t=e=o).length&&("--version"===(r=t[0])||"-V"===r)&&(process.stdout.write(`0.17.6
|
|
3
|
+
`),1)||0===e.length&&(import("../cli-help.js").then(({buildUsageText:e})=>{process.stdout.write(`${e()}
|
|
4
|
+
`),process.exit(1)}).catch(p),1)||void 0!==(n=function(e){var t,r,s,n;switch(e.length){case 1:return"help"===(t=e[0])||c(t)?null:void 0;case 2:return r=e[0],s=e[1],"help"===r?s:(n=r,c(s)?n:void 0);default:return}}(s=e))&&(import("../cli-help.js").then(({buildCommandUsageText:e,buildUsageText:t})=>{var r;if(null===n)return void process.stdout.write(`${t()}
|
|
5
|
+
`);let o=e("long-press"===(r=n)?"longpress":"metrics"===r?"perf":r);o?process.stdout.write(o):i(s)}).catch(p),1)||("mcp"!==o[0]||o.includes("--help")||o.includes("-h")?i(o):import("../server.js").then(({runAgentDeviceMcpServer:e})=>e()).catch(p));export{};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import e from"node:fs";import{setTimeout as r}from"node:timers/promises";import{normalizeBaseUrl as t,ENV_COMPANION_TUNNEL_UNREGISTER_PATH as n,MissingCompanionEnvError as s,ENV_COMPANION_TUNNEL_SERVER_BASE_URL as a,ENV_COMPANION_TUNNEL_STATE_PATH as o,ENV_COMPANION_TUNNEL_LAUNCH_URL as i,ENV_COMPANION_TUNNEL_SCOPE_LEASE_ID as c,ENV_COMPANION_TUNNEL_SCOPE_TENANT_ID as l,ENV_COMPANION_TUNNEL_DEVICE_PORT as f,METRO_COMPANION_RUN_ARG as u,ENV_COMPANION_TUNNEL_SESSION as d,ENV_COMPANION_TUNNEL_SCOPE_RUN_ID as m,ENV_COMPANION_TUNNEL_REGISTER_PATH as y,ENV_COMPANION_TUNNEL_LOCAL_BASE_URL as p,REACT_DEVTOOLS_COMPANION_RUN_ARG as g,ENV_COMPANION_TUNNEL_BEARER_TOKEN as w}from"../
|
|
1
|
+
import e from"node:fs";import{setTimeout as r}from"node:timers/promises";import{normalizeBaseUrl as t,ENV_COMPANION_TUNNEL_UNREGISTER_PATH as n,MissingCompanionEnvError as s,ENV_COMPANION_TUNNEL_SERVER_BASE_URL as a,ENV_COMPANION_TUNNEL_STATE_PATH as o,ENV_COMPANION_TUNNEL_LAUNCH_URL as i,ENV_COMPANION_TUNNEL_SCOPE_LEASE_ID as c,ENV_COMPANION_TUNNEL_SCOPE_TENANT_ID as l,ENV_COMPANION_TUNNEL_DEVICE_PORT as f,METRO_COMPANION_RUN_ARG as u,ENV_COMPANION_TUNNEL_SESSION as d,ENV_COMPANION_TUNNEL_SCOPE_RUN_ID as m,ENV_COMPANION_TUNNEL_REGISTER_PATH as y,ENV_COMPANION_TUNNEL_LOCAL_BASE_URL as p,REACT_DEVTOOLS_COMPANION_RUN_ARG as g,ENV_COMPANION_TUNNEL_BEARER_TOKEN as w}from"../4069.js";class h extends Error{retryable;retryAfterMs;constructor(e,r,t){super(e),this.retryable=r,this.retryAfterMs=t}}function b(e,r){return{authorization:`Bearer ${r}`,"content-type":"application/json",...e.includes("ngrok")?{"ngrok-skip-browser-warning":"1"}:{}}}function S(e){return{...e.bridgeScope,...e.session?{session:e.session}:{},local_base_url:t(e.localBaseUrl),...e.devicePort?{device_port:e.devicePort}:{},...e.launchUrl?{launch_url:e.launchUrl}:{}}}async function v(e){let r,n,s=e.registerPath;try{r=await fetch(`${t(e.serverBaseUrl)}${s}`,{method:"POST",headers:b(e.serverBaseUrl,e.bearerToken),body:JSON.stringify(S(e)),signal:AbortSignal.timeout(5e3)})}catch(r){if(r instanceof Error&&"TimeoutError"===r.name)throw Error(`${s} timed out after 5000ms calling ${t(e.serverBaseUrl)}${s}`);throw r}let a=await r.text();try{n=a?JSON.parse(a):{}}catch{let e;throw new h(`Failed to register companion (${r.status}): invalid JSON response: ${(e=a.replaceAll(/\s+/g," ").trim()).length>300?`${e.slice(0,300)}...`:e}`,I(r.status,void 0),E(r,{}))}if(!r.ok||!0!==n.ok||"string"!=typeof n.data?.ws_url)throw new h(`Failed to register companion (${r.status}): ${JSON.stringify(n)}`,I(r.status,n.error?.code),E(r,n));return{wsUrl:n.data.ws_url}}function I(e,r){return"RATE_LIMITED"===r||"UNAUTHORIZED"!==r&&"INVALID_ARGS"!==r&&"SESSION_NOT_FOUND"!==r&&(408===e||409===e||425===e||429===e||e>=500)}function E(e,r){let t=r.error?.details?.retryAfterMs;if("number"==typeof t&&Number.isFinite(t))return B(t);let n=e.headers.get("retry-after");if(!n)return;let s=Number(n);if(Number.isFinite(s))return B(1e3*s);let a=Date.parse(n);if(Number.isFinite(a))return B(a-Date.now())}function B(e){return Math.max(0,Math.min(6e4,Math.ceil(e)))}async function N(e){let r=e.unregisterPath??null;if(r)try{await fetch(`${t(e.serverBaseUrl)}${r}`,{method:"POST",headers:b(e.serverBaseUrl,e.bearerToken),body:JSON.stringify(S(e)),signal:AbortSignal.timeout(2e3)})}catch(e){console.error(e instanceof Error?e.message:String(e))}}async function k(e){return"string"==typeof e?Buffer.from(e,"utf8"):e instanceof ArrayBuffer?Buffer.from(e):ArrayBuffer.isView(e)?Buffer.from(e.buffer,e.byteOffset,e.byteLength):"u">typeof Blob&&e instanceof Blob?Buffer.from(await e.arrayBuffer()):Buffer.from(String(e),"utf8")}async function L(e){return JSON.parse((await k(e.data)).toString("utf8"))}function U(e,r){1===e.readyState&&e.send(JSON.stringify(r))}async function P(e,r){1!==e.readyState&&await new Promise((t,n)=>{let s=()=>{i(),t()},a=()=>{i(),n(Error(`${r} WebSocket failed before opening.`))},o=()=>{i(),n(Error(`${r} WebSocket closed before opening.`))},i=()=>{e.removeEventListener("open",s),e.removeEventListener("error",a),e.removeEventListener("close",o)};e.addEventListener("open",s,{once:!0}),e.addEventListener("error",a,{once:!0}),e.addEventListener("close",o,{once:!0})})}async function O(e){e.readyState>=WebSocket.CLOSING||await new Promise(r=>{let t=()=>{n(),r()},n=()=>{e.removeEventListener("close",t),e.removeEventListener("error",t)};e.addEventListener("close",t,{once:!0}),e.addEventListener("error",t,{once:!0}),e.readyState>=WebSocket.CLOSING&&t()})}function T(e,r,t){try{e.close(1e3===r||r>=3e3&&r<=4999?r:3001,t)}catch{}}function $(r){return!r.statePath||e.existsSync(r.statePath)}async function M(e,r,n){try{let s=await fetch(new URL(r.path,`${t(n.localBaseUrl)}/`),{method:r.method,headers:r.headers,...r.bodyBase64?{body:Buffer.from(r.bodyBase64,"base64")}:{}}),a=Buffer.from(await s.arrayBuffer());U(e,{type:"http-response",requestId:r.requestId,status:s.status,headers:Object.fromEntries(s.headers.entries()),...a.length>0?{bodyBase64:a.toString("base64")}:{}})}catch(t){U(e,{type:"http-error",requestId:r.requestId,message:t instanceof Error?t.message:String(t)})}}async function _(e,r,n,s){var a;let o,i=new WebSocket((a=n.localBaseUrl,(o=new URL(r.path,`${t(a)}/`)).protocol="https:"===o.protocol?"wss:":"ws:",o.toString()));i.binaryType="arraybuffer";let c=!1;i.addEventListener("message",t=>{(async()=>{if(!c)return;let n=await k(t.data);U(e,{type:"ws-frame",streamId:r.streamId,dataBase64:n.toString("base64"),binary:"string"!=typeof t.data})})().catch(e=>{console.error(e instanceof Error?e.message:String(e))})}),i.addEventListener("close",t=>{s.delete(r.streamId),c&&U(e,{type:"ws-close",streamId:r.streamId,code:t.code,reason:t.reason})}),i.addEventListener("error",()=>{c&&U(e,{type:"ws-close",streamId:r.streamId,code:1011,reason:"Upstream WebSocket error."})}),s.set(r.streamId,i);try{await P(i,"Upstream"),c=!0,U(e,{type:"ws-open-result",streamId:r.streamId,success:!0,headers:{}})}catch(t){s.delete(r.streamId),T(i,1011,"open failed"),U(e,{type:"ws-open-result",streamId:r.streamId,success:!1,error:t instanceof Error?t.message:String(t)})}}async function A(e,r,t,n){switch(r.type){case"ping":return void U(e,{type:"pong",timestamp:r.timestamp});case"http-request":return void await M(e,r,t);case"ws-open":return void await _(e,r,t,n);case"ws-frame":return void function(e,r){let t=r.get(e.streamId);if(!t||1!==t.readyState)return;let n=Buffer.from(e.dataBase64,"base64");t.send(e.binary?n:n.toString("utf8"))}(r,n);case"ws-close":return void function(e,r){let t=r.get(e.streamId);if(t){var n;r.delete(e.streamId),T(t,"number"==typeof(n=e.code)&&Number.isInteger(n)&&(1e3===n||n>=3e3&&n<=4999||n>=1001&&n<=1015&&1004!==n&&1005!==n&&1006!==n)?n:1011,e.reason??"bridge requested close")}}(r,n)}}async function x(e,t={}){let n,s=new Map,a=!1,o=null,i=!1,c=null,l=t.delay??r,f=new Promise(e=>{n=e}),u=()=>{t.exit?.(0)},d=async()=>{(i||c)&&(c??=N(e).finally(()=>{i=!1,c=null}),await c)},m=()=>{!a&&(a=!0,n(),i&&d().finally(u),o&&T(o,1e3,"companion stopping"),t.exit&&setTimeout(u,900).unref())};t.registerProcessSignals&&(process.once("SIGTERM",m),process.once("SIGINT",m));let y=setInterval(()=>{$(e)||(m(),u())},t.leaseCheckIntervalMs??250);y.unref();let p=t.reconnectDelayMs??1e3;try{for(;!a&&$(e);){var g;let r,n=!1;try{i=!1;let r=await v(e);if(p=t.reconnectDelayMs??1e3,n=!0,i=!0,a||!$(e)){await d(),n=!1;break}let c=new WebSocket(r.wsUrl);o=c,c.binaryType="arraybuffer";try{await P(c,"Bridge"),c.addEventListener("message",r=>{(async()=>{let t=await L(r);await A(c,t,e,s)})().catch(e=>{console.error(e instanceof Error?e.message:String(e))})}),await Promise.race([O(c),f])}finally{o=null,s.forEach(e=>T(e,1012,"bridge disconnected")),s.clear(),n&&(await d(),n=!1)}}catch(t){if(o=null,n&&(await d(),n=!1),a||!$(e)||(console.error(t instanceof Error?t.message:String(t)),t instanceof h&&!t.retryable))break;r=t instanceof h?t.retryAfterMs:void 0}if(a||!$(e))break;let c=r??p;void 0===r&&(g=p,p=Math.min(2*g,6e4)),await l(c)}}finally{clearInterval(y),t.registerProcessSignals&&(process.off("SIGTERM",m),process.off("SIGINT",m))}}(async function(e,r){let t=function(e,r){let t=e[0];if(t!==u&&t!==g)return null;let h=r[a]?.trim(),b=r[w]?.trim(),S=r[p]?.trim();if(!h||!b||!S)throw new s("Companion tunnel worker is missing required environment configuration.");let v=r[l]?.trim(),I=r[m]?.trim(),E=r[c]?.trim();if(!v||!I||!E)throw new s("Companion tunnel worker is missing required bridge scope configuration.");let B=r[y]?.trim();if(!B)throw new s("Companion tunnel worker is missing required register path configuration.");return{serverBaseUrl:h,bearerToken:b,localBaseUrl:S,registerPath:B,bridgeScope:{tenantId:v,runId:I,leaseId:E},launchUrl:r[i]?.trim(),statePath:r[o]?.trim(),unregisterPath:r[n]?.trim(),devicePort:function(e){if(!e?.trim())return;let r=Number.parseInt(e,10);if(!Number.isInteger(r)||r<1||r>65535)throw Error("Companion worker received invalid device port configuration.");return r}(r[f]?.trim()),session:r[d]?.trim()}}(e,r);return!!t&&(await x(t,{exit:e=>process.exit(e),registerProcessSignals:!0}),!0)})(process.argv.slice(2),process.env).catch(e=>{if(e instanceof s){console.error(e.message),process.exitCode=1;return}console.error(e instanceof Error?e.stack??e.message:String(e)),process.exitCode=1});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import"../
|
|
1
|
+
import"../9722.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{parentPort as e}from"node:worker_threads";import{normalizeError as t}from"../
|
|
1
|
+
import{parentPort as e}from"node:worker_threads";import{normalizeError as t}from"../733.js";import{computeScreenshotDiffPixels as r,PNG as i,toBuffer as n,decodePng as d}from"../4418.js";function f(e){return e.buffer instanceof ArrayBuffer&&0===e.byteOffset&&e.byteLength===e.buffer.byteLength}function a(e){return(function(e){switch(e.kind){case"decode":return[e.data];case"encode":return[e.png];case"diff-pixels":return[e.diffData,e.diffMask]}})(e).filter(f).map(e=>e.buffer)}e&&e.on("message",f=>{let o;try{o={id:f.id,ok:!0,result:function(e){switch(e.kind){case"decode":{let t=d(n(e.png),e.label);return{kind:"decode",width:t.width,height:t.height,data:t.data}}case"encode":{let t=new i({width:e.width,height:e.height,data:n(e.data)});return{kind:"encode",png:i.sync.write(t)}}case"diff-pixels":return{kind:"diff-pixels",...r(e)}}}(f)}}catch(e){o={id:f.id,ok:!1,error:t(e)}}e.postMessage(o,o.ok?a(o.result):[])});export{a as resultTransferList};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{readUpdateCheckWorkerArgs as e,runUpdateCheckWorker as
|
|
1
|
+
import{readUpdateCheckWorkerArgs as e,runUpdateCheckWorker as o}from"../5448.js";let r=e(process.argv.slice(2));r&&o(r).catch(()=>{process.exitCode=0});
|
package/dist/src/io.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{createLocalArtifactAdapter}from"./
|
|
1
|
+
export{createLocalArtifactAdapter}from"./314.js";
|
package/dist/src/lease.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{resolveLeaseScope as e}from"./
|
|
1
|
+
import{resolveLeaseScope as e}from"./9722.js";async function a(a){let{req:t,leaseRegistry:n}=a,s=e(t);switch(t.command){case"lease_allocate":return{ok:!0,data:{lease:n.allocateLease({tenantId:s.tenantId??"",runId:s.runId??"",backend:s.leaseBackend,ttlMs:s.leaseTtlMs})}};case"lease_heartbeat":return{ok:!0,data:{lease:n.heartbeatLease({leaseId:s.leaseId??"",tenantId:s.tenantId,runId:s.runId,ttlMs:s.leaseTtlMs})}};case"lease_release":return{ok:!0,data:n.releaseLease({leaseId:s.leaseId??"",tenantId:s.tenantId,runId:s.runId})};default:return null}}export{a as handleLeaseCommands};
|