agent-device 0.17.5 → 0.17.7

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 (134) hide show
  1. package/README.md +5 -5
  2. package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.17.5.apk → agent-device-android-multitouch-helper-0.17.7.apk} +0 -0
  3. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.17.7.apk.sha256 +1 -0
  4. package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.17.5.manifest.json → agent-device-android-multitouch-helper-0.17.7.manifest.json} +4 -4
  5. package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.17.5.apk → agent-device-android-snapshot-helper-0.17.7.apk} +0 -0
  6. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.17.7.apk.sha256 +1 -0
  7. package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.17.5.manifest.json → agent-device-android-snapshot-helper-0.17.7.manifest.json} +6 -6
  8. package/dist/src/2133.js +1 -0
  9. package/dist/src/2748.js +1 -0
  10. package/dist/src/{4012.js → 2892.js} +1 -1
  11. package/dist/src/2948.js +1 -0
  12. package/dist/src/2954.js +2 -0
  13. package/dist/src/{7651.js → 3006.js} +1 -1
  14. package/dist/src/314.js +1 -0
  15. package/dist/src/{8806.js → 3340.js} +5 -5
  16. package/dist/src/368.js +1 -0
  17. package/dist/src/4291.js +1 -0
  18. package/dist/src/{7599.js → 432.js} +1 -1
  19. package/dist/src/4418.js +1 -0
  20. package/dist/src/4428.js +3 -0
  21. package/dist/src/4723.js +1 -0
  22. package/dist/src/{113.js → 5448.js} +1 -1
  23. package/dist/src/5484.js +1 -0
  24. package/dist/src/5628.js +1 -0
  25. package/dist/src/587.js +1 -0
  26. package/dist/src/5910.js +2 -0
  27. package/dist/src/6311.js +27 -0
  28. package/dist/src/6918.js +1 -0
  29. package/dist/src/7244.js +1 -0
  30. package/dist/src/7394.js +6 -0
  31. package/dist/src/8184.js +1 -0
  32. package/dist/src/8225.js +1 -0
  33. package/dist/src/{1974.js → 8275.js} +1 -1
  34. package/dist/src/8875.js +1 -0
  35. package/dist/src/9581.js +11 -0
  36. package/dist/src/9624.js +1 -0
  37. package/dist/src/9722.js +38 -0
  38. package/dist/src/9836.js +1 -0
  39. package/dist/src/9873.js +1 -0
  40. package/dist/src/9919.js +6 -0
  41. package/dist/src/android-adb.d.ts +3 -3
  42. package/dist/src/android-adb.js +1 -1
  43. package/dist/src/android-snapshot-helper.js +1 -1
  44. package/dist/src/android.js +1 -1
  45. package/dist/src/apple.js +1 -1
  46. package/dist/src/apps.js +6 -6
  47. package/dist/src/artifacts.js +1 -1
  48. package/dist/src/batch.d.ts +5 -5
  49. package/dist/src/batch.js +1 -1
  50. package/dist/src/{args.js → cli-help.js} +135 -36
  51. package/dist/src/cli-output.js +4 -30
  52. package/dist/src/cli.js +18 -17
  53. package/dist/src/command-surface.js +1 -1
  54. package/dist/src/contracts.d.ts +7 -7
  55. package/dist/src/contracts.js +1 -1
  56. package/dist/src/devices.js +1 -1
  57. package/dist/src/find.js +1 -1
  58. package/dist/src/finders.d.ts +1 -1
  59. package/dist/src/finders.js +1 -1
  60. package/dist/src/generic.js +8 -14
  61. package/dist/src/index.d.ts +34 -28
  62. package/dist/src/index.js +1 -1
  63. package/dist/src/input-actions.js +1 -1
  64. package/dist/src/input-actions~1.js +1 -1
  65. package/dist/src/install-source.js +1 -1
  66. package/dist/src/interaction.js +1 -1
  67. package/dist/src/internal/bin.js +5 -5
  68. package/dist/src/internal/companion-tunnel.js +1 -1
  69. package/dist/src/internal/daemon.js +1 -1
  70. package/dist/src/internal/png-worker.js +1 -1
  71. package/dist/src/internal/update-check-entry.js +1 -1
  72. package/dist/src/io.js +1 -1
  73. package/dist/src/lease.js +1 -1
  74. package/dist/src/linux.js +1 -1
  75. package/dist/src/metro.js +1 -1
  76. package/dist/src/notifications.js +1 -1
  77. package/dist/src/provider.js +1 -0
  78. package/dist/src/react-native.js +1 -1
  79. package/dist/src/record-trace-recording.js +3 -3
  80. package/dist/src/record-trace.js +1 -1
  81. package/dist/src/recording-provider.js +1 -1
  82. package/dist/src/remote-config.d.ts +6 -6
  83. package/dist/src/remote-config.js +1 -1
  84. package/dist/src/rslib-runtime.js +1 -1
  85. package/dist/src/selector-runtime.js +1 -1
  86. package/dist/src/selectors.d.ts +2 -2
  87. package/dist/src/selectors.js +1 -1
  88. package/dist/src/server.js +1 -1
  89. package/dist/src/session.js +8 -8
  90. package/dist/src/snapshot.js +2 -2
  91. package/dist/src/web.js +1 -0
  92. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +6 -6
  93. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +1 -1
  94. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScreenRecorder.swift +9 -5
  95. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +5 -2
  96. package/ios-runner/AgentDeviceRunner/RecordingScripts/recording-overlay.swift +44 -8
  97. package/ios-runner/AgentDeviceRunner/RecordingScripts/recording-resize.swift +59 -16
  98. package/ios-runner/RUNNER_PROTOCOL.md +1 -1
  99. package/package.json +18 -14
  100. package/server.json +3 -3
  101. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.17.5.apk.sha256 +0 -1
  102. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.17.5.apk.sha256 +0 -1
  103. package/dist/src/1010.js +0 -1
  104. package/dist/src/123.js +0 -1
  105. package/dist/src/1231.js +0 -1
  106. package/dist/src/1352.js +0 -1
  107. package/dist/src/208.js +0 -1
  108. package/dist/src/221.js +0 -6
  109. package/dist/src/2403.js +0 -3
  110. package/dist/src/2415.js +0 -38
  111. package/dist/src/3675.js +0 -1
  112. package/dist/src/5611.js +0 -1
  113. package/dist/src/5827.js +0 -1
  114. package/dist/src/6088.js +0 -1
  115. package/dist/src/6133.js +0 -1
  116. package/dist/src/6629.js +0 -1
  117. package/dist/src/7556.js +0 -1
  118. package/dist/src/7719.js +0 -1
  119. package/dist/src/7847.js +0 -1
  120. package/dist/src/8133.js +0 -1
  121. package/dist/src/8656.js +0 -1
  122. package/dist/src/9010.js +0 -1
  123. package/dist/src/9471.js +0 -1
  124. package/dist/src/9542.js +0 -6
  125. package/dist/src/9616.js +0 -2
  126. package/dist/src/9639.js +0 -2
  127. package/dist/src/9671.js +0 -1
  128. package/dist/src/9818.js +0 -1
  129. package/dist/src/989.js +0 -1
  130. /package/dist/src/{2301.js → 4069.js} +0 -0
  131. /package/dist/src/{4829.js → 5560.js} +0 -0
  132. /package/dist/src/{4778.js → 6024.js} +0 -0
  133. /package/dist/src/{9152.js → 733.js} +0 -0
  134. /package/dist/src/{3267.js → 9612.js} +0 -0
