agent-device 0.18.3 → 0.19.1

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 (219) hide show
  1. package/README.md +5 -1
  2. package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.18.3.apk → agent-device-android-multitouch-helper-0.19.1.apk} +0 -0
  3. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.19.1.apk.sha256 +1 -0
  4. package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.18.3.manifest.json → agent-device-android-multitouch-helper-0.19.1.manifest.json} +4 -4
  5. package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.18.3.apk → agent-device-android-snapshot-helper-0.19.1.apk} +0 -0
  6. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.19.1.apk.sha256 +1 -0
  7. package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.18.3.manifest.json → agent-device-android-snapshot-helper-0.19.1.manifest.json} +6 -6
  8. package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTapPointPolicy.swift +28 -0
  9. package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +33 -127
  10. package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +630 -177
  11. package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +155 -0
  12. package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+FlatSnapshotFiltering.swift +67 -0
  13. package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +173 -122
  14. package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Navigation.swift +172 -0
  15. package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollGesture.swift +64 -0
  16. package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SequenceExecution.swift +76 -182
  17. package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +92 -51
  18. package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +213 -137
  19. package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedGesturePolicy.swift +142 -0
  20. package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +208 -46
  21. package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Transport.swift +82 -11
  22. package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +74 -0
  23. package/dist/src/agent-browser-tool.js +1 -0
  24. package/dist/src/android-adb.d.ts +63 -234
  25. package/dist/src/android-adb.js +1 -1
  26. package/dist/src/android-input-ownership.js +6 -0
  27. package/dist/src/android.js +1 -5
  28. package/dist/src/app-lifecycle.js +7 -0
  29. package/dist/src/apple-runner-options.js +1 -0
  30. package/dist/src/apps.js +5 -11
  31. package/dist/src/artifacts.d.ts +4 -3
  32. package/dist/src/artifacts.js +1 -1
  33. package/dist/src/audio-probe.js +1 -1
  34. package/dist/src/batch.d.ts +2 -177
  35. package/dist/src/batch.js +1 -1
  36. package/dist/src/cli-help.js +178 -60
  37. package/dist/src/cli-output.js +1 -1
  38. package/dist/src/cli-runner.js +2 -0
  39. package/dist/src/cli.js +12 -41
  40. package/dist/src/client-metro-companion.js +1 -0
  41. package/dist/src/client.js +3 -0
  42. package/dist/src/command-metadata.js +1 -0
  43. package/dist/src/command-schema.js +22 -0
  44. package/dist/src/command-surface.js +1 -1
  45. package/dist/src/contracts.d.ts +2 -213
  46. package/dist/src/contracts.js +1 -1
  47. package/dist/src/debug-symbols.js +5 -3
  48. package/dist/src/device-input-state.js +2 -0
  49. package/dist/src/devices.js +1 -1
  50. package/dist/src/devices2.js +1 -0
  51. package/dist/src/devices3.js +1 -0
  52. package/dist/src/find.js +1 -1
  53. package/dist/src/finders.d.ts +2 -81
  54. package/dist/src/finders.js +1 -1
  55. package/dist/src/generic.js +1 -1
  56. package/dist/src/handler-utils.js +1 -1
  57. package/dist/src/helper.js +2 -0
  58. package/dist/src/host-process.js +2 -0
  59. package/dist/src/index.d.ts +1444 -1786
  60. package/dist/src/index.js +1 -1
  61. package/dist/src/input-actions.js +3 -1
  62. package/dist/src/input-actions2.js +1 -0
  63. package/dist/src/install-source.d.ts +13 -14
  64. package/dist/src/install-source.js +1 -1
  65. package/dist/src/install-source2.js +1 -0
  66. package/dist/src/interaction-snapshot.js +1 -0
  67. package/dist/src/interaction.js +1 -1
  68. package/dist/src/interactor.js +2 -1
  69. package/dist/src/internal/bin.d.ts +1 -1
  70. package/dist/src/internal/bin.js +2 -5
  71. package/dist/src/internal/companion-tunnel.d.ts +1 -1
  72. package/dist/src/internal/companion-tunnel.js +1 -1
  73. package/dist/src/internal/daemon.d.ts +1 -1
  74. package/dist/src/internal/daemon.js +18 -1
  75. package/dist/src/internal/png-worker.d.ts +29 -26
  76. package/dist/src/internal/png-worker.js +1 -1
  77. package/dist/src/internal/update-check-entry.d.ts +1 -1
  78. package/dist/src/internal/update-check-entry.js +1 -1
  79. package/dist/src/io.d.ts +2 -85
  80. package/dist/src/io.js +1 -1
  81. package/dist/src/lease.js +1 -1
  82. package/dist/src/linux.js +1 -1
  83. package/dist/src/manifest.js +1 -0
  84. package/dist/src/metro.d.ts +69 -113
  85. package/dist/src/metro.js +1 -1
  86. package/dist/src/metro2.js +1 -0
  87. package/dist/src/notifications.js +1 -1
  88. package/dist/src/output-path.js +1 -0
  89. package/dist/src/path-resolution.js +1 -0
  90. package/dist/src/png-worker-contract.js +1 -0
  91. package/dist/src/points.js +4 -0
  92. package/dist/src/project-runtime.js +1 -0
  93. package/dist/src/provider.js +1 -1
  94. package/dist/src/providers.js +1 -0
  95. package/dist/src/react-native.js +1 -1
  96. package/dist/src/record-trace-recording.js +2 -5
  97. package/dist/src/record-trace.js +1 -1
  98. package/dist/src/recording-provider.js +1 -1
  99. package/dist/src/registry.js +38 -0
  100. package/dist/src/remote-config.d.ts +2 -83
  101. package/dist/src/reporting.js +9 -0
  102. package/dist/src/rolldown-runtime.js +1 -0
  103. package/dist/src/runner-client.js +1 -0
  104. package/dist/src/runner-provider.js +1 -0
  105. package/dist/src/runner-sequence.js +1 -1
  106. package/dist/src/runtime-transport.js +1 -0
  107. package/dist/src/runtime.js +3 -0
  108. package/dist/src/scoped-provider.js +1 -0
  109. package/dist/src/sdk-android-adb.d.ts +144 -0
  110. package/dist/src/sdk-android-adb.js +4 -0
  111. package/dist/src/sdk-app-inventory.d.ts +4 -0
  112. package/dist/src/sdk-app-inventory.js +1 -0
  113. package/dist/src/sdk-batch-runner.d.ts +39 -0
  114. package/dist/src/sdk-batch-runner.js +2 -0
  115. package/dist/src/sdk-batch.js +2 -0
  116. package/dist/src/sdk-contracts.d.ts +386 -0
  117. package/dist/src/sdk-contracts.js +2 -0
  118. package/dist/src/sdk-finders.d.ts +60 -0
  119. package/dist/src/sdk-finders.js +1 -0
  120. package/dist/src/sdk-io.d.ts +78 -0
  121. package/dist/src/sdk-io.js +1 -0
  122. package/dist/src/sdk-remote-config.d.ts +139 -0
  123. package/dist/src/sdk-remote-config.js +1 -0
  124. package/dist/src/sdk-selectors.js +1 -0
  125. package/dist/src/selector-runtime.js +1 -1
  126. package/dist/src/selectors.d.ts +38 -137
  127. package/dist/src/selectors.js +1 -1
  128. package/dist/src/selectors2.js +1 -0
  129. package/dist/src/server.js +3 -2
  130. package/dist/src/session.js +10 -11
  131. package/dist/src/setting-state.js +1 -0
  132. package/dist/src/simctl.js +1 -0
  133. package/dist/src/simulator.js +1 -2
  134. package/dist/src/snapshot-diagnostics.js +3 -0
  135. package/dist/src/snapshot-helper.js +5 -0
  136. package/dist/src/snapshot-quality.js +1 -0
  137. package/dist/src/snapshot.js +1 -2
  138. package/dist/src/snapshot2.js +2 -0
  139. package/dist/src/{5560.js → timeouts.js} +1 -1
  140. package/dist/src/tool-provider.js +3 -0
  141. package/dist/src/tool-provider2.js +1 -0
  142. package/dist/src/ttl-memo.js +1 -0
  143. package/dist/src/tv-remote.js +14 -0
  144. package/dist/src/update-check.js +1 -0
  145. package/dist/src/url.js +1 -0
  146. package/dist/src/version.js +1 -0
  147. package/dist/src/web.js +1 -1
  148. package/dist/src/xml.js +2 -0
  149. package/package.json +13 -19
  150. package/server.json +2 -2
  151. package/skills/agent-device/SKILL.md +8 -7
  152. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.18.3.apk.sha256 +0 -1
  153. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.18.3.apk.sha256 +0 -1
  154. package/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +0 -443
  155. package/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+FlatSnapshotFiltering.swift +0 -169
  156. package/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollGesture.swift +0 -220
  157. package/dist/src/1404.js +0 -1
  158. package/dist/src/1986.js +0 -1
  159. package/dist/src/2748.js +0 -1
  160. package/dist/src/2948.js +0 -30
  161. package/dist/src/3006.js +0 -1
  162. package/dist/src/314.js +0 -1
  163. package/dist/src/3340.js +0 -8
  164. package/dist/src/4418.js +0 -1
  165. package/dist/src/4428.js +0 -3
  166. package/dist/src/485.js +0 -1
  167. package/dist/src/4917.js +0 -1
  168. package/dist/src/495.js +0 -5
  169. package/dist/src/5448.js +0 -3
  170. package/dist/src/5484.js +0 -1
  171. package/dist/src/5643.js +0 -1
  172. package/dist/src/587.js +0 -1
  173. package/dist/src/5913.js +0 -4
  174. package/dist/src/6849.js +0 -1
  175. package/dist/src/6918.js +0 -1
  176. package/dist/src/6967.js +0 -1
  177. package/dist/src/760.js +0 -1
  178. package/dist/src/7871.js +0 -1
  179. package/dist/src/8184.js +0 -1
  180. package/dist/src/8225.js +0 -1
  181. package/dist/src/8391.js +0 -1
  182. package/dist/src/8404.js +0 -2
  183. package/dist/src/8414.js +0 -2
  184. package/dist/src/8875.js +0 -4
  185. package/dist/src/893.js +0 -1
  186. package/dist/src/8936.js +0 -1
  187. package/dist/src/9414.js +0 -1
  188. package/dist/src/9581.js +0 -22
  189. package/dist/src/9612.js +0 -1
  190. package/dist/src/9624.js +0 -1
  191. package/dist/src/9722.js +0 -39
  192. package/dist/src/devices~1.js +0 -1
  193. package/dist/src/devices~2.js +0 -1
  194. package/dist/src/input-actions~1.js +0 -1
  195. package/dist/src/rslib-runtime.js +0 -1
  196. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunner/AgentDeviceRunnerApp.m +0 -0
  197. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/project.pbxproj +0 -0
  198. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -0
  199. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/xcshareddata/xcschemes/AgentDeviceRunner.xcscheme +0 -0
  200. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/AgentDeviceRunnerUITests-Bridging-Header.h +0 -0
  201. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/AgentDeviceRunnerUITests.entitlements +0 -0
  202. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.h +0 -0
  203. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.m +0 -0
  204. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerObjCExceptionCatcher.h +0 -0
  205. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerObjCExceptionCatcher.m +0 -0
  206. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.h +0 -0
  207. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.m +0 -0
  208. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Alert.swift +0 -0
  209. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Environment.swift +0 -0
  210. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Exceptions.swift +0 -0
  211. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +0 -0
  212. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +0 -0
  213. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScreenRecorder.swift +0 -0
  214. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SystemModal.swift +0 -0
  215. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TvRemote.swift +0 -0
  216. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests.xctestplan +0 -0
  217. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/RecordingScripts/recording-overlay.swift +0 -0
  218. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/RecordingScripts/recording-resize.swift +0 -0
  219. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/RecordingScripts/recording-trim.swift +0 -0
