agent-device 0.17.1 → 0.17.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/README.md +1 -1
  2. package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.17.1.apk → agent-device-android-multitouch-helper-0.17.2.apk} +0 -0
  3. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.17.2.apk.sha256 +1 -0
  4. package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.17.1.manifest.json → agent-device-android-multitouch-helper-0.17.2.manifest.json} +4 -4
  5. package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.17.1.apk → agent-device-android-snapshot-helper-0.17.2.apk} +0 -0
  6. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.17.2.apk.sha256 +1 -0
  7. package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.17.1.manifest.json → agent-device-android-snapshot-helper-0.17.2.manifest.json} +6 -6
  8. package/dist/src/123.js +1 -0
  9. package/dist/src/1352.js +1 -1
  10. package/dist/src/1534.js +1 -0
  11. package/dist/src/1620.js +1 -0
  12. package/dist/src/1644.js +2 -0
  13. package/dist/src/2284.js +1 -0
  14. package/dist/src/2403.js +3 -0
  15. package/dist/src/2415.js +28 -29
  16. package/dist/src/2474.js +1 -0
  17. package/dist/src/2672.js +1 -0
  18. package/dist/src/3393.js +1 -0
  19. package/dist/src/4778.js +1 -1
  20. package/dist/src/5898.js +1 -0
  21. package/dist/src/7556.js +1 -1
  22. package/dist/src/7847.js +1 -1
  23. package/dist/src/8173.js +27 -0
  24. package/dist/src/8407.js +1 -0
  25. package/dist/src/8699.js +1 -1
  26. package/dist/src/8806.js +3 -3
  27. package/dist/src/9010.js +1 -0
  28. package/dist/src/9238.js +3 -3
  29. package/dist/src/9471.js +1 -1
  30. package/dist/src/9542.js +3 -3
  31. package/dist/src/9616.js +1 -0
  32. package/dist/src/9673.js +1 -0
  33. package/dist/src/9974.js +1 -0
  34. package/dist/src/android-adb.d.ts +12 -6
  35. package/dist/src/android-adb.js +1 -1
  36. package/dist/src/android-snapshot-helper.d.ts +15 -7
  37. package/dist/src/android.js +1 -1
  38. package/dist/src/apple.js +1 -1
  39. package/dist/src/apps.js +1 -1
  40. package/dist/src/args.js +1 -1
  41. package/dist/src/batch.d.ts +16 -4
  42. package/dist/src/cli.js +18 -42
  43. package/dist/src/command-surface.js +1 -1
  44. package/dist/src/contracts.d.ts +28 -4
  45. package/dist/src/contracts.js +1 -1
  46. package/dist/src/find.js +1 -1
  47. package/dist/src/finders.d.ts +3 -1
  48. package/dist/src/generic.js +5 -5
  49. package/dist/src/index.d.ts +141 -73
  50. package/dist/src/index.js +1 -1
  51. package/dist/src/input-actions.js +1 -1
  52. package/dist/src/interaction.js +1 -1
  53. package/dist/src/internal/png-worker.d.ts +26 -0
  54. package/dist/src/internal/png-worker.js +1 -0
  55. package/dist/src/metro.d.ts +3 -1
  56. package/dist/src/react-native.js +1 -1
  57. package/dist/src/remote-config.d.ts +33 -7
  58. package/dist/src/selector-runtime.js +1 -1
  59. package/dist/src/selectors.d.ts +3 -3
  60. package/dist/src/selectors.js +1 -1
  61. package/dist/src/server.js +2 -2
  62. package/dist/src/session.js +10 -11
  63. package/dist/src/snapshot.js +1 -1
  64. package/package.json +6 -3
  65. package/server.json +2 -2
  66. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.17.1.apk.sha256 +0 -1
  67. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.17.1.apk.sha256 +0 -1
  68. package/dist/src/1998.js +0 -1
  69. package/dist/src/2805.js +0 -1
  70. package/dist/src/4057.js +0 -1
  71. package/dist/src/5792.js +0 -1
  72. package/dist/src/6085.js +0 -1
  73. package/dist/src/6232.js +0 -1
  74. package/dist/src/8020.js +0 -1
  75. package/dist/src/8502.js +0 -1
  76. package/dist/src/940.js +0 -1
  77. package/dist/src/9404.js +0 -1
  78. package/dist/src/9533.js +0 -1
  79. package/dist/src/command-metadata.js +0 -1
  80. /package/dist/src/{1393.js → 3675.js} +0 -0
  81. /package/dist/src/{5310.js → 695.js} +0 -0
@@ -2,6 +2,12 @@ export declare type AppErrorCode = KnownAppErrorCode | (string & {});
2
2
 
3
3
  export declare function centerOfRect(rect: Rect): Point;
4
4
 
5
+ export declare const DAEMON_LOCK_POLICIES: readonly ["reject", "strip"];
6
+
7
+ export declare const DAEMON_SERVER_MODES: readonly ["socket", "http", "dual"];
8
+
9
+ export declare const DAEMON_TRANSPORT_PREFERENCES: readonly ["auto", "socket", "http"];
10
+
5
11
  export declare type DaemonArtifact = {
6
12
  field: string;
7
13
  artifactId?: string;
@@ -41,7 +47,7 @@ export declare type DaemonInstallSource = {
41
47
  artifactName: string;
42
48
  }));
43
49
 
44
- export declare type DaemonLockPolicy = 'reject' | 'strip';
50
+ export declare type DaemonLockPolicy = (typeof DAEMON_LOCK_POLICIES)[number];
45
51
 
