agent-device 0.20.3 → 0.20.4

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 (140) hide show
  1. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.3.apk → agent-device-android-ime-helper-0.20.4.apk} +0 -0
  2. package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.4.apk.sha256 +1 -0
  3. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.3.manifest.json → agent-device-android-ime-helper-0.20.4.manifest.json} +4 -4
  4. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.4.apk +0 -0
  5. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.4.apk.sha256 +1 -0
  6. package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.3.manifest.json → agent-device-android-snapshot-helper-0.20.4.manifest.json} +6 -6
  7. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +57 -4
  8. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +45 -9
  9. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Keyboard.swift +73 -0
  10. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Navigation.swift +1 -0
  11. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollGesture.swift +3 -2
  12. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SequenceExecution.swift +1 -1
  13. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedGesturePolicy.swift +8 -2
  14. package/dist/src/agent-browser-tool.js +1 -1
  15. package/dist/src/agent-device-client.js +2 -2
  16. package/dist/src/android-adb.d.ts +1 -1
  17. package/dist/src/android.js +1 -1
  18. package/dist/src/app-helpers.js +1 -1
  19. package/dist/src/app-inventory.d.ts +4 -0
  20. package/dist/src/app-lifecycle.js +7 -7
  21. package/dist/src/app-resolution.js +1 -1
  22. package/dist/src/apps.js +5 -5
  23. package/dist/src/boot-diagnostics.js +1 -1
  24. package/dist/src/cli-config.js +1 -1
  25. package/dist/src/cli-help.js +27 -19
  26. package/dist/src/cli-runner.js +1 -1
  27. package/dist/src/cli.js +15 -14
  28. package/dist/src/client-metro.js +1 -1
  29. package/dist/src/{tv-remote.d.ts → cloud-artifacts.d.ts} +109 -126
  30. package/dist/src/command-metadata.js +1 -1
  31. package/dist/src/command-schema.js +1 -1
  32. package/dist/src/command-surface.js +1 -1
  33. package/dist/src/context.js +1 -1
  34. package/dist/src/contracts.d.ts +1 -1
  35. package/dist/src/debug-symbols.js +4 -4
  36. package/dist/src/device-input-state.d.ts +2 -2
  37. package/dist/src/device-input-state.js +1 -1
  38. package/dist/src/device.js +1 -9
  39. package/dist/src/devices2.js +1 -1
  40. package/dist/src/entities.js +1 -0
  41. package/dist/src/find.js +1 -1
  42. package/dist/src/finders.d.ts +1 -1
  43. package/dist/src/finders.js +1 -1
  44. package/dist/src/generic.js +1 -1
  45. package/dist/src/helper.js +2 -2
  46. package/dist/src/ime-lifecycle.js +9 -0
  47. package/dist/src/index.d.ts +592 -555
  48. package/dist/src/input-actions.js +4 -4
  49. package/dist/src/install-artifact.js +4 -4
  50. package/dist/src/install-artifact2.js +1 -1
  51. package/dist/src/install-source2.js +1 -1
  52. package/dist/src/interaction-snapshot.js +1 -1
  53. package/dist/src/interaction.d.ts +7 -4
  54. package/dist/src/interaction.js +1 -1
  55. package/dist/src/interactor.js +2 -2
  56. package/dist/src/interactor2.js +1 -1
  57. package/dist/src/internal/bin.js +1 -1
  58. package/dist/src/internal/daemon.js +14 -14
  59. package/dist/src/internal/png-worker.js +1 -1
  60. package/dist/src/lease-context.js +1 -1
  61. package/dist/src/lease.js +1 -1
  62. package/dist/src/limrun.d.ts +103 -198
  63. package/dist/src/limrun.js +1 -1
  64. package/dist/src/linux.js +1 -1
  65. package/dist/src/logcat.js +1 -1
  66. package/dist/src/manifest.js +1 -1
  67. package/dist/src/metro.d.ts +1 -1
  68. package/dist/src/parser.js +2 -0
  69. package/dist/src/path-resolution.js +1 -1
  70. package/dist/src/physical-device-control.js +1 -1
  71. package/dist/src/plist-xml.js +1 -0
  72. package/dist/src/plist.js +1 -1
  73. package/dist/src/png-worker-contract.js +1 -1
  74. package/dist/src/process-lock.js +1 -1
  75. package/dist/src/provider-limrun-runtime.js +1 -0
  76. package/dist/src/react-native.js +1 -1
  77. package/dist/src/record-trace.js +1 -1
  78. package/dist/src/register-builtins.js +1 -1
  79. package/dist/src/registry.js +22 -22
  80. package/dist/src/remote-config2.js +1 -1
  81. package/dist/src/reporting.js +7 -7
  82. package/dist/src/runner-client.js +1 -1
  83. package/dist/src/runner-disposal.js +1 -1
  84. package/dist/src/runner-lease.js +1 -1
  85. package/dist/src/runner-provider.js +1 -1
  86. package/dist/src/runner-sequence.js +1 -1
  87. package/dist/src/runtime-transport.js +1 -1
  88. package/dist/src/runtime.js +3 -3
  89. package/dist/src/screenshot-geometry.js +1 -0
  90. package/dist/src/screenshot-result.js +6 -0
  91. package/dist/src/sdk-android-adb.d.ts +5 -6
  92. package/dist/src/sdk-android-adb.js +3 -3
  93. package/dist/src/sdk-batch-runner.d.ts +2 -2
  94. package/dist/src/sdk-batch-runner.js +3 -3
  95. package/dist/src/sdk-contracts.d.ts +21 -25
  96. package/dist/src/sdk-contracts.js +2 -2
  97. package/dist/src/sdk-finders.d.ts +1 -1
  98. package/dist/src/sdk-finders.js +1 -1
  99. package/dist/src/sdk-io.js +1 -1
  100. package/dist/src/sdk-remote-config.d.ts +19 -4
  101. package/dist/src/sdk-remote-config.js +1 -1
  102. package/dist/src/sdk-selectors.js +1 -1
  103. package/dist/src/selector-runtime.js +1 -1
  104. package/dist/src/selector-vocabulary.js +1 -1
  105. package/dist/src/selectors.d.ts +1 -1
  106. package/dist/src/selectors.js +1 -1
  107. package/dist/src/server.js +2 -2
  108. package/dist/src/session-target-evidence.js +1 -1
  109. package/dist/src/session.js +8 -8
  110. package/dist/src/setting-state.js +1 -1
  111. package/dist/src/simulator.js +1 -1
  112. package/dist/src/snapshot.js +1 -1
  113. package/dist/src/snapshot2.js +1 -1
  114. package/dist/src/src.js +1 -0
  115. package/dist/src/tool-provider.js +3 -3
  116. package/dist/src/tool-provider2.js +1 -1
  117. package/dist/src/tool-provider3.js +1 -1
  118. package/dist/src/update-check.js +1 -1
  119. package/dist/src/version.js +1 -1
  120. package/dist/src/viewport-dimension.js +14 -0
  121. package/package.json +17 -7
  122. package/server.json +2 -2
  123. package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.3.apk.sha256 +0 -1
  124. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.3.apk +0 -0
  125. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.3.apk.sha256 +0 -1
  126. package/dist/src/android-input-method-overlays.js +0 -1
  127. package/dist/src/android-input-ownership.js +0 -1
  128. package/dist/src/apple-multitouch-support.js +0 -1
  129. package/dist/src/click-button.d.ts +0 -5
  130. package/dist/src/compatibility-policy.js +0 -1
  131. package/dist/src/gesture-plan-types.js +0 -1
  132. package/dist/src/gesture-plan.js +0 -1
  133. package/dist/src/launch-console.js +0 -1
  134. package/dist/src/recording-export-quality.js +0 -14
  135. package/dist/src/rolldown-runtime.js +0 -1
  136. package/dist/src/runtime2.js +0 -1
  137. package/dist/src/sdk-app-inventory.d.ts +0 -4
  138. package/dist/src/sdk-app-inventory.js +0 -1
  139. package/dist/src/snapshot-diagnostics.js +0 -6
  140. package/dist/src/xml.js +0 -2