@@ -0,0 +1,3 @@
1
+ import{t as e}from"./rolldown-runtime.js";import{F as t,H as n,a as r}from"./sdk-contracts.js";import{A as i,C as a,F as o,b as s,j as c,v as l,x as u}from"./sdk-android-adb.js";import{g as d}from"./sdk-batch.js";import{An as f,Fn as p,Qn as m,Zn as h,mn as ee}from"./tv-remote.js";import{i as te,n as ne}from"./output-path.js";import{C as g,O as re,T as ie,b as ae,g as oe,h as se,l as ce,m as le,n as ue,s as de,u as fe,v as _,w as pe,y as me}from"./snapshot-diagnostics.js";import{n as v,t as he}from"./version.js";import{n as ge}from"./path-resolution.js";import{t as y}from"./timeouts.js";import{u as _e}from"./host-process.js";import{A as ve,C as ye,D as be,E as xe,O as Se,P as Ce,S as we,T as Te,b as Ee,d as De,f as Oe,i as ke,k as Ae,p as je,s as Me,w as Ne,x as Pe,y as Fe}from"./registry.js";import{l as Ie,m as b,v as x}from"./sdk-batch-runner.js";import{n as Le,t as Re}from"./url.js";import{t as ze}from"./client-metro-companion.js";import{n as Be,r as Ve}from"./project-runtime.js";import{t as He}from"./runtime-transport.js";import{t as Ue}from"./command-metadata.js";import{createHash as We,randomUUID as Ge}from"node:crypto";import S from"node:fs";import Ke from"node:os";import C from"node:path";import w from"node:http";import T from"node:https";import{pipeline as qe}from"node:stream/promises";import{Transform as Je,Writable as Ye}from"node:stream";import E from"node:net";const Xe=`/agent-device`;function Ze(e){return D(e,Xe)}function D(e,t){let n=e.endsWith(`/`)?e:`${e}/`;return new URL(t.replace(/^\/+/,``),n).toString()}function O(e){let t=e?.trim();return t?{authorization:`Bearer ${t}`,"x-agent-device-token":t}:{}}async function Qe(e,t){let n=S.statSync(e),r=C.basename(e),i=n.isDirectory(),a=tt(t)??et(e,n),o=[];try{let t=i?await $e(e,o):e,n=S.statSync(t);return{payloadPath:t,fileName:r,artifactType:i?`app-bundle`:`file`,platform:a,contentType:i?`application/gzip`:`application/octet-stream`,sha256:await rt(t),sizeBytes:n.size,cleanup:()=>nt(o)}}catch(e){throw nt(o),e}}async function $e(e,t){let n=S.mkdtempSync(C.join(Ke.tmpdir(),`agent-device-upload-${Ge()}-`));t.push(n);let r=C.join(n,`${C.basename(e)}.tar.gz`);return await l(`tar`,[`czf`,r,`-C`,C.dirname(e),C.basename(e)],{env:{...process.env,COPYFILE_DISABLE:`1`}}),r}function et(e,t){let n=e.toLowerCase();if(t.isDirectory()&&n.endsWith(`.app`)||n.endsWith(`.ipa`))return`ios`;if(n.endsWith(`.apk`)||n.endsWith(`.aab`))return`android`}function tt(e){return e===`ios`||e===`android`?e:void 0}function nt(e){for(let t of e)S.rmSync(t,{recursive:!0,force:!0})}async function rt(e){let n=We(`sha256`),r=new Ye({write(e,t,r){n.update(e),r()}});return await qe(S.createReadStream(e),r).catch(e=>{throw new t(`COMMAND_FAILED`,`Failed to read local artifact`,{},e instanceof Error?e:void 0)}),n.digest(`hex`)}function it(e){let{stage:t,fileName:n,startOffset:r,totalBytes:i,onProgress:a}=e,o=r,s=st(i),c=Math.min(i,r+s);return new Je({transform(e,r,l){o=Math.min(i,o+e.byteLength),o>=c&&(a?.({type:`progress`,stage:t,fileName:n,transferredBytes:o,totalBytes:i}),c=Math.min(i,o+s)),l(null,e)}})}function at(){if(!(process.stderr.isTTY!==!0||process.env.CI))return e=>{process.stderr.write(`${ot(e)}\n`)}}function ot(e){switch(e.type){case`start`:return`Uploading ${e.fileName} (${k(e.totalBytes)}) via ${ct(e.stage)} upload`;case`resume`:return`Resuming ${e.fileName} at ${k(e.transferredBytes)} of ${k(e.totalBytes)}`;case`progress`:return`Uploaded ${k(e.transferredBytes)} of ${k(e.totalBytes)} (${lt(e.transferredBytes,e.totalBytes)})`;case`fallback`:return`Direct upload did not complete; retrying ${e.fileName} with ${ct(e.to)} upload`}}function st(e){return Math.max(8388608,Math.ceil(e*.05))}function ct(e){return e===`direct`?`direct`:`legacy`}function lt(e,t){return t<=0?`100%`:`${Math.min(100,Math.floor(e/t*100))}%`}function k(e){if(e<1024)return`${e} B`;let t=e/1024;if(t<1024)return`${t.toFixed(1)} KiB`;let n=t/1024;return n<1024?`${n.toFixed(1)} MiB`:`${(n/1024).toFixed(1)} GiB`}const ut=300*1e3,dt=`uploadStreamRetryable`;async function ft(e){return await A({...e,url:e.url,redirectCount:0,startOffset:0})}function pt(e){return e instanceof t&&e.details?.[dt]===!0}async function A(e){let n=e.url.protocol===`https:`?T:w,r=S.statSync(e.payloadPath).size,i=gt(e.headers,e.startOffset,r);return ht(e.progress,e.startOffset,r),await new Promise((a,o)=>{let s=!1,c=n.request({protocol:e.url.protocol,host:e.url.hostname,port:e.url.port,method:e.method,path:e.url.pathname+e.url.search,headers:i},n=>{s=!0,re(n).then(i=>{clearTimeout(l);let s=n.statusCode??500,c=n.headers.location;if(c&&_t(s)){if(e.redirectCount>=5){o(new t(`COMMAND_FAILED`,`Artifact upload exceeded redirect limit`,{maxRedirects:5,url:e.url.toString()}));return}let n=new URL(c,e.url);A({...e,url:n,redirectCount:e.redirectCount+1}).then(a,o);return}let u=vt(s)?yt(n.headers,r):void 0;if(u!==void 0){if(u>=r){a({statusCode:200,statusMessage:`Upload already complete`,body:``});return}if(u<=e.startOffset){o(new t(`COMMAND_FAILED`,`Artifact upload resume did not advance`,{offset:u,previousOffset:e.startOffset,url:e.url.toString()}));return}A({...e,startOffset:u}).then(a,o);return}a({statusCode:s,statusMessage:n.statusMessage,body:i})}).catch(o)}),l=setTimeout(()=>{c.destroy(),o(new t(`COMMAND_FAILED`,e.timeoutMessage,{timeoutMs:ut,...e.timeoutHint?{hint:e.timeoutHint}:{},...mt(e)}))},ut);c.on(`error`,n=>{s||(clearTimeout(l),o(new t(`COMMAND_FAILED`,e.errorMessage,{...e.errorHint?{hint:e.errorHint}:{},...mt(e)},n)))}),c.on(`close`,()=>clearTimeout(l)),qe(S.createReadStream(e.payloadPath,{start:e.startOffset}),it({stage:e.progress?.stage??`legacy`,fileName:e.progress?.fileName??C.basename(e.payloadPath),startOffset:e.startOffset,totalBytes:r,onProgress:e.progress?.onProgress}),c).catch(e=>{s||(c.destroy(),o(new t(`COMMAND_FAILED`,`Failed to read local artifact`,{},e instanceof Error?e:Error(String(e)))))})})}function mt(e){return e.retryable===!0?{[dt]:!0}:{}}function ht(e,t,n){e?.onProgress?.({type:t>0?`resume`:`start`,stage:e.stage,fileName:e.fileName,transferredBytes:t,totalBytes:n})}function gt(e,t,n){return t<=0?e:{...e,"content-length":Math.max(n-t,0),"content-range":`bytes ${t}-${n-1}/${n}`}}function _t(e){return[301,302,303,307,308].includes(e)}function vt(e){return e===308}function yt(e,t){let n=bt(e[`x-upload-offset`]??e[`upload-offset`]);if(n!==void 0)return Math.min(n,t);let r=xt(e.range)?.match(/^bytes=0-(\d+)$/);if(!r)return;let i=Number(r[1]);if(!(!Number.isSafeInteger(i)||i<0))return Math.min(i+1,t)}function bt(e){let t=xt(e);if(t===void 0)return;let n=Number(t);return Number.isSafeInteger(n)&&n>=0?n:void 0}function xt(e){return Array.isArray(e)?e[0]:e}const St=30*1e3;async function Ct(e){let t=await Qe(e.localPath,e.platform),n=e.baseUrl.endsWith(`/`)?e.baseUrl:`${e.baseUrl}/`,r=Ge();try{let i=await Dt({normalizedBase:n,token:e.token,artifact:t,uploadAttemptId:r});return i?.kind===`cache-hit`?i.uploadId:i?.kind===`direct-upload`?await wt({normalizedBase:n,token:e.token,artifact:t,preflight:i,uploadAttemptId:r,onProgress:e.onProgress})||(e.onProgress?.({type:`fallback`,from:`direct`,to:`legacy`,fileName:t.fileName}),await Et({normalizedBase:n,token:e.token,artifact:t,onProgress:e.onProgress})):await Et({normalizedBase:n,token:e.token,artifact:t,onProgress:e.onProgress})}finally{t.cleanup()}}async function wt(e){let t=async t=>(await At(e.artifact,t,e.onProgress),await jt({normalizedBase:e.normalizedBase,token:e.token,uploadId:t.uploadId}));try{return await t(e.preflight)}catch(n){if(!Tt(n))return;let r=await Dt({normalizedBase:e.normalizedBase,token:e.token,artifact:e.artifact,uploadAttemptId:e.uploadAttemptId});if(r?.kind===`cache-hit`)return r.uploadId;if(r?.kind===`direct-upload`)try{return await t(r)}catch{return}return}}function Tt(e){return e instanceof t?pt(e):!0}async function Et(e){let{normalizedBase:n,token:r,artifact:i}=e,a=new URL(`upload`,n),o={"content-type":i.contentType,"x-artifact-type":i.artifactType,"x-artifact-filename":i.fileName,"x-artifact-hash":i.sha256,"x-artifact-hash-algorithm":`sha256`,"transfer-encoding":`chunked`};Object.assign(o,O(r));let s=await ft({url:a,method:`POST`,headers:o,payloadPath:i.payloadPath,timeoutMessage:`Artifact upload timed out`,timeoutHint:`The upload to the remote daemon exceeded the 5-minute timeout.`,errorMessage:`Failed to upload artifact to remote daemon`,errorHint:`Verify the remote daemon is reachable and supports artifact uploads.`,progress:{stage:`legacy`,fileName:i.fileName,onProgress:e.onProgress}});try{let e=JSON.parse(s.body);if(!e.ok||!e.uploadId)throw new t(`COMMAND_FAILED`,`Upload failed: ${s.body}`);return e.uploadId}catch(e){throw e instanceof t?e:new t(`COMMAND_FAILED`,`Invalid upload response: ${s.body}`)}}async function Dt(e){let t=new URL(`upload/preflight`,e.normalizedBase),n={"content-type":`application/json`};Object.assign(n,O(e.token));let r=await fetch(t,{method:`POST`,headers:n,signal:AbortSignal.timeout(St),body:JSON.stringify({uploadAttemptId:e.uploadAttemptId,sha256:e.artifact.sha256,fileName:e.artifact.fileName,sizeBytes:e.artifact.sizeBytes,artifactType:e.artifact.artifactType,...e.artifact.platform?{platform:e.artifact.platform}:{},contentType:e.artifact.contentType})}).catch(()=>void 0);if(r?.ok)return Ot(await r.json().catch(()=>void 0))}function Ot(e){if(!e||typeof e!=`object`)return;let t=e;if(t.ok!==!0||typeof t.uploadId!=`string`)return;if(t.cacheHit===!0)return{kind:`cache-hit`,uploadId:t.uploadId};let n=t.upload;if(!n||typeof n.url!=`string`)return;let r=n.headers??{};if(kt(r))return{kind:`direct-upload`,uploadId:t.uploadId,url:n.url,headers:r}}function kt(e){return!e||typeof e!=`object`||Array.isArray(e)?!1:Object.values(e).every(e=>typeof e==`string`)}async function At(e,n,r){let i=await ft({url:new URL(n.url),method:`PUT`,headers:n.headers,payloadPath:e.payloadPath,timeoutMessage:`Direct artifact upload timed out`,timeoutHint:`The direct upload ticket did not accept the artifact within the timeout.`,errorMessage:`Failed to upload artifact with direct upload ticket`,retryable:!0,progress:{stage:`direct`,fileName:e.fileName,onProgress:r}});if(i.statusCode<200||i.statusCode>=300)throw new t(`COMMAND_FAILED`,`Direct artifact upload failed`,{statusCode:i.statusCode,statusMessage:i.statusMessage})}async function jt(e){let n=new URL(`upload/finalize`,e.normalizedBase),r={"content-type":`application/json`};Object.assign(r,O(e.token));let i=await fetch(n,{method:`POST`,headers:r,signal:AbortSignal.timeout(St),body:JSON.stringify({uploadId:e.uploadId})}).catch(e=>{throw new t(`COMMAND_FAILED`,`Failed to finalize direct artifact upload`,{},e)});if(!i.ok)throw new t(`COMMAND_FAILED`,`Direct artifact upload finalize failed`,{status:i.status,statusText:i.statusText});let a=await i.json().catch(()=>void 0);if(!a?.ok||!a.uploadId)throw new t(`COMMAND_FAILED`,`Invalid upload finalize response`);return a.uploadId}async function Mt(e,t){let n=[...e.positionals??[]],r=e.flags?{...e.flags}:void 0,i=e.meta?.installSource,a={},o,s=at();if(!Jt(t))return Lt({positionals:n,flags:r,installSource:i,uploadedArtifactId:o,clientArtifactPaths:a});r=Pt(e,n,r,a);let c=await Rt(e,t,s);return c&&(i=c.installSource,o=c.uploadedArtifactId??o),e.command!==`install`&&e.command!==`reinstall`||(o=await Nt(e,t,n,s)??o),Lt({positionals:n,flags:r,installSource:i,uploadedArtifactId:o,clientArtifactPaths:a})}async function Nt(e,t,n,r){let i=n.length===1?0:1,a=n[i];if(a===void 0)return;if(a.startsWith(`remote:`)){n[i]=a.slice(7);return}let o=It(a,e.meta?.cwd);if(o)return await Ct({localPath:o,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform,onProgress:r})}function Pt(e,t,n,r){let i=zt(e,t);if(!i)return n;i.positionalPath!==void 0&&(t[i.positionalIndex]=i.positionalPath);let a=Ft(n,i.flagPath);return r[i.field]=i.localPath,a}function Ft(e,t){return t===void 0?e:{...e??{},out:t}}function It(e,t){let n=C.isAbsolute(e)?e:C.resolve(t??process.cwd(),e);return S.existsSync(n)?n:void 0}function Lt(e){return{positionals:e.positionals,flags:e.flags,installSource:e.installSource,uploadedArtifactId:e.uploadedArtifactId,...Object.keys(e.clientArtifactPaths).length>0?{clientArtifactPaths:e.clientArtifactPaths}:{}}}async function Rt(e,t,n){let r=e.meta?.installSource;if(e.command!==`install_source`||!r||r.kind!==`path`)return null;let i=r.path.trim();if(!i)return{installSource:r};if(i.startsWith(`remote:`))return{installSource:{...r,path:i.slice(7)}};let a=C.isAbsolute(i)?i:C.resolve(e.meta?.cwd??process.cwd(),i);if(!S.existsSync(a))return{installSource:{...r,path:a}};let o=await Ct({localPath:a,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform,onProgress:n});return{installSource:{...r,path:a},uploadedArtifactId:o}}function zt(e,t){if(e.command===`screenshot`){let n=Ut(e,`path`,`.png`);return t[0]?{field:`path`,localPath:n,positionalIndex:0,positionalPath:M(`screenshot`,`.png`)}:{field:`path`,localPath:n,positionalIndex:0,flagPath:M(`screenshot`,`.png`)}}if(e.command===`record`&&(t[0]??``).toLowerCase()===`start`){if(!Vt(e)&&e.flags?.platform===void 0)return null;let t=Bt(e),n=Ht(Ut(e,`outPath`,t,1),e);return{field:`outPath`,localPath:n,positionalIndex:1,positionalPath:M(`recording`,C.extname(n)||t)}}return null}function Bt(e){return te(e.flags?.platform)}function Vt(e){return j(e.positionals?.[1])||j(e.flags?.out)}function Ht(e,t){return t.flags?.platform===`web`?ne(e,Bt(t)):e}function Ut(e,t,n,r=0){let i=e.positionals?.[r]??e.flags?.out,a=`${t===`path`?`screenshot`:`recording`}-${Date.now()}${n}`,o=j(i)?i:a;return C.isAbsolute(o)?o:C.resolve(e.meta?.cwd??process.cwd(),o)}function j(e){return typeof e==`string`&&e.trim().length>0}function M(e,t){let n=t.startsWith(`.`)?t:`.${t}`;return C.posix.join(`/tmp`,`agent-device-${e}-${Date.now()}-${Math.random().toString(36).slice(2,8)}${n}`)}async function Wt(e,t,n){let r=Array.isArray(n.data?.artifacts)?n.data.artifacts:[];if(r.length===0||!e.baseUrl)return n;let i=n.data?{...n.data}:{},a=[];for(let n of r){if(!n||typeof n!=`object`||typeof n.artifactId!=`string`){a.push(n);continue}let r=Gt(n,t);await Kt({baseUrl:e.baseUrl,token:e.token,artifactId:n.artifactId,destinationPath:r,requestId:t.meta?.requestId}),i[n.field]=r,a.push({...n,localPath:r})}return i.artifacts=a,{ok:!0,data:i}}function Gt(e,t){if(e.localPath&&e.localPath.trim().length>0)return e.localPath;let n=t.meta?.clientArtifactPaths?.[e.field];if(n&&n.trim().length>0)return n;let r=e.fileName?.trim()||`${e.field}-${Date.now()}`;return C.resolve(t.meta?.cwd??process.cwd(),r)}async function Kt(e){let n=new URL(qt(e.baseUrl,e.artifactId)),r=n.protocol===`https:`?T:w;await S.promises.mkdir(C.dirname(e.destinationPath),{recursive:!0}),await new Promise((i,a)=>{let o=!1,s=e.timeoutMs??9e4,c=t=>{if(!o){if(o=!0,clearTimeout(u),t){S.promises.rm(e.destinationPath,{force:!0}).finally(()=>a(t));return}i()}},l=r.request({protocol:n.protocol,host:n.hostname,port:n.port,method:`GET`,path:n.pathname+n.search,headers:O(e.token)},n=>{if((n.statusCode??500)>=400){let r=``;n.setEncoding(`utf8`),n.on(`data`,e=>{r+=e}),n.on(`end`,()=>{c(new t(`COMMAND_FAILED`,`Failed to download remote artifact`,{artifactId:e.artifactId,statusCode:n.statusCode,requestId:e.requestId,body:r}))});return}n.on(`aborted`,()=>{c(new t(`COMMAND_FAILED`,`Remote artifact download was interrupted`,{artifactId:e.artifactId,requestId:e.requestId}))}),qe(n,S.createWriteStream(e.destinationPath)).then(()=>c(),e=>c(e instanceof Error?e:Error(String(e))))}),u=setTimeout(()=>{let n=new t(`COMMAND_FAILED`,`Remote artifact download timed out`,{artifactId:e.artifactId,requestId:e.requestId,timeoutMs:s});c(n),l.destroy(n)},s);l.on(`error`,n=>{if(n instanceof t){c(n);return}c(new t(`COMMAND_FAILED`,`Failed to download remote artifact`,{artifactId:e.artifactId,requestId:e.requestId,timeoutMs:s},n instanceof Error?n:void 0))}),l.end()})}function qt(e,t){let n=e.endsWith(`/`)?e:`${e}/`;return new URL(`artifacts/${encodeURIComponent(t)}`,n).toString()}function Jt(e){return typeof e.baseUrl==`string`&&e.baseUrl.length>0}const Yt=3e3,Xt=1e3;function N(e){let t=on(e);if(!t||typeof t!=`object`)return null;let n=t,r=Zt(n);if(!r)return null;let i=Qt(n);return i?{token:r,...i,transport:$t(n.transport),pid:F(n.pid)??0,version:P(n.version),codeSignature:P(n.codeSignature),processStartTime:P(n.processStartTime)}:null}function Zt(e){return typeof e.token==`string`&&e.token.length>0?e.token:null}function Qt(e){let t=F(e.port),n=F(e.httpPort);return t===void 0&&n===void 0?null:{port:t,httpPort:n}}function $t(e){return e===`socket`||e===`http`||e===`dual`?e:void 0}function P(e){return typeof e==`string`?e:void 0}function F(e){return Number.isInteger(e)&&Number(e)>0?Number(e):void 0}function I(e){let t=on(e);if(!t||typeof t!=`object`)return null;let n=t;return Number.isInteger(n.pid)&&Number(n.pid)>0?{pid:Number(n.pid),processStartTime:typeof n.processStartTime==`string`?n.processStartTime:void 0,startedAt:typeof n.startedAt==`number`?n.startedAt:void 0}:null}function L(e){sn(e)}function R(e){sn(e)}function en(e){let t=B(e);if(!t.hasLock||t.hasInfo)return;let n=I(e.lockPath);if(!n){R(e.lockPath);return}_(n.pid,n.processStartTime)||R(e.lockPath)}async function z(e,t,n={}){let r=n.stopLiveProcesses??!0,i={reason:t,removedInfo:!1,removedLock:!1,stoppedInfoProcess:!1,stoppedLockProcess:!1};try{let t=S.existsSync(e.infoPath),n=N(e.infoPath);if(n){let t=_(n.pid,n.processStartTime);t&&!r?i.retainedInfoProcess=!0:(t&&(await V(n),i.stoppedInfoProcess=!0),L(e.infoPath),i.removedInfo=!0)}else t&&(L(e.infoPath),i.removedInfo=!0);let a=S.existsSync(e.lockPath),o=I(e.lockPath);if(o){let t=_(o.pid,o.processStartTime);t&&!r?i.retainedLockProcess=!0:(t&&(await me(o.pid,{termTimeoutMs:Yt,killTimeoutMs:Xt,expectedStartTime:o.processStartTime}),i.stoppedLockProcess=!0),R(e.lockPath),i.removedLock=!0)}else a&&(R(e.lockPath),i.removedLock=!0)}catch(e){i.error=e instanceof Error?e.message:String(e)}return c({level:i.error?`warn`:`info`,phase:`daemon_startup_metadata_cleanup`,data:i}),i}function B(e){return{hasInfo:S.existsSync(e.infoPath),hasLock:S.existsSync(e.lockPath)}}async function tn(e){let t=B(e);if(!t.hasLock||t.hasInfo)return!1;let n=I(e.lockPath);return!n||!_(n.pid,n.processStartTime)?(R(e.lockPath),!0):!1}async function V(e){await me(e.pid,{termTimeoutMs:Yt,killTimeoutMs:Xt,expectedStartTime:e.processStartTime})}function nn(e){return typeof e.baseUrl==`string`&&e.baseUrl.length>0}function rn(e,t=g(process.env.AGENT_DEVICE_STATE_DIR)){let n=an(t);return e.hasLock&&!e.hasInfo?`agent-device attempted to clean stale daemon metadata automatically, but ${t.lockPath} still exists without ${t.infoPath}. Retry with --debug; if this persists after confirming no agent-device daemon process is running, run: ${n}`:e.hasLock&&e.hasInfo?`agent-device attempted to clean stale daemon metadata automatically, but ${t.infoPath} and ${t.lockPath} still remain. Retry with --debug; if this persists after confirming no agent-device daemon process is running, run: ${n}`:e.hasInfo?`agent-device did not observe reachable daemon metadata after retrying, and ${t.infoPath} still remains. Stale metadata was cleaned automatically when safe; retry with --debug. If this persists after confirming no agent-device daemon process is running, run: ${n}`:`agent-device did not observe reachable daemon metadata after retrying. Stale metadata was cleaned automatically when safe; retry with --debug and check daemon diagnostics logs. If stale metadata returns after confirming no agent-device daemon process is running, run: ${n}`}function an(e){return`rm -f ${oe(e.infoPath)} ${oe(e.lockPath)}`}function on(e){if(!S.existsSync(e))return null;try{return JSON.parse(S.readFileSync(e,`utf8`))}catch{return null}}function sn(e){try{S.existsSync(e)&&S.unlinkSync(e)}catch{}}function cn(e,t){if(t.onProgress){t.onProgress(e);return}e.type===`command`&&(t.req.command===`doctor`&&Ce(),process.stderr.write(`${e.message}\n`))}function H(e,n,r){return new t(`COMMAND_FAILED`,`Invalid daemon response`,{requestId:e.meta?.requestId,line:n},r instanceof Error?r:void 0)}function ln(e){let t=t=>(e.onError(t),!0);return{handleLine(n){let r;try{r=JSON.parse(n)}catch(r){return t(H(e.req,n,r))}if(ce(r))try{return cn(r.event,{req:e.req,onProgress:e.onProgress}),!1}catch(e){return t(e)}return fe(r)?(e.onResponse(r.response),!0):e.responseFormat===`socket-legacy`?(e.onResponse(r),!0):t(H(e.req,n,Error(`Missing daemon progress response envelope`)))}}}function un(e,t){return le(e)&&String(Array.isArray(t)?t.join(`,`):t??``).includes(`application/x-ndjson`)}function dn(e,t){let{req:n,isSettled:r,resolve:i,reject:a,clearTimeout:o}=t,s=``,c=ln({req:n,onProgress:t.onProgress,responseFormat:`socket-legacy`,onResponse(t){o(),i(t),e.end()},onError(e){o(),a(e)}});e.setEncoding(`utf8`),e.on(`data`,e=>{if(r())return;let t=se(s,e);s=t.buffer;for(let e of t.lines)if(c.handleLine(e))return})}function fn(e,n){let{req:r,handleResponseBody:i,reject:a,clearTimeout:o}=n,s=``,c=!1,l=ln({req:r,onProgress:n.onProgress,responseFormat:`ndjson-envelope`,onResponse(e){c=!0,o(),i(JSON.stringify(e))},onError(e){c=!0,o(),a(e)}});e.setEncoding(`utf8`),e.on(`data`,e=>{if(c)return;let t=se(s,e);s=t.buffer;for(let e of t.lines)if(e&&l.handleLine(e))return}),e.on(`end`,()=>{if(c)return;let e=s.trim();e&&l.handleLine(e)||(c=!0,o(),a(H(r,e)))}),e.on(`error`,e=>{c||(c=!0,o(),a(new t(`COMMAND_FAILED`,`Failed to read daemon response`,{requestId:r.meta?.requestId},e instanceof Error?e:void 0)))})}function pn(e,n){let{info:r,req:i,resolve:a,reject:o}=n;try{let n=mn(e);if(n.error){o(hn(n.error,i.meta?.requestId));return}if(!n.result||typeof n.result!=`object`){o(new t(`COMMAND_FAILED`,`Invalid daemon RPC response`,{requestId:i.meta?.requestId}));return}gn(r,i,n.result,a,o)}catch(n){o(new t(`COMMAND_FAILED`,`Invalid daemon response`,{requestId:i.meta?.requestId,line:e},n instanceof Error?n:void 0))}}function mn(e){return JSON.parse(e)}function hn(e,r){let i=e.data??{};return new t(n(i.code==null?void 0:String(i.code),`COMMAND_FAILED`),String(i.message??e.message??`Daemon RPC request failed`),{...typeof i.details==`object`&&i.details?i.details:{},hint:typeof i.hint==`string`?i.hint:void 0,diagnosticId:typeof i.diagnosticId==`string`?i.diagnosticId:void 0,logPath:typeof i.logPath==`string`?i.logPath:void 0,retriable:typeof i.retriable==`boolean`?i.retriable:void 0,supportedOn:typeof i.supportedOn==`string`?i.supportedOn:void 0,requestId:r})}async function gn(e,t,n,r,i){try{r(e.baseUrl&&n.ok?await Wt(e,t,n):n)}catch(e){i(e)}}function _n(e,t){let n=e.meta?.requestId??i();return vn(e.command)?{jsonrpc:`2.0`,id:n,method:yn(e.command),params:bn(e,e.command,t)}:{jsonrpc:`2.0`,id:n,method:`agent_device.command`,params:e}}function vn(e){return e===`lease_allocate`||e===`lease_heartbeat`||e===`lease_release`}function yn(e){switch(e){case`lease_allocate`:return`agent_device.lease.allocate`;case`lease_heartbeat`:return`agent_device.lease.heartbeat`;case`lease_release`:return`agent_device.lease.release`}}function bn(e,t,n){return p(f(e),t,{includeTokenParam:n.includeTokenParam,token:e.token,session:e.session})}const xn=[`xcodebuild .*AgentDeviceRunnerUITests/RunnerTests/testCommand`,`xcodebuild .*AgentDeviceRunner\\.env\\.session-`,`xcodebuild build-for-testing .*apple-runner/AgentDeviceRunner/AgentDeviceRunner\\.xcodeproj`];function Sn(e){let t=d(e.command);if(t.envelopeMs===`unbounded`)return;let n={...t,envelopeMs:t.envelopeMs};return Cn(n,e.positionals??[])??wn(n,e.flags)??n.envelopeMs}function Cn(e,t){if(e.budget.source!==`positional-parser`)return;let n=e.budget.parser(t);return n===null?void 0:En(e,n)}function wn(e,t){if(e.budget.source===`flag`)return e.budget.envelope===`widen`?Tn(e,e.budget,t):typeof t?.timeoutMs==`number`?t.timeoutMs:e.envelopeMs}function Tn(e,t,n){if(n?.settle!==!0)return e.envelopeMs;let r=typeof n.timeoutMs==`number`?n.timeoutMs:t.defaultBudgetMs;return typeof r==`number`?Dn(e,r):e.envelopeMs}function En(e,t){return Math.max(e.envelopeMs,t+Nn)}function Dn(e,t){return Math.max(e.envelopeMs,e.envelopeMs+t+Nn)}function On(e,n,r,i,a,o){let s=a?{terminated:0}:jn(),l=!a&&kn(i),u=l?Mn(e,n):{forcedKill:!1};return c({level:`error`,phase:`daemon_request_timeout`,data:{timeoutMs:o,requestId:r,command:i,timedOutRunnerPidsTerminated:s.terminated,timedOutRunnerCleanupError:s.error,daemonPidReset:l?e.pid:void 0,daemonPidForceKilled:l?u.forcedKill:void 0,daemonPreservedAfterTimeout:!a&&!l,daemonBaseUrl:e.baseUrl}}),new t(`COMMAND_FAILED`,`Daemon request timed out`,{timeoutMs:o,requestId:r,hint:An({remote:a,resetDaemon:l,command:i})})}function kn(e){return d(e).onTimeout===`reset-daemon`}function An(e){let{remote:t,resetDaemon:n,command:r}=e;if(t)return`Retry with --debug and verify the remote daemon URL, auth token, and remote host logs.`;if(!n){let e=r===m.snapshot?` If this was the first Apple-platform snapshot on the device, run agent-device prepare ios-runner with the same --platform before snapshot/test so runner startup is handled explicitly.`:``;return`Retry with --debug and check daemon diagnostics logs. The timed-out ${r??`request`} request was canceled and Apple runner work was aborted when detected; the daemon was kept alive so the session can still be closed or inspected.${e}`}return`Retry with --debug and check daemon diagnostics logs. Timed-out Apple runner xcodebuild processes were terminated when detected.`}function jn(){let e=0;try{for(let t of xn)a(`pkill`,[`-f`,t],{allowFailure:!0}).exitCode===0&&(e+=1);return{terminated:e}}catch(t){return{terminated:e,error:t instanceof Error?t.message:String(t)}}}function Mn(e,t){let n=!1;try{_(e.pid,e.processStartTime)&&(process.kill(e.pid,`SIGKILL`),n=!0)}catch{V(e)}finally{L(t.infoPath),R(t.lockPath)}return{forcedKill:n}}const Nn=3e4,Pn=`Daemon HTTP endpoint is unavailable`,Fn=`Daemon socket endpoint is unavailable`;async function In(e,t){let n=Gn(e,t);if(await Ln(e,n))return!0;let r=Kn(e,t,n);return r?await Ln(e,r):!1}async function Ln(e,t){return t===`http`?await zn(e):await Rn(e.port)}function Rn(e){return e?new Promise(t=>{let n=!1,r=E.createConnection({host:`127.0.0.1`,port:e},()=>{i(!0)}),i=e=>{n||(n=!0,r.destroy(),t(e))};r.setTimeout(500),r.on(`timeout`,()=>{i(!1)}),r.on(`error`,()=>{i(!1)})}):Promise.resolve(!1)}function zn(e){return Vn(e).then(e=>e.reachable)}async function Bn(e){let n=await Vn(e);if(!e.baseUrl||!n.reachable)return n;if(typeof n.rpcProtocolVersion==`number`&&n.rpcProtocolVersion!==1)throw new t(`COMMAND_FAILED`,`Remote daemon RPC protocol is incompatible`,{daemonBaseUrl:e.baseUrl,clientVersion:v(),remoteVersion:n.version,remoteService:n.service,supportedRpcProtocolVersion:1,remoteRpcProtocolVersion:n.rpcProtocolVersion,hint:`Upgrade agent-device on the client or remote host so both support the same daemon RPC protocol.`});return n}function Vn(e){let t=e.baseUrl?D(e.baseUrl,`health`):e.httpPort?`http://127.0.0.1:${e.httpPort}/health`:null;if(!t)return Promise.resolve({reachable:!1});let n=new URL(t),r=n.protocol===`https:`?T:w,i=e.baseUrl?3e3:500;return new Promise(t=>{let a=e.baseUrl?O(e.token):{},o=r.request({protocol:n.protocol,host:n.hostname,port:n.port,path:n.pathname+n.search,method:`GET`,timeout:i,headers:a},e=>{let n=``;e.setEncoding(`utf8`),e.on(`data`,e=>{n+=e}),e.on(`end`,()=>{let r=e.statusCode??500;t({reachable:r<500,statusCode:r,...Hn(n)})})});o.on(`timeout`,()=>{o.destroy(),t({reachable:!1})}),o.on(`error`,()=>{t({reachable:!1})}),o.end()})}function Hn(e){try{let t=JSON.parse(e);return{service:typeof t.service==`string`?t.service:void 0,version:typeof t.version==`string`?t.version:void 0,rpcProtocolVersion:typeof t.rpcProtocolVersion==`number`?t.rpcProtocolVersion:void 0}}catch{return{}}}async function Un(e,t,n,r,i,a={}){let o=Gn(e,n);try{return await Wn(e,t,r,i,o,a)}catch(s){let c=Kn(e,n,o);if(!c||!qn(s,o))throw s;return await Wn(e,t,r,i,c,a)}}async function Wn(e,t,n,r,i,a){return i===`http`?await Zn(e,t,n,r,a):await Xn(e,t,n,r,a)}function Gn(e,n){if(e.baseUrl){if(n===`socket`)throw new t(`COMMAND_FAILED`,`Remote daemon endpoint only supports HTTP transport`,{daemonBaseUrl:e.baseUrl});return`http`}if(n===`http`||n===`socket`)return Jn(e,n);let r=(e.transport===`socket`||e.transport===`dual`?[`socket`,`http`]:[`http`,`socket`]).find(t=>U(e,t));if(r)return r;throw new t(`COMMAND_FAILED`,`Daemon metadata has no reachable transport`)}function U(e,t){return t===`http`?!!e.httpPort:!!e.port}function Kn(e,t,n){if(t!==`auto`||e.baseUrl)return null;let r=n===`socket`?`http`:`socket`;return U(e,r)?r:null}function qn(e,n){return n===`socket`&&e instanceof t&&e.code===`COMMAND_FAILED`&&e.message===`Failed to communicate with daemon`&&e.details?.daemonSocketRequestWritten===!1}function Jn(e,n){if(U(e,n))return n;throw new t(`COMMAND_FAILED`,n===`http`?Pn:Fn)}function Yn(e,n,r,i={}){return c({level:`error`,phase:`daemon_request_socket_error`,data:{requestId:n,message:e instanceof Error?e.message:String(e)}}),new t(`COMMAND_FAILED`,`Failed to communicate with daemon`,{...i,requestId:n,hint:r?`Retry command. If this persists, verify the remote daemon URL, auth token, and remote host reachability.`:`Retry command. If this persists, clean stale daemon metadata and start a fresh session.`},e instanceof Error?e:void 0)}async function Xn(e,n,r,i,a){let o=e.port;if(!o)throw new t(`COMMAND_FAILED`,Fn);return new Promise((t,s)=>{let c=!1,l=E.createConnection({host:`127.0.0.1`,port:o},()=>{c=!0,l.write(`${JSON.stringify(n)}\n`)}),u=!1,d=typeof i==`number`?setTimeout(()=>{u=!0,l.destroy(),s(On(e,r,n.meta?.requestId,n.command,!1,i))},i):void 0;dn(l,{req:n,onProgress:a.onProgress,isSettled:()=>u,clearTimeout:()=>{d&&clearTimeout(d)},resolve:e=>{u=!0,t(e)},reject:e=>{u=!0,s(e)}}),l.on(`error`,e=>{u||(u=!0,d&&clearTimeout(d),s(Yn(e,n.meta?.requestId,!1,{daemonSocketRequestWritten:c})))})})}async function Zn(e,n,r,i,a){let o=e.baseUrl?new URL(D(e.baseUrl,`rpc`)):e.httpPort?new URL(`http://127.0.0.1:${e.httpPort}/rpc`):null;if(!o)throw new t(`COMMAND_FAILED`,Pn);let s=JSON.stringify(_n(n,{includeTokenParam:!e.baseUrl})),c={"content-type":`application/json`,"content-length":Buffer.byteLength(s)};return e.baseUrl&&Object.assign(c,O(e.token)),await new Promise((l,u)=>{let d=(o.protocol===`https:`?T:w).request({protocol:o.protocol,host:o.hostname,port:o.port,method:`POST`,path:o.pathname+o.search,headers:c},r=>{if(un(n,r.headers?.[`content-type`])){fn(r,{req:n,onProgress:a.onProgress,reject:u,clearTimeout:()=>{p&&clearTimeout(p)},handleResponseBody:t=>pn(t,{info:e,req:n,resolve:l,reject:u})});return}re(r).then(t=>{p&&clearTimeout(p),pn(t,{info:e,req:n,resolve:l,reject:u})}).catch(e=>{p&&clearTimeout(p),u(new t(`COMMAND_FAILED`,`Failed to read daemon response`,{requestId:n.meta?.requestId},e instanceof Error?e:void 0))})}),f=nn(e),p=typeof i==`number`?setTimeout(()=>{d.destroy(),u(On(e,r,n.meta?.requestId,n.command,f,i))},i):void 0;d.on(`error`,e=>{p&&clearTimeout(p),u(Yn(e,n.meta?.requestId,f))}),d.write(s),d.end()})}const W=15e3,G=new E.BlockList;G.addSubnet(`127.0.0.0`,8,`ipv4`),G.addAddress(`::1`,`ipv6`),G.addSubnet(`::ffff:127.0.0.0`,104,`ipv6`);function Qn(e){let t=$n(e),n=er(e),r=tr(e,n.remoteBaseUrl),i=nr(e,t,n.rawBaseUrl);return{paths:g(i?rr():t),transportPreference:r.preference,serverMode:r.serverMode,ownedStateDir:i,remoteBaseUrl:n.remoteBaseUrl,remoteAuthToken:n.authToken}}function $n(e){return e.flags?.stateDir??process.env.AGENT_DEVICE_STATE_DIR}function er(e){let t=e.flags?.daemonBaseUrl??process.env.AGENT_DEVICE_DAEMON_BASE_URL,n=xr(t),r=e.flags?.daemonAuthToken??process.env.AGENT_DEVICE_DAEMON_AUTH_TOKEN;return Sr(n,r),{rawBaseUrl:t,remoteBaseUrl:n,authToken:r}}function tr(e,n){let r=e.flags?.daemonTransport??process.env.AGENT_DEVICE_DAEMON_TRANSPORT,i=ie(r);if(n&&i===`socket`)throw new t(`INVALID_ARGS`,`Remote daemon base URL only supports HTTP transport. Remove --daemon-transport socket.`,{daemonBaseUrl:n});return{preference:i,serverMode:pe(e.flags?.daemonServerMode??process.env.AGENT_DEVICE_DAEMON_SERVER_MODE??(r===`dual`?`dual`:void 0))}}function nr(e,t,n){return mr(e.command)&&!t&&!n}function rr(){return S.mkdtempSync(C.join(Ke.tmpdir(),`agent-device-replay-daemon-`))}async function ir(e){if(e.remoteBaseUrl)return await ar(e);let t=await or(e);return t?{info:t,startedByClient:!1}:(en(e.paths),await fr(e))}async function ar(e){let n={transport:`http`,token:e.remoteAuthToken??``,pid:0,baseUrl:e.remoteBaseUrl};if((await Bn(n)).reachable)return{info:n,startedByClient:!1};throw new t(`COMMAND_FAILED`,`Remote daemon is unavailable`,{daemonBaseUrl:e.remoteBaseUrl,hint:`Verify AGENT_DEVICE_DAEMON_BASE_URL points to a reachable daemon with GET /health and POST /rpc. If this CLI was connected with connect proxy, run agent-device disconnect to return to the local daemon.`})}async function or(e){let t=N(e.paths.infoPath);if(!t)return null;let n=await sr(t,e.transportPreference);return lr(t,n)?t:(ur(t,n,e.paths.baseDir),await V(t),L(e.paths.infoPath),null)}async function sr(e,t){try{return await In(e,t)}catch(e){if(cr(e))return!1;throw e}}function cr(e){return e instanceof t&&e.code===`COMMAND_FAILED`&&(e.message===`Daemon HTTP endpoint is unavailable`||e.message===`Daemon socket endpoint is unavailable`)}function lr(e,t){return e.version===v()&&e.codeSignature===vr()&&t}function ur(e,t,n){try{let r=e.version?`pid ${e.pid}, v${e.version}`:`pid ${e.pid}`,i=dr(e,t);process.stderr.write(`Replacing daemon (${r}) in ${n}: ${i}\n`)}catch{}}function dr(e,t){return e.version===v()?e.codeSignature===vr()?t?`not reusable`:`unreachable`:`code-signature mismatch`:`version mismatch (client v${v()})`}async function fr(e){let n=0,r=[],i,a;for(let t=1;t<=2;t+=1){let o;try{o=gr(e),a={pid:o.pid}}catch(n){if(i=n instanceof Error?n.message:String(n),r.push(await z(e.paths,`start_error`)),t<2){await y(150);continue}break}let s=await hr(W,e,o);if(s.kind===`ready`)return{info:s.info,startedByClient:!0};if(s.kind===`early_exit`){if(a=s.exit,i=yr(s.exit),r.push(await z(e.paths,`start_error`)),t<2){await y(150);continue}break}if(await tn(e.paths)){n+=1;continue}let c=B(e.paths),l=t<2,u=await z(e.paths,`startup_timeout`,{stopLiveProcesses:!1});if(r.push(u),u.retainedInfoProcess||u.retainedLockProcess){let t=await hr(W,e,o);if(t.kind===`ready`)return{info:t.info,startedByClient:!0};t.kind===`early_exit`&&(a=t.exit,i=yr(t.exit));break}if(!l)break;!c.hasInfo&&!c.hasLock&&await y(150)}let o=B(e.paths),s=br(e.paths.logPath);throw new t(`COMMAND_FAILED`,`Failed to start daemon`,{kind:`daemon_startup_failed`,stateDir:e.paths.baseDir,infoPath:e.paths.infoPath,lockPath:e.paths.lockPath,logPath:e.paths.logPath,startupTimeoutMs:W,startupAttempts:2,lockRecoveryCount:n,cleanupResults:r,startError:i,daemonProcess:a,...s?{daemonLogTail:s}:{},metadataState:o,hint:rn(o,e.paths)})}async function pr(e,t,n){if(!mr(e.command)||!t.startedByClient&&!n.ownedStateDir||nn(t.info))return;let r={pid:t.info.pid,removedInfo:!1,removedLock:!1,removedStateDir:!1,error:void 0};try{await V(t.info)}catch(e){r.error=e instanceof Error?e.message:String(e)}finally{let e=S.existsSync(n.paths.infoPath);L(n.paths.infoPath),r.removedInfo=e&&!S.existsSync(n.paths.infoPath);let t=S.existsSync(n.paths.lockPath);R(n.paths.lockPath),r.removedLock=t&&!S.existsSync(n.paths.lockPath),n.ownedStateDir&&(S.rmSync(n.paths.baseDir,{recursive:!0,force:!0}),r.removedStateDir=!S.existsSync(n.paths.baseDir))}c({level:r.error?`warn`:`info`,phase:`daemon_replay_cleanup`,data:r})}function mr(e){return e===m.replay||e===m.test}async function hr(e,t,n){let r=Date.now(),i;for(n.exited.then(e=>{i=e});Date.now()-r<e;){if(i)return{kind:`early_exit`,exit:i};let e=N(t.paths.infoPath);if(e&&await In(e,t.transportPreference))return{kind:`ready`,info:e};if(i)return{kind:`early_exit`,exit:i};await y(100)}return{kind:`timeout`}}function gr(e){let t=_r(),n=t.useSrc?[`--experimental-strip-types`,t.srcPath]:[t.distPath],r={...process.env,AGENT_DEVICE_STATE_DIR:e.paths.baseDir,AGENT_DEVICE_DAEMON_SERVER_MODE:e.serverMode};S.mkdirSync(e.paths.baseDir,{recursive:!0});let i=S.openSync(e.paths.logPath,`a`),a=S.openSync(e.paths.logPath,`a`);try{return u(process.execPath,n,{env:r,stdio:[`ignore`,i,a]})}finally{S.closeSync(i),S.closeSync(a)}}function _r(){let e=he(),n=[C.join(e,`dist`,`src`,`internal`,`daemon.js`),C.join(e,`dist`,`src`,`daemon.js`)],r=n[0];if(r===void 0)throw new t(`COMMAND_FAILED`,`Daemon dist path list is empty`);let i=n.find(e=>S.existsSync(e))??r,a=C.join(e,`src`,`daemon.ts`),o=n.some(e=>S.existsSync(e)),s=S.existsSync(a);if(!o&&!s)throw new t(`COMMAND_FAILED`,`Daemon entry not found`,{distPaths:n,srcPath:a});return{root:e,distPath:i,distPaths:n,srcPath:a,useSrc:(process.execArgv.includes(`--experimental-strip-types`)||!o)&&s}}function vr(){let e=_r();return ae(e.useSrc?e.srcPath:e.distPath,e.root)}function yr(e){return e.error?`daemon process ${e.pid} failed to start: ${e.error}`:e.signal?`daemon process ${e.pid} exited before readiness with signal ${e.signal}`:`daemon process ${e.pid} exited before readiness with code ${e.exitCode??0}`}function br(e){try{if(!S.existsSync(e))return;let t=S.statSync(e);if(t.size<=0)return;let n=Math.min(t.size,64e3),r=S.openSync(e,`r`);try{let e=Buffer.alloc(n);S.readSync(r,e,0,n,t.size-n);let i=e.toString(`utf8`).trim();return i.length>0?i:void 0}finally{S.closeSync(r)}}catch{return}}function xr(e){if(!e)return;let n;try{n=new URL(e)}catch(n){throw new t(`INVALID_ARGS`,`Invalid daemon base URL`,{daemonBaseUrl:e},n instanceof Error?n:void 0)}if(n.protocol!==`http:`&&n.protocol!==`https:`)throw new t(`INVALID_ARGS`,`Daemon base URL must use http or https`,{daemonBaseUrl:e});return n.toString().replace(/\/+$/,``)}function Sr(e,n){if(!e)return;let r=new URL(e).hostname;if(!Cr(r)&&!(typeof n==`string`&&n.trim().length>0))throw new t(`INVALID_ARGS`,`Remote daemon base URL for non-loopback hosts requires daemon authentication`,{daemonBaseUrl:e,hint:`Provide --daemon-auth-token or AGENT_DEVICE_DAEMON_AUTH_TOKEN when using a non-loopback remote daemon URL.`})}function Cr(e){let t=e.trim().toLowerCase().replace(/^\[(.*)\]$/,`$1`);return t===`localhost`?!0:E.isIPv4(t)?G.check(t,`ipv4`):E.isIPv6(t)?G.check(t,`ipv6`):!1}async function wr(e,t={}){let n=e.meta?.requestId??i(),r=!!(e.meta?.debug||e.flags?.verbose),a=Qn(e),s=Sn(e),l=await o(`daemon_startup`,async()=>await ir(a),{requestId:n,session:e.session}),u=l.info,d=await Mt(e,u);Tr(e.command);let f={...e,positionals:d.positionals,flags:d.flags,token:u.token,meta:{...e.meta??{},requestId:n,debug:r,includeCost:e.meta?.includeCost,cwd:e.meta?.cwd,sessionExplicit:e.meta?.sessionExplicit,tenantId:e.meta?.tenantId??e.flags?.tenant,runId:e.meta?.runId??e.flags?.runId,leaseId:e.meta?.leaseId??e.flags?.leaseId,sessionIsolation:e.meta?.sessionIsolation??e.flags?.sessionIsolation,lockPolicy:e.meta?.lockPolicy,lockPlatform:e.meta?.lockPlatform,...d.uploadedArtifactId?{uploadedArtifactId:d.uploadedArtifactId}:{},...d.clientArtifactPaths?{clientArtifactPaths:d.clientArtifactPaths}:{},...d.installSource?{installSource:d.installSource}:{}}};c({level:`info`,phase:`daemon_request_prepare`,data:{requestId:n,command:e.command,session:e.session}});try{return await o(`daemon_request`,async()=>await Un(u,f,a.transportPreference,a.paths,s,t),{requestId:n,command:e.command})}finally{await pr(e,l,a)}}function Tr(e){!Er(e)||process.stderr.isTTY!==!0||process.env.CI||process.stderr.write(e===m.reinstall?`Reinstalling...
2
+ `:`Installing...
3
+ `)}function Er(e){return e===m.install||e===m.reinstall||e===h.installSource}const Dr=8081;function Or(e){return typeof e==`string`&&e.trim()?Le(e.trim()):``}function K(e){return typeof e==`string`&&e.trim()?e.trim():void 0}function q(e,t,n){return ge(e,{env:t,cwd:n})}function J(e){try{return S.accessSync(e,S.constants.F_OK),!0}catch{return!1}}function kr(e){try{return S.statSync(e).isDirectory()}catch{return!1}}function Ar(e){let n=C.join(e,`package.json`),r=Ve(e);if(!r)throw new t(`INVALID_ARGS`,`package.json not found at ${n}`);return r}function jr(e){return J(C.join(e,`pnpm-lock.yaml`))?{command:`pnpm`,installArgs:[`install`]}:J(C.join(e,`yarn.lock`))?{command:`yarn`,installArgs:[`install`]}:{command:`npm`,installArgs:[`install`]}}function Mr(e,t){if(t!==`auto`)return t;let n=Be(e);return n===`expo`||n===`repack`?n:`react-native`}function Nr(e,t){return typeof{...e.dependencies??{},...e.devDependencies??{}}[t]==`string`}function Pr(e,t){return[`js`,`mjs`,`cjs`,`ts`,`mts`,`cts`].some(n=>J(C.join(e,`${t}.config.${n}`)))}function Fr(e,t){return Pr(e,`rspack`)?`rspack`:Pr(e,`webpack`)?`webpack`:Nr(t,`@rspack/core`)?`rspack`:Nr(t,`webpack`)?`webpack`:`rspack`}function Y(e,t,n){if(e==null||e===``)return t;let r=Number.parseInt(String(e),10);return Number.isInteger(r)?Math.max(r,n):t}function Ir(e,n){if(e==null||e===``)return n;let r=Number.parseInt(String(e),10);if(!Number.isInteger(r)||r<1||r>65535)throw new t(`INVALID_ARGS`,`Invalid Metro port: ${String(e)}. Use 1-65535.`);return r}function Lr(e,t){return{platform:t,bundleUrl:Re(e,t)}}function Rr(e,t){return{platform:t,metroHost:K(e?.metro_host),metroPort:e?.metro_port,bundleUrl:K(e?.metro_bundle_url),launchUrl:K(e?.launch_url)}}function zr(e,t){if(kr(C.join(e,`node_modules`)))return{installed:!1};let n=jr(e);return a(n.command,n.installArgs,{cwd:e,env:t}),{installed:!0,packageManager:n.command}}async function Br(e){await y(e)}async function Vr(e,n,r={}){try{let t=await fetch(e,{headers:r,signal:AbortSignal.timeout(n)});return{ok:t.ok,status:t.status,body:await t.text()}}catch(r){throw r instanceof Error&&r.name===`TimeoutError`?new t(`COMMAND_FAILED`,`Timed out fetching ${e} after ${n}ms`):r}}async function Hr(e,t){try{let n=await Vr(e,t);return n.ok&&n.body.includes(`packager-status:running`)}catch{return!1}}function Ur(e,t){let n=new URL(`${e.scheme}://localhost`);return n.hostname=e.host,n.port=String(e.port),n.pathname=t,n.toString()}function Wr(e){let t=K(e);if(!t)return`/reload`;let n=new URL(t).pathname.replace(/\/+$/,``);return n.endsWith(`/index.bundle`)?`${n.slice(0,-13)}/reload`:`/reload`}function Gr(e,t,n){return K(e.metroHost)??(t?void 0:K(e.runtime?.metroHost))??(n?void 0:`localhost`)}function Kr(e,t,n){if(e.metroPort!==void 0)return Ir(e.metroPort,Dr);if(!t)return e.runtime?.metroPort??(n?void 0:Dr)}function qr(e){let n=K(e.bundleUrl),r=n??e.runtime?.bundleUrl,i=!!n,a=!!K(r),o=He({metroHost:Gr(e,i,a),metroPort:Kr(e,i,a),bundleUrl:r});if(!o)throw new t(`INVALID_ARGS`,`Unable to resolve Metro host and port for reload.`);return Ur(o,Wr(r))}function Jr(e,t,n,r){return e===`expo`?{command:`npx`,installArgs:[`expo`,`start`,`--host`,`lan`,`--port`,String(n)]}:e===`repack`?{command:`npx`,installArgs:[`react-native`,t===`webpack`?`webpack-start`:`rspack-start`,`--host`,r,`--port`,String(n)]}:{command:`npx`,installArgs:[`react-native`,`start`,`--host`,r,`--port`,String(n)]}}function Yr(e,n,r,i,a,o,c){let l=Jr(n,r,i,a);S.mkdirSync(C.dirname(o),{recursive:!0});let u=S.openSync(o,`a`),d=0;try{d=s(l.command,l.installArgs,{cwd:e,env:c,stdio:[`ignore`,u,u]})}finally{S.closeSync(u)}if(!Number.isInteger(d)||d<=0)throw new t(`COMMAND_FAILED`,`Failed to start React Native dev server. Expected a detached child PID.`);return{pid:d}}async function Xr(e){if(!(!Number.isInteger(e)||e<=0)){try{process.kill(e,`SIGTERM`)}catch(e){let t=e.code;if(t===`ESRCH`||t===`EPERM`)return;throw e}if(!await _e(e,1e3)){try{process.kill(e,`SIGKILL`)}catch(e){let t=e.code;if(t===`ESRCH`||t===`EPERM`)return;throw e}await _e(e,1e3)}}}function Zr(e,t){return{Authorization:`Bearer ${t}`,"Content-Type":`application/json`,...e.includes(`ngrok`)?{"ngrok-skip-browser-warning":`1`}:{}}}function X(e,n){let r=new t(`COMMAND_FAILED`,e);return r.retryable=n,r}function Qr(e,t){return!!(e>=500||e===408||e===425||e===429||JSON.stringify(t).includes(`Metro companion is not connected`))}function $r(e){return!!(e&&typeof e==`object`&&`retryable`in e&&e.retryable===!0)}async function ei(e){let t;try{t=await fetch(`${e.baseUrl}/api/metro/bridge`,{method:`POST`,headers:Zr(e.baseUrl,e.bearerToken),body:JSON.stringify({...e.scope,...e.runtime?{ios_runtime:e.runtime}:{},timeout_ms:e.timeoutMs}),signal:AbortSignal.timeout(e.timeoutMs)})}catch(t){throw t instanceof Error&&t.name===`TimeoutError`?X(`/api/metro/bridge timed out after ${e.timeoutMs}ms calling ${e.baseUrl}/api/metro/bridge`,!0):X(t instanceof Error?t.message:String(t),!0)}let n=ti(await t.text(),t.status,e.baseUrl);if(!t.ok)throw X(`/api/metro/bridge failed (${t.status}): ${JSON.stringify(n)}`,Qr(t.status,n));return ri(n)}function ti(e,t,n){if(!e)return{};try{let t=JSON.parse(e);if(!t||typeof t!=`object`||Array.isArray(t))throw Error(`Expected a JSON object`);return t}catch(r){let i=e.slice(0,200);throw X(`/api/metro/bridge returned invalid JSON (${t}) from ${n}: ${r instanceof Error?r.message:String(r)}. body=${JSON.stringify(i)}`,Qr(t,e))}}function ni(e){return{enabled:e.enabled,baseUrl:e.base_url,statusUrl:e.status_url??``,bundleUrl:e.bundle_url??``,iosRuntime:Rr(e.ios_runtime,`ios`),androidRuntime:Rr(e.android_runtime,`android`),upstream:{bundleUrl:e.upstream.bundle_url??``,host:e.upstream.host??``,port:e.upstream.port??0,statusUrl:e.upstream.status_url??``},probe:{reachable:e.probe.reachable,statusCode:e.probe.status_code,latencyMs:e.probe.latency_ms,detail:e.probe.detail}}}function ri(e){let t=e.data??e;if(!t||typeof t!=`object`||Array.isArray(t))throw X(`/api/metro/bridge returned malformed descriptor: Expected a JSON object.`,!1);try{return ni(t)}catch(e){throw X(`/api/metro/bridge returned malformed descriptor: ${e instanceof Error?e.message:String(e)}`,!1)}}function Z(e,t,n,r,i){let a=[`Metro bridge is required for this run but could not be configured via ${e}/api/metro/bridge.`];return t&&a.push(`bridgeError=${t}`),n?.probe.reachable===!1&&a.push(`bridgeProbe=${n.probe.detail||`unreachable (status ${n.probe.statusCode||0})`}`),r&&r!==t&&a.push(`initialBridgeError=${r}`),i&&a.push(`metroCompanionLog=${i}`),a.join(` `)}function ii(e,n){if(!n?.iosRuntime.bundleUrl)throw new t(`COMMAND_FAILED`,Z(e,`bridge descriptor is missing ios_runtime.metro_bundle_url`,n))}function ai(e,n,r){let i=n||K(r.AGENT_DEVICE_METRO_BEARER_TOKEN)||``,a=i||e&&K(r.AGENT_DEVICE_DAEMON_AUTH_TOKEN)||``;if(e&&!a)throw new t(`INVALID_ARGS`,`metro prepare requires proxy auth when --proxy-base-url is provided. Pass --bearer-token or set AGENT_DEVICE_METRO_BEARER_TOKEN or AGENT_DEVICE_DAEMON_AUTH_TOKEN.`);if(!e&&i)throw new t(`INVALID_ARGS`,`metro prepare requires --proxy-base-url when proxy auth is provided.`);return{proxyEnabled:!!(e&&a),proxyBaseUrl:e,proxyBearerToken:a}}function oi(e){if(!e?.tenantId||!e.runId||!e.leaseId)throw new t(`INVALID_ARGS`,`metro prepare with proxy requires tenantId, runId, and leaseId bridge scope.`);return e}function si(e,n){if(!(e||n))throw new t(`INVALID_ARGS`,`metro prepare requires --public-base-url <url> or --proxy-base-url <url>.`)}function ci(e,t,n){return e.runtimeFilePath?q(e.runtimeFilePath,t,n):null}function li(e,t,n,r){return q(e.logPath??C.join(r,`.agent-device`,`metro.log`),t,n)}function ui(e){let t=e.env??process.env,n=process.cwd(),r=q(e.projectRoot??n,t,n),i=e.kind??`auto`,a=null,o;i===`auto`?(a=Ar(r),o=Mr(a,i)):o=i;let s=null;o===`repack`&&(a??=Ar(r),s=Fr(r,a));let c=Or(e.publicBaseUrl),l=Or(e.proxyBaseUrl);si(c,l);let{proxyEnabled:u,proxyBaseUrl:d,proxyBearerToken:f}=ai(l,K(e.proxyBearerToken)??``,t);return{env:t,projectRoot:r,kind:o,repackBundler:s,metroPort:Ir(e.metroPort??8081,8081),listenHost:K(e.listenHost)??`0.0.0.0`,statusHost:K(e.statusHost)??`127.0.0.1`,publicBaseUrl:c,proxyBaseUrl:d,proxyBearerToken:f,bridgeScope:u?oi(e.bridgeScope):null,startupTimeoutMs:Y(e.startupTimeoutMs,18e4,3e4),probeTimeoutMs:Y(e.probeTimeoutMs,1e4,1e3),reuseExisting:e.reuseExisting??!0,installProjectDeps:e.installDependenciesIfNeeded??!0,runtimeFilePath:ci(e,t,n),logPath:li(e,t,n,r)}}async function di(e,t,n){let r=Date.now()+t;for(;Date.now()<r;){let t=r-Date.now();if(await Hr(e,Math.min(n,Math.max(t,1))))return!0;let i=Math.min(500,Math.max(r-Date.now(),0));i>0&&await Br(i)}return!1}async function fi(e){let n=Date.now()+e.startupTimeoutMs,r=null,i=null;for(;Date.now()<n;){try{let t=await ei({baseUrl:e.baseUrl,bearerToken:e.bearerToken,scope:e.scope,runtime:e.runtime,timeoutMs:e.probeTimeoutMs});if(t.probe.reachable!==!1)return t;r=t,i=null}catch(n){if(i=n instanceof Error?n.message:String(n),!$r(n))throw new t(`COMMAND_FAILED`,Z(e.baseUrl,i,r,e.initialBridgeError,e.companionLogPath),void 0,n)}let a=Math.min(1e3,Math.max(n-Date.now(),0));a>0&&await Br(a)}throw new t(`COMMAND_FAILED`,Z(e.baseUrl,i,r,e.initialBridgeError,e.companionLogPath))}async function pi(e){let n=`http://${e.statusHost}:${e.metroPort}/status`;if(e.reuseExisting&&await Hr(n,e.probeTimeoutMs))return{started:!1,reused:!0,pid:0,statusUrl:n};let r=Yr(e.projectRoot,e.kind,e.repackBundler,e.metroPort,e.listenHost,e.logPath,e.env);if(await di(n,e.startupTimeoutMs,e.probeTimeoutMs))return{started:!0,reused:!1,pid:r.pid,statusUrl:n};throw await Xr(r.pid).catch(()=>{}),new t(`COMMAND_FAILED`,`React Native dev server did not become ready at ${n} within ${e.startupTimeoutMs}ms. Check ${e.logPath}.`,{logPath:e.logPath})}async function mi(e,t){let n=t.bridgeScope;if(!n)return null;let r=null,i=null;try{r=await ei({baseUrl:t.proxyBaseUrl,bearerToken:t.proxyBearerToken,scope:n,timeoutMs:t.probeTimeoutMs})}catch(e){if(!$r(e))throw e;i=e instanceof Error?e.message:String(e)}return(!r||r.probe.reachable===!1)&&(r=await hi(e,t,n,r,i)),ii(t.proxyBaseUrl,r),r}async function hi(e,n,r,i,a){let o;try{o=(await ze({projectRoot:n.projectRoot,serverBaseUrl:n.proxyBaseUrl,bearerToken:n.proxyBearerToken,bridgeScope:r,localBaseUrl:`http://${n.statusHost}:${n.metroPort}`,launchUrl:K(e.launchUrl),profileKey:K(e.companionProfileKey),consumerKey:K(e.companionConsumerKey),env:n.env})).logPath}catch(e){throw new t(`COMMAND_FAILED`,Z(n.proxyBaseUrl,e instanceof Error?e.message:String(e),i,a),void 0,e)}try{return await fi({baseUrl:n.proxyBaseUrl,bearerToken:n.proxyBearerToken,scope:r,probeTimeoutMs:n.probeTimeoutMs,startupTimeoutMs:n.startupTimeoutMs,initialBridgeError:a,companionLogPath:o})}catch(e){throw e instanceof Error?e:Error(String(e))}}function gi(e){return{baseIosRuntime:e?Lr(e,`ios`):{platform:`ios`},baseAndroidRuntime:e?Lr(e,`android`):{platform:`android`}}}function _i(e,t){e&&(S.mkdirSync(C.dirname(e),{recursive:!0}),S.writeFileSync(e,JSON.stringify(t,null,2)))}async function vi(e={}){let t=ui(e),n=t.installProjectDeps?zr(t.projectRoot,t.env):{installed:!1},r=await pi(t),{baseIosRuntime:i,baseAndroidRuntime:a}=gi(t.publicBaseUrl),o=await mi(e,t),s=o?.iosRuntime??i,c=o?.androidRuntime??a,l={projectRoot:t.projectRoot,kind:t.kind,dependenciesInstalled:n.installed,packageManager:n.packageManager??null,started:r.started,reused:r.reused,pid:r.pid,logPath:t.logPath,statusUrl:r.statusUrl,runtimeFilePath:t.runtimeFilePath,iosRuntime:s,androidRuntime:c,bridge:o};return _i(t.runtimeFilePath,l),l}async function yi(e={}){let n=Y(e.timeoutMs,1e4,1e3),r=qr(e),i=await Vr(r,n);if(!i.ok)throw new t(`COMMAND_FAILED`,`React Native dev server reload failed (${i.status}).`,{reloadUrl:r,status:i.status,body:i.body,hint:`Verify Metro or Re.Pack is running and the target React Native app is connected to this dev server instance.`});return{reloaded:!0,reloadUrl:r,status:i.status,body:i.body}}const bi={...ke(),batch:De(xi)};function xi(e,n,r){let i=bi[e];if(!i)throw Error(`Missing daemon writer for batch command: ${e}`);let a=Ue(e);if(!a)throw Error(`Missing command metadata for batch command: ${e}`);try{return Ci(i,a,a.readInput(n))}catch(n){throw new t(`INVALID_ARGS`,`Batch step ${r} ${e} input is invalid: ${n instanceof Error?n.message:String(n)}`,void 0,n)}}function Si(e,t){let n=bi[e];if(!n)throw Error(`Missing daemon writer for command: ${e}`);return Ci(n,Ue(e),t)}function Ci(e,t,n){let r=e(n);return{...r,...t?{metadataFlags:je(t,r.options)}:{}}}function wi(e){throw new t(n(e.code),e.message,{...e.details??{},hint:e.hint,diagnosticId:e.diagnosticId,logPath:e.logPath,retriable:e.retriable,supportedOn:e.supportedOn})}var Ti=e({createAgentDeviceClient:()=>Ei});function Ei(e={},t={}){let n=t.transport??wr,i=t=>r(t.responseLevel??e.responseLevel),a=async(t,r=[],i={},a)=>{let o=$(e,i),s=await n({session:ve(o.session),command:t,positionals:r,flags:Oe(o,a),runtime:o.runtime,meta:Fe(o)});return s.ok||wi(s.error),s.data??{}},o=async(e={})=>{let t=await a(h.sessionList,[],e);return(Array.isArray(t.sessions)?t.sessions:[]).map(xe)},s=async(e,t={})=>{let n=Si(e,t);return await a(n.command,n.positionals,n.options,n.metadataFlags)},c=(t={})=>ve($(e,t).session);return{command:{wait:async e=>await s(`wait`,e),alert:async(e={})=>await s(`alert`,e),...ki(s),reactNative:async e=>await s(`react-native`,e),doctor:async(e={})=>await s(`doctor`,e),prepare:async e=>await s(`prepare`,e),viewport:async e=>await s(`viewport`,e)},devices:{list:async(e={})=>{let t=await s(`devices`,e);return(Array.isArray(t.devices)?t.devices:[]).map(Pe)},capabilities:async(e={})=>{let t=await s(`capabilities`,e),n=Array.isArray(t.availableCommands)?t.availableCommands.filter(e=>typeof e==`string`):[];return{device:Pe(t.device),availableCommands:n}},boot:async(e={})=>await s(`boot`,e),shutdown:async(e={})=>await s(`shutdown`,e)},sessions:{list:async(e={})=>await o(e),stateDir:async(t={})=>g($(e,t).stateDir??process.env.AGENT_DEVICE_STATE_DIR).baseDir,close:async(e={})=>{let t=c(e),n=await s(`close`,e);return{session:t,shutdown:Se(n.shutdown),provider:Q(n.provider),identifiers:{session:t}}},artifacts:async(e={})=>await s(`artifacts`,e)},apps:{install:async e=>Ee(await s(`install`,e),c(e)),reinstall:async e=>Ee(await s(`reinstall`,e),c(e)),installFromSource:async e=>we(await s(`install-from-source`,e),c(e)),list:async(e={})=>{let t=await s(`apps`,e);return Array.isArray(t.apps)?t.apps.filter(e=>typeof e==`string`):[]},open:async e=>{let t=c(e),n=await s(`open`,e),r=Ne(n),i=b(n,`appBundleId`),a=i;return{session:t,sessionStateDir:b(n,`sessionStateDir`),eventLogPath:b(n,`eventLogPath`),appName:b(n,`appName`),appBundleId:i,appId:a,startup:be(n.startup),runtime:Te(n.runtime),device:r,identifiers:{session:t,deviceId:r?.id,deviceName:r?.name,udid:r?.ios?.udid,serial:r?.android?.serial,appId:a,appBundleId:i}}},close:async(e={})=>{let t=c(e),n=await s(`close`,e);return{session:t,closedApp:e.app,shutdown:Se(n.shutdown),identifiers:{session:t}}},push:async e=>await s(`push`,e),triggerEvent:async e=>await s(`trigger-app-event`,e)},materializations:{release:async e=>ye(await a(h.releaseMaterializedPaths,[],{...e,materializationId:e.materializationId}))},leases:{allocate:async e=>Ai(await a(h.leaseAllocate,[],{...e,leaseId:void 0})),heartbeat:async e=>Ai(await a(h.leaseHeartbeat,[],e)),release:async e=>{let t=await a(h.leaseRelease,[],e);return{released:t.released===!0,provider:Q(t.provider)}}},metro:{prepare:async t=>await vi({projectRoot:t.projectRoot??e.cwd,kind:t.kind,publicBaseUrl:t.publicBaseUrl,proxyBaseUrl:t.proxyBaseUrl,proxyBearerToken:t.bearerToken,bridgeScope:t.bridgeScope,launchUrl:t.launchUrl,companionProfileKey:t.companionProfileKey,companionConsumerKey:t.companionConsumerKey,metroPort:t.port,listenHost:t.listenHost,statusHost:t.statusHost,startupTimeoutMs:t.startupTimeoutMs,probeTimeoutMs:t.probeTimeoutMs,reuseExisting:t.reuseExisting,installDependenciesIfNeeded:t.installDependenciesIfNeeded,runtimeFilePath:t.runtimeFilePath,logPath:t.logPath}),reload:async(t={})=>await yi({metroHost:t.metroHost,metroPort:t.metroPort,bundleUrl:t.bundleUrl,runtime:e.runtime,timeoutMs:t.timeoutMs})},capture:{snapshot:async(e={})=>{let t=c(e),n=await s(`snapshot`,e);return i(e)?n:Di(n,t)},screenshot:async(e={})=>{let t=c(e),n=await s(`screenshot`,e);if(i(e))return n;let r=de(n);return{path:x(n,`path`),width:r?.width,height:r?.height,logicalWidth:r?.logicalWidth,logicalHeight:r?.logicalHeight,pixelDensity:r?.pixelDensity,overlayRefs:r?.overlayRefs,identifiers:{session:t}}},diff:async e=>await s(`diff`,e)},interactions:{click:async e=>await s(`click`,e),press:async e=>await s(`press`,e),longPress:async e=>await s(`longpress`,e),swipe:async e=>await s(`swipe`,e),pan:async e=>await s(`gesture-pan`,e),fling:async e=>await s(`gesture-fling`,e),swipeGesture:async e=>await s(`gesture-swipe`,e),focus:async e=>await s(`focus`,e),type:async e=>await s(`type`,e),fill:async e=>await s(`fill`,e),scroll:async e=>await s(`scroll`,e),pinch:async e=>await s(`gesture-pinch`,e),rotateGesture:async e=>await s(`gesture-rotate`,e),transformGesture:async e=>await s(`gesture-transform`,e),get:async e=>await s(`get`,e),is:async e=>await s(`is`,e),find:async e=>await s(`find`,e)},replay:{run:async e=>await s(`replay`,e),test:async e=>await s(`test`,e)},batch:{run:async e=>await s(`batch`,e)},observability:{perf:async(e={})=>await s(`perf`,e),logs:async(e={})=>await s(`logs`,e),events:async(e={})=>await s(`events`,e),network:async(e={})=>await s(`network`,e),audio:async(e={})=>await s(`audio`,e)},debug:{symbols:async t=>{let{symbolicateCrashArtifact:n}=await import(`./debug-symbols.js`);return n({cwd:t.cwd??e.cwd,...t})}},recording:{record:async e=>await s(`record`,e),trace:async e=>await s(`trace`,e)},settings:{update:async e=>await s(`settings`,e)}}}function Di(e,t){let n=b(e,`appBundleId`);return{nodes:Ae(e.nodes),truncated:e.truncated===!0,appName:b(e,`appName`),appBundleId:n,...Oi(e),identifiers:{session:t,appId:n,appBundleId:n}}}function Oi(e){let t=Q(e.visibility),n=Q(e.unchanged),r=ue(e.snapshotDiagnostics);return{...t?{visibility:t}:{},...ee(e),...n?{unchanged:n}:{},...r?{snapshotDiagnostics:r}:{}}}function ki(e){let t={};for(let[n,r]of Object.entries(Me.clientCommandMethods??{}))t[n]=async(t={})=>await e(r,t);return t}function Q(e){return Ie(e)?e:void 0}function $(e,t){return{...e,...t}}function Ai(e){let t=e.lease;if(!Ie(t))throw Error(`Invalid lease response from daemon`);return{leaseId:x(t,`leaseId`),tenantId:x(t,`tenantId`),runId:x(t,`runId`),backend:x(t,`backend`),leaseProvider:b(t,`leaseProvider`),clientId:b(t,`clientId`),deviceKey:b(t,`deviceKey`),createdAt:typeof t.createdAt==`number`?t.createdAt:void 0,heartbeatAt:typeof t.heartbeatAt==`number`?t.heartbeatAt:void 0,expiresAt:typeof t.expiresAt==`number`?t.expiresAt:void 0}}export{Qn as a,Ze as c,ir as i,D as l,Ei as n,Xe as o,wr as r,O as s,Ti as t};
@@ -0,0 +1 @@
1
+ import{m as e}from"./sdk-batch.js";import{o as t}from"./registry.js";const n=t(),r=new Map(n.map(e=>[e.name,e]));function i(){return[...n]}function a(){return e().map(e=>{let t=s(e);if(!t)throw Error(`Missing command metadata for MCP-exposed command: ${e}`);return t})}function o(e){return r.has(e)}function s(e){return r.get(e)}export{a as i,o as n,i as r,s as t};
@@ -0,0 +1,22 @@
1
+ import{g as e,m as t,r as n}from"./registry.js";import{r}from"./command-metadata.js";const i={cdp:{usageOverride:`cdp [...args]`,listUsageOverride:`cdp`,helpDescription:`Run CDP commands for React Native diagnostics, JS heap usage, heap snapshots, and leak analysis`,summary:`Inspect React Native CDP targets, JS heap growth, heap snapshots, retainers, and leak signals`,positionalArgs:[`args?`],allowsExtraPositionals:!0,supportedFlags:t},auth:{usageOverride:`auth status|login|logout`,listUsageOverride:`auth`,helpDescription:`Manage cloud login state used by remote daemon and cloud device workflows.`,summary:`Manage cloud login state used by remote daemon and cloud device workflows`,positionalArgs:[`status|login|logout`],supportedFlags:[`remoteConfig`,`stateDir`]},connect:{usageOverride:`connect [cloud|proxy|browserstack|aws-device-farm] [--remote-config <path>] [--daemon-base-url <url>] [--tenant <id>] [--run-id <id>] [--lease-id <id>] [--lease-backend <backend>] [--force] [--no-login]`,helpDescription:`Connect to a remote daemon, authenticate when needed, and save remote session state. AGENT_DEVICE_CLOUD_BASE_URL is the bridge/control-plane API origin; use AGENT_DEVICE_DAEMON_AUTH_TOKEN=adc_live_... for CI/service-token automation.`,listUsageOverride:`connect`,summary:`Attach CLI commands to a saved remote daemon/cloud lease; inspect for remote runs, tenants, or service-token CI`,allowedFlags:[`remoteConfig`,`daemonBaseUrl`,`tenant`,`runId`,`leaseId`,`leaseBackend`,`providerApp`,`providerOsVersion`,`providerProject`,`providerBuild`,`providerSessionName`,`awsProjectArn`,`awsDeviceArn`,`awsAppArn`,`awsRegion`,`awsInteractionMode`,`force`,`noLogin`],supportedFlags:[`stateDir`,`daemonAuthToken`,`session`,`platform`,`device`,...e,`launchUrl`]},connection:{usageOverride:`connection status`,listUsageOverride:`connection`,helpDescription:`Inspect active remote connection state`,summary:`Inspect the active saved remote connection before assuming commands are local`,positionalArgs:[`status`],supportedFlags:[`remoteConfig`,`stateDir`,`session`]},disconnect:{helpDescription:`Disconnect remote daemon state, stop owned Metro companion, and release lease`,listUsageOverride:`disconnect`,summary:`Clear remote connection state, stop owned Metro companions, and release remote leases`,allowedFlags:[`shutdown`],supportedFlags:[`remoteConfig`,`stateDir`,`session`]},mcp:{helpDescription:`Start the official stdio MCP server. It exposes structured command tools backed by the agent-device client.`,summary:`Start MCP server`},proxy:{usageOverride:`proxy [--host <host>] [--port <port>] [--daemon-auth-token <token>] [--state-dir <path>]`,listUsageOverride:`proxy`,helpDescription:`Expose the local daemon HTTP contract through a tunnel-friendly reverse proxy.
2
+
3
+ Run this on the host that has access to simulators/devices, expose the printed local proxy URL through a tunnel, then point another machine at the tunnel URL with connect proxy.
4
+
5
+ The proxy starts or reuses a local HTTP daemon, accepts /health, /rpc, /upload and resumable /upload/* routes, and /artifacts plus /artifacts/*, and also accepts the same routes under /agent-device/*. Health is unauthenticated for reachability probes. Other routes require the generated bearer token printed at startup, or the explicit --daemon-auth-token value when provided. The proxy rewrites authorized client requests to the upstream daemon token instead of exposing the local daemon token.
6
+
7
+ Use the /agent-device base path when connecting through cloudflared, ngrok, or another shared origin. Treat the bearer token as a secret; anyone with it can control the proxied daemon. This direct proxy flow does not use agent-device auth.
8
+
9
+ Examples:
10
+ agent-device proxy --port 4310
11
+ cloudflared tunnel --url http://127.0.0.1:4310
12
+ agent-device connect proxy --daemon-base-url https://example.trycloudflare.com/agent-device --daemon-auth-token <token>`,summary:`Expose a local daemon through cloudflared, ngrok, or another HTTP tunnel`,allowedFlags:[`proxyHost`,`proxyPort`,`daemonAuthToken`,`stateDir`]},"react-devtools":{usageOverride:`react-devtools [...args]`,listUsageOverride:`react-devtools`,helpDescription:`Run pinned agent-react-devtools commands for React Native performance profiling, component trees, props/state/hooks, and render analysis`,summary:`Inspect React Native components, props, hooks, errors, slow renders, and rerender profiles`,positionalArgs:[`args?`],allowsExtraPositionals:!0,supportedFlags:t},web:{usageOverride:`web setup | web doctor`,listUsageOverride:`web setup|doctor`,helpDescription:`Install and inspect the managed web automation backend used by --platform web.
13
+
14
+ First-run flow:
15
+ agent-device web setup
16
+ agent-device open "https://example.com" --platform web
17
+ agent-device snapshot -i --platform web
18
+ agent-device close --platform web
19
+
20
+ Runtime web commands do not install the backend implicitly. If the managed backend is missing, run agent-device web setup. The backend is resolved only from the managed install in the effective agent-device state dir.
21
+
22
+ Use web setup to install or reuse the pinned backend. Use web doctor after setup to verify browser backend health.`,summary:`Manage web automation backend`,positionalArgs:[`setup|doctor`],supportedFlags:[`stateDir`]}},a=n();function o(e){return Object.hasOwn(i,e)?i[e]:void 0}function s(e){return Object.hasOwn(a,e)?a[e]:void 0}const c=new Map(r().map(e=>[e.name,{helpDescription:e.description,supportedFlags:t}]));function l(e){if(e)return d(e)}function u(e){let t=d(e);if(!t)throw Error(`Missing command schema for ${e}`);return t}function d(e){let t=o(e);if(t)return t;let n=c.get(e),r=s(e);if(n)return r?{...n,...r}:n}function f(e,t){let n=l(e);if(!n?.defaults)return!1;let r=!1;for(let[e,i]of Object.entries(n.defaults))t[e]===void 0&&(t[e]=i,r=!0);return r}export{u as n,l as r,f as t};
@@ -1 +1 @@
1
- import{listCommandFamilyDefinitions as n}from"./2948.js";let a=new Map(n().map(n=>[n.name,n]));async function e(n,e,r){var t;return await (t=e,a.get(t)).invoke(n,r)}export{e as runCommand};
1
+ import{t as e}from"./rolldown-runtime.js";import{a as t}from"./registry.js";var n=e({runCommand:()=>a});const r=t(),i=new Map(r.map(e=>[e.name,e]));async function a(e,t,n){return await o(t).invoke(e,n)}function o(e){return i.get(e)}export{a as n,n as t};
@@ -1,213 +1,2 @@
1
- export declare function centerOfRect(rect: Rect): Point;
2
-
3
- declare const DAEMON_LOCK_POLICIES: readonly ['reject', 'strip'];
4
-
5
- declare type DaemonArtifact = {
6
- field: string;
7
- artifactId?: string;
8
- fileName?: string;
9
- localPath?: string;
10
- path?: string;
11
- };
12
-
13
- export declare type DaemonError = {
14
- code: string;
15
- message: string;
16
- hint?: string;
17
- diagnosticId?: string;
18
- logPath?: string;
19
- details?: Record<string, unknown>;
20
- /**
21
- * Machine-readable typed-error signals (Phase 2). Additive: present only when
22
- * derivable, so the default error wire shape is unchanged.
23
- *
24
- * `retriable` flags a transient failure an agent should retry (vs. a
25
- * deterministic one where a retry is wasted). `supportedOn` lists the platform
26
- * families that DO support the command (derived from the capability matrix),
27
- * surfaced on platform-mismatch errors so an agent self-corrects without a
28
- * wasted round-trip.
29
- */
30
- retriable?: boolean;
31
- supportedOn?: string;
32
- };
33
-
34
- export declare type DaemonInstallSource = {
35
- kind: 'url';
36
- url: string;
37
- headers?: Record<string, string>;
38
- } | {
39
- kind: 'path';
40
- path: string;
41
- } | ({
42
- kind: 'github-actions-artifact';
43
- owner: string;
44
- repo: string;
45
- } & ({
46
- artifactId: number;
47
- } | {
48
- runId: number;
49
- artifactName: string;
50
- } | {
51
- artifactName: string;
52
- }));
53
-
54
- declare type DaemonLockPolicy = (typeof DAEMON_LOCK_POLICIES)[number];
55
-
56
- export declare type DaemonRequest = {
57
- token?: string;
58
- session?: string;
59
- command: string;
60
- positionals: string[];
61
- flags?: Record<string, unknown>;
62
- runtime?: SessionRuntimeHints;
63
- meta?: DaemonRequestMeta;
64
- };
65
-
66
- declare type DaemonRequestMeta = {
67
- requestId?: string;
68
- debug?: boolean;
69
- includeCost?: boolean;
70
- responseLevel?: ResponseLevel;
71
- cwd?: string;
72
- sessionExplicit?: boolean;
73
- tenantId?: string;
74
- runId?: string;
75
- leaseId?: string;
76
- leaseTtlMs?: number;
77
- leaseBackend?: LeaseBackend;
78
- leaseProvider?: string;
79
- deviceKey?: string;
80
- clientId?: string;
81
- sessionIsolation?: SessionIsolationMode;
82
- uploadedArtifactId?: string;
83
- clientArtifactPaths?: Record<string, string>;
84
- installSource?: DaemonInstallSource;
85
- retainMaterializedPaths?: boolean;
86
- materializedPathRetentionMs?: number;
87
- materializationId?: string;
88
- lockPolicy?: DaemonLockPolicy;
89
- lockPlatform?: PlatformSelector;
90
- requestProgress?: 'replay-test' | 'command';
91
- };
92
-
93
- export declare type DaemonResponse = {
94
- ok: true;
95
- data?: DaemonResponseData;
96
- } | {
97
- ok: false;
98
- error: DaemonError;
99
- };
100
-
101
- export declare type DaemonResponseData = Record<string, unknown> & {
102
- artifacts?: DaemonArtifact[];
103
- cost?: ResponseCost;
104
- };
105
-
106
- export declare function defaultHintForCode(code: string): string | undefined;
107
-
108
- export declare type JsonRpcId = string | number | null;
109
-
110
- export declare type JsonRpcRequestEnvelope<TParams = unknown> = {
111
- jsonrpc?: string;
112
- id?: JsonRpcId;
113
- method?: string;
114
- params?: TParams;
115
- };
116
-
117
- declare const LEASE_BACKENDS: readonly ['ios-simulator', 'ios-instance', 'android-instance'];
118
-
119
- export declare type LeaseAllocatePayload = {
120
- token?: string;
121
- session?: string;
122
- tenantId?: string;
123
- tenant?: string;
124
- runId?: string;
125
- ttlMs?: number;
126
- backend?: LeaseBackend;
127
- leaseProvider?: string;
128
- deviceKey?: string;
129
- clientId?: string;
130
- };
131
-
132
- export declare type LeaseBackend = (typeof LEASE_BACKENDS)[number];
133
-
134
- export declare type LeaseHeartbeatPayload = {
135
- token?: string;
136
- session?: string;
137
- tenantId?: string;
138
- tenant?: string;
139
- runId?: string;
140
- leaseId?: string;
141
- ttlMs?: number;
142
- backend?: LeaseBackend;
143
- leaseProvider?: string;
144
- deviceKey?: string;
145
- clientId?: string;
146
- };
147
-
148
- export declare type LeaseReleasePayload = {
149
- token?: string;
150
- session?: string;
151
- tenantId?: string;
152
- tenant?: string;
153
- runId?: string;
154
- leaseId?: string;
155
- backend?: LeaseBackend;
156
- leaseProvider?: string;
157
- deviceKey?: string;
158
- clientId?: string;
159
- };
160
-
161
- declare type NormalizedError = {
162
- code: string;
163
- message: string;
164
- hint?: string;
165
- diagnosticId?: string;
166
- logPath?: string;
167
- details?: Record<string, unknown>;
168
- };
169
-
170
- export declare function normalizeError(err: unknown, context?: {
171
- diagnosticId?: string;
172
- logPath?: string;
173
- }): NormalizedError;
174
-
175
- declare const PLATFORM_SELECTORS: readonly ["apple", "android", "linux", "web", "ios", "macos"];
176
-
177
- declare type PlatformSelector = (typeof PLATFORM_SELECTORS)[number];
178
-
179
- declare type Point = {
180
- x: number;
181
- y: number;
182
- };
183
-
184
- declare type Rect = {
185
- x: number;
186
- y: number;
187
- width: number;
188
- height: number;
189
- };
190
-
191
- declare const RESPONSE_LEVELS: readonly ['digest', 'default', 'full'];
192
-
193
- declare type ResponseCost = {
194
- wallClockMs: number;
195
- runnerRoundTrips: number;
196
- nodeCount?: number;
197
- };
198
-
199
- declare type ResponseLevel = (typeof RESPONSE_LEVELS)[number];
200
-
201
- declare const SESSION_ISOLATION_MODES: readonly ['none', 'tenant'];
202
-
203
- declare type SessionIsolationMode = (typeof SESSION_ISOLATION_MODES)[number];
204
-
205
- export declare type SessionRuntimeHints = {
206
- platform?: 'ios' | 'android';
207
- metroHost?: string;
208
- metroPort?: number;
209
- bundleUrl?: string;
210
- launchUrl?: string;
211
- };
212
-
213
- export { }
1
+ import { D as centerOfRect, F as normalizeError, M as defaultHintForCode, a as DaemonRequest, d as JsonRpcRequestEnvelope, f as LeaseAllocatePayload, h as LeaseReleasePayload, m as LeaseHeartbeatPayload, n as DaemonError, o as DaemonResponse, p as LeaseBackend, r as DaemonInstallSource, s as DaemonResponseData, u as JsonRpcId, y as SessionRuntimeHints } from "./sdk-contracts.js";
2
+ export { type DaemonError, type DaemonInstallSource, type DaemonRequest, type DaemonResponse, type DaemonResponseData, type JsonRpcId, type JsonRpcRequestEnvelope, type LeaseAllocatePayload, type LeaseBackend, type LeaseHeartbeatPayload, type LeaseReleasePayload, type SessionRuntimeHints, centerOfRect, defaultHintForCode, normalizeError };
@@ -1 +1 @@
1
- export{centerOfRect}from"./6849.js";export{defaultHintForCode,normalizeError}from"./485.js";
1
+ import{B as e,L as t,O as n}from"./sdk-contracts.js";export{n as centerOfRect,t as defaultHintForCode,e as normalizeError};
@@ -1,3 +1,5 @@
1
- import e from"node:fs/promises";import t from"node:path";import{AppError as r}from"./485.js";import{isRecord as a}from"./1986.js";import{runCmd as n}from"./8875.js";let i=/^[0-9a-fA-F-]{32,36}$/;function s(e){if(e&&i.test(e))return e.replaceAll("-","").toUpperCase()}function o(e,t){return`${e.uuid}:${d(t)}`}function d(e){return`0x${e.toString(16)}`}function l(e){return"string"==typeof e&&e.length>0?e:void 0}function u(...e){for(let t of e){let e=l(t);if(e)return e}}function c(e){try{let t=JSON.parse(e);return a(t)?t:null}catch{return null}}function m(e){if("number"==typeof e&&Number.isSafeInteger(e))return e;if("string"==typeof e){let t=e.startsWith("0x")?Number.parseInt(e,16):Number(e);return Number.isSafeInteger(t)?t:void 0}}function f(e,t,r){var a;if(!Object.hasOwn(e,t))return;let n="bigint"==typeof(a=e[t])?a:"number"==typeof a&&Number.isSafeInteger(a)?BigInt(a):"string"!=typeof a?void 0:/^(?:0x[0-9a-fA-F]+|\d+)$/.test(a)?BigInt(a):void 0;if(void 0!==n)return n;h(r,t)}function h(e,t){throw new r("INVALID_ARGS",`Invalid ${e} numeric field: ${t}`,{hint:"Crash artifact numeric fields must be integer numbers or integer numeric strings."})}function p(e){return[...new Set(e)]}let y=/^(?:arm64e?|arm64_32|x86_64|armv7[sk]?|i386)$/;async function g(e){return e.dsym&&e.searchPath?[v(e.cwd,e.dsym),...await w(v(e.cwd,e.searchPath))]:e.dsym?[v(e.cwd,e.dsym)]:e.searchPath?await w(v(e.cwd,e.searchPath)):[]}async function w(a){let n=[],i=0;async function s(o){if(!(n.length>=200)){if((i+=1)>1e4)throw new r("COMMAND_FAILED","debug symbols search-path scan exceeded bounds.",{searchPath:a,maxEntries:1e4,hint:"Pass --dsym <App.dSYM> directly or narrow --search-path to the build products directory."});if(!(await b(o,a)).isDirectory()){o===a&&function(e){throw new r("INVALID_ARGS",`debug symbols search path is not a directory: ${e}`,{hint:"Pass an existing build products directory to --search-path, or pass --dsym <App.dSYM> directly."})}(a);return}if(o.endsWith(".dSYM"))return void n.push(o);for(let r of(await e.readdir(o,{withFileTypes:!0})))r.isDirectory()&&await s(t.join(o,r.name))}}return await s(a),n}async function b(t,a){try{return await e.stat(t)}catch{throw new r("INVALID_ARGS",`debug symbols search path does not exist: ${a}`,{hint:"Pass an existing build products directory to --search-path, or pass --dsym <App.dSYM> directly."})}}async function I(e,t){let a=(await Promise.all(p(e).map(e=>A(e,t)))).flat();if(0===a.length)throw new r("COMMAND_FAILED","No UUIDs found in dSYM bundle.",{hint:"Verify the path points to a built .dSYM bundle with DWARF contents."});return a}async function A(e,t){var a;await S(e);let i=await n(t,["--uuid",e],{timeoutMs:15e3,allowFailure:!0});if(0!==i.exitCode)throw new r("COMMAND_FAILED",`Failed to inspect dSYM UUIDs: ${e}`,{stderr:i.stderr,hint:"Verify the dSYM bundle is valid and readable."});return a=e,i.stdout.split("\n").flatMap(e=>{let t=e.match(/^UUID:\s+([0-9a-fA-F-]{32,36})\s+\(([^)]+)\)\s+(.+)$/),r=s(t?.[1]);return t&&r?[{dsymPath:a,uuid:r,arch:t[2],binaryPath:t[3].trim()}]:[]})}async function S(t){let a=await e.stat(t).catch(()=>null);if(!(a?.isDirectory()&&t.endsWith(".dSYM")))throw new r("INVALID_ARGS",`Not a .dSYM bundle: ${t}`,{hint:"Pass the .dSYM bundle path, not the DWARF executable inside it."})}function v(e,r){return t.resolve(e,r)}function x(e,t){let r=`${t}:`,a=e.find(e=>e.trimStart().startsWith(r));return a&&a.slice(a.indexOf(":")+1).trim()||void 0}function M(e,t,r,a){return{index:e,image:t.name,address:d(r),symbol:a.get(o(t,r))?.text}}function $(e){var t;let r;return[(r=(t=e).topFrames.find(e=>e.symbol))?`Start with ${r.symbol} in ${r.image}; it is the first symbolicated frame captured on the crashed thread.`:t.topFrames.length>0?"No symbolicated frame was found on the crashed thread; verify matching dSYMs for the top images.":void 0,e.exceptionType?`Exception: ${e.exceptionType}`:void 0,e.terminationReason?`Termination: ${e.terminationReason}`:void 0].filter(e=>!!e).slice(0,3)}async function N(e,t,r){let a=new Map;for(let n of(function(e,t){let r=new Map;for(let a of e){let e=t.get(a.image.uuid);if(!e)continue;let n=`${a.image.uuid}:${e.dsym.binaryPath}`,i=r.get(n)??{...e,addresses:[]};i.addresses.push(a.address),r.set(n,i)}return r})(e,t).values())for(let e of(await _(r,n)))a.set(o(e.image,e.address),e);return a}async function _(e,t){var a,i,s,o;let l,u,c=p(t.addresses.map(d)),m=await n(e,(a=t,i=c,["-arch",a.image.arch??a.dsym.arch??"arm64","-o",a.dsym.binaryPath,"-l",d(a.image.base),...i]),{timeoutMs:3e4,allowFailure:!0});return 0!==m.exitCode&&function(e){throw new r("COMMAND_FAILED","atos failed while symbolicating crash frames.",{stderr:e,hint:"Verify the crash artifact and dSYM were produced from the same build and architecture."})}(m.stderr),s=t.image,o=c,u=(""===(l=m.stdout.split(/\r?\n/)).at(-1)&&l.pop(),l),o.map((e,t)=>{let r=u[t]?.trim();return{image:s,address:BigInt(e),text:!function(e,t){if(!e)return!1;let r=e.trim().toLowerCase();return!!r&&"??"!==r&&r!==t.toLowerCase()&&!r.startsWith("0x")}(r,e)?void 0:r}})}async function D(){return{dwarfdump:await F("dwarfdump"),atos:await F("atos")}}async function F(e){try{let t=await n("xcrun",["--find",e],{timeoutMs:5e3,allowFailure:!0}),r=t.stdout.trim();if(0===t.exitCode&&r.length>0)return r}catch{}throw new r("TOOL_MISSING",`Apple symbolication tool not found: ${e}`,{hint:"Install Xcode Command Line Tools and verify xcrun --find dwarfdump and xcrun --find atos succeed."})}async function P(n){var i,d,w,b,A,S,v,_,F,P,U,Y,T,L,O,E,V,B,G,W,j,k,K,z,H,J,q,X;let Q,Z,ee,et,er,ea,en,ei,es,eo,ed;if(void 0!==n.action&&"symbols"!==n.action)throw new r("INVALID_ARGS","debug supports only the symbols workflow.",{hint:"Use debug symbols --artifact <crash.ips|crash.log> --dsym <App.dSYM> or --search-path <dir> --out <path>."});let el=n.cwd??process.cwd(),eu=R(el,n.artifact),ec=R(el,n.out??(d=eu,Z=(Q=t.extname(d))?d.slice(0,-Q.length):d,`${Z}-symbolicated${Q||".log"}`)),em=function(e){var r;let n,i=function(e){let t=c(e);if(t)return{payload:t};let r=e.indexOf("\n");if(-1===r)return null;let a=e.slice(0,r),n=c(e.slice(r+1));return n?{header:a,payload:n}:null}(e);if(!i)return null;let d=(Array.isArray(i.payload.usedImages)?i.payload.usedImages:[]).flatMap((e,r)=>(function(e,r){if(!a(e))return[];let n=s(l(e.uuid)),i=f(e,"base","IPS usedImages");if(!n||void 0===i)return[];let o=l(e.path);return[{index:r,name:l(e.name)??(o?t.basename(o):`image-${r}`),uuid:n,arch:l(e.arch),base:i,path:o}]})(e,r));if(0===d.length)return null;let u=(r=Array.isArray(i.payload.threads)?i.payload.threads:[],n=new Map(d.map(e=>[e.index,e])),r.flatMap((e,t)=>{var r;return(a(r=e)&&Array.isArray(r.frames)?r.frames.filter(a):[]).flatMap((e,r)=>(function(e,t,r,a){let n=function(e,t,r){if(!Object.hasOwn(e,t))return;let a=m(e[t]);if(void 0!==a)return a;h(r,t)}(e,"imageIndex","IPS frame"),i=f(e,"imageOffset","IPS frame");if(void 0===n||void 0===i)return[];let s=t.get(n);return s?[{frame:e,frameIndex:a,threadIndex:r,image:s,address:s.base+i}]:[]})(e,n,t,r))}));return{format:"ips",images:d,addresses:u.map(({frame:e,...t})=>t),document:i,frameMatches:u,write:e=>(function(e,t,r){for(let e of t){let t=r.get(o(e.image,e.address))?.text;t&&function(e,t){let r,a=(r=t.match(/^(.*) \+ (\d+)$/))?{symbol:r[1],location:Number(r[2])}:{symbol:t};e.symbol=a.symbol,void 0!==a.location&&(e.symbolLocation=a.location)}(e.frame,t)}e.payload.agentDeviceSymbolication={tool:"agent-device debug symbols",symbolicatedFrames:[...r.values()].filter(e=>e.text).length};let a=`${JSON.stringify(e.payload,null,2)}
2
- `;return e.header?`${e.header}
3
- ${a}`:a})(i,u,e)}}(i=await C(eu,"crash artifact"))??function(e){let r=e.split("\n"),a=function(e){let r=[],a=e.findIndex(e=>/^Binary Images:/i.test(e.trim()));if(-1===a)return r;for(let n of e.slice(a+1)){let e=function(e){let r=e.match(/^\s*(0x[0-9a-fA-F]+)\s*-\s*(0x[0-9a-fA-F]+)\s+\+?(.+?)\s+<([0-9a-fA-F-]{32,36})>\s+(.+)$/);if(!r)return null;let a=s(r[4]);if(!a)return null;let n=function(e,r){let a=e.split(/\s+/),n=a.at(-1);if(n&&y.test(n))return{name:a.slice(0,-1).join(" ").trim(),arch:n};let i=t.basename(r);return{name:e.startsWith(i)?i:e}}(r[3].trim(),r[5].trim());return{name:n.name,arch:n.arch,uuid:a,base:BigInt(r[1]),end:BigInt(r[2]),path:r[5].trim()}}(n);e&&r.push(e)}return r}(r);if(0===a.length)return null;let n=function(e,t){let r,a=[];for(let[n,i]of e.entries()){let e=i.match(/^Thread\s+(\d+)\s+Crashed:/);e?r=Number(e[1]):(0===i.trim().length||/^Thread\s+\d+/.test(i))&&(r=void 0);let s=function(e,t){let r=e.match(/^\s*\d+\s+(.+?)\s+(0x[0-9a-fA-F]+)\b/);if(!r)return null;let a=r[1].trim(),n=BigInt(r[2]),i=function(e,t,r){let a=e.filter(e=>e.name===t);return a.find(e=>{var t,a;return t=e,a=r,void 0!==t.end&&t.base<=a&&a<=t.end})??(1===a.length?a[0]:void 0)}(t,a,n);return i?{image:i,address:n}:null}(i,t),o=i.match(/^\s*(\d+)/);s&&o&&a.push({...s,frameIndex:Number(o[1]),lineIndex:n,threadIndex:r})}return a}(r,a);return{format:"text",images:a,addresses:n,lines:r,frameMatches:n,write(e){let t=new Map(n.map(e=>[e.lineIndex,e]));return r.map((r,a)=>{let n=t.get(a);if(!n)return r;let i=e.get(o(n.image,n.address))?.text;return!i||r.includes(i)?r:`${r} // ${i}`}).join("\n")}}}(i);em||function(){throw new r("UNSUPPORTED_OPERATION","debug symbols currently supports Apple crash artifacts with Binary Images or IPS usedImages.",{hint:"For Android Java/R8 crashes, use retrace with mapping.txt. For Android native crashes, use ndk-stack or addr2line with unstripped .so symbols. Capture the crash with logs, then symbolicate externally until Android support is added."})}();let ef=await g({cwd:el,dsym:n.dsym,searchPath:n.searchPath});if(0===ef.length)throw new r("INVALID_ARGS","debug symbols requires --dsym or --search-path.",{hint:"Pass a matching .dSYM bundle directly, or pass --search-path <dir> so agent-device can match crash image UUIDs to local dSYMs."});let eh=await D(),ep=await I(ef,eh.dwarfdump),ey=function(e,t,a){let n=new Map;for(let r of e){let e=t.find(e=>e.uuid===r.uuid&&(void 0===r.arch||void 0===e.arch||e.arch===r.arch));e&&n.set(r.uuid,{image:r,dsym:e})}if(n.size>0)return n;let i=p(e.map(e=>e.uuid)),s=p(t.map(e=>e.uuid));throw new r("COMMAND_FAILED",a?"dSYM UUID does not match any Apple image in the crash artifact.":"No matching dSYM UUID found under search path.",{artifactUuidCount:i.length,artifactUuidSample:i.slice(0,5),dsymUuidCount:s.length,dsymUuidSample:s.slice(0,5),hint:"Use dwarfdump --uuid <App.dSYM> and compare it with the crash Binary Images or usedImages UUID, then pass the matching dSYM/search path."})}(em.images,ep,!!n.dsym),eg=await N(em.addresses,ey,eh.atos),ew=em.write(eg);await e.mkdir(t.dirname(ec),{recursive:!0}),await e.writeFile(ec,ew,"utf8");let eb=[...ey.values()].map(({image:e,dsym:t})=>({name:e.name,uuid:e.uuid,arch:e.arch??t.arch,dsymPath:t.dsymPath,binaryPath:t.binaryPath})),eI=[...eg.values()].filter(e=>e.text).length,eA=em.images.length-eb.length,eS=eA>0?[`${eA} Apple image${1===eA?"":"s"} had no matching dSYM and were left unchanged.`]:void 0;return{kind:"debugSymbols",platform:"apple",artifactPath:eu,outPath:ec,crash:"ips"===em.format?(w=em.document,b=em.frameMatches,A=eg,en=function(e){let t=m(e.faultingThread);if(void 0!==t)return t;let r=(Array.isArray(e.threads)?e.threads:[]).findIndex(e=>a(e)&&!0===e.triggered);return -1===r?void 0:r}(w.payload),{...ei={format:"ips",...(ee=(S=w).payload,et=(v=S.header)?c(v):null,{appName:(_=ee,F=et,u(_.procName,F?.app_name,F?.name)),bundleId:(P=ee,U=et,er=a(P.bundleInfo)?P.bundleInfo:void 0,u(er?.CFBundleIdentifier,U?.bundleID)),version:(Y=ee,T=et,ea=a(Y.bundleInfo)?Y.bundleInfo:void 0,u(ea?.CFBundleShortVersionString,T?.app_version)),incident:(L=ee,O=et,u(L.incident,O?.incident_id)),timestamp:(E=ee,V=et,u(E.captureTime,V?.timestamp)),exceptionType:a(B=ee.exception)?l(B.type):void 0,exceptionCodes:a(G=ee.exception)?u(G.codes,G.rawCodes):void 0,terminationReason:function(e){if(a(e)){let t;return(t=[l(e.namespace),l(e.code),l(e.reason)].filter(e=>!!e)).length>0?t.join(" "):void 0}}(ee.termination)}),crashedThread:en,topFrames:(W=b,j=en,k=A,W.filter(e=>void 0===j||e.threadIndex===j).slice(0,5).map(e=>M(e.frameIndex,e.image,e.address,k))),findings:[]},findings:$(ei)}):(K=em.lines,z=em.frameMatches,H=eg,eo=function(e){let t=x(e,"Triggered by Thread"),r=t?Number.parseInt(t,10):NaN;if(Number.isSafeInteger(r))return r;for(let t of e){let e=t.match(/^Thread\s+(\d+)\s+Crashed:/);if(e)return Number(e[1])}}(K),{...ed={format:"text",appName:(es=x(K,"Process"),es?.replace(/\s+\[\d+\]$/,"")),bundleId:x(K,"Identifier"),version:x(K,"Version"),incident:x(K,"Incident Identifier"),timestamp:x(K,"Date/Time"),exceptionType:x(K,"Exception Type"),exceptionCodes:x(K,"Exception Codes"),terminationReason:x(K,"Termination Reason"),crashedThread:eo,topFrames:(J=z,q=eo,X=H,void 0===q?[]:J.filter(e=>e.threadIndex===q).slice(0,5).map(e=>M(e.frameIndex,e.image,e.address,X))),findings:[]},findings:$(ed)}),matchedImages:eb,symbolicatedFrames:eI,skippedImages:eA,warnings:eS,message:`Symbolicated ${eI} frame${1===eI?"":"s"} -> ${ec}`}}async function C(t,a){await U(t,a);try{return await e.readFile(t,"utf8")}catch(e){throw new r("INVALID_ARGS",`Failed to read ${a}: ${t}`,{message:e instanceof Error?e.message:String(e)})}}async function U(t,a){try{let n=await e.stat(t);if(n.size<=0x4000000)return;throw new r("INVALID_ARGS",`${a} is too large: ${t}`,{actualBytes:n.size,maxBytes:0x4000000,hint:"Pass a bounded Apple .ips/.crash artifact. For very large logs, first narrow the log to the crash report, or use logs grep/tail for lead-up context."})}catch(e){if(e instanceof r)throw e;throw new r("INVALID_ARGS",`Failed to read ${a}: ${t}`,{message:e instanceof Error?e.message:String(e)})}}function R(e,r){return t.resolve(e,r)}export{P as symbolicateCrashArtifact};
1
+ import{F as e}from"./sdk-contracts.js";import{h as t,v as n}from"./sdk-android-adb.js";import{l as r}from"./sdk-batch-runner.js";import i from"node:path";import a from"node:fs/promises";const o=/^[0-9a-fA-F-]{32,36}$/;function s(e){if(!(!e||!o.test(e)))return e.replaceAll(`-`,``).toUpperCase()}function c(e,t){return`${e.uuid}:${l(t)}`}function l(e){return`0x${e.toString(16)}`}function u(e){return typeof e==`string`&&e.length>0?e:void 0}function d(...e){for(let t of e){let e=u(t);if(e)return e}}function f(e){let t=e.filter(e=>!!e);return t.length>0?t.join(` `):void 0}function p(e){try{let t=JSON.parse(e);return r(t)?t:null}catch{return null}}function m(e){if(typeof e==`number`&&Number.isSafeInteger(e))return e;if(typeof e==`string`){let t=e.startsWith(`0x`)?Number.parseInt(e,16):Number(e);return Number.isSafeInteger(t)?t:void 0}}function h(e,t,n){if(!Object.hasOwn(e,t))return;let r=m(e[t]);if(r!==void 0)return r;v(n,t)}function g(e,t,n){if(!Object.hasOwn(e,t))return;let r=_(e[t]);if(r!==void 0)return r;v(n,t)}function _(e){if(typeof e==`bigint`)return e;if(typeof e==`number`&&Number.isSafeInteger(e)||typeof e==`string`&&/^(?:0x[0-9a-fA-F]+|\d+)$/.test(e))return BigInt(e)}function v(t,n){throw new e(`INVALID_ARGS`,`Invalid ${t} numeric field: ${n}`,{hint:`Crash artifact numeric fields must be integer numbers or integer numeric strings.`})}function y(e){return e.length===1?e[0]:void 0}function b(e){return[...new Set(e)]}function x(e){let t=e.match(/^(.*) \+ (\d+)$/);return t?{symbol:t[1],location:Number(t[2])}:{symbol:e}}const S=/^(?:arm64e?|arm64_32|x86_64|armv7[sk]?|i386)$/;function ee(e){return te(e)??w(e)}function te(e){let t=ne(e);if(!t)return null;let n=(Array.isArray(t.payload.usedImages)?t.payload.usedImages:[]).flatMap((e,t)=>C(e,t));if(n.length===0)return null;let r=re(Array.isArray(t.payload.threads)?t.payload.threads:[],n);return{format:`ips`,images:n,addresses:r.map(({frame:e,...t})=>t),document:t,frameMatches:r,write:e=>oe(t,r,e)}}function ne(e){let t=p(e);if(t)return{payload:t};let n=e.indexOf(`
2
+ `);if(n===-1)return null;let r=e.slice(0,n),i=p(e.slice(n+1));return i?{header:r,payload:i}:null}function re(e,t){let n=new Map(t.map(e=>[e.index,e]));return e.flatMap((e,t)=>ie(e).flatMap((e,r)=>ae(e,n,t,r)))}function ie(e){return!r(e)||!Array.isArray(e.frames)?[]:e.frames.filter(r)}function ae(e,t,n,r){let i=h(e,`imageIndex`,`IPS frame`),a=g(e,`imageOffset`,`IPS frame`);if(i===void 0||a===void 0)return[];let o=t.get(i);return o?[{frame:e,frameIndex:r,threadIndex:n,image:o,address:o.base+a}]:[]}function oe(e,t,n){for(let e of t){let t=n.get(c(e.image,e.address))?.text;t&&se(e.frame,t)}e.payload.agentDeviceSymbolication={tool:`agent-device debug symbols`,symbolicatedFrames:[...n.values()].filter(e=>e.text).length};let r=`${JSON.stringify(e.payload,null,2)}\n`;return e.header?`${e.header}\n${r}`:r}function se(e,t){let n=x(t);e.symbol=n.symbol,n.location!==void 0&&(e.symbolLocation=n.location)}function C(e,t){if(!r(e))return[];let n=s(u(e.uuid)),a=g(e,`base`,`IPS usedImages`);if(!n||a===void 0)return[];let o=u(e.path);return[{index:t,name:u(e.name)??(o?i.basename(o):`image-${t}`),uuid:n,arch:u(e.arch),base:a,path:o}]}function w(e){let t=e.split(`
3
+ `),n=T(t);if(n.length===0)return null;let r=O(t,n);return{format:`text`,images:n,addresses:r,lines:t,frameMatches:r,write(e){let n=new Map(r.map(e=>[e.lineIndex,e]));return t.map((t,r)=>{let i=n.get(r);if(!i)return t;let a=e.get(c(i.image,i.address))?.text;return!a||t.includes(a)?t:`${t} // ${a}`}).join(`
4
+ `)}}}function T(e){let t=[],n=e.findIndex(e=>/^Binary Images:/i.test(e.trim()));if(n===-1)return t;for(let r of e.slice(n+1)){let e=E(r);e&&t.push(e)}return t}function E(e){let t=e.match(/^\s*(0x[0-9a-fA-F]+)\s*-\s*(0x[0-9a-fA-F]+)\s+\+?(.+?)\s+<([0-9a-fA-F-]{32,36})>\s+(.+)$/);if(!t)return null;let n=s(t[4]);if(!n)return null;let r=D(t[3].trim(),t[5].trim());return{name:r.name,arch:r.arch,uuid:n,base:BigInt(t[1]),end:BigInt(t[2]),path:t[5].trim()}}function D(e,t){let n=e.split(/\s+/),r=n.at(-1);if(r&&S.test(r))return{name:n.slice(0,-1).join(` `).trim(),arch:r};let a=i.basename(t);return{name:e.startsWith(a)?a:e}}function O(e,t){let n=[],r;for(let[i,a]of e.entries()){let e=a.match(/^Thread\s+(\d+)\s+Crashed:/);e?r=Number(e[1]):(a.trim().length===0||/^Thread\s+\d+/.test(a))&&(r=void 0);let o=k(a,t),s=a.match(/^\s*(\d+)/);o&&s&&n.push({...o,frameIndex:Number(s[1]),lineIndex:i,threadIndex:r})}return n}function k(e,t){let n=e.match(/^\s*\d+\s+(.+?)\s+(0x[0-9a-fA-F]+)\b/);if(!n)return null;let r=n[1].trim(),i=BigInt(n[2]),a=A(t,r,i);return a?{image:a,address:i}:null}function A(e,t,n){let r=e.filter(e=>e.name===t);return r.find(e=>j(e,n))??y(r)}function j(e,t){return e.end!==void 0&&e.base<=t&&t<=e.end}const M=1e4;async function N(e){return e.dsym&&e.searchPath?[H(e.cwd,e.dsym),...await P(H(e.cwd,e.searchPath))]:e.dsym?[H(e.cwd,e.dsym)]:e.searchPath?await P(H(e.cwd,e.searchPath)):[]}async function P(t){let n=[],r=0;async function o(s){if(n.length>=200)return;if(r+=1,r>M)throw new e(`COMMAND_FAILED`,`debug symbols search-path scan exceeded bounds.`,{searchPath:t,maxEntries:M,hint:`Pass --dsym <App.dSYM> directly or narrow --search-path to the build products directory.`});if(!(await F(s,t)).isDirectory()){s===t&&I(t);return}if(s.endsWith(`.dSYM`)){n.push(s);return}let c=await a.readdir(s,{withFileTypes:!0});for(let e of c)e.isDirectory()&&await o(i.join(s,e.name))}return await o(t),n}async function F(t,n){try{return await a.stat(t)}catch{throw new e(`INVALID_ARGS`,`debug symbols search path does not exist: ${n}`,{hint:`Pass an existing build products directory to --search-path, or pass --dsym <App.dSYM> directly.`})}}function I(t){throw new e(`INVALID_ARGS`,`debug symbols search path is not a directory: ${t}`,{hint:`Pass an existing build products directory to --search-path, or pass --dsym <App.dSYM> directly.`})}async function L(t,n){let r=(await Promise.all(b(t).map(e=>R(e,n)))).flat();if(r.length===0)throw new e(`COMMAND_FAILED`,`No UUIDs found in dSYM bundle.`,{hint:`Verify the path points to a built .dSYM bundle with DWARF contents.`});return r}async function R(e,r){return await z(e),B(e,t(await n(r,[`--uuid`,e],{timeoutMs:15e3,allowFailure:!0}),`Failed to inspect dSYM UUIDs: ${e}`,{hint:`Verify the dSYM bundle is valid and readable.`}).stdout)}async function z(t){if(!((await a.stat(t).catch(()=>null))?.isDirectory()&&t.endsWith(`.dSYM`)))throw new e(`INVALID_ARGS`,`Not a .dSYM bundle: ${t}`,{hint:`Pass the .dSYM bundle path, not the DWARF executable inside it.`})}function B(e,t){return t.split(`
5
+ `).flatMap(t=>{let n=t.match(/^UUID:\s+([0-9a-fA-F-]{32,36})\s+\(([^)]+)\)\s+(.+)$/),r=s(n?.[1]);return n&&r?[{dsymPath:e,uuid:r,arch:n[2],binaryPath:n[3].trim()}]:[]})}function V(t,n,r){let i=new Map;for(let e of t){let t=n.find(t=>t.uuid===e.uuid&&(e.arch===void 0||t.arch===void 0||t.arch===e.arch));t&&i.set(e.uuid,{image:e,dsym:t})}if(i.size>0)return i;let a=b(t.map(e=>e.uuid)),o=b(n.map(e=>e.uuid));throw new e(`COMMAND_FAILED`,r?`dSYM UUID does not match any Apple image in the crash artifact.`:`No matching dSYM UUID found under search path.`,{artifactUuidCount:a.length,artifactUuidSample:a.slice(0,5),dsymUuidCount:o.length,dsymUuidSample:o.slice(0,5),hint:`Use dwarfdump --uuid <App.dSYM> and compare it with the crash Binary Images or usedImages UUID, then pass the matching dSYM/search path.`})}function H(e,t){return i.resolve(e,t)}function U(e,t){return e.format===`ips`?W(e.document,e.frameMatches,t):ve(e.lines,e.frameMatches,t)}function W(e,t,n){let r=me(e.payload),i={format:`ips`,...G(e),crashedThread:r,topFrames:_e(t,r,n),findings:[]};return{...i,findings:Y(i)}}function G(e){let t=e.payload,n=pe(e.header);return{appName:K(t,n),bundleId:ce(t,n),version:le(t,n),incident:ue(t,n),timestamp:de(t,n),exceptionType:fe(t.exception),exceptionCodes:he(t.exception),terminationReason:ge(t.termination)}}function K(e,t){return d(e.procName,t?.app_name,t?.name)}function ce(e,t){return d((r(e.bundleInfo)?e.bundleInfo:void 0)?.CFBundleIdentifier,t?.bundleID)}function le(e,t){return d((r(e.bundleInfo)?e.bundleInfo:void 0)?.CFBundleShortVersionString,t?.app_version)}function ue(e,t){return d(e.incident,t?.incident_id)}function de(e,t){return d(e.captureTime,t?.timestamp)}function fe(e){return r(e)?u(e.type):void 0}function pe(e){return e?p(e):null}function me(e){let t=m(e.faultingThread);if(t!==void 0)return t;let n=(Array.isArray(e.threads)?e.threads:[]).findIndex(e=>r(e)&&e.triggered===!0);return n===-1?void 0:n}function he(e){return r(e)?d(e.codes,e.rawCodes):void 0}function ge(e){if(r(e))return f([u(e.namespace),u(e.code),u(e.reason)])}function _e(e,t,n){return e.filter(e=>t===void 0||e.threadIndex===t).slice(0,5).map(e=>J(e.frameIndex,e.image,e.address,n))}function ve(e,t,n){let r=be(e),i={format:`text`,appName:ye(e),bundleId:q(e,`Identifier`),version:q(e,`Version`),incident:q(e,`Incident Identifier`),timestamp:q(e,`Date/Time`),exceptionType:q(e,`Exception Type`),exceptionCodes:q(e,`Exception Codes`),terminationReason:q(e,`Termination Reason`),crashedThread:r,topFrames:xe(t,r,n),findings:[]};return{...i,findings:Y(i)}}function ye(e){return q(e,`Process`)?.replace(/\s+\[\d+\]$/,``)}function q(e,t){let n=`${t}:`,r=e.find(e=>e.trimStart().startsWith(n));return r&&r.slice(r.indexOf(`:`)+1).trim()||void 0}function be(e){let t=q(e,`Triggered by Thread`),n=t?Number.parseInt(t,10):NaN;if(Number.isSafeInteger(n))return n;for(let t of e){let e=t.match(/^Thread\s+(\d+)\s+Crashed:/);if(e)return Number(e[1])}}function xe(e,t,n){return t===void 0?[]:e.filter(e=>e.threadIndex===t).slice(0,5).map(e=>J(e.frameIndex,e.image,e.address,n))}function J(e,t,n,r){return{index:e,image:t.name,address:l(n),symbol:r.get(c(t,n))?.text}}function Y(e){return[Se(e),e.exceptionType?`Exception: ${e.exceptionType}`:void 0,e.terminationReason?`Termination: ${e.terminationReason}`:void 0].filter(e=>!!e).slice(0,3)}function Se(e){let t=e.topFrames.find(e=>e.symbol);return t?`Start with ${t.symbol} in ${t.image}; it is the first symbolicated frame captured on the crashed thread.`:e.topFrames.length>0?`No symbolicated frame was found on the crashed thread; verify matching dSYMs for the top images.`:void 0}async function Ce(e,t,n){let r=new Map;for(let i of we(e,t).values())for(let e of await Te(n,i))r.set(c(e.image,e.address),e);return r}function we(e,t){let n=new Map;for(let r of e){let e=t.get(r.image.uuid);if(!e)continue;let i=`${r.image.uuid}:${e.dsym.binaryPath}`,a=n.get(i)??{...e,addresses:[]};a.addresses.push(r.address),n.set(i,a)}return n}async function Te(e,r){let i=b(r.addresses.map(l)),a=t(await n(e,Ee(r,i),{timeoutMs:3e4,allowFailure:!0}),`atos failed while symbolicating crash frames.`,{hint:`Verify the crash artifact and dSYM were produced from the same build and architecture.`});return De(r.image,i,a.stdout)}function Ee(e,t){return[`-arch`,e.image.arch??e.dsym.arch??`arm64`,`-o`,e.dsym.binaryPath,`-l`,l(e.image.base),...t]}function De(e,t,n){let r=Oe(n);return t.map((t,n)=>{let i=r[n]?.trim();return{image:e,address:BigInt(t),text:ke(i,t)?i:void 0}})}function Oe(e){let t=e.split(/\r?\n/);return t.at(-1)===``&&t.pop(),t}function ke(e,t){if(!e)return!1;let n=e.trim().toLowerCase();return!n||n===`??`||n===t.toLowerCase()?!1:!n.startsWith(`0x`)}async function Ae(){return{dwarfdump:await X(`dwarfdump`),atos:await X(`atos`)}}async function X(t){try{let e=await n(`xcrun`,[`--find`,t],{timeoutMs:5e3,allowFailure:!0}),r=e.stdout.trim();if(e.exitCode===0&&r.length>0)return r}catch{}throw new e(`TOOL_MISSING`,`Apple symbolication tool not found: ${t}`,{hint:`Install Xcode Command Line Tools and verify xcrun --find dwarfdump and xcrun --find atos succeed.`})}const Z=64*1024*1024;async function je(t){if(t.action!==void 0&&t.action!==`symbols`)throw new e(`INVALID_ARGS`,`debug supports only the symbols workflow.`,{hint:`Use debug symbols --artifact <crash.ips|crash.log> --dsym <App.dSYM> or --search-path <dir> --out <path>.`});let n=t.cwd??process.cwd(),r=$(n,t.artifact),o=$(n,t.out??Pe(r)),s=ee(await Me(r,`crash artifact`));s||Q();let c=await N({cwd:n,dsym:t.dsym,searchPath:t.searchPath});if(c.length===0)throw new e(`INVALID_ARGS`,`debug symbols requires --dsym or --search-path.`,{hint:`Pass a matching .dSYM bundle directly, or pass --search-path <dir> so agent-device can match crash image UUIDs to local dSYMs.`});let l=await Ae(),u=await L(c,l.dwarfdump),d=V(s.images,u,!!t.dsym),f=await Ce(s.addresses,d,l.atos),p=s.write(f);await a.mkdir(i.dirname(o),{recursive:!0}),await a.writeFile(o,p,`utf8`);let m=[...d.values()].map(({image:e,dsym:t})=>({name:e.name,uuid:e.uuid,arch:e.arch??t.arch,dsymPath:t.dsymPath,binaryPath:t.binaryPath})),h=[...f.values()].filter(e=>e.text).length,g=s.images.length-m.length,_=g>0?[`${g} Apple image${g===1?``:`s`} had no matching dSYM and were left unchanged.`]:void 0;return{kind:`debugSymbols`,platform:`apple`,artifactPath:r,outPath:o,crash:U(s,f),matchedImages:m,symbolicatedFrames:h,skippedImages:g,warnings:_,message:`Symbolicated ${h} frame${h===1?``:`s`} -> ${o}`}}function Q(){throw new e(`UNSUPPORTED_OPERATION`,`debug symbols currently supports Apple crash artifacts with Binary Images or IPS usedImages.`,{hint:`For Android Java/R8 crashes, use retrace with mapping.txt. For Android native crashes, use ndk-stack or addr2line with unstripped .so symbols. Capture the crash with logs, then symbolicate externally until Android support is added.`})}async function Me(t,n){await Ne(t,n);try{return await a.readFile(t,`utf8`)}catch(r){let i=r instanceof Error?r.message:String(r);throw new e(`INVALID_ARGS`,`Failed to read ${n}: ${t}`,{message:i})}}async function Ne(t,n){try{let r=await a.stat(t);if(r.size<=Z)return;throw new e(`INVALID_ARGS`,`${n} is too large: ${t}`,{actualBytes:r.size,maxBytes:Z,hint:`Pass a bounded Apple .ips/.crash artifact. For very large logs, first narrow the log to the crash report, or use logs grep/tail for lead-up context.`})}catch(r){if(r instanceof e)throw r;let i=r instanceof Error?r.message:String(r);throw new e(`INVALID_ARGS`,`Failed to read ${n}: ${t}`,{message:i})}}function $(e,t){return i.resolve(e,t)}function Pe(e){let t=i.extname(e);return`${t?e.slice(0,-t.length):e}-symbolicated${t||`.log`}`}export{je as symbolicateCrashArtifact};
@@ -0,0 +1,2 @@
1
+ import{t as e}from"./rolldown-runtime.js";import{F as t}from"./sdk-contracts.js";import{c as n,j as r,n as i}from"./sdk-android-adb.js";import{t as a}from"./timeouts.js";import{a as o,f as s,i as c,o as l,t as u}from"./android-input-ownership.js";var d=e({dismissAndroidKeyboard:()=>v,dismissAndroidKeyboardWithAdb:()=>y,getAndroidKeyboardState:()=>g,getAndroidKeyboardStatusWithAdb:()=>_,readAndroidClipboardText:()=>A,readAndroidClipboardWithAdb:()=>j,writeAndroidClipboardText:()=>M,writeAndroidClipboardWithAdb:()=>N});const f=[`mInputShown`,`mIsInputViewShown`,`isInputViewShown`,`mDecorViewVisible`,`mWindowVisible`,`mInShowWindow`],p=new Map([[2,`number`],[3,`phone`],[4,`datetime`]]),m=new Set([32,208]),h=new Set([128,224,144]);async function g(e){return await _(n(e))}async function _(e){let t=await e([`shell`,`dumpsys`,`input_method`],{allowFailure:!0});if(t.exitCode!==0)throw i(`Failed to query Android keyboard state`,t);return b(t.stdout)}async function v(e){return await y(n(e))}async function y(e){let n=await _(e),r=n,i=0;for(;r.visible&&i<2;)await e([`shell`,`input`,`keyevent`,`111`]),i+=1,await a(120),r=await _(e);if(n.visible&&r.visible)throw new t(`UNSUPPORTED_OPERATION`,`Android keyboard dismiss is unavailable for the current IME without back navigation.`,{attempts:i,inputType:r.inputType,type:r.type,inputMethodPackage:r.inputMethodPackage,focusedPackage:r.focusedPackage,focusedResourceId:r.focusedResourceId,inputOwner:r.inputOwner});return{attempts:i,wasVisible:n.visible,dismissed:n.visible&&!r.visible,visible:r.visible,inputType:r.inputType,type:r.type,inputMethodPackage:r.inputMethodPackage,focusedPackage:r.focusedPackage,focusedResourceId:r.focusedResourceId,inputOwner:r.inputOwner}}function b(e){let t=T(e)??x(e),n=S(e),r=C(e,/\bpackageName=([A-Za-z0-9_.]+)\b/g),i=C(e,/\b(?:resourceId|resource-id)=([^\s,}]+)/g),a=l(e),o=u(r,i,a);return w(r,i,a),{visible:t??!1,inputType:n,type:n?k(n):void 0,inputMethodPackage:a,focusedPackage:r,focusedResourceId:i,inputOwner:o}}function x(e){let t=e.match(/\bmImeWindowVis=0x([0-9a-fA-F]+)\b/)?.[1];if(!t)return null;let n=Number.parseInt(t,16);return Number.isNaN(n)?null:(n&1)!=0}function S(e){let t=C(e,/\binputType=0x([0-9a-fA-F]+)\b/gi);return t?`0x${t.toLowerCase()}`:void 0}function C(e,t){let n;for(let r of e.matchAll(t))n=r[1];return n}function w(e,t,n){n||!c(e)&&!o(t)||r({level:`warn`,phase:`android_input_ownership_fallback`,data:{focusedPackage:e,focusedResourceId:t}})}function T(e){return D(E(e,f))}function E(e,t){let n=new Map,r=RegExp(`\\b(${t.join(`|`)})=([a-zA-Z]+)\\b`,`g`);for(let t of e.matchAll(r)){let e=t[1],r=t[2]?.toLowerCase();!e||r!==`true`&&r!==`false`||n.set(e,r===`true`)}return n}function D(e){if(e.size===0)return null;let t=O(e,[`mWindowVisible`,`mDecorViewVisible`,`mInShowWindow`]);if(t!==void 0)return t;let n=e.get(`mInputShown`);return n===void 0?O(e,[`mIsInputViewShown`,`isInputViewShown`])??null:n}function O(e,t){for(let n of t){let t=e.get(n);if(t!==void 0)return t}}function k(e){let t=Number.parseInt(e.replace(/^0x/i,``),16);if(Number.isNaN(t))return`unknown`;let n=t&15,r=p.get(n);if(r)return r;if(n!==1)return`unknown`;let i=t&4080;return m.has(i)?`email`:h.has(i)?`password`:`text`}async function A(e){return await j(n(e))}async function j(e){return F(await P(e,[`shell`,`cmd`,`clipboard`,`get`,`text`],`read`))}async function M(e,t){await N(n(e),t)}async function N(e,t){await P(e,[`shell`,`cmd`,`clipboard`,`set`,`text`,t],`write`)}async function P(e,n,r){let a=await e(n,{allowFailure:!0});if(s(a.stdout,a.stderr))throw new t(`UNSUPPORTED_OPERATION`,`Android shell clipboard ${r} is not supported on this device.`);if(a.exitCode!==0)throw i(`Failed to ${r} Android clipboard text`,a);return a.stdout}function F(e){let t=e.replace(/\r\n/g,`
2
+ `).replace(/\n$/,``),n=t.match(/^clipboard text:\s*(.*)$/i);return n?n[1]??``:t.trim().toLowerCase()===`null`?``:t}export{A as a,N as c,_ as i,y as n,j as o,g as r,M as s,d as t};
@@ -1 +1 @@
1
- import{promises as e}from"node:fs";import t from"node:os";import i from"node:path";import{AppError as r}from"./485.js";import{isIosFamily as o,sortAppleDevicesForSelection as n}from"./6849.js";import{buildHostMacDevice as s}from"./devices~1.js";import{runXcrun as l,resolveAppleToolProvider as a,buildSimctlArgs as u}from"./9722.js";import{markSimulatorBooted as c}from"./simulator.js";import{resolveIosSimulatorDeviceSetPath as d}from"./3340.js";let p=/^(iphone|ipad|ipod|appletv|realitydevice)/i,f=/ipad/i,m=/\b(apple vision|vision pro|xros|visionos|realitydevice)\b/i,v=/\b(iphone|ipad|ipod)\b/i,_=/^appletv/i,h=["apple tv","appletv","tvos"],S=/^==\s*(.+?)\s*==$/,w=/^(?<name>.+?)\s+\[(?<id>[^[\]]+)\]\s*$/;function P(e){return(e??"").trim().toLowerCase()}function y(e){return P(e.hardwareProperties?.platform)}function C(e){return e.includes("tvos")}function b(e){let t=P(e);return h.some(e=>t.includes(e))}function O(e,t){return"tv"===e?"tvos":t.some(e=>m.test(e))?"visionos":t.some(e=>f.test(e))?"ipados":"ios"}function A(e){return[e.name??"",e.deviceProperties?.name??"",e.deviceProperties?.deviceType??""]}function N(e){return e.hardwareProperties?.productType??e.deviceProperties?.productType??""}async function K(e={}){let t,i,r=d(e.simulatorSetPath),o=e.target;try{t=await l(u(["list","devices","-j"],{simulatorSetPath:r}))}catch{return null}try{i=JSON.parse(t.stdout)}catch{return null}return n(M(i,r)).find(e=>!o||e.target===o)??null}function M(e,t){let i=[];for(let[r,o]of Object.entries(e.devices))if(function(e){let t=P(e);return t.includes("ios")||t.includes("tvos")||t.includes("xros")||t.includes("visionos")}(r))for(let e of o){if(!e.isAvailable)continue;let o=C(P(r))?"tv":"mobile",n={platform:"apple",id:e.udid,name:e.name,kind:"simulator",target:o,appleOs:O(o,[e.deviceTypeIdentifier??"",e.name]),booted:"Booted"===e.state,...t?{simulatorSetPath:t}:{}};n.booted&&c(n),i.push(n)}return i}function x(e,t){let i=new Set(e.map(e=>e.id)),r=[...e];for(let e of t)i.has(e.id)||(i.add(e.id),r.push(e));return r}async function E(){let r=null;try{r=i.join(t.tmpdir(),`agent-device-devicectl-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);let o=await l(["devicectl","list","devices","--json-output",r],{allowFailure:!0,timeoutMs:8e3});if(0!==o.exitCode)return[];let n=await e.readFile(r,"utf8");return function(e){let t=[];for(let i of e.result?.devices??[]){if(!function(e){var t,i;let r=y(e);return!!(r.includes("ios")||r.includes("tvos")||(t=r).includes("xros")||t.includes("visionos"))||(i=N(e),!!p.test(i.trim())||A(e).some(b))}(i))continue;let e=i.hardwareProperties?.udid??i.identifier??"",r=i.name??i.deviceProperties?.name??e;if(!e)continue;let o=function(e){var t;return C(y(e))?"tv":(t=N(e),_.test(t.trim())||A(e).some(b))?"tv":"mobile"}(i);t.push({platform:"apple",id:e,name:r,kind:"device",target:o,appleOs:O(o,[N(i),...A(i)]),booted:!0})}return t}(JSON.parse(n))}catch{return[]}finally{r&&await e.rm(r,{force:!0}).catch(()=>{})}}async function R(){try{let e=await l(["xctrace","list","devices"],{allowFailure:!0});if(0!==e.exitCode)return[];return function(e){let t=[],i=null;for(let r of e.split(/\r?\n/)){let e=r.trim();if(!e)continue;let o=S.exec(e);if(o){i=o[1]?.trim()??null;continue}if("Devices"!==i)continue;let n=w.exec(e),s=n?.groups?.id?.trim()??"",l=n?.groups?.name?.trim()??"";if(!s||!l)continue;let a=function(e){return b(e)?"tv":v.test(e.trim())||m.test(e)?"mobile":null}(l);a&&t.push({platform:"apple",id:s,name:l,kind:"device",target:a,appleOs:O(a,[l]),booted:!0})}return t}(e.stdout)}catch{return[]}}async function T(e={}){if("darwin"!==process.platform)throw new r("UNSUPPORTED_PLATFORM","Apple tools are only available on macOS");if(!await a().whichCommand("xcrun"))throw new r("TOOL_MISSING","xcrun not found in PATH");let t=d(e.simulatorSetPath),i=await l(u(["list","devices","-j"],{simulatorSetPath:t})),c=[];try{let e=JSON.parse(i.stdout);c=M(e,t)}catch(e){throw new r("COMMAND_FAILED","Failed to parse simctl devices JSON",void 0,e)}if(c.push(s()),e.udid&&c.some(t=>o(t)&&t.id===e.udid))return c;if(t)return n(c);let[p,f]=await Promise.all([E(),R()]);return c=x(c,p),n(x(c,f))}export{K as findBootableIosSimulator,T as listAppleDevices};
1
+ import e from"node:os";function t(){return{platform:`apple`,id:`host-macos-local`,name:e.hostname(),kind:`device`,target:`desktop`,appleOs:`macos`,booted:!0}}async function n(){return[t()]}export{t as buildHostMacDevice,n as listMacosDevices};
@@ -0,0 +1 @@
1
+ import{F as e,p as t,w as n}from"./sdk-contracts.js";import{x as r}from"./android-input-ownership.js";import{i,o as a}from"./tool-provider.js";import{t as o}from"./simctl.js";import{r as s}from"./simulator.js";import{buildHostMacDevice as c}from"./devices.js";import{promises as l}from"node:fs";import u from"node:os";import d from"node:path";const f=/^(iphone|ipad|ipod|appletv|realitydevice)/i,p=/ipad/i,m=/\b(apple vision|vision pro|xros|visionos|realitydevice)\b/i,h=/\b(iphone|ipad|ipod)\b/i,g=/^appletv/i,_=[`apple tv`,`appletv`,`tvos`],v=/^==\s*(.+?)\s*==$/,y=/^(?<name>.+?)\s+\[(?<id>[^[\]]+)\]\s*$/;function b(e){return(e??``).trim().toLowerCase()}function x(e){return b(e)}function S(e){return b(e.hardwareProperties?.platform)}function C(e){return e.includes(`tvos`)}function w(e){return e.includes(`xros`)||e.includes(`visionos`)}function T(e){return C(x(e))?`tv`:`mobile`}function E(e){let t=x(e);return t.includes(`ios`)||t.includes(`tvos`)||t.includes(`xros`)||t.includes(`visionos`)}function D(e){let t=b(e);return _.some(e=>t.includes(e))}function O(e){return h.test(e.trim())}function k(e){return D(e)?`tv`:O(e)||m.test(e)?`mobile`:null}function A(e,t){return e===`tv`?`tvos`:t.some(e=>m.test(e))?`visionos`:t.some(e=>p.test(e))?`ipados`:`ios`}function j(e){return f.test(e.trim())}function M(e){return g.test(e.trim())}function N(e){return[e.name??``,e.deviceProperties?.name??``,e.deviceProperties?.deviceType??``]}function P(e){return e.hardwareProperties?.productType??e.deviceProperties?.productType??``}function F(e){return C(S(e))||M(P(e))||N(e).some(D)?`tv`:`mobile`}function I(e){let t=S(e);return t.includes(`ios`)||t.includes(`tvos`)||w(t)||j(P(e))?!0:N(e).some(D)}async function L(e={}){let t=r(e.simulatorSetPath),i=e.target,s;try{s=await a(o([`list`,`devices`,`-j`],{simulatorSetPath:t}))}catch{return null}let c;try{c=JSON.parse(s.stdout)}catch{return null}return n(R(c,t)).find(e=>!i||e.target===i)??null}function R(e,t){let n=[];for(let[r,i]of Object.entries(e.devices))if(E(r))for(let e of i){if(!e.isAvailable)continue;let i=T(r),a={platform:`apple`,id:e.udid,name:e.name,kind:`simulator`,target:i,appleOs:A(i,[e.deviceTypeIdentifier??``,e.name]),booted:e.state===`Booted`,...t?{simulatorSetPath:t}:{}};a.booted&&s(a),n.push(a)}return n}function z(e){let t=[];for(let n of e.result?.devices??[]){if(!I(n))continue;let e=n.hardwareProperties?.udid??n.identifier??``,r=n.name??n.deviceProperties?.name??e;if(!e)continue;let i=F(n);t.push({platform:`apple`,id:e,name:r,kind:`device`,target:i,appleOs:A(i,[P(n),...N(n)]),booted:!0})}return t}function B(e){let t=[],n=null;for(let r of e.split(/\r?\n/)){let e=r.trim();if(!e)continue;let i=v.exec(e);if(i){n=i[1]?.trim()??null;continue}if(n!==`Devices`)continue;let a=y.exec(e),o=a?.groups?.id?.trim()??``,s=a?.groups?.name?.trim()??``;if(!o||!s)continue;let c=k(s);c&&t.push({platform:`apple`,id:o,name:s,kind:`device`,target:c,appleOs:A(c,[s]),booted:!0})}return t}function V(e,t){let n=new Set(e.map(e=>e.id)),r=[...e];for(let e of t)n.has(e.id)||(n.add(e.id),r.push(e));return r}async function H(){let e=null;try{if(e=d.join(u.tmpdir(),`agent-device-devicectl-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`),(await a([`devicectl`,`list`,`devices`,`--json-output`,e],{allowFailure:!0,timeoutMs:8e3})).exitCode!==0)return[];let t=await l.readFile(e,`utf8`);return z(JSON.parse(t))}catch{return[]}finally{e&&await l.rm(e,{force:!0}).catch(()=>{})}}async function U(){try{let e=await a([`xctrace`,`list`,`devices`],{allowFailure:!0});return e.exitCode===0?B(e.stdout):[]}catch{return[]}}async function W(s={}){if(process.platform!==`darwin`)throw new e(`UNSUPPORTED_PLATFORM`,`Apple tools are only available on macOS`);if(!await i().whichCommand(`xcrun`))throw new e(`TOOL_MISSING`,`xcrun not found in PATH`);let l=r(s.simulatorSetPath),u=await a(o([`list`,`devices`,`-j`],{simulatorSetPath:l})),d=[];try{d=R(JSON.parse(u.stdout),l)}catch(t){throw new e(`COMMAND_FAILED`,`Failed to parse simctl devices JSON`,void 0,t)}if(d.push(c()),s.udid&&d.some(e=>t(e)&&e.id===s.udid))return d;if(l)return n(d);let[f,p]=await Promise.all([H(),U()]);return d=V(d,f),n(V(d,p))}export{L as findBootableIosSimulator,W as listAppleDevices};
@@ -0,0 +1 @@
1
+ import{hostname as e}from"node:os";async function t(){return process.platform===`linux`?[{platform:`linux`,id:`local`,name:e(),kind:`device`,target:`desktop`,booted:!0}]:[]}export{t as listLinuxDevices};
package/dist/src/find.js CHANGED
@@ -1 +1 @@
1
- import{errorResponse as e,stripInternalInteractionFlags as t,dispatchCommand as r,noActiveSessionError as n,resolveTargetDevice as a,context_contextFromFlags as o}from"./9722.js";import{parseFindSelectorExpression as i,findBestMatchesByLocator as s,parseFindArgs as l}from"./587.js";import{ensureDeviceReady as c}from"./8414.js";import{dispatchFindReadOnlyViaRuntime as f,readTextForNode as d,createSelectorCaptureRuntime as u}from"./selector-runtime.js";import{resolveActionableTouchResolution as _,isSparseSnapshotQualityVerdict as h,isSnapshotNodeInteractionBlocked as p,resolveActionableTouchNode as m}from"./2948.js";import{resolveSelectorChain as g,extractNodeText as y}from"./893.js";import{centerOfRect as A}from"./6849.js";import{sleep as w}from"./5560.js";import{recordSessionAction as S}from"./handler-utils.js";async function k(r){var o,d,p,w;let S,{req:k,sessionName:U,logPath:b,sessionStore:P,invoke:H}=r,q=k.command;if("find"!==q)return null;let O=k.positionals??[];if(0===O.length)return e("INVALID_ARGS","find requires a locator or text");let{locator:$,query:B,action:G,value:V,timeoutMs:Q}=l(O);if(!B)return e("INVALID_ARGS","find requires a value");if(k.flags?.findFirst&&k.flags?.findLast)return e("INVALID_ARGS","find accepts only one of --first or --last");let T=await f({req:k,sessionName:U,logPath:b,sessionStore:P});if(T)return T;let j=P.get(U),z="exists"===(o=G)||"wait"===o||"get_text"===o||"get_attrs"===o;if(!j&&!z)return n();let J=j?.device??await a(k.flags??{});j||await c(J);let W="click"===(d=G)||"focus"===d||"fill"===d||"type"===d,X=i($,B),Y="web"!==J.platform&&!X&&L($)&&!W?B:void 0,Z=function(e){let{device:t,session:r,req:n,logPath:a,locator:o,query:i,scope:s,interactiveOnly:l}=e,{sessionStore:c,sessionName:f}=e,d=u({device:t,session:r,sessionStore:c,sessionName:f,req:n,logPath:a});return async()=>{let{snapshot:e}=await d.capture({flags:{...n.flags,snapshotInteractiveOnly:l},snapshotScope:s,recovery:l?{legacyIosSparse:{query:i,scope:s,shouldScope:L(o)},sparseVerdictQueryScope:{query:i,shouldScope:L(o)}}:void 0});return{nodes:e.nodes,truncated:e.truncated,backend:e.backend,snapshotQuality:e.snapshotQuality}}}({device:J,session:j,req:k,logPath:b,locator:$,query:B,scope:Y,interactiveOnly:W,sessionStore:P,sessionName:U}),ee={req:k,sessionName:U,logPath:b,sessionStore:P,invoke:H,session:j,device:J,command:q,locator:$,query:B,publicFlags:{...t(k.flags)??{}}};if("wait"===G)return N(ee,Z,$,B,Q);let et=await Z();if(h(et.snapshotQuality))return C(et.snapshotQuality);let{nodes:er}=et,en=function(t){let{nodes:r,locator:n,query:a,selectorChain:o,requiresRect:i,flags:l,platform:c}=t,f=i?r.filter(e=>!v(e,r[0])):r;if(o){let t=g(f,o,{platform:c,requireRect:i,requireUnique:!1});return t?{ok:!0,node:t.node}:{ok:!1,response:e("COMMAND_FAILED","find did not match any element")}}let d=s(f,n,a,{requireRect:i});if(i&&(d.matches=function(e,t){var r,n;let a=t[0]?.rect;if(!a)return e;let o=e.filter(e=>{if(!e.rect)return!1;let t=A(e.rect);return t.x>=a.x&&t.x<=a.x+a.width&&t.y>=a.y&&t.y<=a.y+a.height});return r=o.length>0?o:e,n=t,r.length<2?r:r.map((e,t)=>({node:e,index:t,score:function(e,t){var r,n;let a=_(t,e);if("covered"===a.reason)return 0;let o=(r=a,n=t[0],r.node.rect?"semantic-target"===r.reason||"same-rect-descendant"===r.reason?4:2*!("hittable-ancestor"!==r.reason||v(r.node,n)):0);return o>0?o:e.hittable&&e.rect&&!v(e,t[0])?3:+!!e.rect}(e,n)})).sort((e,t)=>t.score!==e.score?t.score-e.score:M(e.node)-M(t.node)||e.index-t.index).map(e=>e.node)}(d.matches,r)),i&&d.matches.length>1){var u,h,p,m,w;let t=(u=d.matches,h=l,h?.findFirst?[u[0]]:h?.findLast?[u[u.length-1]]:null);if(!t){let t;return{ok:!1,response:(p=d.matches,m=n,w=a,t=p.slice(0,8).map(e=>{let t=y(e)||e.label||e.identifier||e.type||"";return`@${e.ref}${t?`(${t})`:""}`}),e("AMBIGUOUS_MATCH",`find matched ${p.length} elements for ${m} "${w}". Use a more specific locator or selector.`,{locator:m,query:w,matches:p.length,candidates:t}))}}d.matches=t}let S=d.matches[0]??null;return S?{ok:!0,node:S}:{ok:!1,response:e("COMMAND_FAILED","find did not match any element")}}({nodes:er,locator:$,query:B,selectorChain:X,requiresRect:W,flags:k.flags,platform:J.platform});if(!en.ok)return en.response;let ea=en.node,eo=W?v(S=m(p=er,w=ea),p[0])&&w.rect?w:S:ea,ei=`@${eo.ref}`,es={node:ea,resolvedNode:eo,ref:ei,nodes:er,actionFlags:{...k.flags??{},noRecord:!0}},el={exists:()=>I(ee),get_text:()=>x(ee,es),get_attrs:()=>D(ee,es),click:()=>K(ee,es),fill:()=>R(ee,es,V),focus:()=>E(ee,es),type:()=>F(ee,es,V)}[G];return el?el():null}function C(t){return e("COMMAND_FAILED","find could not read the current accessibility tree",{reason:t.reason,hint:"The snapshot quality verdict is sparse. Use screenshot as visual truth, navigate with coordinates if needed, then retry find after reaching a readable screen."})}function M(e){return e.rect?e.rect.width*e.rect.height:1/0}function v(e,t){var r,n;if(!t?.rect||!e.rect)return!1;let a=e.type?.toLowerCase()??"";return(!!a.includes("application")||!!a.includes("window"))&&(r=e.rect,n=t.rect,r.x===n.x&&r.y===n.y&&r.width===n.width&&r.height===n.height)}async function N(t,r,n,a,o){let i,{req:l,sessionStore:c,session:f,command:d,publicFlags:u}=t,_=o??1e4,p=Date.now();for(;Date.now()-p<_;){let{nodes:e,snapshotQuality:t}=await r();if(h(t)){i=t,await w(300);continue}if(s(e,n,a,{requireRect:!1}).matches[0])return S(c,f,l,d,{found:!0,waitedMs:Date.now()-p},{flags:u}),{ok:!0,data:{found:!0,waitedMs:Date.now()-p}};await w(300)}return i?C(i):e("COMMAND_FAILED","find wait timed out")}async function I(e){let{req:t,sessionStore:r,session:n,command:a,publicFlags:o}=e;return S(r,n,t,a,{found:!0},{flags:o}),{ok:!0,data:{found:!0}}}async function x(e,t){let{req:r,sessionStore:n,session:a,command:i,device:s,logPath:l,publicFlags:c}=e,f=await d({device:s,node:t.node,flags:r.flags,appBundleId:a?.appBundleId,traceOutPath:a?.trace?.outPath,surface:a?.surface,contextFromFlags:(e,t,r)=>o(l,e,t,r)});return S(n,a,r,i,{ref:t.ref,action:"get text",text:f},{flags:c}),{ok:!0,data:{ref:t.ref,text:f,node:t.node}}}async function D(e,t){let{req:r,sessionStore:n,session:a,command:o,publicFlags:i}=e;return S(n,a,r,o,{ref:t.ref,action:"get attrs"},{flags:i}),{ok:!0,data:{ref:t.ref,node:t.node}}}async function K(e,t){let{req:r,sessionName:n,sessionStore:a,session:o,invoke:i,command:s,locator:l,query:c,publicFlags:f}=e,d=await i({token:r.token,session:n,command:"click",positionals:[t.ref],flags:t.actionFlags});if(!d.ok)return d;let u=t.resolvedNode.rect?A(t.resolvedNode.rect):t.node.rect?A(t.node.rect):null,_={ref:t.ref,locator:l,query:c};return u&&(_.x=u.x,_.y=u.y),S(a,o,r,s,{ref:t.ref,action:"click",locator:l,query:c},{flags:f}),{ok:!0,data:_}}async function R(t,r,n){let{req:a,sessionName:o,sessionStore:i,session:s,invoke:l,command:c,publicFlags:f}=t;if(!n)return e("INVALID_ARGS","find fill requires text");let d=await l({token:a.token,session:o,command:"fill",positionals:[r.ref,n],flags:r.actionFlags});return d.ok&&S(i,s,a,c,{ref:r.ref,action:"fill"},{flags:f}),d}async function E(e,t){let r=await U(e,t);return r.ok&&b(e,t,"focus"),r}async function F(t,n,a){let{req:i,device:s,logPath:l,session:c}=t;if(!a)return e("INVALID_ARGS","find type requires text");let f=await U(t,n);if(!f.ok)return f;let d=await r(s,"type",[a],i.flags?.out,{...o(l,i.flags,c?.appBundleId,c?.trace?.outPath)});return b(t,n,"type"),{ok:!0,data:d??{ref:n.ref}}}async function U(t,n){var a;let i,{req:s,device:l,logPath:c,session:f}=t,d=(i=[(a=n).resolvedNode,a.node].find(p))?e("COMMAND_FAILED",`Matched element ${a.ref} is covered by another visible element and cannot be focused safely`,{ref:`@${i.ref}`,interactionBlocked:i.interactionBlocked,hint:"Use a different visible target, scroll it clear of the overlay, or inspect with snapshot/screenshot before retrying."}):null;if(d)return d;let u=n.resolvedNode.rect?A(n.resolvedNode.rect):null;return u?{ok:!0,data:await r(l,"focus",[String(u.x),String(u.y)],s.flags?.out,{...o(c,s.flags,f?.appBundleId,f?.trace?.outPath)})??{ref:n.ref}}:e("COMMAND_FAILED","matched element has no bounds")}function b(e,t,r){let{req:n,sessionStore:a,session:o,command:i,publicFlags:s}=e;S(a,o,n,i,{ref:t.ref,action:r},{flags:s})}function L(e){return"role"!==e}export{parseFindArgs}from"./587.js";export{k as handleFindCommands};
1
+ import{O as e}from"./sdk-contracts.js";import{Cn as t,F as n,G as r,I as i,wn as a}from"./tv-remote.js";import{t as o}from"./timeouts.js";import{d as s}from"./sdk-selectors.js";import{t as c}from"./snapshot-quality.js";import{a as l,o as u,r as d}from"./sdk-finders.js";import{a as f}from"./selectors2.js";import{$t as p,Gt as m,Rt as h,en as g,kt as _,ln as v,zt as y}from"./internal/daemon.js";import{a as b}from"./apple-runner-options.js";import{a as x,t as S,w as C}from"./selector-runtime.js";import{t as w}from"./handler-utils.js";async function T(e){let{req:t,sessionName:n,logPath:r,sessionStore:i,invoke:a}=e,o=t.command;if(o!==`find`)return null;let s=t.positionals??[];if(s.length===0)return p(`INVALID_ARGS`,`find requires a locator or text`);let{locator:d,query:f,action:m,value:h,timeoutMs:y}=l(s);if(!f)return p(`INVALID_ARGS`,`find requires a value`);if(t.flags?.findFirst&&t.flags?.findLast)return p(`INVALID_ARGS`,`find accepts only one of --first or --last`);let x=await S({req:t,sessionName:n,logPath:r,sessionStore:i});if(x)return x;let C=i.get(n),w=D(m);if(!C&&!w)return g();let T=C?.device??await v(t.flags??{});C||await b(T);let j=O(m),M=u(d,f),N=ee({device:T,session:C,req:t,logPath:r,locator:d,query:f,scope:T.platform!==`web`&&!M&&$(d)&&!j?f:void 0,interactiveOnly:j,sessionStore:i,sessionName:n}),P={req:t,sessionName:n,logPath:r,sessionStore:i,invoke:a,session:C,device:T,command:o,locator:d,query:f,publicFlags:Z(t.flags)};if(m===`wait`)return B(P,N,d,f,y);let F=await N();if(c(F.snapshotQuality))return k(F.snapshotQuality);let{nodes:I}=F,R=A({nodes:I,locator:d,query:f,selectorChain:M,requiresRect:j,flags:t.flags,platform:T.platform});if(!R.ok)return R.response;let z=R.node,J=j?L(I,z):z,Y={node:z,resolvedNode:J,ref:`@${J.ref}`,nodes:I,actionFlags:{...t.flags??{},noRecord:!0}};C&&(_(C),i.set(n,C));let X={exists:()=>V(P),get_text:()=>H(P,Y),get_attrs:()=>U(P,Y),click:()=>W(P,Y),fill:()=>G(P,Y,h),focus:()=>K(P,Y),type:()=>q(P,Y,h)}[m];return X?E(await X(),()=>i.get(n)):null}function E(e,t){if(!e?.ok||!e.data||typeof e.data.ref!=`string`)return e;let n=t()?.snapshotGeneration;return n===void 0?e:{...e,data:{...e.data,refsGeneration:n}}}function D(e){return e===`exists`||e===`wait`||e===`get_text`||e===`get_attrs`}function O(e){return e===`click`||e===`focus`||e===`fill`||e===`type`}function ee(e){let{device:t,session:n,req:r,logPath:i,locator:a,query:o,scope:s,interactiveOnly:c}=e,{sessionStore:l,sessionName:u}=e,d=x({device:t,session:n,sessionStore:l,sessionName:u,req:r,logPath:i});return async()=>{let{snapshot:e}=await d.capture({flags:{...r.flags,snapshotInteractiveOnly:c},snapshotScope:s,recovery:c?{legacyIosSparse:{query:o,scope:s,shouldScope:$(a)},sparseVerdictQueryScope:{query:o,shouldScope:$(a)}}:void 0});return{nodes:e.nodes,truncated:e.truncated,backend:e.backend,snapshotQuality:e.snapshotQuality}}}function k(e){return p(`COMMAND_FAILED`,`find could not read the current accessibility tree`,{reason:e.reason,hint:`The snapshot quality verdict is sparse. Use screenshot as visual truth, navigate with coordinates if needed, then retry find after reaching a readable screen.`})}function A(e){let{nodes:t,locator:n,query:r,selectorChain:i,requiresRect:a,flags:o,platform:s}=e,c=a?t.filter(e=>!R(e,t[0])):t;if(i){let e=f(c,i,{platform:s,requireRect:a,requireUnique:!1});return e?{ok:!0,node:e.node}:{ok:!1,response:p(`COMMAND_FAILED`,`find did not match any element`)}}let l=d(c,n,r,{requireRect:a});if(a&&(l.matches=M(l.matches,t)),a&&l.matches.length>1){let e=j(l.matches,o);if(!e)return{ok:!1,response:Q(l.matches,n,r)};l.matches=e}let u=l.matches[0]??null;return u?{ok:!0,node:u}:{ok:!1,response:p(`COMMAND_FAILED`,`find did not match any element`)}}function j(e,t){return t?.findFirst?[e[0]]:t?.findLast?[e[e.length-1]]:null}function M(t,n){let r=n[0]?.rect;if(!r)return t;let i=t.filter(t=>{if(!t.rect)return!1;let n=e(t.rect);return n.x>=r.x&&n.x<=r.x+r.width&&n.y>=r.y&&n.y<=r.y+r.height});return N(i.length>0?i:t,n)}function N(e,t){return e.length<2?e:e.map((e,n)=>({node:e,index:n,score:P(e,t)})).sort((e,t)=>t.score===e.score?I(e.node)-I(t.node)||e.index-t.index:t.score-e.score).map(e=>e.node)}function P(e,t){let n=i(t,e);if(n.reason===`covered`)return 0;let r=F(n,t[0]);return r>0?r:e.hittable&&e.rect&&!R(e,t[0])?3:+!!e.rect}function F(e,t){return e.node.rect?e.reason===`semantic-target`||e.reason===`same-rect-descendant`?4:e.reason===`hittable-ancestor`&&!R(e.node,t)?2:0:0}function I(e){return e.rect?e.rect.width*e.rect.height:1/0}function L(e,t){let r=n(e,t);return R(r,e[0])&&t.rect?t:r}function R(e,t){if(!t?.rect||!e.rect)return!1;let n=e.type?.toLowerCase()??``;return!n.includes(`application`)&&!n.includes(`window`)?!1:z(e.rect,t.rect)}function z(e,t){return e.x===t.x&&e.y===t.y&&e.width===t.width&&e.height===t.height}async function B(e,t,n,r,i){let{req:a,sessionStore:s,session:l,command:u,publicFlags:f}=e,m=i??1e4,h=Date.now(),g;for(;Date.now()-h<m;){let{nodes:e,snapshotQuality:i}=await t();if(c(i)){g=i,await o(300);continue}if(d(e,n,r,{requireRect:!1}).matches[0])return w(s,l,a,u,{found:!0,waitedMs:Date.now()-h},{flags:f}),{ok:!0,data:{found:!0,waitedMs:Date.now()-h}};await o(300)}return g?k(g):p(`COMMAND_FAILED`,`find wait timed out`)}async function V(e){let{req:t,sessionStore:n,session:r,command:i,publicFlags:a}=e;return w(n,r,t,i,{found:!0},{flags:a}),{ok:!0,data:{found:!0}}}async function H(e,t){let{req:n,sessionStore:r,session:i,command:a,device:o,logPath:s,publicFlags:c}=e,l=await C({device:o,node:t.node,flags:n.flags,appBundleId:i?.appBundleId,traceOutPath:i?.trace?.outPath,surface:i?.surface,contextFromFlags:(e,t,n)=>y(s,e,t,n)});return w(r,i,n,a,{ref:t.ref,action:`get text`,text:l},{flags:c}),{ok:!0,data:{ref:t.ref,text:l,node:t.node}}}async function U(e,t){let{req:n,sessionStore:r,session:i,command:a,publicFlags:o}=e;return w(r,i,n,a,{ref:t.ref,action:`get attrs`},{flags:o}),{ok:!0,data:{ref:t.ref,node:t.node}}}async function W(n,r){let{req:i,sessionName:o,sessionStore:s,session:c,invoke:l,command:u,locator:d,query:f,publicFlags:p}=n,m=await l({token:i.token,session:o,command:`click`,positionals:[r.ref],flags:r.actionFlags});if(!m.ok)return m;let h=r.resolvedNode.rect?e(r.resolvedNode.rect):r.node.rect?e(r.node.rect):null,g={ref:r.ref,locator:d,query:f};h&&(g.x=h.x,g.y=h.y);let _=t(m.data)??`Tapped ${r.ref}${h?` (${h.x}, ${h.y})`:``}`;return Object.assign(g,a(_)),w(s,c,i,u,{ref:r.ref,action:`click`,locator:d,query:f},{flags:p}),{ok:!0,data:g}}async function G(e,t,n){let{req:r,sessionName:i,sessionStore:a,session:o,invoke:s,command:c,publicFlags:l}=e;if(!n)return p(`INVALID_ARGS`,`find fill requires text`);let u=await s({token:r.token,session:i,command:`fill`,positionals:[t.ref,n],flags:t.actionFlags});return u.ok&&w(a,o,r,c,{ref:t.ref,action:`fill`},{flags:l}),u}async function K(e,t){let n=await J(e,t);return n.ok&&X(e,t,`focus`),n}async function q(e,t,n){let{req:r,device:i,logPath:a,session:o}=e;if(!n)return p(`INVALID_ARGS`,`find type requires text`);let s=await J(e,t);if(!s.ok)return s;let c=await m(i,`type`,[n],r.flags?.out,{...y(a,r.flags,o?.appBundleId,o?.trace?.outPath)});return X(e,t,`type`),{ok:!0,data:c??{ref:t.ref}}}async function J(t,n){let{req:r,device:i,logPath:a,session:o}=t,s=Y(n,`be focused`);if(s)return s;let c=n.resolvedNode.rect?e(n.resolvedNode.rect):null;return c?{ok:!0,data:await m(i,`focus`,[String(c.x),String(c.y)],r.flags?.out,{...y(a,r.flags,o?.appBundleId,o?.trace?.outPath)})??{ref:n.ref}}:p(`COMMAND_FAILED`,`matched element has no bounds`)}function Y(e,t){let n=[e.resolvedNode,e.node].find(r);return n?p(`COMMAND_FAILED`,`Matched element ${e.ref} is covered by another visible element and cannot ${t} safely`,{ref:`@${n.ref}`,interactionBlocked:n.interactionBlocked,hint:`Use a different visible target, scroll it clear of the overlay, or inspect with snapshot/screenshot before retrying.`}):null}function X(e,t,n){let{req:r,sessionStore:i,session:a,command:o,publicFlags:s}=e;w(i,a,r,o,{ref:t.ref,action:n},{flags:s})}function Z(e){return{...h(e)??{}}}function Q(e,t,n){let r=e.slice(0,8).map(e=>{let t=s(e)||e.label||e.identifier||e.type||``;return`@${e.ref}${t?`(${t})`:``}`});return p(`AMBIGUOUS_MATCH`,`find matched ${e.length} elements for ${t} "${n}". Use a more specific locator or selector.`,{locator:t,query:n,matches:e.length,candidates:r})}function $(e){return e!==`role`}export{T as handleFindCommands,l as parseFindArgs};