agent-device 0.18.0 → 0.18.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (159) hide show
  1. package/README.md +3 -2
  2. package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.18.0.apk → agent-device-android-multitouch-helper-0.18.2.apk} +0 -0
  3. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.18.2.apk.sha256 +1 -0
  4. package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.18.0.manifest.json → agent-device-android-multitouch-helper-0.18.2.manifest.json} +4 -4
  5. package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.18.0.apk → agent-device-android-snapshot-helper-0.18.2.apk} +0 -0
  6. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.18.2.apk.sha256 +1 -0
  7. package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.18.0.manifest.json → agent-device-android-snapshot-helper-0.18.2.manifest.json} +6 -6
  8. package/apple-runner/AgentDeviceRunner/AgentDeviceRunner/AgentDeviceRunnerApp.m +156 -0
  9. package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/project.pbxproj +10 -16
  10. package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +2 -0
  11. package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +3 -1
  12. package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +2 -0
  13. package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+FlatSnapshotFiltering.swift +2 -4
  14. package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +9 -36
  15. package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollGesture.swift +2 -0
  16. package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SequenceExecution.swift +2 -0
  17. package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +2 -0
  18. package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +2 -0
  19. package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +0 -1
  20. package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +2 -1
  21. package/dist/src/1986.js +1 -0
  22. package/dist/src/2748.js +1 -1
  23. package/dist/src/2948.js +21 -21
  24. package/dist/src/314.js +1 -1
  25. package/dist/src/3340.js +8 -7
  26. package/dist/src/4418.js +1 -1
  27. package/dist/src/4428.js +3 -3
  28. package/dist/src/485.js +1 -0
  29. package/dist/src/495.js +5 -0
  30. package/dist/src/5484.js +1 -1
  31. package/dist/src/587.js +1 -1
  32. package/dist/src/5913.js +4 -0
  33. package/dist/src/6849.js +1 -0
  34. package/dist/src/6918.js +1 -1
  35. package/dist/src/6967.js +1 -0
  36. package/dist/src/760.js +1 -0
  37. package/dist/src/7871.js +1 -0
  38. package/dist/src/8184.js +1 -1
  39. package/dist/src/8225.js +1 -1
  40. package/dist/src/8391.js +1 -0
  41. package/dist/src/8404.js +2 -0
  42. package/dist/src/8414.js +2 -0
  43. package/dist/src/8875.js +4 -1
  44. package/dist/src/8936.js +1 -1
  45. package/dist/src/9581.js +3 -3
  46. package/dist/src/9624.js +1 -1
  47. package/dist/src/9722.js +37 -32
  48. package/dist/src/android-adb.d.ts +19 -54
  49. package/dist/src/android-adb.js +1 -1
  50. package/dist/src/android.js +5 -5
  51. package/dist/src/apps.js +9 -11
  52. package/dist/src/audio-probe.js +1 -0
  53. package/dist/src/batch.d.ts +34 -26
  54. package/dist/src/batch.js +1 -1
  55. package/dist/src/cli-help.js +61 -9
  56. package/dist/src/cli.js +34 -22
  57. package/dist/src/contracts.d.ts +33 -123
  58. package/dist/src/contracts.js +1 -1
  59. package/dist/src/debug-symbols.js +3 -0
  60. package/dist/src/devices.js +1 -1
  61. package/dist/src/devices~1.js +1 -1
  62. package/dist/src/devices~2.js +1 -1
  63. package/dist/src/find.js +1 -1
  64. package/dist/src/finders.d.ts +2 -6
  65. package/dist/src/finders.js +1 -1
  66. package/dist/src/generic.js +1 -9
  67. package/dist/src/handler-utils.js +1 -0
  68. package/dist/src/index.d.ts +474 -180
  69. package/dist/src/index.js +1 -1
  70. package/dist/src/input-actions.js +1 -1
  71. package/dist/src/input-actions~1.js +1 -1
  72. package/dist/src/install-source.d.ts +0 -26
  73. package/dist/src/install-source.js +1 -1
  74. package/dist/src/interaction.js +1 -1
  75. package/dist/src/interactor.js +1 -0
  76. package/dist/src/internal/bin.js +1 -1
  77. package/dist/src/internal/companion-tunnel.js +1 -1
  78. package/dist/src/internal/png-worker.js +1 -1
  79. package/dist/src/lease.js +1 -1
  80. package/dist/src/linux.js +1 -1
  81. package/dist/src/metro.d.ts +10 -134
  82. package/dist/src/metro.js +1 -1
  83. package/dist/src/notifications.js +1 -1
  84. package/dist/src/react-native.js +1 -1
  85. package/dist/src/record-trace-recording.js +3 -3
  86. package/dist/src/record-trace.js +1 -1
  87. package/dist/src/remote-config.d.ts +15 -17
  88. package/dist/src/remote-config.js +1 -1
  89. package/dist/src/runner-sequence.js +1 -0
  90. package/dist/src/selector-runtime.js +1 -1
  91. package/dist/src/selectors.d.ts +15 -7
  92. package/dist/src/selectors.js +1 -1
  93. package/dist/src/server.js +2 -2
  94. package/dist/src/session.js +11 -11
  95. package/dist/src/simulator.js +2 -2
  96. package/dist/src/snapshot.js +2 -2
  97. package/dist/src/web.js +1 -1
  98. package/macos-helper/Sources/AgentDeviceMacOSHelper/AudioProbe.swift +297 -0
  99. package/macos-helper/Sources/AgentDeviceMacOSHelper/main.swift +30 -0
  100. package/package.json +15 -11
  101. package/server.json +2 -2
  102. package/android-multitouch-helper/README.md +0 -41
  103. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.18.0.apk.sha256 +0 -1
  104. package/android-snapshot-helper/README.md +0 -88
  105. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.18.0.apk.sha256 +0 -1
  106. package/dist/src/1848.js +0 -4
  107. package/dist/src/2577.js +0 -1
  108. package/dist/src/2954.js +0 -2
  109. package/dist/src/4291.js +0 -1
  110. package/dist/src/432.js +0 -4
  111. package/dist/src/4723.js +0 -1
  112. package/dist/src/5341.js +0 -1
  113. package/dist/src/5910.js +0 -2
  114. package/dist/src/6024.js +0 -1
  115. package/dist/src/733.js +0 -1
  116. package/dist/src/7394.js +0 -6
  117. package/dist/src/8275.js +0 -2
  118. package/dist/src/9919.js +0 -6
  119. package/dist/src/android-snapshot-helper.d.ts +0 -359
  120. package/dist/src/android-snapshot-helper.js +0 -1
  121. package/dist/src/apple.js +0 -1
  122. package/dist/src/device-ready.js +0 -2
  123. package/ios-runner/AgentDeviceRunner/AgentDeviceRunner/AgentDeviceRunnerApp.swift +0 -17
  124. package/ios-runner/AgentDeviceRunner/AgentDeviceRunner/Assets.xcassets/AccentColor.colorset/Contents.json +0 -11
  125. package/ios-runner/AgentDeviceRunner/AgentDeviceRunner/Assets.xcassets/AppIcon.appiconset/Contents.json +0 -36
  126. package/ios-runner/AgentDeviceRunner/AgentDeviceRunner/Assets.xcassets/AppIcon.appiconset/logo.jpg +0 -0
  127. package/ios-runner/AgentDeviceRunner/AgentDeviceRunner/Assets.xcassets/Contents.json +0 -6
  128. package/ios-runner/AgentDeviceRunner/AgentDeviceRunner/Assets.xcassets/Logo.imageset/Contents.json +0 -21
  129. package/ios-runner/AgentDeviceRunner/AgentDeviceRunner/Assets.xcassets/Logo.imageset/logo.jpg +0 -0
  130. package/ios-runner/AgentDeviceRunner/AgentDeviceRunner/Assets.xcassets/PoweredBy.imageset/Contents.json +0 -21
  131. package/ios-runner/AgentDeviceRunner/AgentDeviceRunner/Assets.xcassets/PoweredBy.imageset/powered-by.png +0 -0
  132. package/ios-runner/AgentDeviceRunner/AgentDeviceRunner/ContentView.swift +0 -34
  133. package/ios-runner/README.md +0 -53
  134. package/ios-runner/RUNNER_PROTOCOL.md +0 -76
  135. /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -0
  136. /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/xcshareddata/xcschemes/AgentDeviceRunner.xcscheme +0 -0
  137. /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/AgentDeviceRunnerUITests-Bridging-Header.h +0 -0
  138. /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/AgentDeviceRunnerUITests.entitlements +0 -0
  139. /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.h +0 -0
  140. /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.m +0 -0
  141. /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerObjCExceptionCatcher.h +0 -0
  142. /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerObjCExceptionCatcher.m +0 -0
  143. /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.h +0 -0
  144. /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.m +0 -0
  145. /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Alert.swift +0 -0
  146. /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Environment.swift +0 -0
  147. /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Exceptions.swift +0 -0
  148. /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +0 -0
  149. /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +0 -0
  150. /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScreenRecorder.swift +0 -0
  151. /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SystemModal.swift +0 -0
  152. /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Transport.swift +0 -0
  153. /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TvRemote.swift +0 -0
  154. /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests.xctestplan +0 -0
  155. /package/{ios-runner → apple-runner}/AgentDeviceRunner/RecordingScripts/recording-overlay.swift +0 -0
  156. /package/{ios-runner → apple-runner}/AgentDeviceRunner/RecordingScripts/recording-resize.swift +0 -0
  157. /package/{ios-runner → apple-runner}/AgentDeviceRunner/RecordingScripts/recording-trim.swift +0 -0
  158. /package/dist/src/{4069.js → 4917.js} +0 -0
  159. /package/dist/src/{9836.js → 893.js} +0 -0