package/dist/src/cli.js CHANGED
@@ -1,16 +1,17 @@
1
- import{S as e,_ as t,a as n,v as r}from"./sdk-contracts.js";import{A as i,L as a,M as o,N as s,S as c,j as l,v as u}from"./sdk-android-adb.js";import{Q as d,l as f,m as p}from"./sdk-batch-runner.js";import{$t as m,An as h,Dn as g,Ft as ee,Jt as te,On as _,Qt as v,Rt as ne,Yt as re,Zt as y,kn as ie,qt as ae,zt as oe}from"./recording-export-quality.js";import{_t as se,b,bt as ce,c as le,g as ue,gt as de,ht as fe,lt as pe,o as me,v as he,vt as ge,w as x}from"./snapshot-diagnostics.js";import{a as _e,i as ve,n as ye,o as be,r as xe}from"./agent-device-client.js";import{n as Se}from"./version.js";import{n as S}from"./path-resolution.js";import{h as Ce,i as we,s as Te,v as Ee}from"./sdk-device.js";import"./sdk-selectors.js";import{t as De}from"./timeouts.js";import{n as C,u as Oe}from"./host-process.js";import{_ as ke,l as Ae,v as je}from"./registry.js";import{v as Me}from"./url.js";import{a as Ne,i as Pe}from"./client-metro.js";import{n as Fe}from"./command-metadata.js";import{n as Ie}from"./metro2.js";import{t as Le}from"./sdk-remote-config.js";import{n as w,t as Re}from"./remote-config2.js";import"./gesture-plan.js";import{_ as T,a as ze,c as Be,d as Ve,g as E,i as He,n as Ue,o as We,v as Ge}from"./selector-vocabulary.js";import{i as Ke,n as qe,t as Je}from"./command-schema.js";import{t as Ye}from"./update-check.js";import{i as D,r as O,t as Xe}from"./cli-config.js";import{i as k,r as Ze,t as Qe}from"./cli-runner.js";import{t as $e}from"./compatibility-policy.js";import A,{randomBytes as et,randomUUID as tt}from"node:crypto";import j from"node:fs";import M from"node:path";import nt from"node:http";import{pipeline as rt}from"node:stream/promises";import{Readable as it}from"node:stream";import{pathToFileURL as at}from"node:url";import{stringify as ot}from"yaml";const st=new Map([{alias:`long-press`,command:`longpress`},{alias:`metrics`,command:`perf`},{alias:`tap`,command:`press`},{alias:`launch`,command:`open`},{alias:`relaunch`,command:`open`,impliedFlags:[`relaunch`]}].map(e=>[e.alias,e]));function ct(e){return st.get(e.toLowerCase())?.command??e}function lt(e){return st.get(e.toLowerCase())}const N=`open <app> --relaunch`,ut={start:{command:`open`,example:N},restart:{command:`open`,example:N},touch:{command:`press`,example:`press`},input:{command:`fill`,example:`fill`},settext:{command:`fill`,example:`fill`},entertext:{command:`fill`,example:`fill`},screencap:{command:`screenshot`,example:`screenshot`},capture:{command:`screenshot`,example:`screenshot`},dismiss:{command:`keyboard`,example:`keyboard dismiss`},"get-text":{command:`get`,example:`get text`},gettext:{command:`get`,example:`get text`},get_text:{command:`get`,example:`get text`},"open-url":{command:`open`,example:`open <url>`},"close-session":{command:`close`,example:`close`}};function dt(e){if(e.length<=2)return[];let t=h(),n=t.filter(t=>t.startsWith(e));if(n.length>0)return n.sort((e,t)=>e.length-t.length||e.localeCompare(t)).slice(0,3);let r=ft(e),i=t.map(t=>({name:t,distance:pt(e,t)})).filter(e=>e.distance<=r);if(i.length===0)return[];let a=Math.min(...i.map(e=>e.distance));return i.filter(e=>e.distance===a).sort((e,t)=>e.name.localeCompare(t.name)).slice(0,3).map(e=>e.name)}function ft(e){return e.length<4?1:e.length<=6?2:3}function pt(e,t){return e===t?0:e.startsWith(t)||t.startsWith(e)?Math.abs(e.length-t.length):mt(e,t)}function mt(e,t){let n=e.length+1,r=t.length+1,i=Array.from({length:n},()=>Array(r).fill(0));for(let e=0;e<n;e+=1)i[e][0]=e;for(let e=0;e<r;e+=1)i[0][e]=e;for(let a=1;a<n;a+=1)for(let n=1;n<r;n+=1){let r=e[a-1]===t[n-1]?0:1;i[a][n]=Math.min(i[a-1][n]+1,i[a][n-1]+1,i[a-1][n-1]+r)}return i[n-1][r-1]}function ht(e){let t=e.toLowerCase(),n=ut[t]?.example;if(n)return n;let r=dt(t);if(r.length!==0)return r.length===1?r[0]:`one of: ${r.join(`, `)}`}const gt=new Set([`--bundle-id`,`--bundleid`,`--bundle`,`--package`,`--package-name`,`--packagename`,`--app-id`,`--appid`,`--pkg`]),_t=new Set([`--session-locked`,`--session-lock-conflicts`]);function vt(e){return gt.has(e.toLowerCase())?`Unknown flag: ${e}. The app or bundle id is a positional argument, e.g. ${N}.`:_t.has(e.toLowerCase())?`Unknown flag: ${e}. Use --session-lock reject|strip instead.`:`Unknown flag: ${e}`}function yt(e){let n={json:!1,help:!1,version:!1},r=null,i=null,a=[],o=[],s=[],c=!0;for(let o=0;o<e.length;o+=1){let l=e[o];if(c&&l===`--`){c=!1;continue}if(!c){r?a.push(l):(i=l,r=Rt(l));continue}if(Ct(r)){a.push(l);continue}let u=l.startsWith(`--`),d=l.startsWith(`-`)&&l.length>1;if(!u&&!d){r?a.push(l):(i=l,r=Rt(l));continue}let[f,p]=u?Dt(l):[l,void 0];if(xt(r,f))continue;let m=wt(f,r);if(St(r,m)){a.push(l);continue}if(!m){if(Mt(r,a,l)){r?a.push(l):r=l;continue}throw new t(`INVALID_ARGS`,vt(f))}let h=Ot(m,f,p,e[o+1]);h.consumeNext&&(o+=1);let g=n[m.key];if(m.multiple){let e=Array.isArray(g)?[...g,h.value]:g===void 0?[h.value]:[g,h.value];n[m.key]=e}else n[m.key]=h.value;s.push({key:m.key,token:f})}return bt(i,n),{command:r,positionals:a,flags:n,warnings:o,providedFlags:s}}function bt(e,t){if(e)for(let n of lt(e)?.impliedFlags??[])t[n]=!0}function xt(e,t){return t===`-c`&&(e===`snapshot`||e===`diff`)}function St(e,t){return e===`react-devtools`?t?!O(t.key,e):!0:!1}function Ct(e){return e===`cdp`}function wt(e,t){let n=je().filter(t=>t.names.includes(e));if(n.length<=1)return n[0]??ke(e);if(t){let e=n.find(e=>O(e.key,t));if(e)return e}return ke(e)}function Tt(e,n){let r=n?.strictFlags??!0,i=[...e.warnings],a=D({json:!1,help:!1,version:!1},n?.defaultFlags??{});if(D(a,e.flags),e.command&&!ie(e.command)&&!a.help){let n=ht(e.command);throw new t(`INVALID_ARGS`,n?`Unknown command: ${e.command}. Did you mean ${n}?`:`Unknown command: ${e.command}`)}let o=e.providedFlags.filter(t=>!O(t.key,e.command));if(o.length>0){let n=o.map(e=>e.token),s=Ft(e.command,n);if(r)throw new t(`INVALID_ARGS`,s);i.push(s);for(let e of o)delete a[e.key]}for(let t of Object.keys(a))a[t]!==void 0&&(O(t,e.command)||delete a[t]);Et(e),Je(e.command,a);let s=Pt({command:e.command,positionals:e.positionals,flags:a,warnings:i});if(qe(s.command,s.positionals),s.command===`batch`&&+!!a.steps+ +!!a.stepsFile!=1)throw new t(`INVALID_ARGS`,`batch requires exactly one step source: --steps or --steps-file.`);return s}function Et(e){if(e.command!==`back`)return;let n=e.providedFlags.filter(e=>e.key===`backMode`);if(!(new Set(n.map(e=>e.token)).size<=1))throw new t(`INVALID_ARGS`,`back accepts only one explicit mode flag: use either --in-app or --system.`)}function Dt(e){let t=e.indexOf(`=`);return t===-1?[e,void 0]:[e.slice(0,t),e.slice(t+1)]}function Ot(e,n,r,i){if(e.setValue!==void 0){if(r!==void 0)throw new t(`INVALID_ARGS`,`Flag ${n} does not take a value.`);return{value:e.setValue,consumeNext:!1}}if(e.type===`boolean`){if(r!==void 0)throw new t(`INVALID_ARGS`,`Flag ${n} does not take a value.`);return{value:!0,consumeNext:!1}}if(e.type===`booleanOrString`){if(r!==void 0){if(r.trim().length===0)throw new t(`INVALID_ARGS`,`Flag ${n} requires a non-empty value when provided.`);return{value:r,consumeNext:!1}}return i===void 0||At(i)?{value:!0,consumeNext:!1}:jt(i)?{value:i,consumeNext:!0}:{value:!0,consumeNext:!1}}let a=r??i;if(a===void 0||r===void 0&&At(a))throw new t(`INVALID_ARGS`,`Flag ${n} requires a value.`);if(e.type===`string`)return{value:a,consumeNext:r===void 0};if(e.type===`enum`){if(!e.enumValues?.includes(a))throw new t(`INVALID_ARGS`,`Invalid ${kt(n)}: ${a}`);return{value:a,consumeNext:r===void 0}}let o=Number(a);if(!Number.isFinite(o)||typeof e.min==`number`&&o<e.min||typeof e.max==`number`&&o>e.max)throw new t(`INVALID_ARGS`,`Invalid ${kt(n)}: ${a}`);return{value:Math.floor(o),consumeNext:r===void 0}}function kt(e){return e.replace(/^-+/,``)}function At(e){if(!e.startsWith(`-`)||e===`-`)return!1;let[t]=e.startsWith(`--`)?Dt(e):[e,void 0];return ke(t)!==void 0}function jt(e){let t=e.trim();return!t||/^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(t)?!1:!!(t.startsWith(`./`)||t.startsWith(`../`)||t.startsWith(`~/`)||t.startsWith(`/`)||t.includes(`/`)||t.includes(`\\`))}function Mt(e,t,n){if(!Nt(n)||!e)return!1;let r=Ke(e);if(!r||r.allowsExtraPositionals)return!0;let i=r.positionalArgs??[];return i.length===0?!1:t.length<i.length?!0:i.some(e=>e.includes(`?`))}function Nt(e){return/^-\d+(\.\d+)?$/.test(e)}function Pt(e){if(e.flags.help)return e;if(e.command===`snapshot`&&e.flags.snapshotDiff){let{snapshotDiff:t,...n}=e.flags;return{command:`diff`,positionals:[`snapshot`,...e.positionals],flags:n,warnings:e.warnings}}return e}function Ft(e,t){return e?t.length===1?`Flag ${t[0]} is not supported for command ${e}.`:`Flags ${t.join(`, `)} are not supported for command ${e}.`:t.length===1?`Flag ${t[0]} requires a command that supports it.`:`Flags ${t.join(`, `)} require a command that supports them.`}async function It(){let{buildUsageText:e}=await import(`./cli-help.js`);return e()}async function Lt(e){let{buildCommandUsageText:t}=await import(`./cli-help.js`);return t(Rt(e))}function Rt(e){if(e.toLowerCase()===`rotate`)throw new t(`INVALID_ARGS`,`rotate was renamed to orientation; for the two-finger gesture use: gesture rotate`);return ct(e)}const zt={slug:`react-devtools-companion`,runArg:Me,displayName:`React DevTools companion`};async function Bt(e){return await Pe({...e,definition:zt,localBaseUrl:e.localBaseUrl??`http://127.0.0.1:8097`,registerPath:`/api/react-devtools/companion/register`,unregisterPath:`/api/react-devtools/companion/unregister`,devicePort:e.devicePort??8097})}async function Vt(e){return await Ne({...e,definition:zt})}function Ht(e){return e===`android-instance`||e===`ios-instance`}function Ut(e){return[`exec`,`--yes`,`--package`,`agent-cdp@1.6.1`,`--`,`agent-cdp`,...e]}function Wt(e){return e.some(e=>e===`--url`||e.startsWith(`--url=`))}function Gt(e){return e[0]===`target`&&(e[1]===`list`||e[1]===`select`)&&!Wt(e)}function Kt(e){let t=new URL(e);t.search=``,t.hash=``;let n=t.pathname.replace(/\/+$/,``);return t.pathname=n.endsWith(`/index.bundle`)?n.slice(0,-13)||`/`:n||`/`,t.toString().replace(/\/+$/,``)}function qt(e){let t=e?.metroPublicBaseUrl?.trim();return t?Kt(t):null}function Jt(e,n={}){if(!Gt(e)||!n.flags?.metroProxyBaseUrl||!Ht(n.flags.leaseBackend))return e;let r=qt(n.flags);if(!r)throw new t(`INVALID_ARGS`,`cdp remote bridge target discovery requires a React Native dev-server public base URL.`,{hint:`Include metroPublicBaseUrl in the remote config so cdp can reach the local or tunneled Metro/Re.Pack CDP endpoint without bridge proxy authentication.`});return[...e,`--url`,r]}async function Yt(e,t={}){return(await c(`npm`,Ut(Jt(e,t)),{cwd:t.cwd??process.cwd(),env:t.env??process.env,allowFailure:!0,onStdoutChunk:e=>{process.stdout.write(e)},onStderrChunk:e=>{process.stderr.write(e)}})).exitCode}function P(e){let t=nn(e);if(!j.existsSync(t))return null;let n;try{n=JSON.parse(j.readFileSync(t,`utf8`))}catch(t){return dn(e,t),null}return pn(n)?n:(dn(e),null)}function Xt(e){let t=nn({stateDir:e.stateDir,session:e.state.session});j.mkdirSync(M.dirname(t),{recursive:!0}),ln(t,e.state),ln(rn(e.stateDir),{session:e.state.session})}function Zt(e){return{baseUrl:un(e.daemonBaseUrl),authToken:e.daemonAuthToken,transport:e.daemonTransport,serverMode:e.daemonServerMode}}function Qt(e){j.rmSync(nn(e),{force:!0});let t=rn(e.stateDir);on(e.stateDir)===e.session&&j.rmSync(t,{force:!0})}function $t(e){let n=e.validateRemoteConfigHash??!0,r=e.remoteConfig?Re({configPath:e.remoteConfig,cwd:e.cwd,env:e.env}):void 0,i=P(e)??(e.allowActiveFallback?an({stateDir:e.stateDir}):null);if(!i||r&&i.remoteConfigPath!==r)return null;if(n&&tn(i.remoteConfigPath)!==i.remoteConfigHash)throw new t(`INVALID_ARGS`,`Active remote connection config changed. Run agent-device connect --force to refresh it.`,{remoteConfig:i.remoteConfigPath});let a=cn(i,e),o=ee(i);return{runtime:i.runtime,connection:oe(o),flags:{...a,remoteConfig:i.remoteConfigPath,daemonBaseUrl:i.daemon?.baseUrl??a.daemonBaseUrl,daemonAuthToken:i.daemon?.authToken??a.daemonAuthToken,daemonTransport:i.daemon?.transport??a.daemonTransport,daemonServerMode:i.daemon?.serverMode??a.daemonServerMode,...ne(o),sessionIsolation:`tenant`,session:i.session,platform:i.platform??a.platform,target:i.target??a.target}}}function en(e){return oe(ee(e))}function tn(e){try{return A.createHash(`sha256`).update(j.readFileSync(e)).digest(`hex`)}catch(n){throw new t(`INVALID_ARGS`,`Remote config file not found: ${e}`,{cause:n instanceof Error?n.message:String(n)})}}function nn(e){return M.join(e.stateDir,`remote-connections`,`${fn(e.session)}.json`)}function rn(e){return M.join(e,`remote-connections`,`.active-session.json`)}function an(e){let t=on(e.stateDir);return t?P({stateDir:e.stateDir,session:t}):null}function on(e){let t=rn(e);if(j.existsSync(t))try{let e=JSON.parse(j.readFileSync(t,`utf8`));return typeof e.session==`string`?e.session:void 0}catch{return}}function sn(e){if(e)return A.createHash(`sha256`).update(e).digest(`hex`).slice(0,12)}function cn(e,t){try{return w({configPath:e.remoteConfigPath,cwd:t.cwd,env:t.env}).profile}catch(e){if(t.validateRemoteConfigHash===!1)return{};throw e}}function ln(e,t){j.writeFileSync(e,`${JSON.stringify(t,null,2)}\n`,{encoding:`utf8`,mode:384}),j.chmodSync(e,384)}function un(e){if(!e)return;let t=new URL(e);t.username=``,t.password=``;for(let e of[...t.searchParams.keys()])/(auth|key|password|secret|token)/i.test(e)&&t.searchParams.delete(e);return t.toString().replace(/\/+$/,``)}function dn(e,t){l({level:`warn`,phase:`remote_connection_state_invalid`,data:{session:e.session,cause:t instanceof Error?t.message:t?String(t):void 0}}),Qt(e)}function fn(e){let t=e.replaceAll(/[^a-zA-Z0-9._-]/g,`_`);return t?t===e?t:`${t}-${A.createHash(`sha256`).update(e).digest(`hex`).slice(0,8)}`:`default`}function pn(e){if(!e||typeof e!=`object`||Array.isArray(e))return!1;let t=e;return t.version===1&&mn(t,[`session`,`remoteConfigPath`,`remoteConfigHash`,`tenant`,`runId`,`connectedAt`,`updatedAt`])&&hn(t,[`leaseId`,`leaseBackend`,`leaseProvider`,`deviceKey`,`clientId`])&&gn(t.daemon)}function mn(e,t){return t.every(t=>typeof e[t]==`string`)}function hn(e,t){return t.every(t=>e[t]===void 0||typeof e[t]==`string`)}function gn(e){return e===void 0?!0:!e||typeof e!=`object`||Array.isArray(e)?!1:_n(e)}function _n(e){let t=e;return(t.baseUrl===void 0||typeof t.baseUrl==`string`)&&(t.authToken===void 0||typeof t.authToken==`string`)&&(t.transport===void 0||typeof t.transport==`string`)&&(t.serverMode===void 0||typeof t.serverMode==`string`)}const vn=Le.map(e=>e.key);function yn(e){let t={};for(let n of vn){let r=e[n];r!==void 0&&(t[n]=r)}return t}function bn(e){return e.remoteConfig?{...yn(w({configPath:e.remoteConfig,cwd:e.cwd,env:e.env}).profile),remoteConfig:e.remoteConfig}:{}}function xn(e){return e===`cloud`||e===`proxy`||F(e)}function F(e){return e===`limrun`||T(e)}function Sn(e){return T(e)}function Cn(){return[`cloud`,`proxy`,E.browserStack,E.awsDeviceFarm,`limrun`].join(`, `)}function wn(e){return!F(e)}function Tn(e){return e===`proxy`?`proxy`:F(e)?`direct-device-provider`:`remote-provider`}const I=new Set([`artifacts`,`connect`,`connection`,`close`,`disconnect`,`metro`,`session`]),En=new Set([`open`]),Dn=new Set([_.open,_.install,_.reinstall,g.installSource]);async function On(e){let{command:n,flags:r,client:i}=e;if(!r.remoteConfig)return{flags:r,runtime:e.runtime};let a=x(r.stateDir).baseDir,o=w({configPath:r.remoteConfig,cwd:process.cwd(),env:process.env}),s={...yn(o.profile),...r,remoteConfig:o.resolvedPath},c=P({stateDir:a,session:s.session??`default`});if(c&&c.remoteConfigPath!==o.resolvedPath)throw new t(`INVALID_ARGS`,`A different remote connection is already active for this session. Run connect --force or disconnect before using a different --remote-config.`,{session:c.session,activeRemoteConfig:c.remoteConfigPath,requestedRemoteConfig:o.resolvedPath});let l=c??Zn(s,o.resolvedPath,o.profile),u={...s,session:l.session},d=Xn(l.runtime,u.platform)??e.runtime,f=l,p=!c,m,h=In(f);if(h.shouldAllocate(n)){let e=await Nn({command:n,client:i,state:l,nextState:f,nextFlags:u,policy:h});f=e.state,p||=e.changed,m=e.acquiredLeaseForCleanup}let g=await kn({command:n,flags:u,client:i,state:l,nextState:f,runtime:d,positionals:e.positionals,batchSteps:e.batchSteps,forceRuntimePrepare:e.forceRuntimePrepare});return f=g.state,d=g.runtime,p||=g.changed,await Mn({changed:p,stateDir:a,state:f,client:i,acquiredLeaseForCleanup:m,preparedMetroCleanupOnFailure:g.preparedMetroCleanupOnFailure,metroCleanupToStop:g.metroCleanupToStop}),{flags:{...u,session:f.session,leaseId:f.leaseId,leaseBackend:f.leaseBackend,platform:f.platform??u.platform,target:f.target??u.target},runtime:d,connection:en(f)}}async function kn(e){let{command:n,flags:r,state:i,client:a}=e,o=An(e.nextState,r),s=e.runtime;if(!Kn(n,r,e.batchSteps,e.positionals)||!qn(r)||!jn(e.forceRuntimePrepare,s,r.platform))return{state:o,runtime:s,changed:!1};if(!o.leaseId)throw new t(`INVALID_ARGS`,`${n} requires a resolved remote lease before Metro runtime can be prepared.`);let c=await Bn(r,a,i.remoteConfigPath,i.session,{tenantId:i.tenant,runId:i.runId,leaseId:o.leaseId}),l=!Yn(o.metro,c.cleanup);return o={...o,runtime:c.runtime,metro:c.cleanup,updatedAt:new Date().toISOString()},{state:o,runtime:c.runtime,changed:!0,metroCleanupToStop:l?e.nextState.metro:void 0,preparedMetroCleanupOnFailure:l?c.cleanup:void 0}}function An(e,t){return e.leaseId||!t.leaseId?e:{...e,leaseId:t.leaseId,leaseBackend:t.leaseBackend}}function jn(e,t,n){return e===!0||!t||!Jn(t,n)}async function Mn(e){if(e.changed)try{Xt({stateDir:e.stateDir,state:e.state})}catch(t){throw await L(e.preparedMetroCleanupOnFailure),await Wn(e.client,e.state,e.acquiredLeaseForCleanup),t}await L(e.metroCleanupToStop)}async function Nn(e){let{command:t,client:n,state:r,nextFlags:i,policy:a}=e,o=r.leaseBackend??R(i),s=e.nextState,c=await a.resolveLeaseState({command:t,client:n,state:s,flags:i,leaseBackend:o});s=c.state,c.device&&er(i,c.device);let l=s.leaseBackend??o??Gn(i,t);ir(r,i,l);let u=await Qn(n,s,l,a,i),d=u.lease;return i.leaseId=d.leaseId,i.leaseBackend=l,i.platform=s.platform??i.platform,i.target=s.target??i.target,Pn(s,d,l)?{state:s,changed:!1,acquiredLeaseForCleanup:u.acquired?d:void 0}:{state:Fn(s,d,l,i),changed:!0,acquiredLeaseForCleanup:u.acquired?d:void 0}}function Pn(e,t,n){return e.leaseId===t.leaseId&&e.leaseBackend===n&&e.deviceKey===(t.deviceKey??e.deviceKey)}function Fn(e,t,n,r){return{...e,leaseId:t.leaseId,leaseBackend:n,leaseProvider:t.leaseProvider??e.leaseProvider,clientId:t.clientId??e.clientId,deviceKey:t.deviceKey??e.deviceKey,platform:e.platform??r.platform,target:e.target??r.target,updatedAt:new Date().toISOString()}}function In(e){return e.leaseProvider===`proxy`?Rn:T(e.leaseProvider)?zn:Ln}const Ln={shouldAllocate:e=>!I.has(e),ttlMs:()=>void 0,resolveLeaseState:async e=>({state:e.state})},Rn={shouldAllocate:e=>e!==`devices`&&!I.has(e),ttlMs:()=>3e5,resolveLeaseState:$n},zn={shouldAllocate:e=>!I.has(e),ttlMs:()=>6e5,resolveLeaseState:async e=>({state:e.state})};async function Bn(e,n,r,i,a){if(!e.metroProjectRoot&&!e.metroPublicBaseUrl&&!e.metroProxyBaseUrl)return{};if(e.platform!==`ios`&&e.platform!==`android`)throw new t(`INVALID_ARGS`,`Deferred Metro preparation requires platform "ios" or "android".`);if(!e.metroPublicBaseUrl&&!e.metroProxyBaseUrl)throw new t(`INVALID_ARGS`,`Deferred Metro preparation requires metroPublicBaseUrl or metroProxyBaseUrl when Metro settings are provided.`);let o=await n.metro.prepare({projectRoot:e.metroProjectRoot,kind:Ae(e.metroKind),publicBaseUrl:e.metroPublicBaseUrl,proxyBaseUrl:e.metroProxyBaseUrl,bearerToken:e.metroBearerToken,bridgeScope:a,launchUrl:e.launchUrl,companionProfileKey:r,companionConsumerKey:i,port:e.metroPreparePort,listenHost:e.metroListenHost,statusHost:e.metroStatusHost,startupTimeoutMs:e.metroStartupTimeoutMs,probeTimeoutMs:e.metroProbeTimeoutMs,reuseExisting:e.metroNoReuseExisting?!1:void 0,installDependenciesIfNeeded:e.metroNoInstallDeps?!1:void 0,runtimeFilePath:e.metroRuntimeFile});return{runtime:e.platform===`ios`?o.iosRuntime:o.androidRuntime,cleanup:e.metroProxyBaseUrl?{projectRoot:o.projectRoot,profileKey:r,consumerKey:i}:void 0}}async function L(e){if(e)try{await Ie(e)}catch{}}async function Vn(e){try{await Vt({projectRoot:process.cwd(),stateDir:e.stateDir,profileKey:e.state.remoteConfigPath,consumerKey:e.state.session})}catch{}}async function Hn(e,t){return t.leaseId?await e.leases.release({tenant:t.tenant,runId:t.runId,leaseId:t.leaseId,leaseBackend:t.leaseBackend,daemonBaseUrl:t.daemon?.baseUrl,daemonAuthToken:t.daemon?.authToken,daemonTransport:t.daemon?.transport,daemonServerMode:t.daemon?.serverMode,leaseProvider:t.leaseProvider,clientId:t.clientId,deviceKey:t.deviceKey}):{released:!1}}async function Un(e,t){if(t.leaseId)try{await Hn(e,t)}catch{}}async function Wn(e,t,n){if(n)try{await e.leases.release({tenant:t.tenant,runId:t.runId,leaseId:n.leaseId,leaseBackend:t.leaseBackend??n.backend,leaseProvider:t.leaseProvider??n.leaseProvider,clientId:t.clientId??n.clientId,deviceKey:t.deviceKey??n.deviceKey})}catch{}}function R(e){if(e.leaseBackend)return e.leaseBackend;if(e.platform===`android`)return`android-instance`;if(e.platform===`ios`)return`ios-instance`}function Gn(e,n){let r=R(e);if(r)return r;throw new t(`INVALID_ARGS`,`${n} requires --platform ios|android or --lease-backend when the remote connection has not resolved a lease yet.`)}function Kn(e,t,n,r=[]){return e===`cdp`?Gt(r)&&!!t.metroPublicBaseUrl:En.has(e)?!0:e!==`batch`||!n?!1:n.some(e=>{let t=e.command.trim().toLowerCase();return En.has(t)&&e.runtime===void 0})}function qn(e){let t=e.metroKind;return!!(e.metroPublicBaseUrl||e.metroProxyBaseUrl||e.metroProjectRoot||t)}function Jn(e,t){return!e.platform||!t||t!==`ios`&&t!==`android`?!0:e.platform===t}function Yn(e,t){return e?.projectRoot===t?.projectRoot&&e?.profileKey===t?.profileKey&&e?.consumerKey===t?.consumerKey}function Xn(e,t){if(e)return Jn(e,t)?e:void 0}function Zn(e,n,r={}){if(!e.tenant)throw new t(`INVALID_ARGS`,`remote command requires tenant in remote config or via --tenant <id>.`);if(!e.runId)throw new t(`INVALID_ARGS`,`remote command requires runId in remote config or via --run-id <id>.`);if(!e.daemonBaseUrl&&wn(r.leaseProvider))throw new t(`INVALID_ARGS`,`remote command requires daemonBaseUrl in remote config, config, env, or --daemon-base-url.`);let i=new Date().toISOString();return{version:1,session:e.session??`default`,remoteConfigPath:n,remoteConfigHash:tn(n),daemon:Zt(e),tenant:e.tenant,runId:e.runId,leaseId:e.leaseId,leaseBackend:e.leaseBackend??R(e),leaseProvider:r.leaseProvider,clientId:r.clientId,deviceKey:r.deviceKey,platform:e.platform,target:e.target,connectedAt:i,updatedAt:i}}async function Qn(e,t,n,r,i){if(t.leaseId&&t.leaseBackend===n){let i=await ar(e,t.leaseId,{tenant:t.tenant,runId:t.runId,leaseBackend:n,leaseProvider:t.leaseProvider,clientId:t.clientId,deviceKey:t.deviceKey,ttlMs:r.ttlMs(t)});if(i)return{lease:i,acquired:!1}}return{lease:await e.leases.allocate({tenant:t.tenant,runId:t.runId,leaseBackend:n,leaseProvider:t.leaseProvider,clientId:t.clientId,deviceKey:t.deviceKey,ttlMs:r.ttlMs(t),platform:t.platform??i.platform,target:t.target??i.target,device:i.device,udid:i.udid,serial:i.serial,providerApp:i.providerApp,providerOsVersion:i.providerOsVersion,providerProject:i.providerProject,providerBuild:i.providerBuild,providerSessionName:i.providerSessionName,awsProjectArn:i.awsProjectArn,awsDeviceArn:i.awsDeviceArn,awsAppArn:i.awsAppArn,awsRegion:i.awsRegion,awsInteractionMode:i.awsInteractionMode}),acquired:!0}}async function $n(e){if(!Dn.has(e.command)){if(e.state.leaseId&&e.state.deviceKey)return{state:e.state};throw new t(`INVALID_ARGS`,`No active proxy device lease for this session; run open first.`)}let n=await tr(e.client,e.flags),r=nr(n);return{state:{...e.state,deviceKey:r,leaseBackend:e.state.leaseBackend??e.leaseBackend??rr(n),platform:e.state.platform??n.platform,target:e.state.target??n.target,updatedAt:new Date().toISOString()},device:n}}function er(e,t){if(e.platform=t.platform,e.target=t.target??e.target,Te(t)){e.udid=t.id;return}t.platform===`android`&&(e.serial=t.id)}async function tr(e,t){return await Ee((await e.devices.list({platform:t.platform,target:t.target,device:t.device,udid:t.udid,serial:t.serial,iosSimulatorDeviceSet:t.iosSimulatorDeviceSet,androidDeviceAllowlist:t.androidDeviceAllowlist})).map(e=>({...we(e.platform),id:e.id,name:e.name,kind:e.kind,target:e.target,booted:e.booted})),{platform:t.platform,target:t.target,deviceName:t.device,udid:t.udid,serial:t.serial})}function nr(e){return`${Ce(e)}:${e.target??`mobile`}:${e.id}`}function rr(e){if(Te(e))return`ios-instance`;if(e.platform===`android`)return`android-instance`}function ir(e,n,r){if(e.leaseBackend&&e.leaseBackend!==r)throw new t(`INVALID_ARGS`,`Active remote connection is already bound to a different lease backend. Re-run connect --force to replace it.`,{session:e.session,leaseBackend:e.leaseBackend});if(e.platform&&n.platform&&e.platform!==n.platform)throw new t(`INVALID_ARGS`,`Active remote connection is already bound to a different platform. Re-run connect --force to replace it.`,{session:e.session,platform:e.platform});if(e.target&&n.target&&e.target!==n.target)throw new t(`INVALID_ARGS`,`Active remote connection is already bound to a different target. Re-run connect --force to replace it.`,{session:e.session,target:e.target})}async function ar(e,t,n){try{return await e.leases.heartbeat({tenant:n.tenant,runId:n.runId,leaseId:t,leaseBackend:n.leaseBackend,leaseProvider:n.leaseProvider,clientId:n.clientId,deviceKey:n.deviceKey,ttlMs:n.ttlMs})}catch(e){if(or(e))return;throw e}}function or(e){return!(e instanceof t)||e.code!==`UNAUTHORIZED`?!1:e.details?.reason===`LEASE_NOT_FOUND`||e.details?.reason===`LEASE_EXPIRED`||e.details?.reason===`LEASE_REVOKED`}function sr(e){return Fe(e)}async function cr(e,n){let r=await e.text(),i={};if(r.trim().length>0)try{i=JSON.parse(r)}catch(r){throw new t(`COMMAND_FAILED`,n.invalidJsonMessage,{status:e.status},r instanceof Error?r:void 0)}if(!e.ok)throw new t(`UNAUTHORIZED`,n.rejectedMessage,{status:e.status,response:i});return i}const lr=1e3;async function ur(e){return await dr({command:e.command,flags:e.flags,stateDir:e.stateDir,allowInteractiveLogin:e.command===`connect`&&!e.flags.noLogin,env:e.env})}async function dr(e){let n=e.env??e.io?.env??process.env;if(!e.flags.daemonBaseUrl)return{flags:e.flags,source:`none`};if(W(e.flags.daemonAuthToken))return{flags:e.flags,source:`flag`};if(W(n.AGENT_DEVICE_DAEMON_AUTH_TOKEN))return{flags:e.flags,source:`env`};if(!Tr(e.flags.daemonBaseUrl,n))return{flags:e.flags,source:`none`};let r=await _r({stateDir:e.stateDir,flags:e.flags,env:n,io:e.io});if(r)return{flags:{...e.flags,daemonAuthToken:r.accessToken},source:`cli-session`};if(!e.allowInteractiveLogin)throw e.flags.noLogin?new t(`UNAUTHORIZED`,`Remote daemon authentication is required.`,{hint:`Run agent-device auth login, unset --no-login, or set AGENT_DEVICE_DAEMON_AUTH_TOKEN.`}):wr(e.command,n);let i=await z({stateDir:e.stateDir,flags:e.flags,env:n,io:e.io});return{flags:{...e.flags,daemonAuthToken:i.accessToken},source:`login`}}async function fr(e){let n=e.env??e.io?.env??process.env;if(W(e.flags.daemonAuthToken))return{accessToken:e.flags.daemonAuthToken,cloudBaseUrl:H(n)};if(W(n.AGENT_DEVICE_DAEMON_AUTH_TOKEN))return{accessToken:n.AGENT_DEVICE_DAEMON_AUTH_TOKEN,cloudBaseUrl:H(n)};let r=await _r({stateDir:e.stateDir,flags:e.flags,env:n,io:e.io});if(r)return{accessToken:r.accessToken,cloudBaseUrl:r.cloudBaseUrl};if(e.flags.noLogin)throw new t(`UNAUTHORIZED`,`Cloud connection profile authentication is required.`,{hint:`Run agent-device auth login, unset --no-login, or set AGENT_DEVICE_DAEMON_AUTH_TOKEN.`});let i=await z({stateDir:e.stateDir,flags:e.flags,env:n,io:e.io,commandLabel:`agent-device connect`});return{accessToken:i.accessToken,cloudBaseUrl:i.session.cloudBaseUrl}}async function z(e){let n=e.env??e.io?.env??process.env,r=xr(n,e.io);if(r===`non-interactive`)throw wr(e.commandLabel??`agent-device connect`,n);let i=H(n),a=await V({baseUrl:i,pathName:`/api/control-plane/device-auth/start`,body:{client:`agent-device`,tenant:e.flags.tenant,runId:e.flags.runId,daemonBaseUrl:e.flags.daemonBaseUrl,session:e.flags.session},fetchImpl:e.io?.fetch});br(a);let o=a.verificationUriComplete??a.verificationUri,s=r===`local-browser`?a.verificationUri:Er(a.verificationUri,a.userCode);r===`local-browser`?(U(e.io,`Opening ${a.verificationUri}...\n`),await Dr(o,e.io)):U(e.io,`Open this URL on your machine:\n${s}\n\nWaiting for approval for 10 minutes...\n`);let c=await yr({cloudBaseUrl:i,deviceCode:a.deviceCode,expiresIn:a.expiresIn,interval:a.interval,fetchImpl:e.io?.fetch,now:e.io?.now}),l=c.cliSession?.refreshCredential??c.cliSession?.refreshToken;if(!W(c.accessToken)||!W(l))throw new t(`UNAUTHORIZED`,`Device authorization did not return CLI credentials.`);let u=new Date(e.io?.now?.()??Date.now()).toISOString(),d={version:1,id:c.cliSession?.id??`cli-${Date.now().toString(36)}`,cloudBaseUrl:i,workspaceId:c.cliSession?.workspaceId,accountId:c.cliSession?.accountId,name:c.cliSession?.name,refreshCredential:l,createdAt:u,expiresAt:c.cliSession?.expiresAt};return mr({stateDir:e.stateDir,session:d}),{accessToken:c.accessToken,expiresAt:c.expiresAt,session:d}}function pr(e){let t=B(e.stateDir);if(!j.existsSync(t))return null;try{let e=JSON.parse(j.readFileSync(t,`utf8`));return e.version!==1||!W(e.id)||!W(e.cloudBaseUrl)||!W(e.refreshCredential)||!W(e.createdAt)?null:e}catch{return null}}function mr(e){let t=B(e.stateDir);j.mkdirSync(M.dirname(t),{recursive:!0,mode:448}),j.writeFileSync(t,`${JSON.stringify(e.session,null,2)}\n`,{mode:384});try{j.chmodSync(t,384)}catch{}}function hr(e){let t=B(e.stateDir);return j.existsSync(t)?(j.rmSync(t,{force:!0}),!0):!1}function B(e){return M.join(e,`auth`,`cli-session.json`)}function gr(e){let t=pr({stateDir:e.stateDir});return t?{authenticated:!0,source:`cli-session`,sessionId:t.id,cloudBaseUrl:t.cloudBaseUrl,workspaceId:t.workspaceId,accountId:t.accountId,name:t.name,createdAt:t.createdAt,expiresAt:t.expiresAt,expired:Or(t.expiresAt,e.now)}:{authenticated:!1,source:`none`}}async function _r(e){let t=pr({stateDir:e.stateDir});return!t||Or(t.expiresAt,e.io?.now)?null:{accessToken:(await vr({session:t,flags:e.flags,env:e.env,io:e.io})).accessToken,cloudBaseUrl:H(e.env,t.cloudBaseUrl)}}async function vr(e){let n=await V({baseUrl:H(e.env,e.session.cloudBaseUrl),pathName:`/api/control-plane/cli-session/refresh`,body:{refreshCredential:e.session.refreshCredential,tenant:e.flags.tenant,runId:e.flags.runId,daemonBaseUrl:e.flags.daemonBaseUrl,session:e.flags.session},fetchImpl:e.io?.fetch});if(W(n.accessToken))return{accessToken:n.accessToken,expiresAt:n.expiresAt};throw n.status===`revoked`||n.error===`revoked`?new t(`UNAUTHORIZED`,`Stored cloud CLI session was revoked.`,{hint:`Run agent-device auth login again, or set AGENT_DEVICE_DAEMON_AUTH_TOKEN.`,status:n.status,error:n.error}):new t(`UNAUTHORIZED`,`Failed to refresh CLI session.`,{hint:`Run agent-device auth login again, or set AGENT_DEVICE_DAEMON_AUTH_TOKEN.`,status:n.status,error:n.error})}async function yr(e){let n=e.now??Date.now,r=Math.min((e.expiresIn??600)*1e3,6e5),i=n()+r,a=Math.max(lr,(e.interval??5e3/1e3)*1e3);for(;n()<i;){let n=await V({baseUrl:e.cloudBaseUrl,pathName:`/api/control-plane/device-auth/poll`,body:{deviceCode:e.deviceCode},fetchImpl:e.fetchImpl});if(n.status===`approved`||W(n.accessToken))return n;if(n.status===`slow_down`||n.error===`slow_down`)a+=lr;else if(n.status!==`authorization_pending`&&n.error!==`authorization_pending`)throw new t(`UNAUTHORIZED`,`Device authorization was not approved.`,{status:n.status,error:n.error});await kr(a)}throw new t(`TIMEOUT`,`Device authorization expired before approval.`)}async function V(e){let t=await(e.fetchImpl??fetch)(new URL(e.pathName,e.baseUrl),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify(e.body),signal:AbortSignal.timeout(15e3)});return await cr(t,{invalidJsonMessage:`Cloud auth endpoint returned invalid JSON (${t.status}).`,rejectedMessage:`Cloud auth endpoint rejected the request.`})}function br(e){if(!W(e.deviceCode)||!W(e.userCode)||!W(e.verificationUri))throw new t(`COMMAND_FAILED`,`Cloud auth start returned an unusable response.`)}function xr(e,t){let n=t?.stdinIsTTY??process.stdin.isTTY,r=t?.stdoutIsTTY??process.stdout.isTTY;return Sr(e)||!n||!r?`non-interactive`:Cr(e)?`device-code`:`local-browser`}function Sr(e){return e.CI===`true`||e.GITHUB_ACTIONS===`true`||e.BUILDKITE===`true`}function Cr(e){return!!(e.SSH_TTY||e.SSH_CONNECTION||e.CODESPACES===`true`||e.GITPOD_WORKSPACE_ID||e.REMOTE_CONTAINERS===`true`)}function wr(e,n){let r=H(n);return new t(`UNAUTHORIZED`,`${e} cannot perform interactive login in CI or a non-interactive shell.`,{hint:`Create a service/API token: ${new URL(`/api-keys`,r).toString()} Then set AGENT_DEVICE_DAEMON_AUTH_TOKEN=adc_live_...`})}function H(e,n){let r=e.AGENT_DEVICE_CLOUD_BASE_URL??n??`https://cloud.agent-device.dev`;try{return new URL(r).toString().replace(/\/+$/,``)}catch(e){throw new t(`INVALID_ARGS`,`Invalid AGENT_DEVICE_CLOUD_BASE_URL.`,{cloudBaseUrl:r},e instanceof Error?e:void 0)}}function Tr(e,t){if(t.AGENT_DEVICE_CLOUD_AUTH===`1`||t.AGENT_DEVICE_CLOUD_AUTH===`true`||W(t.AGENT_DEVICE_CLOUD_BASE_URL))return!0;try{let t=new URL(e).hostname.toLowerCase();return t===`agent-device.dev`||t.endsWith(`.agent-device.dev`)}catch{return!1}}function Er(e,t){let n=new URL(e);return n.searchParams.set(`user_code`,t),n.toString()}async function Dr(e,t){if(t?.openBrowser){await t.openBrowser(e);return}let n=process.platform;try{n===`darwin`?await u(`open`,[e],{allowFailure:!0,timeoutMs:5e3}):n===`win32`?await u(`cmd`,[`/c`,`start`,``,e],{allowFailure:!0,timeoutMs:5e3}):await u(`xdg-open`,[e],{allowFailure:!0,timeoutMs:5e3})}catch{U(t,`Open this URL on your machine:\n${e}\n`)}}function U(e,t){(e?.stderr??process.stderr).write(t)}function Or(e,t){if(!e)return!1;let n=Date.parse(e);return Number.isFinite(n)?n<=(t?.()??Date.now()):!0}function W(e){return typeof e==`string`&&e.trim().length>0}async function kr(e){await new Promise(t=>setTimeout(t,e))}const Ar=new Set([`daemonAuthToken`,`metroBearerToken`]);function jr(e){let t=K(Nr(e.profile)),n=M.join(e.stateDir,`remote-connections`,`generated`);j.mkdirSync(n,{recursive:!0,mode:448});let r=M.join(n,`${Fr(e.provider)}-${Pr(t)}.json`);j.writeFileSync(r,`${JSON.stringify(t,null,2)}\n`,{mode:384});try{j.chmodSync(r,384)}catch{}return r}function Mr(e){try{return w(e)}catch(n){let i=r(n);throw new t(`COMMAND_FAILED`,`${e.provider} connection profile returned invalid remote config.`,{generatedConfigPath:e.configPath,cause:i.message},i)}}function G(e){let t=Mr({configPath:jr({stateDir:e.stateDir,provider:e.provider,profile:e.profile}),cwd:e.cwd,env:e.env,provider:Ir(e.provider)});return{flags:{...yn(t.profile),...e.flags,...e.extraFlags??{},remoteConfig:t.resolvedPath},remoteConfigPath:t.resolvedPath}}function Nr(e){return Object.fromEntries(Object.entries(e).filter(([e])=>!Ar.has(e)))}function Pr(e){return A.createHash(`sha256`).update(JSON.stringify(e)).digest(`hex`).slice(0,16)}function K(e){return Array.isArray(e)?e.map(K):e&&typeof e==`object`?Object.fromEntries(Object.entries(e).filter(([,e])=>e!==void 0).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>[e,K(t)])):e}function Fr(e){return e.replaceAll(/[^a-zA-Z0-9._-]/g,`_`)||`generated`}function Ir(e){let[t=``,...n]=e;return`${t.toUpperCase()}${n.join(``)}`}function q(...e){return A.createHash(`sha256`).update(e.map(e=>e??``).join(`\0`)).digest(`hex`).slice(0,16)}async function Lr(e){let t=await fr({stateDir:e.stateDir,flags:e.flags,env:e.env,io:{env:e.env,fetch:e.fetchImpl}}),n=await Rr({cloudBaseUrl:t.cloudBaseUrl,accessToken:t.accessToken,fetchImpl:e.fetchImpl}),r=q(e.stateDir,t.cloudBaseUrl,typeof n.daemonBaseUrl==`string`?n.daemonBaseUrl:``,e.flags.session);return G({stateDir:e.stateDir,provider:`cloud`,profile:{...n,leaseProvider:n.leaseProvider??`cloud`,clientId:n.clientId??r,runId:n.runId??`cloud-${r}`},cwd:e.cwd,env:e.env,flags:e.flags,extraFlags:{daemonAuthToken:t.accessToken}})}async function Rr(e){let t=await(e.fetchImpl??fetch)(new URL(`/api/control-plane/connection-profile`,e.cloudBaseUrl),{method:`GET`,headers:{authorization:`Bearer ${e.accessToken}`},signal:AbortSignal.timeout(15e3)});return zr(await cr(t,{invalidJsonMessage:`Cloud connection profile endpoint returned invalid JSON (${t.status}).`,rejectedMessage:`Cloud connection profile endpoint rejected the request.`}))}function zr(e){if(!e||typeof e!=`object`||Array.isArray(e))throw new t(`COMMAND_FAILED`,`Cloud connection profile response is invalid.`);let n=e.connection;if(!n||typeof n!=`object`)throw new t(`COMMAND_FAILED`,`Cloud connection profile response is missing profile.`);if(n.remoteConfigProfile!==void 0)return Br(n.remoteConfigProfile);throw new t(`COMMAND_FAILED`,`Cloud connection profile did not include remoteConfigProfile.`)}function Br(e){if(!e||typeof e!=`object`||Array.isArray(e))throw new t(`COMMAND_FAILED`,`Cloud connection profile remoteConfigProfile is invalid.`);if(Object.keys(e).length===0)throw new t(`COMMAND_FAILED`,`Cloud connection profile remoteConfigProfile is empty.`);return e}function Vr(e){return{metroProjectRoot:e.metroProjectRoot,metroKind:e.metroKind,metroPublicBaseUrl:e.metroPublicBaseUrl,metroProxyBaseUrl:e.metroProxyBaseUrl,metroPreparePort:e.metroPreparePort,metroListenHost:e.metroListenHost,metroStatusHost:e.metroStatusHost,metroStartupTimeoutMs:e.metroStartupTimeoutMs,metroProbeTimeoutMs:e.metroProbeTimeoutMs,metroRuntimeFile:e.metroRuntimeFile,metroNoReuseExisting:e.metroNoReuseExisting,metroNoInstallDeps:e.metroNoInstallDeps,launchUrl:e.launchUrl}}function Hr(e){let t=Wr(e.provider)(e),n=q(e.provider,e.stateDir,e.flags.session,t.device),r={tenant:e.flags.tenant??e.provider,sessionIsolation:e.flags.sessionIsolation??`tenant`,runId:e.flags.runId??`${e.provider}-${n}`,leaseProvider:e.provider,clientId:n,leaseBackend:e.flags.leaseBackend??R(e.flags),target:e.flags.target??`mobile`,session:e.flags.session,...t,...Vr(e.flags)};return G({stateDir:e.stateDir,provider:e.provider,profile:r,cwd:e.cwd,env:e.env,flags:e.flags})}const Ur=[{provider:E.browserStack,buildProfileFields:Gr},{provider:E.awsDeviceFarm,buildProfileFields:Kr}];function Wr(e){let n=Ur.find(t=>t.provider===e)?.buildProfileFields;if(n)return n;throw new t(`INVALID_ARGS`,`Unsupported cloud WebDriver provider "${e}".`)}function Gr(e){return Jr(e.env,`BROWSERSTACK_USERNAME`,`connect browserstack`),Jr(e.env,`BROWSERSTACK_ACCESS_KEY`,`connect browserstack`),{platform:qr(e.flags.platform,`connect browserstack requires --platform ios|android.`),device:J(e.flags.device,`connect browserstack requires --device <name>.`),providerOsVersion:J(e.flags.providerOsVersion,`connect browserstack requires --provider-os-version <version>.`),providerApp:J(e.flags.providerApp,`connect browserstack requires --provider-app <bs://app-id-or-local-path>.`),providerProject:e.flags.providerProject,providerBuild:e.flags.providerBuild,providerSessionName:e.flags.providerSessionName}}function Kr(e){let{env:t,flags:n}=e;return{platform:qr(n.platform,`connect aws-device-farm requires --platform ios|android.`),device:n.device,awsProjectArn:Yr(n.awsProjectArn,t,[`AGENT_DEVICE_AWS_DEVICE_FARM_PROJECT_ARN`,`AWS_DEVICE_FARM_PROJECT_ARN`],`connect aws-device-farm requires --aws-project-arn <arn> or AWS_DEVICE_FARM_PROJECT_ARN.`),awsDeviceArn:Yr(n.awsDeviceArn,t,[`AGENT_DEVICE_AWS_DEVICE_FARM_DEVICE_ARN`,`AWS_DEVICE_FARM_DEVICE_ARN`],`connect aws-device-farm requires --aws-device-arn <arn> or AWS_DEVICE_FARM_DEVICE_ARN.`),awsAppArn:Xr(n.awsAppArn,t,[`AGENT_DEVICE_AWS_DEVICE_FARM_APP_ARN`,`AWS_DEVICE_FARM_APP_ARN`]),awsRegion:Xr(n.awsRegion,t,[`AWS_REGION`,`AWS_DEFAULT_REGION`]),awsInteractionMode:n.awsInteractionMode,providerSessionName:n.providerSessionName}}function qr(e,n){if(e===`android`||e===`ios`)return e;throw new t(`INVALID_ARGS`,n)}function J(e,n){if(e)return e;throw new t(`INVALID_ARGS`,n)}function Jr(e,n,r){let i=e?.[n];if(i)return i;throw new t(`INVALID_ARGS`,`${r} requires ${n} in the environment.`)}function Yr(e,t,n,r){return J(Xr(e,t,n),r)}function Xr(e,t,n){return e||n.map(e=>t?.[e]).find(e=>!!e)}function Zr(e){let n=e.env??process.env;if(!n.LIMRUN_API_KEY?.trim())throw new t(`INVALID_ARGS`,`connect limrun requires LIMRUN_API_KEY.`,{hint:`Set LIMRUN_API_KEY in the environment before running agent-device connect limrun.`});let r=Qr({flags:e.flags});return G({stateDir:e.stateDir,provider:`limrun`,profile:r,cwd:e.cwd,env:n,flags:e.flags})}function Qr(e){let t=e.flags,n=$r(t);return{stateDir:x(t.stateDir).baseDir,daemonTransport:`auto`,tenant:t.tenant??`limrun`,runId:t.runId??`cli-${Date.now().toString(36)}`,sessionIsolation:`tenant`,leaseBackend:n,leaseProvider:`limrun`,platform:t.platform,target:`mobile`,session:t.session,...Vr(t)}}function $r(e){if(e.platform!==`android`&&e.platform!==`ios`)throw new t(`INVALID_ARGS`,`connect limrun requires --platform ios or android.`);if(e.device!==void 0)throw new t(`INVALID_ARGS`,`connect limrun does not accept --device; Limrun selects a remote simulator or emulator.`);let n=R(e),r=e.platform===`ios`?`ios-instance`:`android-instance`;if(n!==r)throw new t(`INVALID_ARGS`,`connect limrun --platform ${e.platform} requires --lease-backend ${r}.`);return r}function ei(e){let n=e.flags.daemonBaseUrl??e.env?.AGENT_DEVICE_DAEMON_BASE_URL;if(!n)throw new t(`INVALID_ARGS`,`connect proxy requires --daemon-base-url <url> or AGENT_DEVICE_DAEMON_BASE_URL.`);let r=q(e.stateDir,n,e.flags.session),i={daemonBaseUrl:n,daemonTransport:e.flags.daemonTransport??`http`,daemonServerMode:e.flags.daemonServerMode,tenant:e.flags.tenant??`proxy`,sessionIsolation:e.flags.sessionIsolation??`tenant`,runId:e.flags.runId??`proxy-${r}`,leaseProvider:`proxy`,clientId:r,leaseBackend:e.flags.leaseBackend??R(e.flags),platform:e.flags.platform,target:e.flags.target,device:e.flags.device,udid:e.flags.udid,serial:e.flags.serial,iosSimulatorDeviceSet:e.flags.iosSimulatorDeviceSet,androidDeviceAllowlist:e.flags.androidDeviceAllowlist,session:e.flags.session,...Vr(e.flags)};return G({stateDir:e.stateDir,provider:`proxy`,profile:i,cwd:e.cwd,env:e.env,flags:e.flags,extraFlags:{daemonBaseUrl:n,daemonTransport:e.flags.daemonTransport??`http`}})}const ti=async({positionals:e,flags:t,client:n})=>{let r=x(t.stateDir).baseDir,i=xi(e);ri(i,t);let a=await ni({provider:i,flags:t,stateDir:r}),o=a.flags,s=pi(a.remoteConfigPath),c=ii(o,s),l=ai({stateDir:r,flags:o,remoteConfigPath:a.remoteConfigPath});oi(l.previous,{flags:o,session:l.session,remoteConfigPath:a.remoteConfigPath,remoteConfigHash:l.remoteConfigHash,desiredLeaseBackend:R(o),connection:s,daemon:l.daemon});let u=si({flags:o,scope:c,connectionMetadata:s,context:l,remoteConfigPath:a.remoteConfigPath});Xt({stateDir:r,state:u}),await di(n,r,o,l.previous);let d=Ni(u),f=ji(o,u);return k(o,Ii(u,f),()=>[`Connected remote session "${l.session}" tenant "${c.tenant}" run "${c.runId}" ${u.leaseId?`lease ${u.leaseId}`:`lease pending`}`,d?.message,f?.message].filter(e=>!!e).join(`
2
- `)),!0};async function ni(e){let{provider:t,flags:n,stateDir:r}=e;return n.remoteConfig?fi(n):Sn(t)?Hr({provider:t,flags:n,stateDir:r,cwd:process.cwd(),env:process.env}):t===`proxy`||!t&&Si(n)?ei({flags:n,stateDir:r,cwd:process.cwd(),env:process.env}):t===`limrun`?Zr({flags:n,stateDir:r,cwd:process.cwd(),env:process.env}):await Lr({flags:n,stateDir:r,cwd:process.cwd(),env:process.env})}function ri(e,n){if(!(!e||!n.remoteConfig))throw new t(`INVALID_ARGS`,`connect provider positional and --remote-config are mutually exclusive.`)}function ii(e,n){if(!e.tenant)throw new t(`INVALID_ARGS`,`connect requires tenant in remote config or via --tenant <id>.`);if(!e.runId)throw new t(`INVALID_ARGS`,`connect requires runId in remote config or via --run-id <id>.`);if(!e.daemonBaseUrl&&wn(n?.leaseProvider))throw new t(`INVALID_ARGS`,`connect requires daemonBaseUrl in remote config, config, env, or --daemon-base-url.`);return{tenant:e.tenant,runId:e.runId}}function ai(e){let{stateDir:t,flags:n,remoteConfigPath:r}=e,i=n.session?null:an({stateDir:t}),a=n.session??i?.session??gi(t);return{session:a,previous:i?.session===a?i:P({stateDir:t,session:a}),remoteConfigHash:tn(r),daemon:Ai(n)}}function oi(e,n){if(!(!e||Ei(e,n))&&!n.flags.force)throw new t(`INVALID_ARGS`,`A different remote connection is already active for this session. Re-run connect with --force to replace it.`,{session:n.session,remoteConfig:e.remoteConfigPath})}function si(e){let{flags:t,scope:n,connectionMetadata:r,context:i,remoteConfigPath:a}=e,o=ui(t,i.previous)?i.previous:null,s=new Date().toISOString(),c=ci(t,o,r),l=li(t,o,s);return{version:1,session:i.session,remoteConfigPath:a,remoteConfigHash:i.remoteConfigHash,daemon:i.daemon,tenant:n.tenant,runId:n.runId,...c,...l,updatedAt:s}}function ci(e,t,n){return{leaseId:t?.leaseId,leaseBackend:t?.leaseBackend??R(e),leaseProvider:n?.leaseProvider??t?.leaseProvider,clientId:n?.clientId??t?.clientId,deviceKey:t?.deviceKey??n?.deviceKey}}function li(e,t,n){return{platform:e.platform??t?.platform,target:e.target??t?.target,runtime:t?.runtime,metro:t?.metro,connectedAt:t?.connectedAt??n}}function ui(e,t){return!!(t&&!e.force)}async function di(e,t,n,r){!r||!n.force||(await L(r.metro),await Vn({stateDir:t,state:r}),await Un(e,r))}function fi(e){if(!e.remoteConfig)throw new t(`INVALID_ARGS`,`connect requires --remote-config <path>.`);return{flags:e,remoteConfigPath:w({configPath:e.remoteConfig,cwd:process.cwd(),env:process.env}).resolvedPath}}function pi(e){let t=w({configPath:e,cwd:process.cwd(),env:process.env}).profile,n={leaseProvider:t.leaseProvider,clientId:t.clientId,deviceKey:t.deviceKey};return Object.values(n).some(e=>e!==void 0)?n:void 0}const mi=async({flags:e,client:t})=>{let{session:n,stateDir:r,state:i}=wi(e);if(!i)return Ti(e,n),!0;let a=i.session,o;try{o=(await t.sessions.close({session:a,shutdown:e.shutdown})).provider}catch{}await L(i.metro),await Vn({stateDir:r,state:i});let s=!1;if(i.leaseId)try{let e=await Hn(t,i);s=e.released,o??=e.provider}catch{}return Qt({stateDir:r,session:a}),k(e,{connected:!1,session:a,released:s,...o?{provider:o}:{}},()=>_i(a,o)),!0},hi=async({positionals:e,flags:n})=>{if(e[0]!==`status`)throw new t(`INVALID_ARGS`,`connection accepts only: status`);let{session:r,state:i}=wi(n);if(!i)return Ti(n,r),!0;let a=Ni(i),o=Mi(i);return k(n,Ii(i,o),()=>[`Connected remote session "${i.session}".`,`tenant=${i.tenant} runId=${i.runId} leaseId=${i.leaseId??`pending`} backend=${i.leaseBackend??`pending`}`,`remoteConfig=${i.remoteConfigPath}`,i.runtime?`metro=prepared`:`metro=not-prepared`,a?.message,o?.message].filter(e=>!!e).join(`
3
- `)),!0};function gi(e){for(let t=0;t<8;t+=1){let t=`adc-${A.randomBytes(3).toString(`hex`)}`;if(!P({stateDir:e,session:t}))return t}return`adc-${Date.now().toString(36)}-${A.randomBytes(2).toString(`hex`)}`}function _i(e,t){return[`Disconnected remote session "${e}".`,...vi(t),...bi(t?.cloudArtifacts?.cloudArtifacts)].join(`
4
- `)}function vi(e){return(Array.isArray(e?.warnings)?e.warnings:[]).flatMap(e=>{let t=yi(e);return t?[t]:[]})}function yi(e){if(!e||typeof e!=`object`)return;let t=e;if(!(typeof t.message!=`string`||t.message.length===0))return`Provider release warning${typeof t.code==`string`&&t.code.length>0?` (${t.code})`:``}: ${t.message}`}function bi(e){return(e??[]).filter(e=>(e.availability??`ready`)===`ready`&&e.url).slice(0,3).map(e=>`${e.name}: ${e.url}`)}function xi(e){let n=e[0];if(n!==void 0){if(e.length>1)throw new t(`INVALID_ARGS`,`connect accepts at most one provider positional.`);if(xn(n))return n;throw new t(`INVALID_ARGS`,`Unknown connect provider: ${n}. Supported providers: ${Cn()}.`)}}function Si(e){return!e.daemonBaseUrl||e.tenant||e.runId||e.leaseId||e.leaseBackend?!1:Ci(e.daemonBaseUrl)}function Ci(e){try{return new URL(e).pathname.replace(/\/+$/,``).endsWith(`/agent-device`)}catch{return!1}}function wi(e){let t=e.session??`default`,n=x(e.stateDir).baseDir;return{session:t,stateDir:n,state:P({stateDir:n,session:t})??(e.session?null:an({stateDir:n}))}}function Ti(e,t){k(e,{connected:!1,session:t},()=>`No remote connection for "${t}".`)}function Ei(e,t){return Di(e,t)&&Oi(e,t)&&ki(e.daemon,t.daemon)}function Di(e,t){return[[e.remoteConfigPath,t.remoteConfigPath],[e.remoteConfigHash,t.remoteConfigHash],[e.session,t.session],[e.tenant,t.flags.tenant],[e.runId,t.flags.runId]].every(([e,t])=>e===t)}function Oi(e,t){return[[e.leaseBackend,t.desiredLeaseBackend],[e.platform,t.flags.platform],[e.target,t.flags.target],[e.leaseProvider,t.connection?.leaseProvider],[e.clientId,t.connection?.clientId]].every(([e,t])=>t===void 0||e===t)}function ki(e,t){return[`baseUrl`,`transport`,`serverMode`].every(n=>(e?.[n]??void 0)===(t?.[n]??void 0))}function Ai(e){return Zt(e)}function ji(e,t){if(!t.runtime&&!(!qn(e)&&!Fi(t.remoteConfigPath)))return Pi(t.remoteConfigPath)}function Mi(e){if(!(e.runtime||!Fi(e.remoteConfigPath)))return Pi(e.remoteConfigPath)}function Ni(e){if(e.leaseId)return;let t=Tn(e.leaseProvider);return t===`proxy`?{status:`deferred`,nextSteps:[`agent-device open <app-id> --relaunch`,`agent-device devices`],message:`Proxy lease allocation is pending; run open when ready to allocate or refresh the device lease. Devices can inspect inventory but do not allocate a proxy lease.`}:t===`direct-device-provider`?{status:`deferred`,nextSteps:[`agent-device open <app-id> --relaunch`,`agent-device snapshot -i`,`agent-device artifacts --json`,`agent-device close`],message:`Hosted ${e.leaseProvider} lease allocation is pending; run open when ready to create the provider session. After close, run "agent-device artifacts --json" to fetch provider video/log links when available.`}:{status:`deferred`,nextSteps:[`agent-device install-from-source <artifact-url> --platform ios|android`,`agent-device open <app-id> --relaunch`,`agent-device snapshot -i`,`agent-device devices`],message:`Lease allocation is pending; run install-from-source, open, snapshot, or devices when ready to allocate or refresh the lease.`+(e.platform===void 0&&e.leaseBackend===void 0?` Add --platform ios|android if the profile does not set a platform.`:``)}}function Pi(e){let t=`agent-device metro prepare --remote-config ${e}`;return{status:`deferred`,nextStep:t,message:`Metro runtime is not prepared yet; it will be prepared automatically on first open, or run "${t}" to inspect it before launch.`}}function Fi(e){try{let t=w({configPath:e,cwd:process.cwd(),env:process.env}).profile;return!!(t.metroPublicBaseUrl||t.metroProxyBaseUrl||t.metroProjectRoot||t.metroKind)}catch{return!1}}function Ii(e,t){let n=Ni(e);return{connected:!0,session:e.session,tenant:e.tenant,runId:e.runId,leaseAllocated:!!e.leaseId,leaseId:e.leaseId,leaseBackend:e.leaseBackend,leaseProvider:e.leaseProvider,platform:e.platform,target:e.target,remoteConfig:e.remoteConfigPath,remoteConfigHash:e.remoteConfigHash,daemonBaseUrlFingerprint:sn(e.daemon?.baseUrl),metro:e.metro?{prepared:!0,projectRoot:e.metro.projectRoot}:{prepared:!1},...n?{leasePreparation:n}:{},...t?{runtimePreparation:t}:{},connectedAt:e.connectedAt,updatedAt:e.updatedAt}}const Li=async({positionals:e,flags:n})=>{let r=e[0]??`status`,i=x(n.stateDir).baseDir;if(r===`status`){let e=gr({stateDir:i});return k(n,e,()=>Ri(e)),!0}if(r===`login`){let e=await z({stateDir:i,flags:n,commandLabel:`agent-device auth login`});return k(n,{authenticated:!0,source:`cli-session`,sessionId:e.session.id,cloudBaseUrl:e.session.cloudBaseUrl,workspaceId:e.session.workspaceId,accountId:e.session.accountId,expiresAt:e.session.expiresAt,agentTokenExpiresAt:e.expiresAt},()=>`Authenticated with cloud CLI session.`),!0}if(r===`logout`){let e=hr({stateDir:i});return k(n,{authenticated:!1,removed:e},()=>e?`Removed stored cloud CLI session.`:`No stored cloud CLI session.`),!0}throw new t(`INVALID_ARGS`,`auth accepts only: status, login, logout`)};function Ri(e){return e.authenticated?[`Authenticated with cloud CLI session.`,`cloud=${e.cloudBaseUrl}`,`session=${e.sessionId}`,e.workspaceId?`workspace=${e.workspaceId}`:null,e.accountId?`account=${e.accountId}`:null,e.expiresAt?`expiresAt=${e.expiresAt}`:null,e.expired?`status=expired`:null].filter(e=>!!e).join(`
5
- `):`Not authenticated.`}async function zi(e){let n=Hi(e.paths.infoPath);if(!n)return Y();if(!n.processStartTime){if(!C(n.pid))return Y();throw new t(`COMMAND_FAILED`,`Refusing to stop a daemon without a verified process start-time identity.`,{pid:n.pid})}if(!ue(n.pid,n.processStartTime)){if(!C(n.pid))return Y();throw new t(`COMMAND_FAILED`,`Refusing to stop a daemon whose PID or start-time identity could not be verified.`,{pid:n.pid,processStartTime:n.processStartTime})}if(!Bi(n.pid,`SIGTERM`))return Y();if(await Oe(n.pid,e.graceTimeoutMs??1e4))return await Wi(e.paths,1e3),{stopped:!0,mode:`graceful`,cleanupConfidence:`known`,claimsReleased:[],claimsOrphaned:[],providerReleases:{status:`completed`,released:[],pending:[]},warnings:[]};if(ue(n.pid,n.processStartTime)&&Bi(n.pid,`SIGKILL`),!await Oe(n.pid,e.killTimeoutMs??2e3))throw new t(`COMMAND_FAILED`,`Daemon did not exit after SIGKILL.`,{pid:n.pid});return{stopped:!0,mode:`forced`,cleanupConfidence:`unknown`,claimsReleased:[],claimsOrphaned:[],providerReleases:{status:`unknown`,released:[],pending:null},warnings:[`The daemon was force-killed before provider lease state could be finalized. Provider allocations may remain active.`]}}function Bi(e,n){if(he(e,n))return!0;if(!C(e))return!1;throw new t(`COMMAND_FAILED`,`Daemon could not be signaled with ${n}.`,{pid:e,signal:n})}function Vi(e){let t=Hi(e);return t?.processStartTime?{pid:t.pid,processStartTime:t.processStartTime}:null}function Hi(e){try{let t=JSON.parse(j.readFileSync(e,`utf8`)),n=t.pid;return typeof n!=`number`||!Number.isInteger(n)||n<=0?null:{pid:n,...Ui(t.processStartTime)?{processStartTime:t.processStartTime}:{}}}catch{return null}}function Ui(e){return typeof e==`string`&&e.trim().length>0}async function Wi(e,t){let n=Date.now();for(;Date.now()-n<t;){if(!j.existsSync(e.infoPath)&&!j.existsSync(e.lockPath))return;await De(25)}}function Y(){return{stopped:!1,mode:`not-running`,cleanupConfidence:`known`,claimsReleased:[],claimsOrphaned:[],providerReleases:{status:`completed`,released:[],pending:[]},warnings:[]}}const Gi=async({positionals:e,flags:n})=>{if(e[0]!==`stop`||e.length!==1)throw new t(`INVALID_ARGS`,`daemon accepts only: stop`);let r=x(n.stateDir),i=Vi(r.infoPath),a=await zi({paths:r}),o=Ki(a,a.mode===`graceful`?Be(r.baseDir):null),s=n.clean===!0&&i!==null&&o.stopped;if(s){let[{cleanupRunnerLeasesForOwner:e},{runnerLeaseCleanupAdapter:t}]=await Promise.all([import(`./runner-lease.js`).then(e=>e.c),import(`./runner-disposal.js`).then(e=>e.s)]);await e({pid:i.pid,startTime:i.processStartTime},t)}let c={...o,clean:s};return k(n,c,()=>qi(c)),!0};function Ki(e,t){return e.mode!==`graceful`||t?t?{...e,providerReleases:{status:`completed`,...t.providerReleases}}:e:{...e,cleanupConfidence:`unknown`,providerReleases:{status:`unknown`,released:[],pending:null},warnings:[...e.warnings,`The graceful shutdown report is unavailable, so provider cleanup state is unknown. Provider allocations may remain active.`]}}function qi(e){return[e.stopped?`Daemon stopped (${e.mode}).`:`No running daemon found.`,e.clean?`Retained runner cleanup completed.`:null,...e.warnings].filter(e=>!!e).join(`
6
- `)}const Ji=async({positionals:e,flags:n})=>{if(e[0]!==`status`||e.length!==1)throw new t(`INVALID_ARGS`,`device accepts only: status`);let r=Ve({platform:n.platform,device:n.device,udid:n.udid,serial:n.serial}),i=r.filter(Yi),a=(n.stale?i:r.filter(e=>!Yi(e))).map(Xi);return k(n,{claims:a,...n.stale?{}:{hiddenStaleClaims:i.length}},()=>Zi(a,{staleOnly:n.stale===!0,hiddenStaleClaims:i.length,staleCommand:ta(n)})),!0};function Yi(e){return e.classification===`owner-process-dead`||e.classification===`owner-state-dir-gone`}function Xi(e){let t=e.claim;return{...e.deviceKey?{deviceKey:e.deviceKey}:{},...t?{}:{fileName:e.fileName},classification:e.classification,...t?{device:t.device,owner:{session:t.session,workspace:t.workspace,stateDir:t.stateDir,pid:t.ownerPid,startTime:t.ownerStartTime}}:{},...e.error?{error:e.error}:{}}}function Zi(e,t){let n=e.map(Qi);if(n.length===0){if(t.staleOnly)return`No stale local advisory device claims found.`;if(t.hiddenStaleClaims===0)return`No local advisory device claims found.`}return[...n,!t.staleOnly&&t.hiddenStaleClaims>0?`${t.hiddenStaleClaims} stale ${t.hiddenStaleClaims===1?`claim`:`claims`} hidden; inspect with: ${t.staleCommand}`:null].filter(e=>!!e).join(`
7
- `)}function Qi(e){return`${$i(e)}: ${e.classification}${ea(e.owner)}`}function $i(e){let t=e.device;return t?`${t.platform??`unknown`} ${t.name??t.id??`claim`}`:String(e.deviceKey??e.fileName??`claim`)}function ea(e){if(!e||typeof e!=`object`)return``;let t=e;return` session=${t.session} workspace=${t.workspace}`}function ta(e){return[`agent-device device status`,...[e.platform?`--platform ${b(e.platform)}`:null,e.device?`--device ${b(e.device)}`:null,e.udid?`--udid ${b(e.udid)}`:null,e.serial?`--serial ${b(e.serial)}`:null].filter(e=>!!e),`--stale`].join(` `)}const na=`${fe}/`,ra=[`content-type`,`content-range`,`x-artifact-type`,`x-artifact-filename`,`x-artifact-hash`,`x-artifact-hash-algorithm`,de],ia=[`content-type`,`content-disposition`,`x-request-id`];function aa(e){let t=_a(e);return nt.createServer((e,n)=>{oa(e,n,t).catch(e=>{Pa(n,e)})})}async function oa(e,t,n){let r=ba(e.url??`/`);if(e.method===`GET`&&r===`/health`){await sa(t,n);return}if(!xa(r,e.method)){t.statusCode=404,t.end(`Not found`);return}let i;if(r===`/rpc`&&(i=(await pe(e,n.maxRpcBodyBytes,`Proxy request body is too large.`)).toString(`utf8`)),!Da(e,n.clientToken,i)){Na(t,r,ja(i));return}await la({req:e,res:t,route:r,options:n,rpcBody:i})}async function sa(e,t){let n=await ca(t);e.statusCode=200,e.setHeader(`content-type`,`application/json`),e.end(JSON.stringify(le(`agent-device-proxy`,{upstream:n})))}async function ca(e){let t=new URL(ce(e.upstreamBaseUrl,`health`)),n=await e.fetchImpl(t,{method:`GET`,headers:Ta({headers:{}},e.upstreamToken,`/health`),signal:AbortSignal.timeout(e.upstreamTimeoutMs)}),r=await n.text();try{return r?JSON.parse(r):{ok:n.ok,status:n.status}}catch{return{ok:n.ok,status:n.status}}}async function la(e){let{req:t,res:n,route:r,options:i,rpcBody:a}=e,o=wa(i.upstreamBaseUrl,r,t.url??`/`),s=t.method??`GET`,c=Ta(t,i.upstreamToken,r),l=Ea(t,r,a,i.upstreamToken);await ua({req:t,res:n,route:r,response:await i.fetchImpl(o,{method:s,headers:c,signal:AbortSignal.timeout(i.upstreamTimeoutMs),...l?{body:l,duplex:`half`}:{}}),clientToken:i.clientToken})}async function ua(e){let{req:t,res:n,route:r,response:i,clientToken:a}=e;if(n.statusCode=i.status,da(i,n),fa(t,n),Ca(r)){await pa({req:t,res:n,response:i,clientToken:a});return}await ga(i,n)}function da(e,t){for(let n of ia){let r=e.headers.get(n);r&&t.setHeader(n,r)}}function fa(e,t){t.hasHeader(`x-request-id`)||t.setHeader(`x-request-id`,Ma(e))}async function pa(e){let{req:t,res:n,response:r,clientToken:i}=e,a=await r.text();n.setHeader(`content-type`,r.headers.get(`content-type`)??`application/json`),n.end(ma(a,t,i))}function ma(e,t,n){let r;try{r=JSON.parse(e)}catch{return e}if(!r||typeof r!=`object`)return e;let i=r;if(!i.upload||typeof i.upload.url!=`string`)return e;let a=ha(i.upload.url,t);if(!a)return e;let o=i.upload.headers&&typeof i.upload.headers==`object`?{...i.upload.headers}:{};return Object.assign(o,se(n)),JSON.stringify({...r,upload:{...i.upload,url:a,headers:o}})}function ha(e,t){let n;try{n=new URL(e)}catch{return null}if(!n.pathname.startsWith(`/upload/`))return null;let r=typeof t.headers.host==`string`?t.headers.host:``;if(!r)return null;let i=new URL(t.url??`/`,`http://127.0.0.1`).pathname,a=i.lastIndexOf(`/upload/preflight`),o=a>=0?i.slice(0,a):``,s=t.headers[`x-forwarded-proto`],c=Array.isArray(s)?s[0]:s,l=new URL(`${c||`http`}://${r}`);return l.pathname=`${o}${n.pathname}`,l.search=n.search,l.toString()}async function ga(e,t){if(!e.body){t.end();return}await rt(it.fromWeb(e.body),t)}function _a(e){return{upstreamBaseUrl:va(e.upstreamBaseUrl,`upstreamBaseUrl`),upstreamToken:ya(e.upstreamToken,`upstreamToken`),clientToken:ya(e.clientToken,`clientToken`),maxRpcBodyBytes:e.maxRpcBodyBytes??1048576,upstreamTimeoutMs:e.upstreamTimeoutMs??3e5,fetchImpl:e.fetchImpl??fetch}}function va(e,n){try{let t=new URL(e);if(t.protocol!==`http:`&&t.protocol!==`https:`)throw Error(`unsupported protocol`);return t.toString().replace(/\/+$/,``)}catch(r){throw new t(`INVALID_ARGS`,`Invalid ${n}`,{[n]:e},r)}}function ya(e,n){let r=e.trim();if(!r)throw new t(`INVALID_ARGS`,`Proxy ${n} is required.`);return r}function ba(e){let t=new URL(e,`http://127.0.0.1`).pathname;return t===`/agent-device`?`/`:t.startsWith(na)?`/${t.slice(na.length)}`:t}function xa(e,t){return e===`/rpc`?t===`POST`:Sa(e,t)?!0:e===`/artifacts`||e===`/artifacts/`||e.startsWith(`/artifacts/`)?t===`GET`:!1}function Sa(e,t){return e===`/upload`||Ca(e)||e===`/upload/finalize`?t===`POST`:e.startsWith(`/upload/direct/`)?t===`PUT`:!1}function Ca(e){return e===`/upload/preflight`}function wa(e,t,n){let r=new URL(ce(e,t)),i=n.indexOf(`?`);return i>=0&&(r.search=n.slice(i)),r}function Ta(e,t,n){let r=new Headers;for(let t of ra){let n=e.headers[t];typeof n==`string`&&n.trim()&&r.set(t,n)}n===`/rpc`&&!r.has(`content-type`)&&r.set(`content-type`,`application/json`);for(let[e,n]of Object.entries(se(t)))r.set(e,n);return r}function Ea(e,t,n,r){if(!(e.method===`GET`||e.method===`HEAD`))return t===`/rpc`?ka(n??``,r):e}function Da(e,t,n){let r=Oa(e,n);return r.length>0&&Ge(r,t)}function Oa(e,t){let n=typeof e.headers.authorization==`string`?e.headers.authorization:``;if(n.toLowerCase().startsWith(`bearer `))return n.slice(7);let r=e.headers[`x-agent-device-token`];if(typeof r==`string`)return r;if(t){let e=Aa(t);if(e)return e}return``}function ka(e,t){let n=JSON.parse(e);return n.params={...n.params??{},token:t},JSON.stringify(n)}function Aa(e){try{let t=JSON.parse(e);return typeof t.params?.token==`string`?t.params.token:``}catch{return``}}function ja(e){if(!e)return null;try{return JSON.parse(e).id??null}catch{return null}}function Ma(e){let t=e.headers[`x-request-id`];return typeof t==`string`&&t.trim()?t.trim().slice(0,128):tt()}function Na(n,r,i){if(n.statusCode=401,n.setHeader(`content-type`,`application/json`),r===`/rpc`){n.end(JSON.stringify({jsonrpc:`2.0`,id:i,error:{code:-32001,message:`Invalid proxy token`,data:e(new t(`UNAUTHORIZED`,`Invalid proxy token`))}}));return}n.end(JSON.stringify({ok:!1,error:`Invalid proxy token`,code:`UNAUTHORIZED`}))}function Pa(t,n){if(t.headersSent){t.destroy(n instanceof Error?n:void 0);return}let r=e(n);t.statusCode=r.code===`INVALID_ARGS`?400:500,t.setHeader(`content-type`,`application/json`),t.end(JSON.stringify({ok:!1,error:r.message,code:r.code}))}const Fa=async({positionals:e,flags:n})=>{if(e.length>0)throw new t(`INVALID_ARGS`,`proxy does not accept positional arguments.`);let r=await Ia(n);return k(n,r,()=>Va(r)),await Ha(),!0};async function Ia(e){let n=be({session:`default`,command:`proxy`,positionals:[],flags:{stateDir:e.stateDir,daemonBaseUrl:``,daemonTransport:`http`,daemonServerMode:`http`}}),r=await _e(n),i=La(r.info.httpPort),a=Ra(e),o=aa({upstreamBaseUrl:i,upstreamToken:r.info.token,clientToken:a});await za(o,e.proxyHost?.trim()||`127.0.0.1`,e.proxyPort??0);let s=o.address();if(!s||typeof s==`string`)throw new t(`COMMAND_FAILED`,`Proxy did not bind to a TCP address.`);let c=`http://${Ba(s.address)}:${s.port}`;return{proxyBaseUrl:c,agentDeviceBaseUrl:ge(c),token:a,upstreamBaseUrl:i,stateDir:n.paths.baseDir}}function La(e){if(!e)throw new t(`COMMAND_FAILED`,`Local daemon HTTP endpoint is unavailable.`,{hint:`Retry after cleaning daemon state, or run proxy with a fresh --state-dir.`});return`http://127.0.0.1:${e}`}function Ra(e){return e.daemonAuthToken?.trim()||et(32).toString(`hex`)}function za(e,t,n){return new Promise((r,i)=>{e.once(`error`,i),e.listen(n,t,()=>{e.off(`error`,i),r()})})}function Ba(e){return e.includes(`:`)&&!e.startsWith(`[`)?`[${e}]`:e}function Va(e,t={}){let n=t.useColor??m(),r=X(`✓`,`green`,n),i=X(e.proxyBaseUrl,`cyan`,n),a=X(`<tunnel URL>`,`cyan`,n),o=X(e.token,`yellow`,n);return[`${r} Proxy listening at ${i}`,``,`Provide this to the agent-device instance connecting:`,``,`Daemon base URL: ${a}`,`Daemon auth token: ${o}`].join(`
8
- `)}function X(e,t,n){return n?ae(e,t,{validateStream:!1}):e}function Ha(){return new Promise(()=>{})}function Z(e,t){return`${e},${t}`}function Ua(e){return`${e.map(e=>ot(e).trimEnd()).join(`
1
+ import{S as e,_ as t,a as n,v as r,w as i}from"./sdk-contracts.js";import{Ht as a,Ut as o,Vt as s,Wt as c,at as l,cn as u,ct as d,dn as f,fn as p,it as m,lt as h,ot as g,ut as ee}from"./viewport-dimension.js";import"./screenshot-geometry.js";import{H as te,p as ne,q as _}from"./sdk-batch-runner.js";import{d as re,gt as ie,h as v,ht as ae,mt as oe,p as se,pt as ce,r as le,st as ue,t as de,vt as fe,y}from"./screenshot-result.js";import{h as pe,i as me,s as he,v as ge}from"./sdk-device.js";import{a as _e,i as ve,n as ye,r as be}from"./agent-device-client.js";import{S as xe,l as Se,x as b}from"./registry.js";import{t as Ce}from"./sdk-remote-config.js";import"./sdk-selectors.js";import{n as we}from"./command-metadata.js";import{A as Te,L as Ee,M as x,N as S,P as De,S as Oe,j as ke,v as Ae}from"./sdk-android-adb.js";import{n as je}from"./version.js";import{n as C}from"./path-resolution.js";import{t as Me}from"./timeouts.js";import{n as Ne,u as Pe}from"./host-process.js";import{v as Fe}from"./url.js";import{a as Ie,i as Le}from"./client-metro.js";import{n as Re}from"./metro2.js";import{n as w,t as ze}from"./remote-config2.js";import{t as Be}from"./src.js";import{C as Ve,S as T,a as He,b as Ue,i as We,n as Ge,p as Ke,u as qe,w as Je,x as Ye,y as Xe}from"./selector-vocabulary.js";import{i as Ze,n as Qe,t as $e}from"./command-schema.js";import{t as et}from"./update-check.js";import{i as tt,r as E,t as nt}from"./cli-config.js";import{i as D,r as rt,t as it}from"./cli-runner.js";import O from"node:path";import k,{randomBytes as at,randomUUID as ot}from"node:crypto";import{parseReplayScriptDetailed as st,readReplayScriptMetadata as ct}from"@agent-device/ad-script";import A from"node:fs";import lt from"node:http";import{pipeline as ut}from"node:stream/promises";import{Readable as dt}from"node:stream";import{pathToFileURL as ft}from"node:url";import{stringify as pt}from"yaml";function mt(e,t){return`${e},${t}`}function ht(e){return`${e.map(e=>pt(e).trimEnd()).join(`
9
2
  ---
10
- `)}\n`}const Wa=new Set(He),Ga=new Set(Ue);function Ka(e){let t=ze(e);return qa(t.actions,{actionLines:t.actionLines,metadata:We(e)})}function qa(e,n={}){let r={config:Ja(n.metadata),warnings:[],unsupported:[]},i=[];for(let[t,a]of e.entries()){let e=n.actionLines?.[t]??t+1,o=Xa(a);switch(o.kind){case`commands`:i.push(...o.commands),Oo(r,o.warnings,a,e);break;case`config`:Eo(r,o.appId,a,e),i.push(...o.commands),Oo(r,o.warnings,a,e);break;case`unsupported`:r.unsupported.push({line:e,action:Mo(a),message:o.message});break}}if(r.unsupported.length>0)throw new t(`INVALID_ARGS`,`Cannot export replay to Maestro YAML: unsupported .ad action ${jo(r.unsupported)}.`,{unsupported:r.unsupported});return{yaml:Ao(r.config,i),warnings:r.warnings}}function Ja(e){return e?.env&&Object.keys(e.env).length>0?{env:e.env}:{}}const Ya={open:Za,click:eo,press:eo,longpress:to,fill:ao,type:oo,keyboard:so,back:()=>({kind:`commands`,commands:[`back`]}),wait:co,find:lo,screenshot:uo,scroll:fo,swipe:po};function Xa(e){return Ya[e.command]?.(e)??{kind:`unsupported`,message:`${e.command} has no Maestro equivalent`}}function Za(e){let[t,n]=e.positionals;if(!t)return{kind:`unsupported`,message:`open requires an app id or URL`};if(No(t))return{kind:`commands`,commands:[{openLink:t}]};let r=Qa(e,t);return n&&No(n)?{kind:`config`,appId:t,commands:[r,{openLink:n}]}:n?{kind:`unsupported`,message:`open with a non-URL second argument is unsupported`}:{kind:`config`,appId:t,commands:[r]}}function Qa(e,t){let n=$a(e);return n?{launchApp:{appId:t,...n}}:`launchApp`}function $a(e){let t=e.flags?.launchArgs,n={};return e.flags?.relaunch===!0&&(n.stopApp=!0),e.flags?.clearAppState===!0&&(n.clearState=!0),Array.isArray(t)&&t.length>0&&(n.launchArguments=t),Object.keys(n).length>0?n:void 0}function eo(e){let[t,n]=e.positionals;if(!t)return{kind:`unsupported`,message:`${e.command} requires a target`};let r=_o(t,n);if(!r)return{kind:`unsupported`,message:`tap target is not Maestro-compatible`};let i=So(e);return i.ok?e.flags?.doubleTap===!0?{kind:`commands`,commands:[{doubleTapOn:r}],warnings:io(e,`doubleTapOn`)}:typeof e.flags?.holdMs==`number`?{kind:`commands`,commands:[{longPressOn:r}],warnings:[ro(e.flags.holdMs),...io(e,`longPressOn`)]}:{kind:`commands`,commands:[To(r,i.options)]}:{kind:`unsupported`,message:i.message}}function to(e){let[t,n]=e.positionals;if(!t)return{kind:`unsupported`,message:`longpress requires a target`};let r=_o(t,n);return r?{kind:`commands`,commands:[{longPressOn:r}],warnings:no(e).map(ro)}:{kind:`unsupported`,message:`longpress target is not Maestro-compatible`}}function no(e){let[t,n,r]=e.positionals,i=Q(t)&&Q(n)?r:n;return i&&Q(i)?[Number(i)]:[]}function ro(e){return`long-press duration exports as Maestro longPressOn; Maestro uses its default long-press duration instead of ${e}ms`}function io(e,t){let n=[];return typeof e.flags?.count==`number`&&e.flags.count>1&&n.push(`tap --count ${e.flags.count} is not represented by Maestro ${t}`),typeof e.flags?.intervalMs==`number`&&e.flags.intervalMs>0&&n.push(`tap --interval-ms ${e.flags.intervalMs} is not represented by Maestro ${t}`),n}function ao(e){let[t,n]=e.positionals;if(!t||n===void 0)return{kind:`unsupported`,message:`fill requires a target and text`};let r=_o(t);return r?{kind:`commands`,commands:[{tapOn:r},{inputText:n}],warnings:[`fill exports as tapOn + inputText; Maestro may append text instead of replacing existing field contents`]}:{kind:`unsupported`,message:`fill target is not Maestro-compatible`}}function oo(e){let[t]=e.positionals;if(t===void 0)return{kind:`unsupported`,message:`type requires text`};let n=Do(t);return n===null?{kind:`commands`,commands:[{inputText:t}]}:{kind:`commands`,commands:[{eraseText:n}]}}function so(e){let[t]=e.positionals;return t===`dismiss`?{kind:`commands`,commands:[`hideKeyboard`]}:t===`enter`||t===`return`?{kind:`commands`,commands:[{pressKey:`Enter`}]}:{kind:`unsupported`,message:`keyboard ${t??``}`.trim()}}function co(e){let[t,n]=e.positionals;if(!t)return{kind:`unsupported`,message:`wait requires a target or duration`};if(Q(t))return{kind:`commands`,commands:[{waitForAnimationToEnd:{timeout:Number(t)}}],warnings:[`wait <ms> exports as waitForAnimationToEnd and may return before the full duration`]};if(t===`text`&&n)return{kind:`commands`,commands:[{extendedWaitUntil:{visible:n,timeout:ko(e,$e.extendedWaitUntilTimeoutMs)}}]};let r=vo(t);return r?{kind:`commands`,commands:[{extendedWaitUntil:{visible:r,timeout:ko(e,$e.extendedWaitUntilTimeoutMs)}}]}:{kind:`unsupported`,message:`wait selector is not Maestro-compatible`}}function lo(e){let[t,n,r]=e.positionals;return t!==`text`||!n||!r?{kind:`unsupported`,message:`only find text <query> exists|missing exports to Maestro`}:r===`exists`?{kind:`commands`,commands:[{assertVisible:n}]}:r===`missing`||r===`not-exists`?{kind:`commands`,commands:[{assertNotVisible:n}]}:{kind:`unsupported`,message:`find text assertion "${r}" is unsupported`}}function uo(e){let[t]=e.positionals;return t?{kind:`commands`,commands:[{takeScreenshot:t}]}:{kind:`unsupported`,message:`screenshot requires an output path`}}function fo(e){let[t]=e.positionals;return!t||t===`down`?{kind:`commands`,commands:[`scroll`]}:{kind:`unsupported`,message:`scroll ${t} is not exported yet`}}function po(e){let t=mo(e);if(!t)return{kind:`unsupported`,message:`only coordinate swipe exports to Maestro`};let n=ho(e);if(n===null)return{kind:`unsupported`,message:`swipe count must be a positive integer`};let r=go(e);return r?{kind:`unsupported`,message:r}:{kind:`commands`,commands:Array.from({length:n},()=>({swipe:t}))}}function mo(e){let[t,n,r,i]=e.positionals;if(!(!Q(t)||!Q(n)||!Q(r)||!Q(i)))return{start:Z(t,n),end:Z(r,i),duration:100}}function ho(e){let t=e.flags?.count??1;return Number.isInteger(t)&&t>=1?t:null}function go(e){if(e.flags?.pauseMs!==void 0)return`swipe --pause-ms has no Maestro equivalent`;if(e.flags?.pattern&&e.flags.pattern!==`one-way`)return`swipe ping-pong pattern has no Maestro equivalent`}function _o(e,t){return Q(e)&&Q(t)?{point:Z(e,t)}:e.startsWith(`@`)?null:vo(e)}function vo(e){let t;try{t=d(e)}catch{return e.includes(`=`)||e.includes(`||`)?null:e}let n=yo(t.selectors);return n===null?t.selectors.length===1?bo(t.selectors[0]):null:n}function yo(e){if(e.length<=1)return null;let t=e.flatMap(e=>e.terms.length===1&&Wa.has(e.terms[0].key)?[e.terms[0].value]:[]);if(t.length!==e.length||t.length===0)return null;let n=t[0];return typeof n==`string`&&t.every(e=>e===n)?n:null}function bo(e){let t={};for(let n of e.terms)if(!xo(t,n))return null;return Object.keys(t).length>0?t:null}function xo(e,t){return Wa.has(t.key)?typeof t.value!=`string`||e.id||e.text||e.label?!1:(e[t.key]=t.value,!0):Ga.has(t.key)&&typeof t.value==`boolean`?(e[t.key]=t.value,!0):!1}function So(e){let t=wo(e);return t?{ok:!1,message:t}:{ok:!0,options:Co(e)}}function Co(e){let t={};return typeof e.flags?.count==`number`&&e.flags.count>1&&(t.repeat=e.flags.count),typeof e.flags?.intervalMs==`number`&&e.flags.intervalMs>0&&(t.delay=e.flags.intervalMs),t}function wo(e){if(e.flags?.jitterPx!==void 0)return`tap --jitter-px has no Maestro equivalent`;if(e.flags?.clickButton&&e.flags.clickButton!==`primary`)return`tap --button ${e.flags.clickButton} has no Maestro equivalent`}function To(e,t){return Object.keys(t).length===0?{tapOn:e}:typeof e==`string`?{tapOn:{text:e,...t}}:e&&typeof e==`object`&&!Array.isArray(e)?{tapOn:{...e,...t}}:{tapOn:e}}function Eo(e,t,n,r){if(!e.config.appId){e.config.appId=t;return}e.config.appId!==t&&e.unsupported.push({line:r,action:Mo(n),message:`multiple app ids cannot be represented in one Maestro config (${e.config.appId} vs ${t})`})}function Do(e){return e.length===0||![...e].every(e=>e===`\b`)?null:e.length}function Oo(e,t,n,r){for(let i of t??[])e.warnings.push({line:r,action:Mo(n),message:i})}function ko(e,t){let n=e.positionals.at(-1);return n&&Q(n)?Number(n):t}function Ao(e,t){return Ua(Object.keys(e).length>0?[e,t]:[t])}function jo(e){return e.map(e=>`line ${e.line} (${e.action}): ${e.message}`).join(`; `)}function Mo(e){return[e.command,...e.positionals??[]].join(` `).trim()}function No(e){return/^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(e)}function Q(e){return e!==void 0&&Number.isFinite(Number(e))}const Po=async e=>{let{positionals:t}=e;return t[0]===`export`?await Io(e):Fo(e)};function Fo({positionals:e,flags:n}){if(e.length>1)throw new t(`INVALID_ARGS`,`replay accepts exactly one input path: replay <path>`);if(n.out!==void 0)throw new t(`INVALID_ARGS`,`replay --out is only supported with replay export.`);return!1}async function Io({positionals:e,flags:n}){Lo(e,n);let r=e[1];if(!r)throw new t(`INVALID_ARGS`,`replay export requires an input path.`);let i=S(r),a=Ka(j.readFileSync(i,`utf8`)),o=typeof n.out==`string`?S(n.out):void 0;o&&(j.mkdirSync(M.dirname(o),{recursive:!0}),j.writeFileSync(o,a.yaml));for(let e of a.warnings)process.stderr.write(`Warning: line ${e.line}: ${e.message}\n`);return k(n,{format:`maestro`,sourcePath:i,...o?{path:o}:{yaml:a.yaml},warnings:a.warnings},()=>o??a.yaml),!0}function Lo(e,n){if(e.length>2)throw new t(`INVALID_ARGS`,`replay export accepts exactly one input path: replay export <file.ad>`);if(n.replayUpdate)throw new t(`INVALID_ARGS`,`replay export does not support --update.`);if(n.replayMaestro)throw new t(`INVALID_ARGS`,`replay export reads .ad files; omit --maestro.`);if(n.replayEnv?.length)throw new t(`INVALID_ARGS`,`replay export does not evaluate --env substitutions.`)}const Ro=async({positionals:e,flags:t,client:r})=>{let i=await Qe({client:r,command:`screenshot`,positionals:e,flags:t});return n(t.responseLevel)?(k(t,i,()=>JSON.stringify(i,null,2)),!0):(k(t,me(i),()=>i.overlayRefs?`Annotated ${i.overlayRefs.length} refs onto ${i.path}`:Vo(i)),!0)},zo=async({positionals:e,flags:n,client:r})=>{if(e[0]===`snapshot`){let t=await Qe({client:r,command:`diff`,positionals:e,flags:n});return k(n,t,()=>re(t)),!0}if(e[0]!==`screenshot`)return!1;let i=n.baseline;if(!i||typeof i!=`string`)throw new t(`INVALID_ARGS`,`diff screenshot requires --baseline <path>`);let a=S(i),o=typeof n.out==`string`?S(n.out):void 0,s=e[1];if(e.length>2)throw new t(`INVALID_ARGS`,`diff screenshot accepts at most one current screenshot path`);let[{createAgentDevice:c,localCommandPolicy:l},{createLocalArtifactAdapter:u}]=await Promise.all([import(`./runtime.js`).then(e=>e.r),import(`./sdk-io.js`).then(e=>e.n)]),d=await c({backend:Bo(r,n),artifacts:u(),sessions:{get:e=>({name:e}),set:()=>{}},policy:l()}).capture.diffScreenshot({session:n.session,baseline:{kind:`path`,path:a},current:s?{kind:`path`,path:S(s)}:{kind:`live`},...o?{out:{kind:`path`,path:o}}:{},threshold:Uo(n.threshold),overlayRefs:n.overlayRefs,normalizeStatusBar:n.screenshotNormalizeStatusBar,surface:n.surface});return k(n,d,()=>te(d)),!0};function Bo(e,t){return{platform:Ho(t),captureScreenshot:async(t,n,r)=>me(await e.capture.screenshot({path:n,session:t.session,overlayRefs:r?.overlayRefs,pixelDensity:r?.pixelDensity,fullscreen:r?.fullscreen,normalizeStatusBar:r?.normalizeStatusBar,stabilize:r?.stabilize,surface:r?.surface}))}}function Vo(e){if(typeof e.width!=`number`||typeof e.height!=`number`)return e.path;let t=typeof e.pixelDensity==`number`?` @${e.pixelDensity}x`:``;return`${e.path} (${e.width}x${e.height}${t})`}function Ho(e){switch(e.platform){case`android`:case`linux`:case`macos`:return e.platform;default:return`ios`}}function Uo(e){if(!(e==null||e===``))return Number(e)}const Wo={connect:ti,disconnect:mi,connection:hi,auth:Li,daemon:Gi,device:Ji,proxy:Fa,replay:Po,screenshot:Ro,diff:zo};async function Go(e){let t={...e.flags},n=Wo[e.command];return n&&await n({...e,flags:t})?!0:sr(e.command)?await Ko({...e,command:e.command,flags:t}):!1}async function Ko(e){let{runGenericClientBackedCommand:t}=await import(`./generic.js`);return await t(e)}function qo(e){return[`exec`,`--yes`,`--package`,`agent-react-devtools@0.4.0`,`--`,`agent-react-devtools`,...e]}function Jo(e){return e===`ios-instance`}function Yo(e){return e[0]===`wait`&&e.includes(`--connected`)}function Xo(e,t,n){n===0||!Yo(e)||!Jo(t?.leaseBackend)||process.stderr.write([`Hint: Remote iOS React DevTools connects during JavaScript startup.`,"If the app was already open before `agent-device react-devtools start`, relaunch it with `agent-device open <bundle-id> --platform ios --relaunch`, then retry `agent-device react-devtools wait --connected`.",``].join(`
11
- `))}function $(e,t,n){return n||(e.push(t),``)}function Zo(e){if(!e?.metroProxyBaseUrl||!Ht(e.leaseBackend))return null;let n=[],r={serverBaseUrl:$(n,`metroProxyBaseUrl`,e.metroProxyBaseUrl),bearerToken:$(n,`metroBearerToken`,e.metroBearerToken),tenantId:$(n,`tenant`,e.tenant),runId:$(n,`runId`,e.runId),leaseId:$(n,`leaseId`,e.leaseId)};if(n.length>0)throw new t(`INVALID_ARGS`,`react-devtools remote bridge requires ${n.join(`, `)}.`,{missing:n});return r}async function Qo(e,t,n){let{flags:r}=t,i=Zo(r);if(!i)return n();let a=t.stateDir??process.cwd(),o=t.session??r?.session??`default`,s=r?.remoteConfig??`${i.tenantId}:${i.runId}:${i.leaseId}`;if(e[0]===`stop`)try{return await n()}finally{await Vt({projectRoot:t.cwd??process.cwd(),stateDir:a,profileKey:s,consumerKey:o})}return await Bt({projectRoot:t.cwd??process.cwd(),stateDir:a,serverBaseUrl:i.serverBaseUrl,bearerToken:i.bearerToken,bridgeScope:{tenantId:i.tenantId,runId:i.runId,leaseId:i.leaseId},session:o,profileKey:s,consumerKey:o,env:t.env??process.env}),await n()}function $o(e,t){if(e[0]!==`start`)return!1;let{flags:n}=t;return n?n.leaseProvider===`limrun`&&n.leaseBackend===`android-instance`&&n.metroProxyBaseUrl===void 0&&t.configureDirectPortReverse!==void 0:!1}async function es(e,t={}){let n=t.cwd??process.cwd(),r=t.env??process.env,i=await Qo(e,t,async()=>($o(e,t)&&await t.configureDirectPortReverse?.(),(await c(`npm`,qo(e),{cwd:n,env:r,allowFailure:!0,onStdoutChunk:e=>{process.stdout.write(e)},onStderrChunk:e=>{process.stderr.write(e)}})).exitCode));return Xo(e,t.flags,i),i}async function ts(e,n){switch(e[0]){case`setup`:{ns(n.flags.json);let{setupManagedAgentBrowser:e}=await import(`./agent-browser-tool.js`).then(e=>e.t),t=await e({stateDir:n.stateDir});return rs(n.flags.json,t),0}case`doctor`:{let{doctorManagedAgentBrowser:e}=await import(`./agent-browser-tool.js`).then(e=>e.t),t=await e({stateDir:n.stateDir});return is(n.flags.json,t.exitCode===0?`Web backend is healthy.`:`Web backend doctor reported issues.`,t),t.exitCode}default:throw new t(`INVALID_ARGS`,`web requires setup or doctor`)}}function ns(e){e||process.stdout.write(`Setting up managed agent-browser backend (downloads if needed)...
12
- `)}function rs(e,t){if(e){v({success:!0,data:{status:as(t)}});return}process.stdout.write(`Managed web backend installed.\nagent-browser available at: ${t.binaryPath}\n`)}function is(e,t,n){if(e){v({success:!0,data:os(n)});return}process.stdout.write(`${t}\n`)}function as(e){let{socketDir:t,...n}=e;return n}function os(e){let t=e.status;return ss(t)?{...e,status:as(t)}:e}function ss(e){return typeof e==`object`&&!!e&&`socketDir`in e&&`installDir`in e&&`binaryPath`in e}function cs(e){let n;try{n=JSON.parse(e)}catch{throw new t(`INVALID_ARGS`,`Batch steps must be valid JSON.`)}if(!Array.isArray(n)||n.length===0)throw new t(`INVALID_ARGS`,`Batch steps must be a non-empty JSON array.`);return ls(n)}function ls(e){let t=!1,n=e.map((e,n)=>{if(ds(e))return fs(e,n+1);let r=ps(e,n+1);return t=!0,us(r)});return t&&process.stderr.write(`Warning: batch steps using positionals/flags are deprecated and will be removed in the next major version. Use {"command":"...","input":{...}} steps instead.
13
- `),n}function us(e){let t=Ze(e.command,e.positionals??[],vs(e.flags));return{command:e.command,input:t,...e.runtime===void 0?{}:{runtime:e.runtime}}}function ds(e){return p(e)&&`input`in e&&!(`positionals`in e)&&!(`flags`in e)}function fs(e,t){let n=f(e.runtime,t),{runtime:r,...i}=e;return{...i,...n===void 0?{}:{runtime:n}}}function ps(e,n){if(!p(e))throw new t(`INVALID_ARGS`,`Invalid batch step ${n}.`);hs(e,n);let r=ms(e.command,n),i=gs(e.positionals,n);qe(r,i??[],`Batch step ${n}`);let a=_s(e.flags,n),o=f(e.runtime,n);return{command:r,...i===void 0?{}:{positionals:i},...a===void 0?{}:{flags:a},...o===void 0?{}:{runtime:o}}}function ms(e,n){let r=typeof e==`string`?e.trim().toLowerCase():``;if(!r)throw new t(`INVALID_ARGS`,`Batch step ${n} requires command.`);if(Fe(r))return r;throw new t(`INVALID_ARGS`,`Batch step ${n} command is not available through command batch: ${String(e)}`)}function hs(e,n){let r=Object.keys(e).filter(e=>![`command`,`positionals`,`flags`,`runtime`].includes(e));if(r.length>0)throw new t(`INVALID_ARGS`,`Batch step ${n} has unknown legacy field(s): ${r.join(`, `)}.`)}function gs(e,n){if(e!==void 0){if(!Array.isArray(e)||e.some(e=>typeof e!=`string`))throw new t(`INVALID_ARGS`,`Batch step ${n} positionals must contain only strings.`);return e}}function _s(e,n){if(e!==void 0){if(!p(e))throw new t(`INVALID_ARGS`,`Batch step ${n} flags must be an object.`);return e}}function vs(e){return{json:!1,help:!1,version:!1,...e}}function ys(e,t={}){let n=bs(t),r={...e};return n.defaultPlatform&&r.platform===void 0&&(r.platform=n.defaultPlatform),r}function bs(e){let t=e.env??process.env,n=e.inheritedPlatform??e.configuredPlatform??Ss(t.AGENT_DEVICE_PLATFORM),r=ws(e.configuredSession??t.AGENT_DEVICE_SESSION);return{defaultPlatform:n,lockPolicy:xs(e.policyOverrides,t,r)}}function xs(e,t,n){let r=e?.sessionLock??Cs(t.AGENT_DEVICE_SESSION_LOCK);if(r)return r;if(n)return`reject`}function Ss(e){if(e===void 0)return;let n=e.trim().toLowerCase();if(n){if(n===`ios`||n===`android`||n===`apple`)return n;throw new t(`INVALID_ARGS`,`Invalid AGENT_DEVICE_PLATFORM: ${e}. Use ios, android, or apple.`)}}function Cs(e){if(e===void 0)return;let n=e.trim().toLowerCase();if(n){if(n===`reject`||n===`strip`)return n;throw new t(`INVALID_ARGS`,`Invalid session lock mode: ${e}. Use reject or strip.`)}}function ws(e){return typeof e==`string`&&e.trim().length>0}function Ts(e,t){let n=yt(e),r=t?.env??process.env,i=t?.cwd??process.cwd(),a=Es(n.command)?bn({remoteConfig:n.flags.remoteConfig,cwd:i,env:r}):{},o=D(Xe({command:n.command,cwd:i,cliFlags:n.flags,env:r}),a);return{...Tt(n,{strictFlags:t?.strictFlags,defaultFlags:o}),providedFlags:n.providedFlags}}function Es(e){return e!==null}const Ds={sendToDaemon:ve},Os=new Set([`launchUrl`,`kind`,`metroBearerToken`,`metroKind`,`metroListenHost`,`metroNoInstallDeps`,`metroNoReuseExisting`,`metroPreparePort`,`metroProbeTimeoutMs`,`metroProjectRoot`,`metroProxyBaseUrl`,`metroPublicBaseUrl`,`metroRuntimeFile`,`metroStartupTimeoutMs`,`metroStatusHost`]),ks=new Set([`connect`,`connection`,`close`,`daemon`,`device`,`disconnect`,`metro`,`proxy`,`session`]);async function As(e,t=Ds){let n=i(),r=Se(),o=Vs(e),s=e.includes(`--json`);await a({session:rc(e)??process.env.AGENT_DEVICE_SESSION??`default`,requestId:n,command:e[0],debug:o},async()=>{let{parsed:i,command:a,positionals:c}=await js(e,{version:r,jsonRequested:s,debugEnabled:o}),l=Ws(a,i.providedFlags),u=Ms(i,{command:a,positionals:c,requestId:n,debugOutputEnabled:l}),d=null;try{if(a===`react-devtools`){process.exit(await Ns(u,t));return}if(a===`web`){process.exit(await ts(c,{flags:u.effectiveFlags,stateDir:u.daemonPaths.baseDir}));return}if(Ye({command:a,currentVersion:r,stateDir:u.daemonPaths.baseDir,flags:u.effectiveFlags}),await Ps(u,t),a===`cdp`){process.exit(await Yt(c,{flags:u.effectiveFlags,runtime:u.resolvedRuntime,cwd:process.cwd(),env:process.env}));return}d=Is(u);let e=await Ls(u);await Rs(u,ye(Fs(u),{transport:ec({command:a,flags:u.effectiveFlags,replayTestReporterRuntime:e,transport:t.sendToDaemon})}),e)}catch(e){zs(e,u,d)}finally{d&&d()}})}async function js(n,r){let i;try{i=Ts(n,{cwd:process.cwd(),env:process.env})}catch(t){l({level:`error`,phase:`cli_parse_failed`,data:{error:t instanceof Error?t.message:String(t)}});let n=e(t,{diagnosticId:s().diagnosticId,logPath:o({force:!0})??void 0});r.jsonRequested?v({success:!1,error:n}):y(n,{showDetails:r.debugEnabled}),process.exit(1)}for(let e of i.warnings)process.stderr.write(`Warning: ${e}\n`);i.flags.version&&(process.stdout.write(`${r.version}\n`),process.exit(0));let a=i.command===`help`,c=i.flags.help;if(a||c){a&&i.positionals.length>1&&(y(new t(`INVALID_ARGS`,`help accepts at most one command.`)),process.exit(1));let e=a?i.positionals[0]:i.command;e||(process.stdout.write(`${await It()}\n`),process.exit(0));let n=await Lt(e);n&&(process.stdout.write(n),process.exit(0)),y(new t(`INVALID_ARGS`,Hs(e))),process.stdout.write(`${await It()}\n`),process.exit(1)}return i.command||(process.stdout.write(`${await It()}\n`),process.exit(1)),{parsed:i,command:i.command,positionals:i.positionals}}function Ms(t,n){let i=new Set(t.providedFlags.map(e=>e.key));try{let e=bs({policyOverrides:t.flags,configuredPlatform:t.flags.platform,configuredSession:t.flags.session}),r=e.lockPolicy?{...t.flags}:ys(t.flags,{policyOverrides:t.flags,configuredPlatform:t.flags.platform,configuredSession:t.flags.session}),a=x(r.stateDir),o=r.session??`default`,s=qs({command:n.command,explicitFlagKeys:i,stateDir:a.baseDir,session:o,remoteConfig:r.remoteConfig,hasResolvedSession:r.session!==void 0}),c=s?Qs(r,s.flags,i):r;return{...n,binding:e,flags:r,daemonPaths:a,sessionName:o,connectionDefaults:s,explicitFlagKeys:i,effectiveFlags:c,resolvedRuntime:s?.runtime,connectionMetadata:s?.connection,parsedBatchSteps:void 0}}catch(i){let a=e(r(i),{diagnosticId:s().diagnosticId,logPath:o({force:!0})??void 0});t.flags.json?v({success:!1,error:a}):y(a,{showDetails:n.debugOutputEnabled}),process.exit(1)}}async function Ns(e,t){return await es(e.positionals,{flags:{...e.effectiveFlags,leaseProvider:e.connectionDefaults?.connection?.leaseProvider},stateDir:e.daemonPaths.baseDir,session:e.effectiveFlags.session??e.sessionName,cwd:process.cwd(),env:process.env,configureDirectPortReverse:async()=>{let n=await t.sendToDaemon({command:g.runtime,positionals:[`port-reverse`],flags:{...e.effectiveFlags,leaseProvider:e.connectionDefaults?.connection?.leaseProvider,devicePort:8097,hostPort:8097,portReverseName:`react-devtools`},session:e.effectiveFlags.session??e.sessionName});n.ok||xe(n.error)}})}async function Ps(e,n){if(e.command===`batch`){if(e.positionals.length>0)throw new t(`INVALID_ARGS`,`batch does not accept positional arguments.`);e.parsedBatchSteps=Gs(e.flags)}if(Ys(e.command)&&(e.effectiveFlags=(await ur({command:e.command,flags:e.effectiveFlags,stateDir:e.daemonPaths.baseDir,env:process.env})).flags),e.effectiveFlags.remoteConfig&&Js(e.command)){let t=ye(Fs(e),{transport:tc(n.sendToDaemon)}),r=await On({command:e.command,flags:e.effectiveFlags,client:t,runtime:e.resolvedRuntime,positionals:e.positionals,batchSteps:e.parsedBatchSteps,forceRuntimePrepare:$s(e.explicitFlagKeys)});e.effectiveFlags=r.flags,e.resolvedRuntime=r.runtime,e.connectionMetadata=r.connection}Xs({command:e.command,flags:e.effectiveFlags,runtime:e.resolvedRuntime,explicitFlagKeys:e.explicitFlagKeys,hadConnectionDefaults:!!e.connectionDefaults})&&process.stderr.write(`Warning: open is using explicit remote daemon or tenant flags without saved Metro runtime hints. React Native apps may launch without bundle/runtime hints; prefer connect --remote-config <path> first or pass --remote-config <path> on this command.
14
- `)}function Fs(e){let t=e.effectiveFlags,n=e.connectionMetadata;return{session:t.session,requestId:e.requestId,stateDir:t.stateDir,daemonBaseUrl:t.daemonBaseUrl,daemonAuthToken:t.daemonAuthToken,daemonTransport:t.daemonTransport,daemonServerMode:t.daemonServerMode,tenant:t.tenant,sessionIsolation:t.sessionIsolation,runId:t.runId,leaseId:t.leaseId,leaseBackend:t.leaseBackend,leaseProvider:n?.leaseProvider,clientId:n?.clientId,deviceKey:n?.deviceKey,providerApp:t.providerApp,providerOsVersion:t.providerOsVersion,providerProject:t.providerProject,providerBuild:t.providerBuild,providerSessionName:t.providerSessionName,awsProjectArn:t.awsProjectArn,awsDeviceArn:t.awsDeviceArn,awsAppArn:t.awsAppArn,awsRegion:t.awsRegion,awsInteractionMode:t.awsInteractionMode,runtime:e.resolvedRuntime,lockPolicy:e.binding.lockPolicy,lockPlatform:e.binding.defaultPlatform,cwd:process.cwd(),debug:e.debugOutputEnabled,cost:t.cost,responseLevel:t.responseLevel}}function Is(e){let t=e.effectiveFlags.daemonBaseUrl;return e.debugOutputEnabled&&!e.effectiveFlags.json&&!t?ic(e.daemonPaths.logPath):null}async function Ls(e){if(e.command!==`test`)return;let{createReplayTestReporterRuntime:t}=await import(`./reporting.js`);return t({debug:e.debugOutputEnabled,verbose:e.effectiveFlags.verbose,json:e.effectiveFlags.json,reporter:e.effectiveFlags.reporter,reportJunit:e.effectiveFlags.reportJunit})}async function Rs(e,n,r){let{command:i,positionals:a,effectiveFlags:o}=e;if(i===`batch`){if(!e.parsedBatchSteps)throw new t(`INVALID_ARGS`,`batch requires --steps or --steps-file.`);let s=e.parsedBatchSteps.map((t,n)=>({...t,input:e.binding.lockPolicy&&e.flags.platform===void 0?{...t.input}:ys(t.input,{policyOverrides:o,configuredPlatform:o.platform,configuredSession:o.session,inheritedPlatform:o.platform})}));if(await Go({command:i,positionals:a,flags:{...o,batchSteps:s},client:n,debug:e.debugOutputEnabled,replayTestReporterRuntime:r}))return}else if(i===`runtime`)throw new t(`INVALID_ARGS`,`runtime command was removed. Use connect --remote-config <path> for remote runs, or metro prepare --remote-config <path> for inspection.`);else if(await Go({command:i,positionals:a,flags:o,client:n,debug:e.debugOutputEnabled,replayTestReporterRuntime:r}))return;throw new t(`INVALID_ARGS`,Us(i))}function zs(t,n,i){let a=r(t),c=e(a,{diagnosticId:s().diagnosticId,logPath:o({force:!0})??void 0});if(n.command===`close`&&Ks(a)){n.effectiveFlags.json&&v({success:!0,data:{closed:`session`,source:`no-daemon`}});return}n.effectiveFlags.json?v({success:!1,error:c}):(y(c,{showDetails:n.debugOutputEnabled}),n.debugOutputEnabled&&Bs(n.daemonPaths.logPath)),i&&i(),process.exit(1)}function Bs(e){try{if(j.existsSync(e)){let t=j.readFileSync(e,`utf8`).split(`
3
+ `)}\n`}const gt=new Set(We),_t=new Set(Ge);function vt(e,n){let r={config:yt(n.metadata),warnings:[],unsupported:[]},i=[];for(let[t,a]of e.entries()){let e=n.actionLines?.[t]??t+1,o=xt(a,n.parseSelector);switch(o.kind){case`commands`:i.push(...o.commands),Qt(r,o.warnings,a,e);break;case`config`:Xt(r,o.appId,a,e),i.push(...o.commands),Qt(r,o.warnings,a,e);break;case`unsupported`:r.unsupported.push({line:e,action:nn(a),message:o.message});break}}if(r.unsupported.length>0)throw new t(`INVALID_ARGS`,`Cannot export replay to Maestro YAML: unsupported .ad action ${tn(r.unsupported)}.`,{unsupported:r.unsupported});return{yaml:en(r.config,i),warnings:r.warnings}}function yt(e){return e?.env&&Object.keys(e.env).length>0?{env:e.env}:{}}const bt={open:St,click:Tt,press:Tt,longpress:Et,fill:At,type:jt,keyboard:Mt,back:()=>({kind:`commands`,commands:[`back`]}),wait:Nt,find:Pt,screenshot:Ft,scroll:It,swipe:Lt};function xt(e,t){return bt[e.command]?.(e,t)??{kind:`unsupported`,message:`${e.command} has no Maestro equivalent`}}function St(e){let[t,n]=e.positionals;if(!t)return{kind:`unsupported`,message:`open requires an app id or URL`};if(rn(t))return{kind:`commands`,commands:[{openLink:t}]};let r=Ct(e,t);return n&&rn(n)?{kind:`config`,appId:t,commands:[r,{openLink:n}]}:n?{kind:`unsupported`,message:`open with a non-URL second argument is unsupported`}:{kind:`config`,appId:t,commands:[r]}}function Ct(e,t){let n=wt(e);return n?{launchApp:{appId:t,...n}}:`launchApp`}function wt(e){let t=e.flags?.launchArgs,n={};return e.flags?.relaunch===!0&&(n.stopApp=!0),e.flags?.clearAppState===!0&&(n.clearState=!0),Array.isArray(t)&&t.length>0&&(n.launchArguments=t),Object.keys(n).length>0?n:void 0}function Tt(e,t){let[n,r]=e.positionals;if(!n)return{kind:`unsupported`,message:`${e.command} requires a target`};let i=Vt(n,r,t);if(!i)return{kind:`unsupported`,message:`tap target is not Maestro-compatible`};let a=Kt(e);return a.ok?e.flags?.doubleTap===!0?{kind:`commands`,commands:[{doubleTapOn:i}],warnings:kt(e,`doubleTapOn`)}:typeof e.flags?.holdMs==`number`?{kind:`commands`,commands:[{longPressOn:i}],warnings:[Ot(e.flags.holdMs),...kt(e,`longPressOn`)]}:{kind:`commands`,commands:[Yt(i,a.options)]}:{kind:`unsupported`,message:a.message}}function Et(e,t){let[n,r]=e.positionals;if(!n)return{kind:`unsupported`,message:`longpress requires a target`};let i=Vt(n,r,t);return i?{kind:`commands`,commands:[{longPressOn:i}],warnings:Dt(e).map(Ot)}:{kind:`unsupported`,message:`longpress target is not Maestro-compatible`}}function Dt(e){let[t,n,r]=e.positionals,i=j(t)&&j(n)?r:n;return i&&j(i)?[Number(i)]:[]}function Ot(e){return`long-press duration exports as Maestro longPressOn; Maestro uses its default long-press duration instead of ${e}ms`}function kt(e,t){let n=[];return typeof e.flags?.count==`number`&&e.flags.count>1&&n.push(`tap --count ${e.flags.count} is not represented by Maestro ${t}`),typeof e.flags?.intervalMs==`number`&&e.flags.intervalMs>0&&n.push(`tap --interval-ms ${e.flags.intervalMs} is not represented by Maestro ${t}`),n}function At(e,t){let[n,r]=e.positionals;if(!n||r===void 0)return{kind:`unsupported`,message:`fill requires a target and text`};let i=Vt(n,void 0,t);return i?{kind:`commands`,commands:[{tapOn:i},{inputText:r}],warnings:[`fill exports as tapOn + inputText; Maestro may append text instead of replacing existing field contents`]}:{kind:`unsupported`,message:`fill target is not Maestro-compatible`}}function jt(e){let[t]=e.positionals;if(t===void 0)return{kind:`unsupported`,message:`type requires text`};let n=Zt(t);return n===null?{kind:`commands`,commands:[{inputText:t}]}:{kind:`commands`,commands:[{eraseText:n}]}}function Mt(e){let[t]=e.positionals;return t===`dismiss`?{kind:`commands`,commands:[`hideKeyboard`]}:t===`enter`||t===`return`?{kind:`commands`,commands:[{pressKey:`Enter`}]}:{kind:`unsupported`,message:`keyboard ${t??``}`.trim()}}function Nt(e,t){let[n,r]=e.positionals;if(!n)return{kind:`unsupported`,message:`wait requires a target or duration`};if(j(n))return{kind:`commands`,commands:[{waitForAnimationToEnd:{timeout:Number(n)}}],warnings:[`wait <ms> exports as waitForAnimationToEnd and may return before the full duration`]};if(n===`text`&&r)return{kind:`commands`,commands:[{extendedWaitUntil:{visible:r,timeout:$t(e,He.extendedWaitUntilTimeoutMs)}}]};let i=Ht(n,t);return i?{kind:`commands`,commands:[{extendedWaitUntil:{visible:i,timeout:$t(e,He.extendedWaitUntilTimeoutMs)}}]}:{kind:`unsupported`,message:`wait selector is not Maestro-compatible`}}function Pt(e){let[t,n,r]=e.positionals;return t!==`text`||!n||!r?{kind:`unsupported`,message:`only find text <query> exists|missing exports to Maestro`}:r===`exists`?{kind:`commands`,commands:[{assertVisible:n}]}:r===`missing`||r===`not-exists`?{kind:`commands`,commands:[{assertNotVisible:n}]}:{kind:`unsupported`,message:`find text assertion "${r}" is unsupported`}}function Ft(e){let[t]=e.positionals;return t?{kind:`commands`,commands:[{takeScreenshot:t}]}:{kind:`unsupported`,message:`screenshot requires an output path`}}function It(e){let[t]=e.positionals;return!t||t===`down`?{kind:`commands`,commands:[`scroll`]}:{kind:`unsupported`,message:`scroll ${t} is not exported yet`}}function Lt(e){let t=Rt(e);if(!t)return{kind:`unsupported`,message:`only coordinate swipe exports to Maestro`};let n=zt(e);if(n===null)return{kind:`unsupported`,message:`swipe count must be a positive integer`};let r=Bt(e);return r?{kind:`unsupported`,message:r}:{kind:`commands`,commands:Array.from({length:n},()=>({swipe:t}))}}function Rt(e){let[t,n,r,i]=e.positionals;if(!(!j(t)||!j(n)||!j(r)||!j(i)))return{start:mt(t,n),end:mt(r,i),duration:100}}function zt(e){let t=e.flags?.count??1;return Number.isInteger(t)&&t>=1?t:null}function Bt(e){if(e.flags?.pauseMs!==void 0)return`swipe --pause-ms has no Maestro equivalent`;if(e.flags?.pattern&&e.flags.pattern!==`one-way`)return`swipe ping-pong pattern has no Maestro equivalent`}function Vt(e,t,n){return j(e)&&j(t)?{point:mt(e,t)}:e.startsWith(`@`)?null:Ht(e,n)}function Ht(e,t){let n;try{n=t(e)}catch{return e.includes(`=`)||e.includes(`||`)?null:e}let r=Ut(n.selectors);return r===null?n.selectors.length===1?Wt(n.selectors[0]):null:r}function Ut(e){if(e.length<=1)return null;let t=e.flatMap(e=>e.terms.length===1&&gt.has(e.terms[0].key)?[e.terms[0].value]:[]);if(t.length!==e.length||t.length===0)return null;let n=t[0];return typeof n==`string`&&t.every(e=>e===n)?n:null}function Wt(e){let t={};for(let n of e.terms)if(!Gt(t,n))return null;return Object.keys(t).length>0?t:null}function Gt(e,t){return gt.has(t.key)?typeof t.value!=`string`||e.id||e.text||e.label?!1:(e[t.key]=t.value,!0):_t.has(t.key)&&typeof t.value==`boolean`?(e[t.key]=t.value,!0):!1}function Kt(e){let t=Jt(e);return t?{ok:!1,message:t}:{ok:!0,options:qt(e)}}function qt(e){let t={};return typeof e.flags?.count==`number`&&e.flags.count>1&&(t.repeat=e.flags.count),typeof e.flags?.intervalMs==`number`&&e.flags.intervalMs>0&&(t.delay=e.flags.intervalMs),t}function Jt(e){if(e.flags?.jitterPx!==void 0)return`tap --jitter-px has no Maestro equivalent`;if(e.flags?.clickButton&&e.flags.clickButton!==`primary`)return`tap --button ${e.flags.clickButton} has no Maestro equivalent`}function Yt(e,t){return Object.keys(t).length===0?{tapOn:e}:typeof e==`string`?{tapOn:{text:e,...t}}:e&&typeof e==`object`&&!Array.isArray(e)?{tapOn:{...e,...t}}:{tapOn:e}}function Xt(e,t,n,r){if(!e.config.appId){e.config.appId=t;return}e.config.appId!==t&&e.unsupported.push({line:r,action:nn(n),message:`multiple app ids cannot be represented in one Maestro config (${e.config.appId} vs ${t})`})}function Zt(e){return e.length===0||![...e].every(e=>e===`\b`)?null:e.length}function Qt(e,t,n,r){for(let i of t??[])e.warnings.push({line:r,action:nn(n),message:i})}function $t(e,t){let n=e.positionals.at(-1);return n&&j(n)?Number(n):t}function en(e,t){return ht(Object.keys(e).length>0?[e,t]:[t])}function tn(e){return e.map(e=>`line ${e.line} (${e.action}): ${e.message}`).join(`; `)}function nn(e){return[e.command,...e.positionals??[]].join(` `).trim()}function rn(e){return/^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(e)}function j(e){return e!==void 0&&Number.isFinite(Number(e))}const an=new Map([{alias:`long-press`,command:`longpress`},{alias:`metrics`,command:`perf`},{alias:`tap`,command:`press`},{alias:`launch`,command:`open`},{alias:`relaunch`,command:`open`,impliedFlags:[`relaunch`]}].map(e=>[e.alias,e]));function on(e){return an.get(e.toLowerCase())?.command??e}function sn(e){return an.get(e.toLowerCase())}const cn=`open <app> --relaunch`,ln={start:{command:`open`,example:cn},restart:{command:`open`,example:cn},touch:{command:`press`,example:`press`},input:{command:`fill`,example:`fill`},settext:{command:`fill`,example:`fill`},entertext:{command:`fill`,example:`fill`},screencap:{command:`screenshot`,example:`screenshot`},capture:{command:`screenshot`,example:`screenshot`},dismiss:{command:`keyboard`,example:`keyboard dismiss`},"get-text":{command:`get`,example:`get text`},gettext:{command:`get`,example:`get text`},get_text:{command:`get`,example:`get text`},"open-url":{command:`open`,example:`open <url>`},"close-session":{command:`close`,example:`close`}};function un(e){if(e.length<=2)return[];let t=c(),n=t.filter(t=>t.startsWith(e));if(n.length>0)return n.sort((e,t)=>e.length-t.length||e.localeCompare(t)).slice(0,3);let r=dn(e),i=t.map(t=>({name:t,distance:fn(e,t)})).filter(e=>e.distance<=r);if(i.length===0)return[];let a=Math.min(...i.map(e=>e.distance));return i.filter(e=>e.distance===a).sort((e,t)=>e.name.localeCompare(t.name)).slice(0,3).map(e=>e.name)}function dn(e){return e.length<4?1:e.length<=6?2:3}function fn(e,t){return e===t?0:e.startsWith(t)||t.startsWith(e)?Math.abs(e.length-t.length):pn(e,t)}function pn(e,t){let n=e.length+1,r=t.length+1,i=Array.from({length:n},()=>Array(r).fill(0));for(let e=0;e<n;e+=1)i[e][0]=e;for(let e=0;e<r;e+=1)i[0][e]=e;for(let a=1;a<n;a+=1)for(let n=1;n<r;n+=1){let r=e[a-1]===t[n-1]?0:1;i[a][n]=Math.min(i[a-1][n]+1,i[a][n-1]+1,i[a-1][n-1]+r)}return i[n-1][r-1]}function mn(e){let t=e.toLowerCase(),n=ln[t]?.example;if(n)return n;let r=un(t);if(r.length!==0)return r.length===1?r[0]:`one of: ${r.join(`, `)}`}const hn=new Set([`--bundle-id`,`--bundleid`,`--bundle`,`--package`,`--package-name`,`--packagename`,`--app-id`,`--appid`,`--pkg`]),gn=new Set([`--session-locked`,`--session-lock-conflicts`]);function _n(e){return hn.has(e.toLowerCase())?`Unknown flag: ${e}. The app or bundle id is a positional argument, e.g. ${cn}.`:gn.has(e.toLowerCase())?`Unknown flag: ${e}. Use --session-lock reject|strip instead.`:`Unknown flag: ${e}`}function vn(e){let n={json:!1,help:!1,version:!1},r=null,i=null,a=[],o=[],s=[],c=!0;for(let o=0;o<e.length;o+=1){let l=e[o];if(c&&l===`--`){c=!1;continue}if(!c){r?a.push(l):(i=l,r=Ln(l));continue}if(Sn(r)){a.push(l);continue}let u=l.startsWith(`--`),d=l.startsWith(`-`)&&l.length>1;if(!u&&!d){r?a.push(l):(i=l,r=Ln(l));continue}let[f,p]=u?En(l):[l,void 0];if(bn(r,f))continue;let m=Cn(f,r);if(xn(r,m)){a.push(l);continue}if(!m){if(jn(r,a,l)){r?a.push(l):r=l;continue}throw new t(`INVALID_ARGS`,_n(f))}let h=Dn(m,f,p,e[o+1]);h.consumeNext&&(o+=1);let g=n[m.key];if(m.multiple){let e=Array.isArray(g)?[...g,h.value]:g===void 0?[h.value]:[g,h.value];n[m.key]=e}else n[m.key]=h.value;s.push({key:m.key,token:f})}return yn(i,n),{command:r,positionals:a,flags:n,warnings:o,providedFlags:s}}function yn(e,t){if(e)for(let n of sn(e)?.impliedFlags??[])t[n]=!0}function bn(e,t){return t===`-c`&&(e===`snapshot`||e===`diff`)}function xn(e,t){return e===`react-devtools`?t?!E(t.key,e):!0:!1}function Sn(e){return e===`cdp`}function Cn(e,t){let n=xe().filter(t=>t.names.includes(e));if(n.length<=1)return n[0]??b(e);if(t){let e=n.find(e=>E(e.key,t));if(e)return e}return b(e)}function wn(e,n){let r=n?.strictFlags??!0,i=[...e.warnings],a=tt({json:!1,help:!1,version:!1},n?.defaultFlags??{});if(tt(a,e.flags),e.command&&!o(e.command)&&!a.help){let n=mn(e.command);throw new t(`INVALID_ARGS`,n?`Unknown command: ${e.command}. Did you mean ${n}?`:`Unknown command: ${e.command}`)}let s=e.providedFlags.filter(t=>!E(t.key,e.command));if(s.length>0){let n=s.map(e=>e.token),o=Pn(e.command,n);if(r)throw new t(`INVALID_ARGS`,o);i.push(o);for(let e of s)delete a[e.key]}for(let t of Object.keys(a))a[t]!==void 0&&(E(t,e.command)||delete a[t]);Tn(e),$e(e.command,a);let c=Nn({command:e.command,positionals:e.positionals,flags:a,warnings:i});if(Qe(c.command,c.positionals),c.command===`batch`&&+!!a.steps+ +!!a.stepsFile!=1)throw new t(`INVALID_ARGS`,`batch requires exactly one step source: --steps or --steps-file.`);return c}function Tn(e){if(e.command!==`back`)return;let n=e.providedFlags.filter(e=>e.key===`backMode`);if(!(new Set(n.map(e=>e.token)).size<=1))throw new t(`INVALID_ARGS`,`back accepts only one explicit mode flag: use either --in-app or --system.`)}function En(e){let t=e.indexOf(`=`);return t===-1?[e,void 0]:[e.slice(0,t),e.slice(t+1)]}function Dn(e,n,r,i){if(e.setValue!==void 0){if(r!==void 0)throw new t(`INVALID_ARGS`,`Flag ${n} does not take a value.`);return{value:e.setValue,consumeNext:!1}}if(e.type===`boolean`){if(r!==void 0)throw new t(`INVALID_ARGS`,`Flag ${n} does not take a value.`);return{value:!0,consumeNext:!1}}if(e.type===`booleanOrString`){if(r!==void 0){if(r.trim().length===0)throw new t(`INVALID_ARGS`,`Flag ${n} requires a non-empty value when provided.`);return{value:r,consumeNext:!1}}return i===void 0||kn(i)?{value:!0,consumeNext:!1}:An(i)?{value:i,consumeNext:!0}:{value:!0,consumeNext:!1}}let a=r??i;if(a===void 0||r===void 0&&kn(a))throw new t(`INVALID_ARGS`,`Flag ${n} requires a value.`);if(e.type===`string`)return{value:a,consumeNext:r===void 0};if(e.type===`enum`){if(!e.enumValues?.includes(a))throw new t(`INVALID_ARGS`,`Invalid ${On(n)}: ${a}`);return{value:a,consumeNext:r===void 0}}let o=Number(a);if(!Number.isFinite(o)||typeof e.min==`number`&&o<e.min||typeof e.max==`number`&&o>e.max)throw new t(`INVALID_ARGS`,`Invalid ${On(n)}: ${a}`);return{value:Math.floor(o),consumeNext:r===void 0}}function On(e){return e.replace(/^-+/,``)}function kn(e){if(!e.startsWith(`-`)||e===`-`)return!1;let[t]=e.startsWith(`--`)?En(e):[e,void 0];return b(t)!==void 0}function An(e){let t=e.trim();return!t||/^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(t)?!1:!!(t.startsWith(`./`)||t.startsWith(`../`)||t.startsWith(`~/`)||t.startsWith(`/`)||t.includes(`/`)||t.includes(`\\`))}function jn(e,t,n){if(!Mn(n)||!e)return!1;let r=Ze(e);if(!r||r.allowsExtraPositionals)return!0;let i=r.positionalArgs??[];return i.length===0?!1:t.length<i.length?!0:i.some(e=>e.includes(`?`))}function Mn(e){return/^-\d+(\.\d+)?$/.test(e)}function Nn(e){if(e.flags.help)return e;if(e.command===`snapshot`&&e.flags.snapshotDiff){let{snapshotDiff:t,...n}=e.flags;return{command:`diff`,positionals:[`snapshot`,...e.positionals],flags:n,warnings:e.warnings}}return e}function Pn(e,t){return e?t.length===1?`Flag ${t[0]} is not supported for command ${e}.`:`Flags ${t.join(`, `)} are not supported for command ${e}.`:t.length===1?`Flag ${t[0]} requires a command that supports it.`:`Flags ${t.join(`, `)} require a command that supports them.`}async function Fn(){let{buildUsageText:e}=await import(`./cli-help.js`);return e()}async function In(e){let{buildCommandUsageText:t}=await import(`./cli-help.js`);return t(Ln(e))}function Ln(e){if(e.toLowerCase()===`rotate`)throw new t(`INVALID_ARGS`,`rotate was renamed to orientation; for the two-finger gesture use: gesture rotate`);return on(e)}const Rn={slug:`react-devtools-companion`,runArg:Fe,displayName:`React DevTools companion`};async function zn(e){return await Le({...e,definition:Rn,localBaseUrl:e.localBaseUrl??`http://127.0.0.1:8097`,registerPath:`/api/react-devtools/companion/register`,unregisterPath:`/api/react-devtools/companion/unregister`,devicePort:e.devicePort??8097})}async function Bn(e){return await Ie({...e,definition:Rn})}function Vn(e){return e===`android-instance`||e===`ios-instance`}function Hn(e){return[`exec`,`--yes`,`--package`,`agent-cdp@1.6.1`,`--`,`agent-cdp`,...e]}function Un(e){return e.some(e=>e===`--url`||e.startsWith(`--url=`))}function Wn(e){return e[0]===`target`&&(e[1]===`list`||e[1]===`select`)&&!Un(e)}function Gn(e){let t=new URL(e);t.search=``,t.hash=``;let n=t.pathname.replace(/\/+$/,``);return t.pathname=n.endsWith(`/index.bundle`)?n.slice(0,-13)||`/`:n||`/`,t.toString().replace(/\/+$/,``)}function Kn(e){let t=e?.metroPublicBaseUrl?.trim();return t?Gn(t):null}function qn(e,n={}){if(!Wn(e)||!n.flags?.metroProxyBaseUrl||!Vn(n.flags.leaseBackend))return e;let r=Kn(n.flags);if(!r)throw new t(`INVALID_ARGS`,`cdp remote bridge target discovery requires a React Native dev-server public base URL.`,{hint:`Include metroPublicBaseUrl in the remote config so cdp can reach the local or tunneled Metro/Re.Pack CDP endpoint without bridge proxy authentication.`});return[...e,`--url`,r]}async function Jn(e,t={}){return(await Oe(`npm`,Hn(qn(e,t)),{cwd:t.cwd??process.cwd(),env:t.env??process.env,allowFailure:!0,onStdoutChunk:e=>{process.stdout.write(e)},onStderrChunk:e=>{process.stderr.write(e)}})).exitCode}function M(e){let t=tr(e);if(!A.existsSync(t))return null;let n;try{n=JSON.parse(A.readFileSync(t,`utf8`))}catch(t){return sr(e,t),null}return lr(n)?n:(sr(e),null)}function Yn(e){let t=tr({stateDir:e.stateDir,session:e.state.session});A.mkdirSync(O.dirname(t),{recursive:!0}),ar(t,e.state),ar(N(e.stateDir),{session:e.state.session})}function Xn(e){return{baseUrl:or(e.daemonBaseUrl),authToken:e.daemonAuthToken,transport:e.daemonTransport,serverMode:e.daemonServerMode}}function Zn(e){A.rmSync(tr(e),{force:!0});let t=N(e.stateDir);nr(e.stateDir)===e.session&&A.rmSync(t,{force:!0})}function Qn(e){let n=e.validateRemoteConfigHash??!0,r=e.remoteConfig?ze({configPath:e.remoteConfig,cwd:e.cwd,env:e.env}):void 0,i=M(e)??(e.allowActiveFallback?P({stateDir:e.stateDir}):null);if(!i||r&&i.remoteConfigPath!==r)return null;if(n&&er(i.remoteConfigPath)!==i.remoteConfigHash)throw new t(`INVALID_ARGS`,`Active remote connection config changed. Run agent-device connect --force to refresh it.`,{remoteConfig:i.remoteConfigPath});let a=ir(i,e),o=u(i);return{runtime:i.runtime,connection:p(o),flags:{...a,remoteConfig:i.remoteConfigPath,daemonBaseUrl:i.daemon?.baseUrl??a.daemonBaseUrl,daemonAuthToken:i.daemon?.authToken??a.daemonAuthToken,daemonTransport:i.daemon?.transport??a.daemonTransport,daemonServerMode:i.daemon?.serverMode??a.daemonServerMode,...f(o),sessionIsolation:`tenant`,session:i.session,platform:i.platform??a.platform,target:i.target??a.target}}}function $n(e){return p(u(e))}function er(e){try{return k.createHash(`sha256`).update(A.readFileSync(e)).digest(`hex`)}catch(n){throw new t(`INVALID_ARGS`,`Remote config file not found: ${e}`,{cause:n instanceof Error?n.message:String(n)})}}function tr(e){return O.join(e.stateDir,`remote-connections`,`${cr(e.session)}.json`)}function N(e){return O.join(e,`remote-connections`,`.active-session.json`)}function P(e){let t=nr(e.stateDir);return t?M({stateDir:e.stateDir,session:t}):null}function nr(e){let t=N(e);if(A.existsSync(t))try{let e=JSON.parse(A.readFileSync(t,`utf8`));return typeof e.session==`string`?e.session:void 0}catch{return}}function rr(e){if(e)return k.createHash(`sha256`).update(e).digest(`hex`).slice(0,12)}function ir(e,t){try{return w({configPath:e.remoteConfigPath,cwd:t.cwd,env:t.env}).profile}catch(e){if(t.validateRemoteConfigHash===!1)return{};throw e}}function ar(e,t){A.writeFileSync(e,`${JSON.stringify(t,null,2)}\n`,{encoding:`utf8`,mode:384}),A.chmodSync(e,384)}function or(e){if(!e)return;let t=new URL(e);t.username=``,t.password=``;for(let e of[...t.searchParams.keys()])/(auth|key|password|secret|token)/i.test(e)&&t.searchParams.delete(e);return t.toString().replace(/\/+$/,``)}function sr(e,t){ke({level:`warn`,phase:`remote_connection_state_invalid`,data:{session:e.session,cause:t instanceof Error?t.message:t?String(t):void 0}}),Zn(e)}function cr(e){let t=e.replaceAll(/[^a-zA-Z0-9._-]/g,`_`);return t?t===e?t:`${t}-${k.createHash(`sha256`).update(e).digest(`hex`).slice(0,8)}`:`default`}function lr(e){if(!e||typeof e!=`object`||Array.isArray(e))return!1;let t=e;return t.version===1&&ur(t,[`session`,`remoteConfigPath`,`remoteConfigHash`,`tenant`,`runId`,`connectedAt`,`updatedAt`])&&dr(t,[`leaseId`,`leaseBackend`,`leaseProvider`,`deviceKey`,`clientId`])&&fr(t.daemon)}function ur(e,t){return t.every(t=>typeof e[t]==`string`)}function dr(e,t){return t.every(t=>e[t]===void 0||typeof e[t]==`string`)}function fr(e){return e===void 0?!0:!e||typeof e!=`object`||Array.isArray(e)?!1:pr(e)}function pr(e){let t=e;return(t.baseUrl===void 0||typeof t.baseUrl==`string`)&&(t.authToken===void 0||typeof t.authToken==`string`)&&(t.transport===void 0||typeof t.transport==`string`)&&(t.serverMode===void 0||typeof t.serverMode==`string`)}const mr=Ce.map(e=>e.key);function F(e){let t={};for(let n of mr){let r=e[n];r!==void 0&&(t[n]=r)}return t}function hr(e){return e.remoteConfig?{...F(w({configPath:e.remoteConfig,cwd:e.cwd,env:e.env}).profile),remoteConfig:e.remoteConfig}:{}}function gr(e){return e===`cloud`||e===`proxy`||I(e)}function I(e){return e===`limrun`||Ve(e)}function _r(){return[`cloud`,`proxy`,T.browserStack,T.awsDeviceFarm,`limrun`].join(`, `)}function vr(e){return!I(e)}function yr(e){return e===`proxy`?`proxy`:I(e)?`direct-device-provider`:`remote-provider`}function br(e){return{providerDeviceOrientation:e.providerDeviceOrientation,providerGeoLocation:e.providerGeoLocation,providerTimezone:e.providerTimezone,providerLanguage:e.providerLanguage,providerLocale:e.providerLocale,providerNetworkProfile:e.providerNetworkProfile,providerCustomNetwork:e.providerCustomNetwork,providerNoResignApp:e.providerNoResignApp}}function L(e){return{metroProjectRoot:e.metroProjectRoot,metroKind:e.metroKind,metroPublicBaseUrl:e.metroPublicBaseUrl,metroProxyBaseUrl:e.metroProxyBaseUrl,metroPreparePort:e.metroPreparePort,metroListenHost:e.metroListenHost,metroStatusHost:e.metroStatusHost,metroStartupTimeoutMs:e.metroStartupTimeoutMs,metroProbeTimeoutMs:e.metroProbeTimeoutMs,metroRuntimeFile:e.metroRuntimeFile,metroNoReuseExisting:e.metroNoReuseExisting,metroNoInstallDeps:e.metroNoInstallDeps,launchUrl:e.launchUrl}}const R=new Set([`artifacts`,`connect`,`connection`,`close`,`disconnect`,`metro`,`session`]),xr=new Set([`open`]),Sr=new Set([a.open,a.install,a.reinstall,s.installSource]);async function Cr(e){let{command:n,flags:r,client:i}=e;if(!r.remoteConfig)return{flags:r,runtime:e.runtime};let a=y(r.stateDir).baseDir,o=w({configPath:r.remoteConfig,cwd:process.cwd(),env:process.env}),s={...F(o.profile),...r,remoteConfig:o.resolvedPath},c=M({stateDir:a,session:s.session??`default`});if(c&&c.remoteConfigPath!==o.resolvedPath)throw new t(`INVALID_ARGS`,`A different remote connection is already active for this session. Run connect --force or disconnect before using a different --remote-config.`,{session:c.session,activeRemoteConfig:c.remoteConfigPath,requestedRemoteConfig:o.resolvedPath});let l=c??Kr(s,o.resolvedPath,o.profile),u={...s,session:l.session},d=Gr(l.runtime,u.platform)??e.runtime,f=l,p=!c,m,h=jr(f);if(h.shouldAllocate(n)){let e=await Or({command:n,client:i,state:l,nextState:f,nextFlags:u,policy:h});f=e.state,p||=e.changed,m=e.acquiredLeaseForCleanup}let g=await wr({command:n,flags:u,client:i,state:l,nextState:f,runtime:d,positionals:e.positionals,batchSteps:e.batchSteps,forceRuntimePrepare:e.forceRuntimePrepare});return f=g.state,d=g.runtime,p||=g.changed,await Dr({changed:p,stateDir:a,state:f,client:i,acquiredLeaseForCleanup:m,preparedMetroCleanupOnFailure:g.preparedMetroCleanupOnFailure,metroCleanupToStop:g.metroCleanupToStop}),{flags:{...u,session:f.session,leaseId:f.leaseId,leaseBackend:f.leaseBackend,platform:f.platform??u.platform,target:f.target??u.target},runtime:d,connection:$n(f)}}async function wr(e){let{command:n,flags:r,state:i,client:a}=e,o=Tr(e.nextState,r),s=e.runtime;if(!Vr(n,r,e.batchSteps,e.positionals)||!Hr(r)||!Er(e.forceRuntimePrepare,s,r.platform))return{state:o,runtime:s,changed:!1};if(!o.leaseId)throw new t(`INVALID_ARGS`,`${n} requires a resolved remote lease before Metro runtime can be prepared.`);let c=await Fr(r,a,i.remoteConfigPath,i.session,{tenantId:i.tenant,runId:i.runId,leaseId:o.leaseId}),l=!Wr(o.metro,c.cleanup);return o={...o,runtime:c.runtime,metro:c.cleanup,updatedAt:new Date().toISOString()},{state:o,runtime:c.runtime,changed:!0,metroCleanupToStop:l?e.nextState.metro:void 0,preparedMetroCleanupOnFailure:l?c.cleanup:void 0}}function Tr(e,t){return e.leaseId||!t.leaseId?e:{...e,leaseId:t.leaseId,leaseBackend:t.leaseBackend}}function Er(e,t,n){return e===!0||!t||!Ur(t,n)}async function Dr(e){if(e.changed)try{Yn({stateDir:e.stateDir,state:e.state})}catch(t){throw await z(e.preparedMetroCleanupOnFailure),await zr(e.client,e.state,e.acquiredLeaseForCleanup),t}await z(e.metroCleanupToStop)}async function Or(e){let{command:t,client:n,state:r,nextFlags:i,policy:a}=e,o=r.leaseBackend??B(i),s=e.nextState,c=await a.resolveLeaseState({command:t,client:n,state:s,flags:i,leaseBackend:o});s=c.state,c.device&&Yr(i,c.device);let l=s.leaseBackend??o??Br(i,t);$r(r,i,l);let u=await qr(n,s,l,a,i),d=u.lease;return i.leaseId=d.leaseId,i.leaseBackend=l,i.platform=s.platform??i.platform,i.target=s.target??i.target,kr(s,d,l)?{state:s,changed:!1,acquiredLeaseForCleanup:u.acquired?d:void 0}:{state:Ar(s,d,l,i),changed:!0,acquiredLeaseForCleanup:u.acquired?d:void 0}}function kr(e,t,n){return e.leaseId===t.leaseId&&e.leaseBackend===n&&e.deviceKey===(t.deviceKey??e.deviceKey)}function Ar(e,t,n,r){return{...e,leaseId:t.leaseId,leaseBackend:n,leaseProvider:t.leaseProvider??e.leaseProvider,clientId:t.clientId??e.clientId,deviceKey:t.deviceKey??e.deviceKey,platform:e.platform??r.platform,target:e.target??r.target,updatedAt:new Date().toISOString()}}function jr(e){return e.leaseProvider===`proxy`?Nr:Ve(e.leaseProvider)?Pr:Mr}const Mr={shouldAllocate:e=>!R.has(e),ttlMs:()=>void 0,resolveLeaseState:async e=>({state:e.state})},Nr={shouldAllocate:e=>e!==`devices`&&!R.has(e),ttlMs:()=>3e5,resolveLeaseState:Jr},Pr={shouldAllocate:e=>!R.has(e),ttlMs:()=>6e5,resolveLeaseState:async e=>({state:e.state})};async function Fr(e,n,r,i,a){if(!e.metroProjectRoot&&!e.metroPublicBaseUrl&&!e.metroProxyBaseUrl)return{};if(e.platform!==`ios`&&e.platform!==`android`)throw new t(`INVALID_ARGS`,`Deferred Metro preparation requires platform "ios" or "android".`);if(!e.metroPublicBaseUrl&&!e.metroProxyBaseUrl)throw new t(`INVALID_ARGS`,`Deferred Metro preparation requires metroPublicBaseUrl or metroProxyBaseUrl when Metro settings are provided.`);let o=await n.metro.prepare({projectRoot:e.metroProjectRoot,kind:Se(e.metroKind),publicBaseUrl:e.metroPublicBaseUrl,proxyBaseUrl:e.metroProxyBaseUrl,bearerToken:e.metroBearerToken,bridgeScope:a,launchUrl:e.launchUrl,companionProfileKey:r,companionConsumerKey:i,port:e.metroPreparePort,listenHost:e.metroListenHost,statusHost:e.metroStatusHost,startupTimeoutMs:e.metroStartupTimeoutMs,probeTimeoutMs:e.metroProbeTimeoutMs,reuseExisting:e.metroNoReuseExisting?!1:void 0,installDependenciesIfNeeded:e.metroNoInstallDeps?!1:void 0,runtimeFilePath:e.metroRuntimeFile});return{runtime:e.platform===`ios`?o.iosRuntime:o.androidRuntime,cleanup:e.metroProxyBaseUrl?{projectRoot:o.projectRoot,profileKey:r,consumerKey:i}:void 0}}async function z(e){if(e)try{await Re(e)}catch{}}async function Ir(e){try{await Bn({projectRoot:process.cwd(),stateDir:e.stateDir,profileKey:e.state.remoteConfigPath,consumerKey:e.state.session})}catch{}}async function Lr(e,t){return t.leaseId?await e.leases.release({tenant:t.tenant,runId:t.runId,leaseId:t.leaseId,leaseBackend:t.leaseBackend,daemonBaseUrl:t.daemon?.baseUrl,daemonAuthToken:t.daemon?.authToken,daemonTransport:t.daemon?.transport,daemonServerMode:t.daemon?.serverMode,leaseProvider:t.leaseProvider,clientId:t.clientId,deviceKey:t.deviceKey}):{released:!1}}async function Rr(e,t){if(t.leaseId)try{await Lr(e,t)}catch{}}async function zr(e,t,n){if(n)try{await e.leases.release({tenant:t.tenant,runId:t.runId,leaseId:n.leaseId,leaseBackend:t.leaseBackend??n.backend,leaseProvider:t.leaseProvider??n.leaseProvider,clientId:t.clientId??n.clientId,deviceKey:t.deviceKey??n.deviceKey})}catch{}}function B(e){if(e.leaseBackend)return e.leaseBackend;if(e.platform===`android`)return`android-instance`;if(e.platform===`ios`)return`ios-instance`}function Br(e,n){let r=B(e);if(r)return r;throw new t(`INVALID_ARGS`,`${n} requires --platform ios|android or --lease-backend when the remote connection has not resolved a lease yet.`)}function Vr(e,t,n,r=[]){return e===`cdp`?Wn(r)&&!!t.metroPublicBaseUrl:xr.has(e)?!0:e!==`batch`||!n?!1:n.some(e=>{let t=e.command.trim().toLowerCase();return xr.has(t)&&e.runtime===void 0})}function Hr(e){let t=e.metroKind;return!!(e.metroPublicBaseUrl||e.metroProxyBaseUrl||e.metroProjectRoot||t)}function Ur(e,t){return!e.platform||!t||t!==`ios`&&t!==`android`?!0:e.platform===t}function Wr(e,t){return e?.projectRoot===t?.projectRoot&&e?.profileKey===t?.profileKey&&e?.consumerKey===t?.consumerKey}function Gr(e,t){if(e)return Ur(e,t)?e:void 0}function Kr(e,n,r={}){if(!e.tenant)throw new t(`INVALID_ARGS`,`remote command requires tenant in remote config or via --tenant <id>.`);if(!e.runId)throw new t(`INVALID_ARGS`,`remote command requires runId in remote config or via --run-id <id>.`);if(!e.daemonBaseUrl&&vr(r.leaseProvider))throw new t(`INVALID_ARGS`,`remote command requires daemonBaseUrl in remote config, config, env, or --daemon-base-url.`);let i=new Date().toISOString();return{version:1,session:e.session??`default`,remoteConfigPath:n,remoteConfigHash:er(n),daemon:Xn(e),tenant:e.tenant,runId:e.runId,leaseId:e.leaseId,leaseBackend:e.leaseBackend??B(e),leaseProvider:r.leaseProvider,clientId:r.clientId,deviceKey:r.deviceKey,platform:e.platform,target:e.target,connectedAt:i,updatedAt:i}}async function qr(e,t,n,r,i){if(t.leaseId&&t.leaseBackend===n){let i=await ei(e,t.leaseId,{tenant:t.tenant,runId:t.runId,leaseBackend:n,leaseProvider:t.leaseProvider,clientId:t.clientId,deviceKey:t.deviceKey,ttlMs:r.ttlMs(t)});if(i)return{lease:i,acquired:!1}}return{lease:await e.leases.allocate({tenant:t.tenant,runId:t.runId,leaseBackend:n,leaseProvider:t.leaseProvider,clientId:t.clientId,deviceKey:t.deviceKey,ttlMs:r.ttlMs(t),platform:t.platform??i.platform,target:t.target??i.target,device:i.device,udid:i.udid,serial:i.serial,providerApp:i.providerApp,providerOsVersion:i.providerOsVersion,providerProject:i.providerProject,providerBuild:i.providerBuild,providerSessionName:i.providerSessionName,...br(i),awsProjectArn:i.awsProjectArn,awsDeviceArn:i.awsDeviceArn,awsAppArn:i.awsAppArn,awsRegion:i.awsRegion,awsInteractionMode:i.awsInteractionMode}),acquired:!0}}async function Jr(e){if(!Sr.has(e.command)){if(e.state.leaseId&&e.state.deviceKey)return{state:e.state};throw new t(`INVALID_ARGS`,`No active proxy device lease for this session; run open first.`)}let n=await Xr(e.client,e.flags),r=Zr(n);return{state:{...e.state,deviceKey:r,leaseBackend:e.state.leaseBackend??e.leaseBackend??Qr(n),platform:e.state.platform??n.platform,target:e.state.target??n.target,updatedAt:new Date().toISOString()},device:n}}function Yr(e,t){if(e.platform=t.platform,e.target=t.target??e.target,he(t)){e.udid=t.id;return}t.platform===`android`&&(e.serial=t.id)}async function Xr(e,t){return await ge((await e.devices.list({platform:t.platform,target:t.target,device:t.device,udid:t.udid,serial:t.serial,iosSimulatorDeviceSet:t.iosSimulatorDeviceSet,androidDeviceAllowlist:t.androidDeviceAllowlist})).map(e=>({...me(e.platform),id:e.id,name:e.name,kind:e.kind,target:e.target,booted:e.booted})),{platform:t.platform,target:t.target,deviceName:t.device,udid:t.udid,serial:t.serial})}function Zr(e){return`${pe(e)}:${e.target??`mobile`}:${e.id}`}function Qr(e){if(he(e))return`ios-instance`;if(e.platform===`android`)return`android-instance`}function $r(e,n,r){if(e.leaseBackend&&e.leaseBackend!==r)throw new t(`INVALID_ARGS`,`Active remote connection is already bound to a different lease backend. Re-run connect --force to replace it.`,{session:e.session,leaseBackend:e.leaseBackend});if(e.platform&&n.platform&&e.platform!==n.platform)throw new t(`INVALID_ARGS`,`Active remote connection is already bound to a different platform. Re-run connect --force to replace it.`,{session:e.session,platform:e.platform});if(e.target&&n.target&&e.target!==n.target)throw new t(`INVALID_ARGS`,`Active remote connection is already bound to a different target. Re-run connect --force to replace it.`,{session:e.session,target:e.target})}async function ei(e,t,n){try{return await e.leases.heartbeat({tenant:n.tenant,runId:n.runId,leaseId:t,leaseBackend:n.leaseBackend,leaseProvider:n.leaseProvider,clientId:n.clientId,deviceKey:n.deviceKey,ttlMs:n.ttlMs})}catch(e){if(ti(e))return;throw e}}function ti(e){return!(e instanceof t)||e.code!==`UNAUTHORIZED`?!1:e.details?.reason===`LEASE_NOT_FOUND`||e.details?.reason===`LEASE_EXPIRED`||e.details?.reason===`LEASE_REVOKED`}function ni(e){return we(e)}async function ri(e,n){let r=await e.text(),i={};if(r.trim().length>0)try{i=JSON.parse(r)}catch(r){throw new t(`COMMAND_FAILED`,n.invalidJsonMessage,{status:e.status},r instanceof Error?r:void 0)}if(!e.ok)throw new t(`UNAUTHORIZED`,n.rejectedMessage,{status:e.status,response:i});return i}const ii=1e3;async function ai(e){return await oi({command:e.command,flags:e.flags,stateDir:e.stateDir,allowInteractiveLogin:e.command===`connect`&&!e.flags.noLogin,env:e.env})}async function oi(e){let n=e.env??e.io?.env??process.env;if(!e.flags.daemonBaseUrl)return{flags:e.flags,source:`none`};if(G(e.flags.daemonAuthToken))return{flags:e.flags,source:`flag`};if(G(n.AGENT_DEVICE_DAEMON_AUTH_TOKEN))return{flags:e.flags,source:`env`};if(!bi(e.flags.daemonBaseUrl,n))return{flags:e.flags,source:`none`};let r=await fi({stateDir:e.stateDir,flags:e.flags,env:n,io:e.io});if(r)return{flags:{...e.flags,daemonAuthToken:r.accessToken},source:`cli-session`};if(!e.allowInteractiveLogin)throw e.flags.noLogin?new t(`UNAUTHORIZED`,`Remote daemon authentication is required.`,{hint:`Run agent-device auth login, unset --no-login, or set AGENT_DEVICE_DAEMON_AUTH_TOKEN.`}):yi(e.command,n);let i=await V({stateDir:e.stateDir,flags:e.flags,env:n,io:e.io});return{flags:{...e.flags,daemonAuthToken:i.accessToken},source:`login`}}async function si(e){let n=e.env??e.io?.env??process.env;if(G(e.flags.daemonAuthToken))return{accessToken:e.flags.daemonAuthToken,cloudBaseUrl:W(n)};if(G(n.AGENT_DEVICE_DAEMON_AUTH_TOKEN))return{accessToken:n.AGENT_DEVICE_DAEMON_AUTH_TOKEN,cloudBaseUrl:W(n)};let r=await fi({stateDir:e.stateDir,flags:e.flags,env:n,io:e.io});if(r)return{accessToken:r.accessToken,cloudBaseUrl:r.cloudBaseUrl};if(e.flags.noLogin)throw new t(`UNAUTHORIZED`,`Cloud connection profile authentication is required.`,{hint:`Run agent-device auth login, unset --no-login, or set AGENT_DEVICE_DAEMON_AUTH_TOKEN.`});let i=await V({stateDir:e.stateDir,flags:e.flags,env:n,io:e.io,commandLabel:`agent-device connect`});return{accessToken:i.accessToken,cloudBaseUrl:i.session.cloudBaseUrl}}async function V(e){let n=e.env??e.io?.env??process.env,r=gi(n,e.io);if(r===`non-interactive`)throw yi(e.commandLabel??`agent-device connect`,n);let i=W(n),a=await U({baseUrl:i,pathName:`/api/control-plane/device-auth/start`,body:{client:`agent-device`,tenant:e.flags.tenant,runId:e.flags.runId,daemonBaseUrl:e.flags.daemonBaseUrl,session:e.flags.session},fetchImpl:e.io?.fetch});hi(a);let o=a.verificationUriComplete??a.verificationUri,s=r===`local-browser`?a.verificationUri:xi(a.verificationUri,a.userCode);r===`local-browser`?(Ci(e.io,`Opening ${a.verificationUri}...\n`),await Si(o,e.io)):Ci(e.io,`Open this URL on your machine:\n${s}\n\nWaiting for approval for 10 minutes...\n`);let c=await mi({cloudBaseUrl:i,deviceCode:a.deviceCode,expiresIn:a.expiresIn,interval:a.interval,fetchImpl:e.io?.fetch,now:e.io?.now}),l=c.cliSession?.refreshCredential??c.cliSession?.refreshToken;if(!G(c.accessToken)||!G(l))throw new t(`UNAUTHORIZED`,`Device authorization did not return CLI credentials.`);let u=new Date(e.io?.now?.()??Date.now()).toISOString(),d={version:1,id:c.cliSession?.id??`cli-${Date.now().toString(36)}`,cloudBaseUrl:i,workspaceId:c.cliSession?.workspaceId,accountId:c.cliSession?.accountId,name:c.cliSession?.name,refreshCredential:l,createdAt:u,expiresAt:c.cliSession?.expiresAt};return li({stateDir:e.stateDir,session:d}),{accessToken:c.accessToken,expiresAt:c.expiresAt,session:d}}function ci(e){let t=H(e.stateDir);if(!A.existsSync(t))return null;try{let e=JSON.parse(A.readFileSync(t,`utf8`));return e.version!==1||!G(e.id)||!G(e.cloudBaseUrl)||!G(e.refreshCredential)||!G(e.createdAt)?null:e}catch{return null}}function li(e){let t=H(e.stateDir);A.mkdirSync(O.dirname(t),{recursive:!0,mode:448}),A.writeFileSync(t,`${JSON.stringify(e.session,null,2)}\n`,{mode:384});try{A.chmodSync(t,384)}catch{}}function ui(e){let t=H(e.stateDir);return A.existsSync(t)?(A.rmSync(t,{force:!0}),!0):!1}function H(e){return O.join(e,`auth`,`cli-session.json`)}function di(e){let t=ci({stateDir:e.stateDir});return t?{authenticated:!0,source:`cli-session`,sessionId:t.id,cloudBaseUrl:t.cloudBaseUrl,workspaceId:t.workspaceId,accountId:t.accountId,name:t.name,createdAt:t.createdAt,expiresAt:t.expiresAt,expired:wi(t.expiresAt,e.now)}:{authenticated:!1,source:`none`}}async function fi(e){let t=ci({stateDir:e.stateDir});return!t||wi(t.expiresAt,e.io?.now)?null:{accessToken:(await pi({session:t,flags:e.flags,env:e.env,io:e.io})).accessToken,cloudBaseUrl:W(e.env,t.cloudBaseUrl)}}async function pi(e){let n=await U({baseUrl:W(e.env,e.session.cloudBaseUrl),pathName:`/api/control-plane/cli-session/refresh`,body:{refreshCredential:e.session.refreshCredential,tenant:e.flags.tenant,runId:e.flags.runId,daemonBaseUrl:e.flags.daemonBaseUrl,session:e.flags.session},fetchImpl:e.io?.fetch});if(G(n.accessToken))return{accessToken:n.accessToken,expiresAt:n.expiresAt};throw n.status===`revoked`||n.error===`revoked`?new t(`UNAUTHORIZED`,`Stored cloud CLI session was revoked.`,{hint:`Run agent-device auth login again, or set AGENT_DEVICE_DAEMON_AUTH_TOKEN.`,status:n.status,error:n.error}):new t(`UNAUTHORIZED`,`Failed to refresh CLI session.`,{hint:`Run agent-device auth login again, or set AGENT_DEVICE_DAEMON_AUTH_TOKEN.`,status:n.status,error:n.error})}async function mi(e){let n=e.now??Date.now,r=Math.min((e.expiresIn??600)*1e3,6e5),i=n()+r,a=Math.max(ii,(e.interval??5e3/1e3)*1e3);for(;n()<i;){let n=await U({baseUrl:e.cloudBaseUrl,pathName:`/api/control-plane/device-auth/poll`,body:{deviceCode:e.deviceCode},fetchImpl:e.fetchImpl});if(n.status===`approved`||G(n.accessToken))return n;if(n.status===`slow_down`||n.error===`slow_down`)a+=ii;else if(n.status!==`authorization_pending`&&n.error!==`authorization_pending`)throw new t(`UNAUTHORIZED`,`Device authorization was not approved.`,{status:n.status,error:n.error});await Ti(a)}throw new t(`TIMEOUT`,`Device authorization expired before approval.`)}async function U(e){let t=await(e.fetchImpl??fetch)(new URL(e.pathName,e.baseUrl),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify(e.body),signal:AbortSignal.timeout(15e3)});return await ri(t,{invalidJsonMessage:`Cloud auth endpoint returned invalid JSON (${t.status}).`,rejectedMessage:`Cloud auth endpoint rejected the request.`})}function hi(e){if(!G(e.deviceCode)||!G(e.userCode)||!G(e.verificationUri))throw new t(`COMMAND_FAILED`,`Cloud auth start returned an unusable response.`)}function gi(e,t){let n=t?.stdinIsTTY??process.stdin.isTTY,r=t?.stdoutIsTTY??process.stdout.isTTY;return _i(e)||!n||!r?`non-interactive`:vi(e)?`device-code`:`local-browser`}function _i(e){return e.CI===`true`||e.GITHUB_ACTIONS===`true`||e.BUILDKITE===`true`}function vi(e){return!!(e.SSH_TTY||e.SSH_CONNECTION||e.CODESPACES===`true`||e.GITPOD_WORKSPACE_ID||e.REMOTE_CONTAINERS===`true`)}function yi(e,n){let r=W(n);return new t(`UNAUTHORIZED`,`${e} cannot perform interactive login in CI or a non-interactive shell.`,{hint:`Create a service/API token: ${new URL(`/api-keys`,r).toString()} Then set AGENT_DEVICE_DAEMON_AUTH_TOKEN=adc_live_...`})}function W(e,n){let r=e.AGENT_DEVICE_CLOUD_BASE_URL??n??`https://cloud.agent-device.dev`;try{return new URL(r).toString().replace(/\/+$/,``)}catch(e){throw new t(`INVALID_ARGS`,`Invalid AGENT_DEVICE_CLOUD_BASE_URL.`,{cloudBaseUrl:r},e instanceof Error?e:void 0)}}function bi(e,t){if(t.AGENT_DEVICE_CLOUD_AUTH===`1`||t.AGENT_DEVICE_CLOUD_AUTH===`true`||G(t.AGENT_DEVICE_CLOUD_BASE_URL))return!0;try{let t=new URL(e).hostname.toLowerCase();return t===`agent-device.dev`||t.endsWith(`.agent-device.dev`)}catch{return!1}}function xi(e,t){let n=new URL(e);return n.searchParams.set(`user_code`,t),n.toString()}async function Si(e,t){if(t?.openBrowser){await t.openBrowser(e);return}let n=process.platform;try{n===`darwin`?await Ae(`open`,[e],{allowFailure:!0,timeoutMs:5e3}):n===`win32`?await Ae(`cmd`,[`/c`,`start`,``,e],{allowFailure:!0,timeoutMs:5e3}):await Ae(`xdg-open`,[e],{allowFailure:!0,timeoutMs:5e3})}catch{Ci(t,`Open this URL on your machine:\n${e}\n`)}}function Ci(e,t){(e?.stderr??process.stderr).write(t)}function wi(e,t){if(!e)return!1;let n=Date.parse(e);return Number.isFinite(n)?n<=(t?.()??Date.now()):!0}function G(e){return typeof e==`string`&&e.trim().length>0}async function Ti(e){await new Promise(t=>setTimeout(t,e))}const Ei=new Set([`daemonAuthToken`,`metroBearerToken`]);function Di(e){let t=ji(ki(e.profile)),n=O.join(e.stateDir,`remote-connections`,`generated`);A.mkdirSync(n,{recursive:!0,mode:448});let r=O.join(n,`${Mi(e.provider)}-${Ai(t)}.json`);A.writeFileSync(r,`${JSON.stringify(t,null,2)}\n`,{mode:384});try{A.chmodSync(r,384)}catch{}return r}function Oi(e){try{return w(e)}catch(n){let i=r(n);throw new t(`COMMAND_FAILED`,`${e.provider} connection profile returned invalid remote config.`,{generatedConfigPath:e.configPath,cause:i.message},i)}}function K(e){let t=Oi({configPath:Di({stateDir:e.stateDir,provider:e.provider,profile:e.profile}),cwd:e.cwd,env:e.env,provider:Ni(e.provider)});return{flags:{...F(t.profile),...e.flags,...e.extraFlags??{},remoteConfig:t.resolvedPath},remoteConfigPath:t.resolvedPath}}function ki(e){return Object.fromEntries(Object.entries(e).filter(([e])=>!Ei.has(e)))}function Ai(e){return k.createHash(`sha256`).update(JSON.stringify(e)).digest(`hex`).slice(0,16)}function ji(e){return Array.isArray(e)?e.map(ji):e&&typeof e==`object`?Object.fromEntries(Object.entries(e).filter(([,e])=>e!==void 0).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>[e,ji(t)])):e}function Mi(e){return e.replaceAll(/[^a-zA-Z0-9._-]/g,`_`)||`generated`}function Ni(e){let[t=``,...n]=e;return`${t.toUpperCase()}${n.join(``)}`}function Pi(...e){return k.createHash(`sha256`).update(e.map(e=>e??``).join(`\0`)).digest(`hex`).slice(0,16)}async function Fi(e){let t=await si({stateDir:e.stateDir,flags:e.flags,env:e.env,io:{env:e.env,fetch:e.fetchImpl}}),n=await Ii({cloudBaseUrl:t.cloudBaseUrl,accessToken:t.accessToken,fetchImpl:e.fetchImpl}),r=Pi(e.stateDir,t.cloudBaseUrl,typeof n.daemonBaseUrl==`string`?n.daemonBaseUrl:``,e.flags.session);return K({stateDir:e.stateDir,provider:`cloud`,profile:{...n,leaseProvider:n.leaseProvider??`cloud`,clientId:n.clientId??r,runId:n.runId??`cloud-${r}`},cwd:e.cwd,env:e.env,flags:e.flags,extraFlags:{daemonAuthToken:t.accessToken}})}async function Ii(e){let t=await(e.fetchImpl??fetch)(new URL(`/api/control-plane/connection-profile`,e.cloudBaseUrl),{method:`GET`,headers:{authorization:`Bearer ${e.accessToken}`},signal:AbortSignal.timeout(15e3)});return Li(await ri(t,{invalidJsonMessage:`Cloud connection profile endpoint returned invalid JSON (${t.status}).`,rejectedMessage:`Cloud connection profile endpoint rejected the request.`}))}function Li(e){if(!e||typeof e!=`object`||Array.isArray(e))throw new t(`COMMAND_FAILED`,`Cloud connection profile response is invalid.`);let n=e.connection;if(!n||typeof n!=`object`)throw new t(`COMMAND_FAILED`,`Cloud connection profile response is missing profile.`);if(n.remoteConfigProfile!==void 0)return Ri(n.remoteConfigProfile);throw new t(`COMMAND_FAILED`,`Cloud connection profile did not include remoteConfigProfile.`)}function Ri(e){if(!e||typeof e!=`object`||Array.isArray(e))throw new t(`COMMAND_FAILED`,`Cloud connection profile remoteConfigProfile is invalid.`);if(Object.keys(e).length===0)throw new t(`COMMAND_FAILED`,`Cloud connection profile remoteConfigProfile is empty.`);return e}function zi(e){let t=Vi(e.provider)(e),n=Pi(e.provider,e.stateDir,e.flags.session,t.device),r={tenant:e.flags.tenant??e.provider,sessionIsolation:e.flags.sessionIsolation??`tenant`,runId:e.flags.runId??`${e.provider}-${n}`,leaseProvider:e.provider,clientId:n,leaseBackend:e.flags.leaseBackend??B(e.flags),target:e.flags.target??`mobile`,session:e.flags.session,...t,...L(e.flags)};return K({stateDir:e.stateDir,provider:e.provider,profile:r,cwd:e.cwd,env:e.env,flags:e.flags})}const Bi=[{provider:T.browserStack,buildProfileFields:Hi},{provider:T.awsDeviceFarm,buildProfileFields:Wi}];function Vi(e){let n=Bi.find(t=>t.provider===e)?.buildProfileFields;if(n)return n;throw new t(`INVALID_ARGS`,`Unsupported cloud WebDriver provider "${e}".`)}function Hi(e){return Ki(e.env,`BROWSERSTACK_USERNAME`,`connect browserstack`),Ki(e.env,`BROWSERSTACK_ACCESS_KEY`,`connect browserstack`),{platform:Gi(e.flags.platform,`connect browserstack requires --platform ios|android.`),device:q(e.flags.device,`connect browserstack requires --device <name>.`),providerOsVersion:q(e.flags.providerOsVersion,`connect browserstack requires --provider-os-version <version>.`),providerApp:Ui(q(e.flags.providerApp,`connect browserstack requires --provider-app <bs://app-id-or-local-path>.`),e.cwd),providerProject:e.flags.providerProject,providerBuild:e.flags.providerBuild,providerSessionName:e.flags.providerSessionName,...br(e.flags)}}function Ui(e,n){if(e.startsWith(`bs://`)||/^https?:\/\//i.test(e))return e;let r=O.resolve(n,e);try{if(A.statSync(r).isFile())return r}catch{}throw new t(`INVALID_ARGS`,`BrowserStack app file not found: ${r}`)}function Wi(e){let{env:t,flags:n}=e;Ye(n,T.awsDeviceFarm);let r=Gi(n.platform,`connect aws-device-farm requires --platform ios|android.`),i=qi(n.awsProjectArn,t,[`AGENT_DEVICE_AWS_DEVICE_FARM_PROJECT_ARN`,`AWS_DEVICE_FARM_PROJECT_ARN`],`connect aws-device-farm requires --aws-project-arn <arn> or AWS_DEVICE_FARM_PROJECT_ARN.`);return{platform:r,device:n.device,awsProjectArn:i,awsDeviceArn:qi(n.awsDeviceArn,t,[`AGENT_DEVICE_AWS_DEVICE_FARM_DEVICE_ARN`,`AWS_DEVICE_FARM_DEVICE_ARN`],`connect aws-device-farm requires --aws-device-arn <arn> or AWS_DEVICE_FARM_DEVICE_ARN.`),awsAppArn:Ji(n.awsAppArn,t,[`AGENT_DEVICE_AWS_DEVICE_FARM_APP_ARN`,`AWS_DEVICE_FARM_APP_ARN`]),awsRegion:Ji(n.awsRegion,t,[`AWS_REGION`,`AWS_DEFAULT_REGION`])??Ue(i),awsInteractionMode:n.awsInteractionMode,providerSessionName:n.providerSessionName}}function Gi(e,n){if(e===`android`||e===`ios`)return e;throw new t(`INVALID_ARGS`,n)}function q(e,n){if(e)return e;throw new t(`INVALID_ARGS`,n)}function Ki(e,n,r){let i=e?.[n];if(i)return i;throw new t(`INVALID_ARGS`,`${r} requires ${n} in the environment.`)}function qi(e,t,n,r){return q(Ji(e,t,n),r)}function Ji(e,t,n){return e||n.map(e=>t?.[e]).find(e=>!!e)}function Yi(e){let n=e.env??process.env;if(!n.LIMRUN_API_KEY?.trim())throw new t(`INVALID_ARGS`,`connect limrun requires LIMRUN_API_KEY.`,{hint:`Set LIMRUN_API_KEY in the environment before running agent-device connect limrun.`});let r=Xi({flags:e.flags});return K({stateDir:e.stateDir,provider:`limrun`,profile:r,cwd:e.cwd,env:n,flags:e.flags})}function Xi(e){let t=e.flags,n=Zi(t);return{stateDir:y(t.stateDir).baseDir,daemonTransport:`auto`,tenant:t.tenant??`limrun`,runId:t.runId??`cli-${Date.now().toString(36)}`,sessionIsolation:`tenant`,leaseBackend:n,leaseProvider:`limrun`,platform:t.platform,target:`mobile`,session:t.session,...L(t)}}function Zi(e){if(e.platform!==`android`&&e.platform!==`ios`)throw new t(`INVALID_ARGS`,`connect limrun requires --platform ios or android.`);if(e.device!==void 0)throw new t(`INVALID_ARGS`,`connect limrun does not accept --device; Limrun selects a remote simulator or emulator.`);let n=B(e),r=e.platform===`ios`?`ios-instance`:`android-instance`;if(n!==r)throw new t(`INVALID_ARGS`,`connect limrun --platform ${e.platform} requires --lease-backend ${r}.`);return r}function Qi(e){let n=e.flags.daemonBaseUrl??e.env?.AGENT_DEVICE_DAEMON_BASE_URL;if(!n)throw new t(`INVALID_ARGS`,`connect proxy requires --daemon-base-url <url> or AGENT_DEVICE_DAEMON_BASE_URL.`);let r=Pi(e.stateDir,n,e.flags.session),i={daemonBaseUrl:n,daemonTransport:e.flags.daemonTransport??`http`,daemonServerMode:e.flags.daemonServerMode,tenant:e.flags.tenant??`proxy`,sessionIsolation:e.flags.sessionIsolation??`tenant`,runId:e.flags.runId??`proxy-${r}`,leaseProvider:`proxy`,clientId:r,leaseBackend:e.flags.leaseBackend??B(e.flags),platform:e.flags.platform,target:e.flags.target,device:e.flags.device,udid:e.flags.udid,serial:e.flags.serial,iosSimulatorDeviceSet:e.flags.iosSimulatorDeviceSet,androidDeviceAllowlist:e.flags.androidDeviceAllowlist,session:e.flags.session,...L(e.flags)};return K({stateDir:e.stateDir,provider:`proxy`,profile:i,cwd:e.cwd,env:e.env,flags:e.flags,extraFlags:{daemonBaseUrl:n,daemonTransport:e.flags.daemonTransport??`http`}})}const $i={cloud:{resolve:Fi,verify:async()=>({service:`the configured cloud service`,status:`verified`,verificationMessage:`Credentials and connection profile verified.`})},proxy:{resolve:Qi,verify:async()=>({service:`Agent Device Proxy`,status:`configured`,verificationMessage:`Proxy configuration saved. Access is checked by the first remote command.`})},browserstack:{resolve:e=>zi({provider:`browserstack`,...e}),verify:na},"aws-device-farm":{resolve:e=>zi({provider:`aws-device-farm`,...e}),verify:ra},limrun:{resolve:Yi,verify:ia}};async function ea(e){let t=e.cwd??process.cwd(),n=e.env??process.env;if(e.flags.remoteConfig){let r=w({configPath:e.flags.remoteConfig,cwd:t,env:n}),i=r.profile.leaseProvider;return{flags:{...F(r.profile),...e.flags,remoteConfig:r.resolvedPath},remoteConfigPath:r.resolvedPath,...gr(i)?{provider:i}:{}}}let r=e.provider??(aa(e.flags)?`proxy`:`cloud`);return{...await $i[r].resolve({flags:e.flags,stateDir:e.stateDir,cwd:t,env:n}),provider:r}}async function ta(e){let t=e.env??process.env;return e.provider?await $i[e.provider].verify({flags:e.flags,env:t}):{service:`remote provider`,status:`configured`,verificationMessage:`Remote connection profile loaded. Access is checked by the first remote command.`}}async function na(e){let{flags:t,env:n}=e;return await Xe.verifyConnection({provider:`browserstack`,username:J(n.BROWSERSTACK_USERNAME,`BrowserStack profile missed BROWSERSTACK_USERNAME.`),accessKey:J(n.BROWSERSTACK_ACCESS_KEY,`BrowserStack profile missed BROWSERSTACK_ACCESS_KEY.`),platform:Y(t.platform,`BrowserStack`),deviceName:J(t.device,`BrowserStack profile missed device.`),osVersion:J(t.providerOsVersion,`BrowserStack profile missed OS version.`),app:J(t.providerApp,`BrowserStack profile missed app.`)})}async function ra(e){let{flags:t}=e;return await Xe.verifyConnection({provider:`aws-device-farm`,platform:Y(t.platform,`AWS Device Farm`),projectArn:J(t.awsProjectArn,`AWS Device Farm profile missed project ARN.`),deviceArn:J(t.awsDeviceArn,`AWS Device Farm profile missed device ARN.`),appArn:t.awsAppArn,region:t.awsRegion})}async function ia(e){return await Be({apiKey:J(e.env.LIMRUN_API_KEY,`Limrun profile missed LIMRUN_API_KEY.`),clientVersion:je(),platform:Y(e.flags.platform,`Limrun`),region:e.env.LIMRUN_REGION?.trim()||void 0})}function aa(e){if(!e.daemonBaseUrl||e.tenant||e.runId||e.leaseId||e.leaseBackend)return!1;try{return new URL(e.daemonBaseUrl).pathname.replace(/\/+$/,``).endsWith(`/agent-device`)}catch{return!1}}function J(e,n){if(e!==void 0)return e;throw new t(`COMMAND_FAILED`,n,{hint:`Reconnect to regenerate and validate the provider profile.`})}function Y(e,n){if(e===`android`||e===`ios`)return e;throw new t(`COMMAND_FAILED`,`${n} profile missed a mobile platform.`,{hint:`Reconnect with --platform ios|android.`})}function X(e,t){if(e.leaseId)return;let n=yr(e.leaseProvider);return n===`proxy`?{status:`deferred`,nextSteps:da(e,t).nextSteps,message:`No live device session has been created. Run devices to inspect inventory without allocating, then open when ready.`}:n===`direct-device-provider`?{status:`deferred`,nextSteps:da(e,t).nextSteps,message:`No live device session has been created. The first device command shown below will allocate one.`}:{status:`deferred`,nextSteps:[`agent-device install-from-source <artifact-url> --platform ios|android`,`agent-device open <app-id> --relaunch`,`agent-device snapshot -i`,`agent-device devices`],message:`No live device session has been created. Run a device command when ready to allocate or refresh the lease.`+(e.platform===void 0&&e.leaseBackend===void 0?` Add --platform ios|android if the profile does not set a platform.`:``)}}function oa(e,t){return{...t,preparationMessage:X(e,t)?.message??`No live device session has been created.`,...da(e,t)}}function sa(e){let{state:t,readiness:n,runtimePreparation:r}=e;if(!n){let e=X(t);return[`Configured remote session "${t.session}" tenant "${t.tenant}" run "${t.runId}"${t.leaseId?` lease ${t.leaseId}`:``}.`,e?.message,r?.message].filter(e=>!!e).join(`
4
+ `)}let i=va(n),a=[`${i===`verified`?`Connected`:`Configured`} successfully with ${n.service}.`,`${i===`verified`?`Verified`:`Status`}: ${n.verificationMessage}`];return n.project&&a.push(`Project: ${n.project.name??n.project.reference} — verified`),n.device&&a.push(la(n.device)),n.app&&a.push(ua(t,n.app)),a.push(n.preparationMessage),a.push(`Next:`),a.push(...n.nextSteps.map(e=>` ${e}`)),a.push(...n.notes??[]),r&&a.push(r.message),a.join(`
5
+ `)}function ca(e){let{state:t,runtimePreparation:n,readiness:r}=e,i=X(t,r),a=r?.nextSteps??i?.nextSteps??[];return{connected:!0,session:t.session,tenant:t.tenant,runId:t.runId,leaseAllocated:!!t.leaseId,leaseId:t.leaseId,leaseBackend:t.leaseBackend,leaseProvider:t.leaseProvider,platform:t.platform,target:t.target,remoteConfig:t.remoteConfigPath,remoteConfigHash:t.remoteConfigHash,daemonBaseUrlFingerprint:rr(t.daemon?.baseUrl),liveSession:{status:t.leaseId?`created`:`not-created`,...t.leaseId?{leaseId:t.leaseId}:{}},...r?{verification:{status:va(r),service:r.service,message:r.verificationMessage,...r.project?{project:r.project}:{}},...r.device?{device:r.device}:{},...r.app?{app:r.app}:{},nextSteps:a,...r.notes?{notes:r.notes}:{}}:{},metro:t.metro?{prepared:!0,projectRoot:t.metro.projectRoot}:{prepared:!1},...i?{leasePreparation:i}:{},...n?{runtimePreparation:n}:{},connectedAt:t.connectedAt,updatedAt:t.updatedAt}}function la(e){let t=`osVersion`in e?e.osVersion:void 0,n=[e.platform,t].filter(Boolean).join(` `),r=n?` (${n})`:``;return e.status===`deferred`?`Device: ${e.name??`Provider-selected device`} — allocated on first device command`:`Device: ${e.name??e.reference??`Configured device`}${r} — verified`}function ua(e,t){return t.status===`missing`?`App: ${xa(e)} — ${t.message??`Install or attach an app before open.`}`:`App: ${t.name??t.reference??`configured app`} — ${t.status===`verified`?`verified`:t.message??`configured`}`}function da(e,t){let n=yr(e.leaseProvider);if(n===`proxy`)return{nextSteps:[`agent-device devices`,`agent-device open ${ba(e.platform)} --relaunch`]};if(!t&&n===`direct-device-provider`)return{nextSteps:ya()};let r=t?.app?.status===`missing`;return{nextSteps:fa(t)?_a(e):[...ma(t),...ga(e).nextSteps],...pa(t)?{notes:ha(!r)}:{}}}function fa(e){return e?.app?.status===`missing`&&e.device?.status===`deferred`}function pa(e){return e?.provider===`browserstack`||e?.provider===`aws-device-farm`}function ma(e){return e?.app?.status!==`missing`||!e.project?.reference||!e.device?.reference?[]:[`agent-device connect aws-device-farm --platform ${e.device.platform} --aws-project-arn ${e.project.reference} --aws-device-arn ${e.device.reference} --aws-app-arn <arn> --force`]}function ha(e){return[...e?[`Use the installed package or bundle identifier in open, not the app artifact name.`]:[],`After close, run agent-device artifacts --json for provider video and logs.`]}function ga(e){return{nextSteps:[`agent-device open ${ba(e.platform)} --relaunch`]}}function _a(e){let t=ba(e.platform);return[`agent-device install ${t} <app-path-or-url>`,`agent-device open ${t} --relaunch`]}function va(e){return`status`in e?e.status:`verified`}function ya(){return[`agent-device open <package-or-bundle-id> --relaunch`,`agent-device snapshot -i`,`agent-device close`,`agent-device artifacts --json`]}function ba(e){return e===`ios`?`<bundle-id>`:`<package-id>`}function xa(e){return e.leaseProvider===`aws-device-farm`?`not attached`:e.leaseProvider===`limrun`?`not installed yet`:`not available`}const Sa=async({positionals:e,flags:t,client:n})=>{let r=y(t.stateDir).baseDir,i=Ba(e);Ca(i,t);let a=await ea({provider:i,flags:t,stateDir:r}),o=a.flags,s=Ma(a.remoteConfigPath),c=wa(o,s),l=Ta({stateDir:r,flags:o,remoteConfigPath:a.remoteConfigPath});Ea(l.previous,{flags:o,session:l.session,remoteConfigPath:a.remoteConfigPath,remoteConfigHash:l.remoteConfigHash,desiredLeaseBackend:B(o),connection:s,daemon:l.daemon});let u=await ta({provider:a.provider,flags:o,env:process.env}),d=Da({flags:o,scope:c,connectionMetadata:s,context:l,remoteConfigPath:a.remoteConfigPath});Yn({stateDir:r,state:d}),await ja(n,r,o,l.previous);let f=Ja(o,d),p=oa(d,u);return D(o,ca({state:d,runtimePreparation:f,readiness:p}),()=>sa({state:d,runtimePreparation:f,readiness:p})),!0};function Ca(e,n){if(!(!e||!n.remoteConfig))throw new t(`INVALID_ARGS`,`connect provider positional and --remote-config are mutually exclusive.`)}function wa(e,n){if(!e.tenant)throw new t(`INVALID_ARGS`,`connect requires tenant in remote config or via --tenant <id>.`);if(!e.runId)throw new t(`INVALID_ARGS`,`connect requires runId in remote config or via --run-id <id>.`);if(!e.daemonBaseUrl&&vr(n?.leaseProvider))throw new t(`INVALID_ARGS`,`connect requires daemonBaseUrl in remote config, config, env, or --daemon-base-url.`);return{tenant:e.tenant,runId:e.runId}}function Ta(e){let{stateDir:t,flags:n,remoteConfigPath:r}=e,i=n.session?null:P({stateDir:t}),a=n.session??i?.session??Fa(t);return{session:a,previous:i?.session===a?i:M({stateDir:t,session:a}),remoteConfigHash:er(r),daemon:qa(n)}}function Ea(e,n){if(!(!e||Ua(e,n))&&!n.flags.force)throw new t(`INVALID_ARGS`,`A different remote connection is already active for this session. Re-run connect with --force to replace it.`,{session:n.session,remoteConfig:e.remoteConfigPath})}function Da(e){let{flags:t,scope:n,connectionMetadata:r,context:i,remoteConfigPath:a}=e,o=Aa(t,i.previous)?i.previous:null,s=new Date().toISOString(),c=Oa(t,o,r),l=ka(t,o,s);return{version:1,session:i.session,remoteConfigPath:a,remoteConfigHash:i.remoteConfigHash,daemon:i.daemon,tenant:n.tenant,runId:n.runId,...c,...l,updatedAt:s}}function Oa(e,t,n){return{leaseId:t?.leaseId,leaseBackend:t?.leaseBackend??B(e),leaseProvider:n?.leaseProvider??t?.leaseProvider,clientId:n?.clientId??t?.clientId,deviceKey:t?.deviceKey??n?.deviceKey}}function ka(e,t,n){return{platform:e.platform??t?.platform,target:e.target??t?.target,runtime:t?.runtime,metro:t?.metro,connectedAt:t?.connectedAt??n}}function Aa(e,t){return!!(t&&!e.force)}async function ja(e,t,n,r){!r||!n.force||(await z(r.metro),await Ir({stateDir:t,state:r}),await Rr(e,r))}function Ma(e){let t=w({configPath:e,cwd:process.cwd(),env:process.env}).profile,n={leaseProvider:t.leaseProvider,clientId:t.clientId,deviceKey:t.deviceKey};return Object.values(n).some(e=>e!==void 0)?n:void 0}const Na=async({flags:e,client:t})=>{let{session:n,stateDir:r,state:i}=Va(e);if(!i)return Ha(e,n),!0;let a=i.session,o;if(i.leaseId||i.runtime||i.metro)try{o=(await t.sessions.close({session:a,shutdown:e.shutdown})).provider}catch{}await z(i.metro),await Ir({stateDir:r,state:i});let s=!1;if(i.leaseId)try{let e=await Lr(t,i);s=e.released,o??=e.provider}catch{}return Zn({stateDir:r,session:a}),D(e,{connected:!1,session:a,released:s,...o?{provider:o}:{}},()=>Ia(a,o)),!0},Pa=async({positionals:e,flags:n})=>{if(e[0]!==`status`)throw new t(`INVALID_ARGS`,`connection accepts only: status`);let{session:r,state:i}=Va(n);if(!i)return Ha(n,r),!0;let a=X(i),o=Ya(i);return D(n,ca({state:i,runtimePreparation:o}),()=>[`Configured remote session "${i.session}".`,`tenant=${i.tenant} runId=${i.runId} leaseId=${i.leaseId??`pending`} backend=${i.leaseBackend??`pending`}`,`remoteConfig=${i.remoteConfigPath}`,i.runtime?`metro=prepared`:`metro=not-prepared`,a?.message,o?.message].filter(e=>!!e).join(`
6
+ `)),!0};function Fa(e){for(let t=0;t<8;t+=1){let t=`adc-${k.randomBytes(3).toString(`hex`)}`;if(!M({stateDir:e,session:t}))return t}return`adc-${Date.now().toString(36)}-${k.randomBytes(2).toString(`hex`)}`}function Ia(e,t){return[`Disconnected remote session "${e}".`,...La(t),...za(t?.cloudArtifacts?.cloudArtifacts)].join(`
7
+ `)}function La(e){return(Array.isArray(e?.warnings)?e.warnings:[]).flatMap(e=>{let t=Ra(e);return t?[t]:[]})}function Ra(e){if(!e||typeof e!=`object`)return;let t=e;if(!(typeof t.message!=`string`||t.message.length===0))return`Provider release warning${typeof t.code==`string`&&t.code.length>0?` (${t.code})`:``}: ${t.message}`}function za(e){return(e??[]).filter(e=>(e.availability??`ready`)===`ready`&&e.url).slice(0,3).map(e=>`${e.name}: ${e.url}`)}function Ba(e){let n=e[0];if(n!==void 0){if(e.length>1)throw new t(`INVALID_ARGS`,`connect accepts at most one provider positional.`);if(gr(n))return n;throw new t(`INVALID_ARGS`,`Unknown connect provider: ${n}. Supported providers: ${_r()}.`)}}function Va(e){let t=e.session??`default`,n=y(e.stateDir).baseDir;return{session:t,stateDir:n,state:M({stateDir:n,session:t})??(e.session?null:P({stateDir:n}))}}function Ha(e,t){D(e,{connected:!1,session:t},()=>`No remote connection for "${t}".`)}function Ua(e,t){return Wa(e,t)&&Ga(e,t)&&Ka(e.daemon,t.daemon)}function Wa(e,t){return[[e.remoteConfigPath,t.remoteConfigPath],[e.remoteConfigHash,t.remoteConfigHash],[e.session,t.session],[e.tenant,t.flags.tenant],[e.runId,t.flags.runId]].every(([e,t])=>e===t)}function Ga(e,t){return[[e.leaseBackend,t.desiredLeaseBackend],[e.platform,t.flags.platform],[e.target,t.flags.target],[e.leaseProvider,t.connection?.leaseProvider],[e.clientId,t.connection?.clientId]].every(([e,t])=>t===void 0||e===t)}function Ka(e,t){return[`baseUrl`,`transport`,`serverMode`].every(n=>(e?.[n]??void 0)===(t?.[n]??void 0))}function qa(e){return Xn(e)}function Ja(e,t){if(!t.runtime&&!(!Hr(e)&&!Za(t.remoteConfigPath)))return Xa(t.remoteConfigPath)}function Ya(e){if(!(e.runtime||!Za(e.remoteConfigPath)))return Xa(e.remoteConfigPath)}function Xa(e){let t=`agent-device metro prepare --remote-config ${e}`;return{status:`deferred`,nextStep:t,message:`Metro runtime is not prepared yet; it will be prepared automatically on first open, or run "${t}" to inspect it before launch.`}}function Za(e){try{let t=w({configPath:e,cwd:process.cwd(),env:process.env}).profile;return!!(t.metroPublicBaseUrl||t.metroProxyBaseUrl||t.metroProjectRoot||t.metroKind)}catch{return!1}}const Qa=async({positionals:e,flags:n})=>{let r=e[0]??`status`,i=y(n.stateDir).baseDir;if(r===`status`){let e=di({stateDir:i});return D(n,e,()=>$a(e)),!0}if(r===`login`){let e=await V({stateDir:i,flags:n,commandLabel:`agent-device auth login`});return D(n,{authenticated:!0,source:`cli-session`,sessionId:e.session.id,cloudBaseUrl:e.session.cloudBaseUrl,workspaceId:e.session.workspaceId,accountId:e.session.accountId,expiresAt:e.session.expiresAt,agentTokenExpiresAt:e.expiresAt},()=>`Authenticated with cloud CLI session.`),!0}if(r===`logout`){let e=ui({stateDir:i});return D(n,{authenticated:!1,removed:e},()=>e?`Removed stored cloud CLI session.`:`No stored cloud CLI session.`),!0}throw new t(`INVALID_ARGS`,`auth accepts only: status, login, logout`)};function $a(e){return e.authenticated?[`Authenticated with cloud CLI session.`,`cloud=${e.cloudBaseUrl}`,`session=${e.sessionId}`,e.workspaceId?`workspace=${e.workspaceId}`:null,e.accountId?`account=${e.accountId}`:null,e.expiresAt?`expiresAt=${e.expiresAt}`:null,e.expired?`status=expired`:null].filter(e=>!!e).join(`
8
+ `):`Not authenticated.`}async function eo(e){let n=ro(e.paths.infoPath);if(!n)return Z();if(!n.processStartTime){if(!Ne(n.pid))return Z();throw new t(`COMMAND_FAILED`,`Refusing to stop a daemon without a verified process start-time identity.`,{pid:n.pid})}if(!re(n.pid,n.processStartTime)){if(!Ne(n.pid))return Z();throw new t(`COMMAND_FAILED`,`Refusing to stop a daemon whose PID or start-time identity could not be verified.`,{pid:n.pid,processStartTime:n.processStartTime})}if(!to(n.pid,`SIGTERM`))return Z();if(await Pe(n.pid,e.graceTimeoutMs??1e4))return await ao(e.paths,1e3),{stopped:!0,mode:`graceful`,cleanupConfidence:`known`,claimsReleased:[],claimsOrphaned:[],providerReleases:{status:`completed`,released:[],pending:[]},warnings:[]};if(re(n.pid,n.processStartTime)&&to(n.pid,`SIGKILL`),!await Pe(n.pid,e.killTimeoutMs??2e3))throw new t(`COMMAND_FAILED`,`Daemon did not exit after SIGKILL.`,{pid:n.pid});return{stopped:!0,mode:`forced`,cleanupConfidence:`unknown`,claimsReleased:[],claimsOrphaned:[],providerReleases:{status:`unknown`,released:[],pending:null},warnings:[`The daemon was force-killed before provider lease state could be finalized. Provider allocations may remain active.`]}}function to(e,n){if(se(e,n))return!0;if(!Ne(e))return!1;throw new t(`COMMAND_FAILED`,`Daemon could not be signaled with ${n}.`,{pid:e,signal:n})}function no(e){let t=ro(e);return t?.processStartTime?{pid:t.pid,processStartTime:t.processStartTime}:null}function ro(e){try{let t=JSON.parse(A.readFileSync(e,`utf8`)),n=t.pid;return typeof n!=`number`||!Number.isInteger(n)||n<=0?null:{pid:n,...io(t.processStartTime)?{processStartTime:t.processStartTime}:{}}}catch{return null}}function io(e){return typeof e==`string`&&e.trim().length>0}async function ao(e,t){let n=Date.now();for(;Date.now()-n<t;){if(!A.existsSync(e.infoPath)&&!A.existsSync(e.lockPath))return;await Me(25)}}function Z(){return{stopped:!1,mode:`not-running`,cleanupConfidence:`known`,claimsReleased:[],claimsOrphaned:[],providerReleases:{status:`completed`,released:[],pending:[]},warnings:[]}}const oo=async({positionals:e,flags:n})=>{if(e[0]!==`stop`||e.length!==1)throw new t(`INVALID_ARGS`,`daemon accepts only: stop`);let r=y(n.stateDir),i=no(r.infoPath),a=await eo({paths:r}),o=so(a,a.mode===`graceful`?qe(r.baseDir):null),s=n.clean===!0&&i!==null&&o.stopped;if(s){let[{cleanupRunnerLeasesForOwner:e},{runnerLeaseCleanupAdapter:t}]=await Promise.all([import(`./runner-lease.js`).then(e=>e.c),import(`./runner-disposal.js`).then(e=>e.s)]);await e({pid:i.pid,startTime:i.processStartTime},t)}let c={...o,clean:s};return D(n,c,()=>co(c)),!0};function so(e,t){return e.mode!==`graceful`||t?t?{...e,providerReleases:{status:`completed`,...t.providerReleases}}:e:{...e,cleanupConfidence:`unknown`,providerReleases:{status:`unknown`,released:[],pending:null},warnings:[...e.warnings,`The graceful shutdown report is unavailable, so provider cleanup state is unknown. Provider allocations may remain active.`]}}function co(e){return[e.stopped?`Daemon stopped (${e.mode}).`:`No running daemon found.`,e.clean?`Retained runner cleanup completed.`:null,...e.warnings].filter(e=>!!e).join(`
9
+ `)}const lo=async({positionals:e,flags:n})=>{if(e[0]!==`status`||e.length!==1)throw new t(`INVALID_ARGS`,`device accepts only: status`);let r=Ke({platform:n.platform,device:n.device,udid:n.udid,serial:n.serial}),i=r.filter(uo),a=(n.stale?i:r.filter(e=>!uo(e))).map(fo);return D(n,{claims:a,...n.stale?{}:{hiddenStaleClaims:i.length}},()=>po(a,{staleOnly:n.stale===!0,hiddenStaleClaims:i.length,staleCommand:_o(n)})),!0};function uo(e){return e.classification===`owner-process-dead`||e.classification===`owner-state-dir-gone`}function fo(e){let t=e.claim;return{...e.deviceKey?{deviceKey:e.deviceKey}:{},...t?{}:{fileName:e.fileName},classification:e.classification,...t?{device:t.device,owner:{session:t.session,workspace:t.workspace,stateDir:t.stateDir,pid:t.ownerPid,startTime:t.ownerStartTime}}:{},...e.error?{error:e.error}:{}}}function po(e,t){let n=e.map(mo);if(n.length===0){if(t.staleOnly)return`No stale local advisory device claims found.`;if(t.hiddenStaleClaims===0)return`No local advisory device claims found.`}return[...n.length===0?[`No live local advisory device claims found.`]:n,!t.staleOnly&&t.hiddenStaleClaims>0?`${t.hiddenStaleClaims} stale ${t.hiddenStaleClaims===1?`claim`:`claims`} hidden; inspect with: ${t.staleCommand}`:null].filter(e=>!!e).join(`
10
+ `)}function mo(e){return`${ho(e)}: ${e.classification}${go(e.owner)}`}function ho(e){let t=e.device;return t?`${t.platform??`unknown`} ${t.name??t.id??`claim`}`:String(e.deviceKey??e.fileName??`claim`)}function go(e){if(!e||typeof e!=`object`)return``;let t=e;return` session=${t.session} workspace=${t.workspace}`}function _o(e){return[`agent-device device status`,...[e.platform?`--platform ${v(e.platform)}`:null,e.device?`--device ${v(e.device)}`:null,e.udid?`--udid ${v(e.udid)}`:null,e.serial?`--serial ${v(e.serial)}`:null].filter(e=>!!e),`--stale`].join(` `)}const vo=`${ce}/`,yo=[`content-type`,`content-range`,`x-artifact-type`,`x-artifact-filename`,`x-artifact-hash`,`x-artifact-hash-algorithm`,oe],bo=[`content-type`,`content-disposition`,`x-request-id`];function xo(e){let t=No(e);return lt.createServer((e,n)=>{So(e,n,t).catch(e=>{Xo(n,e)})})}async function So(e,t,n){let r=Io(e.url??`/`);if(e.method===`GET`&&r===`/health`){await Co(t,n);return}if(!Lo(r,e.method)){t.statusCode=404,t.end(`Not found`);return}let i;if(r===`/rpc`&&(i=(await ue(e,n.maxRpcBodyBytes,`Proxy request body is too large.`)).toString(`utf8`)),!Uo(e,n.clientToken,i)){Yo(t,r,qo(i));return}await To({req:e,res:t,route:r,options:n,rpcBody:i})}async function Co(e,t){let n=await wo(t);e.statusCode=200,e.setHeader(`content-type`,`application/json`),e.end(JSON.stringify(le(`agent-device-proxy`,{upstream:n})))}async function wo(e){let t=new URL(fe(e.upstreamBaseUrl,`health`)),n=await e.fetchImpl(t,{method:`GET`,headers:Vo({headers:{}},e.upstreamToken,`/health`),signal:AbortSignal.timeout(e.upstreamTimeoutMs)}),r=await n.text();try{return r?JSON.parse(r):{ok:n.ok,status:n.status}}catch{return{ok:n.ok,status:n.status}}}async function To(e){let{req:t,res:n,route:r,options:i,rpcBody:a}=e,o=Bo(i.upstreamBaseUrl,r,t.url??`/`),s=t.method??`GET`,c=Vo(t,i.upstreamToken,r),l=Ho(t,r,a,i.upstreamToken);await Eo({req:t,res:n,route:r,response:await i.fetchImpl(o,{method:s,headers:c,signal:AbortSignal.timeout(i.upstreamTimeoutMs),...l?{body:l,duplex:`half`}:{}}),clientToken:i.clientToken})}async function Eo(e){let{req:t,res:n,route:r,response:i,clientToken:a}=e;if(n.statusCode=i.status,Do(i,n),Oo(t,n),zo(r)){await ko({req:t,res:n,response:i,clientToken:a});return}await Mo(i,n)}function Do(e,t){for(let n of bo){let r=e.headers.get(n);r&&t.setHeader(n,r)}}function Oo(e,t){t.hasHeader(`x-request-id`)||t.setHeader(`x-request-id`,Jo(e))}async function ko(e){let{req:t,res:n,response:r,clientToken:i}=e,a=await r.text();n.setHeader(`content-type`,r.headers.get(`content-type`)??`application/json`),n.end(Ao(a,t,i))}function Ao(e,t,n){let r;try{r=JSON.parse(e)}catch{return e}if(!r||typeof r!=`object`)return e;let i=r;if(!i.upload||typeof i.upload.url!=`string`)return e;let a=jo(i.upload.url,t);if(!a)return e;let o=i.upload.headers&&typeof i.upload.headers==`object`?{...i.upload.headers}:{};return Object.assign(o,ae(n)),JSON.stringify({...r,upload:{...i.upload,url:a,headers:o}})}function jo(e,t){let n;try{n=new URL(e)}catch{return null}if(!n.pathname.startsWith(`/upload/`))return null;let r=typeof t.headers.host==`string`?t.headers.host:``;if(!r)return null;let i=new URL(t.url??`/`,`http://127.0.0.1`).pathname,a=i.lastIndexOf(`/upload/preflight`),o=a>=0?i.slice(0,a):``,s=t.headers[`x-forwarded-proto`],c=Array.isArray(s)?s[0]:s,l=new URL(`${c||`http`}://${r}`);return l.pathname=`${o}${n.pathname}`,l.search=n.search,l.toString()}async function Mo(e,t){if(!e.body){t.end();return}await ut(dt.fromWeb(e.body),t)}function No(e){return{upstreamBaseUrl:Po(e.upstreamBaseUrl,`upstreamBaseUrl`),upstreamToken:Fo(e.upstreamToken,`upstreamToken`),clientToken:Fo(e.clientToken,`clientToken`),maxRpcBodyBytes:e.maxRpcBodyBytes??1048576,upstreamTimeoutMs:e.upstreamTimeoutMs??3e5,fetchImpl:e.fetchImpl??fetch}}function Po(e,n){try{let t=new URL(e);if(t.protocol!==`http:`&&t.protocol!==`https:`)throw Error(`unsupported protocol`);return t.toString().replace(/\/+$/,``)}catch(r){throw new t(`INVALID_ARGS`,`Invalid ${n}`,{[n]:e},r)}}function Fo(e,n){let r=e.trim();if(!r)throw new t(`INVALID_ARGS`,`Proxy ${n} is required.`);return r}function Io(e){let t=new URL(e,`http://127.0.0.1`).pathname;return t===`/agent-device`?`/`:t.startsWith(vo)?`/${t.slice(vo.length)}`:t}function Lo(e,t){return e===`/rpc`?t===`POST`:Ro(e,t)?!0:e===`/artifacts`||e===`/artifacts/`||e.startsWith(`/artifacts/`)?t===`GET`:!1}function Ro(e,t){return e===`/upload`||zo(e)||e===`/upload/finalize`?t===`POST`:e.startsWith(`/upload/direct/`)?t===`PUT`:!1}function zo(e){return e===`/upload/preflight`}function Bo(e,t,n){let r=new URL(fe(e,t)),i=n.indexOf(`?`);return i>=0&&(r.search=n.slice(i)),r}function Vo(e,t,n){let r=new Headers;for(let t of yo){let n=e.headers[t];typeof n==`string`&&n.trim()&&r.set(t,n)}n===`/rpc`&&!r.has(`content-type`)&&r.set(`content-type`,`application/json`);for(let[e,n]of Object.entries(ae(t)))r.set(e,n);return r}function Ho(e,t,n,r){if(!(e.method===`GET`||e.method===`HEAD`))return t===`/rpc`?Go(n??``,r):e}function Uo(e,t,n){let r=Wo(e,n);return r.length>0&&Je(r,t)}function Wo(e,t){let n=typeof e.headers.authorization==`string`?e.headers.authorization:``;if(n.toLowerCase().startsWith(`bearer `))return n.slice(7);let r=e.headers[`x-agent-device-token`];if(typeof r==`string`)return r;if(t){let e=Ko(t);if(e)return e}return``}function Go(e,t){let n=JSON.parse(e);return n.params={...n.params??{},token:t},JSON.stringify(n)}function Ko(e){try{let t=JSON.parse(e);return typeof t.params?.token==`string`?t.params.token:``}catch{return``}}function qo(e){if(!e)return null;try{return JSON.parse(e).id??null}catch{return null}}function Jo(e){let t=e.headers[`x-request-id`];return typeof t==`string`&&t.trim()?t.trim().slice(0,128):ot()}function Yo(n,r,i){if(n.statusCode=401,n.setHeader(`content-type`,`application/json`),r===`/rpc`){n.end(JSON.stringify({jsonrpc:`2.0`,id:i,error:{code:-32001,message:`Invalid proxy token`,data:e(new t(`UNAUTHORIZED`,`Invalid proxy token`))}}));return}n.end(JSON.stringify({ok:!1,error:`Invalid proxy token`,code:`UNAUTHORIZED`}))}function Xo(t,n){if(t.headersSent){t.destroy(n instanceof Error?n:void 0);return}let r=e(n);t.statusCode=r.code===`INVALID_ARGS`?400:500,t.setHeader(`content-type`,`application/json`),t.end(JSON.stringify({ok:!1,error:r.message,code:r.code}))}const Zo=async({positionals:e,flags:n})=>{if(e.length>0)throw new t(`INVALID_ARGS`,`proxy does not accept positional arguments.`);let r=await Qo(n);return D(n,r,()=>rs(r)),await is(),!0};async function Qo(e){let n=_e({session:`default`,command:`proxy`,positionals:[],flags:{stateDir:e.stateDir,daemonBaseUrl:``,daemonTransport:`http`,daemonServerMode:`http`}}),r=await ve(n),i=$o(r.info.httpPort),a=es(e),o=xo({upstreamBaseUrl:i,upstreamToken:r.info.token,clientToken:a});await ts(o,e.proxyHost?.trim()||`127.0.0.1`,e.proxyPort??0);let s=o.address();if(!s||typeof s==`string`)throw new t(`COMMAND_FAILED`,`Proxy did not bind to a TCP address.`);let c=`http://${ns(s.address)}:${s.port}`;return{proxyBaseUrl:c,agentDeviceBaseUrl:ie(c),token:a,upstreamBaseUrl:i,stateDir:n.paths.baseDir}}function $o(e){if(!e)throw new t(`COMMAND_FAILED`,`Local daemon HTTP endpoint is unavailable.`,{hint:`Retry after cleaning daemon state, or run proxy with a fresh --state-dir.`});return`http://127.0.0.1:${e}`}function es(e){return e.daemonAuthToken?.trim()||at(32).toString(`hex`)}function ts(e,t,n){return new Promise((r,i)=>{e.once(`error`,i),e.listen(n,t,()=>{e.off(`error`,i),r()})})}function ns(e){return e.includes(`:`)&&!e.startsWith(`[`)?`[${e}]`:e}function rs(e,t={}){let n=t.useColor??ee(),r=Q(`✓`,`green`,n),i=Q(e.proxyBaseUrl,`cyan`,n),a=Q(`<tunnel URL>`,`cyan`,n),o=Q(e.token,`yellow`,n);return[`${r} Proxy listening at ${i}`,``,`Provide this to the agent-device instance connecting:`,``,`Daemon base URL: ${a}`,`Daemon auth token: ${o}`].join(`
11
+ `)}function Q(e,t,n){return n?m(e,t,{validateStream:!1}):e}function is(){return new Promise(()=>{})}const as=async e=>{let{positionals:t}=e;return t[0]===`export`?await ss(e):os(e)};function os({positionals:e,flags:n}){if(e.length>1)throw new t(`INVALID_ARGS`,`replay accepts exactly one input path: replay <path>`);if(n.out!==void 0)throw new t(`INVALID_ARGS`,`replay --out is only supported with replay export.`);return!1}async function ss({positionals:e,flags:n}){cs(e,n);let r=e[1];if(!r)throw new t(`INVALID_ARGS`,`replay export requires an input path.`);let i=C(r),a=A.readFileSync(i,`utf8`),o=st(a),s=vt(o.actions,{actionLines:o.actionLines,metadata:ct(a),parseSelector:te}),c=typeof n.out==`string`?C(n.out):void 0;c&&(A.mkdirSync(O.dirname(c),{recursive:!0}),A.writeFileSync(c,s.yaml));for(let e of s.warnings)process.stderr.write(`Warning: line ${e.line}: ${e.message}\n`);return D(n,{format:`maestro`,sourcePath:i,...c?{path:c}:{yaml:s.yaml},warnings:s.warnings},()=>c??s.yaml),!0}function cs(e,n){if(e.length>2)throw new t(`INVALID_ARGS`,`replay export accepts exactly one input path: replay export <file.ad>`);if(n.replayUpdate)throw new t(`INVALID_ARGS`,`replay export does not support --update.`);if(n.replayMaestro)throw new t(`INVALID_ARGS`,`replay export reads .ad files; omit --maestro.`);if(n.replayEnv?.length)throw new t(`INVALID_ARGS`,`replay export does not evaluate --env substitutions.`)}const ls=async({positionals:e,flags:t,client:r})=>{let i=await it({client:r,command:`screenshot`,positionals:e,flags:t});return n(t.responseLevel)?(D(t,i,()=>JSON.stringify(i,null,2)),!0):(D(t,de(i),()=>i.overlayRefs?`Annotated ${i.overlayRefs.length} refs onto ${i.path}`:fs(i)),!0)},us=async({positionals:e,flags:n,client:r})=>{if(e[0]===`snapshot`){let t=await it({client:r,command:`diff`,positionals:e,flags:n});return D(n,t,()=>g(t)),!0}if(e[0]!==`screenshot`)return!1;let i=n.baseline;if(!i||typeof i!=`string`)throw new t(`INVALID_ARGS`,`diff screenshot requires --baseline <path>`);let a=C(i),o=typeof n.out==`string`?C(n.out):void 0,s=e[1];if(e.length>2)throw new t(`INVALID_ARGS`,`diff screenshot accepts at most one current screenshot path`);let[{createAgentDevice:c,localCommandPolicy:u},{createLocalArtifactAdapter:d}]=await Promise.all([import(`./runtime.js`).then(e=>e.r),import(`./sdk-io.js`).then(e=>e.n)]),f=await c({backend:ds(r,n),artifacts:d(),sessions:{get:e=>({name:e}),set:()=>{}},policy:u()}).capture.diffScreenshot({session:n.session,baseline:{kind:`path`,path:a},current:s?{kind:`path`,path:C(s)}:{kind:`live`},...o?{out:{kind:`path`,path:o}}:{},threshold:ms(n.threshold),overlayRefs:n.overlayRefs,normalizeStatusBar:n.screenshotNormalizeStatusBar,surface:n.surface});return D(n,f,()=>l(f)),!0};function ds(e,t){return{platform:ps(t),captureScreenshot:async(t,n,r)=>de(await e.capture.screenshot({path:n,session:t.session,overlayRefs:r?.overlayRefs,pixelDensity:r?.pixelDensity,fullscreen:r?.fullscreen,normalizeStatusBar:r?.normalizeStatusBar,stabilize:r?.stabilize,surface:r?.surface}))}}function fs(e){if(typeof e.width!=`number`||typeof e.height!=`number`)return e.path;let t=typeof e.pixelDensity==`number`?` @${e.pixelDensity}x`:``;return`${e.path} (${e.width}x${e.height}${t})`}function ps(e){switch(e.platform){case`android`:case`linux`:case`macos`:return e.platform;default:return`ios`}}function ms(e){if(!(e==null||e===``))return Number(e)}const hs={connect:Sa,disconnect:Na,connection:Pa,auth:Qa,daemon:oo,device:lo,proxy:Zo,replay:as,screenshot:ls,diff:us};async function gs(e){let t={...e.flags},n=hs[e.command];return n&&await n({...e,flags:t})?!0:ni(e.command)?await _s({...e,command:e.command,flags:t}):!1}async function _s(e){let{runGenericClientBackedCommand:t}=await import(`./generic.js`);return await t(e)}function vs(e){return[`exec`,`--yes`,`--package`,`agent-react-devtools@0.4.0`,`--`,`agent-react-devtools`,...e]}function ys(e){return e===`ios-instance`}function bs(e){return e[0]===`wait`&&e.includes(`--connected`)}function xs(e,t,n){n===0||!bs(e)||!ys(t?.leaseBackend)||process.stderr.write([`Hint: Remote iOS React DevTools connects during JavaScript startup.`,"If the app was already open before `agent-device react-devtools start`, relaunch it with `agent-device open <bundle-id> --platform ios --relaunch`, then retry `agent-device react-devtools wait --connected`.",``].join(`
12
+ `))}function $(e,t,n){return n||(e.push(t),``)}function Ss(e){if(!e?.metroProxyBaseUrl||!Vn(e.leaseBackend))return null;let n=[],r={serverBaseUrl:$(n,`metroProxyBaseUrl`,e.metroProxyBaseUrl),bearerToken:$(n,`metroBearerToken`,e.metroBearerToken),tenantId:$(n,`tenant`,e.tenant),runId:$(n,`runId`,e.runId),leaseId:$(n,`leaseId`,e.leaseId)};if(n.length>0)throw new t(`INVALID_ARGS`,`react-devtools remote bridge requires ${n.join(`, `)}.`,{missing:n});return r}async function Cs(e,t,n){let{flags:r}=t,i=Ss(r);if(!i)return n();let a=t.stateDir??process.cwd(),o=t.session??r?.session??`default`,s=r?.remoteConfig??`${i.tenantId}:${i.runId}:${i.leaseId}`;if(e[0]===`stop`)try{return await n()}finally{await Bn({projectRoot:t.cwd??process.cwd(),stateDir:a,profileKey:s,consumerKey:o})}return await zn({projectRoot:t.cwd??process.cwd(),stateDir:a,serverBaseUrl:i.serverBaseUrl,bearerToken:i.bearerToken,bridgeScope:{tenantId:i.tenantId,runId:i.runId,leaseId:i.leaseId},session:o,profileKey:s,consumerKey:o,env:t.env??process.env}),await n()}function ws(e,t){if(e[0]!==`start`)return!1;let{flags:n}=t;return n?n.leaseProvider===`limrun`&&n.leaseBackend===`android-instance`&&n.metroProxyBaseUrl===void 0&&t.configureDirectPortReverse!==void 0:!1}async function Ts(e,t={}){let n=t.cwd??process.cwd(),r=t.env??process.env,i=await Cs(e,t,async()=>(ws(e,t)&&await t.configureDirectPortReverse?.(),(await Oe(`npm`,vs(e),{cwd:n,env:r,allowFailure:!0,onStdoutChunk:e=>{process.stdout.write(e)},onStderrChunk:e=>{process.stderr.write(e)}})).exitCode));return xs(e,t.flags,i),i}async function Es(e,n){switch(e[0]){case`setup`:{Ds(n.flags.json);let{setupManagedAgentBrowser:e}=await import(`./agent-browser-tool.js`).then(e=>e.t),t=await e({stateDir:n.stateDir});return Os(n.flags.json,t),0}case`doctor`:{let{doctorManagedAgentBrowser:e}=await import(`./agent-browser-tool.js`).then(e=>e.t),t=await e({stateDir:n.stateDir});return ks(n.flags.json,t.exitCode===0?`Web backend is healthy.`:`Web backend doctor reported issues.`,t),t.exitCode}default:throw new t(`INVALID_ARGS`,`web requires setup or doctor`)}}function Ds(e){e||process.stdout.write(`Setting up managed agent-browser backend (downloads if needed)...
13
+ `)}function Os(e,t){if(e){h({success:!0,data:{status:As(t)}});return}process.stdout.write(`Managed web backend installed.\nagent-browser available at: ${t.binaryPath}\n`)}function ks(e,t,n){if(e){h({success:!0,data:js(n)});return}process.stdout.write(`${t}\n`)}function As(e){let{socketDir:t,...n}=e;return n}function js(e){let t=e.status;return Ms(t)?{...e,status:As(t)}:e}function Ms(e){return typeof e==`object`&&!!e&&`socketDir`in e&&`installDir`in e&&`binaryPath`in e}function Ns(e){let n;try{n=JSON.parse(e)}catch{throw new t(`INVALID_ARGS`,`Batch steps must be valid JSON.`)}if(!Array.isArray(n)||n.length===0)throw new t(`INVALID_ARGS`,`Batch steps must be a non-empty JSON array.`);return Ps(n)}function Ps(e){let t=!1,n=e.map((e,n)=>{if(Is(e))return Ls(e,n+1);let r=Rs(e,n+1);return t=!0,Fs(r)});return t&&process.stderr.write(`Warning: batch steps using positionals/flags are deprecated and will be removed in the next major version. Use {"command":"...","input":{...}} steps instead.
14
+ `),n}function Fs(e){let t=rt(e.command,e.positionals??[],Us(e.flags));return{command:e.command,input:t,...e.runtime===void 0?{}:{runtime:e.runtime}}}function Is(e){return _(e)&&`input`in e&&!(`positionals`in e)&&!(`flags`in e)}function Ls(e,t){let n=ne(e.runtime,t),{runtime:r,...i}=e;return{...i,...n===void 0?{}:{runtime:n}}}function Rs(e,n){if(!_(e))throw new t(`INVALID_ARGS`,`Invalid batch step ${n}.`);Bs(e,n);let r=zs(e.command,n),i=Vs(e.positionals,n);Qe(r,i??[],`Batch step ${n}`);let a=Hs(e.flags,n),o=ne(e.runtime,n);return{command:r,...i===void 0?{}:{positionals:i},...a===void 0?{}:{flags:a},...o===void 0?{}:{runtime:o}}}function zs(e,n){let r=typeof e==`string`?e.trim().toLowerCase():``;if(!r)throw new t(`INVALID_ARGS`,`Batch step ${n} requires command.`);if(we(r))return r;throw new t(`INVALID_ARGS`,`Batch step ${n} command is not available through command batch: ${String(e)}`)}function Bs(e,n){let r=Object.keys(e).filter(e=>![`command`,`positionals`,`flags`,`runtime`].includes(e));if(r.length>0)throw new t(`INVALID_ARGS`,`Batch step ${n} has unknown legacy field(s): ${r.join(`, `)}.`)}function Vs(e,n){if(e!==void 0){if(!Array.isArray(e)||e.some(e=>typeof e!=`string`))throw new t(`INVALID_ARGS`,`Batch step ${n} positionals must contain only strings.`);return e}}function Hs(e,n){if(e!==void 0){if(!_(e))throw new t(`INVALID_ARGS`,`Batch step ${n} flags must be an object.`);return e}}function Us(e){return{json:!1,help:!1,version:!1,...e}}function Ws(e,t={}){let n=Gs(t),r={...e};return n.defaultPlatform&&r.platform===void 0&&(r.platform=n.defaultPlatform),r}function Gs(e){let t=e.env??process.env,n=e.inheritedPlatform??e.configuredPlatform??qs(t.AGENT_DEVICE_PLATFORM),r=Ys(e.configuredSession??t.AGENT_DEVICE_SESSION);return{defaultPlatform:n,lockPolicy:Ks(e.policyOverrides,t,r)}}function Ks(e,t,n){let r=e?.sessionLock??Js(t.AGENT_DEVICE_SESSION_LOCK);if(r)return r;if(n)return`reject`}function qs(e){if(e===void 0)return;let n=e.trim().toLowerCase();if(n){if(n===`ios`||n===`android`||n===`apple`)return n;throw new t(`INVALID_ARGS`,`Invalid AGENT_DEVICE_PLATFORM: ${e}. Use ios, android, or apple.`)}}function Js(e){if(e===void 0)return;let n=e.trim().toLowerCase();if(n){if(n===`reject`||n===`strip`)return n;throw new t(`INVALID_ARGS`,`Invalid session lock mode: ${e}. Use reject or strip.`)}}function Ys(e){return typeof e==`string`&&e.trim().length>0}function Xs(e,t){let n=vn(e),r=t?.env??process.env,i=t?.cwd??process.cwd(),a=Zs(n.command)?hr({remoteConfig:n.flags.remoteConfig,cwd:i,env:r}):{},o=tt(nt({command:n.command,cwd:i,cliFlags:n.flags,env:r}),a);return{...wn(n,{strictFlags:t?.strictFlags,defaultFlags:o}),providedFlags:n.providedFlags}}function Zs(e){return e!==null}const Qs={sendToDaemon:be},$s=new Set([`launchUrl`,`kind`,`metroBearerToken`,`metroKind`,`metroListenHost`,`metroNoInstallDeps`,`metroNoReuseExisting`,`metroPreparePort`,`metroProbeTimeoutMs`,`metroProjectRoot`,`metroProxyBaseUrl`,`metroPublicBaseUrl`,`metroRuntimeFile`,`metroStartupTimeoutMs`,`metroStatusHost`]),ec=new Set([`connect`,`connection`,`close`,`daemon`,`device`,`disconnect`,`metro`,`proxy`,`session`]);async function tc(e,t=Qs){let n=Te(),r=je(),i=pc(e),a=e.includes(`--json`);await Ee({session:kc(e)??process.env.AGENT_DEVICE_SESSION??`default`,requestId:n,command:e[0],debug:i},async()=>{let{parsed:o,command:s,positionals:c}=await rc(e,{version:r,jsonRequested:a,debugEnabled:i}),l=gc(s,o.providedFlags),u=ic(o,{command:s,positionals:c,requestId:n,debugOutputEnabled:l});nc(u.effectiveFlags);let d=null;try{if(s===`react-devtools`){process.exit(await ac(u,t));return}if(s===`web`){process.exit(await Es(c,{flags:u.effectiveFlags,stateDir:u.daemonPaths.baseDir}));return}if(et({command:s,currentVersion:r,stateDir:u.daemonPaths.baseDir,flags:u.effectiveFlags}),await oc(u,t),nc(u.effectiveFlags),s===`cdp`){process.exit(await Jn(c,{flags:u.effectiveFlags,runtime:u.resolvedRuntime,cwd:process.cwd(),env:process.env}));return}d=cc(u);let e=await lc(u);await uc(u,ye(sc(u),{transport:Ec({command:s,flags:u.effectiveFlags,replayTestReporterRuntime:e,transport:t.sendToDaemon})}),e)}catch(e){dc(e,u,d)}finally{d&&d()}})}function nc(e){e.daemonAuthToken&&De(e.daemonAuthToken)}async function rc(n,r){let i;try{i=Xs(n,{cwd:process.cwd(),env:process.env})}catch(t){ke({level:`error`,phase:`cli_parse_failed`,data:{error:t instanceof Error?t.message:String(t)}});let n=e(t,{diagnosticId:S().diagnosticId,logPath:x({force:!0})??void 0});r.jsonRequested?h({success:!1,error:n}):d(n,{showDetails:r.debugEnabled}),process.exit(1)}for(let e of i.warnings)process.stderr.write(`Warning: ${e}\n`);i.flags.version&&(process.stdout.write(`${r.version}\n`),process.exit(0));let a=i.command===`help`,o=i.flags.help;if(a||o){a&&i.positionals.length>1&&(d(new t(`INVALID_ARGS`,`help accepts at most one command.`)),process.exit(1));let e=a?i.positionals[0]:i.command;e||(process.stdout.write(`${await Fn()}\n`),process.exit(0));let n=await In(e);n&&(process.stdout.write(n),process.exit(0)),d(new t(`INVALID_ARGS`,mc(e))),process.stdout.write(`${await Fn()}\n`),process.exit(1)}return i.command||(process.stdout.write(`${await Fn()}\n`),process.exit(1)),{parsed:i,command:i.command,positionals:i.positionals}}function ic(t,n){let i=new Set(t.providedFlags.map(e=>e.key));try{let e=Gs({policyOverrides:t.flags,configuredPlatform:t.flags.platform,configuredSession:t.flags.session}),r=e.lockPolicy?{...t.flags}:Ws(t.flags,{policyOverrides:t.flags,configuredPlatform:t.flags.platform,configuredSession:t.flags.session}),a=y(r.stateDir),o=r.session??`default`,s=yc({command:n.command,explicitFlagKeys:i,stateDir:a.baseDir,session:o,remoteConfig:r.remoteConfig,hasResolvedSession:r.session!==void 0}),c=s?wc(r,s.flags,i):r;return{...n,binding:e,flags:r,daemonPaths:a,sessionName:o,connectionDefaults:s,explicitFlagKeys:i,effectiveFlags:c,resolvedRuntime:s?.runtime,connectionMetadata:s?.connection,parsedBatchSteps:void 0}}catch(i){let a=e(r(i),{diagnosticId:S().diagnosticId,logPath:x({force:!0})??void 0});t.flags.json?h({success:!1,error:a}):d(a,{showDetails:n.debugOutputEnabled}),process.exit(1)}}async function ac(e,t){let{daemonAuthToken:n,...r}=e.effectiveFlags;return await Ts(e.positionals,{flags:{...r,leaseProvider:e.connectionDefaults?.connection?.leaseProvider},stateDir:e.daemonPaths.baseDir,session:e.effectiveFlags.session??e.sessionName,cwd:process.cwd(),env:process.env,configureDirectPortReverse:async()=>{let a=await t.sendToDaemon({command:s.runtime,positionals:[`port-reverse`],flags:{...r,leaseProvider:e.connectionDefaults?.connection?.leaseProvider,devicePort:8097,hostPort:8097,portReverseName:`react-devtools`},session:e.effectiveFlags.session??e.sessionName},{authToken:n});a.ok||i(a.error)}})}async function oc(e,n){if(e.command===`batch`){if(e.positionals.length>0)throw new t(`INVALID_ARGS`,`batch does not accept positional arguments.`);e.parsedBatchSteps=_c(e.flags)}if(xc(e.command)&&(e.effectiveFlags=(await ai({command:e.command,flags:e.effectiveFlags,stateDir:e.daemonPaths.baseDir,env:process.env})).flags),e.effectiveFlags.remoteConfig&&bc(e.command)){let t=ye(sc(e),{transport:Dc(n.sendToDaemon)}),r=await Cr({command:e.command,flags:e.effectiveFlags,client:t,runtime:e.resolvedRuntime,positionals:e.positionals,batchSteps:e.parsedBatchSteps,forceRuntimePrepare:Tc(e.explicitFlagKeys)});e.effectiveFlags=r.flags,e.resolvedRuntime=r.runtime,e.connectionMetadata=r.connection}Sc({command:e.command,flags:e.effectiveFlags,runtime:e.resolvedRuntime,explicitFlagKeys:e.explicitFlagKeys,hadConnectionDefaults:!!e.connectionDefaults})&&process.stderr.write(`Warning: open is using explicit remote daemon or tenant flags without saved Metro runtime hints. React Native apps may launch without bundle/runtime hints; prefer connect --remote-config <path> first or pass --remote-config <path> on this command.
15
+ `)}function sc(e){let t=e.effectiveFlags,n=e.connectionMetadata;return{session:t.session,requestId:e.requestId,stateDir:t.stateDir,daemonBaseUrl:t.daemonBaseUrl,daemonAuthToken:t.daemonAuthToken,daemonTransport:t.daemonTransport,daemonServerMode:t.daemonServerMode,tenant:t.tenant,sessionIsolation:t.sessionIsolation,runId:t.runId,leaseId:t.leaseId,leaseBackend:t.leaseBackend,leaseProvider:n?.leaseProvider,clientId:n?.clientId,deviceKey:n?.deviceKey,providerApp:t.providerApp,providerOsVersion:t.providerOsVersion,providerProject:t.providerProject,providerBuild:t.providerBuild,providerSessionName:t.providerSessionName,providerDeviceOrientation:t.providerDeviceOrientation,providerGeoLocation:t.providerGeoLocation,providerTimezone:t.providerTimezone,providerLanguage:t.providerLanguage,providerLocale:t.providerLocale,providerNetworkProfile:t.providerNetworkProfile,providerCustomNetwork:t.providerCustomNetwork,providerNoResignApp:t.providerNoResignApp,awsProjectArn:t.awsProjectArn,awsDeviceArn:t.awsDeviceArn,awsAppArn:t.awsAppArn,awsRegion:t.awsRegion,awsInteractionMode:t.awsInteractionMode,runtime:e.resolvedRuntime,lockPolicy:e.binding.lockPolicy,lockPlatform:e.binding.defaultPlatform,cwd:process.cwd(),debug:e.debugOutputEnabled,cost:t.cost,responseLevel:t.responseLevel}}function cc(e){let t=e.effectiveFlags.daemonBaseUrl;return e.debugOutputEnabled&&!e.effectiveFlags.json&&!t?Ac(e.daemonPaths.logPath):null}async function lc(e){if(e.command!==`test`)return;let{createReplayTestReporterRuntime:t}=await import(`./reporting.js`);return t({debug:e.debugOutputEnabled,verbose:e.effectiveFlags.verbose,json:e.effectiveFlags.json,reporter:e.effectiveFlags.reporter,reportJunit:e.effectiveFlags.reportJunit})}async function uc(e,n,r){let{command:i,positionals:a,effectiveFlags:o}=e;if(i===`batch`){if(!e.parsedBatchSteps)throw new t(`INVALID_ARGS`,`batch requires --steps or --steps-file.`);let s=e.parsedBatchSteps.map((t,n)=>({...t,input:e.binding.lockPolicy&&e.flags.platform===void 0?{...t.input}:Ws(t.input,{policyOverrides:o,configuredPlatform:o.platform,configuredSession:o.session,inheritedPlatform:o.platform})}));if(await gs({command:i,positionals:a,flags:{...o,batchSteps:s},client:n,debug:e.debugOutputEnabled,replayTestReporterRuntime:r}))return}else if(i===`runtime`)throw new t(`INVALID_ARGS`,`runtime command was removed. Use connect --remote-config <path> for remote runs, or metro prepare --remote-config <path> for inspection.`);else if(await gs({command:i,positionals:a,flags:o,client:n,debug:e.debugOutputEnabled,replayTestReporterRuntime:r}))return;throw new t(`INVALID_ARGS`,hc(i))}function dc(t,n,i){let a=r(t),o=e(a,{diagnosticId:S().diagnosticId,logPath:x({force:!0})??void 0});if(n.command===`close`&&vc(a)){n.effectiveFlags.json&&h({success:!0,data:{closed:`session`,source:`no-daemon`}});return}n.effectiveFlags.json?h({success:!1,error:o}):(d(o,{showDetails:n.debugOutputEnabled}),n.debugOutputEnabled&&fc(n.daemonPaths.logPath)),i&&i(),process.exit(1)}function fc(e){try{if(A.existsSync(e)){let t=A.readFileSync(e,`utf8`).split(`
15
16
  `),n=t.slice(Math.max(0,t.length-200)).join(`
16
- `);n.trim().length>0&&process.stderr.write(`\n[daemon log]\n${n}\n`)}}catch{}}function Vs(e){try{let t=yt(e);return Ws(t.command??``,t.providedFlags)}catch{return e.includes(`--debug`)||e.includes(`-v`)||e.includes(`--verbose`)}}function Hs(e){let t=ht(e);return t?`Unknown command: ${e}. Did you mean ${t}?`:`Unknown command: ${e}`}function Us(e){return ie(e)?(l({level:`error`,phase:`cli_known_command_unhandled`,data:{command:e}}),`Command is registered but no CLI handler accepted it: ${e}`):`Unknown command: ${e}`}function Ws(e,t){return t.some(t=>t.key===`verbose`&&(t.token===`--debug`||t.token===`-v`||e!==`test`))}function Gs(e){let n=``;if(e.steps)n=e.steps;else if(e.stepsFile)try{n=j.readFileSync(e.stepsFile,`utf8`)}catch(n){let r=n instanceof Error?n.message:String(n);throw new t(`INVALID_ARGS`,`Failed to read --steps-file ${e.stepsFile}: ${r}`)}return cs(n)}function Ks(e){return e.code===`COMMAND_FAILED`?e.details?.kind===`daemon_startup_failed`?!0:e.message.toLowerCase().includes(`failed to start daemon`)?typeof e.details?.infoPath==`string`||typeof e.details?.lockPath==`string`:!1:!1}function qs(e){return e.command===`connect`||e.command===`connection`||e.command===`daemon`||e.command===`proxy`?null:$t({stateDir:e.stateDir,session:e.session,remoteConfig:e.remoteConfig,cwd:process.cwd(),env:process.env,allowActiveFallback:!e.explicitFlagKeys.has(`session`)&&(!e.remoteConfig||e.command===`disconnect`||!e.hasResolvedSession),validateRemoteConfigHash:e.command!==`disconnect`})}function Js(e){return!ks.has(e)}function Ys(e){return e!==`auth`&&e!==`connection`&&e!==`daemon`&&e!==`device`&&e!==`proxy`}function Xs(e){return e.command!==`open`||e.runtime||e.flags.bundleUrl||e.flags.metroHost||e.flags.metroPort||e.flags.remoteConfig||e.hadConnectionDefaults?!1:Zs(e.explicitFlagKeys)}function Zs(e){return e.has(`daemonBaseUrl`)||e.has(`daemonTransport`)||e.has(`tenant`)||e.has(`sessionIsolation`)||e.has(`runId`)||e.has(`leaseId`)||e.has(`leaseBackend`)}function Qs(e,t,n){let r={...e};for(let[e,i]of Object.entries(t))i!==void 0&&(n.has(e)||(r[e]=i));return r}function $s(e){for(let t of Os)if(e.has(t))return!0;return!1}function ec(e){let{command:t,flags:n,replayTestReporterRuntime:r,transport:i}=e;return n.json?tc(i):async e=>await nc(i,{...e,meta:{...e.meta,requestProgress:t===`test`?`replay-test`:`command`}},t===`test`&&r?{onProgress:r.onProgress}:void 0)}function tc(e){return async t=>await nc(e,t)}async function nc(e,t,n){return await e(t,n)}function rc(e){for(let t=0;t<e.length;t+=1){let n=e[t];if(n.startsWith(`--session=`)){let e=n.slice(10).trim();return e.length>0?e:null}if(n===`--session`){let n=e[t+1]?.trim();return n&&!n.startsWith(`-`)?n:null}}return null}at(process.argv[1]??``).href===import.meta.url&&As(process.argv.slice(2)).catch(t=>{y(e(r(t)),{showDetails:!0}),process.exit(1)});function ic(e){try{let t=j.existsSync(e)?j.statSync(e).size:0,n=!1,r=setInterval(()=>{if(!n&&j.existsSync(e))try{let n=j.statSync(e);if(n.size<t&&(t=0),n.size<=t)return;let r=j.openSync(e,`r`);try{let e=Buffer.alloc(n.size-t);j.readSync(r,e,0,e.length,t),t=n.size,e.length>0&&process.stdout.write(e.toString(`utf8`))}finally{j.closeSync(r)}}catch{}},200);return()=>{n=!0,clearInterval(r)}}catch{return null}}export{As as runCli};
17
+ `);n.trim().length>0&&process.stderr.write(`\n[daemon log]\n${n}\n`)}}catch{}}function pc(e){try{let t=vn(e);return gc(t.command??``,t.providedFlags)}catch{return e.includes(`--debug`)||e.includes(`-v`)||e.includes(`--verbose`)}}function mc(e){let t=mn(e);return t?`Unknown command: ${e}. Did you mean ${t}?`:`Unknown command: ${e}`}function hc(e){return o(e)?(ke({level:`error`,phase:`cli_known_command_unhandled`,data:{command:e}}),`Command is registered but no CLI handler accepted it: ${e}`):`Unknown command: ${e}`}function gc(e,t){return t.some(t=>t.key===`verbose`&&(t.token===`--debug`||t.token===`-v`||e!==`test`))}function _c(e){let n=``;if(e.steps)n=e.steps;else if(e.stepsFile)try{n=A.readFileSync(e.stepsFile,`utf8`)}catch(n){let r=n instanceof Error?n.message:String(n);throw new t(`INVALID_ARGS`,`Failed to read --steps-file ${e.stepsFile}: ${r}`)}return Ns(n)}function vc(e){return e.code===`COMMAND_FAILED`?e.details?.kind===`daemon_startup_failed`?!0:e.message.toLowerCase().includes(`failed to start daemon`)?typeof e.details?.infoPath==`string`||typeof e.details?.lockPath==`string`:!1:!1}function yc(e){return e.command===`connect`||e.command===`connection`||e.command===`daemon`||e.command===`proxy`?null:Qn({stateDir:e.stateDir,session:e.session,remoteConfig:e.remoteConfig,cwd:process.cwd(),env:process.env,allowActiveFallback:!e.explicitFlagKeys.has(`session`)&&(!e.remoteConfig||e.command===`disconnect`||!e.hasResolvedSession),validateRemoteConfigHash:e.command!==`disconnect`})}function bc(e){return!ec.has(e)}function xc(e){return e!==`auth`&&e!==`connection`&&e!==`daemon`&&e!==`device`&&e!==`proxy`}function Sc(e){return e.command!==`open`||e.runtime||e.flags.bundleUrl||e.flags.metroHost||e.flags.metroPort||e.flags.remoteConfig||e.hadConnectionDefaults?!1:Cc(e.explicitFlagKeys)}function Cc(e){return e.has(`daemonBaseUrl`)||e.has(`daemonTransport`)||e.has(`tenant`)||e.has(`sessionIsolation`)||e.has(`runId`)||e.has(`leaseId`)||e.has(`leaseBackend`)}function wc(e,t,n){let r={...e};for(let[e,i]of Object.entries(t))i!==void 0&&(n.has(e)||(r[e]=i));return r}function Tc(e){for(let t of $s)if(e.has(t))return!0;return!1}function Ec(e){let{command:t,flags:n,replayTestReporterRuntime:r,transport:i}=e;return n.json?Dc(i):async(e,n)=>{let a=t===`test`&&r?{...n,onProgress:r.onProgress}:n;return await Oc(i,{...e,meta:{...e.meta,requestProgress:t===`test`?`replay-test`:`command`}},a)}}function Dc(e){return async(t,n)=>await Oc(e,t,n)}async function Oc(e,t,n){return await e(t,n)}function kc(e){for(let t=0;t<e.length;t+=1){let n=e[t];if(n.startsWith(`--session=`)){let e=n.slice(10).trim();return e.length>0?e:null}if(n===`--session`){let n=e[t+1]?.trim();return n&&!n.startsWith(`-`)?n:null}}return null}ft(process.argv[1]??``).href===import.meta.url&&tc(process.argv.slice(2)).catch(t=>{d(e(r(t)),{showDetails:!0}),process.exit(1)});function Ac(e){try{let t=A.existsSync(e)?A.statSync(e).size:0,n=!1,r=setInterval(()=>{if(!n&&A.existsSync(e))try{let n=A.statSync(e);if(n.size<t&&(t=0),n.size<=t)return;let r=A.openSync(e,`r`);try{let e=Buffer.alloc(n.size-t);A.readSync(r,e,0,e.length,t),t=n.size,e.length>0&&process.stdout.write(e.toString(`utf8`))}finally{A.closeSync(r)}}catch{}},200);return()=>{n=!0,clearInterval(r)}}catch{return null}}export{tc as runCli};