46
52
  export declare type DaemonRequest = {
47
53
  token?: string;
@@ -63,7 +69,7 @@ export declare type DaemonRequestMeta = {
63
69
  leaseId?: string;
64
70
  leaseTtlMs?: number;
65
71
  leaseBackend?: LeaseBackend;
66
- sessionIsolation?: 'none' | 'tenant';
72
+ sessionIsolation?: SessionIsolationMode;
67
73
  uploadedArtifactId?: string;
68
74
  clientArtifactPaths?: Record<string, string>;
69
75
  installSource?: DaemonInstallSource;
@@ -71,7 +77,7 @@ export declare type DaemonRequestMeta = {
71
77
  materializedPathRetentionMs?: number;
72
78
  materializationId?: string;
73
79
  lockPolicy?: DaemonLockPolicy;
74
- lockPlatform?: 'ios' | 'macos' | 'android' | 'linux' | 'apple';
80
+ lockPlatform?: PlatformSelector;
75
81
  requestProgress?: 'replay-test';
76
82
  };
77
83
 
@@ -89,6 +95,10 @@ export declare type DaemonResponseData = Record<string, unknown> & {
89
95
 
90
96
  export declare const daemonRuntimeSchema: RuntimeSchema<SessionRuntimeHints>;
91
97
 
98
+ export declare type DaemonServerMode = (typeof DAEMON_SERVER_MODES)[number];
99
+
100
+ export declare type DaemonTransportPreference = (typeof DAEMON_TRANSPORT_PREFERENCES)[number];
101
+
92
102
  export declare function defaultHintForCode(code: string): string | undefined;
93
103
 
94
104
  export declare type JsonRpcId = string | number | null;
@@ -104,6 +114,8 @@ export declare const jsonRpcRequestSchema: RuntimeSchema<JsonRpcRequestEnvelope<
104
114
 
105
115
  declare type KnownAppErrorCode = 'INVALID_ARGS' | 'DEVICE_NOT_FOUND' | 'DEVICE_IN_USE' | 'TOOL_MISSING' | 'APP_NOT_INSTALLED' | 'UNSUPPORTED_PLATFORM' | 'UNSUPPORTED_OPERATION' | 'NOT_IMPLEMENTED' | 'COMMAND_FAILED' | 'SESSION_NOT_FOUND' | 'UNAUTHORIZED' | 'AMBIGUOUS_MATCH' | 'UNKNOWN';
106
116
 
117
+ export declare const LEASE_BACKENDS: readonly ["ios-simulator", "ios-instance", "android-instance"];
118
+
107
119
  export declare type LeaseAllocatePayload = {
108
120
  token?: string;
109
121
  session?: string;
@@ -116,7 +128,7 @@ export declare type LeaseAllocatePayload = {
116
128
 
117
129
  export declare const leaseAllocateSchema: RuntimeSchema<LeaseAllocatePayload>;
118
130
 
119
- export declare type LeaseBackend = 'ios-simulator' | 'ios-instance' | 'android-instance';
131
+ export declare type LeaseBackend = (typeof LEASE_BACKENDS)[number];
120
132
 
121
133
  export declare type LeaseHeartbeatPayload = {
122
134
  token?: string;
@@ -141,6 +153,10 @@ export declare type LeaseReleasePayload = {
141
153
 
142
154
  export declare const leaseReleaseSchema: RuntimeSchema<LeaseReleasePayload>;
143
155
 
156
+ export declare const NETWORK_INCLUDE_MODES: readonly ["summary", "headers", "body", "all"];
157
+
158
+ export declare type NetworkIncludeMode = (typeof NETWORK_INCLUDE_MODES)[number];
159
+
144
160
  declare type NormalizedError = {
145
161
  code: string;
146
162
  message: string;
@@ -155,6 +171,10 @@ export declare function normalizeError(err: unknown, context?: {
155
171
  logPath?: string;
156
172
  }): NormalizedError;
157
173
 
174
+ declare const PLATFORM_SELECTORS: readonly ["ios", "macos", "android", "linux", "apple"];
175
+
176
+ declare type PlatformSelector = (typeof PLATFORM_SELECTORS)[number];
177
+
158
178
  declare type Point = {
159
179
  x: number;
160
180
  y: number;
@@ -198,6 +218,10 @@ declare type RuntimeSchema<T> = {
198
218
  parse(input: unknown): T;
199
219
  };
200
220
 
221
+ export declare const SESSION_ISOLATION_MODES: readonly ["none", "tenant"];
222
+
223
+ export declare type SessionIsolationMode = (typeof SESSION_ISOLATION_MODES)[number];
224
+
201
225
  export declare type SessionRuntimeHints = {
202
226
  platform?: 'ios' | 'android';
203
227
  metroHost?: string;
@@ -1 +1 @@
1
- function t(t){return{parse:e=>t(e,"$")}}function e(t,e){throw Error(`${t}: ${e}`)}function a(t,a){return(!t||"object"!=typeof t||Array.isArray(t))&&e(a,"Expected an object"),t}function n(t,a){return"string"!=typeof t&&e(a,"Expected a string"),t}function r(t,a){let r=n(t,a).trim();return r||e(a,"Expected a non-empty string"),r}function i(t,a){return Number.isInteger(t)||e(a,"Expected an integer"),t}function o(t,e,a){let r=t[e];return void 0===r?void 0:n(r,`${a}.${e}`)}function s(t,a,n){let r=t[a];if(void 0!==r)return"boolean"!=typeof r&&e(`${n}.${a}`,"Expected a boolean"),r}function d(t,e,a){let n=t[e];return void 0===n?void 0:i(n,`${a}.${e}`)}function l(t,e,n){let r=t[e];return void 0===r?void 0:a(r,`${n}.${e}`)}function c(t,a,n,r){let i=t[a];if(void 0!==i)return"string"==typeof i&&n.includes(i)||e(`${r}.${a}`,`Expected one of: ${n.join(", ")}`),i}function u(t,e){let r=a(t,e),i={};for(let[t,a]of Object.entries(r))i[t]=n(a,`${e}.${t}`);return i}let m=t((t,e)=>{let n=a(t,e);return{platform:c(n,"platform",["ios","android"],e),metroHost:o(n,"metroHost",e),metroPort:d(n,"metroPort",e),bundleUrl:o(n,"bundleUrl",e),launchUrl:o(n,"launchUrl",e)}}),f=t((t,f)=>{var $,p;let I=a(t,f),h=($=I.positionals,p=`${f}.positionals`,Array.isArray($)||e(p,"Expected an array"),$),v=l(I,"meta",f);return{token:o(I,"token",f),session:o(I,"session",f),command:n(I.command,`${f}.command`),positionals:h.map((t,e)=>n(t,`${f}.positionals[${String(e)}]`)),flags:l(I,"flags",f),runtime:void 0===I.runtime?void 0:m.parse(I.runtime),meta:void 0===v?void 0:{requestId:o(v,"requestId",`${f}.meta`),debug:s(v,"debug",`${f}.meta`),cwd:o(v,"cwd",`${f}.meta`),sessionExplicit:s(v,"sessionExplicit",`${f}.meta`),tenantId:o(v,"tenantId",`${f}.meta`),runId:o(v,"runId",`${f}.meta`),leaseId:o(v,"leaseId",`${f}.meta`),leaseTtlMs:d(v,"leaseTtlMs",`${f}.meta`),leaseBackend:c(v,"leaseBackend",["ios-simulator","ios-instance","android-instance"],`${f}.meta`),sessionIsolation:c(v,"sessionIsolation",["none","tenant"],`${f}.meta`),uploadedArtifactId:o(v,"uploadedArtifactId",`${f}.meta`),clientArtifactPaths:void 0===v.clientArtifactPaths?void 0:u(v.clientArtifactPaths,`${f}.meta.clientArtifactPaths`),installSource:void 0===v.installSource?void 0:function(t,o){let s=a(t,o),d=n(s.kind,`${o}.kind`);if("url"===d){let t=n(s.url,`${o}.url`),e=void 0===s.headers?void 0:u(s.headers,`${o}.headers`);return e?{kind:d,url:t,headers:e}:{kind:d,url:t}}if("path"===d)return{kind:d,path:n(s.path,`${o}.path`)};if("github-actions-artifact"===d){let t,a,n,d,l;return t=r(s.owner,`${o}.owner`),a=r(s.repo,`${o}.repo`),n=void 0!==s.artifactId,d=void 0!==s.runId,l=void 0!==s.artifactName,(n&&(d||l)&&e(`${o}`,"Expected either artifactId or artifactName, not both"),n||!d||l||e(`${o}`,"Expected artifactName when runId is specified"),n||l||e(`${o}`,"Expected artifactId or artifactName"),n)?{kind:"github-actions-artifact",owner:t,repo:a,artifactId:i(s.artifactId,`${o}.artifactId`)}:{kind:"github-actions-artifact",owner:t,repo:a,...d?{runId:i(s.runId,`${o}.runId`)}:{},artifactName:r(s.artifactName,`${o}.artifactName`)}}e(`${o}.kind`,'Expected "url", "path", or "github-actions-artifact"')}(v.installSource,`${f}.meta.installSource`),retainMaterializedPaths:s(v,"retainMaterializedPaths",`${f}.meta`),materializedPathRetentionMs:d(v,"materializedPathRetentionMs",`${f}.meta`),materializationId:o(v,"materializationId",`${f}.meta`),lockPolicy:c(v,"lockPolicy",["reject","strip"],`${f}.meta`),lockPlatform:c(v,"lockPlatform",["ios","macos","android","linux","apple"],`${f}.meta`)}}});function $(t,e){return{token:o(t,"token",e),session:o(t,"session",e),tenantId:o(t,"tenantId",e),tenant:o(t,"tenant",e),runId:o(t,"runId",e)}}let p=t((t,e)=>{let n=a(t,e);return{...$(n,e),ttlMs:d(n,"ttlMs",e),backend:c(n,"backend",["ios-simulator","ios-instance","android-instance"],e)}}),I=t((t,e)=>{let n,r={record:n=a(t,e),leaseId:o(n,"leaseId",e),ttlMs:d(n,"ttlMs",e)};return{...$(r.record,e),leaseId:r.leaseId,ttlMs:r.ttlMs}}),h=t((t,n)=>{let r=a(t,n);return void 0!==r.ttlMs&&e(`${n}.ttlMs`,"Unexpected field"),{...$(r,n),leaseId:o(r,"leaseId",n)}}),v=t((t,n)=>{let r,i=a(t,n);return{jsonrpc:o(i,"jsonrpc",n),id:(null==(r=i.id)||"string"!=typeof r&&"number"!=typeof r&&e(`${n}.id`,"Expected a string, number, or null"),r),method:o(i,"method",n),params:i.params}});export{centerOfRect}from"./4057.js";export{defaultHintForCode,normalizeError}from"./9152.js";export{f as daemonCommandRequestSchema,m as daemonRuntimeSchema,v as jsonRpcRequestSchema,p as leaseAllocateSchema,I as leaseHeartbeatSchema,h as leaseReleaseSchema};
1
+ export{DAEMON_LOCK_POLICIES,DAEMON_SERVER_MODES,DAEMON_TRANSPORT_PREFERENCES,LEASE_BACKENDS,NETWORK_INCLUDE_MODES,SESSION_ISOLATION_MODES,daemonCommandRequestSchema,daemonRuntimeSchema,jsonRpcRequestSchema,leaseAllocateSchema,leaseHeartbeatSchema,leaseReleaseSchema}from"./9616.js";export{centerOfRect}from"./1644.js";export{defaultHintForCode,normalizeError}from"./9152.js";
package/dist/src/find.js CHANGED
@@ -1 +1 @@
1
- import{context_contextFromFlags as e,setSessionSnapshot as t,captureSnapshot as r,dispatchCommand as n,errorResponse as o,ensureDeviceReady as a,getActiveAndroidSnapshotFreshness as i,resolveTargetDevice as s,stripInternalInteractionFlags as l}from"./2415.js";import{findBestMatchesByLocator as c,parseFindArgs as f}from"./7556.js";import{dispatchFindReadOnlyViaRuntime as d,readTextForNode as u}from"./selector-runtime.js";import{centerOfRect as p}from"./4057.js";import{resolveActionableTouchResolution as _,resolveActionableTouchNode as g,isSnapshotNodeInteractionBlocked as h}from"./9533.js";import{sleep as m}from"./4829.js";import{extractNodeText as A}from"./940.js";async function y(e){var n,u;let{req:h,sessionName:m,logPath:y,sessionStore:R,invoke:K}=e,F=h.command;if("find"!==F)return null;let E=h.positionals??[];if(0===E.length)return o("INVALID_ARGS","find requires a locator or text");let{locator:P,query:U,action:b,value:L,timeoutMs:O}=f(E);if(!U)return o("INVALID_ARGS","find requires a value");if(h.flags?.findFirst&&h.flags?.findLast)return o("INVALID_ARGS","find accepts only one of --first or --last");let H=await d({req:h,sessionName:m,logPath:y,sessionStore:R});if(H)return H;let $=R.get(m),B="exists"===(n=b)||"wait"===n||"get_text"===n||"get_attrs"===n;if(!$&&!B)return o("SESSION_NOT_FOUND","No active session. Run open first.");let q=$?.device??await s(h.flags??{});$||await a(q);let G="click"===(u=b)||"focus"===u||"fill"===u||"type"===u,V="role"===P||G?void 0:U,T=0,j=null,z=async()=>{let e=Date.now();if(j&&e-T<750&&!i($))return{nodes:j};let{snapshot:n}=await r({device:q,session:$,flags:{...h.flags,snapshotInteractiveOnly:G,snapshotCompact:G},outPath:h.flags?.out,logPath:y,snapshotScope:V}),o=n.nodes;return T=e,j=o,$&&(t($,n),R.set(m,$)),{nodes:o,truncated:n.truncated,backend:n.backend}},J={req:h,sessionName:m,logPath:y,sessionStore:R,invoke:K,session:$,device:q,command:F,locator:P,query:U,publicFlags:{...l(h.flags)??{}}};if("wait"===b)return k(J,z,P,U,O);let{nodes:Q}=await z(),W=function(e){let{nodes:t,locator:r,query:n,requiresRect:a,flags:i}=e,s=c(t,r,n,{requireRect:a});if(a&&(s.matches=function(e,t){var r,n;let o=t[0]?.rect;if(!o)return e;let a=e.filter(e=>{if(!e.rect)return!1;let t=p(e.rect);return t.x>=o.x&&t.x<=o.x+o.width&&t.y>=o.y&&t.y<=o.y+o.height});return r=a.length>0?a:e,n=t,r.length<2?r:r.map((e,t)=>{var r,o;let a;return{node:e,index:t,score:(r=e,"covered"===(a=_(o=n,r)).reason?0:"semantic-target"===a.reason&&a.node.rect||"same-rect-descendant"===a.reason&&a.node.rect?4:"hittable-ancestor"===a.reason&&a.node.rect&&!S(a.node,o[0])?2:r.hittable&&r.rect&&!S(r,o[0])?3:+!!r.rect)}}).sort((e,t)=>t.score!==e.score?t.score-e.score:w(e.node)-w(t.node)||e.index-t.index).map(e=>e.node)}(s.matches,t)),a&&s.matches.length>1)if(i?.findFirst)s.matches=[s.matches[0]];else{if(!i?.findLast){var l,f,d;let e;return{ok:!1,response:(l=s.matches,f=r,d=n,e=l.slice(0,8).map(e=>{let t=A(e)||e.label||e.identifier||e.type||"";return`@${e.ref}${t?`(${t})`:""}`}),o("AMBIGUOUS_MATCH",`find matched ${l.length} elements for ${f} "${d}". Use a more specific locator or selector.`,{locator:f,query:d,matches:l.length,candidates:e}))}}s.matches=[s.matches[s.matches.length-1]]}let u=s.matches[0]??null;return u?{ok:!0,node:u}:{ok:!1,response:o("COMMAND_FAILED","find did not match any element")}}({nodes:Q,locator:P,query:U,requiresRect:G,flags:h.flags});if(!W.ok)return W.response;let X=W.node,Y=G?g(Q,X):X,Z=`@${Y.ref}`,ee={node:X,resolvedNode:Y,ref:Z,nodes:Q,actionFlags:{...h.flags??{},noRecord:!0}},et={exists:()=>N(J),get_text:()=>C(J,ee),get_attrs:()=>x(J,ee),click:()=>I(J,ee),fill:()=>M(J,ee,L),focus:()=>v(J,ee),type:()=>D(J,ee,L)}[b];return et?et():null}function w(e){return e.rect?e.rect.width*e.rect.height:1/0}function S(e,t){if(!t?.rect||!e.rect)return!1;let r=e.type?.toLowerCase()??"";return(!!r.includes("application")||!!r.includes("window"))&&e.rect.x===t.rect.x&&e.rect.y===t.rect.y&&e.rect.width===t.rect.width&&e.rect.height===t.rect.height}async function k(e,t,r,n,a){let{req:i,sessionStore:s,session:l,command:f,publicFlags:d}=e,u=a??1e4,p=Date.now();for(;Date.now()-p<u;){let{nodes:e}=await t();if(c(e,r,n,{requireRect:!1}).matches[0])return l&&s.recordAction(l,{command:f,positionals:i.positionals??[],flags:d,result:{found:!0,waitedMs:Date.now()-p}}),{ok:!0,data:{found:!0,waitedMs:Date.now()-p}};await m(300)}return o("COMMAND_FAILED","find wait timed out")}async function N(e){let{req:t,sessionStore:r,session:n,command:o,publicFlags:a}=e;return n&&r.recordAction(n,{command:o,positionals:t.positionals??[],flags:a,result:{found:!0}}),{ok:!0,data:{found:!0}}}async function C(t,r){let{req:n,sessionStore:o,session:a,command:i,device:s,logPath:l,publicFlags:c}=t,f=await u({device:s,node:r.node,flags:n.flags,appBundleId:a?.appBundleId,traceOutPath:a?.trace?.outPath,surface:a?.surface,contextFromFlags:(t,r,n)=>e(l,t,r,n)});return a&&o.recordAction(a,{command:i,positionals:n.positionals??[],flags:c,result:{ref:r.ref,action:"get text",text:f}}),{ok:!0,data:{ref:r.ref,text:f,node:r.node}}}async function x(e,t){let{req:r,sessionStore:n,session:o,command:a,publicFlags:i}=e;return o&&n.recordAction(o,{command:a,positionals:r.positionals??[],flags:i,result:{ref:t.ref,action:"get attrs"}}),{ok:!0,data:{ref:t.ref,node:t.node}}}async function I(e,t){let{req:r,sessionName:n,sessionStore:o,session:a,invoke:i,command:s,locator:l,query:c,publicFlags:f}=e,d=await i({token:r.token,session:n,command:"click",positionals:[t.ref],flags:t.actionFlags});if(!d.ok)return d;let u=t.resolvedNode.rect?p(t.resolvedNode.rect):t.node.rect?p(t.node.rect):null,_={ref:t.ref,locator:l,query:c};return u&&(_.x=u.x,_.y=u.y),a&&o.recordAction(a,{command:s,positionals:r.positionals??[],flags:f,result:{ref:t.ref,action:"click",locator:l,query:c}}),{ok:!0,data:_}}async function M(e,t,r){let{req:n,sessionName:a,sessionStore:i,session:s,invoke:l,command:c,publicFlags:f}=e;if(!r)return o("INVALID_ARGS","find fill requires text");let d=await l({token:n.token,session:a,command:"fill",positionals:[t.ref,r],flags:t.actionFlags});return d.ok&&s&&i.recordAction(s,{command:c,positionals:n.positionals??[],flags:f,result:{ref:t.ref,action:"fill"}}),d}async function v(e,t){let r=await R(e,t);return r.ok&&K(e,t,"focus"),r}async function D(t,r,a){let{req:i,device:s,logPath:l,session:c}=t;if(!a)return o("INVALID_ARGS","find type requires text");let f=await R(t,r);if(!f.ok)return f;let d=await n(s,"type",[a],i.flags?.out,{...e(l,i.flags,c?.appBundleId,c?.trace?.outPath)});return K(t,r,"type"),{ok:!0,data:d??{ref:r.ref}}}async function R(t,r){var a;let i,{req:s,device:l,logPath:c,session:f}=t,d=(i=[(a=r).resolvedNode,a.node].find(h))?o("COMMAND_FAILED",`Matched element ${a.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(d)return d;let u=r.resolvedNode.rect?p(r.resolvedNode.rect):null;return u?{ok:!0,data:await n(l,"focus",[String(u.x),String(u.y)],s.flags?.out,{...e(c,s.flags,f?.appBundleId,f?.trace?.outPath)})??{ref:r.ref}}:o("COMMAND_FAILED","matched element has no bounds")}function K(e,t,r){let{req:n,sessionStore:o,session:a,command:i,publicFlags:s}=e;a&&o.recordAction(a,{command:i,positionals:n.positionals??[],flags:s,result:{ref:t.ref,action:r}})}export{parseFindArgs}from"./7556.js";export{y as handleFindCommands};
1
+ import{context_contextFromFlags as e,setSessionSnapshot as t,captureSnapshot as r,dispatchCommand as n,errorResponse as o,ensureDeviceReady as a,getActiveAndroidSnapshotFreshness as i,resolveTargetDevice as s,stripInternalInteractionFlags as l}from"./2415.js";import{findBestMatchesByLocator as c,parseFindArgs as f}from"./7556.js";import{dispatchFindReadOnlyViaRuntime as d,readTextForNode as u}from"./selector-runtime.js";import{centerOfRect as p}from"./1644.js";import{resolveActionableTouchResolution as _,resolveActionableTouchNode as g,isSnapshotNodeInteractionBlocked as h}from"./1620.js";import{sleep as m}from"./4829.js";import{extractNodeText as A}from"./7847.js";async function y(e){var n,u;let{req:h,sessionName:m,logPath:y,sessionStore:R,invoke:K}=e,F=h.command;if("find"!==F)return null;let E=h.positionals??[];if(0===E.length)return o("INVALID_ARGS","find requires a locator or text");let{locator:P,query:U,action:b,value:L,timeoutMs:O}=f(E);if(!U)return o("INVALID_ARGS","find requires a value");if(h.flags?.findFirst&&h.flags?.findLast)return o("INVALID_ARGS","find accepts only one of --first or --last");let H=await d({req:h,sessionName:m,logPath:y,sessionStore:R});if(H)return H;let $=R.get(m),B="exists"===(n=b)||"wait"===n||"get_text"===n||"get_attrs"===n;if(!$&&!B)return o("SESSION_NOT_FOUND","No active session. Run open first.");let q=$?.device??await s(h.flags??{});$||await a(q);let G="click"===(u=b)||"focus"===u||"fill"===u||"type"===u,V="role"===P||G?void 0:U,T=0,j=null,z=async()=>{let e=Date.now();if(j&&e-T<750&&!i($))return{nodes:j};let{snapshot:n}=await r({device:q,session:$,flags:{...h.flags,snapshotInteractiveOnly:G,snapshotCompact:G},outPath:h.flags?.out,logPath:y,snapshotScope:V}),o=n.nodes;return T=e,j=o,$&&(t($,n),R.set(m,$)),{nodes:o,truncated:n.truncated,backend:n.backend}},J={req:h,sessionName:m,logPath:y,sessionStore:R,invoke:K,session:$,device:q,command:F,locator:P,query:U,publicFlags:{...l(h.flags)??{}}};if("wait"===b)return k(J,z,P,U,O);let{nodes:Q}=await z(),W=function(e){let{nodes:t,locator:r,query:n,requiresRect:a,flags:i}=e,s=c(t,r,n,{requireRect:a});if(a&&(s.matches=function(e,t){var r,n;let o=t[0]?.rect;if(!o)return e;let a=e.filter(e=>{if(!e.rect)return!1;let t=p(e.rect);return t.x>=o.x&&t.x<=o.x+o.width&&t.y>=o.y&&t.y<=o.y+o.height});return r=a.length>0?a:e,n=t,r.length<2?r:r.map((e,t)=>{var r,o;let a;return{node:e,index:t,score:(r=e,"covered"===(a=_(o=n,r)).reason?0:"semantic-target"===a.reason&&a.node.rect||"same-rect-descendant"===a.reason&&a.node.rect?4:"hittable-ancestor"===a.reason&&a.node.rect&&!S(a.node,o[0])?2:r.hittable&&r.rect&&!S(r,o[0])?3:+!!r.rect)}}).sort((e,t)=>t.score!==e.score?t.score-e.score:w(e.node)-w(t.node)||e.index-t.index).map(e=>e.node)}(s.matches,t)),a&&s.matches.length>1)if(i?.findFirst)s.matches=[s.matches[0]];else{if(!i?.findLast){var l,f,d;let e;return{ok:!1,response:(l=s.matches,f=r,d=n,e=l.slice(0,8).map(e=>{let t=A(e)||e.label||e.identifier||e.type||"";return`@${e.ref}${t?`(${t})`:""}`}),o("AMBIGUOUS_MATCH",`find matched ${l.length} elements for ${f} "${d}". Use a more specific locator or selector.`,{locator:f,query:d,matches:l.length,candidates:e}))}}s.matches=[s.matches[s.matches.length-1]]}let u=s.matches[0]??null;return u?{ok:!0,node:u}:{ok:!1,response:o("COMMAND_FAILED","find did not match any element")}}({nodes:Q,locator:P,query:U,requiresRect:G,flags:h.flags});if(!W.ok)return W.response;let X=W.node,Y=G?g(Q,X):X,Z=`@${Y.ref}`,ee={node:X,resolvedNode:Y,ref:Z,nodes:Q,actionFlags:{...h.flags??{},noRecord:!0}},et={exists:()=>N(J),get_text:()=>C(J,ee),get_attrs:()=>x(J,ee),click:()=>I(J,ee),fill:()=>M(J,ee,L),focus:()=>v(J,ee),type:()=>D(J,ee,L)}[b];return et?et():null}function w(e){return e.rect?e.rect.width*e.rect.height:1/0}function S(e,t){if(!t?.rect||!e.rect)return!1;let r=e.type?.toLowerCase()??"";return(!!r.includes("application")||!!r.includes("window"))&&e.rect.x===t.rect.x&&e.rect.y===t.rect.y&&e.rect.width===t.rect.width&&e.rect.height===t.rect.height}async function k(e,t,r,n,a){let{req:i,sessionStore:s,session:l,command:f,publicFlags:d}=e,u=a??1e4,p=Date.now();for(;Date.now()-p<u;){let{nodes:e}=await t();if(c(e,r,n,{requireRect:!1}).matches[0])return l&&s.recordAction(l,{command:f,positionals:i.positionals??[],flags:d,result:{found:!0,waitedMs:Date.now()-p}}),{ok:!0,data:{found:!0,waitedMs:Date.now()-p}};await m(300)}return o("COMMAND_FAILED","find wait timed out")}async function N(e){let{req:t,sessionStore:r,session:n,command:o,publicFlags:a}=e;return n&&r.recordAction(n,{command:o,positionals:t.positionals??[],flags:a,result:{found:!0}}),{ok:!0,data:{found:!0}}}async function C(t,r){let{req:n,sessionStore:o,session:a,command:i,device:s,logPath:l,publicFlags:c}=t,f=await u({device:s,node:r.node,flags:n.flags,appBundleId:a?.appBundleId,traceOutPath:a?.trace?.outPath,surface:a?.surface,contextFromFlags:(t,r,n)=>e(l,t,r,n)});return a&&o.recordAction(a,{command:i,positionals:n.positionals??[],flags:c,result:{ref:r.ref,action:"get text",text:f}}),{ok:!0,data:{ref:r.ref,text:f,node:r.node}}}async function x(e,t){let{req:r,sessionStore:n,session:o,command:a,publicFlags:i}=e;return o&&n.recordAction(o,{command:a,positionals:r.positionals??[],flags:i,result:{ref:t.ref,action:"get attrs"}}),{ok:!0,data:{ref:t.ref,node:t.node}}}async function I(e,t){let{req:r,sessionName:n,sessionStore:o,session:a,invoke:i,command:s,locator:l,query:c,publicFlags:f}=e,d=await i({token:r.token,session:n,command:"click",positionals:[t.ref],flags:t.actionFlags});if(!d.ok)return d;let u=t.resolvedNode.rect?p(t.resolvedNode.rect):t.node.rect?p(t.node.rect):null,_={ref:t.ref,locator:l,query:c};return u&&(_.x=u.x,_.y=u.y),a&&o.recordAction(a,{command:s,positionals:r.positionals??[],flags:f,result:{ref:t.ref,action:"click",locator:l,query:c}}),{ok:!0,data:_}}async function M(e,t,r){let{req:n,sessionName:a,sessionStore:i,session:s,invoke:l,command:c,publicFlags:f}=e;if(!r)return o("INVALID_ARGS","find fill requires text");let d=await l({token:n.token,session:a,command:"fill",positionals:[t.ref,r],flags:t.actionFlags});return d.ok&&s&&i.recordAction(s,{command:c,positionals:n.positionals??[],flags:f,result:{ref:t.ref,action:"fill"}}),d}async function v(e,t){let r=await R(e,t);return r.ok&&K(e,t,"focus"),r}async function D(t,r,a){let{req:i,device:s,logPath:l,session:c}=t;if(!a)return o("INVALID_ARGS","find type requires text");let f=await R(t,r);if(!f.ok)return f;let d=await n(s,"type",[a],i.flags?.out,{...e(l,i.flags,c?.appBundleId,c?.trace?.outPath)});return K(t,r,"type"),{ok:!0,data:d??{ref:r.ref}}}async function R(t,r){var a;let i,{req:s,device:l,logPath:c,session:f}=t,d=(i=[(a=r).resolvedNode,a.node].find(h))?o("COMMAND_FAILED",`Matched element ${a.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(d)return d;let u=r.resolvedNode.rect?p(r.resolvedNode.rect):null;return u?{ok:!0,data:await n(l,"focus",[String(u.x),String(u.y)],s.flags?.out,{...e(c,s.flags,f?.appBundleId,f?.trace?.outPath)})??{ref:r.ref}}:o("COMMAND_FAILED","matched element has no bounds")}function K(e,t,r){let{req:n,sessionStore:o,session:a,command:i,publicFlags:s}=e;a&&o.recordAction(a,{command:i,positionals:n.positionals??[],flags:s,result:{ref:t.ref,action:r}})}export{parseFindArgs}from"./7556.js";export{y as handleFindCommands};
@@ -1,3 +1,5 @@
1
+ declare const FIND_LOCATORS: readonly ["any", "text", "label", "value", "role", "id"];
2
+
1
3
  declare type FindAction = {
2
4
  kind: 'click';
3
5
  } | {
@@ -24,7 +26,7 @@ export declare function findBestMatchesByLocator(nodes: SnapshotNode[], locator:
24
26
  score: number;
25
27
  };
26
28
 
27
- export declare type FindLocator = 'any' | 'text' | 'label' | 'value' | 'role' | 'id';
29
+ export declare type FindLocator = (typeof FIND_LOCATORS)[number];
28
30
 
29
31
  export declare type FindMatchOptions = {
30
32
  requireRect?: boolean;
@@ -1,9 +1,9 @@
1
- import t from"node:fs";import e from"node:path";import{formatDurationSeconds as r}from"./9542.js";import{AppError as s}from"./9152.js";import{runCliCommandWithOutput as n,printJson as i,writeCommandOutput as o}from"./cli.js";import{readCommandMessage as a}from"./1998.js";function u(s){var n,i;if("skipped"===s.status)return[];let o=(n=s).artifactsDir?e.join(n.artifactsDir,`attempt-${n.attempts}`,"replay-timing.ndjson"):void 0;if(!o)return[];let a=function(e){try{return t.readFileSync(e,"utf8").split(/\r?\n/).filter(t=>t.trim().length>0).flatMap(t=>{try{let e=JSON.parse(t);return c(e)?[e]:[]}catch{return[]}})}catch{return[]}}(o);if(0===a.length)return[];let u=[],m=[];for(let t of a){if("replay_action_start"===(i=t).type&&d(i)&&l(i,"line")&&f(i,"command")&&(void 0===i.positionals||Array.isArray(i.positionals))){u.push(t);continue}(function(t){var e;return["replay_action_stop"===t.type&&d(t)&&l(t,"line")&&f(t,"command"),void 0===(e=t).ok||"boolean"==typeof e.ok,l(t,"durationMs"),f(t,"errorCode"),void 0===t.resultTiming||c(t.resultTiming)].every(Boolean)})(t)&&m.push({stop:t,start:function(t,e){let r=e.command,s=t.findIndex(t=>t.step===e.step&&(void 0===r||void 0===t.command||t.command===r));if(!(s<0))return t.splice(s,1)[0]}(u,t)})}return 0===m.length?[]:[s.attempts>1?`steps (attempt ${s.attempts}):`:"steps:",...m.map(({stop:t,start:e})=>{var s,n,i,o,a,u;let d,l,f;return s=t,n=e,d=!1===s.ok?"[FAIL] ":!0===s.ok?"":"[info] ",` ${d}${i=n,o=s,[function(t){if(!t)return"unknown";if(!t.startsWith("__maestro"))return t;let e=t.slice(9);return e.length>0?e[0].toLowerCase()+e.slice(1):t}(i?.command??o.command),...(i?.positionals??[]).map(p)].join(" ")}${a=s,u=n,(f=["number"==typeof(l=u?.line??a.line)?`line ${l}`:"","number"==typeof a.durationMs?r(a.durationMs):"",a.errorCode??"",a.resultTiming?`timing ${JSON.stringify(a.resultTiming)}`:""].filter(Boolean)).length>0?` (${f.join(", ")})`:""}`})]}function d(t){return"number"==typeof t.step}function l(t,e){return void 0===t[e]||"number"==typeof t[e]}function f(t,e){return void 0===t[e]||"string"==typeof t[e]}function p(t){return"string"==typeof t?JSON.stringify(t):"number"==typeof t||"boolean"==typeof t?String(t):JSON.stringify(t)}function c(t){return!!t&&"object"==typeof t&&!Array.isArray(t)}function m(t){var r,s;let n,i,o,a=t.attempts>1?` after ${t.attempts} attempts`:"",d=y(t);for(let u of(process.stdout.write(`FAIL ${(n=h(r=t),i=e.basename(r.file),o=n&&n.length>0?`${JSON.stringify(n)} in ${i}`:i,`${o}${M(r)}`)}${a}${d}
1
+ import t from"node:fs";import e from"node:path";import{formatDurationSeconds as r}from"./9542.js";import{AppError as s}from"./9152.js";import{printJson as n}from"./8173.js";import{runCliCommandWithOutput as i,writeCommandOutput as o}from"./cli.js";import{readCommandMessage as a}from"./1534.js";function u(s){var n,i;if("skipped"===s.status)return[];let o=(n=s).artifactsDir?e.join(n.artifactsDir,`attempt-${n.attempts}`,"replay-timing.ndjson"):void 0;if(!o)return[];let a=function(e){try{return t.readFileSync(e,"utf8").split(/\r?\n/).filter(t=>t.trim().length>0).flatMap(t=>{try{let e=JSON.parse(t);return c(e)?[e]:[]}catch{return[]}})}catch{return[]}}(o);if(0===a.length)return[];let u=[],m=[];for(let t of a){if("replay_action_start"===(i=t).type&&d(i)&&l(i,"line")&&f(i,"command")&&(void 0===i.positionals||Array.isArray(i.positionals))){u.push(t);continue}(function(t){var e;return["replay_action_stop"===t.type&&d(t)&&l(t,"line")&&f(t,"command"),void 0===(e=t).ok||"boolean"==typeof e.ok,l(t,"durationMs"),f(t,"errorCode"),void 0===t.resultTiming||c(t.resultTiming)].every(Boolean)})(t)&&m.push({stop:t,start:function(t,e){let r=e.command,s=t.findIndex(t=>t.step===e.step&&(void 0===r||void 0===t.command||t.command===r));if(!(s<0))return t.splice(s,1)[0]}(u,t)})}return 0===m.length?[]:[s.attempts>1?`steps (attempt ${s.attempts}):`:"steps:",...m.map(({stop:t,start:e})=>{var s,n,i,o,a,u;let d,l,f;return s=t,n=e,d=!1===s.ok?"[FAIL] ":!0===s.ok?"":"[info] ",` ${d}${i=n,o=s,[function(t){if(!t)return"unknown";if(!t.startsWith("__maestro"))return t;let e=t.slice(9);return e.length>0?e[0].toLowerCase()+e.slice(1):t}(i?.command??o.command),...(i?.positionals??[]).map(p)].join(" ")}${a=s,u=n,(f=["number"==typeof(l=u?.line??a.line)?`line ${l}`:"","number"==typeof a.durationMs?r(a.durationMs):"",a.errorCode??"",a.resultTiming?`timing ${JSON.stringify(a.resultTiming)}`:""].filter(Boolean)).length>0?` (${f.join(", ")})`:""}`})]}function d(t){return"number"==typeof t.step}function l(t,e){return void 0===t[e]||"number"==typeof t[e]}function f(t,e){return void 0===t[e]||"string"==typeof t[e]}function p(t){return"string"==typeof t?JSON.stringify(t):"number"==typeof t||"boolean"==typeof t?String(t):JSON.stringify(t)}function c(t){return!!t&&"object"==typeof t&&!Array.isArray(t)}function m(t){var r,s;let n,i,o,a=t.attempts>1?` after ${t.attempts} attempts`:"",d=y(t);for(let u of(process.stdout.write(`FAIL ${(n=h(r=t),i=e.basename(r.file),o=n&&n.length>0?`${JSON.stringify(n)} in ${i}`:i,`${o}${M(r)}`)}${a}${d}
2
2
  `),process.stdout.write(` ${t.error?.message??"Unknown test failure"}
3
- `),[A((s=t).error),w(s,"artifacts"),I(s.error,"log"),b(s.error,"diagnostic")].filter(k)))process.stdout.write(` ${u}
3
+ `),[A((s=t).error),w(s,"artifacts"),C(s.error,"log"),b(s.error,"diagnostic")].filter(k)))process.stdout.write(` ${u}
4
4
  `);for(let e of u(t))process.stdout.write(` ${e}
5
- `)}function $(t){return"passed"===t.status&&t.attempts>1}function g(t){let r=h(t),s=r&&r.length>0?JSON.stringify(r):e.basename(t.file);return`${s}${M(t)}`}function h(t){let e=t.title?.trim();return e&&e.length>0?e:void 0}function y(t){if("passed"===t.status&&t.attempts>1)return v(t);if("failed"===t.status&&t.attempts>1&&t.durationMs>0)return` (total ${r(t.durationMs)})`;let e="passed"===t.status&&"number"==typeof t.finalAttemptDurationMs?t.finalAttemptDurationMs:t.durationMs;return e>0?` (${r(e)})`:""}function v(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(", ")})`:""}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 S(t,e,r={}){r.includeMessage&&t.push(`errorMessage: ${e.message}`),C(t,A(e)),C(t,b(e,"diagnosticId")),C(t,I(e,"logPath")),!1!==r.includeDetails&&_(t,e,r.detailsIndent)}function _(t,e,r){let s=e.details?JSON.stringify(e.details,null,r):void 0;s&&t.push(`details: ${s}`)}function w(t,e){return"artifactsDir"in t&&t.artifactsDir?`${e}: ${t.artifactsDir}`:void 0}function A(t){return t.hint?`hint: ${t.hint}`:void 0}function b(t,e){return t.diagnosticId?`${e}: ${t.diagnosticId}`:void 0}function I(t,e){return t.logPath?`${e}: ${t.logPath}`:void 0}function C(t,e){e&&t.push(e)}function k(t){return void 0!==t}function j(t){return"passed"!==t.status?[]:(t.warnings??[]).map(t=>`warning: ${t}`)}function D(t){return(Math.max(0,t)/1e3).toFixed(3)}function x(t){return t.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;").replaceAll("'","&apos;")}async function N({command:d,positionals:l,flags:f,client:p}){var c,A,b,I,k;"test"===d&&(({json:f.json}).json||process.stderr.write("Running replay suite...\n"));let{result:F,cliOutput:P}=await n({client:p,command:d,positionals:l,flags:f});if(P){c=f,A=P,!c.json&&A.stderr&&process.stderr.write(A.stderr),o(c,c.json?A.jsonData??A.data:A.data,()=>A.text)}else{let n=(b=d,I=f,k=F,"test"===b?function(n){let{suite:o,json:a,verbose:d,reportJunit:l}=n;return(l&&function(r,n){let i=e.dirname(r);try{t.mkdirSync(i,{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="${D(t.durationMs)}">`];for(let s of t.tests)r.push(...function(t){let r=x(`${h(t)??e.basename(t.file)}${M(t)}`),s=x(`${"."===e.dirname(t.file)?t.file:e.dirname(t.file)}${M(t)}`),n=x(t.file),i=D(t.durationMs),o=[` <testcase classname="${s}" name="${r}" file="${n}" time="${i}">`];"failed"===t.status?o.push(` <failure message="${x(t.error.message)}">${x(function(t){let e=[t.error.message];return S(e,t.error,{includeDetails:!1}),C(e,w(t,"artifactsDir")),_(e,t.error,2),e.join("\n")}(t))}</failure>`):"skipped"===t.status&&o.push(` <skipped message="${x(t.message)}" />`);let a=function(t){let e=[`status: ${t.status}`,`durationMs: ${t.durationMs}`];return function(t,e){var r,s,n,i;for(let r of(C(t,"attempts"in e?`attempts: ${e.attempts}`:void 0),C(t,"session"in e?`session: ${e.session}`:void 0),C(t,"replayed"in e?`replayed: ${e.replayed}`:void 0),C(t,"healed"in e?`healed: ${e.healed}`:void 0),j(e)))t.push(r);C(t,w(e,"artifactsDir")),r=t,s=e,"shardIndex"in s&&"number"==typeof s.shardIndex&&(r.push(`shardIndex: ${s.shardIndex}`),C(r,"number"==typeof s.shardCount?`shardCount: ${s.shardCount}`:void 0),C(r,"string"==typeof s.deviceId?`deviceId: ${s.deviceId}`:void 0)),"failed"===e.status&&(n=t,i=e,n.push(`errorCode: ${i.error.code}`),S(n,i.error,{includeMessage:!0})),C(t,$(e)?"flaky: true":void 0)}(e,t),e.join("\n")}(t);return a&&o.push(` <system-out>${x(a)}</system-out>`),o.push(" </testcase>"),o}(s));return r.push(" </testsuite>"),r.push("</testsuites>"),`${r.join("\n")}
6
- `}(n),"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}`)}}(l,o),a)?(i({success:!0,data:o}),+(o.failed>0)):function(t,e={}){let s=t.tests.filter($);if(e.verbose)for(let e of t.tests)!function(t){var e;if("failed"===t.status)return m(t);let r=y(t);for(let s of(process.stdout.write(`${"passed"===(e=t).status?"PASS":"skipped"===e.status?"SKIP":"INFO"} ${g(t)}${r}
5
+ `)}function $(t){return"passed"===t.status&&t.attempts>1}function g(t){let r=h(t),s=r&&r.length>0?JSON.stringify(r):e.basename(t.file);return`${s}${M(t)}`}function h(t){let e=t.title?.trim();return e&&e.length>0?e:void 0}function y(t){if("passed"===t.status&&t.attempts>1)return v(t);if("failed"===t.status&&t.attempts>1&&t.durationMs>0)return` (total ${r(t.durationMs)})`;let e="passed"===t.status&&"number"==typeof t.finalAttemptDurationMs?t.finalAttemptDurationMs:t.durationMs;return e>0?` (${r(e)})`:""}function v(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(", ")})`:""}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 _(t,e,r={}){r.includeMessage&&t.push(`errorMessage: ${e.message}`),I(t,A(e)),I(t,b(e,"diagnosticId")),I(t,C(e,"logPath")),!1!==r.includeDetails&&S(t,e,r.detailsIndent)}function S(t,e,r){let s=e.details?JSON.stringify(e.details,null,r):void 0;s&&t.push(`details: ${s}`)}function w(t,e){return"artifactsDir"in t&&t.artifactsDir?`${e}: ${t.artifactsDir}`:void 0}function A(t){return t.hint?`hint: ${t.hint}`:void 0}function b(t,e){return t.diagnosticId?`${e}: ${t.diagnosticId}`:void 0}function C(t,e){return t.logPath?`${e}: ${t.logPath}`:void 0}function I(t,e){e&&t.push(e)}function k(t){return void 0!==t}function j(t){return"passed"!==t.status?[]:(t.warnings??[]).map(t=>`warning: ${t}`)}function D(t){return(Math.max(0,t)/1e3).toFixed(3)}function x(t){return t.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;").replaceAll("'","&apos;")}async function N({command:d,positionals:l,flags:f,client:p}){var c,A,b,C,k;"test"===d&&(({json:f.json}).json||process.stderr.write("Running replay suite...\n"));let{result:P,cliOutput:F}=await i({client:p,command:d,positionals:l,flags:f});if(F){c=f,A=F,!c.json&&A.stderr&&process.stderr.write(A.stderr),o(c,c.json?A.jsonData??A.data:A.data,()=>A.text)}else{let i=(b=d,C=f,k=P,"test"===b?function(i){let{suite:o,json:a,verbose:d,reportJunit:l}=i;return(l&&function(r,n){let i=e.dirname(r);try{t.mkdirSync(i,{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="${D(t.durationMs)}">`];for(let s of t.tests)r.push(...function(t){let r=x(`${h(t)??e.basename(t.file)}${M(t)}`),s=x(`${"."===e.dirname(t.file)?t.file:e.dirname(t.file)}${M(t)}`),n=x(t.file),i=D(t.durationMs),o=[` <testcase classname="${s}" name="${r}" file="${n}" time="${i}">`];"failed"===t.status?o.push(` <failure message="${x(t.error.message)}">${x(function(t){let e=[t.error.message];return _(e,t.error,{includeDetails:!1}),I(e,w(t,"artifactsDir")),S(e,t.error,2),e.join("\n")}(t))}</failure>`):"skipped"===t.status&&o.push(` <skipped message="${x(t.message)}" />`);let a=function(t){let e=[`status: ${t.status}`,`durationMs: ${t.durationMs}`];return function(t,e){var r,s,n,i;for(let r of(I(t,"attempts"in e?`attempts: ${e.attempts}`:void 0),I(t,"session"in e?`session: ${e.session}`:void 0),I(t,"replayed"in e?`replayed: ${e.replayed}`:void 0),I(t,"healed"in e?`healed: ${e.healed}`:void 0),j(e)))t.push(r);I(t,w(e,"artifactsDir")),r=t,s=e,"shardIndex"in s&&"number"==typeof s.shardIndex&&(r.push(`shardIndex: ${s.shardIndex}`),I(r,"number"==typeof s.shardCount?`shardCount: ${s.shardCount}`:void 0),I(r,"string"==typeof s.deviceId?`deviceId: ${s.deviceId}`:void 0)),"failed"===e.status&&(n=t,i=e,n.push(`errorCode: ${i.error.code}`),_(n,i.error,{includeMessage:!0})),I(t,$(e)?"flaky: true":void 0)}(e,t),e.join("\n")}(t);return a&&o.push(` <system-out>${x(a)}</system-out>`),o.push(" </testcase>"),o}(s));return r.push(" </testsuite>"),r.push("</testsuites>"),`${r.join("\n")}
6
+ `}(n),"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}`)}}(l,o),a)?(n({success:!0,data:o}),+(o.failed>0)):function(t,e={}){let s=t.tests.filter($);if(e.verbose)for(let e of t.tests)!function(t){var e;if("failed"===t.status)return m(t);let r=y(t);for(let s of(process.stdout.write(`${"passed"===(e=t).status?"PASS":"skipped"===e.status?"SKIP":"INFO"} ${g(t)}${r}
7
7
  `),"skipped"===t.status&&process.stdout.write(` ${t.message??"skipped"}
8
8
  `),j(t)))process.stdout.write(` ${s}
9
9
  `);for(let e of u(t))process.stdout.write(` ${e}
@@ -12,4 +12,4 @@ import t from"node:fs";import e from"node:path";import{formatDurationSeconds as
12
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
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)}
14
14
  `),e.attemptFailures??[])){let e="number"==typeof t.durationMs?` (${r(t.durationMs)})`:"";process.stdout.write(` attempt ${t.attempt} failed${e}: ${t.message}
15
- `)}}(s),+(t.failed>0)}(o,{verbose:d})}({suite:k,verbose:I.verbose,json:I.json,reportJunit:I.reportJunit}):(o(I,k,()=>a(k)),0));0!==n&&process.exit(n)}return!0}export{N as runGenericClientBackedCommand};
15
+ `)}}(s),+(t.failed>0)}(o,{verbose:d})}({suite:k,verbose:C.verbose,json:C.json,reportJunit:C.reportJunit}):(o(C,k,()=>a(k)),0));0!==i&&process.exit(i)}return!0}export{N as runGenericClientBackedCommand};