package/dist/src/index.js CHANGED
@@ -1 +1 @@
1
- export{AppError,isAgentDeviceError,normalizeAgentDeviceError}from"./733.js";export{centerOfRect}from"./4291.js";export{createAgentDeviceClient}from"./9919.js";export{createLocalArtifactAdapter}from"./314.js";
1
+ export{AppError,isAgentDeviceError,normalizeAgentDeviceError}from"./485.js";export{centerOfRect}from"./6849.js";export{createAgentDeviceClient}from"./495.js";export{createLocalArtifactAdapter}from"./314.js";
@@ -1 +1 @@
1
- import{emitDiagnostic as t}from"./432.js";import{runAndroidAdb as e}from"./3340.js";import{getAndroidKeyboardState as n,isAndroidInputMethodOwnedNode as a}from"./9624.js";import{captureAndroidUiHierarchyXml as r}from"./9722.js";import{androidUiNodes as i}from"./7394.js";import{AppError as o}from"./733.js";import{buildScrollGesturePlan as u}from"./2948.js";import{resolveAndroidTextInjector as l}from"./2954.js";import{sleep as c}from"./5560.js";function s(t){var e;return!!t&&(!!t.password||!!(e=t.text)&&Array.from(e).every(f))}function d(t){if(!t)return null;let e=s(t);return{...t,text:e?null:t.text,...e?{textRedacted:!0}:{}}}function f(t){return"•"===t||"*"===t||"●"===t}async function p(t,e,n,a){let r=null,i=null,o=await y(t);for(let u of[0,150,350]){u>0&&await c(u);let l=await g(t,e,n,a,o);if(r=l,"ime_capture"===l.reason)return l;i=l.ok?l:null}return i??r??{ok:!1,actual:null,reason:"text_mismatch",targetInput:null,actualInput:null}}async function h(t,e,n){var a,i,o;return a=await r(t),i=e,o=n,m(a,i,o).actualInput?.text??null}async function g(t,e,n,a,i){return function(t,e,n,a,r={}){var i,o;let u,l=m(t,e,n,r);return!function(t){let{targetInput:e,actualInput:n}=t;return!!e&&!!n&&n!==e&&n.inputMethodOwned&&!e.inputMethodOwned}(l)?function(t,e){let n=t.actualInput;if(!n||!s(n))return null;let a=n.text??null,r=Array.from(a??"").length,i=Array.from(e).length,o=null!==a&&r>0&&i>0&&r===i;return{ok:o,actual:a,reason:o?void 0:"masked_unverified",masked:!0,targetInput:t.targetInput,actualInput:n}}(l,a)??(i=l,o=a,{ok:function(t,e){if(t===e)return!0;let n=w(t),a=w(e);return!!n&&!!a&&!!(n===a||function(t,e){if(t.length!==e.length||0===t.length||t.slice(1)!==e.slice(1))return!1;let n=t[0],a=e[0];return!!n&&!!a&&a.toLowerCase()===a&&n===a.toUpperCase()}(n,a))}(u=i.actualInput?.text??null,o),actual:u,reason:"text_mismatch",targetInput:i.targetInput,actualInput:i.actualInput}):{ok:!1,actual:l.actualInput?.text??null,reason:"ime_capture",targetInput:l.targetInput,actualInput:l.actualInput}}(await r(t),e,n,a,i)}function m(t,e,n,r={}){var o;let u,l={focusedEdit:null,editAtPoint:null,anyAtPoint:null};for(let o of i(t)){let t=function(t,e){if(!t.rect)return null;let n=t.text??"",r=Math.max(1,t.rect.width*t.rect.height);return{text:n||null,className:t.className,resourceId:t.resourceId,packageName:t.packageName,rect:t.rect,focused:t.focused??!1,password:!0===t.password,inputMethodOwned:a({packageName:t.packageName,resourceId:t.resourceId,activeInputMethodPackage:e.activeInputMethodPackage}),area:r,editText:function(t){let e=t.toLowerCase();return e.includes("edittext")||e.includes("textfield")}(t.className??"")}}(o,r);t&&function(t,e,n,a){var r,i,o;let u=(r=e.rect,i=n,o=a,i>=r.x&&i<=r.x+r.width&&o>=r.y&&o<=r.y+r.height);if(u&&e.editText&&(t.editAtPoint=_(t.editAtPoint,e)),e.focused&&e.editText){t.focusedEdit=_(t.focusedEdit,e);return}u&&e.text&&(t.anyAtPoint=_(t.anyAtPoint,e))}(l,t,e,n)}return{targetInput:u=(o=l).editAtPoint??o.anyAtPoint,actualInput:(o.focusedEdit?.text?o.focusedEdit:null)??u}}function w(t){return(t??"").replace(/\s+/g," ").trim()}async function y(e){try{return{activeInputMethodPackage:(await n(e)).inputMethodPackage}}catch(e){return t({level:"warn",phase:"android_fill_verification_input_method_probe_failed",data:{error:e instanceof Error?e.message:String(e)}}),{}}}function _(t,e){return t&&t.area<e.area?t:e}async function A(t,n,a){await e(t,["shell","input","tap",String(n),String(a)])}async function x(t,n,a,r,i,o=250){await e(t,["shell","input","swipe",String(n),String(a),String(r),String(i),String(o)])}async function I(t){await e(t,["shell","input","keyevent","4"])}async function M(t){await e(t,["shell","input","keyevent","3"])}async function S(t){await e(t,["shell","input","keyevent","ENTER"])}async function k(t,n){let a=function(t){switch(t){case"portrait":return"0";case"landscape-left":return"1";case"portrait-upside-down":return"2";case"landscape-right":return"3";default:throw new o("INVALID_ARGS",`Unsupported Android rotation: ${t}`)}}(n);await e(t,["shell","settings","put","system","accelerometer_rotation","0"]),await e(t,["shell","settings","put","system","user_rotation",a])}async function E(t){await e(t,["shell","input","keyevent","187"])}async function v(t,n,a,r=800){await e(t,["shell","input","swipe",String(n),String(a),String(n),String(a),String(r)])}async function C(t,e,n=0){let a=l(t);if(a){await a({action:"type",text:e,delayMs:n}),T("type","provider-native",e);return}(z(e),await D(t,"type"),n>0&&Array.from(e).length>1)?await L(t,{action:"type",text:e,chunkSize:1,delayMs:n}):await L(t,{action:"type",text:e,chunkSize:O,delayMs:0})}async function P(t,e,n){await A(t,e,n)}async function N(t,e,n,a,r=0){let i=l(t);if(i){await i({action:"fill",target:{x:e,y:n},text:a,delayMs:r}),T("fill","provider-native",a);let o=await p(t,e,n,a);if(o.ok)return;b(a,o)}z(a);let o=Array.from(a).length,u=null;for(let i of[{clearPadding:12,minClear:8,maxClear:48,chunkSize:r>0?1:O,inputDelayMs:r},{clearPadding:24,minClear:16,maxClear:96,chunkSize:r>0?1:4,inputDelayMs:r>0?r:15}]){var c,s;await P(t,e,n),await D(t,"fill");let r=(c=o+i.clearPadding,s=i.minClear,Math.max(s,Math.min(i.maxClear,c)));await F(t,r),await L(t,{action:"fill",text:a,chunkSize:i.chunkSize,delayMs:i.inputDelayMs});let l=await p(t,e,n,a);if(u=l,l.ok)return;"ime_capture"===l.reason&&b(a,l)}b(a,u)}function b(t,e){let n;throw new o("COMMAND_FAILED",e?.reason==="ime_capture"?"Android fill input was captured by the active keyboard instead of the app field":e?.reason==="masked_unverified"?"Android fill verification could not confirm masked text value":"Android fill verification failed",(n=function(t,e){var n;if(!e)return{expected:t,actual:null,failureReason:"text_mismatch",targetInput:null,actualInput:null};let a=!0===(n=e).masked||s(n.targetInput)||s(n.actualInput),r={failureReason:e.reason??"text_mismatch",targetInput:d(e.targetInput),actualInput:d(e.actualInput)};return a?{...r,expectedLength:Array.from(t).length,actual:null,masked:!0,actualLength:Array.from(e.actual??"").length}:{...r,expected:t,actual:e.actual}}(t,e),e?.reason==="ime_capture"&&(n.hint="The focused input belongs to the Android keyboard/IME, not the app field. Disable handwriting/stylus input or switch to a standard IME, then retry fill."),n))}async function K(t,n,a){let r=await R(t),i=u({direction:n,amount:a?.amount,pixels:a?.pixels,referenceWidth:r.width,referenceHeight:r.height}),o=a?.durationMs??300;return await e(t,["shell","input","swipe",String(i.x1),String(i.y1),String(i.x2),String(i.y2),String(o)]),{...i,...a?.durationMs!==void 0?{durationMs:a.durationMs}:{}}}async function D(e,a){let r;try{r=await n(e)}catch(e){t({level:"warn",phase:"android_input_ownership_probe_failed",data:{action:a,error:e instanceof Error?e.message:String(e)}});return}if("ime"===r.inputOwner)throw new o("COMMAND_FAILED","KEYBOARD_OVERLAY_BLOCKING: Android text input is blocked because the focused input belongs to the active keyboard/IME.",{failureReason:"ime_capture",action:a,inputOwner:r.inputOwner,inputType:r.inputType,type:r.type,inputMethodPackage:r.inputMethodPackage,focusedPackage:r.focusedPackage,focusedResourceId:r.focusedResourceId,nextAction:"Focused input appears to be owned by the keyboard/IME; dismiss or change the IME before retrying text entry."})}async function R(t){let n=(await e(t,["shell","wm","size"])).stdout.match(/Physical size:\s*(\d+)x(\d+)/);if(!n)throw new o("COMMAND_FAILED","Unable to read screen size");return{width:Number(n[1]),height:Number(n[2])}}let O=8;async function L(t,n){let a=n.text.split("\n");for(let[r,i]of a.entries()){let o=function(t,e){let n=Math.max(1,Math.floor(e)),a=[],r=Array.from(t);for(let t=0;t<r.length;t+=n)a.push(r.slice(t,t+n).join(""));return a.length>0?a:[""]}(i,n.chunkSize);for(let[e,i]of o.entries())await U(t,i),n.delayMs>0&&(e+1<o.length||r+1<a.length)&&await c(n.delayMs);r+1<a.length&&await e(t,["shell","input","keyevent","ENTER"])}T(n.action,"adb-shell",n.text)}async function U(t,n){if(n)try{await e(t,["shell","input","text",n.replace(/ /g,"%s")])}catch(t){if(function(t){if(!(t instanceof o)||"COMMAND_FAILED"!==t.code)return!1;let e=t.details?.stderr,n=("string"==typeof e?e:"").toLowerCase();return!!(n.includes("exception occurred while executing 'text'")||n.includes("nullpointerexception")&&n.includes("inputshellcommand.sendtext"))}(t))throw H(n,t);throw t}}function z(t){if(!function(t){for(let e of t){let t=e.codePointAt(0);if(void 0!==t&&"\n"!==e&&(t<32||t>126))return!1}return!0}(t))throw H(t)}function H(t,e){return new o("COMMAND_FAILED","Android text input requires provider-native text injection for non-ASCII/control characters; the current adb-shell fallback supports ASCII text only.",{backend:"adb-shell",textLength:Array.from(t).length,textPreview:t.slice(0,32)},e instanceof Error?e:void 0)}function T(e,n,a){t({phase:"android_text_injection",data:{action:e,backend:n,textLength:Array.from(a).length}})}async function F(t,n){let a=Math.max(0,n);await e(t,["shell","input","keyevent","KEYCODE_MOVE_END"],{allowFailure:!0});for(let n=0;n<a;n+=24){let r=Math.min(24,a-n);await e(t,["shell","input","keyevent",...Array(r).fill("KEYCODE_DEL")],{allowFailure:!0})}}export{E as appSwitcherAndroid,I as backAndroid,N as fillAndroid,P as focusAndroid,R as getAndroidScreenSize,M as homeAndroid,v as longPressAndroid,A as pressAndroid,S as pressAndroidEnter,h as readAndroidTextAtPoint,k as rotateAndroid,K as scrollAndroid,x as swipeAndroid,C as typeAndroid};
1
+ import{emitDiagnostic as t}from"./8875.js";import{runAndroidAdb as e,resolveAndroidTextInjector as n}from"./3340.js";import{getAndroidKeyboardState as a,isAndroidInputMethodOwnedNode as r}from"./9624.js";import{captureAndroidUiHierarchyXml as i,androidUiNodes as o}from"./9722.js";import{AppError as u}from"./485.js";import{buildScrollGesturePlan as l}from"./2948.js";import{sleep as c}from"./5560.js";function s(t){var e;return!!t&&(!!t.password||!!(e=t.text)&&Array.from(e).every(f))}function d(t){if(!t)return null;let e=s(t);return{...t,text:e?null:t.text,...e?{textRedacted:!0}:{}}}function f(t){return"•"===t||"*"===t||"●"===t}async function p(t,e,n,a){let r=null,i=null,o=await m(t);for(let u of[0,150,350]){u>0&&await c(u);let l=await g(t,e,n,a,o);if(r=l,"ime_capture"===l.reason)return l;i=l.ok?l:null}return i??r??{ok:!1,actual:null,reason:"text_mismatch",targetInput:null,actualInput:null}}async function h(t,e,n){var a,r,o;return a=await i(t),r=e,o=n,w(a,r,o).actualInput?.text??null}async function g(t,e,n,a,r){return function(t,e,n,a,r={}){var i,o;let u,l=w(t,e,n,r);return!function(t){let{targetInput:e,actualInput:n}=t;return!!e&&!!n&&n!==e&&n.inputMethodOwned&&!e.inputMethodOwned}(l)?function(t,e){let n=t.actualInput;if(!n||!s(n))return null;let a=n.text??null,r=Array.from(a??"").length,i=Array.from(e).length,o=null!==a&&r>0&&i>0&&r===i;return{ok:o,actual:a,reason:o?void 0:"masked_unverified",masked:!0,targetInput:t.targetInput,actualInput:n}}(l,a)??(i=l,o=a,{ok:function(t,e){if(t===e)return!0;let n=y(t),a=y(e);return!!n&&!!a&&!!(n===a||function(t,e){if(t.length!==e.length||0===t.length||t.slice(1)!==e.slice(1))return!1;let n=t[0],a=e[0];return!!n&&!!a&&a.toLowerCase()===a&&n===a.toUpperCase()}(n,a))}(u=i.actualInput?.text??null,o),actual:u,reason:"text_mismatch",targetInput:i.targetInput,actualInput:i.actualInput}):{ok:!1,actual:l.actualInput?.text??null,reason:"ime_capture",targetInput:l.targetInput,actualInput:l.actualInput}}(await i(t),e,n,a,r)}function w(t,e,n,a={}){var i;let u,l={focusedEdit:null,editAtPoint:null,anyAtPoint:null};for(let i of o(t)){let t=function(t,e){if(!t.rect)return null;let n=t.text??"",a=Math.max(1,t.rect.width*t.rect.height);return{text:n||null,className:t.className,resourceId:t.resourceId,packageName:t.packageName,rect:t.rect,focused:t.focused??!1,password:!0===t.password,inputMethodOwned:r({packageName:t.packageName,resourceId:t.resourceId,activeInputMethodPackage:e.activeInputMethodPackage}),area:a,editText:function(t){let e=t.toLowerCase();return e.includes("edittext")||e.includes("textfield")}(t.className??"")}}(i,a);t&&function(t,e,n,a){var r,i,o;let u=(r=e.rect,i=n,o=a,i>=r.x&&i<=r.x+r.width&&o>=r.y&&o<=r.y+r.height);if(u&&e.editText&&(t.editAtPoint=_(t.editAtPoint,e)),e.focused&&e.editText){t.focusedEdit=_(t.focusedEdit,e);return}u&&e.text&&(t.anyAtPoint=_(t.anyAtPoint,e))}(l,t,e,n)}return{targetInput:u=(i=l).editAtPoint??i.anyAtPoint,actualInput:(i.focusedEdit?.text?i.focusedEdit:null)??u}}function y(t){return(t??"").replace(/\s+/g," ").trim()}async function m(e){try{return{activeInputMethodPackage:(await a(e)).inputMethodPackage}}catch(e){return t({level:"warn",phase:"android_fill_verification_input_method_probe_failed",data:{error:e instanceof Error?e.message:String(e)}}),{}}}function _(t,e){return t&&t.area<e.area?t:e}async function A(t,n,a){await e(t,["shell","input","tap",String(n),String(a)])}async function x(t,n,a,r,i,o=250){await e(t,["shell","input","swipe",String(n),String(a),String(r),String(i),String(o)])}async function I(t){await e(t,["shell","input","keyevent","4"])}async function M(t){await e(t,["shell","input","keyevent","3"])}async function k(t){await e(t,["shell","input","keyevent","ENTER"])}async function S(t,n){let a=function(t){switch(t){case"portrait":return"0";case"landscape-left":return"1";case"portrait-upside-down":return"2";case"landscape-right":return"3";default:throw new u("INVALID_ARGS",`Unsupported Android rotation: ${t}`)}}(n);await e(t,["shell","settings","put","system","accelerometer_rotation","0"]),await e(t,["shell","settings","put","system","user_rotation",a])}async function v(t){await e(t,["shell","input","keyevent","187"])}async function E(t,n,a,r=800){await e(t,["shell","input","swipe",String(n),String(a),String(n),String(a),String(r)])}async function C(t,e,a=0){let r=n(t);if(r){await r({action:"type",text:e,delayMs:a}),F("type","provider-native",e);return}(U(e),await K(t,"type"),a>0&&Array.from(e).length>1)?await L(t,{action:"type",text:e,chunkSize:1,delayMs:a}):await L(t,{action:"type",text:e,chunkSize:O,delayMs:0})}async function P(t,e,n){await A(t,e,n)}async function N(t,e,a,r,i=0){let o=n(t);if(o){await o({action:"fill",target:{x:e,y:a},text:r,delayMs:i}),F("fill","provider-native",r);let n=await p(t,e,a,r);if(n.ok)return;b(r,n)}U(r);let u=Array.from(r).length,l=null;for(let n of[{clearPadding:12,minClear:8,maxClear:48,chunkSize:i>0?1:O,inputDelayMs:i},{clearPadding:24,minClear:16,maxClear:96,chunkSize:i>0?1:4,inputDelayMs:i>0?i:15}]){var c,s;await P(t,e,a),await K(t,"fill");let i=(c=u+n.clearPadding,s=n.minClear,Math.max(s,Math.min(n.maxClear,c)));await H(t,i),await L(t,{action:"fill",text:r,chunkSize:n.chunkSize,delayMs:n.inputDelayMs});let o=await p(t,e,a,r);if(l=o,o.ok)return;"ime_capture"===o.reason&&b(r,o)}b(r,l)}function b(t,e){let n;throw new u("COMMAND_FAILED",e?.reason==="ime_capture"?"Android fill input was captured by the active keyboard instead of the app field":e?.reason==="masked_unverified"?"Android fill verification could not confirm masked text value":"Android fill verification failed",(n=function(t,e){var n;if(!e)return{expected:t,actual:null,failureReason:"text_mismatch",targetInput:null,actualInput:null};let a=!0===(n=e).masked||s(n.targetInput)||s(n.actualInput),r={failureReason:e.reason??"text_mismatch",targetInput:d(e.targetInput),actualInput:d(e.actualInput)};return a?{...r,expectedLength:Array.from(t).length,actual:null,masked:!0,actualLength:Array.from(e.actual??"").length}:{...r,expected:t,actual:e.actual}}(t,e),e?.reason==="ime_capture"&&(n.hint="The focused input belongs to the Android keyboard/IME, not the app field. Disable handwriting/stylus input or switch to a standard IME, then retry fill."),n))}async function D(t,n,a){let r=await R(t),i=l({direction:n,amount:a?.amount,pixels:a?.pixels,referenceWidth:r.width,referenceHeight:r.height}),o=a?.durationMs??300;return await e(t,["shell","input","swipe",String(i.x1),String(i.y1),String(i.x2),String(i.y2),String(o)]),{...i,...a?.durationMs!==void 0?{durationMs:a.durationMs}:{}}}async function K(e,n){let r;try{r=await a(e)}catch(e){t({level:"warn",phase:"android_input_ownership_probe_failed",data:{action:n,error:e instanceof Error?e.message:String(e)}});return}if("ime"===r.inputOwner)throw new u("COMMAND_FAILED","KEYBOARD_OVERLAY_BLOCKING: Android text input is blocked because the focused input belongs to the active keyboard/IME.",{failureReason:"ime_capture",action:n,inputOwner:r.inputOwner,inputType:r.inputType,type:r.type,inputMethodPackage:r.inputMethodPackage,focusedPackage:r.focusedPackage,focusedResourceId:r.focusedResourceId,nextAction:"Focused input appears to be owned by the keyboard/IME; dismiss or change the IME before retrying text entry."})}async function R(t){let n=(await e(t,["shell","wm","size"])).stdout.match(/Physical size:\s*(\d+)x(\d+)/);if(!n)throw new u("COMMAND_FAILED","Unable to read screen size");return{width:Number(n[1]),height:Number(n[2])}}let O=8;async function L(t,n){let a=n.text.split("\n");for(let[r,i]of a.entries()){let o=function(t,e){let n=Math.max(1,Math.floor(e)),a=[],r=Array.from(t);for(let t=0;t<r.length;t+=n)a.push(r.slice(t,t+n).join(""));return a.length>0?a:[""]}(i,n.chunkSize);for(let[e,i]of o.entries())await z(t,i),n.delayMs>0&&(e+1<o.length||r+1<a.length)&&await c(n.delayMs);r+1<a.length&&await e(t,["shell","input","keyevent","ENTER"])}F(n.action,"adb-shell",n.text)}async function z(t,n){if(n)try{await e(t,["shell","input","text",n.replace(/ /g,"%s")])}catch(t){if(function(t){if(!(t instanceof u)||"COMMAND_FAILED"!==t.code)return!1;let e=t.details?.stderr,n=("string"==typeof e?e:"").toLowerCase();return!!(n.includes("exception occurred while executing 'text'")||n.includes("nullpointerexception")&&n.includes("inputshellcommand.sendtext"))}(t))throw T(n,t);throw t}}function U(t){if(!function(t){for(let e of t){let t=e.codePointAt(0);if(void 0!==t&&"\n"!==e&&(t<32||t>126))return!1}return!0}(t))throw T(t)}function T(t,e){return new u("COMMAND_FAILED","Android text input requires provider-native text injection for non-ASCII/control characters; the current adb-shell fallback supports ASCII text only.",{backend:"adb-shell",textLength:Array.from(t).length,textPreview:t.slice(0,32)},e instanceof Error?e:void 0)}function F(e,n,a){t({phase:"android_text_injection",data:{action:e,backend:n,textLength:Array.from(a).length}})}async function H(t,n){let a=Math.max(0,n);await e(t,["shell","input","keyevent","KEYCODE_MOVE_END"],{allowFailure:!0});for(let n=0;n<a;n+=24){let r=Math.min(24,a-n);await e(t,["shell","input","keyevent",...Array(r).fill("KEYCODE_DEL")],{allowFailure:!0})}}export{v as appSwitcherAndroid,I as backAndroid,N as fillAndroid,P as focusAndroid,R as getAndroidScreenSize,M as homeAndroid,E as longPressAndroid,A as pressAndroid,k as pressAndroidEnter,h as readAndroidTextAtPoint,S as rotateAndroid,D as scrollAndroid,x as swipeAndroid,C as typeAndroid};
@@ -1 +1 @@
1
- import{AppError as a}from"./733.js";import{resolveLinuxToolProvider as t}from"./9722.js";import{sleep as i}from"./5560.js";let o=null;async function n(){let i=t();if(o?.provider===i)return o;let n=process.env.WAYLAND_DISPLAY||"wayland"===process.env.XDG_SESSION_TYPE?"wayland":"x11";if("wayland"===n){if(await i.whichCommand("ydotool"))return o={tool:"ydotool",display:n,provider:i};throw new a("TOOL_MISSING","ydotool is required for input synthesis on Wayland (xdotool does not work on Wayland). Install it via your package manager.")}if(await i.whichCommand("xdotool"))return o={tool:"xdotool",display:n,provider:i};throw new a("TOOL_MISSING","xdotool is required for input synthesis on X11. Install it via your package manager.")}async function e(...a){await t().runCommand("xdotool",a,{allowFailure:!1,timeoutMs:1e4})}async function l(...a){await t().runCommand("ydotool",a,{allowFailure:!1,timeoutMs:1e4})}function r(){return t().input}async function u(a,t){let{tool:i}=await n();"xdotool"===i?await e("mousemove","--sync",String(a),String(t)):await l("mousemove","--absolute","-x",String(a),"-y",String(t))}async function w(a,t){let i=r();if(i)return void await i.key(a,t);let{tool:o}=await n();"xdotool"===o?await e("key","--clearmodifiers",a):await l("key",...t)}async function c(a,t,i,o){await u(a,t);let{tool:r}=await n();"xdotool"===r?await e("click",i):await l("click",o)}async function s(a,t,i,o,n){let e=r();e?await e.click(a,t,i):await c(a,t,o,n)}async function d(a,t){await s(a,t,"primary","1","0xC0")}async function y(a,t){await s(a,t,"secondary","3","0xC1")}async function x(a,t){await s(a,t,"middle","2","0xC2")}async function f(a,t){let i=r();if(i)return void await i.doubleClick(a,t);let{tool:o}=await n();await u(a,t),"xdotool"===o?await e("click","--repeat","2","1"):(await l("click","0xC0"),await l("click","0xC0"))}async function m(a,t,o=800){let w=r();if(w)return void await w.longPress(a,t,o);let{tool:c}=await n();await u(a,t),"xdotool"===c?(await e("mousedown","1"),await i(o),await e("mouseup","1")):(await l("click","--down","0xC0"),await i(o),await l("click","--up","0xC0"))}async function p(a,t){await d(a,t)}async function S(a,t,o,w,c=300){let s=r();if(s)return void await s.drag(a,t,o,w,c);let{tool:d}=await n();await u(a,t),"xdotool"===d?(await e("mousedown","1"),await e("mousemove","--sync",String(o),String(w)),await i(c),await e("mouseup","1")):(await l("click","--down","0xC0"),await l("mousemove","--absolute","-x",String(o),"-y",String(w)),await i(c),await l("click","--up","0xC0"))}async function C(a,t){let i=r();if(i)return await i.scroll(a,t),k(t);let{tool:o}=await n(),u=5;if(t?.pixels!=null?u="xdotool"===o?Math.max(1,Math.round(t.pixels/15)):Math.max(1,Math.round(t.pixels/40)):t?.amount!=null&&(u=Math.max(1,Math.round(5*(t.amount/.6)))),"xdotool"===o){let i="up"===a?"4":"down"===a?"5":"left"===a?"6":"7";await g(u,t?.durationMs,async a=>{await e("click","--repeat",String(a),i)})}else"up"===a||"down"===a?await g(u,t?.durationMs,async t=>{let i="up"===a?String(-t):String(t);await l("mousemove","--wheel","-y",i)}):await g(u,t?.durationMs,async t=>{let i="left"===a?String(-t):String(t);await l("mousemove","--wheel","-x",i)});return k(t)}async function g(a,t,o){if(void 0===t||t<=0||a<=1)return void await o(a);let n=t/Math.max(1,a-1);for(let t=0;t<a;t+=1)await o(1),t<a-1&&await i(n)}function k(a){return a?.durationMs!==void 0?{durationMs:a.durationMs}:{}}async function h(a,t=0){let i=r();if(i)return void await i.typeText(a,{delayMs:t});let{tool:o}=await n();if("xdotool"===o){let i=["type"];t>0&&i.push("--delay",String(t)),i.push("--clearmodifiers","--",a),await e(...i)}else await l("type","--",a)}async function M(a,t,o,n=0){await d(a,t),await i(100),await w("ctrl+a",["29:1","30:1","30:0","29:0"]),await i(50),await h(o,n)}export{f as doubleClickLinux,M as fillLinux,p as focusLinux,m as longPressLinux,x as middleClickLinux,d as pressLinux,y as rightClickLinux,C as scrollLinux,w as sendKey,S as swipeLinux,h as typeLinux};
1
+ import{AppError as a}from"./485.js";import{resolveLinuxToolProvider as t}from"./9722.js";import{sleep as i}from"./5560.js";let o=null;async function n(){let i=t();if(o?.provider===i)return o;let n=process.env.WAYLAND_DISPLAY||"wayland"===process.env.XDG_SESSION_TYPE?"wayland":"x11";if("wayland"===n){if(await i.whichCommand("ydotool"))return o={tool:"ydotool",display:n,provider:i};throw new a("TOOL_MISSING","ydotool is required for input synthesis on Wayland (xdotool does not work on Wayland). Install it via your package manager.")}if(await i.whichCommand("xdotool"))return o={tool:"xdotool",display:n,provider:i};throw new a("TOOL_MISSING","xdotool is required for input synthesis on X11. Install it via your package manager.")}async function e(...a){await t().runCommand("xdotool",a,{allowFailure:!1,timeoutMs:1e4})}async function l(...a){await t().runCommand("ydotool",a,{allowFailure:!1,timeoutMs:1e4})}function r(){return t().input}async function u(a,t){let{tool:i}=await n();"xdotool"===i?await e("mousemove","--sync",String(a),String(t)):await l("mousemove","--absolute","-x",String(a),"-y",String(t))}async function w(a,t){let i=r();if(i)return void await i.key(a,t);let{tool:o}=await n();"xdotool"===o?await e("key","--clearmodifiers",a):await l("key",...t)}async function c(a,t,i,o){await u(a,t);let{tool:r}=await n();"xdotool"===r?await e("click",i):await l("click",o)}async function s(a,t,i,o,n){let e=r();e?await e.click(a,t,i):await c(a,t,o,n)}async function d(a,t){await s(a,t,"primary","1","0xC0")}async function y(a,t){await s(a,t,"secondary","3","0xC1")}async function x(a,t){await s(a,t,"middle","2","0xC2")}async function f(a,t){let i=r();if(i)return void await i.doubleClick(a,t);let{tool:o}=await n();await u(a,t),"xdotool"===o?await e("click","--repeat","2","1"):(await l("click","0xC0"),await l("click","0xC0"))}async function m(a,t,o=800){let w=r();if(w)return void await w.longPress(a,t,o);let{tool:c}=await n();await u(a,t),"xdotool"===c?(await e("mousedown","1"),await i(o),await e("mouseup","1")):(await l("click","--down","0xC0"),await i(o),await l("click","--up","0xC0"))}async function p(a,t){await d(a,t)}async function S(a,t,o,w,c=300){let s=r();if(s)return void await s.drag(a,t,o,w,c);let{tool:d}=await n();await u(a,t),"xdotool"===d?(await e("mousedown","1"),await e("mousemove","--sync",String(o),String(w)),await i(c),await e("mouseup","1")):(await l("click","--down","0xC0"),await l("mousemove","--absolute","-x",String(o),"-y",String(w)),await i(c),await l("click","--up","0xC0"))}async function C(a,t){let i=r();if(i)return await i.scroll(a,t),k(t);let{tool:o}=await n(),u=5;if(t?.pixels!=null?u="xdotool"===o?Math.max(1,Math.round(t.pixels/15)):Math.max(1,Math.round(t.pixels/40)):t?.amount!=null&&(u=Math.max(1,Math.round(5*(t.amount/.6)))),"xdotool"===o){let i="up"===a?"4":"down"===a?"5":"left"===a?"6":"7";await g(u,t?.durationMs,async a=>{await e("click","--repeat",String(a),i)})}else"up"===a||"down"===a?await g(u,t?.durationMs,async t=>{let i="up"===a?String(-t):String(t);await l("mousemove","--wheel","-y",i)}):await g(u,t?.durationMs,async t=>{let i="left"===a?String(-t):String(t);await l("mousemove","--wheel","-x",i)});return k(t)}async function g(a,t,o){if(void 0===t||t<=0||a<=1)return void await o(a);let n=t/Math.max(1,a-1);for(let t=0;t<a;t+=1)await o(1),t<a-1&&await i(n)}function k(a){return a?.durationMs!==void 0?{durationMs:a.durationMs}:{}}async function h(a,t=0){let i=r();if(i)return void await i.typeText(a,{delayMs:t});let{tool:o}=await n();if("xdotool"===o){let i=["type"];t>0&&i.push("--delay",String(t)),i.push("--clearmodifiers","--",a),await e(...i)}else await l("type","--",a)}async function M(a,t,o,n=0){await d(a,t),await i(100),await w("ctrl+a",["29:1","30:1","30:0","29:0"]),await i(50),await h(o,n)}export{f as doubleClickLinux,M as fillLinux,p as focusLinux,m as longPressLinux,x as middleClickLinux,d as pressLinux,y as rightClickLinux,C as scrollLinux,w as sendKey,S as swipeLinux,h as typeLinux};
@@ -1,31 +1,5 @@
1
- export declare const ARCHIVE_EXTENSIONS: readonly [".zip", ".tar", ".tar.gz", ".tgz"];
2
-
3
- export declare function isBlockedIpAddress(address: string): boolean;
4
-
5
- export declare function isBlockedSourceHostname(hostname: string): boolean;
6
-
7
1
  export declare function isTrustedInstallSourceUrl(sourceUrl: string | URL): boolean;