@@ -0,0 +1 @@
1
+ import{deflateSync as t,inflateSync as e}from"node:zlib";import{AppError as r}from"./733.js";let n=Buffer.from([137,80,78,71,13,10,26,10]),i=new Map([[0,1],[2,3],[3,1],[4,2],[6,4]]),o=new Map([[0,new Set([1,2,4,8,16])],[2,new Set([8,16])],[3,new Set([1,2,4,8])],[4,new Set([8,16])],[6,new Set([8,16])]]),f=[{x:0,y:0,dx:8,dy:8},{x:4,y:0,dx:8,dy:8},{x:0,y:4,dx:4,dy:8},{x:2,y:0,dx:4,dy:4},{x:0,y:2,dx:2,dy:4},{x:1,y:0,dx:2,dy:2},{x:0,y:1,dx:1,dy:2}];class a{width;height;data;static sync={read:h,write:l};constructor(t){this.width=E(t.width,"width"),this.height=E(t.height,"height");let e=this.width*this.height*4;if(this.data=t.data?Buffer.from(t.data):Buffer.alloc(e),this.data.length!==e)throw Error(`PNG data length must be ${e} bytes`)}}function h(t){var r;let{metadata:h,idatChunks:l}=function(t){let e,r=[];for(let f of function*(t){if(!t.subarray(0,n.length).equals(n))throw Error("Invalid PNG signature");let e=n.length;for(;e<t.length;){if(e+12>t.length)throw Error("Truncated PNG chunk");let r=t.readUInt32BE(e),n=t.toString("ascii",e+4,e+8),i=e+8,o=i+r;if(o+4>t.length)throw Error(`Truncated PNG ${n} chunk`);let f=t.subarray(i,o),a=t.readUInt32BE(o);if(g(t.subarray(e+4,o))!==a)throw Error(`Invalid PNG ${n} chunk CRC`);e=o+4,yield{type:n,data:f}}}(t))if("IHDR"===f.type?e=function(t){var e;if(13!==t.length)throw Error("Invalid PNG IHDR length");let r=t.readUInt32BE(0),n=t.readUInt32BE(4),f=t[8],a=t[9],h=t[10],l=t[11],u=t[12];if(e=a,!i.has(e))throw Error(`Unsupported PNG color type ${a}`);let c=o.get(a);if(!c?.has(f))throw Error(`Unsupported PNG color type ${a} with bit depth ${f}`);if(0!==h)throw Error(`Unsupported PNG compression method ${h}`);if(0!==l)throw Error(`Unsupported PNG filter method ${l}`);if(0!==u&&1!==u)throw Error(`Unsupported PNG interlace method ${u}`);return{width:E(r,"width"),height:E(n,"height"),bitDepth:f,colorType:a,interlace:u}}(f.data):"IDAT"===f.type?r.push(Buffer.from(f.data)):e=function(t,e){if("PLTE"===t.type){if(!e)throw Error("PNG PLTE appeared before IHDR");e.palette=Buffer.from(t.data)}else if("tRNS"===t.type){if(!e)throw Error("PNG tRNS appeared before IHDR");e.transparency=Buffer.from(t.data)}return e}(f,e),"IEND"===f.type)break;return{metadata:e,idatChunks:r}}(t);if(!h)throw Error("PNG is missing IHDR");if(0===l.length)throw Error("PNG is missing IDAT");let s=function(t,r){let n=function(t){if(0===t.interlace)return function(t,e){return(p(t)+1)*e}(t,t.height);let e=0;for(let r of f){let n=c(t.width,r.x,r.dx),i=c(t.height,r.y,r.dy);0!==n&&0!==i&&(e+=function(t,e){return(p(t)+1)*e}({...t,width:n,height:i},i))}return e}(r);try{let r=e(Buffer.concat(t),{maxOutputLength:n});if(r.length!==n)throw Error("PNG pixel data is truncated");return r}catch(t){var i;if((i=t)instanceof Error&&"code"in i&&"ERR_BUFFER_TOO_LARGE"===i.code)throw Error(`PNG pixel data exceeds expected length ${n}`);throw t}}(l,h);return new a({width:h.width,height:h.height,data:1===h.interlace?function(t,e){let r=Buffer.alloc(e.width*e.height*4),n=0;for(let i of f){let o=c(e.width,i.x,i.dx),f=c(e.height,i.y,i.dy);if(0===o||0===f)continue;let a={...e,width:o,height:f,interlace:0},h=u({inflated:t,offset:n,scanlineLength:p(a),height:f,bytesPerPixel:y(a)});n=h.offset;let l=p(a);for(let t=0;t<f;t+=1){let n=h.raw.subarray(t*l,(t+1)*l);for(let f=0;f<o;f+=1){let o=i.x+f*i.dx,h=((i.y+t*i.dy)*e.width+o)*4,[l,u,c,s]=d(n,f,a);r[h]=l,r[h+1]=u,r[h+2]=c,r[h+3]=s}}}return r}(s,h):function(t,e){let r=Buffer.alloc(e.width*e.height*4),n=p(e);for(let i=0;i<e.height;i+=1){let o=t.subarray(i*n,(i+1)*n);for(let t=0;t<e.width;t+=1){let n=(i*e.width+t)*4,[f,a,h,l]=d(o,t,e);r[n]=f,r[n+1]=a,r[n+2]=h,r[n+3]=l}}return r}(u({inflated:s,offset:0,scanlineLength:p(r=h),height:r.height,bytesPerPixel:y(r)}).raw,h)})}function l(e){let r=4*e.width,i=Buffer.alloc((r+1)*e.height);for(let t=0;t<e.height;t+=1){let n=t*(r+1);i[n]=0,e.data.copy(i,n+1,t*r,(t+1)*r)}let o=Buffer.alloc(13);return o.writeUInt32BE(e.width,0),o.writeUInt32BE(e.height,4),o[8]=8,o[9]=6,o[10]=0,o[11]=0,o[12]=0,Buffer.concat([n,w("IHDR",o),w("IDAT",t(i)),w("IEND",Buffer.alloc(0))])}function u(t){let{inflated:e,offset:r,scanlineLength:n,height:i,bytesPerPixel:o}=t,f=r+(n+1)*i;if(e.length<f)throw Error("PNG pixel data is truncated");let a=Buffer.alloc(n*i);for(let t=0;t<i;t+=1){let i=r+t*(n+1),f=t*n,h=e[i];for(let r=0;r<n;r+=1){let l=e[i+1+r],u=r>=o?a[f+r-o]:0,c=t>0?a[f+r-n]:0,d=t>0&&r>=o?a[f+r-n-o]:0;a[f+r]=function(t,e,r,n,i){if(0===t)return e;if(1===t)return e+r&255;if(2===t)return e+n&255;if(3===t)return e+Math.floor((r+n)/2)&255;if(4===t)return e+function(t,e,r){let n=t+e-r,i=Math.abs(n-t),o=Math.abs(n-e),f=Math.abs(n-r);return i<=o&&i<=f?t:o<=f?e:r}(r,n,i)&255;throw Error(`Unsupported PNG filter type ${t}`)}(h,l,u,c,d)}}return{raw:a,offset:f}}function c(t,e,r){return t<=e?0:Math.floor((t-e+r-1)/r)}function d(t,e,r){if(3===r.colorType){var n,o,f,a,h,l,u,c=t,d=e,p=r;if(!p.palette)throw Error("Indexed PNG is missing PLTE");let i=s(c,d,p.bitDepth),y=3*i;if(y+2>=p.palette.length)throw Error("Indexed PNG palette is invalid");return[p.palette[y],p.palette[y+1],p.palette[y+2],p.transparency?.[i]??255]}if(r.bitDepth<8){let i,o;return[o=Math.round((i=s(t,e,(n=r).bitDepth))/((1<<n.bitDepth)-1)*255),o,o,255*!(n.transparency&&n.transparency.length>=2&&i===n.transparency.readUInt16BE(0))]}let y=16===r.bitDepth?2:1,w=e*i.get(r.colorType)*y,g=e=>16===r.bitDepth?t.readUInt16BE(w+2*e):t[w+e*y],E=t=>{var e;return e=g(t),16===r.bitDepth?Math.round(e/65535*255):e};if(0===r.colorType){let t=E(0);return[t,t,t,255*(o=g(0),!(f=r).transparency||!!(f.transparency.length<2)||o!==f.transparency.readUInt16BE(0))]}if(2===r.colorType){return[E(0),E(1),E(2),255*(a=g(0),h=g(1),l=g(2),!(u=r).transparency||!!(u.transparency.length<6)||a!==u.transparency.readUInt16BE(0)||h!==u.transparency.readUInt16BE(2)||l!==u.transparency.readUInt16BE(4))]}if(4===r.colorType){let t=E(0);return[t,t,t,E(1)]}return[E(0),E(1),E(2),E(3)]}function s(t,e,r){let n=e*r;return t[Math.floor(n/8)]>>8-r-n%8&(1<<r)-1}function p(t){let e=i.get(t.colorType);return Math.ceil(t.width*e*t.bitDepth/8)}function y(t){return Math.max(1,Math.ceil(i.get(t.colorType)*t.bitDepth/8))}function w(t,e){let r=Buffer.from(t,"ascii"),n=Buffer.alloc(8+e.length+4);return n.writeUInt32BE(e.length,0),r.copy(n,4),e.copy(n,8),n.writeUInt32BE(g(Buffer.concat([r,e])),8+e.length),n}function g(t){let e=0xffffffff;for(let r of t){e^=r;for(let t=0;t<8;t+=1)e=1&e?0xedb88320^e>>>1:e>>>1}return(0xffffffff^e)>>>0}function E(t,e){if(!Number.isInteger(t)||t<1)throw Error(`PNG ${e} must be positive`);return t}function x(t,e){try{return a.sync.read(t)}catch(t){throw new r("COMMAND_FAILED",`Failed to decode ${e} as PNG`,{label:e,reason:t instanceof Error?t.message:String(t)})}}function B(t){let{baselineData:e,currentData:r,maxColorDistance:n}=t,i=t.width*t.height,o=Buffer.alloc(4*i),f=new Uint8Array(i),a=0;for(let t=0,i=0;t<e.length;t+=4,i+=1){if(Math.sqrt((e[t]-r[t])**2+(e[t+1]-r[t+1])**2+(e[t+2]-r[t+2])**2)>n){a+=1,f[i]=1;let e=P(r,t);o[t]=b(e,220,.78),o[t+1]=b(e,0,.78),o[t+2]=b(e,0,.78),o[t+3]=255;continue}let h=P(r,t);o[t]=h,o[t+1]=h,o[t+2]=h,o[t+3]=255}return{diffData:o,diffMask:f,differentPixels:a}}function P(t,e){return b(Math.round(.299*t[e]+.587*t[e+1]+.114*t[e+2]),255,.72)}function b(t,e,r){return Math.round(t*(1-r)+e*r)}function I(t){return Buffer.from(t.buffer,t.byteOffset,t.byteLength)}export{a as PNG,B as computeScreenshotDiffPixels,x as decodePng,I as toBuffer};
@@ -0,0 +1,3 @@
1
+ import e from"node:fs";import{parseAllDocuments as t,stringify as n}from"yaml";import{AppError as r}from"./733.js";import{recordingQualityInputToExportQuality as i,readScreenshotScriptFlag as o,MAESTRO_COMPAT_TRACKER_URL as s,MAESTRO_NEW_ISSUE_URL as l}from"./9873.js";import{formatScriptStringLiteral as a,parseReplayOpenFlags as u,formatPortableActionLine as f,parseReplaySeriesFlags as c,parseReplayRuntimeFlags as p,isClickLikeCommand as h}from"./368.js";let d=/^[A-Z_][A-Z0-9_]*$/,m=/(\\\$\{)|\$\{([A-Za-z_][A-Za-z0-9_.]*)(?::-((?:[^}\\]|\\.)*))?\}/g,g="AD_VAR_";function A(e){return e.startsWith("AD_")}function v(e){return new r("INVALID_ARGS",`The AD_* namespace is reserved for built-in variables. Rename ${e} to avoid the AD_ prefix.`)}function y(e){let t={};if(e.builtins)for(let[n,r]of Object.entries(e.builtins))t[n]=r;for(let n of[e.fileEnv,e.shellEnv,e.cliEnv])if(n)for(let[e,r]of Object.entries(n)){if(A(e))throw v(e);t[e]=r}return{values:t}}function w(e,t){Object.assign(e.values,t)}function b(e){let t={};for(let[n,r]of Object.entries(e)){if("string"!=typeof r||!n.startsWith(g))continue;let e=n.slice(g.length);0!==e.length&&d.test(e)&&(A(e)||(t[e]=r))}return t}function I(e){let t={};for(let n of e){let e=n.indexOf("=");if(e<=0)throw new r("INVALID_ARGS",`Invalid -e entry "${n}": expected KEY=VALUE.`);let i=n.slice(0,e);if(!d.test(i))throw new r("INVALID_ARGS",`Invalid -e key "${i}": keys must be uppercase letters, digits, and underscores (e.g. APP_ID).`);if(A(i))throw v(i);t[i]=n.slice(e+1)}return t}function $(e){return Array.isArray(e)?e.filter(e=>"string"==typeof e):[]}function S(e){if(e&&"object"==typeof e&&!Array.isArray(e)){let t={};for(let[n,r]of Object.entries(e))"string"==typeof r&&(t[n]=r);return t}return process.env}function _(e,t,n){return e.replace(m,(e,i,o,s)=>{if(i)return"${";if(!o)return e;if(Object.prototype.hasOwnProperty.call(t.values,o))return String(t.values[o]);if(void 0!==s)return s.replace(/\\(.)/g,"$1");throw new r("INVALID_ARGS",`Unresolved variable \${${o}} at ${n.file}:${n.line}.`)})}function N(e,t,n){return{...e,positionals:(e.positionals??[]).map(e=>_(e,t,n)),flags:R(e.flags,t,n)??{},runtime:R(e.runtime,t,n),replayControl:function(e,t,n){if(!e)return e;if(e.kind==="maestroRunFlowWhen"){return{...e,selector:_(e.selector,t,n)}}return e}(e.replayControl,t,n)}}function R(e,t,n){return e?function e(t,n,r){return"string"==typeof t?_(t,n,r):Array.isArray(t)?t.map(t=>e(t,n,r)):t&&"object"==typeof t?Object.fromEntries(Object.entries(t).map(([t,i])=>[t,e(i,n,r)])):t}(e,t,n):e}let D=new Set(["ios","android","macos","linux"]),M=new Set(["mobile","tv","desktop"]);function x(e){let t=[],n=[],s=e.split(/\r?\n/),l=!1;for(let[e,a]of s.entries()){let s=a.trim();if(0===s.length||s.startsWith("#"))continue;if(L(s)){if(l)throw new r("INVALID_ARGS",`env directives must precede all actions (line ${e+1}).`);continue}let f=function(e){let t=e.trim();if(0===t.length||t.startsWith("#"))return null;let[n,...s]=function(e){let t=[],n=0;for(;n<e.length&&!((n=function(e,t){let n=t;for(;n<e.length&&/\s/.test(e.charAt(n));)n+=1;return n}(e,n))>=e.length);){let i='"'===e[n]?function(e,t){let n=!1,i=t+1;for(;i<e.length;i+=1){let t=e.charAt(i);if('"'===t&&!n)break;if(n){n=!1;continue}n="\\"===t}if(i>=e.length)throw new r("INVALID_ARGS",`Invalid replay script line: ${e}`);return{value:JSON.parse(e.slice(t,i+1)),nextCursor:i+1}}(e,n):function(e,t){let n=t;for(;n<e.length&&!/\s/.test(e.charAt(n));)n+=1;return{value:e.slice(t,n),nextCursor:n}}(e,n);t.push(i.value),n=i.nextCursor}return t}(t);if(void 0===n||"context"===n)return null;let l={ts:Date.now(),command:n,positionals:[],flags:{}};if("snapshot"===n){l.positionals=[];for(let e=0;e<s.length;e+=1){let t=s[e];if("-i"===t){l.flags.snapshotInteractiveOnly=!0;continue}if("-c"!==t){if("--raw"===t){l.flags.snapshotRaw=!0;continue}if("--force-full"===t){l.flags.snapshotForceFull=!0;continue}if(("-d"===t||"--depth"===t)&&e+1<s.length){let t=Number(s[e+1]);Number.isFinite(t)&&t>=0&&(l.flags.snapshotDepth=Math.floor(t)),e+=1;continue}if(("-s"===t||"--scope"===t)&&e+1<s.length){l.flags.snapshotScope=s[e+1],e+=1;continue}if("--backend"===t&&e+1<s.length){e+=1;continue}}}return l}if("open"===n){let e=u(s);return l.positionals=e.positionals,Object.assign(l.flags,e.flags),l.runtime=e.runtime,l}if("runtime"===n){let e=p(s);return l.positionals=e.positionals,Object.assign(l.flags,e.flags),l}if(h(n)){let e=c(n,s);Object.assign(l.flags,e.flags);let t=e.positionals[0];if(void 0===t)return l;if(t.startsWith("@"))return l.positionals=[t],e.positionals[1]&&(l.result={refLabel:e.positionals[1]}),l;let r=e.positionals[0],i=e.positionals[1];return V(r)&&V(i)&&e.positionals.length>=2?l.positionals=[r,i]:l.positionals=[e.positionals.join(" ")],l}if("fill"===n){let e=c(n,s);if(Object.assign(l.flags,e.flags),!(e.positionals.length>=2))return l.positionals=e.positionals,l;let[t,r,...i]=e.positionals;return t.startsWith("@")?(i.length>0?(l.positionals=[t,i.join(" ")],l.result={refLabel:r}):l.positionals=[t,r],l):(l.positionals=[t,[r,...i].join(" ")],l)}if("get"===n){let e=s[0],t=s[1];return void 0===e||void 0===t?l.positionals=s:t.startsWith("@")?(l.positionals=[e,t],s[2]&&(l.result={refLabel:s[2]})):l.positionals=[e,s.slice(1).join(" ")],l}if("swipe"===n||"type"===n){let e=c(n,s);return Object.assign(l.flags,e.flags),l.positionals=e.positionals,l}if("record"===n){let e=[];for(let t=0;t<s.length;t+=1){let n=s[t];if("--hide-touches"===n){l.flags.hideTouches=!0;continue}if("--fps"===n&&t+1<s.length){let e=Number(s[t+1]);Number.isFinite(e)&&(l.flags.fps=Math.floor(e)),t+=1;continue}if("--quality"===n&&t+1<s.length){let e=i(s[t+1]);void 0!==e&&(l.flags.quality=e),t+=1;continue}if("--max-size"===n&&t+1<s.length){let e=Number(s[t+1]);Number.isFinite(e)&&(l.flags.screenshotMaxSize=Math.floor(e)),t+=1;continue}e.push(n)}return l.positionals=e,l}if("screenshot"===n){let e=[];for(let t=0;t<s.length;t+=1){let n=s[t],r=o({args:s,index:t,flags:l.flags});if(r.handled){t=r.nextIndex;continue}e.push(n)}return l.positionals=e,l}return l.positionals=s,l}(a);f&&(t.push(f),n.push(e+1),l=!0)}return{actions:t,actionLines:n}}function O(e){let t=e.split(/\r?\n/),n={};for(let[e,i]of t.entries()){let t=i.trim();if(0===t.length||t.startsWith("#"))continue;if(L(t)){!function(e,t,n){let{key:i,value:o}=function(e,t){let n=e.slice(3).replace(/^[\s]+/,""),i=n.indexOf("=");if(i<=0)throw new r("INVALID_ARGS",`Invalid env directive on line ${t}: expected "env KEY=VALUE".`);let o=n.slice(0,i);if(!d.test(o))throw new r("INVALID_ARGS",`Invalid env key "${o}" on line ${t}: keys must be uppercase letters, digits, and underscores (e.g. APP_ID).`);if(o.startsWith("AD_"))throw new r("INVALID_ARGS",`Invalid env key "${o}" on line ${t}: the AD_* namespace is reserved for built-in variables. Rename ${o} to avoid the AD_ prefix.`);return{key:o,value:function(e,t){if(0===e.length)return"";if(e.startsWith('"'))try{let t=JSON.parse(e);if("string"!=typeof t)throw Error("not a string literal");return t}catch{throw new r("INVALID_ARGS",`Invalid quoted env value on line ${t}.`)}return e}(n.slice(i+1),t)}}(t,n),s=e.env??{};if(Object.prototype.hasOwnProperty.call(s,i))throw new r("INVALID_ARGS",`Duplicate env directive "${i}" on line ${n}.`);s[i]=o,e.env=s}(n,t,e+1);continue}if(!t.startsWith("context "))break;let o=t.match(/(?:^|\s)platform=([^\s]+)/);if(o){let e=o[1];e&&D.has(e)&&j(n,"platform",e)}let s=t.match(/(?:^|\s)target=([^\s]+)/);if(s){let e=s[1];e&&M.has(e)&&j(n,"target",e)}let l=t.match(/(?:^|\s)timeout=(\d+)/);if(l){let e=Number(l[1]);Number.isFinite(e)&&e>=1&&j(n,"timeoutMs",Math.floor(e))}let a=t.match(/(?:^|\s)retries=(\d+)/);if(a){let e=Number(a[1]);Number.isFinite(e)&&e>=0&&j(n,"retries",Math.floor(e))}}return n}function L(e){return"env"===e||e.startsWith("env ")||e.startsWith("env ")}function j(e,t,n){let i=e[t];if(void 0!==i)throw new r("INVALID_ARGS",i===n?`Duplicate replay test metadata "${t}" in context header.`:`Conflicting replay test metadata "${t}" in context header: ${String(i)} vs ${String(n)}.`);e[t]=n}function V(e){return!!e&&!Number.isNaN(Number(e))}function k(t,n,r){let i=[];if(r){let e=r.device.kind?` kind=${r.device.kind}`:"",t=r.device.target?` target=${r.device.target}`:"";i.push(`context platform=${r.device.platform}${t} device=${a(r.device.name)}${e} theme=unknown`)}for(let e of n)i.push(f(e,{runtimeIncludeAllPositionals:!0}));let o=`${i.join("\n")}
2
+ `,s=`${t}.tmp-${process.pid}-${Date.now()}`;e.writeFileSync(s,o),e.renameSync(s,t)}function E(e){let n=t(e);for(let e of n)if(e.errors.length>0){let t=e.errors[0]?.message??"Invalid Maestro YAML flow.";throw new r("INVALID_ARGS",`Invalid Maestro YAML flow: ${t}`)}return n.map(e=>e.toJSON()).filter(e=>null!==e)}function G(e){return`${e.map(e=>n(e).trimEnd()).join("\n---\n")}
3
+ `}function C(e,t=[],n){return{ts:Date.now(),command:e,positionals:t,flags:n??{}}}function P(e,t,n){let r=new Set(n),i=Object.keys(e).filter(e=>!r.has(e));if(i.length>0)throw J(`Maestro ${t} field "${i[0]}" is not supported yet.`)}function W(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}function F(e){return e.map((e,t)=>{if("string"==typeof e||W(e))return e;throw new r("INVALID_ARGS",`Unsupported Maestro command at index ${t+1}: expected a scalar or one-key map.`)})}function K(e){if(e){let t;return"android"===(t=e.trim().toLowerCase())?"android":"ios"===t?"ios":void 0}}function z(e,t){if(null==e)return{};if(!W(e))throw new r("INVALID_ARGS",`${t} expects a map.`);let n={};for(let[t,r]of Object.entries(e))("string"==typeof r||"number"==typeof r||"boolean"==typeof r)&&(n[t]=String(r));return n}function U(e,t){return W(e)&&"number"==typeof e.timeout&&Number.isFinite(e.timeout)?Math.max(0,Math.floor(e.timeout)):t}function q(e,t){if(e.appId)return e.appId;throw new r("INVALID_ARGS",`${t} requires appId in the Maestro flow config.`)}function Y(e,t){if("string"==typeof t)return t;throw new r("INVALID_ARGS",`${e} expects a string value.`)}function Z(e,t){return e.replace(/\$\{([A-Za-z_][A-Za-z0-9_.]*)\}/g,(e,n)=>Object.prototype.hasOwnProperty.call(t.env,n)?String(t.env[n]):e)}function H(e){throw J(`Maestro command "${e}" is not supported yet.`)}function J(e){throw new r("INVALID_ARGS",`${e} See supported/unsupported Maestro compatibility at ${s}. If this syntax matters for your flows, comment there or open a focused issue at ${l}.`)}function T(e,t){return`${e},${t}`}function B(e){let t=e.match(/^(\d+),(\d+)$/);if(!t)throw J('Only absolute Maestro point selectors like "100,200" are supported.');return{x:Number(t[1]),y:Number(t[2])}}function Q(e){let t=e.match(/^\s*(\d+)\s*,\s*(\d+)\s*$/);if(t)return{kind:"absolute",x:Number(t[1]),y:Number(t[2])};let n=e.match(/^\s*(\d+(?:\.\d+)?)%\s*,\s*(\d+(?:\.\d+)?)%\s*$/);if(n)return{kind:"percent",x:Number(n[1]),y:Number(n[2])};throw J('Only Maestro swipe coordinates like "100,200" or "50%,75%" are supported.')}export{P as assertOnlyKeys,y as buildReplayVarScope,b as collectReplayShellEnv,T as formatMaestroPoint,W as isPlainRecord,w as mergeReplayVarScopeValues,F as normalizeCommandList,K as normalizePlatform,B as parseAbsolutePoint,Q as parseMaestroPoint,E as parseMaestroYamlDocuments,I as parseReplayCliEnvEntries,x as parseReplayScriptDetailed,z as readEnvMap,$ as readReplayCliEnvEntries,O as readReplayScriptMetadata,S as readReplayShellEnvSource,U as readTimeoutMs,q as requireAppId,Y as requireStringValue,Z as resolveMaestroString,N as resolveReplayAction,G as stringifyMaestroYamlDocuments,C as support_action,H as unsupportedCommand,J as unsupportedMaestroSyntax,k as writeReplayScript};
@@ -0,0 +1 @@
1
+ import e from"node:fs";import t from"node:path";import{AppError as n}from"./733.js";import{PLATFORM_SELECTORS as r}from"./5910.js";import{resolveUserPath as o}from"./9612.js";let i=new Set(["1","true","yes","on"]),a=new Set(["0","false","no","off"]);function s(e){return`AGENT_DEVICE_${e.replace(/([A-Z])/g,"_$1").replace(/[^A-Za-z0-9_]/g,"_").toUpperCase()}`}function l(e,t,r,o){if(e.multiple)return(Array.isArray(t)?t:[t]).map(t=>l({...e,multiple:!1},t,r,o));if("boolean"===e.type){var i=t,a=r,s=o;if("boolean"==typeof i)return i;if("string"==typeof i){let e=u(i);if(void 0!==e)return e}throw new n("INVALID_ARGS",`Invalid value for "${s}" in ${a}. Expected boolean.`)}if("booleanOrString"===e.type){if("boolean"==typeof t)return t;if("string"==typeof t&&void 0!==u(t))return u(t);if("string"==typeof t&&t.trim().length>0)return t;throw new n("INVALID_ARGS",`Invalid value for "${o}" in ${r}. Expected boolean or non-empty string.`)}if("string"===e.type){if("string"==typeof t&&t.trim().length>0)return t;throw new n("INVALID_ARGS",`Invalid value for "${o}" in ${r}. Expected non-empty string.`)}if("enum"===e.type){if(void 0!==e.setValue){var f=e,y=t,p=r,m=o;let i=f.setValue;if(y===i)return i;if("string"==typeof y){let e=y.trim();if(""===e||"true"===e||"1"===e)return i;if("false"===e||"0"===e)return}if(!0===y)return i;if(!1!==y)throw new n("INVALID_ARGS",`Invalid value for "${m}" in ${p}. Expected boolean-like value for enum flag.`);return}if("string"!=typeof t||!e.enumValues?.includes(t))throw new n("INVALID_ARGS",`Invalid value for "${o}" in ${r}. Expected one of: ${e.enumValues?.join(", ")}.`);return t}let c="number"==typeof t?t:"string"==typeof t?Number(t):NaN;if(!Number.isFinite(c)||!Number.isInteger(c))throw new n("INVALID_ARGS",`Invalid value for "${o}" in ${r}. Expected integer.`);if("number"==typeof e.min&&c<e.min)throw new n("INVALID_ARGS",`Invalid value for "${o}" in ${r}. Must be >= ${e.min}.`);if("number"==typeof e.max&&c>e.max)throw new n("INVALID_ARGS",`Invalid value for "${o}" in ${r}. Must be <= ${e.max}.`);return c}function u(e){let t=e.trim().toLowerCase();return!!i.has(t)||!a.has(t)&&void 0}let f=[{key:"stateDir",type:"string",path:!0},{key:"daemonBaseUrl",type:"string"},{key:"daemonAuthToken",type:"string"},{key:"daemonTransport",type:"enum",enumValues:["auto","socket","http"]},{key:"daemonServerMode",type:"enum",enumValues:["socket","http","dual"]},{key:"tenant",type:"string"},{key:"sessionIsolation",type:"enum",enumValues:["none","tenant"]},{key:"runId",type:"string"},{key:"leaseId",type:"string"},{key:"leaseBackend",type:"enum",enumValues:["ios-simulator","ios-instance","android-instance"]},{key:"platform",type:"enum",enumValues:r},{key:"target",type:"enum",enumValues:["mobile","tv","desktop"]},{key:"device",type:"string"},{key:"udid",type:"string"},{key:"serial",type:"string"},{key:"iosSimulatorDeviceSet",type:"string",path:!0,env:!1},{key:"androidDeviceAllowlist",type:"string"},{key:"session",type:"string"},{key:"metroProjectRoot",type:"string",path:!0},{key:"metroKind",type:"enum",enumValues:["auto","react-native","expo"]},{key:"metroPublicBaseUrl",type:"string"},{key:"metroProxyBaseUrl",type:"string"},{key:"metroBearerToken",type:"string"},{key:"metroPreparePort",type:"int",min:1,max:65535},{key:"metroListenHost",type:"string"},{key:"metroStatusHost",type:"string"},{key:"metroStartupTimeoutMs",type:"int",min:1},{key:"metroProbeTimeoutMs",type:"int",min:1},{key:"metroRuntimeFile",type:"string",path:!0},{key:"metroNoReuseExisting",type:"boolean"},{key:"metroNoInstallDeps",type:"boolean"}],y=new Map(f.map(e=>[e.key,e]));function p(e){let t=e.env??process.env;return o(e.configPath,{cwd:e.cwd,env:t})}function m(r){let i=function(r){let i,a,s=r.env??process.env,u=p(r);if(!e.existsSync(u))throw new n("INVALID_ARGS",`Remote config file not found: ${u}`);try{i=e.readFileSync(u,"utf8")}catch(e){throw new n("INVALID_ARGS",`Failed to read remote config file: ${u}`,{cause:e instanceof Error?e.message:String(e)})}try{a=JSON.parse(i)}catch(e){throw new n("INVALID_ARGS",`Invalid JSON in remote config file: ${u}`,{cause:e instanceof Error?e.message:String(e)})}if(!a||"object"!=typeof a||Array.isArray(a))throw new n("INVALID_ARGS",`Remote config file must contain a JSON object: ${u}`);let f={},m=a,c=t.dirname(u);for(let[e,t]of Object.entries(m)){let r=y.get(e);if(!r)throw new n("INVALID_ARGS",`Unsupported remote config key "${e}" in remote config file ${u}.`);let i=l(r,t,`remote config file ${u}`,e);f[r.key]="string"==typeof i&&"path"in r&&r.path?o(i,{cwd:c,env:s}):i}return{resolvedPath:u,profile:f}}(r);return{resolvedPath:i.resolvedPath,profile:function(...e){let t={};for(let n of e)if(n)for(let e of f){let r=n[e.key];void 0!==r&&(t[e.key]=r)}return t}(function(e=process.env){let t={};for(let n of f){let r=(function(e){let t=y.get(e);return t?.env===!1?[]:[s(e)]})(n.key).map(t=>({name:t,value:e[t]})).find(e=>"string"==typeof e.value&&e.value.trim().length>0);r&&(t[n.key]=l(n,r.value,`environment variable ${r.name}`,r.name))}return t}(r.env),i.profile)}}export{f as REMOTE_CONFIG_FIELD_SPECS,s as buildPrimaryEnvVarName,l as parseSourceValue,p as resolveRemoteConfigPath,m as resolveRemoteConfigProfile};
@@ -1,3 +1,3 @@
1
- import e from"node:fs";import t from"node:path";import{fileURLToPath as r}from"node:url";import{runCmdDetached as n}from"./9818.js";let i="agent-device",o="--agent-device-run-update-check";function a(a){var c,p,u,m,h,f,g;let k,v,y;if(!(!(!(c=a).command||"help"===c.command||"test"===c.command||c.flags.help||c.flags.version||c.flags.json||process.env.CI?.trim()||"test"===process.env.NODE_ENV||process.env.AGENT_DEVICE_NO_UPDATE_NOTIFIER?.trim())&&process.stderr.isTTY))return;let S=Date.now(),V=t.join(a.stateDir,"update-check.json"),w=s(V);p=w,u=a.currentVersion,!p.latestVersion||0>=l(p.latestVersion,u)||!0===p.prompted||(process.stderr.write(`Update available: ${i} ${a.currentVersion} -> ${w.latestVersion}. Run \`npm install -g ${i}@latest\` to upgrade the CLI and bundled skills.
1
+ import e from"node:fs";import t from"node:path";import{fileURLToPath as r}from"node:url";import{runCmdDetached as n}from"./8875.js";let i="agent-device",o="--agent-device-run-update-check";function a(a){var c,p,u,m,h,f,g;let k,v,y;if(!(!(!(c=a).command||"help"===c.command||"test"===c.command||c.flags.help||c.flags.version||c.flags.json||process.env.CI?.trim()||"test"===process.env.NODE_ENV||process.env.AGENT_DEVICE_NO_UPDATE_NOTIFIER?.trim())&&process.stderr.isTTY))return;let S=Date.now(),V=t.join(a.stateDir,"update-check.json"),w=s(V);p=w,u=a.currentVersion,!p.latestVersion||0>=l(p.latestVersion,u)||!0===p.prompted||(process.stderr.write(`Update available: ${i} ${a.currentVersion} -> ${w.latestVersion}. Run \`npm install -g ${i}@latest\` to upgrade the CLI and bundled skills.
2
2
  `),d(V,{...w,prompted:!0})),m=w,h=S,(void 0===(k=function(e){if(!e)return;let t=Date.parse(e);return Number.isNaN(t)?void 0:t}(m.checkedAt))||h-k>=12096e5)&&(f=V,g=a.currentVersion,y=(v=function(){let n=r(import.meta.url),i=t.extname(n)||".js",o=[t.join(t.dirname(n),`update-check-entry${i}`),t.join(t.dirname(n),"internal",`update-check-entry${i}`)].find(t=>e.existsSync(t));if(!o)throw Error("Update check entrypoint not found. Rebuild the package to include the update-check worker entry.");return o}()).endsWith(".ts")?["--experimental-strip-types"]:[],n(process.execPath,[...y,v,o,f,g]))}async function c(e){let t=Date.now(),r=s(e.cachePath);try{let n=await p()??void 0;if(!n||0>=l(n,e.currentVersion))return void d(e.cachePath,{checkedAt:new Date(t).toISOString()});d(e.cachePath,{checkedAt:new Date(t).toISOString(),latestVersion:n,prompted:r.latestVersion===n&&!0===r.prompted})}catch{d(e.cachePath,{...r,checkedAt:new Date(t).toISOString()})}}function s(t){try{let r=JSON.parse(e.readFileSync(t,"utf8"));return{checkedAt:"string"==typeof r.checkedAt?r.checkedAt:void 0,latestVersion:"string"==typeof r.latestVersion?r.latestVersion:void 0,prompted:!0===r.prompted}}catch{return{}}}function d(r,n){try{e.mkdirSync(t.dirname(r),{recursive:!0}),e.writeFileSync(r,`${JSON.stringify(n,null,2)}
3
3
  `,"utf8")}catch{}}async function p(){let e=await fetch(`https://registry.npmjs.org/${i}/latest`,{signal:AbortSignal.timeout(3500),headers:{accept:"application/json"}});if(!e.ok)return;let t=await e.json();return"string"==typeof t.version&&t.version.trim().length>0?t.version.trim():void 0}function l(e,t){return e.localeCompare(t,void 0,{numeric:!0})}function u(e){if(e[0]!==o)return null;let t=e[1]?.trim(),r=e[2]?.trim();return t&&r?{cachePath:t,currentVersion:r}:null}export{a as maybeRunUpgradeNotifier,u as readUpdateCheckWorkerArgs,c as runUpdateCheckWorker};