8
2
 
9
- export declare type MaterializedInstallable = {
10
- archivePath?: string;
11
- installablePath: string;
12
- cleanup: () => Promise<void>;
13
- };
14
-
15
- declare type MaterializeInstallableOptions = {
16
- source: MaterializeInstallSource;
17
- isInstallablePath: (candidatePath: string, stat: {
18
- isFile(): boolean;
19
- isDirectory(): boolean;
20
- }) => boolean;
21
- installableLabel: string;
22
- allowArchiveExtraction?: boolean;
23
- signal?: AbortSignal;
24
- downloadTimeoutMs?: number;
25
- };
26
-
27
- export declare function materializeInstallablePath(options: MaterializeInstallableOptions): Promise<MaterializedInstallable>;
28
-
29
3
  export declare type MaterializeInstallSource = {
30
4
  kind: 'url';
31
5
  url: string;
@@ -1 +1 @@
1
- export{ARCHIVE_EXTENSIONS,isBlockedIpAddress,isBlockedSourceHostname,isTrustedInstallSourceUrl,materializeInstallablePath,validateDownloadSourceUrl}from"./5484.js";
1
+ export{isTrustedInstallSourceUrl,validateDownloadSourceUrl}from"./5484.js";
@@ -1 +1 @@
1
- import{__webpack_require__ as e}from"./rslib-runtime.js";import{createDaemonRuntimeSessionStore as t,setSessionSnapshot as r,dispatchCommand as a,ensureAndroidBlockingSystemDialogReady as n,isCommandSupportedOnDevice as o,errorResponse as s,recoverAndroidBlockingSystemDialog as i,getActiveAndroidSnapshotFreshness as l}from"./9722.js";import{buttonTag as c,resolveClickButton as f,readFillTargetFromPositionals as u,getClickButtonValidationError as d,successText as p}from"./2948.js";import{createAgentDevice as g}from"./2577.js";import{asAppError as m,normalizeError as k,AppError as S}from"./733.js";import{dispatchGetViaRuntime as _,isAndroidEscapeError as y,createDaemonRuntimePolicy as w,assertAndroidPressStayedInApp as h,dispatchIsViaRuntime as b,isDirectIosSelectorFallbackError as v,refSnapshotFlagGuardResponse as N,readSimpleIosSelectorTarget as x}from"./selector-runtime.js";import{resolveWebProvider as F}from"./provider.js";import{interaction_snapshot_captureSnapshotForSession as R,readSnapshotNodesReferenceFrame as P,resolveDirectTouchReferenceFrameSafely as M,buildTouchVisualizationResult as O,finalizeTouchInteraction as C}from"./8184.js";import{emitDiagnostic as I}from"./432.js";import{PUBLIC_COMMANDS as A}from"./5341.js";var E={};function q(e,t){return"macos"!==e.device.platform||"desktop"!==e.surface&&"menubar"!==e.surface||"menubar"===e.surface&&("click"===t||"press"===t)?null:s("UNSUPPORTED_OPERATION",`${t} is not supported on macOS ${e.surface} sessions yet. Open an app session to act, or use the ${e.surface} surface to inspect.`)}function U(e){if(e.length<2)return null;let t=Number(e[0]),r=Number(e[1]);return Number.isFinite(t)&&Number.isFinite(r)?{x:t,y:r}:null}function T(e,t){let r=U(e);if(r)return{ok:!0,target:{kind:"point",x:r.x,y:r.y}};let a=e[0]??"";if(a.startsWith("@"))return{ok:!0,target:{kind:"ref",ref:a,fallbackLabel:e.slice(1).join(" ").trim()}};let n=e.join(" ").trim();return n?{ok:!0,target:{kind:"selector",selector:n}}:{ok:!1,response:s("INVALID_ARGS",`${t} requires @ref, selector expression, or x y coordinates`)}}function D(e){return"ref"===e.kind?{ref:H(e.target?.kind==="ref"?e.target.ref:void 0),refLabel:e.refLabel,selectorChain:e.selectorChain}:"selector"===e.kind?{selector:e.target?.kind==="selector"?e.target.selector:void 0,selectorChain:e.selectorChain,refLabel:e.refLabel}:{}}function H(e){return e?.startsWith("@")?e.slice(1):e}function K(e){let n=e.sessionStore.get(e.sessionName);if(!n)throw new S("SESSION_NOT_FOUND","No active session. Run open first.");return g({backend:function(e){let{req:t,session:r}=e,n=function(e){if("web"!==e.device.platform)return;let t=F();return t.clickRef||t.fillRef?t:void 0}(r);return{platform:r.device.platform,captureSnapshot:async(a,n)=>({snapshot:await e.captureSnapshotForSession(r,t.flags,e.sessionStore,e.contextFromFlags,{interactiveOnly:n?.interactiveOnly===!0,includeRects:n?.includeRects===!0})}),tap:async(n,o)=>L(await a(r.device,"press",[String(o.x),String(o.y)],t.flags?.out,e.contextFromFlags(t.flags,r.appBundleId,r.trace?.outPath))),tapTarget:n?.clickRef?async(e,t)=>(await n.clickRef?.(t.ref),{ref:H(t.ref)}):void 0,fill:async(n,o,s)=>L(await a(r.device,"fill",[String(o.x),String(o.y),s],t.flags?.out,e.contextFromFlags(t.flags,r.appBundleId,r.trace?.outPath))),fillTarget:n?.fillRef?async(e,t,r,a)=>(await n.fillRef?.(t.ref,r,a),{ref:H(t.ref),text:r,delayMs:a?.delayMs??0}):void 0,longPress:async(n,o,s)=>L(await a(r.device,"longpress",[String(o.x),String(o.y),...s?.durationMs===void 0?[]:[String(s.durationMs)]],t.flags?.out,e.contextFromFlags(t.flags,r.appBundleId,r.trace?.outPath))),typeText:async(n,o)=>L(await a(r.device,"type",[o],t.flags?.out,e.contextFromFlags(t.flags,r.appBundleId,r.trace?.outPath)))}}({...e,session:n}),...w("interaction commands",{plural:!0}),sessions:t({sessionName:e.sessionName,getSession:()=>n,recordOptions:{includeSnapshot:!0},setRecord:t=>{t.snapshot&&(r(n,t.snapshot),e.sessionStore.set(e.sessionName,n))}})})}function L(e){return e&&"object"==typeof e?e:void 0}async function j(e){switch(e.req.command){case"press":return await B(e,"press");case"click":return await B(e,"click");case"longpress":return await B(e,"longpress");case"fill":return await X(e);default:return null}}async function B(e,t){let r,{req:a,sessionName:n,sessionStore:i}=e,l=i.get(n);if(!l)return s("SESSION_NOT_FOUND","No active session. Run open first.");let u="click"===t?"click":t,p="longpress"===t?"longpress":"press",g=q(l,u);if(g)return g;if(!o(p,l.device))return s("UNSUPPORTED_OPERATION",`${p} is not supported on this device`);let m=f(a.flags),k=c(m);if("longpress"!==t&&"primary"!==m){let e=d({commandLabel:u,platform:l.device.platform,button:m,count:a.flags?.count,intervalMs:a.flags?.intervalMs,holdMs:a.flags?.holdMs,jitterPx:a.flags?.jitterPx,doubleTap:a.flags?.doubleTap});if(e)return s(e.code,e.message,e.details)}let S="longpress"===t?function(e){var t,r,a;let n,o=U(e);if(o){return{ok:!0,target:{kind:"point",x:o.x,y:o.y},...void 0===(t=e[2])?{}:{durationMs:Number(t)}}}let s=(n=(r=e).at(-1),r.length>1&&void 0!==(a=n)&&""!==a.trim()&&Number.isFinite(Number(a))?{targetPositionals:r.slice(0,-1),duration:{durationMs:Number(n)}}:{targetPositionals:r,duration:{}}),i=T(s.targetPositionals,"longpress");return i.ok?{ok:!0,target:i.target,...s.duration}:i}(a.positionals??[]):T(a.positionals??[],u);if(!S.ok)return S.response;if("ref"===S.target.kind){let n=e.refSnapshotFlagGuardResponse("longpress"===t?"longpress":"press",a.flags);if(n)return n;r=await J(e,l)}let _=function(e){var t;let{session:r,commandLabel:a,target:n,flags:o}=e;if("click"!==a||"selector"!==n.kind||(t=o,t?.count!==void 0||t?.intervalMs!==void 0||t?.holdMs!==void 0||t?.jitterPx!==void 0||t?.doubleTap!==void 0||t?.clickButton!==void 0&&"primary"!==t.clickButton))return null;let s=x({session:r,selectorExpression:n.selector});return s?{...s,...o?.maestro?.allowNonHittableCoordinateFallback?{allowNonHittableCoordinateFallback:!0}:{}}:null}({session:l,commandLabel:u,target:S.target,flags:a.flags});if(_){let t=await $(e,l,_);if(t)return t}let y="longpress"===t?S.durationMs:void 0;return await z(e,{androidFreshnessBaseline:r,run:async e=>await G({runtime:e,command:t,target:S.target,sessionName:n,requestId:a.meta?.requestId,clickButton:m,flags:a.flags,durationMs:y}),afterRun:async e=>{var t;await h(l,(t=S.target,"point"===t.kind?"coordinate tap":"ref"===e.kind&&e.target?.kind==="ref"?e.target.ref:"selector"===e.kind&&e.target?.kind==="selector"?e.target.selector:"target"))},buildPayloads:async r=>{var a;let n="durationMs"in(a=r)?a.durationMs:void 0,o=await W({params:e,session:l,result:r,extra:"longpress"===t?{...void 0!==n?{durationMs:n}:{},gesture:"longpress"}:k});return{result:o,responseData:o}}})}async function G(e){let{runtime:t,command:r,target:a,sessionName:n,requestId:o,flags:s}=e;if("longpress"===r)return await t.interactions.longPress(a,{session:n,requestId:o,durationMs:e.durationMs});let i={session:n,requestId:o,button:e.clickButton,count:s?.count,intervalMs:s?.intervalMs,holdMs:s?.holdMs,jitterPx:s?.jitterPx,doubleTap:s?.doubleTap};return"click"===r?await t.interactions.click(a,i):await t.interactions.press(a,i)}async function W(e){let{params:t,session:r,result:a,extra:n}=e,o="point"===a.kind?await M({session:r,flags:t.req.flags,sessionStore:t.sessionStore,contextFromFlags:t.contextFromFlags,captureSnapshotForSession:t.captureSnapshotForSession}):P(r.snapshot?.nodes??[]);return O({data:a.backendResult,fallbackX:a.point?.x,fallbackY:a.point?.y,referenceFrame:o,extra:{...D(a),...n}})}async function $(e,t,r){return await V({params:e,session:t,selector:r,command:"press",positionals:[],extra:{selector:r.raw},fallbackPhase:"ios_direct_selector_tap_fallback"})}async function V(e){let{params:t,session:r,selector:n,command:o,positionals:s,extra:i,fallbackPhase:l}=e,c=Date.now();try{var f,u;let e,l,d=await a(r.device,o,s,t.req.flags?.out,{...t.contextFromFlags(t.req.flags,r.appBundleId,r.trace?.outPath),directElementSelector:n,surface:r.surface})??{},p=Date.now(),g=(f=d,e="number"==typeof f.x?f.x:void 0,l="number"==typeof f.y?f.y:void 0,void 0!==e&&void 0!==l?{x:e,y:l}:{x:0,y:0}),m=O({data:d,fallbackX:g.x,fallbackY:g.y,referenceFrame:(u=d,"number"==typeof u.referenceWidth&&"number"==typeof u.referenceHeight?{referenceWidth:u.referenceWidth,referenceHeight:u.referenceHeight}:void 0),extra:{...i,...function(e,t){if(!e.allowNonHittableCoordinateFallback)return{};let r="tapped via non-hittable coordinate fallback"===t.message;return{maestroNonHittableCoordinateFallbackAllowed:!0,maestroNonHittableCoordinateFallbackUsed:r,...r?{maestroFallbackReason:"non-hittable-coordinate"}:{}}}(n,d)}});return C({session:r,sessionStore:t.sessionStore,command:t.req.command,positionals:t.req.positionals??[],retryPositionals:Q(g),flags:t.req.flags,result:m,responseData:m,actionStartedAt:c,actionFinishedAt:p})}catch(e){if(!v(e))return{ok:!1,error:k(e)};return I({level:"debug",phase:l,data:{selector:n.raw,error:e instanceof Error?e.message:String(e)}}),null}}async function X(e){let{req:t,sessionName:r,sessionStore:a}=e,n=a.get(r);if(n){let e=q(n,"fill");if(e)return e}if(n&&!o("fill",n.device))return s("UNSUPPORTED_OPERATION","fill is not supported on this device");if(!n)return s("SESSION_NOT_FOUND","No active session. Run open first.");let i=function(e){let t=e[0]??"";if(t.startsWith("@")){var r;let a=u(e).text;return a?{ok:!0,target:{kind:"ref",ref:t,fallbackLabel:(r=e).length>=3&&r[1]?.trim()||""},text:a}:{ok:!1,response:s("INVALID_ARGS","fill requires text after ref")}}let a=U(e);if(a){let t=e.slice(2).join(" ");return t?{ok:!0,target:{kind:"point",x:a.x,y:a.y},text:t}:{ok:!1,response:s("INVALID_ARGS","fill requires text after coordinates")}}let n=u(e);return"selector"!==n.kind?{ok:!1,response:s("INVALID_ARGS","fill requires x y text, @ref text, or selector text")}:n.text.trim()?{ok:!0,target:{kind:"selector",selector:n.target.selector},text:n.text}:{ok:!1,response:s("INVALID_ARGS","fill requires text after selector")}}(t.positionals??[]);if(!i.ok)return i.response;if("ref"===i.target.kind){let r=e.refSnapshotFlagGuardResponse("fill",t.flags);if(r)return r;await J(e,n)}let l=function(e){let{session:t,target:r,flags:a}=e;if("selector"!==r.kind)return null;let n=x({session:t,selectorExpression:r.selector});return n?{...n,...a?.maestro?.allowNonHittableCoordinateFallback?{allowNonHittableCoordinateFallback:!0}:{}}:null}({session:n,target:i.target,flags:t.flags});if(l){let t=await Y(e,n,l,i.text);if(t)return t}return await z(e,{run:async e=>await e.interactions.fill(i.target,i.text,{session:r,requestId:t.meta?.requestId,delayMs:t.flags?.delayMs}),buildPayloads:e=>{let t="point"===e.kind?void 0:P(n.snapshot?.nodes??[]),r=O({data:e.backendResult,fallbackX:e.point?.x,fallbackY:e.point?.y,referenceFrame:t,extra:{...D(e),text:i.text}});e.warning&&(r.warning=e.warning);let a="ref"===e.kind?{...e.backendResult??{ref:H(e.target?.kind==="ref"?e.target.ref:void 0),...e.point?{x:e.point.x,y:e.point.y}:{}}}:r;return e.warning&&(a.warning=e.warning),{result:r,responseData:a}}})}async function Y(e,t,r,a){return await V({params:e,session:t,selector:r,command:"fill",positionals:[a],extra:{selector:r.raw,text:a},fallbackPhase:"ios_direct_selector_fill_fallback"})}async function z(e,t){let r=e.sessionStore.get(e.sessionName);if(!r)return s("SESSION_NOT_FOUND","No active session. Run open first.");let a=K(e),o=Date.now();try{let s=await n({session:r,command:e.req.command,phase:"before-command"}),i=await t.run(a);await t.afterRun?.(i),await n({session:r,command:e.req.command,phase:"after-command"});let l=Date.now(),{result:c,responseData:f}=await t.buildPayloads(i);return"recovered"===s.status&&(c.warning=s.warning,f.warning=s.warning),C({session:r,sessionStore:e.sessionStore,command:e.req.command,positionals:e.req.positionals??[],retryPositionals:function(e,t){if(("ref"!==t.kind||t.node)&&("click"===e||"press"===e)&&t.point)return Q(t.point)}(e.req.command,i),flags:e.req.flags,result:c,responseData:f,actionStartedAt:o,actionFinishedAt:l,androidFreshnessBaseline:t.androidFreshnessBaseline})}catch(t){let e=m(t);if(y(e))throw e;return{ok:!1,error:k(t)}}}async function J(e,t){if(!l(t))return;let r=t.snapshot?.comparisonSafe===!0?t.snapshot:void 0;try{await e.captureSnapshotForSession(t,e.req.flags,e.sessionStore,e.contextFromFlags,{interactiveOnly:!0,androidFreshnessMode:"ref-refresh"})}catch(t){I({level:"warn",phase:"android_ref_snapshot_refresh_failed",data:{command:e.req.command,error:t instanceof Error?t.message:String(t)}})}return r}function Q(e){return[String(e.x),String(e.y)]}async function Z(e){let t=await j({...e,captureSnapshotForSession:R,refSnapshotFlagGuardResponse:N});if(t)return t;switch(e.req.command){case A.type:return await ee({...e,captureSnapshotForSession:R});case"get":return await _(e);case"is":return await b(e);default:return null}}async function ee(e){let{sessionName:t,sessionStore:r}=e,a=r.get(t);if(!a)return s("SESSION_NOT_FOUND","No active session. Run open first.");if(!o(A.type,a.device))return s("UNSUPPORTED_OPERATION","type is not supported on this device");let n=await et(a);return n||await er(e,a)}async function et(e){return"android"===e.device.platform&&e.recording&&"failed"===(await i({session:e})).status?s("COMMAND_FAILED","Android system dialog blocked the recording session"):null}async function er(e,t){let{req:r,sessionName:a,sessionStore:o}=e,s=(r.positionals??[]).join(" "),i=K(e),l=Date.now();try{let e=await n({session:t,command:r.command,phase:"before-command"}),c=await i.interactions.typeText(s,{session:a,requestId:r.meta?.requestId,delayMs:r.flags?.delayMs});await n({session:t,command:r.command,phase:"after-command"});let f=Date.now(),u={...c.backendResult??{},text:c.text,delayMs:c.delayMs,...p(c.message??`Typed ${Array.from(c.text).length} chars`)};return"recovered"===e.status&&(u.warning=e.warning),C({session:t,sessionStore:o,command:r.command,positionals:r.positionals??[],flags:r.flags,result:u,responseData:u,actionStartedAt:l,actionFinishedAt:f})}catch(e){return{ok:!1,error:k(e)}}}e.r(E),e.d(E,{handleInteractionCommands:()=>Z});export{E as interaction_namespaceObject};
1
+ import{__webpack_require__ as e}from"./rslib-runtime.js";import{isMacOs as t,publicPlatformString as r}from"./6849.js";import{createDaemonRuntimeSessionStore as a,setSessionSnapshot as n,dispatchCommand as s,requireCommandSupported as o,ensureAndroidBlockingSystemDialogReady as i,errorResponse as l,NO_ACTIVE_SESSION_MESSAGE as c,noActiveSessionError as f,recoverAndroidBlockingSystemDialog as u,getActiveAndroidSnapshotFreshness as d}from"./9722.js";import{buttonTag as p,resolveClickButton as g,readFillTargetFromPositionals as m,getClickButtonValidationError as k,successText as y}from"./2948.js";import{createAgentDevice as w}from"./7871.js";import{asAppError as _,normalizeError as S,AppError as h}from"./485.js";import{assertAndroidPressStayedInApp as b,isAndroidEscapeError as x,createDaemonRuntimePolicy as v,dispatchGetViaRuntime as F,dispatchIsViaRuntime as N,isDirectIosSelectorFallbackError as M,refSnapshotFlagGuardResponse as P,readSimpleIosSelectorTarget as R}from"./selector-runtime.js";import{resolveWebProvider as C}from"./provider.js";import{interaction_snapshot_captureSnapshotForSession as A,readSnapshotNodesReferenceFrame as q,resolveDirectTouchReferenceFrameSafely as I,buildTouchVisualizationResult as K,finalizeTouchInteraction as H}from"./8184.js";import{emitDiagnostic as E}from"./8875.js";import{PUBLIC_COMMANDS as D}from"./1986.js";var U={};function O(e,r){return t(e.device)&&("desktop"===e.surface||"menubar"===e.surface)&&("menubar"!==e.surface||"click"!==r&&"press"!==r)?l("UNSUPPORTED_OPERATION",`${r} is not supported on macOS ${e.surface} sessions yet. Open an app session to act, or use the ${e.surface} surface to inspect.`):null}function T(e){if(e.length<2)return null;let t=Number(e[0]),r=Number(e[1]);return Number.isFinite(t)&&Number.isFinite(r)?{x:t,y:r}:null}function L(e,t){let r=T(e);if(r)return{ok:!0,target:{kind:"point",x:r.x,y:r.y}};let a=e[0]??"";if(a.startsWith("@"))return{ok:!0,target:{kind:"ref",ref:a,fallbackLabel:e.slice(1).join(" ").trim()}};let n=e.join(" ").trim();return n?{ok:!0,target:{kind:"selector",selector:n}}:{ok:!1,response:l("INVALID_ARGS",`${t} requires @ref, selector expression, or x y coordinates`)}}function j(e){return"ref"===e.kind?{ref:B(e.target?.kind==="ref"?e.target.ref:void 0),refLabel:e.refLabel,selectorChain:e.selectorChain}:"selector"===e.kind?{selector:e.target?.kind==="selector"?e.target.selector:void 0,selectorChain:e.selectorChain,refLabel:e.refLabel}:{}}function B(e){return e?.startsWith("@")?e.slice(1):e}function G(e){let t=e.sessionStore.get(e.sessionName);if(!t)throw new h("SESSION_NOT_FOUND",c);return w({backend:function(e){let{req:t,session:a}=e,n=function(e){if("web"!==e.device.platform)return;let t=C();return t.clickRef||t.fillRef?t:void 0}(a);return{platform:r(a.device),captureSnapshot:async(r,n)=>({snapshot:await e.captureSnapshotForSession(a,t.flags,e.sessionStore,e.contextFromFlags,{interactiveOnly:n?.interactiveOnly===!0,includeRects:n?.includeRects===!0})}),tap:async(r,n)=>W(await s(a.device,"press",[String(n.x),String(n.y)],t.flags?.out,e.contextFromFlags(t.flags,a.appBundleId,a.trace?.outPath))),tapTarget:n?.clickRef?async(e,t)=>(await n.clickRef?.(t.ref),{ref:B(t.ref)}):void 0,fill:async(r,n,o)=>W(await s(a.device,"fill",[String(n.x),String(n.y),o],t.flags?.out,e.contextFromFlags(t.flags,a.appBundleId,a.trace?.outPath))),fillTarget:n?.fillRef?async(e,t,r,a)=>(await n.fillRef?.(t.ref,r,a),{ref:B(t.ref),text:r,delayMs:a?.delayMs??0}):void 0,longPress:async(r,n,o)=>W(await s(a.device,"longpress",[String(n.x),String(n.y),...o?.durationMs===void 0?[]:[String(o.durationMs)]],t.flags?.out,e.contextFromFlags(t.flags,a.appBundleId,a.trace?.outPath))),typeText:async(r,n)=>W(await s(a.device,"type",[n],t.flags?.out,e.contextFromFlags(t.flags,a.appBundleId,a.trace?.outPath)))}}({...e,session:t}),...v("interaction commands",{plural:!0}),sessions:a({sessionName:e.sessionName,getSession:()=>t,recordOptions:{includeSnapshot:!0},setRecord:r=>{r.snapshot&&(n(t,r.snapshot),e.sessionStore.set(e.sessionName,t))}})})}function W(e){return e&&"object"==typeof e?e:void 0}async function V(e){switch(e.req.command){case"press":return await $(e,"press");case"click":return await $(e,"click");case"longpress":return await $(e,"longpress");case"fill":return await Q(e);default:return null}}async function $(e,t){let a,{req:n,sessionName:s,sessionStore:i}=e,c=i.get(s);if(!c)return f();let u="click"===t?"click":t,d="longpress"===t?"longpress":"press",m=O(c,u);if(m)return m;let y=o(d,c.device);if(y)return y;let w=g(n.flags),_=p(w);if("longpress"!==t&&"primary"!==w){let e=k({commandLabel:u,platform:r(c.device),button:w,count:n.flags?.count,intervalMs:n.flags?.intervalMs,holdMs:n.flags?.holdMs,jitterPx:n.flags?.jitterPx,doubleTap:n.flags?.doubleTap});if(e)return l(e.code,e.message,e.details)}let S="longpress"===t?function(e){var t,r,a;let n,s=T(e);if(s){return{ok:!0,target:{kind:"point",x:s.x,y:s.y},...void 0===(t=e[2])?{}:{durationMs:Number(t)}}}let o=(n=(r=e).at(-1),r.length>1&&void 0!==(a=n)&&""!==a.trim()&&Number.isFinite(Number(a))?{targetPositionals:r.slice(0,-1),duration:{durationMs:Number(n)}}:{targetPositionals:r,duration:{}}),i=L(o.targetPositionals,"longpress");return i.ok?{ok:!0,target:i.target,...o.duration}:i}(n.positionals??[]):L(n.positionals??[],u);if(!S.ok)return S.response;if("ref"===S.target.kind){let r=e.refSnapshotFlagGuardResponse("longpress"===t?"longpress":"press",n.flags);if(r)return r;a=await er(e,c)}let h=function(e){var t;let{session:r,commandLabel:a,target:n,flags:s}=e;if("click"!==a||"selector"!==n.kind||(t=s,t?.count!==void 0||t?.intervalMs!==void 0||t?.holdMs!==void 0||t?.jitterPx!==void 0||t?.doubleTap!==void 0||t?.clickButton!==void 0&&"primary"!==t.clickButton))return null;let o=R({session:r,selectorExpression:n.selector});return o?{...o,...s?.maestro?.allowNonHittableCoordinateFallback?{allowNonHittableCoordinateFallback:!0}:{}}:null}({session:c,commandLabel:u,target:S.target,flags:n.flags});if(h){let t=await z(e,c,h);if(t)return t}let x="longpress"===t?S.durationMs:void 0;return await ee(e,{androidFreshnessBaseline:a,run:async e=>await X({runtime:e,command:t,target:S.target,sessionName:s,requestId:n.meta?.requestId,clickButton:w,flags:n.flags,durationMs:x}),afterRun:async e=>{if(!c.lease?.leaseProvider){var t;await b(c,(t=S.target,"point"===t.kind?"coordinate tap":"ref"===e.kind&&e.target?.kind==="ref"?e.target.ref:"selector"===e.kind&&e.target?.kind==="selector"?e.target.selector:"target"))}},buildPayloads:async r=>{var a;let n="durationMs"in(a=r)?a.durationMs:void 0,s=await Y({params:e,session:c,result:r,extra:"longpress"===t?{...void 0!==n?{durationMs:n}:{},gesture:"longpress"}:_});return{result:s,responseData:s}}})}async function X(e){let{runtime:t,command:r,target:a,sessionName:n,requestId:s,flags:o}=e;if("longpress"===r)return await t.interactions.longPress(a,{session:n,requestId:s,durationMs:e.durationMs});let i={session:n,requestId:s,button:e.clickButton,count:o?.count,intervalMs:o?.intervalMs,holdMs:o?.holdMs,jitterPx:o?.jitterPx,doubleTap:o?.doubleTap};return"click"===r?await t.interactions.click(a,i):await t.interactions.press(a,i)}async function Y(e){let{params:t,session:r,result:a,extra:n}=e,s="point"===a.kind?await I({session:r,flags:t.req.flags,sessionStore:t.sessionStore,contextFromFlags:t.contextFromFlags,captureSnapshotForSession:t.captureSnapshotForSession}):q(r.snapshot?.nodes??[]);return K({data:a.backendResult,fallbackX:a.point?.x,fallbackY:a.point?.y,referenceFrame:s,extra:{...j(a),...n}})}async function z(e,t,r){return await J({params:e,session:t,selector:r,command:"press",positionals:[],extra:{selector:r.raw},fallbackPhase:"ios_direct_selector_tap_fallback"})}async function J(e){let{params:t,session:r,selector:a,command:n,positionals:o,extra:i,fallbackPhase:l}=e,c=Date.now();try{var f,u;let e,l,d=await s(r.device,n,o,t.req.flags?.out,{...t.contextFromFlags(t.req.flags,r.appBundleId,r.trace?.outPath),directElementSelector:a,surface:r.surface})??{},p=Date.now(),g=(f=d,e="number"==typeof f.x?f.x:void 0,l="number"==typeof f.y?f.y:void 0,void 0!==e&&void 0!==l?{x:e,y:l}:{x:0,y:0}),m=K({data:d,fallbackX:g.x,fallbackY:g.y,referenceFrame:(u=d,"number"==typeof u.referenceWidth&&"number"==typeof u.referenceHeight?{referenceWidth:u.referenceWidth,referenceHeight:u.referenceHeight}:void 0),extra:{...i,...function(e,t){if(!e.allowNonHittableCoordinateFallback)return{};let r="tapped via non-hittable coordinate fallback"===t.message;return{maestroNonHittableCoordinateFallbackAllowed:!0,maestroNonHittableCoordinateFallbackUsed:r,...r?{maestroFallbackReason:"non-hittable-coordinate"}:{}}}(a,d)}});return H({session:r,sessionStore:t.sessionStore,command:t.req.command,positionals:t.req.positionals??[],retryPositionals:ea(g),flags:t.req.flags,result:m,responseData:m,actionStartedAt:c,actionFinishedAt:p})}catch(e){if(!M(e))return{ok:!1,error:S(e)};return E({level:"debug",phase:l,data:{selector:a.raw,error:e instanceof Error?e.message:String(e)}}),null}}async function Q(e){let{req:t,sessionName:r,sessionStore:a}=e,n=a.get(r);if(n){let e=O(n,"fill");if(e)return e;let t=o("fill",n.device);if(t)return t}if(!n)return f();let s=function(e){let t=e[0]??"";if(t.startsWith("@")){var r;let a=m(e).text;return a?{ok:!0,target:{kind:"ref",ref:t,fallbackLabel:(r=e).length>=3&&r[1]?.trim()||""},text:a}:{ok:!1,response:l("INVALID_ARGS","fill requires text after ref")}}let a=T(e);if(a){let t=e.slice(2).join(" ");return t?{ok:!0,target:{kind:"point",x:a.x,y:a.y},text:t}:{ok:!1,response:l("INVALID_ARGS","fill requires text after coordinates")}}let n=m(e);return"selector"!==n.kind?{ok:!1,response:l("INVALID_ARGS","fill requires x y text, @ref text, or selector text")}:n.text.trim()?{ok:!0,target:{kind:"selector",selector:n.target.selector},text:n.text}:{ok:!1,response:l("INVALID_ARGS","fill requires text after selector")}}(t.positionals??[]);if(!s.ok)return s.response;if("ref"===s.target.kind){let r=e.refSnapshotFlagGuardResponse("fill",t.flags);if(r)return r;await er(e,n)}let i=function(e){let{session:t,target:r,flags:a}=e;if("selector"!==r.kind)return null;let n=R({session:t,selectorExpression:r.selector});return n?{...n,...a?.maestro?.allowNonHittableCoordinateFallback?{allowNonHittableCoordinateFallback:!0}:{}}:null}({session:n,target:s.target,flags:t.flags});if(i){let t=await Z(e,n,i,s.text);if(t)return t}return await ee(e,{run:async e=>await e.interactions.fill(s.target,s.text,{session:r,requestId:t.meta?.requestId,delayMs:t.flags?.delayMs}),buildPayloads:e=>{let t="point"===e.kind?void 0:q(n.snapshot?.nodes??[]),r=K({data:e.backendResult,fallbackX:e.point?.x,fallbackY:e.point?.y,referenceFrame:t,extra:{...j(e),text:s.text}});e.warning&&(r.warning=e.warning);let a="ref"===e.kind?{...e.backendResult??{ref:B(e.target?.kind==="ref"?e.target.ref:void 0),...e.point?{x:e.point.x,y:e.point.y}:{}}}:r;return e.warning&&(a.warning=e.warning),{result:r,responseData:a}}})}async function Z(e,t,r,a){return await J({params:e,session:t,selector:r,command:"fill",positionals:[a],extra:{selector:r.raw,text:a},fallbackPhase:"ios_direct_selector_fill_fallback"})}async function ee(e,t){let r=e.sessionStore.get(e.sessionName);if(!r)return f();let a=G(e),n=Date.now();try{let{readiness:s,runtimeResult:o}=await et(r,e.req.command,async()=>{let e=await t.run(a);return await t.afterRun?.(e),e}),i=Date.now(),{result:l,responseData:c}=await t.buildPayloads(o);return"recovered"===s.status&&(l.warning=s.warning,c.warning=s.warning),H({session:r,sessionStore:e.sessionStore,command:e.req.command,positionals:e.req.positionals??[],retryPositionals:function(e,t){if(("ref"!==t.kind||t.node)&&("click"===e||"press"===e)&&t.point)return ea(t.point)}(e.req.command,o),flags:e.req.flags,result:l,responseData:c,actionStartedAt:n,actionFinishedAt:i,androidFreshnessBaseline:t.androidFreshnessBaseline})}catch(t){let e=_(t);if(x(e))throw e;return{ok:!1,error:S(t)}}}async function et(e,t,r){if(e.lease?.leaseProvider)return{readiness:{status:"clear"},runtimeResult:await r()};let a=await i({session:e,command:t,phase:"before-command"}),n=await r();return await i({session:e,command:t,phase:"after-command"}),{readiness:a,runtimeResult:n}}async function er(e,t){if(!d(t))return;let r=t.snapshot?.comparisonSafe===!0?t.snapshot:void 0;try{await e.captureSnapshotForSession(t,e.req.flags,e.sessionStore,e.contextFromFlags,{interactiveOnly:!0,androidFreshnessMode:"ref-refresh"})}catch(t){E({level:"warn",phase:"android_ref_snapshot_refresh_failed",data:{command:e.req.command,error:t instanceof Error?t.message:String(t)}})}return r}function ea(e){return[String(e.x),String(e.y)]}async function en(e){let t=await V({...e,captureSnapshotForSession:A,refSnapshotFlagGuardResponse:P});if(t)return t;switch(e.req.command){case D.type:return await es({...e,captureSnapshotForSession:A});case"get":return await F(e);case"is":return await N(e);default:return null}}async function es(e){let{sessionName:t,sessionStore:r}=e,a=r.get(t);if(!a)return f();let n=o(D.type,a.device);if(n)return n;let s=await eo(a);return s||await ei(e,a)}async function eo(e){return"android"===e.device.platform&&e.recording&&"failed"===(await u({session:e})).status?l("COMMAND_FAILED","Android system dialog blocked the recording session"):null}async function ei(e,t){let{req:r,sessionName:a,sessionStore:n}=e,s=(r.positionals??[]).join(" "),o=G(e),l=Date.now();try{let e=await i({session:t,command:r.command,phase:"before-command"}),c=await o.interactions.typeText(s,{session:a,requestId:r.meta?.requestId,delayMs:r.flags?.delayMs});await i({session:t,command:r.command,phase:"after-command"});let f=Date.now(),u={...c.backendResult??{},text:c.text,delayMs:c.delayMs,...y(c.message??`Typed ${Array.from(c.text).length} chars`)};return"recovered"===e.status&&(u.warning=e.warning),H({session:t,sessionStore:n,command:r.command,positionals:r.positionals??[],flags:r.flags,result:u,responseData:u,actionStartedAt:l,actionFinishedAt:f})}catch(e){return{ok:!1,error:S(e)}}}e.r(U),e.d(U,{handleInteractionCommands:()=>en});export{U as interaction_namespaceObject};
@@ -0,0 +1 @@
1
+ import{readSnapshotQualityVerdict as e,normalizeScrollDurationMs as a,buildScrollGesturePlan as t,assertScrollGestureInput as n}from"./2948.js";import{isIosFamily as o,isTvOsDevice as d,isMacOs as i}from"./6849.js";import{runMacOsScreenshotAction as r,runAppleRunnerCommand as s}from"./9722.js";import{parseRunnerSequenceResult as u,buildRunnerSequenceCommand as l}from"./runner-sequence.js";import{writeIosClipboardText as p,openIosApp as c,openIosDevice as m,screenshotIos as y,closeIosApp as v,setIosSetting as h,readIosClipboardText as f}from"./apps.js";import{withDiagnosticTimer as I}from"./8875.js";import{AppError as w}from"./485.js";function B(e,a,t){return{command:"remotePress",remoteButton:e,...void 0!==t?{durationMs:t}:{},...void 0!==a?{appBundleId:a}:{}}}function M(e,a,n,o={includeDuration:!0}){let d=g(e.referenceWidth),i=g(e.referenceHeight);if(void 0===d||void 0===i)return C(e,{amount:n?.amount});let r=t({direction:a,amount:n?.amount,pixels:n?.pixels,referenceWidth:d,referenceHeight:i});return C(e,{amount:n?.amount,pixels:r.pixels,durationMs:o?.includeDuration?n?.durationMs:void 0,preferProvidedPixels:!0})}function _(e,a={includeDuration:!0}){return{...e?.amount!==void 0?{amount:e.amount}:{},...e?.pixels!==void 0?{pixels:e.pixels}:{},...a?.includeDuration&&e?.durationMs!==void 0?{durationMs:e.durationMs}:{}}}function g(e){return"number"==typeof e&&Number.isFinite(e)?e:void 0}function C(e,a){var t,n,o,d;let i,r,s,u,{x1:l,y1:p,x2:c,y2:m}=(i=g((t=e).x),r=g(t.y),s=g(t.x2),u=g(t.y2),{...void 0!==i?{x1:i}:{},...void 0!==r?{y1:r}:{},...void 0!==s?{x2:s}:{},...void 0!==u?{y2:u}:{}}),y=g(e.referenceWidth),v=g(e.referenceHeight),h=(n=a,o=void 0!==l&&void 0!==c?Math.round(Math.abs(c-l)):void 0,d=void 0!==p&&void 0!==m?Math.round(Math.abs(m-p)):void 0,n?.preferProvidedPixels&&void 0!==n.pixels?n.pixels:void 0!==o&&o>0?o:void 0!==d&&d>0?d:void 0);return{...void 0!==l?{x1:l}:{},...void 0!==p?{y1:p}:{},...void 0!==c?{x2:c}:{},...void 0!==m?{y2:m}:{},...void 0!==y?{referenceWidth:y}:{},...void 0!==v?{referenceHeight:v}:{},...a?.amount!==void 0?{amount:a.amount}:{},...void 0!==h?{pixels:h}:{},...a?.durationMs!==void 0?{durationMs:a.durationMs}:{}}}async function S(e,a,t,n,o,d){return M(await e(a,{command:"desktopScroll",direction:o,..._(d,{includeDuration:!0}),appBundleId:t.appBundleId},n),o,d,{includeDuration:!0})}function x(e,a,t,n){return{command:"tap",x:t,y:n,...b(e)?{synthesized:!0}:{},appBundleId:a.appBundleId}}function b(e){return o(e)&&!d(e)}function D(e,a,t,n,i,r,s,u){var l,p;let c=o(e)&&!d(e)?(l=s,p=u.defaultDurationMs,void 0===l?p:Math.min(1e4,Math.max(16,Math.round(l)))):s??u.legacyDefaultDurationMs;return{command:"drag",x:t,y:n,x2:i,y2:r,...void 0!==c?{durationMs:c}:{},...!0===u.synthesized?{synthesized:!0}:{},appBundleId:a.appBundleId}}async function P(e,t,o,r,s,u){return(a(u?.durationMs,{invalidMessage:"scroll durationMs must be a non-negative integer at most 10000"}),d(t))?C(await e(t,B(s,o.appBundleId,u?.durationMs),r),{amount:u?.amount,durationMs:u?.durationMs}):(n(u??{}),i(t))?await S(e,t,o,r,s,u):M(await e(t,{command:"scroll",direction:s,..._(u),appBundleId:o.appBundleId},r),s,u)}function k(a,t){let n;if("watchos"===a.appleOs)throw new w("UNSUPPORTED_PLATFORM","watchOS is not supported: XCUITest cannot drive watchOS UI, so this device has no runner backend.");let{overrides:o,runnerOpts:M}={runnerOpts:n={verbose:t.verbose,logPath:t.logPath,traceLogPath:t.traceLogPath,requestId:t.requestId,iosXctestrunFile:t.iosXctestrunFile,iosXctestDerivedDataPath:t.iosXctestDerivedDataPath,iosXctestEnvDir:t.iosXctestEnvDir,runnerLeaseContext:t.runnerLeaseContext},overrides:{tap:async(e,o)=>await s(a,x(a,t,e,o),n),tapElementSelector:async e=>await s(a,{command:"tap",selectorKey:e.key,selectorValue:e.value,allowNonHittableCoordinateFallback:e.allowNonHittableCoordinateFallback,appBundleId:t.appBundleId},n),doubleTap:async(e,o)=>{let d=await s(a,l([{kind:"doubleTap",x:e,y:o}],t.appBundleId),n);return u(d),d},swipe:async(e,o,d,i,r)=>await s(a,D(a,t,e,o,d,i,r,{defaultDurationMs:250,synthesized:b(a)}),n),pan:async(e,o,d,i,r)=>await s(a,D(a,t,e,o,d,i,r,{defaultDurationMs:500,legacyDefaultDurationMs:500,synthesized:b(a)}),n),fling:async(e,o,d,i,r)=>await s(a,D(a,t,e,o,d,i,r,{defaultDurationMs:16,legacyDefaultDurationMs:16,synthesized:b(a)}),n),longPress:async(e,o,d)=>await s(a,{command:"longPress",x:e,y:o,durationMs:d,appBundleId:t.appBundleId},n),focus:async(e,o)=>await s(a,x(a,t,e,o),n),type:async(e,o)=>{await s(a,{command:"type",text:e,delayMs:o,textEntryMode:"\n"===e?void 0:"append",appBundleId:t.appBundleId},n)},fillElementSelector:async(e,o,d)=>await s(a,{command:"type",selectorKey:e.key,selectorValue:e.value,allowNonHittableCoordinateFallback:e.allowNonHittableCoordinateFallback,text:o,delayMs:d,textEntryMode:"replace",appBundleId:t.appBundleId},n),fill:async(e,o,d,i)=>await s(a,{command:"type",x:e,y:o,text:d,delayMs:i,textEntryMode:"replace",appBundleId:t.appBundleId},n),scroll:async(e,o)=>await P(s,a,t,n,e,o),pinch:async(e,o,d)=>{await s(a,{command:"pinch",scale:e,x:o,y:d,appBundleId:t.appBundleId},n)},rotateGesture:async(e,o,d,i)=>{await s(a,{command:"rotateGesture",degrees:e,x:o,y:d,velocity:i,appBundleId:t.appBundleId},n)},transformGesture:async e=>await s(a,{command:"transformGesture",x:e.x,y:e.y,dx:e.dx,dy:e.dy,scale:e.scale,degrees:e.degrees,durationMs:e.durationMs,appBundleId:t.appBundleId},n)}};return{open:(e,t)=>c(a,e,{appBundleId:t?.appBundleId,launchConsole:t?.launchConsole,launchArgs:t?.launchArgs,terminateRunningApp:t?.terminateRunningApp,url:t?.url}),openDevice:()=>m(a),close:e=>v(a,e),screenshot:async(e,t)=>{i(a)&&t?.surface&&"app"!==t.surface?await r(e,{surface:t.surface,fullscreen:t.fullscreen}):await y(a,e,{appBundleId:t?.appBundleId,fullscreen:t?.fullscreen,runnerOptions:M,normalizeStatusBar:t?.normalizeStatusBar,skipIosSimulatorBootCheck:t?.skipIosSimulatorBootCheck})},snapshot:async t=>{var n;let o={nodes:Array.isArray((n=await I("snapshot_capture",async()=>await s(a,{command:"snapshot",appBundleId:t?.appBundleId,interactiveOnly:t?.interactiveOnly,depth:t?.depth,scope:t?.scope,raw:t?.raw},M),{backend:"xctest"})).nodes)?n.nodes:void 0,truncated:"boolean"==typeof n.truncated?n.truncated:void 0,quality:e(n.snapshotQuality),message:"string"==typeof n.message&&n.message.trim().length>0?n.message:void 0},d=o.nodes??[];if(0===d.length&&"simulator"===a.kind)throw new w("COMMAND_FAILED","XCTest snapshot returned 0 nodes on iOS simulator.");return{nodes:d,truncated:o.truncated??!1,backend:"xctest",...o.quality?{quality:o.quality}:{},...!o.quality&&o.message?{warnings:[o.message]}:{}}},back:async e=>{d(a)?await s(a,B("menu",t.appBundleId),M):await s(a,{command:"system"===e?"backSystem":"backInApp",appBundleId:t.appBundleId},M)},home:async()=>{d(a)?await s(a,B("home",t.appBundleId),M):await s(a,{command:"home",appBundleId:t.appBundleId},M)},rotate:async e=>{await s(a,{command:"rotate",orientation:e,appBundleId:t.appBundleId},M)},appSwitcher:async()=>{await s(a,{command:"appSwitcher",appBundleId:t.appBundleId},M)},readClipboard:()=>f(a),writeClipboard:e=>p(a,e),setSetting:(e,t,n,o)=>h(a,e,t,n,o),...o}}export{k as createAppleInteractor};
@@ -1,5 +1,5 @@
1
1
  var e,t,r,s;let n,o=process.argv.slice(2);function c(e){return"--help"===e||"-h"===e}function i(e){import("../cli.js").then(({runCli:t})=>t(e)).catch(p)}function p(e){process.stderr.write(`${e instanceof Error?e.message:String(e)}
2
- `),process.exit(1)}1===(t=e=o).length&&("--version"===(r=t[0])||"-V"===r)&&(process.stdout.write(`0.18.0
2
+ `),process.exit(1)}1===(t=e=o).length&&("--version"===(r=t[0])||"-V"===r)&&(process.stdout.write(`0.18.2
3
3
  `),1)||0===e.length&&(import("../cli-help.js").then(({buildUsageText:e})=>{process.stdout.write(`${e()}
4
4
  `),process.exit(1)}).catch(p),1)||void 0!==(n=function(e){var t,r,s,n;switch(e.length){case 1:return"help"===(t=e[0])||c(t)?null:void 0;case 2:return r=e[0],s=e[1],"help"===r?s:(n=r,c(s)?n:void 0);default:return}}(s=e))&&(import("../cli-help.js").then(({buildCommandUsageText:e,buildUsageText:t})=>{var r;if(null===n)return void process.stdout.write(`${t()}
5
5
  `);let o=e("long-press"===(r=n)?"longpress":"metrics"===r?"perf":r);o?process.stdout.write(o):i(s)}).catch(p),1)||("mcp"!==o[0]||o.includes("--help")||o.includes("-h")?i(o):import("../server.js").then(({runAgentDeviceMcpServer:e})=>e()).catch(p));export{};
@@ -1 +1 @@
1
- import e from"node:fs";import{setTimeout as r}from"node:timers/promises";import{normalizeBaseUrl as t,ENV_COMPANION_TUNNEL_UNREGISTER_PATH as n,MissingCompanionEnvError as s,ENV_COMPANION_TUNNEL_SERVER_BASE_URL as a,ENV_COMPANION_TUNNEL_STATE_PATH as o,ENV_COMPANION_TUNNEL_LAUNCH_URL as i,ENV_COMPANION_TUNNEL_SCOPE_LEASE_ID as c,ENV_COMPANION_TUNNEL_SCOPE_TENANT_ID as l,ENV_COMPANION_TUNNEL_DEVICE_PORT as f,METRO_COMPANION_RUN_ARG as u,ENV_COMPANION_TUNNEL_SESSION as d,ENV_COMPANION_TUNNEL_SCOPE_RUN_ID as m,ENV_COMPANION_TUNNEL_REGISTER_PATH as y,ENV_COMPANION_TUNNEL_LOCAL_BASE_URL as p,REACT_DEVTOOLS_COMPANION_RUN_ARG as g,ENV_COMPANION_TUNNEL_BEARER_TOKEN as w}from"../4069.js";class h extends Error{retryable;retryAfterMs;constructor(e,r,t){super(e),this.retryable=r,this.retryAfterMs=t}}function b(e,r){return{authorization:`Bearer ${r}`,"content-type":"application/json",...e.includes("ngrok")?{"ngrok-skip-browser-warning":"1"}:{}}}function S(e){return{...e.bridgeScope,...e.session?{session:e.session}:{},local_base_url:t(e.localBaseUrl),...e.devicePort?{device_port:e.devicePort}:{},...e.launchUrl?{launch_url:e.launchUrl}:{}}}async function v(e){let r,n,s=e.registerPath;try{r=await fetch(`${t(e.serverBaseUrl)}${s}`,{method:"POST",headers:b(e.serverBaseUrl,e.bearerToken),body:JSON.stringify(S(e)),signal:AbortSignal.timeout(5e3)})}catch(r){if(r instanceof Error&&"TimeoutError"===r.name)throw Error(`${s} timed out after 5000ms calling ${t(e.serverBaseUrl)}${s}`);throw r}let a=await r.text();try{n=a?JSON.parse(a):{}}catch{let e;throw new h(`Failed to register companion (${r.status}): invalid JSON response: ${(e=a.replaceAll(/\s+/g," ").trim()).length>300?`${e.slice(0,300)}...`:e}`,I(r.status,void 0),E(r,{}))}if(!r.ok||!0!==n.ok||"string"!=typeof n.data?.ws_url)throw new h(`Failed to register companion (${r.status}): ${JSON.stringify(n)}`,I(r.status,n.error?.code),E(r,n));return{wsUrl:n.data.ws_url}}function I(e,r){return"RATE_LIMITED"===r||"UNAUTHORIZED"!==r&&"INVALID_ARGS"!==r&&"SESSION_NOT_FOUND"!==r&&(408===e||409===e||425===e||429===e||e>=500)}function E(e,r){let t=r.error?.details?.retryAfterMs;if("number"==typeof t&&Number.isFinite(t))return B(t);let n=e.headers.get("retry-after");if(!n)return;let s=Number(n);if(Number.isFinite(s))return B(1e3*s);let a=Date.parse(n);if(Number.isFinite(a))return B(a-Date.now())}function B(e){return Math.max(0,Math.min(6e4,Math.ceil(e)))}async function N(e){let r=e.unregisterPath??null;if(r)try{await fetch(`${t(e.serverBaseUrl)}${r}`,{method:"POST",headers:b(e.serverBaseUrl,e.bearerToken),body:JSON.stringify(S(e)),signal:AbortSignal.timeout(2e3)})}catch(e){console.error(e instanceof Error?e.message:String(e))}}async function k(e){return"string"==typeof e?Buffer.from(e,"utf8"):e instanceof ArrayBuffer?Buffer.from(e):ArrayBuffer.isView(e)?Buffer.from(e.buffer,e.byteOffset,e.byteLength):"u">typeof Blob&&e instanceof Blob?Buffer.from(await e.arrayBuffer()):Buffer.from(String(e),"utf8")}async function L(e){return JSON.parse((await k(e.data)).toString("utf8"))}function U(e,r){1===e.readyState&&e.send(JSON.stringify(r))}async function P(e,r){1!==e.readyState&&await new Promise((t,n)=>{let s=()=>{i(),t()},a=()=>{i(),n(Error(`${r} WebSocket failed before opening.`))},o=()=>{i(),n(Error(`${r} WebSocket closed before opening.`))},i=()=>{e.removeEventListener("open",s),e.removeEventListener("error",a),e.removeEventListener("close",o)};e.addEventListener("open",s,{once:!0}),e.addEventListener("error",a,{once:!0}),e.addEventListener("close",o,{once:!0})})}async function O(e){e.readyState>=WebSocket.CLOSING||await new Promise(r=>{let t=()=>{n(),r()},n=()=>{e.removeEventListener("close",t),e.removeEventListener("error",t)};e.addEventListener("close",t,{once:!0}),e.addEventListener("error",t,{once:!0}),e.readyState>=WebSocket.CLOSING&&t()})}function T(e,r,t){try{e.close(1e3===r||r>=3e3&&r<=4999?r:3001,t)}catch{}}function $(r){return!r.statePath||e.existsSync(r.statePath)}async function M(e,r,n){try{let s=await fetch(new URL(r.path,`${t(n.localBaseUrl)}/`),{method:r.method,headers:r.headers,...r.bodyBase64?{body:Buffer.from(r.bodyBase64,"base64")}:{}}),a=Buffer.from(await s.arrayBuffer());U(e,{type:"http-response",requestId:r.requestId,status:s.status,headers:Object.fromEntries(s.headers.entries()),...a.length>0?{bodyBase64:a.toString("base64")}:{}})}catch(t){U(e,{type:"http-error",requestId:r.requestId,message:t instanceof Error?t.message:String(t)})}}async function _(e,r,n,s){var a;let o,i=new WebSocket((a=n.localBaseUrl,(o=new URL(r.path,`${t(a)}/`)).protocol="https:"===o.protocol?"wss:":"ws:",o.toString()));i.binaryType="arraybuffer";let c=!1;i.addEventListener("message",t=>{(async()=>{if(!c)return;let n=await k(t.data);U(e,{type:"ws-frame",streamId:r.streamId,dataBase64:n.toString("base64"),binary:"string"!=typeof t.data})})().catch(e=>{console.error(e instanceof Error?e.message:String(e))})}),i.addEventListener("close",t=>{s.delete(r.streamId),c&&U(e,{type:"ws-close",streamId:r.streamId,code:t.code,reason:t.reason})}),i.addEventListener("error",()=>{c&&U(e,{type:"ws-close",streamId:r.streamId,code:1011,reason:"Upstream WebSocket error."})}),s.set(r.streamId,i);try{await P(i,"Upstream"),c=!0,U(e,{type:"ws-open-result",streamId:r.streamId,success:!0,headers:{}})}catch(t){s.delete(r.streamId),T(i,1011,"open failed"),U(e,{type:"ws-open-result",streamId:r.streamId,success:!1,error:t instanceof Error?t.message:String(t)})}}async function A(e,r,t,n){switch(r.type){case"ping":return void U(e,{type:"pong",timestamp:r.timestamp});case"http-request":return void await M(e,r,t);case"ws-open":return void await _(e,r,t,n);case"ws-frame":return void function(e,r){let t=r.get(e.streamId);if(!t||1!==t.readyState)return;let n=Buffer.from(e.dataBase64,"base64");t.send(e.binary?n:n.toString("utf8"))}(r,n);case"ws-close":return void function(e,r){let t=r.get(e.streamId);if(t){var n;r.delete(e.streamId),T(t,"number"==typeof(n=e.code)&&Number.isInteger(n)&&(1e3===n||n>=3e3&&n<=4999||n>=1001&&n<=1015&&1004!==n&&1005!==n&&1006!==n)?n:1011,e.reason??"bridge requested close")}}(r,n)}}async function x(e,t={}){let n,s=new Map,a=!1,o=null,i=!1,c=null,l=t.delay??r,f=new Promise(e=>{n=e}),u=()=>{t.exit?.(0)},d=async()=>{(i||c)&&(c??=N(e).finally(()=>{i=!1,c=null}),await c)},m=()=>{!a&&(a=!0,n(),i&&d().finally(u),o&&T(o,1e3,"companion stopping"),t.exit&&setTimeout(u,900).unref())};t.registerProcessSignals&&(process.once("SIGTERM",m),process.once("SIGINT",m));let y=setInterval(()=>{$(e)||(m(),u())},t.leaseCheckIntervalMs??250);y.unref();let p=t.reconnectDelayMs??1e3;try{for(;!a&&$(e);){var g;let r,n=!1;try{i=!1;let r=await v(e);if(p=t.reconnectDelayMs??1e3,n=!0,i=!0,a||!$(e)){await d(),n=!1;break}let c=new WebSocket(r.wsUrl);o=c,c.binaryType="arraybuffer";try{await P(c,"Bridge"),c.addEventListener("message",r=>{(async()=>{let t=await L(r);await A(c,t,e,s)})().catch(e=>{console.error(e instanceof Error?e.message:String(e))})}),await Promise.race([O(c),f])}finally{o=null,s.forEach(e=>T(e,1012,"bridge disconnected")),s.clear(),n&&(await d(),n=!1)}}catch(t){if(o=null,n&&(await d(),n=!1),a||!$(e)||(console.error(t instanceof Error?t.message:String(t)),t instanceof h&&!t.retryable))break;r=t instanceof h?t.retryAfterMs:void 0}if(a||!$(e))break;let c=r??p;void 0===r&&(g=p,p=Math.min(2*g,6e4)),await l(c)}}finally{clearInterval(y),t.registerProcessSignals&&(process.off("SIGTERM",m),process.off("SIGINT",m))}}(async function(e,r){let t=function(e,r){let t=e[0];if(t!==u&&t!==g)return null;let h=r[a]?.trim(),b=r[w]?.trim(),S=r[p]?.trim();if(!h||!b||!S)throw new s("Companion tunnel worker is missing required environment configuration.");let v=r[l]?.trim(),I=r[m]?.trim(),E=r[c]?.trim();if(!v||!I||!E)throw new s("Companion tunnel worker is missing required bridge scope configuration.");let B=r[y]?.trim();if(!B)throw new s("Companion tunnel worker is missing required register path configuration.");return{serverBaseUrl:h,bearerToken:b,localBaseUrl:S,registerPath:B,bridgeScope:{tenantId:v,runId:I,leaseId:E},launchUrl:r[i]?.trim(),statePath:r[o]?.trim(),unregisterPath:r[n]?.trim(),devicePort:function(e){if(!e?.trim())return;let r=Number.parseInt(e,10);if(!Number.isInteger(r)||r<1||r>65535)throw Error("Companion worker received invalid device port configuration.");return r}(r[f]?.trim()),session:r[d]?.trim()}}(e,r);return!!t&&(await x(t,{exit:e=>process.exit(e),registerProcessSignals:!0}),!0)})(process.argv.slice(2),process.env).catch(e=>{if(e instanceof s){console.error(e.message),process.exitCode=1;return}console.error(e instanceof Error?e.stack??e.message:String(e)),process.exitCode=1});
1
+ import e from"node:fs";import{setTimeout as r}from"node:timers/promises";import{normalizeBaseUrl as t,ENV_COMPANION_TUNNEL_UNREGISTER_PATH as n,MissingCompanionEnvError as s,ENV_COMPANION_TUNNEL_SERVER_BASE_URL as a,ENV_COMPANION_TUNNEL_STATE_PATH as o,ENV_COMPANION_TUNNEL_LAUNCH_URL as i,ENV_COMPANION_TUNNEL_SCOPE_LEASE_ID as c,ENV_COMPANION_TUNNEL_SCOPE_TENANT_ID as l,ENV_COMPANION_TUNNEL_DEVICE_PORT as f,METRO_COMPANION_RUN_ARG as u,ENV_COMPANION_TUNNEL_SESSION as d,ENV_COMPANION_TUNNEL_SCOPE_RUN_ID as m,ENV_COMPANION_TUNNEL_REGISTER_PATH as y,ENV_COMPANION_TUNNEL_LOCAL_BASE_URL as p,REACT_DEVTOOLS_COMPANION_RUN_ARG as g,ENV_COMPANION_TUNNEL_BEARER_TOKEN as w}from"../4917.js";class h extends Error{retryable;retryAfterMs;constructor(e,r,t){super(e),this.retryable=r,this.retryAfterMs=t}}function b(e,r){return{authorization:`Bearer ${r}`,"content-type":"application/json",...e.includes("ngrok")?{"ngrok-skip-browser-warning":"1"}:{}}}function S(e){return{...e.bridgeScope,...e.session?{session:e.session}:{},local_base_url:t(e.localBaseUrl),...e.devicePort?{device_port:e.devicePort}:{},...e.launchUrl?{launch_url:e.launchUrl}:{}}}async function v(e){let r,n,s=e.registerPath;try{r=await fetch(`${t(e.serverBaseUrl)}${s}`,{method:"POST",headers:b(e.serverBaseUrl,e.bearerToken),body:JSON.stringify(S(e)),signal:AbortSignal.timeout(5e3)})}catch(r){if(r instanceof Error&&"TimeoutError"===r.name)throw Error(`${s} timed out after 5000ms calling ${t(e.serverBaseUrl)}${s}`);throw r}let a=await r.text();try{n=a?JSON.parse(a):{}}catch{let e;throw new h(`Failed to register companion (${r.status}): invalid JSON response: ${(e=a.replaceAll(/\s+/g," ").trim()).length>300?`${e.slice(0,300)}...`:e}`,I(r.status,void 0),E(r,{}))}if(!r.ok||!0!==n.ok||"string"!=typeof n.data?.ws_url)throw new h(`Failed to register companion (${r.status}): ${JSON.stringify(n)}`,I(r.status,n.error?.code),E(r,n));return{wsUrl:n.data.ws_url}}function I(e,r){return"RATE_LIMITED"===r||"UNAUTHORIZED"!==r&&"INVALID_ARGS"!==r&&"SESSION_NOT_FOUND"!==r&&(408===e||409===e||425===e||429===e||e>=500)}function E(e,r){let t=r.error?.details?.retryAfterMs;if("number"==typeof t&&Number.isFinite(t))return B(t);let n=e.headers.get("retry-after");if(!n)return;let s=Number(n);if(Number.isFinite(s))return B(1e3*s);let a=Date.parse(n);if(Number.isFinite(a))return B(a-Date.now())}function B(e){return Math.max(0,Math.min(6e4,Math.ceil(e)))}async function N(e){let r=e.unregisterPath??null;if(r)try{await fetch(`${t(e.serverBaseUrl)}${r}`,{method:"POST",headers:b(e.serverBaseUrl,e.bearerToken),body:JSON.stringify(S(e)),signal:AbortSignal.timeout(2e3)})}catch(e){console.error(e instanceof Error?e.message:String(e))}}async function k(e){return"string"==typeof e?Buffer.from(e,"utf8"):e instanceof ArrayBuffer?Buffer.from(e):ArrayBuffer.isView(e)?Buffer.from(e.buffer,e.byteOffset,e.byteLength):"u">typeof Blob&&e instanceof Blob?Buffer.from(await e.arrayBuffer()):Buffer.from(String(e),"utf8")}async function L(e){return JSON.parse((await k(e.data)).toString("utf8"))}function U(e,r){1===e.readyState&&e.send(JSON.stringify(r))}async function P(e,r){1!==e.readyState&&await new Promise((t,n)=>{let s=()=>{i(),t()},a=()=>{i(),n(Error(`${r} WebSocket failed before opening.`))},o=()=>{i(),n(Error(`${r} WebSocket closed before opening.`))},i=()=>{e.removeEventListener("open",s),e.removeEventListener("error",a),e.removeEventListener("close",o)};e.addEventListener("open",s,{once:!0}),e.addEventListener("error",a,{once:!0}),e.addEventListener("close",o,{once:!0})})}async function O(e){e.readyState>=WebSocket.CLOSING||await new Promise(r=>{let t=()=>{n(),r()},n=()=>{e.removeEventListener("close",t),e.removeEventListener("error",t)};e.addEventListener("close",t,{once:!0}),e.addEventListener("error",t,{once:!0}),e.readyState>=WebSocket.CLOSING&&t()})}function T(e,r,t){try{e.close(1e3===r||r>=3e3&&r<=4999?r:3001,t)}catch{}}function $(r){return!r.statePath||e.existsSync(r.statePath)}async function M(e,r,n){try{let s=await fetch(new URL(r.path,`${t(n.localBaseUrl)}/`),{method:r.method,headers:r.headers,...r.bodyBase64?{body:Buffer.from(r.bodyBase64,"base64")}:{}}),a=Buffer.from(await s.arrayBuffer());U(e,{type:"http-response",requestId:r.requestId,status:s.status,headers:Object.fromEntries(s.headers.entries()),...a.length>0?{bodyBase64:a.toString("base64")}:{}})}catch(t){U(e,{type:"http-error",requestId:r.requestId,message:t instanceof Error?t.message:String(t)})}}async function _(e,r,n,s){var a;let o,i=new WebSocket((a=n.localBaseUrl,(o=new URL(r.path,`${t(a)}/`)).protocol="https:"===o.protocol?"wss:":"ws:",o.toString()));i.binaryType="arraybuffer";let c=!1;i.addEventListener("message",t=>{(async()=>{if(!c)return;let n=await k(t.data);U(e,{type:"ws-frame",streamId:r.streamId,dataBase64:n.toString("base64"),binary:"string"!=typeof t.data})})().catch(e=>{console.error(e instanceof Error?e.message:String(e))})}),i.addEventListener("close",t=>{s.delete(r.streamId),c&&U(e,{type:"ws-close",streamId:r.streamId,code:t.code,reason:t.reason})}),i.addEventListener("error",()=>{c&&U(e,{type:"ws-close",streamId:r.streamId,code:1011,reason:"Upstream WebSocket error."})}),s.set(r.streamId,i);try{await P(i,"Upstream"),c=!0,U(e,{type:"ws-open-result",streamId:r.streamId,success:!0,headers:{}})}catch(t){s.delete(r.streamId),T(i,1011,"open failed"),U(e,{type:"ws-open-result",streamId:r.streamId,success:!1,error:t instanceof Error?t.message:String(t)})}}async function A(e,r,t,n){switch(r.type){case"ping":return void U(e,{type:"pong",timestamp:r.timestamp});case"http-request":return void await M(e,r,t);case"ws-open":return void await _(e,r,t,n);case"ws-frame":return void function(e,r){let t=r.get(e.streamId);if(!t||1!==t.readyState)return;let n=Buffer.from(e.dataBase64,"base64");t.send(e.binary?n:n.toString("utf8"))}(r,n);case"ws-close":return void function(e,r){let t=r.get(e.streamId);if(t){var n;r.delete(e.streamId),T(t,"number"==typeof(n=e.code)&&Number.isInteger(n)&&(1e3===n||n>=3e3&&n<=4999||n>=1001&&n<=1015&&1004!==n&&1005!==n&&1006!==n)?n:1011,e.reason??"bridge requested close")}}(r,n)}}async function x(e,t={}){let n,s=new Map,a=!1,o=null,i=!1,c=null,l=t.delay??r,f=new Promise(e=>{n=e}),u=()=>{t.exit?.(0)},d=async()=>{(i||c)&&(c??=N(e).finally(()=>{i=!1,c=null}),await c)},m=()=>{!a&&(a=!0,n(),i&&d().finally(u),o&&T(o,1e3,"companion stopping"),t.exit&&setTimeout(u,900).unref())};t.registerProcessSignals&&(process.once("SIGTERM",m),process.once("SIGINT",m));let y=setInterval(()=>{$(e)||(m(),u())},t.leaseCheckIntervalMs??250);y.unref();let p=t.reconnectDelayMs??1e3;try{for(;!a&&$(e);){var g;let r,n=!1;try{i=!1;let r=await v(e);if(p=t.reconnectDelayMs??1e3,n=!0,i=!0,a||!$(e)){await d(),n=!1;break}let c=new WebSocket(r.wsUrl);o=c,c.binaryType="arraybuffer";try{await P(c,"Bridge"),c.addEventListener("message",r=>{(async()=>{let t=await L(r);await A(c,t,e,s)})().catch(e=>{console.error(e instanceof Error?e.message:String(e))})}),await Promise.race([O(c),f])}finally{o=null,s.forEach(e=>T(e,1012,"bridge disconnected")),s.clear(),n&&(await d(),n=!1)}}catch(t){if(o=null,n&&(await d(),n=!1),a||!$(e)||(console.error(t instanceof Error?t.message:String(t)),t instanceof h&&!t.retryable))break;r=t instanceof h?t.retryAfterMs:void 0}if(a||!$(e))break;let c=r??p;void 0===r&&(g=p,p=Math.min(2*g,6e4)),await l(c)}}finally{clearInterval(y),t.registerProcessSignals&&(process.off("SIGTERM",m),process.off("SIGINT",m))}}(async function(e,r){let t=function(e,r){let t=e[0];if(t!==u&&t!==g)return null;let h=r[a]?.trim(),b=r[w]?.trim(),S=r[p]?.trim();if(!h||!b||!S)throw new s("Companion tunnel worker is missing required environment configuration.");let v=r[l]?.trim(),I=r[m]?.trim(),E=r[c]?.trim();if(!v||!I||!E)throw new s("Companion tunnel worker is missing required bridge scope configuration.");let B=r[y]?.trim();if(!B)throw new s("Companion tunnel worker is missing required register path configuration.");return{serverBaseUrl:h,bearerToken:b,localBaseUrl:S,registerPath:B,bridgeScope:{tenantId:v,runId:I,leaseId:E},launchUrl:r[i]?.trim(),statePath:r[o]?.trim(),unregisterPath:r[n]?.trim(),devicePort:function(e){if(!e?.trim())return;let r=Number.parseInt(e,10);if(!Number.isInteger(r)||r<1||r>65535)throw Error("Companion worker received invalid device port configuration.");return r}(r[f]?.trim()),session:r[d]?.trim()}}(e,r);return!!t&&(await x(t,{exit:e=>process.exit(e),registerProcessSignals:!0}),!0)})(process.argv.slice(2),process.env).catch(e=>{if(e instanceof s){console.error(e.message),process.exitCode=1;return}console.error(e instanceof Error?e.stack??e.message:String(e)),process.exitCode=1});
@@ -1 +1 @@
1
- import{parentPort as e}from"node:worker_threads";import{normalizeError as t}from"../733.js";import{computeScreenshotDiffPixels as r,PNG as i,toBuffer as n,decodePng as d}from"../4418.js";function f(e){return e.buffer instanceof ArrayBuffer&&0===e.byteOffset&&e.byteLength===e.buffer.byteLength}function a(e){return(function(e){switch(e.kind){case"decode":return[e.data];case"encode":return[e.png];case"diff-pixels":return[e.diffData,e.diffMask]}})(e).filter(f).map(e=>e.buffer)}e&&e.on("message",f=>{let o;try{o={id:f.id,ok:!0,result:function(e){switch(e.kind){case"decode":{let t=d(n(e.png),e.label);return{kind:"decode",width:t.width,height:t.height,data:t.data}}case"encode":{let t=new i({width:e.width,height:e.height,data:n(e.data)});return{kind:"encode",png:i.sync.write(t)}}case"diff-pixels":return{kind:"diff-pixels",...r(e)}}}(f)}}catch(e){o={id:f.id,ok:!1,error:t(e)}}e.postMessage(o,o.ok?a(o.result):[])});export{a as resultTransferList};
1
+ import{parentPort as e}from"node:worker_threads";import{normalizeError as t}from"../485.js";import{computeScreenshotDiffPixels as r,PNG as i,toBuffer as n,decodePng as d}from"../4418.js";function f(e){return e.buffer instanceof ArrayBuffer&&0===e.byteOffset&&e.byteLength===e.buffer.byteLength}function a(e){return(function(e){switch(e.kind){case"decode":return[e.data];case"encode":return[e.png];case"diff-pixels":return[e.diffData,e.diffMask]}})(e).filter(f).map(e=>e.buffer)}e&&e.on("message",f=>{let o;try{o={id:f.id,ok:!0,result:function(e){switch(e.kind){case"decode":{let t=d(n(e.png),e.label);return{kind:"decode",width:t.width,height:t.height,data:t.data}}case"encode":{let t=new i({width:e.width,height:e.height,data:n(e.data)});return{kind:"encode",png:i.sync.write(t)}}case"diff-pixels":return{kind:"diff-pixels",...r(e)}}}(f)}}catch(e){o={id:f.id,ok:!1,error:t(e)}}e.postMessage(o,o.ok?a(o.result):[])});export{a as resultTransferList};
package/dist/src/lease.js CHANGED
@@ -1 +1 @@
1
- import{resolveLeaseScope as e}from"./9722.js";import{leaseScopeToAllocateRequest as a,leaseScopeToHeartbeatRequest as t,leaseScopeToReleaseRequest as r}from"./2948.js";async function s(s){let{req:l,leaseRegistry:o}=s,_=e(l);switch(l.command){case"lease_allocate":return{ok:!0,data:{lease:o.allocateLease(a(_))}};case"lease_heartbeat":return{ok:!0,data:{lease:o.heartbeatLease(t(_))}};case"lease_release":return{ok:!0,data:o.releaseLease(r(_))};default:return null}}export{s as handleLeaseCommands};
1
+ import{PUBLIC_COMMANDS as e}from"./1986.js";import{resolveRequestOrSessionLeaseScope as a,resolveLeaseScope as r}from"./9722.js";import{leaseScopeToAllocateRequest as t,leaseScopeToReleaseRequest as o,leaseScopeToHeartbeatRequest as s}from"./2948.js";import{AppError as i}from"./485.js";async function l(i){let{req:l,sessionName:n,sessionStore:c,leaseRegistry:_,leaseLifecycleProvider:v,cloudArtifactProvider:f}=i,u=r(l);switch(l.command){case e.artifacts:{let e=a(l,c.get(n));return{ok:!0,data:await d(l,e,f)}}case"lease_allocate":{let e,a=_.allocateLease(t(u));try{e=await v?.allocate?.(a,{req:l})}catch(e){throw _.releaseLease(o({leaseId:a.leaseId,tenantId:a.tenantId,runId:a.runId,leaseBackend:a.backend,leaseProvider:a.leaseProvider,deviceKey:a.deviceKey,clientId:a.clientId})),e}return{ok:!0,data:{lease:a,...e?{provider:e}:{}}}}case"lease_heartbeat":{let e=_.heartbeatLease(s(u)),a=await v?.heartbeat?.(e,{req:l});return{ok:!0,data:{lease:e,...a?{provider:a}:{}}}}case"lease_release":{let e=_.releaseLease(o(u)),a=e.lease?await v?.release?.(e.lease,{req:l}):void 0;return{ok:!0,data:{released:e.released,...a?{provider:a}:{}}}}default:return null}}async function d(e,a,r){var t;let o,s=(t=e.flags,"string"==typeof(o=t?.providerSessionId)&&o.length>0?o:void 0);if(!a.leaseProvider)throw new i("INVALID_ARGS","artifacts requires --provider for provider session lookup or an active cloud connection.");if(!a.leaseId&&!s)throw new i("INVALID_ARGS","artifacts requires an active cloud lease or --provider-session <id>.");let l=await r?.listCloudArtifacts?.({provider:a.leaseProvider,leaseId:a.leaseId,providerSessionId:s});if(!l)throw new i("UNSUPPORTED_OPERATION",`Cloud artifacts are not available for provider "${a.leaseProvider}".`);return l}export{l as handleLeaseCommands};
package/dist/src/linux.js CHANGED
@@ -1 +1 @@
1
- import{longPressLinux as t,pressLinux as e,typeLinux as n,scrollLinux as o,sendKey as r,fillLinux as a,focusLinux as i,swipeLinux as s,doubleClickLinux as p}from"./input-actions~1.js";import{snapshotLinux as u,resolveLinuxToolProvider as c}from"./9722.js";import{AppError as w}from"./733.js";import{withDiagnosticTimer as _}from"./432.js";async function P(t){await c().desktop.openTarget(t)}async function d(t){await c().desktop.closeApp(t)}async function O(){await r("alt+Left",["56:1","105:1","105:0","56:0"])}async function f(){await r("super+d",["125:1","32:1","32:0","125:0"])}async function l(){return await c().clipboard.readText()}async function S(t){await c().clipboard.writeText(t)}async function E(t,e){await c().screenshot.capture(t,e)}function N(){return{open:t=>P(t),openDevice:()=>Promise.resolve(),close:t=>d(t),tap:(t,n)=>e(t,n),doubleTap:(t,e)=>p(t,e),swipe:(t,e,n,o,r)=>s(t,e,n,o,r),pan:(t,e,n,o,r)=>s(t,e,n,o,r),fling:()=>{throw new w("UNSUPPORTED_OPERATION","gesture fling not supported on Linux")},longPress:(e,n,o)=>t(e,n,o),focus:(t,e)=>i(t,e),type:(t,e)=>n(t,e),fill:(t,e,n,o)=>a(t,e,n,o),scroll:(t,e)=>o(t,e),pinch:()=>{throw new w("UNSUPPORTED_OPERATION","gesture pinch not supported on Linux")},screenshot:(t,e)=>E(t,e),snapshot:async t=>{let e=await _("snapshot_capture",async()=>await u(t?.surface),{backend:"linux-atspi"});return{nodes:e.nodes??[],truncated:e.truncated??!1,backend:"linux-atspi"}},back:()=>O(),home:()=>f(),rotate:()=>{throw new w("UNSUPPORTED_OPERATION","rotate not supported on Linux")},rotateGesture:()=>{throw new w("UNSUPPORTED_OPERATION","gesture rotate not supported on Linux")},transformGesture:()=>{throw new w("UNSUPPORTED_OPERATION","gesture transform not supported on Linux")},appSwitcher:()=>{throw new w("UNSUPPORTED_OPERATION","appSwitcher not yet supported on Linux")},readClipboard:()=>l(),writeClipboard:t=>S(t),setSetting:()=>{throw new w("UNSUPPORTED_OPERATION","setSetting not supported on Linux")}}}export{N as createLinuxInteractor};
1
+ import{longPressLinux as t,pressLinux as e,typeLinux as n,scrollLinux as o,sendKey as r,fillLinux as a,focusLinux as i,swipeLinux as s,doubleClickLinux as p}from"./input-actions~1.js";import{snapshotLinux as u,resolveLinuxToolProvider as c}from"./9722.js";import{AppError as w}from"./485.js";import{withDiagnosticTimer as _}from"./8875.js";async function P(t){await c().desktop.openTarget(t)}async function d(t){await c().desktop.closeApp(t)}async function O(){await r("alt+Left",["56:1","105:1","105:0","56:0"])}async function f(){await r("super+d",["125:1","32:1","32:0","125:0"])}async function l(){return await c().clipboard.readText()}async function S(t){await c().clipboard.writeText(t)}async function E(t,e){await c().screenshot.capture(t,e)}function N(){return{open:t=>P(t),openDevice:()=>Promise.resolve(),close:t=>d(t),tap:(t,n)=>e(t,n),doubleTap:(t,e)=>p(t,e),swipe:(t,e,n,o,r)=>s(t,e,n,o,r),pan:(t,e,n,o,r)=>s(t,e,n,o,r),fling:()=>{throw new w("UNSUPPORTED_OPERATION","gesture fling not supported on Linux")},longPress:(e,n,o)=>t(e,n,o),focus:(t,e)=>i(t,e),type:(t,e)=>n(t,e),fill:(t,e,n,o)=>a(t,e,n,o),scroll:(t,e)=>o(t,e),pinch:()=>{throw new w("UNSUPPORTED_OPERATION","gesture pinch not supported on Linux")},screenshot:(t,e)=>E(t,e),snapshot:async t=>{let e=await _("snapshot_capture",async()=>await u(t?.surface),{backend:"linux-atspi"});return{nodes:e.nodes??[],truncated:e.truncated??!1,backend:"linux-atspi"}},back:()=>O(),home:()=>f(),rotate:()=>{throw new w("UNSUPPORTED_OPERATION","rotate not supported on Linux")},rotateGesture:()=>{throw new w("UNSUPPORTED_OPERATION","gesture rotate not supported on Linux")},transformGesture:()=>{throw new w("UNSUPPORTED_OPERATION","gesture transform not supported on Linux")},appSwitcher:()=>{throw new w("UNSUPPORTED_OPERATION","appSwitcher not yet supported on Linux")},readClipboard:()=>l(),writeClipboard:t=>S(t),setSetting:()=>{throw new w("UNSUPPORTED_OPERATION","setSetting not supported on Linux")}}}export{N as createLinuxInteractor};
@@ -1,37 +1,5 @@
1
- export declare function buildAndroidRuntimeHints(baseUrl: string): MetroRuntimeHints;
2
-
3
1
  export declare function buildBundleUrl(baseUrl: string, platform: 'ios' | 'android'): string;
4
2
 
5
- export declare function buildIosRuntimeHints(baseUrl: string): MetroRuntimeHints;
6
-
7
- export declare type CompanionTunnelScope = {
8
- tenantId: string;
9
- runId: string;
10
- leaseId: string;
11
- };
12
-
13
- export declare function ensureMetroTunnel(options: EnsureMetroTunnelOptions): Promise<EnsureMetroTunnelResult>;
14
-
15
- export declare type EnsureMetroTunnelOptions = {
16
- projectRoot: string;
17
- serverBaseUrl: string;
18
- bearerToken: string;
19
- localBaseUrl: string;
20
- bridgeScope: MetroBridgeScope;
21
- launchUrl?: string;
22
- profileKey?: string;
23
- consumerKey?: string;
24
- env?: EnvSource;
25
- };
26
-
27
- export declare type EnsureMetroTunnelResult = {
28
- pid: number;
29
- started: boolean;
30
- logPath: string;
31
- };
32
-
33
- declare type EnvSource = NodeJS.ProcessEnv | Record<string, string | undefined>;
34
-
35
3
  export declare type MetroBridgeDescriptor = {
36
4
  enabled: boolean;
37
5
  base_url: string;
@@ -53,48 +21,20 @@ export declare type MetroBridgeDescriptor = {
53
21
  };
54
22
  };
55
23
 
56
- export declare type MetroBridgeResult = {
57
- enabled: boolean;
58
- baseUrl: string;
59
- statusUrl: string;
60
- bundleUrl: string;
61
- iosRuntime: MetroRuntimeHints;
62
- androidRuntime: MetroRuntimeHints;
63
- upstream: {
64
- bundleUrl: string;
65
- host: string;
66
- port: number;
67
- statusUrl: string;
68
- };
69
- probe: {
70
- reachable: boolean;
71
- statusCode: number;
72
- latencyMs: number;
73
- detail: string;
74
- };
75
- };
76
-
77
- export declare type MetroBridgeRuntimePayload = {
24
+ declare type MetroBridgeRuntimePayload = {
78
25
  metro_host?: string;
79
26
  metro_port?: number;
80
27
  metro_bundle_url?: string;
81
28
  launch_url?: string;
82
29
  };
83
30
 
84
- export declare type MetroBridgeScope = CompanionTunnelScope;
85
-
86
- declare type MetroPrepareKind = 'auto' | 'react-native' | 'expo';
87
-
88
- /** Re-export of {@link SessionRuntimeHints} under the Metro-specific alias used by public API consumers. */
89
- export declare type MetroRuntimeHints = SessionRuntimeHints;
90
-
91
- export declare type MetroTunnelHttpErrorMessage = {
31
+ declare type MetroTunnelHttpErrorMessage = {
92
32
  type: 'http-error';
93
33
  requestId: string;
94
34
  message: string;
95
35
  };
96
36
 
97
- export declare type MetroTunnelHttpRequestMessage = {
37
+ declare type MetroTunnelHttpRequestMessage = {
98
38
  type: 'http-request';
99
39
  requestId: string;
100
40
  method: string;
@@ -103,7 +43,7 @@ export declare type MetroTunnelHttpRequestMessage = {
103
43
  bodyBase64?: string;
104
44
  };
105
45
 
106
- export declare type MetroTunnelHttpResponseMessage = {
46
+ declare type MetroTunnelHttpResponseMessage = {
107
47
  type: 'http-response';
108
48
  requestId: string;
109
49
  status: number;
@@ -111,14 +51,12 @@ export declare type MetroTunnelHttpResponseMessage = {
111
51
  bodyBase64?: string;
112
52
  };
113
53
 
114
- export declare type MetroTunnelMessage = MetroTunnelRequestMessage | MetroTunnelResponseMessage;
115
-
116
- export declare type MetroTunnelPingMessage = {
54
+ declare type MetroTunnelPingMessage = {
117
55
  type: 'ping';
118
56
  timestamp: number;
119
57
  };
120
58
 
121
- export declare type MetroTunnelPongMessage = {
59
+ declare type MetroTunnelPongMessage = {
122
60
  type: 'pong';
123
61
  timestamp: number;
124
62
  };
@@ -127,28 +65,28 @@ export declare type MetroTunnelRequestMessage = MetroTunnelPingMessage | MetroTu
127
65
 
128
66
  export declare type MetroTunnelResponseMessage = MetroTunnelPongMessage | MetroTunnelHttpResponseMessage | MetroTunnelHttpErrorMessage | MetroTunnelWebSocketOpenResultMessage | MetroTunnelWebSocketFrameMessage | MetroTunnelWebSocketCloseMessage;
129
67
 
130
- export declare type MetroTunnelWebSocketCloseMessage = {
68
+ declare type MetroTunnelWebSocketCloseMessage = {
131
69
  type: 'ws-close';
132
70
  streamId: string;
133
71
  code?: number;
134
72
  reason?: string;
135
73
  };
136
74
 
137
- export declare type MetroTunnelWebSocketFrameMessage = {
75
+ declare type MetroTunnelWebSocketFrameMessage = {
138
76
  type: 'ws-frame';
139
77
  streamId: string;
140
78
  dataBase64: string;
141
79
  binary: boolean;
142
80
  };
143
81
 
144
- export declare type MetroTunnelWebSocketOpenMessage = {
82
+ declare type MetroTunnelWebSocketOpenMessage = {
145
83
  type: 'ws-open';
146
84
  streamId: string;
147
85
  path: string;
148
86
  headers?: Record<string, string>;
149
87
  };
150
88
 
151
- export declare type MetroTunnelWebSocketOpenResultMessage = {
89
+ declare type MetroTunnelWebSocketOpenResultMessage = {
152
90
  type: 'ws-open-result';
153
91
  streamId: string;
154
92
  success: boolean;
@@ -158,60 +96,6 @@ export declare type MetroTunnelWebSocketOpenResultMessage = {
158
96
 
159
97
  export declare function normalizeBaseUrl(input: string): string;
160
98
 
161
- export declare function prepareRemoteMetro(options: PrepareRemoteMetroOptions): Promise<PrepareRemoteMetroResult>;
162
-
163
- export declare type PrepareRemoteMetroOptions = {
164
- projectRoot: string;
165
- kind: MetroPrepareKind;
166
- publicBaseUrl?: string;
167
- proxyBaseUrl?: string;
168
- proxyBearerToken?: string;
169
- bridgeScope?: MetroBridgeScope;
170
- launchUrl?: string;
171
- profileKey?: string;
172
- consumerKey?: string;
173
- port?: number;
174
- listenHost?: string;
175
- statusHost?: string;
176
- startupTimeoutMs?: number;
177
- probeTimeoutMs?: number;
178
- reuseExisting?: boolean;
179
- installDependenciesIfNeeded?: boolean;
180
- runtimeFilePath?: string;
181
- logPath?: string;
182
- env?: EnvSource;
183
- };
184
-
185
- export declare type PrepareRemoteMetroResult = {
186
- iosRuntime: MetroRuntimeHints;
187
- androidRuntime: MetroRuntimeHints;
188
- bridge: MetroBridgeResult | null;
189
- started: boolean;
190
- reused: boolean;
191
- logPath: string;
192
- };
193
-
194
- declare type ReloadMetroOptions = {
195
- metroHost?: string;
196
- metroPort?: number | string;
197
- bundleUrl?: string;
198
- runtime?: MetroRuntimeHints;
199
- timeoutMs?: number | string;
200
- };
201
-
202
- declare type ReloadMetroResult = {
203
- reloaded: true;
204
- reloadUrl: string;
205
- status: number;
206
- body: string;
207
- };
208
-
209
- export declare function reloadRemoteMetro(options?: ReloadRemoteMetroOptions): Promise<ReloadRemoteMetroResult>;
210
-
211
- export declare type ReloadRemoteMetroOptions = ReloadMetroOptions;
212
-
213
- export declare type ReloadRemoteMetroResult = ReloadMetroResult;
214
-
215
99
  export declare function resolveRuntimeTransport(runtime: SessionRuntimeHints | undefined): {
216
100
  host: string;
217
101
  port: number;
@@ -226,12 +110,4 @@ declare type SessionRuntimeHints = {
226
110
  launchUrl?: string;
227
111
  };
228
112
 
229
- export declare function stopMetroTunnel(options: StopMetroTunnelOptions): Promise<void>;
230
-
231
- export declare type StopMetroTunnelOptions = {
232
- projectRoot: string;
233
- profileKey?: string;
234
- consumerKey?: string;
235
- };
236
-
237
113
  export { }
package/dist/src/metro.js CHANGED
@@ -1 +1 @@
1
- import{buildMetroRuntimeHints as e,ensureMetroCompanion as t,reloadMetro as r,stopMetroCompanion as o,prepareMetroRuntime as n}from"./8275.js";import{resolveRuntimeTransportHints as i}from"./8936.js";function s(e){return i(e)}async function a(e){let t=await n({projectRoot:e.projectRoot,kind:e.kind,publicBaseUrl:e.publicBaseUrl,proxyBaseUrl:e.proxyBaseUrl,proxyBearerToken:e.proxyBearerToken,bridgeScope:e.bridgeScope,launchUrl:e.launchUrl,companionProfileKey:e.profileKey,companionConsumerKey:e.consumerKey,metroPort:e.port,listenHost:e.listenHost,statusHost:e.statusHost,startupTimeoutMs:e.startupTimeoutMs,probeTimeoutMs:e.probeTimeoutMs,reuseExisting:e.reuseExisting,installDependenciesIfNeeded:e.installDependenciesIfNeeded,runtimeFilePath:e.runtimeFilePath,logPath:e.logPath,env:e.env});return{iosRuntime:t.iosRuntime,androidRuntime:t.androidRuntime,bridge:t.bridge,started:t.started,reused:t.reused,logPath:t.logPath}}async function u(e){let r=await t(e);return{pid:r.pid,started:r.spawned,logPath:r.logPath}}async function l(e){await o(e)}async function d(e={}){return await r(e)}function p(t){return e(t,"ios")}function m(t){return e(t,"android")}export{buildBundleUrl,normalizeBaseUrl}from"./4069.js";export{m as buildAndroidRuntimeHints,p as buildIosRuntimeHints,u as ensureMetroTunnel,a as prepareRemoteMetro,d as reloadRemoteMetro,s as resolveRuntimeTransport,l as stopMetroTunnel};
1
+ export{buildBundleUrl,normalizeBaseUrl}from"./4917.js";export{resolveRuntimeTransport}from"./6967.js";
@@ -1 +1 @@
1
- import{AppError as e}from"./733.js";import{runAndroidAdb as r}from"./3340.js";async function t(t,o,i){let n="string"==typeof i.action&&i.action.trim()?i.action.trim():`${o}.TEST_PUSH`,s=["shell","am","broadcast","-a",n,"-p",o],a="string"==typeof i.receiver?i.receiver.trim():"";a&&s.push("-n",a);let p=i.extras;if(void 0!==p&&("object"!=typeof p||null===p||Array.isArray(p)))throw new e("INVALID_ARGS","Android push payload extras must be an object");let u=0;for(let[r,t]of Object.entries(p??{}))r&&(function(r,t,o){if("string"==typeof o)return r.push("--es",t,o);if("boolean"==typeof o)return r.push("--ez",t,o?"true":"false");if("number"==typeof o&&Number.isFinite(o))return Number.isInteger(o)?r.push("--ei",t,String(o)):r.push("--ef",t,String(o));throw new e("INVALID_ARGS",`Unsupported Android broadcast extra type for "${t}". Use string, boolean, or number.`)}(s,r,t),u+=1);return await r(t,s),{action:n,extrasCount:u}}export{t as pushAndroidNotification};
1
+ import{AppError as e}from"./485.js";import{runAndroidAdb as r}from"./3340.js";async function t(t,o,i){let n="string"==typeof i.action&&i.action.trim()?i.action.trim():`${o}.TEST_PUSH`,s=["shell","am","broadcast","-a",n,"-p",o],a="string"==typeof i.receiver?i.receiver.trim():"";a&&s.push("-n",a);let p=i.extras;if(void 0!==p&&("object"!=typeof p||null===p||Array.isArray(p)))throw new e("INVALID_ARGS","Android push payload extras must be an object");let u=0;for(let[r,t]of Object.entries(p??{}))r&&(function(r,t,o){if("string"==typeof o)return r.push("--es",t,o);if("boolean"==typeof o)return r.push("--ez",t,o?"true":"false");if("number"==typeof o&&Number.isFinite(o))return Number.isInteger(o)?r.push("--ei",t,String(o)):r.push("--ef",t,String(o));throw new e("INVALID_ARGS",`Unsupported Android broadcast extra type for "${t}". Use string, boolean, or number.`)}(s,r,t),u+=1);return await r(t,s),{action:n,extrasCount:u}}export{t as pushAndroidNotification};
@@ -1 +1 @@
1
- import{dispatchCommand as e,errorResponse as t,isCommandSupportedOnDevice as i}from"./9722.js";import{stripUndefined as a,PUBLIC_COMMANDS as s}from"./5341.js";import{isSparseSnapshotQualityVerdict as r,analyzeReactNativeOverlay as n,successText as o}from"./2948.js";import{normalizeError as d}from"./733.js";import{interaction_snapshot_captureSnapshotForSession as l,readSnapshotNodesReferenceFrame as c,finalizeTouchInteraction as v}from"./8184.js";async function f(e){var a,c;let{req:v,sessionName:f,sessionStore:u}=e;if(v.command!==s.reactNative)return null;let y=1===(a=v.positionals??[]).length&&"dismiss-overlay"===a[0]?{ok:!0}:{ok:!1,response:t("INVALID_ARGS","react-native supports only: dismiss-overlay")};if(!y.ok)return y.response;let p=u.get(f);if(!p)return t("SESSION_NOT_FOUND","No active session. Run open first.");if(!i(s.reactNative,p.device))return t("UNSUPPORTED_OPERATION","react-native dismiss-overlay is not supported on this device");try{let i=await l(p,v.flags,u,e.contextFromFlags,{interactiveOnly:!0});if(r(i.snapshotQuality)){return c=i.snapshotQuality,t("COMMAND_FAILED","React Native overlay state could not be determined because the accessibility tree is unreadable",{reason:c.reason,hint:"The snapshot quality verdict is sparse. Use screenshot as visual truth; if an overlay is visible, report it or navigate with coordinates, then retry snapshot or dismiss-overlay on a readable screen."})}let a=n(i.nodes),s=a.primaryAction;if(!s)return a.detected?t("COMMAND_FAILED","React Native overlay detected, but no safe dismiss target was found",{hint:"Use screenshot --overlay-refs for visual evidence and report the overlay instead of pressing the warning body."}):{ok:!0,data:{action:"dismiss-overlay",detected:!1,dismissed:!1,...o("No React Native overlay detected")}};return await m(e,p,i,s)}catch(e){return{ok:!1,error:d(e)}}}async function m(t,i,s,r){let{req:n,sessionStore:d}=t,l=Date.now(),f=await e(i.device,"press",[String(r.point.x),String(r.point.y)],n.flags?.out,t.contextFromFlags(n.flags,i.appBundleId,i.trace?.outPath))??{},m=Date.now(),y=await u(t,i),p=a({...c(s.nodes),...f,action:"dismiss-overlay",overlayAction:r.action,x:r.point.x,y:r.point.y,ref:r.ref,label:r.label,warning:r.warning,dismissed:!0,verified:y.verified,verificationRequired:!y.verified,verificationWarning:y.verificationWarning,nextCommand:y.nextCommand,...o(y.verified?"React Native overlay dismiss action sent and verified gone":"React Native overlay dismiss action sent, but verification still detects an overlay")});return v({session:i,sessionStore:d,command:n.command,positionals:n.positionals??[],flags:n.flags,result:p,responseData:p,actionStartedAt:l,actionFinishedAt:m})}async function u(e,t){let{req:i,sessionStore:a}=e,s=await l(t,i.flags,a,e.contextFromFlags,{interactiveOnly:!0});return r(s.snapshotQuality)?{verified:!1,verificationWarning:"React Native overlay dismissal could not be verified because the post-dismiss accessibility tree is unreadable. Use screenshot as visual truth.",nextCommand:"agent-device screenshot"}:n(s.nodes).detected?{verified:!1,verificationWarning:"React Native overlay is still detected after dismissal. Use screenshot --overlay-refs for visual evidence and report the overlay instead of pressing the warning body.",nextCommand:"agent-device screenshot --overlay-refs"}:{verified:!0}}export{f as handleReactNativeCommands};
1
+ import{dispatchCommand as e,noActiveSessionError as t,requireCommandSupported as i,errorResponse as a}from"./9722.js";import{stripUndefined as s,PUBLIC_COMMANDS as r}from"./1986.js";import{isSparseSnapshotQualityVerdict as n,analyzeReactNativeOverlay as o,successText as d}from"./2948.js";import{normalizeError as l}from"./485.js";import{interaction_snapshot_captureSnapshotForSession as c,readSnapshotNodesReferenceFrame as v,finalizeTouchInteraction as f}from"./8184.js";async function m(e){var s,v;let{req:f,sessionName:m,sessionStore:u}=e;if(f.command!==r.reactNative)return null;let p=1===(s=f.positionals??[]).length&&"dismiss-overlay"===s[0]?{ok:!0}:{ok:!1,response:a("INVALID_ARGS","react-native supports only: dismiss-overlay")};if(!p.ok)return p.response;let g=u.get(m);if(!g)return t();let h=i(r.reactNative,g.device,{message:"react-native dismiss-overlay is not supported on this device"});if(h)return h;try{let t=await c(g,f.flags,u,e.contextFromFlags,{interactiveOnly:!0});if(n(t.snapshotQuality)){return v=t.snapshotQuality,a("COMMAND_FAILED","React Native overlay state could not be determined because the accessibility tree is unreadable",{reason:v.reason,hint:"The snapshot quality verdict is sparse. Use screenshot as visual truth; if an overlay is visible, report it or navigate with coordinates, then retry snapshot or dismiss-overlay on a readable screen."})}let i=o(t.nodes),s=i.primaryAction;if(!s)return i.detected?a("COMMAND_FAILED","React Native overlay detected, but no safe dismiss target was found",{hint:"Use screenshot --overlay-refs for visual evidence and report the overlay instead of pressing the warning body."}):{ok:!0,data:{action:"dismiss-overlay",detected:!1,dismissed:!1,...d("No React Native overlay detected")}};return await y(e,g,t,s)}catch(e){return{ok:!1,error:l(e)}}}async function y(t,i,a,r){let{req:n,sessionStore:o}=t,l=Date.now(),c=await e(i.device,"press",[String(r.point.x),String(r.point.y)],n.flags?.out,t.contextFromFlags(n.flags,i.appBundleId,i.trace?.outPath))??{},m=Date.now(),y=await u(t,i),p=s({...v(a.nodes),...c,action:"dismiss-overlay",overlayAction:r.action,x:r.point.x,y:r.point.y,ref:r.ref,label:r.label,warning:r.warning,dismissed:!0,verified:y.verified,verificationRequired:!y.verified,verificationWarning:y.verificationWarning,nextCommand:y.nextCommand,...d(y.verified?"React Native overlay dismiss action sent and verified gone":"React Native overlay dismiss action sent, but verification still detects an overlay")});return f({session:i,sessionStore:o,command:n.command,positionals:n.positionals??[],flags:n.flags,result:p,responseData:p,actionStartedAt:l,actionFinishedAt:m})}async function u(e,t){let{req:i,sessionStore:a}=e,s=await c(t,i.flags,a,e.contextFromFlags,{interactiveOnly:!0});return n(s.snapshotQuality)?{verified:!1,verificationWarning:"React Native overlay dismissal could not be verified because the post-dismiss accessibility tree is unreadable. Use screenshot as visual truth.",nextCommand:"agent-device screenshot"}:o(s.nodes).detected?{verified:!1,verificationWarning:"React Native overlay is still detected after dismissal. Use screenshot --overlay-refs for visual evidence and report the overlay instead of pressing the warning body.",nextCommand:"agent-device screenshot --overlay-refs"}:{verified:!0}}export{m as handleReactNativeCommands};