@@ -0,0 +1 @@
1
+ import t from"node:dns/promises";import e from"node:net";import{createWriteStream as a,promises as r}from"node:fs";import o from"node:os";import i from"node:path";import{Readable as n}from"node:stream";import{pipeline as s}from"node:stream/promises";import{AppError as l}from"./733.js";import{runCmd as c}from"./8875.js";import{expandUserHomePath as h}from"./9612.js";let u=[".zip",".tar",".tar.gz",".tgz"],d=Object.freeze([...u]);async function p(t){let e=[];try{let a=await w(t.source,{signal:t.signal,downloadTimeoutMs:t.downloadTimeoutMs});e.push(a.cleanup);let r=await v(a.localPath,{archivePath:void 0,isInstallablePath:t.isInstallablePath,installableLabel:t.installableLabel,allowArchiveExtraction:!1!==t.allowArchiveExtraction,registerCleanup:t=>{e.push(t)}});return{archivePath:r.archivePath,installablePath:r.installablePath,cleanup:async()=>{await g(e)}}}catch(t){throw await g(e),t}}async function w(t,e){if("path"===t.kind)return{localPath:h(t.path),cleanup:async()=>{}};let a=await r.mkdtemp(i.join(o.tmpdir(),"agent-device-source-"));try{return{localPath:await f(a,t.url,t.headers,e),cleanup:async()=>{await r.rm(a,{recursive:!0,force:!0})}}}catch(t){throw await r.rm(a,{recursive:!0,force:!0}),t}}async function f(t,e,r,o){let c;try{c=new URL(e)}catch{throw new l("INVALID_ARGS",`Invalid source URL: ${e}`)}await m(c);let h=o?.signal;if(h?.aborted)throw new l("COMMAND_FAILED","request canceled",{reason:"request_canceled"});let u=o?.downloadTimeoutMs??12e4,d=AbortSignal.timeout(u),p=h?AbortSignal.any([h,d]):d;try{let e=await fetch(c,{headers:r,redirect:"follow",signal:p});if(!e.ok)throw new l("COMMAND_FAILED",`Failed to download app source: ${e.status} ${e.statusText}`,{status:e.status,statusText:e.statusText,url:c.toString()});let o=function(t,e){let a=t.headers.get("content-disposition"),r=a?.match(/filename\*?=(?:UTF-8'')?"?([^";]+)"?/i),o=r?.[1]?.trim();if(o)return i.basename(o);let n=i.basename(e.pathname);return n||"downloaded-artifact.bin"}(e,c),h=i.join(t,o),u=e.body;if(!u)throw new l("COMMAND_FAILED","Download response body was empty",{url:c.toString()});return await s(n.fromWeb(u),a(h)),h}catch(t){if(h?.aborted)throw new l("COMMAND_FAILED","request canceled",{reason:"request_canceled"},t);if(d.aborted)throw new l("COMMAND_FAILED",`App source download timed out after ${u}ms`,{timeoutMs:u,url:c.toString()},t);throw t}}async function m(e){if("http:"!==e.protocol&&"https:"!==e.protocol)throw new l("INVALID_ARGS",`Unsupported source URL protocol: ${e.protocol}`);if(A(e.hostname.toLowerCase()))throw new l("INVALID_ARGS",`Source URL host is not allowed: ${e.hostname}`,{hint:"Use a public artifact URL."});if((await t.lookup(e.hostname,{all:!0,verbatim:!0}).catch(()=>[])).some(t=>L(t.address)))throw new l("INVALID_ARGS",`Source URL host resolved to a private or loopback address: ${e.hostname}`,{hint:"Use a public artifact URL."})}function b(t){var e,a,r,o;let i=t instanceof URL?t:new URL(t),n=i.hostname.toLowerCase();if(!n)return!1;let s=i.pathname;return e=n,a=s,("api.github.com"===e?/^\/repos\/[^/]+\/[^/]+\/actions\/artifacts\/\d+\/zip$/i.test(a):"github.com"===e&&/^\/[^/]+\/[^/]+\/(?:actions\/runs\/\d+\/artifacts\/\d+|suites\/\d+\/artifacts\/\d+)$/i.test(a))||(r=n,o=s,("expo.dev"===r||!!r.endsWith(".expo.dev"))&&/^\/(?:artifacts\/eas\/|accounts\/[^/]+\/projects\/[^/]+\/builds\/)/i.test(o))}function A(t){return!!(!t||"localhost"===t||t.endsWith(".localhost"))||L(t)}function L(t){let a,r=e.isIP(t);return 4===r?function(t){let e=t.split(".").map(t=>Number.parseInt(t,10));if(4!==e.length||e.some(t=>Number.isNaN(t)||t<0||t>255))return!1;let a=e[0],r=e[1];return void 0!==a&&void 0!==r&&(10===a||127===a||169===a&&254===r||172===a&&!!(r>=16)&&!!(r<=31)||192===a&&168===r)}(t):6===r&&!!("::1"===(a=t.toLowerCase())||a.startsWith("fc")||a.startsWith("fd")||a.startsWith("fe80:"))}async function v(t,e){let a=await r.stat(t).catch(()=>null);if(!a)throw new l("INVALID_ARGS",`App source not found: ${t}`);if(e.isInstallablePath(t,a))return{archivePath:e.archivePath,installablePath:t};if(a.isFile()&&S(t)){if(!e.allowArchiveExtraction)throw new l("INVALID_ARGS",`URL sources must point directly to a ${e.installableLabel}; archive extraction is not allowed`,{path:t});let a=await _(t);return e.registerCleanup(a.cleanup),await v(a.outputPath,{...e,archivePath:e.archivePath??t})}if(a.isDirectory()){let a=await I(t,e.isInstallablePath),r=a[0];if(void 0!==r&&1===a.length)return{archivePath:e.archivePath,installablePath:r};if(a.length>1)throw new l("INVALID_ARGS",`Found multiple ${e.installableLabel} candidates under ${t}`,{matches:a});let o=await I(t,(t,e)=>e.isFile()&&S(t)),i=o[0];if(void 0!==i&&1===o.length){if(!e.allowArchiveExtraction)throw new l("INVALID_ARGS",`URL sources must point directly to a ${e.installableLabel}; nested archives are not allowed`,{path:i});let t=await _(i);return e.registerCleanup(t.cleanup),await v(t.outputPath,{...e,archivePath:e.archivePath??i})}if(o.length>1)throw new l("INVALID_ARGS",`Found multiple nested archives under ${t}; expected one ${e.installableLabel} source`,{matches:o})}throw new l("INVALID_ARGS",`Expected ${e.installableLabel} source, but got ${t}`)}async function I(t,e){let a=[],o=[{path:t,depth:0}];for(;o.length>0;){let t=o.shift();if(!t)continue;let n=await r.readdir(t.path,{withFileTypes:!0});for(let r of(n.sort((t,e)=>t.name.localeCompare(e.name)),n)){let n=i.join(t.path,r.name);if(e(n,r)){a.push(n);continue}r.isDirectory()&&t.depth<5&&o.push({path:n,depth:t.depth+1})}}return a}async function _(t){let e=await r.mkdtemp(i.join(o.tmpdir(),"agent-device-archive-"));try{return t.toLowerCase().endsWith(".zip")?await P(t,e):t.toLowerCase().endsWith(".tar.gz")||t.toLowerCase().endsWith(".tgz")?await c("tar",["-xzf",t,"-C",e]):await c("tar",["-xf",t,"-C",e]),{outputPath:e,cleanup:async()=>{await r.rm(e,{recursive:!0,force:!0})}}}catch(t){throw await r.rm(e,{recursive:!0,force:!0}),t}}async function P(t,e){await c("unzip",["-q",t,"-d",e])}function S(t){let e=t.toLowerCase();return u.some(t=>e.endsWith(t))}async function g(t){for(let e of[...t].reverse())await e()}export{d as ARCHIVE_EXTENSIONS,L as isBlockedIpAddress,A as isBlockedSourceHostname,b as isTrustedInstallSourceUrl,p as materializeInstallablePath,m as validateDownloadSourceUrl};
@@ -0,0 +1 @@
1
+ import{URL as t}from"node:url";import{runCmdSync as r}from"./8875.js";import{sleep as e}from"./5560.js";import{AppError as n}from"./733.js";let o=[/(^|[/\s"'=])dist\/src\/daemon\.js($|[\s"'])/,/(^|[/\s"'=])dist\/src\/internal\/daemon\.js($|[\s"'])/,/(^|[/\s"'=])src\/daemon\.ts($|[\s"'])/];function i(t){if(!Number.isInteger(t)||t<=0)return!1;try{return process.kill(t,0),!0}catch(t){return"EPERM"===t.code}}function u(t){if(!Number.isInteger(t)||t<=0)return!1;try{return process.kill(-t,0),!0}catch(t){return"EPERM"===t.code}}function s(t){if(!Number.isInteger(t)||t<=0)return null;try{let e=r("ps",["-p",String(t),"-o","lstart="],{allowFailure:!0,timeoutMs:1e3});if(0!==e.exitCode)return null;let n=e.stdout.trim();return n.length>0?n:null}catch{return null}}function l(t){if(!Number.isInteger(t)||t<=0)return null;try{let e=r("ps",["-p",String(t),"-o","command="],{allowFailure:!0,timeoutMs:1e3});if(0!==e.exitCode)return null;let n=e.stdout.trim();return n.length>0?n:null}catch{return null}}function c(t,r){let e;if(!i(t))return!1;if(r){let e=s(t);if(!e||e!==r)return!1}let n=l(t);return!!n&&!!(e=n.toLowerCase().replaceAll("\\","/")).includes("agent-device")&&o.some(t=>t.test(e))}function a(t,r){try{return process.kill(t,r),!0}catch(r){let t=r.code;if("ESRCH"===t||"EPERM"===t)return!1;throw r}}async function m(t,r){if(!i(t))return!0;let n=Date.now();for(;Date.now()-n<r;)if(await e(50),!i(t))return!0;return!i(t)}async function f(t,r){!c(t,r.expectedStartTime)||!a(t,"SIGTERM")||await m(t,r.termTimeoutMs)||a(t,"SIGKILL")&&await m(t,r.killTimeoutMs)}function p(r){if(!r)return;let e=d(r.metroHost),o=h(r.metroPort),i="http",u=d(r.bundleUrl);if(u){var s;let r;try{r=new t(u)}catch(t){throw new n("INVALID_ARGS",`Invalid runtime bundle URL: ${u}`,{},t)}("http:"===r.protocol||"https:"===r.protocol)&&(e??=d(r.hostname),o??=h(r.port.length>0?Number(r.port):"https:"===(s=r.protocol)?443:"http:"===s?80:void 0),i="https:"===r.protocol?"https":"http")}if(e&&o)return{host:e,port:o,scheme:i}}function d(t){let r=t?.trim();return r&&r.length>0?r:void 0}function h(t){if(Number.isInteger(t)&&!(t<=0)&&!(t>65535))return t}export{c as isAgentDeviceDaemonProcess,i as isProcessAlive,u as isProcessGroupAlive,l as readProcessCommand,s as readProcessStartTime,p as resolveRuntimeTransportHints,f as stopProcessForTakeover,d as trimRuntimeValue,m as waitForProcessExit};
@@ -0,0 +1 @@
1
+ import{AppError as e}from"./733.js";let t=["any","text","label","value","role","id"],r=["text","label","value","role","id"];function i(e,t,r,u={}){let a=l(r);if(!a)return{matches:[],score:0};let c=0,s=[];for(let r of e){if(u.requireRect&&!r.rect)continue;let e=function(e,t,r){switch(t){case"role":return function(e,t){let r=o(e??"");return r?r===t?2:+!!r.includes(t):0}(e.type,r);case"label":return n(e.label,r);case"value":return n(e.value,r);case"id":return n(e.identifier,r);default:return Math.max(n(e.label,r),n(e.value,r),n(e.identifier,r))}}(r,t,a);if(!(e<=0)){if(e>c){c=e,s.length=0,s.push(r);continue}e===c&&s.push(r)}}return{matches:s,score:c}}function n(e,t){let r=l(e??"");return r?r===t?2:+!!r.includes(t):0}function l(e){return e.trim().toLowerCase().replace(/\s+/g," ")}function o(e){let t=e.trim();return t?t=(t.split(".").pop()??t).replace(/XCUIElementType/gi,"").toLowerCase():""}function u(t){let i="any",n=0;r.includes(t[0])&&(i=t[0],n=1);let l=t[n]??"",o=t.slice(n+1);if(0===o.length)return{locator:i,query:l,action:"click"};let u=o[0]?.toLowerCase();if("get"===u){let t=o[1]?.toLowerCase();if("text"===t)return{locator:i,query:l,action:"get_text"};if("attrs"===t)return{locator:i,query:l,action:"get_attrs"};throw new e("INVALID_ARGS","find get only supports text or attrs")}if("wait"===u)return{locator:i,query:l,action:"wait",timeoutMs:function(e){if(!e)return null;let t=Number(e);return Number.isFinite(t)?t:null}(o[1])??void 0};if("exists"===u)return{locator:i,query:l,action:"exists"};if("click"===u)return{locator:i,query:l,action:"click"};if("focus"===u)return{locator:i,query:l,action:"focus"};if("fill"===u)return{locator:i,query:l,action:"fill",value:o.slice(1).join(" ")};if("type"===u)return{locator:i,query:l,action:"type",value:o.slice(1).join(" ")};throw new e("INVALID_ARGS",`Unsupported find action: ${o[0]}`)}export{t as FIND_LOCATORS,i as findBestMatchesByLocator,o as normalizeRole,l as normalizeText,u as parseFindArgs};
@@ -0,0 +1,2 @@
1
+ import{AppError as e}from"./733.js";let t=["ios","macos","android","linux","web","apple"],i=["mobile","tv","desktop"];function r(e){return e}function o(e){return"apple"===e||"ios"===e||"macos"===e}function l(e,t){return!t||("apple"===t?o(e):e===t)}function a(e){return"macos"===e||"desktop"===e?"macOS":"tv"===e?"tvOS":"iOS"}function n(e){let{simulatorSetPath:t,platform:i,target:r}=e;if(t&&"macos"!==i&&"desktop"!==r)return t}async function m(t,i,r={}){let a=t,n=e=>e.toLowerCase().replace(/_/g," ").replace(/\s+/g," ").trim();if(i.platform&&(a=a.filter(e=>l(e.platform,i.platform))),i.target&&(a=a.filter(e=>(e.target??"mobile")===i.target)),i.udid){let t=a.find(e=>e.id===i.udid&&o(e.platform));if(!t)throw new e("DEVICE_NOT_FOUND",`No Apple device with UDID ${i.udid}`);return t}if(i.serial){let t=a.find(e=>e.id===i.serial&&"android"===e.platform);if(!t)throw new e("DEVICE_NOT_FOUND",`No Android device with serial ${i.serial}`);return t}if(i.deviceName){let t=n(i.deviceName),r=a.find(e=>n(e.name)===t);if(!r)throw new e("DEVICE_NOT_FOUND",`No device named ${i.deviceName}`);return r}let d=a[0];if(void 0!==d&&1===a.length)return d;if(0===a.length){var f;let t=r.simulatorSetPath;if(t&&(!(f=i.platform)||"apple"===f||"ios"===f))throw new e("DEVICE_NOT_FOUND","No devices found in the scoped simulator set",{simulatorSetPath:t,hint:`The simulator set at "${t}" appears to be empty. Create a simulator first:
2
+ xcrun simctl --set "${t}" create "iPhone 16" com.apple.CoreSimulator.SimDeviceType.iPhone-16 com.apple.CoreSimulator.SimRuntime.iOS-18-0`,selector:i});throw new e("DEVICE_NOT_FOUND","No devices found",{selector:i})}let p=a.filter(e=>"device"!==e.kind);p.length>0&&(a=p);let c=a.filter(e=>e.booted),s=c[0];if(void 0!==s&&1===c.length)return s;let u=c[0]??a[0];if(void 0===u)throw new e("DEVICE_NOT_FOUND","No devices found",{selector:i});return u}export{i as DEVICE_TARGETS,t as PLATFORM_SELECTORS,o as isApplePlatform,l as matchesPlatformSelector,r as normalizePlatformSelector,a as resolveApplePlatformName,n as resolveAppleSimulatorSetPathForSelector,m as resolveDevice};
@@ -0,0 +1,27 @@
1
+ import e from"node:path";import{styleText as t}from"node:util";import{buildMobileSnapshotPresentation as n,displayNodeLabel as r}from"./9873.js";import{normalizeError as i,AppError as o}from"./733.js";import{isSnapshotBackend as l,usesMobileSnapshotPresentation as s}from"./4291.js";import{buildSnapshotDisplayLines as a,formatSnapshotLine as u}from"./7244.js";function d(e){return e.width>0&&e.height>0}function f(e,t){return!!e&&!!t&&e.x>=t.x-2&&e.y>=t.y-2&&e.x+e.width<=t.x+t.width+2&&e.y+e.height<=t.y+t.height+2}function c(e){return"number"!=typeof e.parentIndex}function h(e){let t=(e.type??"").toLowerCase(),n=(e.identifier??"").trim().toLowerCase();return t.includes("edittext")||t.includes("textfield")||"composer"===n}function p(e){let t=(e.type??"").toLowerCase();return t.includes("scroll")||t.includes("list")||t.includes("recyclerview")}function g(e){var t;let n=r(e);if(!n||n!==e.identifier?.trim()||(t=n,!/^[\w.]+:id\/[\w.-]+$/i.test(t)))return n;let i=(e.type??"").toLowerCase();return i.includes("view")||i.includes("layout")||i.includes("image")||i.includes("list")||i.includes("recyclerview")||i.includes("collection")?"":n}function $(e){let t=e.trim().replace(/\s+/g," ").toLowerCase();return!t||/^(true|false|\d+)$/.test(t)?null:t}function x(e,t){let n=[],r=[t];for(;r.length>0;){let t=r.pop();for(let i of e)i.parentIndex===t&&(n.push(i),r.push(i.index))}return n}function m(e,t,n){let r=[t];for(;r.length>0;){let t=r.pop();if(!n.has(t))for(let i of(n.add(t),e))i.parentIndex!==t||n.has(i.index)||r.push(i.index)}}let y=["button","switch","checkbox","radio"],v=["button","image","textview","view"];function b(e){if(!0===e.hittable||h(e))return!1;let t=(e.type??"").toLowerCase();return t.includes("text")||t.includes("image")||t.includes("icon")}function C(e){if(!e.rect||!d(e.rect)||c(e)||h(e))return!1;let t=(e.type??"").toLowerCase();return"text"===t||M(t,v)}function w(e,t){let n=S(e);return S(t)>n?t:e}function S(e){let t=(e.type??"").toLowerCase(),n=0;return M(t,y)?n+=100:t.includes("image")?n+=30:t.includes("textview")||"text"===t?n+=20:t.includes("view")&&(n+=10),!0===e.hittable&&(n+=20),!1!==e.enabled&&(n+=5),n}function M(e,t){return t.some(t=>e.includes(t))}function N(e){process.stdout.write(`${JSON.stringify(e,null,2)}
2
+ `)}function I(e,t={}){let n=e instanceof o?i(e):e;process.stderr.write(`Error (${n.code}): ${n.message}
3
+ `),n.hint&&process.stderr.write(`Hint: ${n.hint}
4
+ `),n.diagnosticId&&process.stderr.write(`Diagnostic ID: ${n.diagnosticId}
5
+ `),n.logPath&&process.stderr.write(`Diagnostics Log: ${n.logPath}
6
+ `),t.showDetails&&n.details&&process.stderr.write(`${JSON.stringify(n.details,null,2)}
7
+ `)}function A(e,t={}){var i,o,y,v;let S,M,N,I,O,_=e.nodes,k=Array.isArray(_)?_:[],L=s(l(e.backend)?e.backend:void 0),j=function(e,t,n){let r;if(n.raw||!((r=e.androidSnapshot)&&"object"==typeof r&&"android-helper"===r.backend))return{nodes:t,filteredCount:0};let i=function(e){var t,n;if(0===e.length)return e;let r=new Set,i=new Map,o=new Map(e.map(e=>[e.index,e]));(function(e,t){for(let n of e)!n.rect||d(n.rect)||c(n)||m(e,n.index,t)})(e,r),function(e,t,n,r){for(let i of e){if(n.has(i.index)||i.rect||c(i))continue;let o=function(e,t,n){let r=e;for(;"number"==typeof r.parentIndex;){let e=t.get(r.parentIndex);if(!e)break;if(n(e))return e;r=e}return null}(i,t,p);o&&function(e,t,n){if(!n)return;let r=e.get(t.index)??t;e.set(t.index,{...r,hiddenContentAbove:!0===r.hiddenContentAbove||"above"===n||void 0,hiddenContentBelow:!0===r.hiddenContentBelow||"below"===n||void 0})}(r,o,function(e,t){let n=t.filter(t=>t.parentIndex===e.parentIndex&&t.rect&&d(t.rect)).map(e=>e.index);return 0===n.length?null:e.index<Math.min(...n)?"above":e.index>Math.max(...n)?"below":null}(i,e)),m(e,i.index,n)}}(e,o,r,i);for(let n of e){if(r.has(n.index)||!(!0===(t=n).hittable&&!h(t)&&t.rect&&d(t.rect)&&0===g(t).trim().length))continue;let o=function(e,t,n){let r=[],i=[],o=new Set;for(let l of e){if(n.has(l.index)||!b(l)||!f(l.rect,t.rect))continue;let e=g(l).trim().replace(/\s+/g," "),s=$(e);i.push(l.index),!e||!s||o.has(s)||(o.add(s),r.push(e))}return{label:r.join(", "),removableIndexes:i}}(x(e,n.index),n,r);if(o.label)for(let t of(i.set(n.index,{...n,...i.get(n.index),label:o.label}),o.removableIndexes))m(e,t,r)}for(let t of e){if(r.has(t.index)||!(!0===(n=t).hittable&&!h(n)&&n.rect&&d(n.rect)&&$(g(n))))continue;let i=$(g(t));if(!i)continue;let o=x(e,t.index).filter(e=>!r.has(e.index)&&function(e,t,n){if(!C(t)||!f(t.rect,e.rect))return!1;let r=$(g(t));return!!(r&&n!==r&&n.includes(r))}(t,e,i));for(let t of o.filter(b))m(e,t.index,r);let l=o.filter(e=>!b(e)),s=new Set(l.map(e=>$(g(e))).filter(e=>!!e));if(!(l.length<2)&&!(s.size<2))for(let t of l)m(e,t.index,r)}let l=new Map;for(let t of e){if(r.has(t.index)||!C(t))continue;let n=$(g(t));if(!n)continue;let o=l.get(n);if(o&&function(e,t,n){var r,i,o,l;return!n.has(e.index)&&(r=e.rect,i=t.rect,!r||!i||Math.abs(r.y+r.height/2-(i.y+i.height/2))<=Math.max(r.height,i.height,1))&&(o=e,l=t,(o.parentIndex===l.parentIndex?3>=Math.abs(o.index-l.index):o.parentIndex!==l.index&&l.parentIndex!==o.index&&1>=Math.abs((o.depth??0)-(l.depth??0))&&2>=Math.abs(o.index-l.index))||function(e,t){let n=e.parentIndex===t.index?t:t.parentIndex===e.index?e:null,r=n?.index===e.index?t:n?.index===t.index?e:null;return!!n&&!!r&&w(n,r).index===n.index}(e,t))}(o,t,r)){let s=function(e,t,n,r,i){var o,l,s;let a=w(t,n),u=a.index===t.index?n:t,d=(u.type??"").toLowerCase().includes("image")?"has image":null,f=i.get(a.index)??a,c=i.get(u.index)?.presentationHints??u.presentationHints;return i.set(a.index,{...f,presentationHints:(o=f.presentationHints,l=c,s=d,[...new Set([...Array.isArray(o)?o:[],...Array.isArray(l)?l:[],...s?[s]:[]])])}),m(e,u.index,r),i.get(a.index)??a}(e,o,t,r,i);l.set(n,s);continue}l.set(n,t)}return e.filter(e=>!r.has(e.index)).map(e=>i.get(e.index)??e)}(t);return{nodes:i,filteredCount:t.length-i.length}}(e,k,t),H=(S="string"==typeof(i=e).appName?i.appName:void 0,M="string"==typeof i.appBundleId?i.appBundleId:void 0,N=[],S&&N.push(`Page: ${S}`),M&&N.push(`App: ${M}`),N.length>0?`${N.join("\n")}
8
+ `:""),T=function(e,t,n,i={nodes:t,filteredCount:0}){var o;let l=K(e);if(!(o=e).snapshotQuality&&!function(e){let t=e.snapshotDiagnostics;if(!t||"object"!=typeof t)return!1;let n=t.stats;return!!(n&&"object"==typeof n&&"web"===n.platform)}(o)){let e=function(e,t){if(!0===t.scoped||!0===t.depthLimited||e.length>3)return null;let n=1===e.length?"node":"nodes";return`Hint: sparse accessibility snapshot returned ${e.length} ${n}; snapshot state is invalid or unavailable for this screen. Use plain screenshot, not screenshot --overlay-refs, as visual truth. If screenshot shows the Home Screen or another app, run open for this app again first. Then navigate away with coordinates if needed and retry snapshot -i on the next screen.`}(t,n);e&&l.push(e)}!n.raw&&i.filteredCount>0&&l.push(`Collapsed ${i.filteredCount} Android helper node${1===i.filteredCount?"":"s"} from the agent-facing text snapshot; use --raw or --json for the full hierarchy.`);let s=i.filteredCount>0?i.nodes:t;return!n.raw&&function(e){if(e.length<20)return!1;let t=new Map;for(let n of e){let e=(n.type??"").toLowerCase(),i=function(e){var t;let n=e.trim().replace(/\s+/g," ").toLowerCase();return!n||(t=n,/\S+@\S+\.\S+/.test(t))?null:n}(r(n));if(!i)continue;let o=`${e}|${i}`,l=t.get(o)??[];l.push(n),t.set(o,l)}let n=0;for(let e of t.values())!(e.length<=1)&&function(e){for(let r=0;r<e.length;r+=1)for(let i=r+1;i<e.length;i+=1){var t,n;if(t=e[r]?.rect,n=e[i]?.rect,!t||!n||!(t.x+t.width<=n.x+.5||n.x+n.width<=t.x+.5||t.y+t.height<=n.y+.5||n.y+n.height<=t.y+.5))return!0}return!1}(e)&&(n+=e.length);return n>=8}(s)&&l.push("Warning: possible repeated nav subtree detected."),l}(e,k,t,j),B=T.length>0?`${T.join("\n")}
9
+ `:"",D=t.raw?null:(I=e.unchanged)&&"object"==typeof I?"number"!=typeof I.ageMs||"number"!=typeof I.nodeCount?null:{ageMs:I.ageMs,nodeCount:I.nodeCount,interactiveOnly:!0===I.interactiveOnly||void 0,scope:"string"==typeof I.scope?I.scope:void 0}:null;if(D){let e;return`${H}${B}${e=function(e){if(e<1e3)return`${Math.round(e)}ms`;if(e<6e4)return`${(Math.round(e/100)/10).toFixed(1)}s`;let t=e/6e4;return t<60?`${(Math.round(10*t)/10).toFixed(1)}m`:`${(Math.round(t/60*10)/10).toFixed(1)}h`}((o=D).ageMs),o.scope?`Scoped snapshot unchanged for scope "${o.scope}" since previous read ${e} ago.
10
+ Previous refs in this scope remain valid. Use find/get/is for a targeted query, or --force-full to re-emit.`:o.interactiveOnly?`Interactive snapshot unchanged since previous read ${e} ago.
11
+ ${o.nodeCount} visible nodes are unchanged. Previous @e refs are still valid. Use find/get/is for a targeted query, or --force-full to re-emit.`:`Snapshot unchanged since previous read ${e} ago.
12
+ Refs from the previous snapshot are still valid. Use --force-full to re-emit the tree, or use find/get/is for a targeted query.`}
13
+ `}let R=t.raw||!L?null:n(j.nodes),z=!!e.truncated,U=R?.nodes??k,E=t.raw||!L?null:function(e,t,n,r,i=0){let o,l=(o=e.visibility)&&"object"==typeof o&&"boolean"==typeof o.partial&&"number"==typeof o.visibleNodeCount&&"number"==typeof o.totalNodeCount&&Array.isArray(o.reasons)?{partial:o.partial,visibleNodeCount:o.visibleNodeCount,totalNodeCount:o.totalNodeCount,reasons:o.reasons.filter(e=>"string"==typeof e)}:null;if(0===i&&l)return l;let s=(t?.hiddenCount??0)+i,a=!!t&&t.nodes.some(e=>e.hiddenContentAbove||e.hiddenContentBelow);return s>0?{partial:!0,visibleNodeCount:n,totalNodeCount:Math.max(r,l?.totalNodeCount??r),reasons:[...new Set([...l?.reasons??[],"offscreen-nodes"])]}:l||(a?{partial:!0,visibleNodeCount:n,totalNodeCount:n,reasons:[]}:null)}(e,R,U.length,k.length,j.filteredCount),F=(y=k.length,v=E,O=z?" (truncated)":"",v?.partial?v.totalNodeCount>v.visibleNodeCount?`Snapshot: ${v.visibleNodeCount} visible nodes (${v.totalNodeCount} total)${O}`:`Snapshot: ${v.visibleNodeCount} visible nodes${O}`:`Snapshot: ${y} nodes${O}`);return 0===k.length?`${H}${F}
14
+ ${B}`:t.raw?`${H}${F}
15
+ ${B}${k.map(e=>JSON.stringify(e)).join("\n")}
16
+ `:t.flatten?`${H}${F}
17
+ ${B}${a(U,{summarizeTextSurfaces:!0}).flatMap(e=>[u(e.node,0,!1,e.type,{summarizeTextSurfaces:!0}),...J({...e,depth:0})]).join("\n")}${P(R)}
18
+ `:`${H}${F}
19
+ ${B}${(function(e){let t=[],n=[],r=new Map(e.map(e=>[e.node.index,e.node])),i=e=>{for(var i,o,l;n.length>0&&(!e||(i=e,o=n[n.length-1],l=r,!function(e,t,n){let r=e;for(;"number"==typeof r.parentIndex;){if(r.parentIndex===t.index)return!0;let e=n.get(r.parentIndex);if(!e)break;r=e}return!1}(i.node,o.node,l)&&i.depth<=o.depth));)t.push(...J(n.pop(),"below"))};for(let r of e)i(r),t.push(r.text),t.push(...J(r,"above")),r.node.hiddenContentBelow&&n.push(r);return i(),t})(a(U,{summarizeTextSurfaces:!0})).join("\n")}${P(R)}
20
+ `}function P(e){return e&&e.summaryLines.length>0?`
21
+ ${e.summaryLines.join("\n")}`:""}function O(e){let t=!0===e.baselineInitialized,n=e.summary??{},r=B(n.additions),i=B(n.removals),o=B(n.unchanged),l=D(),s=K(e),a=s.length>0?`${s.join("\n")}
22
+ `:"";if(t)return`${a}Baseline initialized (${o} lines).
23
+ `;let u=(function(e){if(0===e.length)return e;let t=e.map((e,t)=>({index:t,kind:e.kind})).filter(e=>"added"===e.kind||"removed"===e.kind).map(e=>e.index);if(0===t.length)return e;let n=Array(e.length).fill(!1);for(let r of t){let t=Math.max(0,r-1),i=Math.min(e.length-1,r+1);for(let e=t;e<=i;e+=1)n[e]=!0}return e.filter((e,t)=>n[t])})(Array.isArray(e.lines)?e.lines:[]).map(e=>{let t="string"==typeof e.text?e.text:"";if("added"===e.kind){let e=t.startsWith(" ")?`+${t}`:`+ ${t}`;return l?R(e,"green"):e}if("removed"===e.kind){let e=t.startsWith(" ")?`-${t}`:`- ${t}`;return l?R(e,"red"):e}return l?R(t,"dim"):t}),d=u.length>0?`${u.join("\n")}
24
+ `:"";if(!l)return`${a}${d}${r} additions, ${i} removals, ${o} unchanged
25
+ `;let f=`${R(String(r),"green")} additions, ${R(String(i),"red")} removals, ${R(String(o),"dim")} unchanged`;return`${a}${d}${f}
26
+ `}function _(e){var t,n,r,i;let o,l,s,a,u=D(),d=!0===e.match,f=e.dimensionMismatch,c=[];return c.push(...function(e,t){if(!0===e.match){let e=t?R("✓","green"):"✓";return[`${e} Screenshots match.`]}let n=e.dimensionMismatch,r=t?R("✗","red"):"✗";if(n){let e=n.expected,t=n.actual;return[`${r} Screenshots have different dimensions: expected ${e?.width}x${e?.height}, got ${t?.width}x${t?.height}`]}let i=B(e.differentPixels),o=B(e.mismatchPercentage),l=0===o&&i>0?"<0.01":String(o),s=`${l}% pixels differ`;return[`${r} ${t?R(s,"red"):s}`]}(e,u)),c.push(...function(e,t,n){if(t)return[];let r=[];if(e.diffPath){let t=T(e.diffPath),i=n?R("Diff image:","dim"):"Diff image:",o=n?R(t,"green"):t;r.push(` ${i} ${o}`)}if(e.currentOverlayPath){let t=T(e.currentOverlayPath),i=n?R("Current overlay:","dim"):"Current overlay:",o=n?R(t,"green"):t,l=B(e.currentOverlayRefCount),s=l>0?` (${l} refs)`:"";r.push(` ${i} ${o}${s}`)}return r}(e,d,u)),d||f||(c.push(...(t=e,n=u,o=B(t.differentPixels),l=B(t.totalPixels),s=n?R(String(o),"red"):String(o),[` ${s} different / ${l} total pixels`])),c.push(...(r=e,i=u,0===(a=function(e){let t=[];for(let n of(e.ocr?.movementClusters??[]).slice(0,2))t.push(`text movement cluster: ${function(e){let t=e.slice(0,4).map(e=>JSON.stringify(e)),n=e.length>t.length?` +${e.length-t.length} more`:"";return`${t.join(", ")}${n}`}(n.texts)} dx=${H(n.xRange)}px dy=${H(n.yRange)}px`);let n=(e.nonTextDeltas??[]).filter(e=>["icon","toggle","chevron"].includes(e.likelyKind)).slice(0,3);n.length>0&&t.push(`non-text controls: ${n.map(j).join("; ")}`);let r=(e.nonTextDeltas??[]).filter(e=>"separator"===e.likelyKind).slice(0,2);return r.length>0&&t.push(`non-text boundaries: ${r.map(j).join("; ")}`),t.slice(0,6)}(r)).length?[]:[` ${z("Hints:",i)}`,...a.map(e=>` - ${e}`)])),c.push(...function(e,t){let n=Array.isArray(e.regions)?e.regions:[];if(0===n.length)return[];let r=[` ${z("Changed regions:",t)}`];for(let e of n.slice(0,5))r.push(...function(e){let t=0===e.shareOfDiffPercentage&&e.differentPixels>0?"<0.01":String(e.shareOfDiffPercentage),n=e.rect,r=[` ${e.index}. ${e.location} x=${n.x} y=${n.y} ${n.width}x${n.height}, ${t}% of diff, change=${e.dominantChange}`],i=function(e){let t=[e.size?`size=${e.size}`:null,e.shape?`shape=${e.shape}`:null,"number"==typeof e.densityPercentage?`density=${e.densityPercentage}%`:null,e.averageBaselineColorHex&&e.averageCurrentColorHex?`avgColor=${e.averageBaselineColorHex}->${e.averageCurrentColorHex}`:null,"number"==typeof e.baselineLuminance&&"number"==typeof e.currentLuminance?`luminance=${e.baselineLuminance}->${e.currentLuminance}`:null].filter(e=>null!==e);return t.length>0?t.join(" "):null}(e);i&&r.push(` ${i}`);let o=e.currentOverlayMatches?.[0];if(o){let e=o.label?` "${o.label}"`:"";r.push(` overlaps @${o.ref}${e}, ${o.regionCoveragePercentage}% of region`)}return r}(e));return r}(e,u)),c.push(...function(e,t){let n=e.ocr?.matches??[];if(0===n.length)return[];let r=n.slice(0,8),i=[` ${z(`OCR text deltas (${e.ocr?.provider}; baselineBlocks=${e.ocr?.baselineBlocks} currentBlocks=${e.ocr?.currentBlocks}; showing ${r.length}/${n.length}; px):`,t)}`,` ${z("item | text | movePx | sizeDeltaPx | bboxBaseline | bboxCurrent | confidence | issueHint",t)}`];for(let[e,t]of r.entries()){let n=t.delta;i.push(` ${e+1} | ${JSON.stringify(t.text)} | ${L(n.x)},${L(n.y)} | ${L(n.width)},${L(n.height)} | ${k(t.baselineRect)} | ${k(t.currentRect)} | ${t.confidence} | ${t.possibleTextMetricMismatch?"ocr-bbox-size-change":"-"}`)}return i}(e,u)),c.push(...function(e,t){let n=e.nonTextDeltas??[];if(0===n.length)return[];let r=n.slice(0,8),i=[` ${z(`Non-text visual deltas (showing ${r.length}/${n.length}; px):`,t)}`,` ${z("item | region | slot | kind | bboxCurrent | nearestText",t)}`];for(let e of r)i.push(` ${e.index} | ${e.regionIndex?`r${e.regionIndex}`:"-"} | ${e.slot} | ${e.likelyKind} | ${k(e.rect)} | ${e.nearestText?JSON.stringify(e.nearestText):"-"}`);return i}(e,u))),`${c.join("\n")}
27
+ `}function k(e){return`x=${e.x},y=${e.y},w=${e.width},h=${e.height}`}function L(e){return e>0?`+${e}`:String(e)}function j(e){let t=e.nearestText?` near ${JSON.stringify(e.nearestText)}`:"",n=e.regionIndex?` r${e.regionIndex}`:"";return`${e.likelyKind}${t}${n}`}function H(e){return e.min===e.max?L(e.min):`${L(e.min)}..${L(e.max)}`}function T(t){let n=process.cwd(),r=e.relative(n,t);return""!==r&&(r.startsWith("..")||e.isAbsolute(r))?t:""===r?".":`.${e.sep}${r}`}function B(e){return"number"==typeof e&&Number.isFinite(e)?e:0}function D(e=process.stdout){let t=process.env.FORCE_COLOR;return"string"==typeof t?"0"!==t:"string"!=typeof process.env.NO_COLOR&&!!e.isTTY}function R(e,n,r){return t(n,e,r)}function z(e,t){return t?R(e,"dim"):e}function K(e){let t=e.warnings;return Array.isArray(t)?t.filter(e=>"string"==typeof e&&e.length>0):[]}function J(e,t){var n;let r="scroll-area"===(n=e.type)||"list"===n||"collection"===n||"table"===n?n:null;if(!r)return[];let i=[];if(e.node.hiddenContentAbove&&"below"!==t&&i.push(`[content above ${r} hidden]`),e.node.hiddenContentBelow&&"above"!==t&&i.push(`[content below ${r} hidden]`),0===i.length)return[];let o=" ".repeat(e.depth+1);return i.map(e=>`${o}${e}`)}export{R as colorize,_ as formatScreenshotDiffText,O as formatSnapshotDiffText,A as formatSnapshotText,I as printHumanError,N as printJson,D as supportsColor};
@@ -0,0 +1 @@
1
+ import{asAppError as t,AppError as e}from"./733.js";import{normalizeBatchCommandName as r,INHERITED_PARENT_FLAG_KEYS as o,assertBatchRuntimeCommandAllowed as a,BATCH_DAEMON_STEP_KEYS as n}from"./2133.js";let s=new Set(n);async function i(e,r,o){let a=e.flags,n=a?.batchOnError??"stop";if("stop"!==n)return p("INVALID_ARGS",`Unsupported batch on-error mode: ${n}.`);let s=a?.batchMaxSteps??100;if(!Number.isInteger(s)||s<1||s>1e3)return p("INVALID_ARGS",`Invalid batch max-steps: ${String(a?.batchMaxSteps)}`);try{let t=l(a?.batchSteps,s),n=Date.now(),i=[];for(let[a,n]of t.entries()){let s=await h(e,r,n,o,a+1);if(!s.ok)return{ok:!1,error:{code:s.error.code,message:`Batch failed at step ${s.step} (${n.command}): ${s.error.message}`,hint:s.error.hint,diagnosticId:s.error.diagnosticId,logPath:s.error.logPath,details:{...s.error.details??{},step:s.step,command:n.command,positionals:n.positionals,executed:a,total:t.length,partialResults:i}}};i.push(s.result)}return{ok:!0,data:{total:t.length,executed:t.length,totalDurationMs:Date.now()-n,results:i}}}catch(r){let e=t(r);return p(e.code,e.message,e.details)}}function l(t,o){if(!Array.isArray(t)||0===t.length)throw new e("INVALID_ARGS","batch requires a non-empty batchSteps array.");if(t.length>o)throw new e("INVALID_ARGS",`batch has ${t.length} steps; max allowed is ${o}.`);let n=[];for(let o=0;o<t.length;o+=1){let i=t[o];if(!i||"object"!=typeof i)throw new e("INVALID_ARGS",`Invalid batch step at index ${o}.`);let l=Object.keys(i).filter(t=>!s.has(t));if(l.length>0){let t=l.map(t=>`"${t}"`).join(", ");throw new e("INVALID_ARGS",`Batch step ${o+1} has unknown field(s): ${t}. Allowed fields: command, positionals, flags, runtime.`)}let c=r(i.command);if(!c)throw new e("INVALID_ARGS",`Batch step ${o+1} requires command.`);if(a(c,o+1),void 0!==i.positionals&&!Array.isArray(i.positionals))throw new e("INVALID_ARGS",`Batch step ${o+1} positionals must be an array.`);let m=i.positionals??[];if(m.some(t=>"string"!=typeof t))throw new e("INVALID_ARGS",`Batch step ${o+1} positionals must contain only strings.`);if(void 0!==i.flags&&("object"!=typeof i.flags||Array.isArray(i.flags)||!i.flags))throw new e("INVALID_ARGS",`Batch step ${o+1} flags must be an object.`);if(void 0!==i.runtime&&("object"!=typeof i.runtime||Array.isArray(i.runtime)||!i.runtime))throw new e("INVALID_ARGS",`Batch step ${o+1} runtime must be an object.`);n.push({command:c,positionals:m,flags:i.flags??{},runtime:i.runtime})}return n}function c(t,e){let{batchSteps:r,batchOnError:o,batchMaxSteps:a,...n}=e??{};return m(t,n)}function m(t,e){let r=t??{};for(let t of o)void 0===e[t]&&void 0!==r[t]&&(e[t]=r[t]);return e}async function h(t,e,r,o,a){let n=Date.now(),s=c(t.flags,r.flags);void 0===s.session&&(s.session=e);let i=await o({token:t.token,session:e,command:r.command,positionals:r.positionals,flags:s,runtime:void 0===r.runtime?t.runtime:r.runtime,meta:t.meta}),l=Date.now()-n;return i.ok?{ok:!0,step:a,result:{step:a,command:r.command,ok:!0,data:i.data??{},durationMs:l}}:{ok:!1,step:a,error:i.error}}function p(t,e,r){return{ok:!1,error:{code:t,message:e,...r?{details:r}:{}}}}export{c as buildBatchStepFlags,m as mergeParentFlags,i as runBatch,l as validateAndNormalizeBatchSteps};
@@ -0,0 +1 @@
1
+ import e from"node:fs";import t from"node:path";import{fileURLToPath as r}from"node:url";import{buildTextPreview as i,trimText as l,describeTextSurface as o}from"./9836.js";import{isSystemScrollIndicatorLabel as n}from"./9873.js";function a(){try{let r=c();return JSON.parse(e.readFileSync(t.join(r,"package.json"),"utf8")).version??"0.0.0"}catch{return"0.0.0"}}function c(){let i=t.dirname(r(import.meta.url)),l=i;for(let r=0;r<6;r+=1){let r=t.join(l,"package.json");if(e.existsSync(r))return l;l=t.dirname(l)}return i}let u={application:"application",navigationbar:"navigation-bar",tabbar:"tab-bar",button:"button",imagebutton:"button",link:"link",cell:"cell",statictext:"text",checkedtextview:"text",textbox:"text-field",textfield:"text-field",edittext:"text-field",textarea:"text-view",switch:"switch",slider:"slider",image:"image",imageview:"image",webview:"webview",framelayout:"group",linearlayout:"group",relativelayout:"group",constraintlayout:"group",viewgroup:"group",view:"group",listview:"list",recyclerview:"list",collectionview:"collection",searchfield:"search",segmentedcontrol:"segmented-control",group:"group",window:"window",checkbox:"checkbox",radio:"radio",menuitem:"menu-item",toolbar:"toolbar",scrollarea:"scroll-area",scrollview:"scroll-area",nestedscrollview:"scroll-area",table:"table"};function s(e,t={}){let r=[],i=[];for(let l of e){let e=l.depth??0,o=l.label?.trim()||l.value?.trim()||l.identifier?.trim()||"",n=f(l.type??"Element");if("group"===n&&!o)continue;for(;r.length>0&&e<=r[r.length-1];)r.pop();let a=r.length;r.push(e),i.push({node:l,depth:a,type:n,text:d(l,a,!1,n,t)})}return i}function d(e,t,r,n,a={}){var c,u,s,x,b,g,v,y;let $,S=n??f(e.type??"Element"),_=o(e,S),k=(c=e,u=S,s=a,x=_,s.summarizeTextSurfaces&&x.shouldSummarize&&function(e,t,r){let i=l(e.label);if(i&&i!==r)return i;let o=l(e.identifier);if(o&&!w(o)&&o!==r)return o;switch(t){case"text":case"text-view":return"Text view";case"text-field":return"Text field";case"search":return"Search field";default:return""}}(c,u,x.text)||p(c,u)),C=" ".repeat(t),j=e.ref?`@${e.ref}`:"",E=(b=e,g=S,v=a,y=_,$=[],!1===b.enabled&&$.push("disabled"),$.push(...b.presentationHints??[]),v.summarizeTextSurfaces&&(!0===b.selected&&$.push("selected"),!0===b.focused&&$.push("focused"),m(g)&&$.push("editable"),function(e,t){if("scroll-area"===t)return!0;let r=(e.type??"").toLowerCase(),i=`${e.role??""} ${e.subrole??""}`.toLowerCase();return r.includes("scroll")||i.includes("scroll")}(b,g)&&$.push("scrollable"),y.shouldSummarize&&($.push(`preview:"${i(y.text).replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`),$.push("truncated"))),h($)).map(e=>` [${e}]`).join(""),L=k?` "${k}"`:"";return r?`${C}${j} [${S}]${E}`.trimEnd():`${C}${j} [${S}]${L}${E}`.trimEnd()}function p(e,t){var r,i;let l=e.label?.trim();if(l&&(r=t,i=l,("scroll-area"===r||"list"===r||"collection"===r||"table"===r)&&n(i)))return"";let o=e.value?.trim();if(m(t)){if(o)return o;if(l)return l}else if(l)return l;if(o)return o;let a=e.identifier?.trim();return!a||w(a)&&("group"===t||"image"===t||"list"===t||"collection"===t)?"":a}function f(e){var t;let r=e.replace(/XCUIElementType/gi,"").toLowerCase(),i=e.includes(".")&&(e.startsWith("android.")||e.startsWith("androidx.")||e.startsWith("com."));return(r.includes(".")&&(r=r.replace(/^android\.widget\./,"").replace(/^android\.view\./,"").replace(/^android\.webkit\./,"").replace(/^androidx\./,"").replace(/^com\.google\.android\./,"").replace(/^com\.android\./,""),i&&r.includes(".")&&(r=r.slice(r.lastIndexOf(".")+1))),"textview"===r)?i?"text":"text-view":(t=r,(Object.prototype.hasOwnProperty.call(u,t)?u[t]:void 0)||r||"element")}function m(e){return"text-field"===e||"text-view"===e||"search"===e}function w(e){return/^[\w.]+:id\/[\w.-]+$/i.test(e)}function h(e){return[...new Set(e)]}export{s as buildSnapshotDisplayLines,p as displayLabel,c as findProjectRoot,f as formatRole,d as formatSnapshotLine,a as readVersion};
@@ -0,0 +1,6 @@
1
+ import e from"node:crypto";import t from"node:fs";import r from"node:fs/promises";import n from"node:os";import i from"node:path";import o from"node:net";import{AppError as a}from"./733.js";import{intersectArea as s,isScrollableType as l}from"./6024.js";import{emitDiagnostic as u}from"./432.js";import{installAndroidAdbPackage as d}from"./2954.js";let c="android-snapshot-helper",h="com.callstack.agentdevice.snapshothelper",p="com.callstack.agentdevice.snapshothelper/.SnapshotInstrumentation",f="android-snapshot-helper-v1",w="uiautomator-xml",m={"-r":"replace","-t":"allowTestPackages","-d":"allowDowngrade","-g":"grantPermissions"};async function A(e){let t=await x(e.apkPath);if(t!==e.manifest.sha256)throw new a("COMMAND_FAILED","Android snapshot helper APK checksum mismatch",{apkPath:e.apkPath,expectedSha256:e.manifest.sha256,actualSha256:t})}async function M(e){let t=e.fetch??fetch,o=await t(e.manifestUrl);if(!o.ok)throw new a("COMMAND_FAILED","Failed to download Android snapshot helper manifest",{manifestUrl:e.manifestUrl,status:o.status,statusText:o.statusText});let s=g(JSON.parse((await v(o,65536,"Android snapshot helper manifest")).toString("utf8")));if(!s.apkUrl)throw new a("COMMAND_FAILED","Android snapshot helper manifest does not include apkUrl",{manifestUrl:e.manifestUrl});let l=e.cacheDir??i.join(n.tmpdir(),`agent-device-android-snapshot-helper-${s.version}`),u=!e.cacheDir;await r.mkdir(l,{recursive:!0});let d=s.assetName??`agent-device-android-snapshot-helper-${s.version}.apk`,c=i.join(l,d),h=await t(s.apkUrl);if(!h.ok)throw new a("COMMAND_FAILED","Failed to download Android snapshot helper APK",{apkUrl:s.apkUrl,status:h.status,statusText:h.statusText});await r.writeFile(c,await v(h,0x1400000,"Android snapshot helper APK"));let p={apkPath:c,manifest:s};return await A(p),{...p,cleanup:async()=>{await r.rm(u?l:c,{recursive:u,force:!0})}}}function g(e){var t,r;if(!e||"object"!=typeof e||Array.isArray(e))throw new a("INVALID_ARGS","Android snapshot helper manifest must be an object.");return{name:D(e.name,"name",c),version:y(e.version,"version"),releaseTag:I(e.releaseTag),assetName:I(e.assetName),apkUrl:(t=e.apkUrl,r="apkUrl",null===t?null:y(t,r)),sha256:function(e){let t=y(e,"sha256").trim().toLowerCase();if(64!==t.length||!function(e){for(let t of e){let e=t.charCodeAt(0),r=e>=48&&e<=57,n=e>=97&&e<=102;if(!r&&!n)return!1}return!0}(t))throw new a("INVALID_ARGS","Android snapshot helper manifest sha256 must be a 64-character hex string.");return t}(e.sha256),checksumName:I(e.checksumName),packageName:y(e.packageName,"packageName"),versionCode:C(e.versionCode,"versionCode"),instrumentationRunner:y(e.instrumentationRunner,"instrumentationRunner"),minSdk:C(e.minSdk,"minSdk"),targetSdk:void 0===e.targetSdk?void 0:C(e.targetSdk,"targetSdk"),outputFormat:D(e.outputFormat,"outputFormat",w),statusProtocol:D(e.statusProtocol,"statusProtocol",f),installArgs:N(e.installArgs)}}async function v(e,t,r){let n=e.headers.get("content-length");if(null!==n){let e=Number(n);if(Number.isFinite(e)&&e>t)throw new a("COMMAND_FAILED",`${r} download exceeds size limit`,{contentLength:e,maxBytes:t})}if(!e.body){let n=Buffer.from(await e.arrayBuffer());if(n.length>t)throw new a("COMMAND_FAILED",`${r} download exceeds size limit`,{contentLength:n.length,maxBytes:t});return n}let i=e.body.getReader(),o=[],s=0;try{for(;;){let{done:e,value:n}=await i.read();if(e)break;if((s+=n.byteLength)>t)throw new a("COMMAND_FAILED",`${r} download exceeds size limit`,{contentLength:s,maxBytes:t});o.push(Buffer.from(n))}}finally{i.releaseLock()}return Buffer.concat(o,s)}function N(e){let t=function(e,t){if(!Array.isArray(e)||!e.every(e=>"string"==typeof e))throw new a("INVALID_ARGS",`Android snapshot helper manifest ${t} must be a string array.`);return e}(e,"installArgs");if("install"!==t[0])throw new a("INVALID_ARGS",'Android snapshot helper manifest installArgs must start with "install".');if(t.some(e=>e.includes("\0")))throw new a("INVALID_ARGS","Android snapshot helper manifest installArgs must not contain null bytes.");let r=t.slice(1).find(e=>void 0===b(e));if(r)throw new a("INVALID_ARGS",`Android snapshot helper manifest installArgs contains unsupported install flag "${r}".`);return t}async function x(r){return await new Promise((n,i)=>{let o=e.createHash("sha256"),a=t.createReadStream(r);a.on("error",i),a.on("data",e=>o.update(e)),a.on("end",()=>n(o.digest("hex")))})}function y(e,t){if("string"!=typeof e||0===e.trim().length)throw new a("INVALID_ARGS",`Android snapshot helper manifest ${t} is required.`);return e}function I(e){return"string"==typeof e&&e.trim().length>0?e:void 0}function C(e,t){if("number"!=typeof e||!Number.isInteger(e))throw new a("INVALID_ARGS",`Android snapshot helper manifest ${t} must be an integer.`);return e}function D(e,t,r){if(e!==r)throw new a("INVALID_ARGS",`Android snapshot helper manifest ${t} must be "${r}".`);return r}function b(e){if(Object.hasOwn(m,e))return m[e]}function*S(e){let t=/<node\b[^>]*>/g,r=t.exec(e);for(;r;)yield _(r[0]),r=t.exec(e)}function _(e){let t,r,n,i,o,a=(t=function(e){let t=new Map,r=e.indexOf(" "),n=e.lastIndexOf(">");if(r<0||n<=r)return t;let i=r;for(;i<n;){let r=function(e,t,r){var n,i;if((t=F(e,t,r))>=r||"/"===(n=e[t])||">"===n)return;let o=t;t=function(e,t,r){for(var n;t<r&&!("="===(n=e[t]??"")||"/"===n||">"===n||L(n));)t+=1;return t}(e,t,r);let a=e.slice(o,t);if(t=F(e,t,r),!a||"="!==e[t])return;t=F(e,t+1,r);let s=e[t];if('"'!==(i=s)&&"'"!==i)return;let l=t+1,u=e.indexOf(s,l);if(!(u<0)&&!(u>=r))return{name:a,value:function(e){let t="",r=0;for(;r<e.length;){let n=e.indexOf("&",r);if(n<0){t+=e.slice(r);break}t+=e.slice(r,n);let i=e.indexOf(";",n+1);if(i<0){t+=e.slice(n);break}t+=function(e){switch(e){case"amp":return"&";case"lt":return"<";case"gt":return">";case"quot":return'"';case"apos":return"'";default:return function(e){if(!e.startsWith("#"))return;let t=e[1]?.toLowerCase()==="x"?16:10,r=16===t?e.slice(2):e.slice(1);if(!r||!function(e,t){for(let r of e){let e=r.charCodeAt(0),n=e>=48&&e<=57;if(10===t){if(!n)return!1;continue}let i=e>=65&&e<=70,o=e>=97&&e<=102;if(!n&&!i&&!o)return!1}return!0}(r,t))return;let n=Number.parseInt(r,t);if(Number.isFinite(n))try{return String.fromCodePoint(n)}catch{return}}(e)}}(e.slice(n+1,i))??e.slice(n,i+1),r=i+1}return t}(e.slice(l,u)),nextCursor:u+1}}(e,i,n);if(!r)break;t.set(r.name,r.value),i=r.nextCursor}return t}(e),r=e=>{let r=O(t,e);if(null!==r)return"true"===r},n=(e,r)=>{let n=(e=>{let r=O(t,e);if(null===r||""===r.trim())return;let n=Number(r);return Number.isFinite(n)?n:void 0})(r);return void 0===n?{}:{[e]:n}},i=(e,t)=>{let n=r(t);return void 0===n?{}:{[e]:n}},{text:O(t,"text"),desc:O(t,"content-desc"),resourceId:O(t,"resource-id"),packageName:O(t,"package"),className:O(t,"class"),bounds:O(t,"bounds"),clickable:r("clickable"),enabled:r("enabled"),focusable:r("focusable"),focused:r("focused"),password:r("password"),...i("visibleToUser","visible-to-user"),...n("drawingOrder","drawing-order"),...i("scrollable","scrollable"),...i("canScrollForward","can-scroll-forward"),...i("canScrollBackward","can-scroll-backward"),...n("windowIndex","window-index"),...n("windowType","window-type"),...n("windowLayer","window-layer"),...i("windowActive","window-active"),...i("windowFocused","window-focused"),...void 0===(o=E(O(t,"window-bounds")))?{}:{windowRect:o}}),s=E(a.bounds);return{...a,...s?{rect:s}:{}}}function T(e,t,r){let{sourceNodes:n,...i}=k(P(e),t,r);return i}function k(e,t,r){let n={nodes:[],sourceNodes:[],...void 0!==t?{maxNodes:t}:{},maxDepth:r.depth??1/0,options:r,analysis:function(e){let t=0,r=0,n=[...e.children];for(;n.length>0;){let e=n.pop();t+=1,r=Math.max(r,e.depth),n.push(...e.children)}return{rawNodeCount:t,maxDepth:r}}(e),interactiveDescendantMemo:new Map,truncated:!1},i=r.scope?function(e,t){let r=t.toLowerCase(),n=[...e.children],i=0;for(;i<n.length;){let e=n[i++],t=e.label?.toLowerCase()??"",o=e.value?.toLowerCase()??"",a=e.identifier?.toLowerCase()??"";if(t.includes(r)||o.includes(r)||a.includes(r))return e;n.push(...e.children)}return null}(e,r.scope):null;for(let t of i?[i]:e.children)if(function e(t,r,n,i,o=!1,a=!1){if(void 0!==t.maxNodes&&t.nodes.length>=t.maxNodes){t.truncated=!0;return}if(n>t.maxDepth)return;let s=t.options.raw||function(e,t,r,n,i){var o,a,s;if(!1===e.visibleToUser)return!1;let u=function(e){let t=V(e.type),r=!!(e.label&&e.label.trim().length>0),n=!!(e.identifier&&e.identifier.trim().length>0);return{type:t,hasMeaningfulText:r&&!B(e.label??""),hasMeaningfulId:n&&!B(e.identifier??""),isStructural:function(e){let t=e.split(".").pop()??e;return t.includes("layout")||"viewgroup"===t||"view"===t}(t),isVisual:"imageview"===t||"imagebutton"===t}}(e);return t.interactiveOnly?function(e,t,r,n,i){var o,a,s,u,d;return!((o=e).rect&&(o.rect.width<=0||o.rect.height<=0))&&(!!(e.hittable||l(t.type)&&n)||(a=t,s=r,u=n,d=i,(!!a.hasMeaningfulText||!!a.hasMeaningfulId)&&!a.isVisual&&(!a.isStructural||!!d)&&(s||u||d)))}(e,u,r,n,i):!u.isStructural&&!u.isVisual||(o=e,a=u,s=n,!!o.hittable||!!a.hasMeaningfulText||!!a.hasMeaningfulId||s)}(r,t.options,o,function e(t,r){let n=t.interactiveDescendantMemo.get(r);if(void 0!==n)return n;for(let n of r.children)if(!1!==n.visibleToUser&&(n.hittable||e(t,n)))return t.interactiveDescendantMemo.set(r,!0),!0;return t.interactiveDescendantMemo.set(r,!1),!1}(t,r),a)?function(e,t,r,n){let i=e.nodes.length;return e.sourceNodes.push(t),e.nodes.push({index:i,type:t.type??void 0,label:t.label??void 0,value:t.value??void 0,identifier:t.identifier??void 0,bundleId:t.packageName??void 0,rect:t.rect,enabled:t.enabled,visibleToUser:t.visibleToUser,hittable:t.hittable,depth:r,parentIndex:n,...t.hiddenContentAbove?{hiddenContentAbove:!0}:{},...t.hiddenContentBelow?{hiddenContentBelow:!0}:{}}),i}(t,r,n,i):i,u=o||!!r.hittable,d=a||function(e){if(!e)return!1;let t=V(e);return t.includes("recyclerview")||t.includes("listview")||t.includes("gridview")}(r.type);for(let i of r.children)if(e(t,i,n+1,s,u,d),t.truncated)return}(n,t,0),n.truncated)break;let o={nodes:n.nodes,sourceNodes:n.sourceNodes,analysis:n.analysis};return n.truncated?{...o,truncated:!0}:o}function F(e,t,r){for(;t<r&&L(e[t]??"");)t+=1;return t}function L(e){return" "===e||"\n"===e||"\r"===e||" "===e}function O(e,t){return e.get(t)??null}function E(e){if(!e)return;let t=/\[(-?\d+),(-?\d+)\]\[(-?\d+),(-?\d+)\]/.exec(e);if(!t)return;let r=Number(t[1]),n=Number(t[2]);return{x:r,y:n,width:Math.max(0,Number(t[3])-r),height:Math.max(0,Number(t[4])-n)}}function P(e){let t={type:null,label:null,value:null,identifier:null,packageName:null,depth:-1,children:[]},r=[t],n=/<node\b[^>]*>|<\/node>/g,i=n.exec(e);for(;i;){let t=i[0];if(t.startsWith("</node")){r.length>1&&r.pop(),i=n.exec(e);continue}let o=_(t),a=r[r.length-1],s={type:o.className,label:o.text||o.desc,value:o.text,identifier:o.resourceId,packageName:o.packageName,rect:o.rect,enabled:o.enabled,visibleToUser:o.visibleToUser,drawingOrder:o.drawingOrder,hittable:o.clickable??o.focusable,scrollable:o.scrollable,canScrollForward:o.canScrollForward,canScrollBackward:o.canScrollBackward,windowIndex:o.windowIndex,windowType:o.windowType,windowLayer:o.windowLayer,windowActive:o.windowActive,windowFocused:o.windowFocused,windowRect:o.windowRect,depth:a.depth+1,parentIndex:void 0,children:[]};a.children.push(s),t.endsWith("/>")||r.push(s),i=n.exec(e)}return function e(t){let r=0;for(let n of t.children)!1!==n.visibleToUser&&(e(n),t.children[r]=n,r+=1);r<t.children.length&&(t.children.length=r)}(t),function(e){let t,r=e.children.filter(U);if(r.length<2)return;let n=r.filter(e=>$(e)&&H(e));if(0===n.length)return;let i=(t=n.map(e=>e.windowLayer).filter(e=>void 0!==e)).length>0?Math.max(...t):void 0;e.children=e.children.filter(e=>!$(e)||!!H(e)&&(void 0===i||e.windowLayer===i))}(t),function e(t,r){for(let n of t.children)e(n,r);if(t.children.length<2)return;let n=t.children,i=n.filter(e=>{var t,n;return t=e,n=r,!1!==t.visibleToUser&&void 0!==t.drawingOrder&&R(t)&&function e(t,r){let n=r.agentVisibleContentMemo.get(t);if(void 0!==n)return n;let i=function(t,r){if(!1===t.visibleToUser)return!1;if(t.hittable)return!0;let n=t.label?.trim()??"";if(n&&!B(n))return!0;let i=t.identifier?.trim()??"";return!(!i||B(i))||t.children.some(t=>e(t,r))}(t,r);return r.agentVisibleContentMemo.set(t,i),i}(t,n)});0!==i.length&&(t.children=n.filter(e=>!function(e,t){if(!1===e.visibleToUser||void 0===e.drawingOrder||!R(e))return!1;for(let r of t)if(r!==e&&!(r.drawingOrder<=e.drawingOrder)&&function(e,t){let r=t.width*t.height;return r<=0?0:s(e,t)/r}(r.rect,e.rect)>=.9)return!0;return!1}(e,i)))}(t,{agentVisibleContentMemo:new WeakMap}),function(e){let t=[...e.children];for(;t.length>0;){let e=t.pop();t.push(...e.children),function(e){if(!e.scrollable||!l(e.type)||`${e.type??""}`.toLowerCase().includes("horizontalscrollview"))return!1;let t=function(e){if(!e.rect||0===e.children.length)return null;let t=e.children.map(e=>e.rect).filter(e=>void 0!==e);if(0===t.length)return null;let r=Math.min(...t.map(e=>e.x)),n=Math.max(...t.map(e=>e.x+e.width)),i=Math.min(...t.map(e=>e.y)),o=Math.max(...t.map(e=>e.y+e.height));return{horizontal:Math.max(0,n-r-e.rect.width),vertical:Math.max(0,o-i-e.rect.height)}}(e);return!t||!(t.horizontal>t.vertical)||!(t.horizontal>16)}(e)&&(e.canScrollBackward&&(e.hiddenContentAbove=!0),e.canScrollForward&&(e.hiddenContentBelow=!0))}}(t),t}function R(e){return!!(e.rect&&e.rect.width>0&&e.rect.height>0)}function U(e){return void 0!==e.windowIndex||void 0!==e.windowType}function $(e){return 1===e.windowType}function H(e){return!0===e.windowActive||!0===e.windowFocused}function V(e){return e?e.toLowerCase():""}function B(e){let t=e.trim();return!!t&&/^[\w.]+:id\/[\w.-]+$/i.test(t)}async function K(e){let t=G(e),r=await e.adb(W(t),{allowFailure:!0,timeoutMs:t.commandTimeoutMs}),{output:n,cleanupDone:i}=await X(e,t,r);if(t.outputPath&&!i&&await J(e.adb,t.outputPath),0!==r.exitCode)throw new a("COMMAND_FAILED","Android snapshot helper failed",{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode,helper:n.metadata});return n}function G(e){let t=Q(e.timeoutMs,8e3),r=Q(e.packageName,h);return{waitForIdleTimeoutMs:Q(e.waitForIdleTimeoutMs,500),waitForIdleQuietMs:Q(e.waitForIdleQuietMs,100),timeoutMs:t,commandTimeoutMs:Q(e.commandTimeoutMs,t+5e3),maxDepth:Q(e.maxDepth,128),maxNodes:Q(e.maxNodes,5e3),packageName:r,runner:Q(e.instrumentationRunner,`${r}/.SnapshotInstrumentation`),...e.outputPath?{outputPath:e.outputPath}:{},...void 0!==e.emitChunks?{emitChunks:e.emitChunks}:{}}}function Q(e,t){return void 0===e?t:e}function W(e){return["shell","am","instrument","-w","-e","waitForIdleTimeoutMs",String(e.waitForIdleTimeoutMs),"-e","waitForIdleQuietMs",String(e.waitForIdleQuietMs),"-e","timeoutMs",String(e.timeoutMs),"-e","maxDepth",String(e.maxDepth),"-e","maxNodes",String(e.maxNodes),...e.outputPath?["-e","outputPath",e.outputPath]:[],...void 0!==e.emitChunks?["-e","emitChunks",String(e.emitChunks)]:[],e.runner]}async function X(e,t,r){try{return{output:Y(`${r.stdout}
2
+ ${r.stderr}`),cleanupDone:!1}}catch(n){return await z(e,t,r,n)}}async function z(e,t,r,n){if(n instanceof a&&0!==r.exitCode&&n.details?.helper)throw n;let i=await j(e,t,r);if(i)return{output:i,cleanupDone:!0};throw new a("COMMAND_FAILED",0===r.exitCode?"Android snapshot helper output could not be parsed":"Android snapshot helper failed before returning parseable output",{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode},n)}async function j(e,t,r){if(0===r.exitCode&&t.outputPath){var n;return await q(e.adb,t.outputPath,function(e){try{let t=er(e);return et(ee(t.results))}catch{return null}}(`${r.stdout}
3
+ ${r.stderr}`)??{outputFormat:w,waitForIdleTimeoutMs:(n=t).waitForIdleTimeoutMs,waitForIdleQuietMs:n.waitForIdleQuietMs,timeoutMs:n.timeoutMs,maxDepth:n.maxDepth,maxNodes:n.maxNodes,transport:"instrumentation"})}}async function q(e,t,r){let n;try{var i;n=await e((i=t,["shell","sh","-c",'cat "$1"; status=$?; rm -f "$1"; exit "$status"',"agent-device-snapshot-helper-output",i]),{allowFailure:!0,timeoutMs:5e3})}catch{return}if(0!==n.exitCode)return;let o=n.stdout.trim();if(o.includes("<hierarchy")&&o.includes("</hierarchy>"))return{xml:o,metadata:r}}async function J(e,t){try{await e(["shell","rm","-f",t],{allowFailure:!0,timeoutMs:5e3})}catch{}}function Y(e){let t=er(e),r=ee(t.results);return{xml:function(e,t){if(0===e.length)throw new a("COMMAND_FAILED","Android snapshot helper did not return XML chunks",{helper:t});let r=function(e){let t=e[0]?.count??e.length;if(t<1||e.length!==t||e.some(e=>e.count!==t))throw new a("COMMAND_FAILED","Android snapshot helper returned incomplete XML chunks",{expectedChunks:t,actualChunks:e.length});return t}(e),n=Buffer.concat(function(e,t){let r=[];for(let n=0;n<t;n+=1){let i=e.get(n);if(void 0===i)throw new a("COMMAND_FAILED","Android snapshot helper returned incomplete XML chunks",{missingChunkIndex:n,expectedChunks:t});r.push(Buffer.from(i,"base64"))}return r}(function(e,t){let r=new Map;for(let n of e){if(void 0===n.index||n.index<0||n.index>=t)throw new a("COMMAND_FAILED","Android snapshot helper returned invalid chunk index",{chunkIndex:n.index,expectedChunks:t});if(r.has(n.index))throw new a("COMMAND_FAILED","Android snapshot helper returned duplicate XML chunks",{chunkIndex:n.index});r.set(n.index,n.payloadBase64)}return r}(e,r),r)).toString("utf8");if(!n.includes("<hierarchy")||!n.includes("</hierarchy>"))throw new a("COMMAND_FAILED","Android snapshot helper output did not contain XML",{xml:n});return n}(function(e){let t=[];for(let r of e){if(r.agentDeviceProtocol!==f||r.outputFormat!==w)continue;let{payloadBase64:e}=r;void 0!==e&&t.push({index:el(r.chunkIndex),count:el(r.chunkCount),payloadBase64:e})}return t}(t.status),r),metadata:{...et(r),transport:"instrumentation"}}}function Z(e,t={outputFormat:w},r={},n){return{...T(e,n,r),metadata:t}}function ee(e){let t=e.find(e=>e.agentDeviceProtocol===f);if(!t)throw new a("COMMAND_FAILED","Android snapshot helper did not return a final result");if("true"!==t.ok){var r;throw new a("COMMAND_FAILED",(r=t).message&&"null"!==r.message?r.message:r.errorType||"Android snapshot helper returned an error",{errorType:t.errorType,helper:t})}return t}function et(e){var t;return{helperApiVersion:e.helperApiVersion,outputFormat:w,waitForIdleTimeoutMs:el(e.waitForIdleTimeoutMs),waitForIdleQuietMs:el(e.waitForIdleQuietMs),timeoutMs:el(e.timeoutMs),maxDepth:el(e.maxDepth),maxNodes:el(e.maxNodes),rootPresent:eu(e.rootPresent),captureMode:"interactive-windows"===(t=e.captureMode)||"active-window"===t?t:void 0,windowCount:el(e.windowCount),nodeCount:el(e.nodeCount),truncated:eu(e.truncated),elapsedMs:el(e.elapsedMs)}}function er(e){var t;let r={status:[],results:[],currentStatus:null,currentResult:null};for(let t of e.split(/\r?\n/))!function(e,t){if(e.startsWith("INSTRUMENTATION_STATUS: ")){t.currentStatus??={},eo(e.slice(24),t.currentStatus);return}if(e.startsWith("INSTRUMENTATION_STATUS_CODE: "))return en(t);if(e.startsWith("INSTRUMENTATION_RESULT: ")){t.currentResult??={},eo(e.slice(24),t.currentResult);return}e.startsWith("INSTRUMENTATION_CODE: ")&&ei(t)}(t,r);return en(t=r),ei(t),{status:r.status,results:r.results}}function en(e){e.currentStatus&&(e.status.push(e.currentStatus),e.currentStatus=null)}function ei(e){e.currentResult&&(e.results.push(e.currentResult),e.currentResult=null)}function eo(e,t){let r=e.indexOf("=");r<0||(t[e.slice(0,r)]=e.slice(r+1))}function ea(e){if(void 0===e)return;let t=Number(e);return Number.isFinite(t)?t:void 0}function es(e){return"true"===e||"false"!==e&&void 0}let el=ea,eu=es,ed=new Map,ec=new Map;async function eh(e){var t,r,n;let i;if(!(void 0===(i=process.env.AGENT_DEVICE_ANDROID_SNAPSHOT_HELPER_SESSION)||!/^(0|false|no|off)$/i.test(i))||!e.adbProvider?.spawn)return;let o=G(e),a=e.deviceKey??"android:default",s=(t=a,r=o,n=e,JSON.stringify({deviceKey:t,packageName:r.packageName,runner:r.runner,helperVersion:n.helperVersion,helperVersionCode:n.helperVersionCode,waitForIdleTimeoutMs:r.waitForIdleTimeoutMs,waitForIdleQuietMs:r.waitForIdleQuietMs,timeoutMs:r.timeoutMs,maxDepth:r.maxDepth,maxNodes:r.maxNodes}));if(ec.get(a)===s)return;let l=ed.get(a);if(l&&l.identity!==s&&(await ep(a),l=void 0),!l)try{l=await ef({deviceKey:a,identity:s,options:e,resolved:o})}catch(e){ec.set(a,s),u({level:"warn",phase:"android_snapshot_helper_session_disabled",data:{deviceKey:a,reason:e instanceof Error?e.message:String(e)}});return}try{let e=l.capturedCount>0,t=await em(l,o);return l.capturedCount+=1,{xml:t.xml,metadata:{...t.metadata,transport:"persistent-session",sessionReused:e}}}catch(e){throw await ep(a),e}}async function ep(e){let t=ed.get(e);if(t){ed.delete(e);try{await eA(t,`quit ${Date.now()}`,1e3)}catch{}try{await t.process.kill("SIGTERM")}catch{}await ew(t.process,2e3);try{await eM(t)}catch{}u({phase:"android_snapshot_helper_session_stop",data:{deviceKey:e,port:t.port,capturedCount:t.capturedCount,lifetimeMs:Date.now()-t.startedAtMs}})}}async function ef(e){let t=await new Promise((e,t)=>{let r=o.createServer();r.unref(),r.on("error",t),r.listen(0,"127.0.0.1",()=>{let n=r.address();if(!n||"string"==typeof n)return void r.close(()=>t(Error("Failed to allocate a local TCP port")));let i=n.port;r.close(()=>e(i))})});await e.options.adb(["forward",`tcp:${t}`,`tcp:${t}`],{allowFailure:!1,timeoutMs:5e3});let r=W({...e.resolved,outputPath:void 0,emitChunks:!1}),n=r[r.length-1];if(!n)throw new a("INVALID_ARGS","Android snapshot helper runner was not resolved");let i=[...r.slice(0,-1),"-e","sessionPort",String(t),n],s=e.options.adbProvider.spawn(i,{allowFailure:!0,captureOutput:!1}),l={identity:e.identity,deviceKey:e.deviceKey,port:t,adb:e.options.adb,process:s,startedAtMs:Date.now(),capturedCount:0};try{var d;return await (d=s,new Promise((e,t)=>{let r="",n=setTimeout(()=>{t(new a("COMMAND_FAILED","Android snapshot helper session did not become ready",{output:r,timeoutMs:1e4}))},1e4),i=t=>{(r+=t.toString()).includes(`agentDeviceProtocol=${f}`)&&r.includes("sessionReady=true")&&(clearTimeout(n),e())};d.stdout?.on("data",i),d.stderr?.on("data",i),d.once("exit",(e,i)=>{clearTimeout(n),t(new a("COMMAND_FAILED","Android snapshot helper session exited before ready",{output:r,exitCode:e,signal:i}))}),d.on("error",e=>{clearTimeout(n),t(e)})})),ed.set(e.deviceKey,l),u({phase:"android_snapshot_helper_session_ready",data:{deviceKey:e.deviceKey,port:t,packageName:e.resolved.packageName,runner:e.resolved.runner}}),l}catch(e){await eM(l);try{s.kill("SIGTERM")}catch{}throw await ew(s,2e3),e}}function ew(e,t){return new Promise(r=>{let n=setTimeout(r,t);e.once("close",()=>{clearTimeout(n),r()}),e.once("exit",()=>{clearTimeout(n),r()})})}async function em(e,t){let r=`snapshot-${Date.now()}-${Math.random().toString(16).slice(2)}`,n=Math.min(t.commandTimeoutMs,Math.max(t.timeoutMs+1e4,3e3));return function(e,t){var r;let{headers:n,xml:i}=function(e){let t=e.indexOf("\n\n");if(t<0)throw new a("COMMAND_FAILED","Android snapshot helper session returned malformed output",{response:e});return{headers:function(e){let t={};for(let r of e.split(/\r?\n/)){let e=r.indexOf("=");e<0||(t[r.slice(0,e)]=r.slice(e+1))}return t}(e.slice(0,t)),xml:e.slice(t+2)}}(e);return function(e,t){if(e.agentDeviceProtocol!==f)throw new a("COMMAND_FAILED","Android snapshot helper session returned wrong protocol",{headers:e});if(e.outputFormat!==w)throw new a("COMMAND_FAILED","Android snapshot helper session returned wrong output format",{headers:e});if(e.requestId!==t)throw new a("COMMAND_FAILED","Android snapshot helper session returned stale output",{headers:e,requestId:t});if("true"!==e.ok)throw new a("COMMAND_FAILED",e.message||e.errorType||"Android snapshot helper session returned an error",{helper:e})}(n,t),function(e,t){let r=ea(e.byteLength);if(void 0!==r&&Buffer.byteLength(t,"utf8")!==r)throw new a("COMMAND_FAILED","Android snapshot helper session returned truncated XML",{headers:e,actualByteLength:Buffer.byteLength(t,"utf8")});if(!t.includes("<hierarchy")||!t.includes("</hierarchy>"))throw new a("COMMAND_FAILED","Android snapshot helper session did not return XML",{headers:e,xml:t})}(n,i),{xml:i,metadata:{helperApiVersion:(r=n).helperApiVersion,outputFormat:w,waitForIdleTimeoutMs:ea(r.waitForIdleTimeoutMs),waitForIdleQuietMs:ea(r.waitForIdleQuietMs),timeoutMs:ea(r.timeoutMs),maxDepth:ea(r.maxDepth),maxNodes:ea(r.maxNodes),rootPresent:es(r.rootPresent),captureMode:"interactive-windows"===r.captureMode||"active-window"===r.captureMode?r.captureMode:void 0,windowCount:ea(r.windowCount),nodeCount:ea(r.nodeCount),truncated:es(r.truncated),elapsedMs:ea(r.elapsedMs)}}}(await eA(e,`snapshot ${r}`,n),r)}function eA(e,t,r){return new Promise((n,i)=>{let s=o.connect({host:"127.0.0.1",port:e.port}),l=[],u=setTimeout(()=>{s.destroy(),i(new a("COMMAND_FAILED","Android snapshot helper session request timed out",{command:t,timeoutMs:r,port:e.port}))},r);s.on("connect",()=>{s.write(`${t}
4
+ `)}),s.on("data",e=>{l.push(Buffer.from(e))}),s.on("error",e=>{clearTimeout(u),i(e)}),s.on("close",()=>{clearTimeout(u),n(Buffer.concat(l).toString("utf8"))})})}async function eM(e){await e.process.stdin?.end(),await e.process.stdout?.destroy(),await e.process.stderr?.destroy(),await eg(e)}async function eg(e){await e.adb(["forward","--remove",`tcp:${e.port}`],{allowFailure:!0,timeoutMs:5e3})}let ev=new Map;function eN(e){ey(ex(e.deviceKey,e.packageName,e.versionCode))}function ex(e,t,r){return e?`${e}\0${t}\0${r}`:void 0}function ey(e){e&&ev.delete(e)}async function eI(e){var t,r,n;let{adb:i,artifact:o}=e,s=e.installPolicy??"missing-or-outdated",l=o.manifest.packageName,u=o.manifest.versionCode;if("never"===s)return{packageName:l,versionCode:u,installed:!1,reason:"skipped"};let d=ex(e.deviceKey,l,u),c=d?ev.get(d):void 0;if(d&&"always"!==s&&void 0!==c)return{packageName:l,versionCode:u,installedVersionCode:c,installed:!1,reason:"current"};let h=await eC(i,l,e.timeoutMs),p=(t=s,r=h,n=u,"never"===t?"skipped":"always"===t?"forced":void 0===r?"missing":r<n?"outdated":"current");if("current"===p){if(void 0===h)throw Error("Expected installed versionCode for current Android snapshot helper");return d&&ev.set(d,h),{packageName:l,versionCode:u,installedVersionCode:h,installed:!1,reason:p}}await A(o);let f=await eD(i,e.adbProvider??i,o.apkPath,function(e){let t={};for(let r of e.slice(1)){let e=b(r);if(!e)throw new a("INVALID_ARGS",`Android snapshot helper manifest installArgs contains unsupported install flag "${r}".`);t[e]=!0}return t}(N(o.manifest.installArgs)),{packageName:l,timeoutMs:e.timeoutMs});if(0!==f.exitCode)throw ey(d),new a("COMMAND_FAILED","Failed to install Android snapshot helper",{packageName:l,versionCode:u,stdout:f.stdout,stderr:f.stderr,exitCode:f.exitCode});return d&&ev.set(d,u),{packageName:l,versionCode:u,installedVersionCode:h,installed:!0,reason:p}}async function eC(e,t,r){let n=await e(["shell","cmd","package","list","packages","--show-versioncode",t],{allowFailure:!0,timeoutMs:r});if(0===n.exitCode){var i=`${n.stdout}
5
+ ${n.stderr}`,o=t;let e=`package:${o}`;for(let t of i.split(/\r?\n/)){if(!t.startsWith(e)||t.length>e.length&&!/\s/.test(t[e.length]??""))continue;let r=/(?:^|\s)versionCode:(\d+)(?:\s|$)/.exec(t);if(r)return Number(r[1])}return}}async function eD(e,t,r,n,i){var o;let a=async()=>await d(r,{allowFailure:!0,provider:t,...n,timeoutMs:i.timeoutMs}),s=await a();if(0===s.exitCode||(o=s,!`${o.stdout}
6
+ ${o.stderr}`.includes("INSTALL_FAILED_UPDATE_INCOMPATIBLE")))return s;let l=await e(["uninstall",i.packageName],{allowFailure:!0,timeoutMs:i.timeoutMs}),u=await a();return 0===u.exitCode?u:{...u,stderr:[u.stderr,l.stderr?`Previous uninstall stderr after INSTALL_FAILED_UPDATE_INCOMPATIBLE: ${l.stderr}`:""].filter(Boolean).join("\n")}}export{c as ANDROID_SNAPSHOT_HELPER_NAME,w as ANDROID_SNAPSHOT_HELPER_OUTPUT_FORMAT,h as ANDROID_SNAPSHOT_HELPER_PACKAGE,f as ANDROID_SNAPSHOT_HELPER_PROTOCOL,p as ANDROID_SNAPSHOT_HELPER_RUNNER,S as androidUiNodes,k as buildUiHierarchySnapshot,K as captureAndroidSnapshotWithHelper,eh as captureAndroidSnapshotWithHelperSession,eI as ensureAndroidSnapshotHelper,eN as forgetAndroidSnapshotHelperInstall,g as parseAndroidSnapshotHelperManifest,Y as parseAndroidSnapshotHelperOutput,Z as parseAndroidSnapshotHelperXml,T as parseUiHierarchy,P as parseUiHierarchyTree,M as prepareAndroidSnapshotHelperArtifactFromManifestUrl,ep as stopAndroidSnapshotHelperSession,A as verifyAndroidSnapshotHelperArtifact};
@@ -0,0 +1 @@
1
+ import{setSessionSnapshot as e,captureSnapshot as r,isNavigationSensitiveAction as t,markPendingInteractionOutcome as n,markPostGestureStabilization as o,getSnapshotReferenceFrame as i,recordTouchVisualizationEvent as a,markAndroidSnapshotFreshness as c,stripInternalInteractionFlags as s}from"./9722.js";import{isSparseSnapshotQualityVerdict as d,successText as f}from"./9873.js";import{getAndroidScreenSize as u}from"./input-actions.js";import{emitDiagnostic as l}from"./432.js";async function h(t,n,o,i,a){let c={...n??{},snapshotInteractiveOnly:a.interactiveOnly},s=i(c,t.appBundleId,t.trace?.outPath),{snapshot:f}=await r({device:t.device,session:t,flags:c,outPath:c.out,logPath:s.logPath??"",androidFreshnessMode:a.androidFreshnessMode});return d(f.snapshotQuality)||(e(t,f),o.set(t.name,t)),f}function p(e){var r,t,n;let o,i,a,{data:c,fallbackX:s,fallbackY:d,referenceFrame:u,extra:l}=e,h=(r=l,t=s,n=d,o="string"==typeof r?.ref?r.ref:void 0,i="string"==typeof r?.button?r.button:void 0,a="string"==typeof r?.gesture?r.gesture:void 0,("string"==typeof r?.text?`Filled ${Array.from(r.text).length} chars`:o?"longpress"===a?`Long pressed @${o} (${t}, ${n})`:i&&"primary"!==i?`Clicked ${i} @${o} (${t}, ${n})`:`Tapped @${o} (${t}, ${n})`:void 0)??("string"==typeof c?.message?c.message:void 0));return{x:s,y:d,...u??{},...l??{},...c??{},...f(h)}}function g(e){let{session:r,sessionStore:i,command:d,positionals:f,retryPositionals:u,flags:l,result:h,responseData:p,actionStartedAt:g,actionFinishedAt:_,androidFreshnessBaseline:m}=e,v=s(l);return i.recordAction(r,{command:d,positionals:f,flags:v??{},result:h}),n({session:r,command:d,positionals:u??f,flags:l,preSnapshot:r.snapshot}),t(d)&&c(r,d,m??r.snapshot),o(r,d,u??f,l),a(r,d,f,h,v??{},g,_),{ok:!0,data:p}}async function _(e){let{session:r,flags:t,sessionStore:n,contextFromFlags:o,captureSnapshotForSession:a}=e;if(!r.recording)return;if(r.recording.touchReferenceFrame)return r.recording.touchReferenceFrame;if("android"===r.device.platform){let e=await u(r.device),t={referenceWidth:e.width,referenceHeight:e.height};return r.recording&&(r.recording.touchReferenceFrame=t),t}let c=i(r.snapshot);if(c)return r.recording&&(r.recording.touchReferenceFrame=c),c;if(!r.recording)return;let s=i(await a(r,t,n,o,{interactiveOnly:!0}));return s&&r.recording&&(r.recording.touchReferenceFrame=s),s}async function m(e){try{return await _(e)}catch(r){l({level:"warn",phase:"touch_reference_frame_resolve_failed",data:{platform:e.session.device.platform,error:r instanceof Error?r.message:String(r)}});return}}function v(e){return i({nodes:e,createdAt:0})}export{p as buildTouchVisualizationResult,g as finalizeTouchInteraction,h as interaction_snapshot_captureSnapshotForSession,v as readSnapshotNodesReferenceFrame,m as resolveDirectTouchReferenceFrameSafely};
@@ -0,0 +1 @@
1
+ import{AppError as t}from"./733.js";let e=["camera","microphone","photos","contacts","contacts-limited","notifications","calendar","location","location-always","media-library","motion","reminders","siri"];function r(e){let r=e.trim().toLowerCase();if("grant"===r)return"grant";if("deny"===r)return"deny";if("reset"===r)return"reset";throw new t("INVALID_ARGS",`Invalid permission action: ${e}. Use grant|deny|reset.`)}function i(r){let i=r?.trim().toLowerCase();if("camera"===i||"microphone"===i||"photos"===i||"contacts"===i||"contacts-limited"===i||"notifications"===i||"calendar"===i||"location"===i||"location-always"===i||"media-library"===i||"motion"===i||"reminders"===i||"siri"===i)return i;throw new t("INVALID_ARGS",`permission setting requires a target: ${e.join("|")}`)}function n(e){let r=e.trim().toLowerCase();if("light"===r)return"light";if("dark"===r)return"dark";if("toggle"===r)return"toggle";throw new t("INVALID_ARGS",`Invalid appearance state: ${e}. Use light|dark|toggle.`)}function o(e){let r=e.toLowerCase();if("on"===r||"true"===r||"1"===r)return!0;if("off"===r||"false"===r||"0"===r)return!1;throw new t("INVALID_ARGS",`Invalid setting state: ${e}`)}function a(t){return t.map(t=>({args:t.args.join(" "),exitCode:t.exitCode,stderr:t.stderr.slice(0,400)}))}export{n as parseAppearanceAction,r as parsePermissionAction,i as parsePermissionTarget,o as parseSettingState,a as summarizeCommandAttemptFailures};
@@ -1,2 +1,2 @@
1
- import e from"node:fs";import t from"node:path";import{createHash as r}from"node:crypto";import{fileURLToPath as n}from"node:url";import{runCmdDetached as o,runCmdSync as i}from"./9818.js";import{readProcessCommand as a,waitForProcessExit as s,resolveRuntimeTransportHints as l,isProcessAlive as u,readProcessStartTime as c}from"./8656.js";import{normalizeBaseUrl as d,ENV_COMPANION_TUNNEL_BEARER_TOKEN as p,ENV_COMPANION_TUNNEL_SERVER_BASE_URL as m,ENV_COMPANION_TUNNEL_STATE_PATH as h,ENV_COMPANION_TUNNEL_LAUNCH_URL as f,ENV_COMPANION_TUNNEL_SCOPE_LEASE_ID as g,ENV_COMPANION_TUNNEL_SCOPE_TENANT_ID as y,ENV_COMPANION_TUNNEL_DEVICE_PORT as b,buildBundleUrl as P,METRO_COMPANION_RUN_ARG as S,ENV_COMPANION_TUNNEL_SESSION as w,ENV_COMPANION_TUNNEL_SCOPE_RUN_ID as E,ENV_COMPANION_TUNNEL_REGISTER_PATH as _,ENV_COMPANION_TUNNEL_LOCAL_BASE_URL as v,ENV_COMPANION_TUNNEL_UNREGISTER_PATH as U}from"./2301.js";import{AppError as M}from"./9152.js";import{resolveUserPath as I}from"./3267.js";import{sleep as k}from"./4829.js";let T="companion-tunnel";function A(e){return r("sha256").update(e).digest("hex")}function N(e){return e?.trim()?e.trim():void 0}function R(e,r,n,o){let i=o??t.join(e,".agent-device");if(!n)return{statePath:t.join(i,`${r.slug}.json`),logPath:t.join(i,`${r.slug}.log`)};let a=A(n).slice(0,12),s=t.join(i,r.slug);return{statePath:t.join(s,`${r.slug}-${a}.json`),logPath:t.join(s,`${r.slug}-${a}.log`)}}function $(t){try{let r=JSON.parse(e.readFileSync(t,"utf8"));if(!Number.isInteger(r.pid)||0>=Number(r.pid)||"string"!=typeof r.serverBaseUrl||"string"!=typeof r.localBaseUrl||"string"!=typeof r.tokenHash||0===r.tokenHash.length)return null;let n=Array.isArray(r.consumers)?r.consumers.filter(e=>"string"==typeof e&&e.length>0):[];return{pid:Number(r.pid),startTime:"string"==typeof r.startTime?r.startTime:void 0,command:"string"==typeof r.command?r.command:void 0,serverBaseUrl:r.serverBaseUrl,localBaseUrl:r.localBaseUrl,launchUrl:N("string"==typeof r.launchUrl?r.launchUrl:void 0),registerPath:N("string"==typeof r.registerPath?r.registerPath:void 0),unregisterPath:N("string"==typeof r.unregisterPath?r.unregisterPath:void 0),devicePort:Number.isInteger(r.devicePort)?Number(r.devicePort):void 0,session:N("string"==typeof r.session?r.session:void 0),bridgeScope:function(e){if(!(!e||"object"!=typeof e||Array.isArray(e))&&"string"==typeof e.tenantId&&"string"==typeof e.runId&&"string"==typeof e.leaseId)return{tenantId:e.tenantId,runId:e.runId,leaseId:e.leaseId}}(r.bridgeScope),tokenHash:r.tokenHash,consumers:n}}catch{return null}}function x(r,n){e.mkdirSync(t.dirname(r),{recursive:!0}),e.writeFileSync(r,`${JSON.stringify(n,null,2)}
1
+ import e from"node:fs";import t from"node:path";import{createHash as r}from"node:crypto";import{fileURLToPath as n}from"node:url";import{runCmdDetached as o,runCmdSync as i}from"./8875.js";import{readProcessCommand as a,waitForProcessExit as s,resolveRuntimeTransportHints as l,isProcessAlive as u,readProcessStartTime as c}from"./5628.js";import{normalizeBaseUrl as d,ENV_COMPANION_TUNNEL_BEARER_TOKEN as p,ENV_COMPANION_TUNNEL_SERVER_BASE_URL as m,ENV_COMPANION_TUNNEL_STATE_PATH as h,ENV_COMPANION_TUNNEL_LAUNCH_URL as f,ENV_COMPANION_TUNNEL_SCOPE_LEASE_ID as g,ENV_COMPANION_TUNNEL_SCOPE_TENANT_ID as y,ENV_COMPANION_TUNNEL_DEVICE_PORT as b,buildBundleUrl as P,METRO_COMPANION_RUN_ARG as S,ENV_COMPANION_TUNNEL_SESSION as w,ENV_COMPANION_TUNNEL_SCOPE_RUN_ID as E,ENV_COMPANION_TUNNEL_REGISTER_PATH as _,ENV_COMPANION_TUNNEL_LOCAL_BASE_URL as v,ENV_COMPANION_TUNNEL_UNREGISTER_PATH as U}from"./4069.js";import{AppError as M}from"./733.js";import{resolveUserPath as I}from"./9612.js";import{sleep as k}from"./5560.js";let T="companion-tunnel";function A(e){return r("sha256").update(e).digest("hex")}function N(e){return e?.trim()?e.trim():void 0}function R(e,r,n,o){let i=o??t.join(e,".agent-device");if(!n)return{statePath:t.join(i,`${r.slug}.json`),logPath:t.join(i,`${r.slug}.log`)};let a=A(n).slice(0,12),s=t.join(i,r.slug);return{statePath:t.join(s,`${r.slug}-${a}.json`),logPath:t.join(s,`${r.slug}-${a}.log`)}}function $(t){try{let r=JSON.parse(e.readFileSync(t,"utf8"));if(!Number.isInteger(r.pid)||0>=Number(r.pid)||"string"!=typeof r.serverBaseUrl||"string"!=typeof r.localBaseUrl||"string"!=typeof r.tokenHash||0===r.tokenHash.length)return null;let n=Array.isArray(r.consumers)?r.consumers.filter(e=>"string"==typeof e&&e.length>0):[];return{pid:Number(r.pid),startTime:"string"==typeof r.startTime?r.startTime:void 0,command:"string"==typeof r.command?r.command:void 0,serverBaseUrl:r.serverBaseUrl,localBaseUrl:r.localBaseUrl,launchUrl:N("string"==typeof r.launchUrl?r.launchUrl:void 0),registerPath:N("string"==typeof r.registerPath?r.registerPath:void 0),unregisterPath:N("string"==typeof r.unregisterPath?r.unregisterPath:void 0),devicePort:Number.isInteger(r.devicePort)?Number(r.devicePort):void 0,session:N("string"==typeof r.session?r.session:void 0),bridgeScope:function(e){if(!(!e||"object"!=typeof e||Array.isArray(e))&&"string"==typeof e.tenantId&&"string"==typeof e.runId&&"string"==typeof e.leaseId)return{tenantId:e.tenantId,runId:e.runId,leaseId:e.leaseId}}(r.bridgeScope),tokenHash:r.tokenHash,consumers:n}}catch{return null}}function x(r,n){e.mkdirSync(t.dirname(r),{recursive:!0}),e.writeFileSync(r,`${JSON.stringify(n,null,2)}
2
2
  `,"utf8")}function j(t){try{let r=e.readdirSync(t);0===r.length&&e.rmdirSync(t)}catch{}}function B(r,n){let o=t.dirname(r.statePath),i=t.dirname(r.logPath);var a=r.statePath;try{e.unlinkSync(a)}catch{}var s=r.logPath;try{e.unlinkSync(s)}catch{}j(o),i!==o&&j(i),t.basename(o)===n.slug&&j(t.dirname(o))}function C(e,t){return e.includes(t.runArg)}function D(e){return N(e.consumerKey)??N(e.profileKey)??null}function H(e,t){return!t||e.consumers.includes(t)?e:{...e,consumers:[...e.consumers,t]}}async function K(e,t){if(!u(e.pid))return;let r=a(e.pid);if(r&&C(r,t)){try{process.kill(e.pid,"SIGTERM")}catch(t){let e=t.code;if("ESRCH"===e||"EPERM"===e)return;throw t}if(!await s(e.pid,1e3)){try{process.kill(e.pid,"SIGKILL")}catch(t){let e=t.code;if("ESRCH"===e||"EPERM"===e)return;throw t}await s(e.pid,1e3)}}}async function O(r){var i;let s,l=D(r),P=R(r.projectRoot,r.definition,r.profileKey,r.stateDir),S=$(P.statePath);if(S&&function(e,t){var r,n;if(!u(e.pid))return!1;if(e.startTime){let t=c(e.pid);if(!t||t!==e.startTime)return!1}let o=a(e.pid);return!!o&&!!C(o,t.definition)&&!!e.bridgeScope&&e.serverBaseUrl===d(t.serverBaseUrl)&&e.localBaseUrl===d(t.localBaseUrl)&&e.launchUrl===N(t.launchUrl)&&e.registerPath===N(t.registerPath)&&e.unregisterPath===N(t.unregisterPath)&&e.devicePort===t.devicePort&&e.session===N(t.session)&&(r=e.bridgeScope,n=t.bridgeScope,r.tenantId===n.tenantId&&r.runId===n.runId&&r.leaseId===n.leaseId)&&e.tokenHash===A(t.bearerToken)}(S,r)){let e=H(S,l);return e!==S&&x(P.statePath,e),{pid:S.pid,spawned:!1,statePath:P.statePath,logPath:P.logPath}}S&&(await K(S,r.definition),B(P,r.definition)),i=P.statePath,e.mkdirSync(t.dirname(i),{recursive:!0}),e.closeSync(e.openSync(i,"a"));try{s=function(r,i){let s=function(r){let o=n(import.meta.url),i=t.extname(o)||".js",a=[t.join(t.dirname(o),`${T}${i}`),t.join(t.dirname(o),"internal",`${T}${i}`)].find(t=>e.existsSync(t));if(!a)throw Error(`${r.displayName} entrypoint not found. Rebuild the package to include the companion worker entry.`);return a}(r.definition),l=s.endsWith(".ts")?["--experimental-strip-types"]:[];e.mkdirSync(t.dirname(i),{recursive:!0});let u=e.openSync(i,"a"),P=0;try{let e;P=o(process.execPath,[...l,s,r.definition.runArg],{env:((e={...r.env??process.env})[m]=d(r.serverBaseUrl),e[p]=r.bearerToken,e[v]=d(r.localBaseUrl),e[h]=R(r.projectRoot,r.definition,r.profileKey,r.stateDir).statePath,e[y]=r.bridgeScope.tenantId,e[E]=r.bridgeScope.runId,e[g]=r.bridgeScope.leaseId,r.launchUrl?.trim()?e[f]=r.launchUrl.trim():delete e[f],r.registerPath?.trim()?e[_]=r.registerPath.trim():delete e[_],r.unregisterPath?.trim()?e[U]=r.unregisterPath.trim():delete e[U],void 0!==r.devicePort?e[b]=String(r.devicePort):delete e[b],r.session?.trim()?e[w]=r.session.trim():delete e[w],e),stdio:["ignore",u,u]})}finally{e.closeSync(u)}if(!Number.isInteger(P)||P<=0)throw Error(`Failed to start ${r.definition.displayName} process.`);return{pid:P,startTime:c(P)??void 0,command:a(P)??void 0,serverBaseUrl:d(r.serverBaseUrl),localBaseUrl:d(r.localBaseUrl),launchUrl:N(r.launchUrl),registerPath:N(r.registerPath),unregisterPath:N(r.unregisterPath),devicePort:r.devicePort,session:N(r.session),bridgeScope:r.bridgeScope,tokenHash:A(r.bearerToken),consumers:[]}}(r,P.logPath),x(P.statePath,H(s,l))}catch(e){throw s&&await K(s,r.definition).catch(()=>{}),B(P,r.definition),e}return{pid:s.pid,spawned:!0,statePath:P.statePath,logPath:P.logPath}}async function L(e){let t=D(e),r=R(e.projectRoot,e.definition,e.profileKey,e.stateDir),n=$(r.statePath);if(!n)return B(r,e.definition),{stopped:!1,statePath:r.statePath};let o=t?{...n,consumers:n.consumers.filter(e=>e!==t)}:{...n,consumers:[]};return o.consumers.length>0?(x(r.statePath,o),{stopped:!1,statePath:r.statePath}):(await K(n,e.definition),B(r,e.definition),{stopped:!0,statePath:r.statePath})}let G={slug:"metro-companion",runArg:S,displayName:"Metro companion"};async function F(e){return await O({...e,definition:G,registerPath:e.registerPath??"/api/metro/companion/register"})}async function J(e){return await L({...e,definition:G})}function V(e){return"string"==typeof e&&e.trim()?d(e.trim()):""}function q(e){return"string"==typeof e&&e.trim()?e.trim():void 0}function W(e,t,r){return I(e,{env:t,cwd:r})}function z(t){try{return e.accessSync(t,e.constants.F_OK),!0}catch{return!1}}function Q(e,t,r){if(null==e||""===e)return t;let n=Number.parseInt(String(e),10);return Number.isInteger(n)?Math.max(n,r):t}function X(e,t){if(null==e||""===e)return t;let r=Number.parseInt(String(e),10);if(!Number.isInteger(r)||r<1||r>65535)throw new M("INVALID_ARGS",`Invalid Metro port: ${String(e)}. Use 1-65535.`);return r}function Y(e,t){return{platform:t,bundleUrl:P(e,t)}}function Z(e,t){return{platform:t,metroHost:q(e?.metro_host),metroPort:e?.metro_port,bundleUrl:q(e?.metro_bundle_url),launchUrl:q(e?.launch_url)}}async function ee(e){await k(e)}async function et(e,t,r={}){try{let n=await fetch(e,{headers:r,signal:AbortSignal.timeout(t)});return{ok:n.ok,status:n.status,body:await n.text()}}catch(r){if(r instanceof Error&&"TimeoutError"===r.name)throw Error(`Timed out fetching ${e} after ${t}ms`);throw r}}async function er(e,t){try{let r=await et(e,t);return r.ok&&r.body.includes("packager-status:running")}catch{return!1}}async function en(e){if(Number.isInteger(e)&&!(e<=0)){try{process.kill(e,"SIGTERM")}catch(t){let e=t.code;if("ESRCH"===e||"EPERM"===e)return;throw t}if(!await s(e,1e3)){try{process.kill(e,"SIGKILL")}catch(t){let e=t.code;if("ESRCH"===e||"EPERM"===e)return;throw t}await s(e,1e3)}}}function eo(e,t){let r=Error(e);return r.retryable=t,r}function ei(e,t){return!!(e>=500||408===e||425===e||429===e||JSON.stringify(t).includes("Metro companion is not connected"))}function ea(e){return!!(e&&"object"==typeof e&&"retryable"in e&&!0===e.retryable)}async function es(e){let t;try{var r,n;t=await fetch(`${e.baseUrl}/api/metro/bridge`,{method:"POST",headers:(r=e.baseUrl,n=e.bearerToken,{Authorization:`Bearer ${n}`,"Content-Type":"application/json",...r.includes("ngrok")?{"ngrok-skip-browser-warning":"1"}:{}}),body:JSON.stringify({...e.scope,...e.runtime?{ios_runtime:e.runtime}:{},timeout_ms:e.timeoutMs}),signal:AbortSignal.timeout(e.timeoutMs)})}catch(t){if(t instanceof Error&&"TimeoutError"===t.name)throw eo(`/api/metro/bridge timed out after ${e.timeoutMs}ms calling ${e.baseUrl}/api/metro/bridge`,!0);throw eo(t instanceof Error?t.message:String(t),!0)}let o=function(e,t,r){if(!e)return{};try{let t=JSON.parse(e);if(!t||"object"!=typeof t||Array.isArray(t))throw Error("Expected a JSON object");return t}catch(i){let n=e.slice(0,200),o=i instanceof Error?i.message:String(i);throw eo(`/api/metro/bridge returned invalid JSON (${t}) from ${r}: ${o}. body=${JSON.stringify(n)}`,ei(t,e))}}(await t.text(),t.status,e.baseUrl);if(!t.ok)throw eo(`/api/metro/bridge failed (${t.status}): ${JSON.stringify(o)}`,ei(t.status,o));var i=o;let a=i.data??i;if(!a||"object"!=typeof a||Array.isArray(a))throw eo("/api/metro/bridge returned malformed descriptor: Expected a JSON object.",!1);try{return{enabled:a.enabled,baseUrl:a.base_url,statusUrl:a.status_url??"",bundleUrl:a.bundle_url??"",iosRuntime:Z(a.ios_runtime,"ios"),androidRuntime:Z(a.android_runtime,"android"),upstream:{bundleUrl:a.upstream.bundle_url??"",host:a.upstream.host??"",port:a.upstream.port??0,statusUrl:a.upstream.status_url??""},probe:{reachable:a.probe.reachable,statusCode:a.probe.status_code,latencyMs:a.probe.latency_ms,detail:a.probe.detail}}}catch(e){throw eo(`/api/metro/bridge returned malformed descriptor: ${e instanceof Error?e.message:String(e)}`,!1)}}function el(e,t,r,n,o){let i=[`Metro bridge is required for this run but could not be configured via ${e}/api/metro/bridge.`];return t&&i.push(`bridgeError=${t}`),r?.probe.reachable===!1&&i.push(`bridgeProbe=${r.probe.detail||`unreachable (status ${r.probe.statusCode||0})`}`),n&&n!==t&&i.push(`initialBridgeError=${n}`),o&&i.push(`metroCompanionLog=${o}`),i.join(" ")}async function eu(e,t,r){let n=Date.now()+t;for(;Date.now()<n;){let t=Math.min(r,Math.max(n-Date.now(),1));if(await er(e,t))return!0;let o=Math.min(500,Math.max(n-Date.now(),0));o>0&&await ee(o)}return!1}async function ec(e){let t=Date.now()+e.startupTimeoutMs,r=null,n=null;for(;Date.now()<t;){try{let t=await es({baseUrl:e.baseUrl,bearerToken:e.bearerToken,scope:e.scope,runtime:e.runtime,timeoutMs:e.probeTimeoutMs});if(!1!==t.probe.reachable)return t;r=t,n=null}catch(e){if(n=e instanceof Error?e.message:String(e),!ea(e))break}let o=Math.min(1e3,Math.max(t-Date.now(),0));o>0&&await ee(o)}throw Error(el(e.baseUrl,n,r,e.initialBridgeError,e.companionLogPath))}async function ed(r){let n=`http://${r.statusHost}:${r.metroPort}/status`;if(r.reuseExisting&&await er(n,r.probeTimeoutMs))return{started:!1,reused:!0,pid:0,statusUrl:n};let i=function(r,n,i,a,s,l){let u="expo"===n?{command:"npx",installArgs:["expo","start","--host","lan","--port",String(i)]}:{command:"npx",installArgs:["react-native","start","--host",a,"--port",String(i)]};e.mkdirSync(t.dirname(s),{recursive:!0});let c=e.openSync(s,"a"),d=0;try{d=o(u.command,u.installArgs,{cwd:r,env:l,stdio:["ignore",c,c]})}finally{e.closeSync(c)}if(!Number.isInteger(d)||d<=0)throw Error("Failed to start Metro. Expected a detached child PID.");return{pid:d}}(r.projectRoot,r.kind,r.metroPort,r.listenHost,r.logPath,r.env);if(await eu(n,r.startupTimeoutMs,r.probeTimeoutMs))return{started:!0,reused:!1,pid:i.pid,statusUrl:n};throw await en(i.pid).catch(()=>{}),Error(`Metro did not become ready at ${n} within ${r.startupTimeoutMs}ms. Check ${r.logPath}.`)}async function ep(e,t){let r=t.bridgeScope;if(!r)return null;let n=null,o=null;try{n=await es({baseUrl:t.proxyBaseUrl,bearerToken:t.proxyBearerToken,scope:r,timeoutMs:t.probeTimeoutMs})}catch(e){if(!ea(e))throw e;o=e instanceof Error?e.message:String(e)}n&&!1!==n.probe.reachable||(n=await em(e,t,r,n,o));var i=t.proxyBaseUrl,a=n;if(!a?.iosRuntime.bundleUrl)throw Error(el(i,"bridge descriptor is missing ios_runtime.metro_bundle_url",a));return n}async function em(e,t,r,n,o){let i;try{i=(await F({projectRoot:t.projectRoot,serverBaseUrl:t.proxyBaseUrl,bearerToken:t.proxyBearerToken,bridgeScope:r,localBaseUrl:`http://${t.statusHost}:${t.metroPort}`,launchUrl:q(e.launchUrl),profileKey:q(e.companionProfileKey),consumerKey:q(e.companionConsumerKey),env:t.env})).logPath}catch(e){throw Error(el(t.proxyBaseUrl,e instanceof Error?e.message:String(e),n,o))}try{return await ec({baseUrl:t.proxyBaseUrl,bearerToken:t.proxyBearerToken,scope:r,probeTimeoutMs:t.probeTimeoutMs,startupTimeoutMs:t.startupTimeoutMs,initialBridgeError:o,companionLogPath:i})}catch(e){throw e instanceof Error?e:Error(String(e))}}async function eh(r={}){var n,o;let a=function(r){let n=r.env??process.env,o=process.cwd(),i=W(r.projectRoot??o,n,o),a=V(r.publicBaseUrl),s=V(r.proxyBaseUrl);if(!a&&!s)throw new M("INVALID_ARGS","metro prepare requires --public-base-url <url> or --proxy-base-url <url>.");let{proxyEnabled:l,proxyBaseUrl:u,proxyBearerToken:c}=function(e,t,r){let n=t||q(r.AGENT_DEVICE_METRO_BEARER_TOKEN)||"",o=n||e&&q(r.AGENT_DEVICE_DAEMON_AUTH_TOKEN)||"";if(e&&!o)throw new M("INVALID_ARGS","metro prepare requires proxy auth when --proxy-base-url is provided. Pass --bearer-token or set AGENT_DEVICE_METRO_BEARER_TOKEN or AGENT_DEVICE_DAEMON_AUTH_TOKEN.");if(!e&&n)throw new M("INVALID_ARGS","metro prepare requires --proxy-base-url when proxy auth is provided.");return{proxyEnabled:!!(e&&o),proxyBaseUrl:e,proxyBearerToken:o}}(s,q(r.proxyBearerToken)??"",n);return{env:n,projectRoot:i,kind:function(r,n){if("auto"!==n)return n;let o=function(r){let n=t.join(r,"package.json");if(!z(n))throw new M("INVALID_ARGS",`package.json not found at ${n}`);return JSON.parse(e.readFileSync(n,"utf8"))}(r);return"string"==typeof({...o.dependencies??{},...o.devDependencies??{}}).expo?"expo":"react-native"}(i,r.kind??"auto"),metroPort:X(r.metroPort??8081,8081),listenHost:q(r.listenHost)??"0.0.0.0",statusHost:q(r.statusHost)??"127.0.0.1",publicBaseUrl:a,proxyBaseUrl:u,proxyBearerToken:c,bridgeScope:l?function(e){if(!e?.tenantId||!e.runId||!e.leaseId)throw new M("INVALID_ARGS","metro prepare with proxy requires tenantId, runId, and leaseId bridge scope.");return e}(r.bridgeScope):null,startupTimeoutMs:Q(r.startupTimeoutMs,18e4,3e4),probeTimeoutMs:Q(r.probeTimeoutMs,1e4,1e3),reuseExisting:r.reuseExisting??!0,installProjectDeps:r.installDependenciesIfNeeded??!0,runtimeFilePath:r.runtimeFilePath?W(r.runtimeFilePath,n,o):null,logPath:W(r.logPath??t.join(i,".agent-device","metro.log"),n,o)}}(r),s=a.installProjectDeps?function(r,n){if(function(t){try{return e.statSync(t).isDirectory()}catch{return!1}}(t.join(r,"node_modules")))return{installed:!1};let o=z(t.join(r,"pnpm-lock.yaml"))?{command:"pnpm",installArgs:["install"]}:z(t.join(r,"yarn.lock"))?{command:"yarn",installArgs:["install"]}:{command:"npm",installArgs:["install"]};return i(o.command,o.installArgs,{cwd:r,env:n}),{installed:!0,packageManager:o.command}}(a.projectRoot,a.env):{installed:!1},l=await ed(a),{baseIosRuntime:u,baseAndroidRuntime:c}={baseIosRuntime:(n=a.publicBaseUrl)?Y(n,"ios"):{platform:"ios"},baseAndroidRuntime:n?Y(n,"android"):{platform:"android"}},d=await ep(r,a),p=d?.iosRuntime??u,m=d?.androidRuntime??c,h={projectRoot:a.projectRoot,kind:a.kind,dependenciesInstalled:s.installed,packageManager:s.packageManager??null,started:l.started,reused:l.reused,pid:l.pid,logPath:a.logPath,statusUrl:l.statusUrl,runtimeFilePath:a.runtimeFilePath,iosRuntime:p,androidRuntime:m,bridge:d};return o=a.runtimeFilePath,o&&(e.mkdirSync(t.dirname(o),{recursive:!0}),e.writeFileSync(o,JSON.stringify(h,null,2))),h}async function ef(e={}){let t=Q(e.timeoutMs,1e4,1e3),r=function(e){var t;let r,n=q(e.bundleUrl),o=n??e.runtime?.bundleUrl,i=!!n,a=!!q(o),s=l({metroHost:q(e.metroHost)??(i?void 0:q(e.runtime?.metroHost))??(a?void 0:"localhost"),metroPort:void 0!==e.metroPort?X(e.metroPort,8081):i?void 0:e.runtime?.metroPort??(a?void 0:8081),bundleUrl:o});if(!s)throw new M("INVALID_ARGS","Unable to resolve Metro host and port for reload.");return t=function(e){let t=q(e);if(!t)return"/reload";let r=new URL(t).pathname.replace(/\/+$/,"");return r.endsWith("/index.bundle")?`${r.slice(0,-13)}/reload`:"/reload"}(o),(r=new URL(`${s.scheme}://localhost`)).hostname=s.host,r.port=String(s.port),r.pathname=t,r.toString()}(e),n=await et(r,t);if(!n.ok)throw new M("COMMAND_FAILED",`Metro reload failed (${n.status}).`,{reloadUrl:r,status:n.status,body:n.body,hint:"Verify Metro is running and the target React Native app is connected to this Metro instance."});return{reloaded:!0,reloadUrl:r,status:n.status,body:n.body}}export{Y as buildMetroRuntimeHints,O as ensureCompanionTunnel,F as ensureMetroCompanion,eh as prepareMetroRuntime,ef as reloadMetro,L as stopCompanionTunnel,J as stopMetroCompanion};
@@ -0,0 +1 @@
1
+ import{AsyncLocalStorage as t}from"node:async_hooks";import{constants as e}from"node:fs";import{access as r,stat as n}from"node:fs/promises";import o from"node:path";import{spawn as i,spawnSync as u}from"node:child_process";import{Readable as d}from"node:stream";import{pipeline as s}from"node:stream/promises";import{AppError as a}from"./733.js";let f=/^[A-Za-z0-9][A-Za-z0-9._+-]*$/,c=[".com",".exe",".bat",".cmd"],l=new t;async function m(t,e){return t?await l.run(t,e):await e()}async function p(t){return await l.run(void 0,t)}async function w(t,e,r={}){let n=l.getStore()?.(t,e,r);return n?await n:await v(t,e,r)}async function h(t,e,r={}){let n=l.getStore()?.(t,e,r);return n?await n:await v(t,e,r)}function v(t,e,r={}){let n=O(t);return new Promise((o,u)=>{let d=i(n,e,{cwd:r.cwd,env:r.env,stdio:["pipe","pipe","pipe"],detached:r.detached,windowsHide:!0,shell:!1});r.onSpawn?.(d);let s="",f=r.binaryStdout?[]:void 0,c="",l=!1,m=P(r.timeoutMs),p=m?setTimeout(()=>{l=!0,H(d,r.detached)},m):null,w=B(d,r);r.binaryStdout||d.stdout.setEncoding("utf8"),d.stderr.setEncoding("utf8"),G(d,r.stdin).catch(o=>{var i,s,f,c;w.didAbort||l||(i=o)instanceof Error&&"code"in i&&"EPIPE"===i.code||(u((s=n,f=t,new a("COMMAND_FAILED",`Failed to write stdin for ${s}`,{cmd:f,args:e},(c=o)instanceof Error?c:void 0))),H(d,r.detached))}),d.stdout.on("data",t=>{if(r.binaryStdout)return void f?.push(Buffer.isBuffer(t)?t:Buffer.from(t));let e=String(t);s+=e,r.onStdoutChunk?.(e)}),d.stderr.on("data",t=>{let e=String(t);c+=e,r.onStderrChunk?.(e)}),d.on("error",r=>{p&&clearTimeout(p),w.dispose(),u(L(w,n,t,e,r))}),d.on("close",i=>{p&&clearTimeout(p),w.dispose();let d=i??1;if(!w.didAbort&&l&&m){var h,v,A,S,b,E;return void u((h=n,v=t,A=e,S=m,b=d,E=s,new a("COMMAND_FAILED",`${h} timed out after ${S}ms`,{cmd:v,args:A,stdout:E,stderr:c,exitCode:b,timeoutMs:S})))}let g=N(w,n,t,e,d,r.allowFailure,s,c);g?u(g):o({stdout:s,stderr:c,exitCode:d,stdoutBuffer:f?Buffer.concat(f):void 0})})})}async function A(t){let e=D(t);if(!e)return!1;if(o.isAbsolute(e))return F(e);let r=process.env.PATH;if(!r)return!1;let n=function(){if("win32"!==process.platform)return[""];let t=process.env.PATHEXT;if(!t)return c;let e=t.split(";").map(t=>t.trim().toLowerCase()).filter(t=>t.length>0);return e.length>0?e:c}();for(let t of r.split(o.delimiter)){let r=t.trim();if(r){for(let t of function(t,e){if("win32"!==process.platform)return[t];let r=t.toLowerCase();return e.some(t=>r.endsWith(t))?[t]:e.map(e=>`${t}${e}`)}(e,n))if(await F(o.join(r,t)))return!0}}return!1}async function S(t,e){let r=x(t,e,"executable");if(r){if(!await F(r))throw new a("TOOL_MISSING",`${e} points to a missing or non-executable file: ${r}`,{envName:e,path:r});return r}}async function b(t,e){let r=x(t,e,"file");if(r){if(!await T(r))throw new a("TOOL_MISSING",`${e} points to a missing or non-file path: ${r}`,{envName:e,path:r});return r}}function E(t,e,r={}){let n=O(t),o=u(n,e,{cwd:r.cwd,env:r.env,stdio:["pipe","pipe","pipe"],encoding:r.binaryStdout?void 0:"utf8",input:r.stdin,timeout:P(r.timeoutMs),windowsHide:!0,shell:!1,...void 0!==r.maxBuffer?{maxBuffer:r.maxBuffer}:{}});if(o.error){let i=o.error.code;if("ETIMEDOUT"===i)throw new a("COMMAND_FAILED",`${n} timed out after ${P(r.timeoutMs)}ms`,{cmd:t,args:e,timeoutMs:P(r.timeoutMs)},o.error);if("ENOENT"===i)throw I(n,t,o.error);throw C(n,t,e,o.error)}let i=r.binaryStdout?Buffer.isBuffer(o.stdout)?o.stdout:Buffer.from(o.stdout??""):void 0,d=r.binaryStdout?"":"string"==typeof o.stdout?o.stdout:(o.stdout??"").toString(),s="string"==typeof o.stderr?o.stderr:(o.stderr??"").toString(),f=o.status??1;if(0!==f&&!r.allowFailure)throw $(n,t,e,f,d,s);return{stdout:d,stderr:s,exitCode:f,stdoutBuffer:i}}function g(t,e,r={}){return y(t,e,r).pid}function y(t,e,r={}){let n=i(O(t),e,{cwd:r.cwd,env:r.env,stdio:r.stdio??"ignore",detached:!0,windowsHide:!0,shell:!1}),o=n.pid??0,u=new Promise(t=>{n.once("error",e=>{t({pid:o,error:e.message})}),n.once("exit",(e,r)=>{t({pid:o,..."number"==typeof e?{exitCode:e}:{},...r?{signal:r}:{}})})});return n.unref(),{pid:o,exited:u}}function M(t,e,r={}){let n=O(t),o=i(n,e,{cwd:r.cwd,env:r.env,stdio:r.stdio??["ignore","pipe","pipe"],detached:r.detached,windowsHide:!0,shell:!1}),u="",d="",s=r.captureOutput??!0,a=B(o,r);s&&(o.stdout?.setEncoding("utf8"),o.stderr?.setEncoding("utf8"),o.stdout?.on("data",t=>{u+=t}),o.stderr?.on("data",t=>{d+=t}));let f=new Promise((i,s)=>{o.on("error",r=>{a.dispose(),s(L(a,n,t,e,r))}),o.on("close",o=>{a.dispose();let f=o??1,c=N(a,n,t,e,f,r.allowFailure,u,d);c?s(c):i({stdout:u,stderr:d,exitCode:f})})});return{child:o,wait:f}}function O(t){let e=D(t);if(!e)throw new a("INVALID_ARGS",`Invalid executable command: ${JSON.stringify(t)}`,{cmd:t,hint:"Use a bare command name from PATH or an absolute executable path."});return e}function I(t,e,r){return new a("TOOL_MISSING",`${t} not found in PATH`,{cmd:e},r)}function C(t,e,r,n){return new a("COMMAND_FAILED",`Failed to run ${t}`,{cmd:e,args:r},n)}function _(t,e,r){return new a("COMMAND_FAILED","request canceled",{cmd:e,args:r,executable:t,reason:"request_canceled"})}function $(t,e,r,n,o,i){return new a("COMMAND_FAILED",`${t} exited with code ${n}`,{cmd:e,args:r,stdout:o,stderr:i,exitCode:n,processExitError:!0})}function L(t,e,r,n,o){return t.didAbort?_(e,r,n):"ENOENT"===o.code?I(e,r,o):C(e,r,n,o)}function N(t,e,r,n,o,i,u,d){return t.didAbort?_(e,r,n):0===o||i?null:$(e,r,n,o,u,d)}function x(t,e,r){let n=t?.trim();if(n){if(!o.isAbsolute(n)||n.includes("\0"))throw new a("INVALID_ARGS",`${e} must be an absolute ${r} path, not ${JSON.stringify(t)}`,{envName:e,path:t});return n}}function D(t){let e=t.trim();return!e||e.includes("\0")?null:o.isAbsolute(e)?e:e.includes("/")||e.includes("\\")?null:f.test(e)?e:null}async function F(t){try{if(!await T(t))return!1;return await r(t,"win32"===process.platform?e.F_OK:e.X_OK),!0}catch{return!1}}async function T(t){try{return(await n(t)).isFile()}catch{return!1}}function P(t){if(!Number.isFinite(t))return;let e=Math.floor(t);if(!(e<=0))return e}function B(t,e){let r=!1,n=()=>{r=!0,H(t,e.detached)};return e.signal?.aborted?n():e.signal?.addEventListener("abort",n,{once:!0}),{get didAbort(){return r},dispose:()=>{e.signal?.removeEventListener("abort",n)}}}function H(t,e){if(e&&t.pid&&"win32"!==process.platform)try{process.kill(-t.pid,"SIGKILL");return}catch{}t.kill("SIGKILL")}async function G(t,e){if(t.stdin){if(void 0===e)return void t.stdin?.end();await s(d.from([e]),t.stdin)}}export{F as isExecutablePath,S as resolveExecutableOverridePath,b as resolveFileOverridePath,w as runCmd,M as runCmdBackground,g as runCmdDetached,y as runCmdDetachedMonitored,h as runCmdStreaming,E as runCmdSync,A as whichCmd,m as withCommandExecutorOverride,p as withoutCommandExecutorOverride};
@@ -0,0 +1,11 @@
1
+ import{COMMON_COMMAND_SUPPORTED_FLAG_KEYS as e,managementCliSchemas as t,perfCliSchemas as o,captureCliSchemas as n,observabilityCliSchemas as s,replayCliSchemas as a,interactionCliSchemas as r,recordingCliSchemas as i,METRO_PREPARE_FLAGS as d,batchCliSchemas as c,systemCliSchemas as l,reactNativeCliSchemas as m}from"./9873.js";import{listCommandMetadata as p,debuggingCliSchemas as u,metroCliSchemas as g}from"./2948.js";let f={auth:{usageOverride:"auth status|login|logout",listUsageOverride:"auth",helpDescription:"Manage cloud login state used by remote daemon and cloud device workflows.",summary:"Manage cloud login state used by remote daemon and cloud device workflows",positionalArgs:["status|login|logout"],supportedFlags:["remoteConfig","stateDir"]},connect:{usageOverride:"connect [--remote-config <path>] [--daemon-base-url <url>] [--tenant <id>] [--run-id <id>] [--lease-id <id>] [--lease-backend <backend>] [--force] [--no-login]",helpDescription:"Connect to a remote daemon, authenticate when needed, and save remote session state. AGENT_DEVICE_CLOUD_BASE_URL is the bridge/control-plane API origin; use AGENT_DEVICE_DAEMON_AUTH_TOKEN=adc_live_... for CI/service-token automation.",listUsageOverride:"connect",summary:"Attach CLI commands to a saved remote daemon/cloud lease; inspect for remote runs, tenants, or service-token CI",allowedFlags:["remoteConfig","daemonBaseUrl","tenant","runId","leaseId","leaseBackend","force","noLogin"],supportedFlags:["stateDir","daemonAuthToken","session","platform",...d,"launchUrl"]},connection:{usageOverride:"connection status",listUsageOverride:"connection",helpDescription:"Inspect active remote connection state",summary:"Inspect the active saved remote connection before assuming commands are local",positionalArgs:["status"],supportedFlags:["remoteConfig","stateDir","session"]},disconnect:{helpDescription:"Disconnect remote daemon state, stop owned Metro companion, and release lease",listUsageOverride:"disconnect",summary:"Clear remote connection state, stop owned Metro companions, and release remote leases",allowedFlags:["shutdown"],supportedFlags:["remoteConfig","stateDir","session"]},mcp:{helpDescription:"Start the official stdio MCP server. It exposes structured command tools backed by the agent-device client.",summary:"Start MCP server"},"react-devtools":{usageOverride:"react-devtools [...args]",listUsageOverride:"react-devtools",helpDescription:"Run pinned agent-react-devtools commands for React Native performance profiling, component trees, props/state/hooks, and render analysis",summary:"Inspect React Native components, props, hooks, errors, slow renders, and rerender profiles",positionalArgs:["args?"],allowsExtraPositionals:!0,supportedFlags:e},web:{usageOverride:"web setup | web doctor",listUsageOverride:"web setup|doctor",helpDescription:`Install and inspect the managed web automation backend used by --platform web.
2
+
3
+ First-run flow:
4
+ agent-device web setup
5
+ agent-device open "https://example.com" --platform web
6
+ agent-device snapshot -i --platform web
7
+ agent-device close --platform web
8
+
9
+ Runtime web commands do not install the backend implicitly. If the managed backend is missing, run agent-device web setup. The backend is resolved only from the managed install in the effective agent-device state dir.
10
+
11
+ Use web setup to install or reuse the pinned backend. Use web doctor after setup to verify browser backend health.`,summary:"Manage web automation backend",positionalArgs:["setup|doctor"],supportedFlags:["stateDir"]}},v={...t,...n,...l,...r,...s,...o,...u,...g,...a,...c,...i,...m},h=new Map(p().map(t=>[t.name,{helpDescription:t.description,supportedFlags:e}]));function b(e){if(e)return C(e)}function w(e){let t=C(e);if(!t)throw Error(`Missing command schema for ${e}`);return t}function C(e){let t=Object.hasOwn(f,e)?f[e]:void 0;if(t)return t;let o=h.get(e),n=Object.hasOwn(v,e)?v[e]:void 0;if(o)return n?{...o,...n}:o}function _(e,t){let o=b(e);if(!o?.defaults)return!1;let n=!1;for(let[e,s]of Object.entries(o.defaults))void 0===t[e]&&(t[e]=s,n=!0);return n}export{_ as applyCommandDefaults,w as getCliCommandSchema,b as getCommandSchema};
@@ -0,0 +1 @@
1
+ import{emitDiagnostic as e}from"./432.js";import{AppError as t}from"./733.js";import{isClipboardShellUnsupported as i}from"./3340.js";import{resolveAndroidAdbExecutor as n}from"./2954.js";import{sleep as r}from"./5560.js";let o=new Set(["com.google.android.inputmethod.latin","com.samsung.android.honeyboard","com.touchtype.swiftkey","com.microsoft.swiftkey"]);function a(e){let t=u(e.packageName),i=(e.resourceId??"").toLowerCase(),n=u(e.activeInputMethodPackage);if(t&&n&&t===n)return{inputMethodOwned:!0,source:"active-input-method"};if(n&&i.startsWith(`${n}:id/`))return{inputMethodOwned:!0,source:"active-input-method-resource"};if(t&&o.has(t))return{inputMethodOwned:!0,source:"known-ime-package"};for(let e of o)if(i.startsWith(`${e}:id/`))return{inputMethodOwned:!0,source:"known-ime-resource"};return{inputMethodOwned:!1,source:"app"}}function d(e){return a(e).inputMethodOwned}function u(e){return(e??"").trim().toLowerCase()||void 0}let s=["mInputShown","mIsInputViewShown","isInputViewShown","mDecorViewVisible","mWindowVisible","mInShowWindow"],c=new Map([[2,"number"],[3,"phone"],[4,"datetime"]]),l=new Set([32,208]),p=new Set([128,224,144]);async function w(e){return await f(n(e))}async function f(i){var n,r,d;let w,f,m,h,_,I,y,C,g=await i(["shell","dumpsys","input_method"],{allowFailure:!0});if(0!==g.exitCode)throw new t("COMMAND_FAILED","Failed to query Android keyboard state",{stdout:g.stdout,stderr:g.stderr,exitCode:g.exitCode});return f=function(e){var t=function(e,t){let i=new Map,n=RegExp(`\\b(${t.join("|")})=([a-zA-Z]+)\\b`,"g");for(let t of e.matchAll(n)){let e=t[1],n=t[2]?.toLowerCase();e&&("true"===n||"false"===n)&&i.set(e,"true"===n)}return i}(e,s);if(0===t.size)return null;let i=A(t,["mWindowVisible","mDecorViewVisible","mInShowWindow"]);if(void 0!==i)return i;let n=t.get("mInputShown");return void 0!==n?n:A(t,["mIsInputViewShown","isInputViewShown"])??null}(n=g.stdout)??function(e){let t=e.match(/\bmImeWindowVis=0x([0-9a-fA-F]+)\b/),i=t?.[1];if(!i)return null;let n=Number.parseInt(i,16);return Number.isNaN(n)?null:(1&n)!=0}(n),m=(w=b(n,/\binputType=0x([0-9a-fA-F]+)\b/gi))?`0x${w.toLowerCase()}`:void 0,h=b(n,/\bpackageName=([A-Za-z0-9_.]+)\b/g),_=b(n,/\b(?:resourceId|resource-id)=([^\s,}]+)/g),y=function(e,t,i){return e||t?a({packageName:e,resourceId:t,activeInputMethodPackage:i}).inputMethodOwned?"ime":"app":"unknown"}(h,_,I=function(e){for(let t of[/\bmCurMethodId=([^\s]+)/i,/\bmCurId=([^\s]+)/i,/\bmCurrentInputMethodId=([^\s]+)/i,/\bcurMethodId=([^\s]+)/i]){let i=e.match(t),n=function(e){let t=(e??"").trim();if(!t)return;let i=(t.split("/")[0]??"").match(/[a-zA-Z0-9_.]+/);return u(i?.[0])}(i?.[1]);if(n)return n}}(n)),r=h,d=_,!I&&((C=u(r))&&o.has(C)||function(e){let t=(e??"").toLowerCase();for(let e of o)if(t.startsWith(`${e}:id/`))return!0;return!1}(d))&&e({level:"warn",phase:"android_input_ownership_fallback",data:{focusedPackage:r,focusedResourceId:d}}),{visible:f??!1,inputType:m,type:m?function(e){let t=Number.parseInt(e.replace(/^0x/i,""),16);if(Number.isNaN(t))return"unknown";let i=15&t,n=c.get(i);if(n)return n;if(1!==i)return"unknown";let r=4080&t;return l.has(r)?"email":p.has(r)?"password":"text"}(m):void 0,inputMethodPackage:I,focusedPackage:h,focusedResourceId:_,inputOwner:y}}async function m(e){return await h(n(e))}async function h(e){let i=await f(e),n=i,o=0;for(;n.visible&&o<2;)await e(["shell","input","keyevent","111"]),o+=1,await r(120),n=await f(e);if(i.visible&&n.visible)throw new t("UNSUPPORTED_OPERATION","Android keyboard dismiss is unavailable for the current IME without back navigation.",{attempts:o,inputType:n.inputType,type:n.type,inputMethodPackage:n.inputMethodPackage,focusedPackage:n.focusedPackage,focusedResourceId:n.focusedResourceId,inputOwner:n.inputOwner});return{attempts:o,wasVisible:i.visible,dismissed:i.visible&&!n.visible,visible:n.visible,inputType:n.inputType,type:n.type,inputMethodPackage:n.inputMethodPackage,focusedPackage:n.focusedPackage,focusedResourceId:n.focusedResourceId,inputOwner:n.inputOwner}}function b(e,t){let i;for(let n of e.matchAll(t))i=n[1];return i}function A(e,t){for(let i of t){let t=e.get(i);if(void 0!==t)return t}}async function _(e){return await I(n(e))}async function I(e){let t,i;return(i=(t=(await g(e,["shell","cmd","clipboard","get","text"],"read")).replace(/\r\n/g,"\n").replace(/\n$/,"")).match(/^clipboard text:\s*(.*)$/i))?i[1]??"":"null"===t.trim().toLowerCase()?"":t}async function y(e,t){await C(n(e),t)}async function C(e,t){await g(e,["shell","cmd","clipboard","set","text",t],"write")}async function g(e,n,r){let o=await e(n,{allowFailure:!0});if(i(o.stdout,o.stderr))throw new t("UNSUPPORTED_OPERATION",`Android shell clipboard ${r} is not supported on this device.`);if(0!==o.exitCode)throw new t("COMMAND_FAILED",`Failed to ${r} Android clipboard text`,{stdout:o.stdout,stderr:o.stderr,exitCode:o.exitCode});return o.stdout}export{m as dismissAndroidKeyboard,h as dismissAndroidKeyboardWithAdb,w as getAndroidKeyboardState,f as getAndroidKeyboardStatusWithAdb,d as isAndroidInputMethodOwnedNode,_ as readAndroidClipboardText,I as readAndroidClipboardWithAdb,y as writeAndroidClipboardText,C as writeAndroidClipboardWithAdb};