agent-device 0.18.3 → 0.19.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (219) hide show
  1. package/README.md +5 -1
  2. package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.18.3.apk → agent-device-android-multitouch-helper-0.19.1.apk} +0 -0
  3. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.19.1.apk.sha256 +1 -0
  4. package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.18.3.manifest.json → agent-device-android-multitouch-helper-0.19.1.manifest.json} +4 -4
  5. package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.18.3.apk → agent-device-android-snapshot-helper-0.19.1.apk} +0 -0
  6. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.19.1.apk.sha256 +1 -0
  7. package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.18.3.manifest.json → agent-device-android-snapshot-helper-0.19.1.manifest.json} +6 -6
  8. package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTapPointPolicy.swift +28 -0
  9. package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +33 -127
  10. package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +630 -177
  11. package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +155 -0
  12. package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+FlatSnapshotFiltering.swift +67 -0
  13. package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +173 -122
  14. package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Navigation.swift +172 -0
  15. package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollGesture.swift +64 -0
  16. package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SequenceExecution.swift +76 -182
  17. package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +92 -51
  18. package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +213 -137
  19. package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedGesturePolicy.swift +142 -0
  20. package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +208 -46
  21. package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Transport.swift +82 -11
  22. package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +74 -0
  23. package/dist/src/agent-browser-tool.js +1 -0
  24. package/dist/src/android-adb.d.ts +63 -234
  25. package/dist/src/android-adb.js +1 -1
  26. package/dist/src/android-input-ownership.js +6 -0
  27. package/dist/src/android.js +1 -5
  28. package/dist/src/app-lifecycle.js +7 -0
  29. package/dist/src/apple-runner-options.js +1 -0
  30. package/dist/src/apps.js +5 -11
  31. package/dist/src/artifacts.d.ts +4 -3
  32. package/dist/src/artifacts.js +1 -1
  33. package/dist/src/audio-probe.js +1 -1
  34. package/dist/src/batch.d.ts +2 -177
  35. package/dist/src/batch.js +1 -1
  36. package/dist/src/cli-help.js +178 -60
  37. package/dist/src/cli-output.js +1 -1
  38. package/dist/src/cli-runner.js +2 -0
  39. package/dist/src/cli.js +12 -41
  40. package/dist/src/client-metro-companion.js +1 -0
  41. package/dist/src/client.js +3 -0
  42. package/dist/src/command-metadata.js +1 -0
  43. package/dist/src/command-schema.js +22 -0
  44. package/dist/src/command-surface.js +1 -1
  45. package/dist/src/contracts.d.ts +2 -213
  46. package/dist/src/contracts.js +1 -1
  47. package/dist/src/debug-symbols.js +5 -3
  48. package/dist/src/device-input-state.js +2 -0
  49. package/dist/src/devices.js +1 -1
  50. package/dist/src/devices2.js +1 -0
  51. package/dist/src/devices3.js +1 -0
  52. package/dist/src/find.js +1 -1
  53. package/dist/src/finders.d.ts +2 -81
  54. package/dist/src/finders.js +1 -1
  55. package/dist/src/generic.js +1 -1
  56. package/dist/src/handler-utils.js +1 -1
  57. package/dist/src/helper.js +2 -0
  58. package/dist/src/host-process.js +2 -0
  59. package/dist/src/index.d.ts +1444 -1786
  60. package/dist/src/index.js +1 -1
  61. package/dist/src/input-actions.js +3 -1
  62. package/dist/src/input-actions2.js +1 -0
  63. package/dist/src/install-source.d.ts +13 -14
  64. package/dist/src/install-source.js +1 -1
  65. package/dist/src/install-source2.js +1 -0
  66. package/dist/src/interaction-snapshot.js +1 -0
  67. package/dist/src/interaction.js +1 -1
  68. package/dist/src/interactor.js +2 -1
  69. package/dist/src/internal/bin.d.ts +1 -1
  70. package/dist/src/internal/bin.js +2 -5
  71. package/dist/src/internal/companion-tunnel.d.ts +1 -1
  72. package/dist/src/internal/companion-tunnel.js +1 -1
  73. package/dist/src/internal/daemon.d.ts +1 -1
  74. package/dist/src/internal/daemon.js +18 -1
  75. package/dist/src/internal/png-worker.d.ts +29 -26
  76. package/dist/src/internal/png-worker.js +1 -1
  77. package/dist/src/internal/update-check-entry.d.ts +1 -1
  78. package/dist/src/internal/update-check-entry.js +1 -1
  79. package/dist/src/io.d.ts +2 -85
  80. package/dist/src/io.js +1 -1
  81. package/dist/src/lease.js +1 -1
  82. package/dist/src/linux.js +1 -1
  83. package/dist/src/manifest.js +1 -0
  84. package/dist/src/metro.d.ts +69 -113
  85. package/dist/src/metro.js +1 -1
  86. package/dist/src/metro2.js +1 -0
  87. package/dist/src/notifications.js +1 -1
  88. package/dist/src/output-path.js +1 -0
  89. package/dist/src/path-resolution.js +1 -0
  90. package/dist/src/png-worker-contract.js +1 -0
  91. package/dist/src/points.js +4 -0
  92. package/dist/src/project-runtime.js +1 -0
  93. package/dist/src/provider.js +1 -1
  94. package/dist/src/providers.js +1 -0
  95. package/dist/src/react-native.js +1 -1
  96. package/dist/src/record-trace-recording.js +2 -5
  97. package/dist/src/record-trace.js +1 -1
  98. package/dist/src/recording-provider.js +1 -1
  99. package/dist/src/registry.js +38 -0
  100. package/dist/src/remote-config.d.ts +2 -83
  101. package/dist/src/reporting.js +9 -0
  102. package/dist/src/rolldown-runtime.js +1 -0
  103. package/dist/src/runner-client.js +1 -0
  104. package/dist/src/runner-provider.js +1 -0
  105. package/dist/src/runner-sequence.js +1 -1
  106. package/dist/src/runtime-transport.js +1 -0
  107. package/dist/src/runtime.js +3 -0
  108. package/dist/src/scoped-provider.js +1 -0
  109. package/dist/src/sdk-android-adb.d.ts +144 -0
  110. package/dist/src/sdk-android-adb.js +4 -0
  111. package/dist/src/sdk-app-inventory.d.ts +4 -0
  112. package/dist/src/sdk-app-inventory.js +1 -0
  113. package/dist/src/sdk-batch-runner.d.ts +39 -0
  114. package/dist/src/sdk-batch-runner.js +2 -0
  115. package/dist/src/sdk-batch.js +2 -0
  116. package/dist/src/sdk-contracts.d.ts +386 -0
  117. package/dist/src/sdk-contracts.js +2 -0
  118. package/dist/src/sdk-finders.d.ts +60 -0
  119. package/dist/src/sdk-finders.js +1 -0
  120. package/dist/src/sdk-io.d.ts +78 -0
  121. package/dist/src/sdk-io.js +1 -0
  122. package/dist/src/sdk-remote-config.d.ts +139 -0
  123. package/dist/src/sdk-remote-config.js +1 -0
  124. package/dist/src/sdk-selectors.js +1 -0
  125. package/dist/src/selector-runtime.js +1 -1
  126. package/dist/src/selectors.d.ts +38 -137
  127. package/dist/src/selectors.js +1 -1
  128. package/dist/src/selectors2.js +1 -0
  129. package/dist/src/server.js +3 -2
  130. package/dist/src/session.js +10 -11
  131. package/dist/src/setting-state.js +1 -0
  132. package/dist/src/simctl.js +1 -0
  133. package/dist/src/simulator.js +1 -2
  134. package/dist/src/snapshot-diagnostics.js +3 -0
  135. package/dist/src/snapshot-helper.js +5 -0
  136. package/dist/src/snapshot-quality.js +1 -0
  137. package/dist/src/snapshot.js +1 -2
  138. package/dist/src/snapshot2.js +2 -0
  139. package/dist/src/{5560.js → timeouts.js} +1 -1
  140. package/dist/src/tool-provider.js +3 -0
  141. package/dist/src/tool-provider2.js +1 -0
  142. package/dist/src/ttl-memo.js +1 -0
  143. package/dist/src/tv-remote.js +14 -0
  144. package/dist/src/update-check.js +1 -0
  145. package/dist/src/url.js +1 -0
  146. package/dist/src/version.js +1 -0
  147. package/dist/src/web.js +1 -1
  148. package/dist/src/xml.js +2 -0
  149. package/package.json +13 -19
  150. package/server.json +2 -2
  151. package/skills/agent-device/SKILL.md +8 -7
  152. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.18.3.apk.sha256 +0 -1
  153. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.18.3.apk.sha256 +0 -1
  154. package/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +0 -443
  155. package/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+FlatSnapshotFiltering.swift +0 -169
  156. package/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollGesture.swift +0 -220
  157. package/dist/src/1404.js +0 -1
  158. package/dist/src/1986.js +0 -1
  159. package/dist/src/2748.js +0 -1
  160. package/dist/src/2948.js +0 -30
  161. package/dist/src/3006.js +0 -1
  162. package/dist/src/314.js +0 -1
  163. package/dist/src/3340.js +0 -8
  164. package/dist/src/4418.js +0 -1
  165. package/dist/src/4428.js +0 -3
  166. package/dist/src/485.js +0 -1
  167. package/dist/src/4917.js +0 -1
  168. package/dist/src/495.js +0 -5
  169. package/dist/src/5448.js +0 -3
  170. package/dist/src/5484.js +0 -1
  171. package/dist/src/5643.js +0 -1
  172. package/dist/src/587.js +0 -1
  173. package/dist/src/5913.js +0 -4
  174. package/dist/src/6849.js +0 -1
  175. package/dist/src/6918.js +0 -1
  176. package/dist/src/6967.js +0 -1
  177. package/dist/src/760.js +0 -1
  178. package/dist/src/7871.js +0 -1
  179. package/dist/src/8184.js +0 -1
  180. package/dist/src/8225.js +0 -1
  181. package/dist/src/8391.js +0 -1
  182. package/dist/src/8404.js +0 -2
  183. package/dist/src/8414.js +0 -2
  184. package/dist/src/8875.js +0 -4
  185. package/dist/src/893.js +0 -1
  186. package/dist/src/8936.js +0 -1
  187. package/dist/src/9414.js +0 -1
  188. package/dist/src/9581.js +0 -22
  189. package/dist/src/9612.js +0 -1
  190. package/dist/src/9624.js +0 -1
  191. package/dist/src/9722.js +0 -39
  192. package/dist/src/devices~1.js +0 -1
  193. package/dist/src/devices~2.js +0 -1
  194. package/dist/src/input-actions~1.js +0 -1
  195. package/dist/src/rslib-runtime.js +0 -1
  196. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunner/AgentDeviceRunnerApp.m +0 -0
  197. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/project.pbxproj +0 -0
  198. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -0
  199. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/xcshareddata/xcschemes/AgentDeviceRunner.xcscheme +0 -0
  200. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/AgentDeviceRunnerUITests-Bridging-Header.h +0 -0
  201. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/AgentDeviceRunnerUITests.entitlements +0 -0
  202. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.h +0 -0
  203. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.m +0 -0
  204. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerObjCExceptionCatcher.h +0 -0
  205. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerObjCExceptionCatcher.m +0 -0
  206. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.h +0 -0
  207. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.m +0 -0
  208. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Alert.swift +0 -0
  209. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Environment.swift +0 -0
  210. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Exceptions.swift +0 -0
  211. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +0 -0
  212. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +0 -0
  213. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScreenRecorder.swift +0 -0
  214. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SystemModal.swift +0 -0
  215. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TvRemote.swift +0 -0
  216. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests.xctestplan +0 -0
  217. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/RecordingScripts/recording-overlay.swift +0 -0
  218. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/RecordingScripts/recording-resize.swift +0 -0
  219. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/RecordingScripts/recording-trim.swift +0 -0
package/dist/src/cli.js CHANGED
@@ -1,41 +1,12 @@
1
- import{pathToFileURL as e}from"node:url";import t from"node:fs";import r from"node:os";import n from"node:path";import o,{randomBytes as s,randomUUID as a}from"node:crypto";import i from"node:http";import{Readable as l}from"node:stream";import{pipeline as c}from"node:stream/promises";import{createRequestId as d,runCmdStreaming as u,buildPrimaryEnvVarName as f,withDiagnosticsScope as p,getDiagnosticsMeta as m,runCmd as g,flushDiagnosticsToSessionFile as h,parseSourceValue as v,emitDiagnostic as y}from"./8875.js";import{isClientBackedCliCommandName as w,INTERNAL_COMMANDS as I,listCliCommandNames as A,PUBLIC_COMMANDS as S,parseBatchStepRuntime as k,isRecord as _}from"./1986.js";import{getCliCommandSchema as D,applyCommandDefaults as b,getCommandSchema as C}from"./9581.js";import{asAppError as $,normalizeError as N,AppError as R}from"./485.js";import{buildCommandUsageText as P,buildUsageText as x}from"./cli-help.js";import{isCommandName as E,printHumanError as T,getFlagDefinition as U,listCommandFamilyCliReaders as M,colorize as L,parseInstallSourceConfig as B,formatScreenshotDiffText as O,formatCliStatusMarker as V,getFlagDefinitions as j,formatSnapshotDiffText as G,leaseScopeFromOptions as F,supportsColor as K,GLOBAL_FLAG_KEYS as H,leaseScopeToCommandFlags as q,leaseScopeToConnectionMetadata as W,printJson as J}from"./2948.js";import{ensureCompanionTunnel as z,stopCompanionTunnel as Z}from"./8404.js";import{REACT_DEVTOOLS_COMPANION_RUN_ARG as Y}from"./4917.js";import{deviceFieldsFromPublicPlatform as X,device_PLATFORM_SELECTORS as Q,isIosFamily as ee,resolveDevice as et,publicPlatformString as er,isNonDefaultResponseLevel as en}from"./6849.js";import{resolveUserPath as eo,expandUserHomePath as es}from"./9612.js";import{localCommandPolicy as ea,isCloudWebDriverProviderName as ei,CLOUD_WEBDRIVER_PROVIDERS as el,timingSafeStringEqual as ec,createAgentDevice as ed}from"./7871.js";import{buildDaemonHealthPayload as eu,readNodeHttpRequestBody as ef,resolveDaemonPaths as ep}from"./5913.js";import{stopMetroTunnel as em}from"./6967.js";import{buildDaemonHttpAuthHeaders as eg,sendToDaemon as eh,ensureDaemon as ev,createAgentDeviceClient as ey,buildDaemonHttpBaseUrl as ew,buildDaemonHttpUrl as eI,resolveClientSettings as eA,DAEMON_HTTP_BASE_PATH as eS}from"./495.js";import"./893.js";import{stringifyMaestroYamlDocuments as ek,parseReplayScriptDetailed as e_,formatMaestroPoint as eD,readReplayScriptMetadata as eb}from"./4428.js";import{formatCliOutput as eC}from"./cli-output.js";import{runCommand as e$}from"./command-surface.js";import{createLocalArtifactAdapter as eN}from"./314.js";import{readVersion as eR}from"./1404.js";import{maybeRunUpgradeNotifier as eP}from"./5448.js";import{parseSelectorChain as ex}from"./587.js";function eE(e,t){for(let[r,n]of Object.entries(t))void 0!==n&&(e[r]=n);return e}let eT=new Set(["config","remoteConfig","help","version","batchSteps","githubActionsArtifact"]),eU=new Set(["appsFilter","iosSimulatorDeviceSet","sessionLocked","sessionLockConflicts"]),eM=function(){let e=new Map;for(let t of j()){let r=e.get(t.key);r?r.push(t):e.set(t.key,[t])}let t=new Map;for(let e of H)t.set(e,new Set(["*"]));for(let e of A()){let r=D(e);for(let n of[...r.allowedFlags??[],...r.supportedFlags??[]]){let r=t.get(n);r&&r.has("*")||(r?r.add(e):t.set(n,new Set([e])))}}return[...e.entries()].map(([e,r])=>({key:e,flagDefinitions:r,config:{enabled:!eT.has(e),key:e},env:{names:eU.has(e)?[]:[f(e)]},supportsCommand(r){let n=t.get(e);return!!n&&(!!n.has("*")||!!r&&n.has(r))}})).sort((e,t)=>e.key.localeCompare(t.key))}(),eL=new Map(eM.map(e=>[e.key,e]));function eB(e,t){return eL.get(e)?.supportsCommand(t)??!1}function eO(e){let t=e.flagDefinitions.find(e=>void 0===e.setValue);if(t)return t;let r=function(e){let t=e.flagDefinitions[0];if(!t)throw Error(`Missing flag definition for option ${e.key}`);return t}(e);if("enum"===r.type){let t=r.enumValues??e.flagDefinitions.map(e=>e.setValue).filter(e=>void 0!==e);return{...r,setValue:void 0,enumValues:t}}return r}function eV(e){let t={json:!1,help:!1,version:!1},r=null,n=[],o=[],s=!0;for(let c=0;c<e.length;c+=1){var a,i,l;let d=e[c];if(s&&"--"===d){s=!1;continue}if(!s){r?n.push(d):r=eK(d);continue}if("cdp"===r){n.push(d);continue}let u=d.startsWith("--"),f=d.startsWith("-")&&d.length>1;if(!u&&!f){r?n.push(d):r=eK(d);continue}let[p,m]=u?ej(d):[d,void 0];if(a=r,"-c"===p&&("snapshot"===a||"diff"===a))continue;let g=function(e,t){let r=j().filter(t=>t.names.includes(e));if(r.length<=1)return r[0]??U(e);if(t){let e=r.find(e=>eB(e.key,t));if(e)return e}return U(e)}(p,r);if(i=r,l=g,"react-devtools"===i&&(!l||!eB(l.key,i))){n.push(d);continue}if(!g){if(function(e,t,r){var n;if(n=r,!/^-\d+(\.\d+)?$/.test(n)||!e)return!1;let o=C(e);if(!o||o.allowsExtraPositionals)return!0;let s=o.positionalArgs??[];return 0!==s.length&&(t.length<s.length||s.some(e=>e.includes("?")))}(r,n,d)){r?n.push(d):r=d;continue}throw new R("INVALID_ARGS",`Unknown flag: ${p}`)}let h=function(e,t,r,n){if(void 0!==e.setValue){if(void 0!==r)throw new R("INVALID_ARGS",`Flag ${t} does not take a value.`);return{value:e.setValue,consumeNext:!1}}if("boolean"===e.type){if(void 0!==r)throw new R("INVALID_ARGS",`Flag ${t} does not take a value.`);return{value:!0,consumeNext:!1}}if("booleanOrString"===e.type){if(void 0!==r){if(0===r.trim().length)throw new R("INVALID_ARGS",`Flag ${t} requires a non-empty value when provided.`);return{value:r,consumeNext:!1}}return void 0===n||eF(n)||!function(e){let t=e.trim();return!(!t||/^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(t))&&!!(t.startsWith("./")||t.startsWith("../")||t.startsWith("~/")||t.startsWith("/")||t.includes("/")||t.includes("\\"))}(n)?{value:!0,consumeNext:!1}:{value:n,consumeNext:!0}}let o=r??n;if(void 0===o||void 0===r&&eF(o))throw new R("INVALID_ARGS",`Flag ${t} requires a value.`);if("string"===e.type)return{value:o,consumeNext:void 0===r};if("enum"===e.type){if(!e.enumValues?.includes(o))throw new R("INVALID_ARGS",`Invalid ${eG(t)}: ${o}`);return{value:o,consumeNext:void 0===r}}let s=Number(o);if(!Number.isFinite(s)||"number"==typeof e.min&&s<e.min||"number"==typeof e.max&&s>e.max)throw new R("INVALID_ARGS",`Invalid ${eG(t)}: ${o}`);return{value:Math.floor(s),consumeNext:void 0===r}}(g,p,m,e[c+1]);h.consumeNext&&(c+=1);let v=t[g.key];if(g.multiple){let e=Array.isArray(v)?[...v,h.value]:void 0===v?[h.value]:[v,h.value];t[g.key]=e}else t[g.key]=h.value;o.push({key:g.key,token:p})}return{command:r,positionals:n,flags:t,warnings:[],providedFlags:o}}function ej(e){let t=e.indexOf("=");return -1===t?[e,void 0]:[e.slice(0,t),e.slice(t+1)]}function eG(e){return e.replace(/^-+/,"")}function eF(e){if(!e.startsWith("-")||"-"===e)return!1;let[t]=e.startsWith("--")?ej(e):[e,void 0];return void 0!==U(t)}function eK(e){return"long-press"===e?"longpress":"metrics"===e?"perf":e}let eH=["onSuiteStart","onTestStart","onTestStep","onTestResult","onSuiteEnd","getExitCode"];async function eq(e){let t=function(e){if(e.startsWith("file:"))return e;let t=e.startsWith("~/")?n.join(r.homedir(),e.slice(2)):e;return n.resolve(process.cwd(),t)}(e.modulePath),o=function(e,t){let r=e.createReporter??e.default??e.reporter;if(!r)throw new R("INVALID_ARGS",`Custom test reporter ${t} must export default, createReporter, or reporter.`);return"function"==typeof r?r:()=>r}(await eW(t),e.modulePath);var s=await o({spec:e.raw,modulePath:t}),a=e.modulePath;if(!s||"object"!=typeof s)throw new R("INVALID_ARGS",`Custom test reporter ${a} must export a reporter object or factory.`);if("string"!=typeof s.name||0===s.name.trim().length)throw new R("INVALID_ARGS",`Custom test reporter ${a} must define name.`);for(let e of eH)if(void 0!==s[e]&&"function"!=typeof s[e])throw new R("INVALID_ARGS",`Custom test reporter ${a} ${e} must be a function.`);return s}async function eW(t){try{let r=t.startsWith("file:")?t:e(t).href;return await import(r)}catch(r){let e=r instanceof Error?r.message:String(r);throw new R("INVALID_ARGS",`Failed to load custom test reporter ${t}: ${e}`)}}function eJ(e){let t=Math.max(0,e)/1e3;return t>=10?`${t.toFixed(1)}s`:t>=1?`${t.toFixed(2)}s`:`${t.toFixed(3).replace(/0+$/,"").replace(/\.$/,"")}s`}function ez(e){var r,o;let s=(r=e).artifactsDir?n.join(r.artifactsDir,`attempt-${r.attempts}`,"replay-timing.ndjson"):void 0;if(!s)return[];let a=function(e){try{return t.readFileSync(e,"utf8").split(/\r?\n/).filter(e=>e.trim().length>0).flatMap(e=>{try{let t=JSON.parse(e);return e1(t)?[t]:[]}catch{return[]}})}catch{return[]}}(s);if(0===a.length)return[];let i=[],l=[];for(let e of a){if("replay_action_start"===(o=e).type&&eZ(o)&&eY(o,"line")&&eX(o,"command")&&(void 0===o.positionals||Array.isArray(o.positionals))){i.push(e);continue}(function(e){var t;return["replay_action_stop"===e.type&&eZ(e)&&eY(e,"line")&&eX(e,"command"),void 0===(t=e).ok||"boolean"==typeof t.ok,eY(e,"durationMs"),eX(e,"errorCode"),void 0===e.resultTiming||e1(e.resultTiming)].every(Boolean)})(e)&&l.push({stop:e,start:function(e,t){let r=t.command,n=e.findIndex(e=>e.step===t.step&&(void 0===r||void 0===e.command||e.command===r));if(!(n<0))return e.splice(n,1)[0]}(i,e)})}return l}function eZ(e){return"number"==typeof e.step}function eY(e,t){return void 0===e[t]||"number"==typeof e[t]}function eX(e,t){return void 0===e[t]||"string"==typeof e[t]}function eQ(e,t){var r,n,o,s;let a,i,l=!1===e.ok?"[FAIL] ":!0===e.ok?"":"[info] ";return` ${l}${r=t,n=e,[function(e){if(!e)return"unknown";if(!e.startsWith("__maestro"))return e;let t=e.slice(9);return t.length>0?t[0].toLowerCase()+t.slice(1):e}(r?.command??n.command),...(r?.positionals??[]).map(e0)].join(" ")}${o=e,s=t,(i=["number"==typeof(a=s?.line??o.line)?`line ${a}`:"","number"==typeof o.durationMs?eJ(o.durationMs):"",o.errorCode??"",o.resultTiming?`timing ${JSON.stringify(o.resultTiming)}`:""].filter(Boolean)).length>0?` (${i.join(", ")})`:""}`}function e0(e){return"string"==typeof e?JSON.stringify(e):"number"==typeof e||"boolean"==typeof e?String(e):JSON.stringify(e)}function e1(e){return!!e&&"object"==typeof e&&!Array.isArray(e)}let e8=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"],e3="\x1b[0m";function e2(e,t){return L(e,t,{validateStream:!1})}function e4(e,t={}){var r;let n;if("number"!=typeof e.shardIndex)return"";let o="number"==typeof e.shardCount?e.shardCount:"?",s=(r=e,(n=r.deviceName?.trim())||r.deviceId?.trim()||void 0),a=` [${e.shardIndex+1}/${o}${s?` ${s}`:""}]`;return t.useColor?e2(a,"dim"):a}function e5(e){return`\r\x1b[2K${e}`}function e6(e){return"number"==typeof e&&Number.isFinite(e)&&e>0?Math.floor(e):80}function e9(e,t){let r=e6(t);return e7(e)<=r?e:r<=0?"":r<=3?".".repeat(r):`${function(e,t){if(t<=0)return"";let r=0,n="";for(let o=0;o<e.length&&r<t;){let t=te(e,o);if(t){n+=t,o+=t.length;continue}n+=e[o],o+=1,r+=1}return n}(e,r-3)}...${e.includes("\x1b[")?e3:""}`}function e7(e){let t=0;for(let r=0;r<e.length;){let n=te(e,r);if(n){r+=n.length;continue}t+=1,r+=1}return t}function te(e,t){if(!e.startsWith("\x1b[",t))return null;for(let n=t+2;n<e.length;n+=1){var r;if((r=e.charCodeAt(n))>=64&&r<=126)return e.slice(t,n+1)}return null}function tt(e){return{file:e.file,title:e.title,durationMs:e.durationMs??0,attempts:e.attempt??1,artifactsDir:e.artifactsDir,session:e.session??""}}function tr(e){return+(e.failed>0)}function tn(e){return"failed"===e.status}function to(e){return"passed"===e.status&&e.attempts>1}function ts(e){let t=th(e),r=n.basename(e.file),o=t&&t.length>0?t:r;return`${o}${tv(e)}`}function ta(e,t){return"artifactsDir"in e&&e.artifactsDir?`${t}: ${e.artifactsDir}`:void 0}function ti(e){return e.hint?`hint: ${e.hint}`:void 0}function tl(e,t){return e.diagnosticId?`${t}: ${e.diagnosticId}`:void 0}function tc(e,t){return e.logPath?`${t}: ${e.logPath}`:void 0}function td(e,t,r={}){r.includeMessage&&e.push(`errorMessage: ${t.message}`),tf(e,ti(t)),tf(e,tl(t,"diagnosticId")),tf(e,tc(t,"logPath")),!1!==r.includeDetails&&tu(e,t,r.detailsIndent)}function tu(e,t,r){let n=t.details?JSON.stringify(t.details,null,r):void 0;n&&e.push(`details: ${n}`)}function tf(e,t){t&&e.push(t)}function tp(e){return(Math.max(0,e)/1e3).toFixed(3)}function tm(e){return e.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;").replaceAll("'","&apos;")}function tg(e){return void 0!==e}function th(e){let t=e.title?.trim();return t&&t.length>0?t:void 0}function tv(e){var t;let r;if(!("shardIndex"in e)||"number"!=typeof e.shardIndex)return"";let n="number"==typeof e.shardCount?e.shardCount:"?",o=(r="deviceName"in(t=e)?t.deviceName?.trim():void 0)||("deviceId"in t?t.deviceId?.trim():void 0)||void 0;return` [${e.shardIndex+1}/${n}${o?` ${o}`:""}]`}let ty="\x1b[?25l",tw="\x1b[?25h";function tI(e){return e.stderr.isTTY&&!process.env.CI}function tA(e){var t,r;let n,o=e.trim();if(!o)throw new R("INVALID_ARGS","Test reporter spec cannot be empty.");if((t=o).startsWith(".")||t.startsWith("/")||t.startsWith("~")||t.startsWith("file:"))return{kind:"custom",modulePath:o,raw:o};let{name:s,value:a}=(n=(r=o).indexOf(":"))<0?{name:r.trim()}:{name:r.slice(0,n).trim(),value:r.slice(n+1)};if("default"===s){if(void 0!==a)throw new R("INVALID_ARGS","The default test reporter does not accept options.");return{kind:"builtin",name:s,raw:o}}if("junit"===s)return void 0===a?{kind:"builtin",name:s,raw:o}:{kind:"builtin",name:s,raw:o,outputPath:a};throw new R("INVALID_ARGS",`Unknown test reporter "${s}". Built-in reporters: default, junit:<path>. Custom reporters must be file paths.`)}let tS={"suite-start":"onSuiteStart","test-start":"onTestStart","test-step":"onTestStep","test-result":"onTestResult"};async function tk(e){let t,r=(t=e.reporters&&e.reporters.length>0?e.reporters.map(tA):e.json?[]:[tA("default")],e.reportJunit&&t.push(tA(`junit:${e.reportJunit}`)),t);return await Promise.all(r.map(tb))}async function t_(e,t,r){for(let n of e)await n.onSuiteEnd?.(t,r)}function tD(e,t,r,n){let o=n instanceof Error?n.message:String(n);r.stderr.write(`Reporter ${e.name} ${String(t)} failed: ${o}
2
- `)}async function tb(e){let r;if("custom"===e.kind)return await eq(e);if("default"===e.name){let e,t,r,o,s,a,i;return o=!1,s=(r,o)=>{i(),t="test-step"===r.type?r:void 0;let s=(e??=function(e={}){let t=new Set,r=!1,o=0;return{render(s){var a,i;if("suite-start"===s.type){t.clear(),r=!1;return}if("test-step"===s.type){if(!e.liveProgress)return;r=!0;let t=e8[o%e8.length]??e8[0];return o+=1,{text:e5(function(e,t,r){let o=e.title?.trim(),s=n.basename(e.file),a=K(process.stderr),i=function(e,t={}){return t.useColor?e2(e,"blue"):e}(r,{useColor:a}),l=e4(e,{useColor:a}),c=function(e,t={}){let r=e.stepIndex??0,n=e.stepTotal??0,o=`${r}/${n}`,s=e.stepCommand?.trim(),a=e.stepValue?.trim();if(!t.useColor){let e=[o,s,a].filter(Boolean).join(" ");return` [${e}]`}let i=e2("[","dim"),l=e2("]","dim"),c=[e2(o,"dim"),s?e2(s,"magenta"):"",a?e2(a,"green"):""].filter(Boolean);return` ${i}${c.join(" ")}${l}`}(e,{useColor:a}),d=`${l}${c}`,u=`${i} `;if(!o)return e9(`${u}${s}${d}`,t.columns);let f=e9(o,Math.max(0,e6(t.columns)-e7(u)-e7(d)));return e9(`${u}${f}${d}`,t.columns)}(s.test,e,t)),newline:!1}}if("test-result"!==s.type)return;if("pass"===(a=s.test).status||"skip"===a.status||"fail"===a.status&&!a.retrying){let e,r=(e="number"==typeof(i=s.test).shardIndex?i.shardIndex:"",[i.status,i.index,i.total,i.file,i.title??"",e].join("\0"));if(t.has(r))return;t.add(r)}let l=function(e,t={}){var r,o,s,a,i;let l,c,d,u,f,p,m;if("fail"===e.status&&e.retrying)return;let g=[(r=e,d=K(process.stderr),u="pass"===(o=r).status?V("pass",{passFormat:o.attempt&&o.attempt>1?"yellow":"green"}):V("fail"===o.status?"fail":"skip"),f=(s=r,l=s.title?.trim(),c=n.basename(s.file),l||c),p=e4(r,{useColor:d}),m=void 0!==r.durationMs?` ${function(e,t={}){let r=eJ(e.durationMs??0);return t.useColor?e2(r,"yellow"):r}(r,{useColor:d})}`:"",`${u} ${f}${p}${m}`)];return function(e,t,r){var o,s,a,i;let l;if(o=t,!0===r.verbose&&"fail"===o.status)return;let c="fail"===(s=t).status&&s.title?.trim()?` file: ${n.basename(s.file)}`:void 0,d=function(e){let t=e.message?.replace(/\s+/g," ").trim();if(t)return` ${"fail"===e.status?`failed at: ${t}`:t}`}(t);c&&e.push(c),d&&e.push(d),a=e,i=t,l=i.hint?.replace(/\s+/g," ").trim(),"fail"===i.status&&l&&a.push(` hint: ${l}`),e.push(...function(e){if("fail"!==e.status||e.retrying)return[];let t=[];return e.session&&t.push(` session: ${e.session}`),e.artifactsDir&&t.push(` artifacts: ${e.artifactsDir}`),t}(t))}(g,e,t),t.verbose&&g.push(...("pass"===(a=e).status||"fail"===a.status)&&a.artifactsDir&&a.attempt?(function(e){if("skipped"===e.status)return[];let t=ez(e);return 0===t.length?[]:[e.attempts>1?`steps (attempt ${e.attempts}):`:"steps:",...t.map(({stop:e,start:t})=>eQ(e,t))]})("pass"===a.status?{...tt(a),status:"passed",replayed:0,healed:0}:{...tt(i=a),status:"failed",error:{code:"COMMAND_FAILED",message:i.message??"Unknown test failure"}}).map(e=>` ${e}`):[]),g.join("\n")}(s.test,e);if(!l)return;let c=r?e5(l):l;return r=!1,{text:c,newline:!0}}}}({verbose:o.verbose,liveProgress:tI(o),columns:o.stderr.columns})).render(r);s&&(o.stderr.write(s.newline?`${s.text}
3
- `:s.text),"test-step"===r.type&&tI(o)&&a(o))},a=n=>{!r&&t&&(r=setInterval(()=>{if(!t)return;let r=e?.render(t);r&&n.stderr.write(r.newline?`${r.text}
4
- `:r.text)},80),r.unref?.())},i=()=>{r&&(clearInterval(r),r=void 0)},{name:"default",onSuiteStart:(e,t)=>{!o&&tI(t)&&(t.stderr.write(ty),o=!0),s({type:"suite-start",suite:e},t)},onTestStep:(e,t)=>{s({type:"test-step",test:e},t)},onTestResult:(e,t)=>{s({type:"test-result",test:e},t)},onSuiteEnd:(e,r)=>{var s,a,l,c;let d,u,f,p,m,g,h,v;i(),t=void 0,o&&(r.stderr.write(tw),o=!1),s=e,a=r,d=s.tests.filter(to),a.stdout.write(`${(l=s,c=d.length,u="number"==typeof l.durationMs?l.durationMs:void 0,f=K(),p=function(e,t={}){let r=`${e} passed`;return t.useColor?L(r,"green"):r}(l.passed,{useColor:f}),m=function(e,t={}){let r=`(${e})`;return t.useColor?L(r,"dim"):r}(l.total,{useColor:f}),g=l.failed>0?`, ${l.failed} failed`:"",h=c>0?`, ${c} flaky`:"",v=void 0!==u?` in ${function(e,t={}){let r=eJ(e);return t.useColor?L(r,"yellow"):r}(u,{useColor:f})}`:"",`Test summary: ${p} ${m}${g}${h}${v}`)}
5
- `),function(e,t){if(0!==e.length)for(let r of(t.stdout.write("\n"),t.stdout.write("Failures:\n"),e))t.stdout.write(` ${ts(r)}
6
- `),function(e,t,r){let o=th(e)?`file: ${n.basename(e.file)}`:void 0;for(let n of(o&&t.stdout.write(`${r}${o}
7
- `),t.stdout.write(`${r}${e.error?.message??"Unknown test failure"}
8
- `),[ti(e.error),ta(e,"artifacts"),tc(e.error,"log"),tl(e.error,"diagnostic")].filter(tg)))t.stdout.write(`${r}${n}
9
- `);if(t.debug)for(let n of function(e){let t=ez(e),r=t.findIndex(({stop:e})=>!1===e.ok);if(r<0)return[];let n=t.slice(Math.max(0,r-2),r+1);return[e.attempts>1?`steps (attempt ${e.attempts}):`:"steps:",...n.map(({stop:e,start:t})=>eQ(e,t))]}(e))t.stdout.write(`${r}${n}
10
- `)}(r,t," ")}(s.tests.filter(tn),a),function(e,t){if(0!==e.length)for(let r of(t.stdout.write("\n"),t.stdout.write("Flaky tests:\n"),e))for(let e of(t.stdout.write(` ${K()?L("✓","yellow"):"✓"} ${ts(r)} after ${r.attempts} attempts${function(e){let t=["number"==typeof e.finalAttemptDurationMs?`passed attempt ${eJ(e.finalAttemptDurationMs)}`:"",e.durationMs>0?`total ${eJ(e.durationMs)}`:""].filter(Boolean);return t.length>0?` (${t.join(", ")})`:""}(r)}
11
- `),r.attemptFailures??[])){let r="number"==typeof e.durationMs?` (${eJ(e.durationMs)})`:"";t.stdout.write(` attempt ${e.attempt} failed${r}: ${e.message}
12
- `)}}(d,a)},getExitCode:tr}}return r=function(e){if(e&&e.trim().length>0)return e;throw new R("INVALID_ARGS","The junit test reporter requires an output path. Use --reporter junit:<path>.")}(e.outputPath),{name:"junit",onSuiteEnd:e=>(function(e,r){let o=n.dirname(e);try{t.mkdirSync(o,{recursive:!0}),t.writeFileSync(e,function(e){let t=['<?xml version="1.0" encoding="UTF-8"?>',"<testsuites>",` <testsuite name="agent-device replay suite" tests="${e.total}" failures="${e.failed}" skipped="${e.skipped}" time="${tp(e.durationMs)}">`];for(let r of e.tests)t.push(...function(e){let t=tm(`${th(e)??n.basename(e.file)}${tv(e)}`),r=tm(`${"."===n.dirname(e.file)?e.file:n.dirname(e.file)}${tv(e)}`),o=tm(e.file),s=tp(e.durationMs),a=[` <testcase classname="${r}" name="${t}" file="${o}" time="${s}">`];"failed"===e.status?a.push(` <failure message="${tm(e.error.message)}">${tm(function(e){let t=[e.error.message];return td(t,e.error,{includeDetails:!1}),tf(t,ta(e,"artifactsDir")),tu(t,e.error,2),t.join("\n")}(e))}</failure>`):"skipped"===e.status&&a.push(` <skipped message="${tm(e.message)}" />`);let i=function(e){let t=[`status: ${e.status}`,`durationMs: ${e.durationMs}`];return function(e,t){var r,n;for(let r of(tf(e,"attempts"in t?`attempts: ${t.attempts}`:void 0),tf(e,"session"in t?`session: ${t.session}`:void 0),tf(e,"replayed"in t?`replayed: ${t.replayed}`:void 0),tf(e,"healed"in t?`healed: ${t.healed}`:void 0),"passed"!==t.status?[]:(t.warnings??[]).map(e=>`warning: ${e}`)))e.push(r);tf(e,ta(t,"artifactsDir")),"shardIndex"in t&&"number"==typeof t.shardIndex&&(e.push(`shardIndex: ${t.shardIndex}`),tf(e,"number"==typeof t.shardCount?`shardCount: ${t.shardCount}`:void 0),tf(e,"string"==typeof t.deviceId?`deviceId: ${t.deviceId}`:void 0),tf(e,"string"==typeof t.deviceName?`deviceName: ${t.deviceName}`:void 0)),"failed"===t.status&&(r=e,n=t,r.push(`errorCode: ${n.error.code}`),td(r,n.error,{includeMessage:!0})),tf(e,to(t)?"flaky: true":void 0)}(t,e),t.join("\n")}(e);return i&&a.push(` <system-out>${tm(i)}</system-out>`),a.push(" </testcase>"),a}(r));return t.push(" </testsuite>"),t.push("</testsuites>"),`${t.join("\n")}
13
- `}(r),"utf8")}catch(r){let t=r instanceof Error?r.message:String(r);throw new R("COMMAND_FAILED",`Failed to write JUnit report to ${e}: ${t}`)}})(r,e),getExitCode:tr}}async function tC(e){let{suite:t,json:r,debug:n,verbose:o,reporter:s,reportJunit:a}=e,i=e.reporterRuntime??await t$({debug:n,verbose:o,reporter:s,reportJunit:a,json:r});await t_(i.reporters,t,i.context),r&&J({success:!0,data:t});var l=i.reporters;let c=tr(t);for(let e of l){let r=e.getExitCode?.(t);void 0!==r&&(c=Math.max(c,r))}return c}async function t$(e){var t;let r=await tk({reporters:e.reporter,reportJunit:e.reportJunit,json:e.json}),n={debug:(t={debug:e.debug,verbose:e.verbose}).debug,verbose:t.verbose??t.debug,stdout:tN(process.stdout),stderr:tN(process.stderr)};return{reporters:r,context:n,onProgress(e){!function(e,t,r){let n=function(e){if("command"===e.type)return;if("replay-test-suite"===e.type)return{type:"suite-start",suite:{total:e.total,runnable:e.runnable,skipped:e.skipped,artifactsDir:e.artifactsDir,shardMode:e.shardMode,shardCount:e.shardCount}};let t={file:e.file,title:e.title,index:e.index,total:e.total,attempt:e.attempt,maxAttempts:e.maxAttempts,session:e.session,artifactsDir:e.artifactsDir,shardIndex:e.shardIndex,shardCount:e.shardCount,deviceId:e.deviceId,deviceName:e.deviceName};return"start"===e.status?{type:"test-start",test:t}:"progress"===e.status?{type:"test-step",test:{...t,stepIndex:e.stepIndex,stepTotal:e.stepTotal,stepCommand:e.stepCommand,stepValue:e.stepValue}}:{type:"test-result",test:{...t,status:e.status,durationMs:e.durationMs,retrying:e.retrying,message:e.message,hint:e.hint}}}(t);if(!n)return;let o=tS[n.type];for(let t of e)try{let e=function(e,t,r){switch(t.type){case"suite-start":return e.onSuiteStart?.(t.suite,r);case"test-start":return e.onTestStart?.(t.test,r);case"test-step":return e.onTestStep?.(t.test,r);case"test-result":return e.onTestResult?.(t.test,r)}}(t,n,r);e instanceof Promise&&e.catch(e=>tD(t,o,r,e))}catch(e){tD(t,o,r,e)}}(r,e,n)}}}function tN(e){return{isTTY:!0===e.isTTY,columns:e.columns,write:t=>e.write(t)}}let tR={slug:"react-devtools-companion",runArg:Y,displayName:"React DevTools companion"};async function tP(e){return await z({...e,definition:tR,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 tx(e){return await Z({...e,definition:tR})}let tE=[{key:"stateDir",type:"string",path:!0},{key:"daemonBaseUrl",type:"string"},{key:"daemonAuthToken",type:"string"},{key:"daemonTransport",type:"enum",enumValues:["auto","socket","http"]},{key:"daemonServerMode",type:"enum",enumValues:["socket","http","dual"]},{key:"tenant",type:"string"},{key:"sessionIsolation",type:"enum",enumValues:["none","tenant"]},{key:"runId",type:"string"},{key:"leaseId",type:"string"},{key:"leaseBackend",type:"enum",enumValues:["ios-simulator","ios-instance","android-instance"]},{key:"platform",type:"enum",enumValues:Q},{key:"target",type:"enum",enumValues:["mobile","tv","desktop"]},{key:"device",type:"string"},{key:"udid",type:"string"},{key:"serial",type:"string"},{key:"iosSimulatorDeviceSet",type:"string",path:!0,env:!1},{key:"androidDeviceAllowlist",type:"string"},{key:"session",type:"string"},{key:"providerApp",type:"string"},{key:"providerOsVersion",type:"string"},{key:"providerProject",type:"string"},{key:"providerBuild",type:"string"},{key:"providerSessionName",type:"string"},{key:"awsProjectArn",type:"string"},{key:"awsDeviceArn",type:"string"},{key:"awsAppArn",type:"string"},{key:"awsRegion",type:"string"},{key:"awsInteractionMode",type:"enum",enumValues:["INTERACTIVE","NO_VIDEO","VIDEO_ONLY"]},{key:"metroProjectRoot",type:"string",path:!0},{key:"metroKind",type:"enum",enumValues:["auto","react-native","expo"]},{key:"metroPublicBaseUrl",type:"string"},{key:"metroProxyBaseUrl",type:"string"},{key:"metroBearerToken",type:"string"},{key:"metroPreparePort",type:"int",min:1,max:65535},{key:"metroListenHost",type:"string"},{key:"metroStatusHost",type:"string"},{key:"metroStartupTimeoutMs",type:"int",min:1},{key:"metroProbeTimeoutMs",type:"int",min:1},{key:"metroRuntimeFile",type:"string",path:!0},{key:"metroNoReuseExisting",type:"boolean"},{key:"metroNoInstallDeps",type:"boolean"}],tT=[...tE,{key:"leaseProvider",type:"string",env:!1},{key:"deviceKey",type:"string",env:!1},{key:"clientId",type:"string",env:!1}],tU=new Map(tT.map(e=>[e.key,e]));function tM(e){let t=e.env??process.env;return eo(e.configPath,{cwd:e.cwd,env:t})}function tL(e){let r=function(e){let r,o,s=e.env??process.env,a=tM(e);if(!t.existsSync(a))throw new R("INVALID_ARGS",`Remote config file not found: ${a}`);try{r=t.readFileSync(a,"utf8")}catch(e){throw new R("INVALID_ARGS",`Failed to read remote config file: ${a}`,{cause:e instanceof Error?e.message:String(e)})}try{o=JSON.parse(r)}catch(e){throw new R("INVALID_ARGS",`Invalid JSON in remote config file: ${a}`,{cause:e instanceof Error?e.message:String(e)})}if(!o||"object"!=typeof o||Array.isArray(o))throw new R("INVALID_ARGS",`Remote config file must contain a JSON object: ${a}`);let i={},l=o,c=n.dirname(a);for(let[e,t]of Object.entries(l)){let r=tU.get(e);if(!r)throw new R("INVALID_ARGS",`Unsupported remote config key "${e}" in remote config file ${a}.`);let n=v(r,t,`remote config file ${a}`,e);i[r.key]="string"==typeof n&&"path"in r&&r.path?eo(n,{cwd:c,env:s}):n}return{resolvedPath:a,profile:i}}(e);return{resolvedPath:r.resolvedPath,profile:function(...e){let t={};for(let r of e)if(r)for(let e of tT){let n=r[e.key];void 0!==n&&(t[e.key]=n)}return t}(function(e=process.env){let t={};for(let r of tT){let n=(function(e){let t=tU.get(e);return t?.env===!1?[]:[f(e)]})(r.key).map(t=>({name:t,value:e[t]})).find(e=>"string"==typeof e.value&&e.value.trim().length>0);n&&(t[r.key]=v(r,n.value,`environment variable ${n.name}`,n.name))}return t}(e.env),r.profile)}}function tB(e){return"android-instance"===e||"ios-instance"===e}function tO(e){return"target"===e[0]&&("list"===e[1]||"select"===e[1])&&!e.some(e=>"--url"===e||e.startsWith("--url="))}async function tV(e,t={}){let r=function(e,t={}){if(!tO(e)||!t.flags?.metroProxyBaseUrl||!tB(t.flags.leaseBackend))return e;let r=function(e){let t=e?.metroPublicBaseUrl?.trim();if(t){let e,r;return(e=new URL(t)).search="",e.hash="",r=e.pathname.replace(/\/+$/,""),e.pathname=r.endsWith("/index.bundle")?r.slice(0,-13)||"/":r||"/",e.toString().replace(/\/+$/,"")}return null}(t.flags);if(!r)throw new R("INVALID_ARGS","cdp remote bridge target discovery requires a Metro public base URL.",{hint:"Include metroPublicBaseUrl in the remote config so cdp can reach the local or tunneled Metro CDP endpoint without bridge proxy authentication."});return[...e,"--url",r]}(e,t);return(await u("npm",["exec","--yes","--package","agent-cdp@1.6.1","--","agent-cdp",...r],{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 tj(e){var r,n,o,s,a;let i,l=tq(e);if(!t.existsSync(l))return null;try{i=JSON.parse(t.readFileSync(l,"utf8"))}catch(t){return tY(e,t),null}return!(!(r=i)||"object"!=typeof r||Array.isArray(r))&&1===r.version&&(n=r,["session","remoteConfigPath","remoteConfigHash","tenant","runId","connectedAt","updatedAt"].every(e=>"string"==typeof n[e]))&&(o=r,["leaseId","leaseBackend","leaseProvider","deviceKey","clientId"].every(e=>void 0===o[e]||"string"==typeof o[e]))&&(void 0===(s=r.daemon)||!(!s||"object"!=typeof s||Array.isArray(s))&&(void 0===(a=s).baseUrl||"string"==typeof a.baseUrl)&&(void 0===a.authToken||"string"==typeof a.authToken)&&(void 0===a.transport||"string"==typeof a.transport)&&(void 0===a.serverMode||"string"==typeof a.serverMode))?i:(tY(e),null)}function tG(e){let r=tq({stateDir:e.stateDir,session:e.state.session});t.mkdirSync(n.dirname(r),{recursive:!0}),tZ(r,e.state),tZ(tW(e.stateDir),{session:e.state.session})}function tF(e){return{baseUrl:function(e){if(!e)return;let t=new URL(e);for(let e of(t.username="",t.password="",[...t.searchParams.keys()]))/(auth|key|password|secret|token)/i.test(e)&&t.searchParams.delete(e);return t.toString().replace(/\/+$/,"")}(e.daemonBaseUrl),authToken:e.daemonAuthToken,transport:e.daemonTransport,serverMode:e.daemonServerMode}}function tK(e){t.rmSync(tq(e),{force:!0});let r=tW(e.stateDir);tz(e.stateDir)===e.session&&t.rmSync(r,{force:!0})}function tH(e){try{return o.createHash("sha256").update(t.readFileSync(e)).digest("hex")}catch(t){throw new R("INVALID_ARGS",`Remote config file not found: ${e}`,{cause:t instanceof Error?t.message:String(t)})}}function tq(e){return n.join(e.stateDir,"remote-connections",`${function(e){let t=e.replaceAll(/[^a-zA-Z0-9._-]/g,"_");if(!t)return"default";if(t===e)return t;let r=o.createHash("sha256").update(e).digest("hex").slice(0,8);return`${t}-${r}`}(e.session)}.json`)}function tW(e){return n.join(e,"remote-connections",".active-session.json")}function tJ(e){let t=tz(e.stateDir);return t?tj({stateDir:e.stateDir,session:t}):null}function tz(e){let r=tW(e);if(t.existsSync(r))try{let e=JSON.parse(t.readFileSync(r,"utf8"));return"string"==typeof e.session?e.session:void 0}catch{return}}function tZ(e,r){t.writeFileSync(e,`${JSON.stringify(r,null,2)}
14
- `,{encoding:"utf8",mode:384}),t.chmodSync(e,384)}function tY(e,t){y({level:"warn",phase:"remote_connection_state_invalid",data:{session:e.session,cause:t instanceof Error?t.message:t?String(t):void 0}}),tK(e)}let tX=tE.map(e=>e.key);function tQ(e){let t={};for(let r of tX){let n=e[r];void 0!==n&&(t[r]=n)}return t}let t0=new Set(["artifacts","connect","connection","close","disconnect","metro","session"]),t1=new Set(["open"]),t8=new Set([S.open,S.install,S.reinstall,I.installSource]);async function t3(e){var t;let r,{command:n,flags:o,client:s}=e;if(!o.remoteConfig)return{flags:o,runtime:e.runtime};let a=ep(o.stateDir).baseDir,i=tL({configPath:o.remoteConfig,cwd:process.cwd(),env:process.env}),l={...tQ(i.profile),...o,remoteConfig:i.resolvedPath},c=tj({stateDir:a,session:l.session??"default"});if(c&&c.remoteConfigPath!==i.resolvedPath)throw new R("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:i.resolvedPath});let d=c??function(e,t,r={}){if(!e.tenant)throw new R("INVALID_ARGS","remote command requires tenant in remote config or via --tenant <id>.");if(!e.runId)throw new R("INVALID_ARGS","remote command requires runId in remote config or via --run-id <id>.");if(!e.daemonBaseUrl&&!ei(r.leaseProvider))throw new R("INVALID_ARGS","remote command requires daemonBaseUrl in remote config, config, env, or --daemon-base-url.");let n=new Date().toISOString();return{version:1,session:e.session??"default",remoteConfigPath:t,remoteConfigHash:tH(t),daemon:tF(e),tenant:e.tenant,runId:e.runId,leaseId:e.leaseId,leaseBackend:e.leaseBackend??ra(e),leaseProvider:r.leaseProvider,clientId:r.clientId,deviceKey:r.deviceKey,platform:e.platform,target:e.target,connectedAt:n,updatedAt:n}}(l,i.resolvedPath,i.profile),u={...l,session:d.session},f=function(e,t){if(e)return rl(e,t)?e:void 0}(d.runtime,u.platform)??e.runtime,p=d,m=!c,g="proxy"===(t=p).leaseProvider?t9:ei(t.leaseProvider)?t7:t6;if(g.shouldAllocate(n)){let e=await t5({command:n,client:s,state:d,nextState:p,nextFlags:u,policy:g});p=e.state,m=m||e.changed,r=e.acquiredLeaseForCleanup}let h=await t2({command:n,flags:u,client:s,state:d,nextState:p,runtime:f,positionals:e.positionals,batchSteps:e.batchSteps,forceRuntimePrepare:e.forceRuntimePrepare});return p=h.state,f=h.runtime,m=m||h.changed,await t4({changed:m,stateDir:a,state:p,client:s,acquiredLeaseForCleanup:r,preparedMetroCleanupOnFailure:h.preparedMetroCleanupOnFailure,metroCleanupToStop:h.metroCleanupToStop}),{flags:{...u,session:p.session,leaseId:p.leaseId,leaseBackend:p.leaseBackend,platform:p.platform??u.platform,target:p.target??u.target},runtime:f,connection:W(F(p))}}async function t2(e){var t,r,n,o,s,a,i;let{command:l,flags:c,state:d,client:u}=e,f=(t=e.nextState,r=c,t.leaseId||!r.leaseId?t:{...t,leaseId:r.leaseId,leaseBackend:r.leaseBackend}),p=e.runtime;if(!function(e,t,r,n=[]){return"cdp"===e?tO(n)&&!!t.metroPublicBaseUrl:!!t1.has(e)||"batch"===e&&!!r&&r.some(e=>{let t=e.command.trim().toLowerCase();return t1.has(t)&&void 0===e.runtime})}(l,c,e.batchSteps,e.positionals)||!ri(c)||(n=e.forceRuntimePrepare,o=p,s=c.platform,!0!==n&&o&&rl(o,s)))return{state:f,runtime:p,changed:!1};if(!f.leaseId)throw new R("INVALID_ARGS",`${l} requires a resolved remote lease before Metro runtime can be prepared.`);let m=await re(c,u,d.remoteConfigPath,d.session,{tenantId:d.tenant,runId:d.runId,leaseId:f.leaseId}),g=(a=f.metro,i=m.cleanup,a?.projectRoot!==i?.projectRoot||a?.profileKey!==i?.profileKey||a?.consumerKey!==i?.consumerKey);return{state:f={...f,runtime:m.runtime,metro:m.cleanup,updatedAt:new Date().toISOString()},runtime:m.runtime,changed:!0,metroCleanupToStop:g?e.nextState.metro:void 0,preparedMetroCleanupOnFailure:g?m.cleanup:void 0}}async function t4(e){if(e.changed)try{tG({stateDir:e.stateDir,state:e.state})}catch(t){throw await rt(e.preparedMetroCleanupOnFailure),await rs(e.client,e.state,e.acquiredLeaseForCleanup),t}await rt(e.metroCleanupToStop)}async function t5(e){let{command:t,client:r,state:n,nextFlags:o,policy:s}=e,a=n.leaseBackend??ra(o),i=e.nextState,l=await s.resolveLeaseState({command:t,client:r,state:i,flags:o,leaseBackend:a});i=l.state,l.device&&function(e,t){if(e.platform=t.platform,e.target=t.target??e.target,ee(t)){e.udid=t.id;return}"android"===t.platform&&(e.serial=t.id)}(o,l.device);let c=i.leaseBackend??a??function(e,t){let r=ra(e);if(r)return r;throw new R("INVALID_ARGS",`${t} requires --platform ios|android or --lease-backend when the remote connection has not resolved a lease yet.`)}(o,t);var d,u,f,p,m,g,h,v=n,y=o,w=c;if(v.leaseBackend&&v.leaseBackend!==w)throw new R("INVALID_ARGS","Active remote connection is already bound to a different lease backend. Re-run connect --force to replace it.",{session:v.session,leaseBackend:v.leaseBackend});if(v.platform&&y.platform&&v.platform!==y.platform)throw new R("INVALID_ARGS","Active remote connection is already bound to a different platform. Re-run connect --force to replace it.",{session:v.session,platform:v.platform});if(v.target&&y.target&&v.target!==y.target)throw new R("INVALID_ARGS","Active remote connection is already bound to a different target. Re-run connect --force to replace it.",{session:v.session,target:v.target});let I=await rc(r,i,c,s,o),A=I.lease;return(o.leaseId=A.leaseId,o.leaseBackend=c,o.platform=i.platform??o.platform,o.target=i.target??o.target,d=i,u=A,f=c,d.leaseId===u.leaseId&&d.leaseBackend===f&&d.deviceKey===(u.deviceKey??d.deviceKey))?{state:i,changed:!1,acquiredLeaseForCleanup:I.acquired?A:void 0}:{state:(p=i,m=A,g=c,h=o,{...p,leaseId:m.leaseId,leaseBackend:g,leaseProvider:m.leaseProvider??p.leaseProvider,clientId:m.clientId??p.clientId,deviceKey:m.deviceKey??p.deviceKey,platform:p.platform??h.platform,target:p.target??h.target,updatedAt:new Date().toISOString()}),changed:!0,acquiredLeaseForCleanup:I.acquired?A:void 0}}let t6={shouldAllocate:e=>!t0.has(e),ttlMs:()=>void 0,resolveLeaseState:async e=>({state:e.state})},t9={shouldAllocate:e=>"devices"!==e&&!t0.has(e),ttlMs:()=>3e5,resolveLeaseState:rd},t7={shouldAllocate:e=>!t0.has(e),ttlMs:()=>6e5,resolveLeaseState:async e=>({state:e.state})};async function re(e,t,r,n,o){if(!e.metroProjectRoot&&!e.metroPublicBaseUrl&&!e.metroProxyBaseUrl)return{};if("ios"!==e.platform&&"android"!==e.platform)throw new R("INVALID_ARGS",'Deferred Metro preparation requires platform "ios" or "android".');if(!e.metroPublicBaseUrl&&!e.metroProxyBaseUrl)throw new R("INVALID_ARGS","Deferred Metro preparation requires metroPublicBaseUrl or metroProxyBaseUrl when Metro settings are provided.");let s=await t.metro.prepare({projectRoot:e.metroProjectRoot,kind:function(e){if(void 0!==e){if("auto"===e||"react-native"===e||"expo"===e)return e;throw new R("INVALID_ARGS","metro prepare --kind must be auto, react-native, or expo")}}(e.metroKind),publicBaseUrl:e.metroPublicBaseUrl,proxyBaseUrl:e.metroProxyBaseUrl,bearerToken:e.metroBearerToken,bridgeScope:o,launchUrl:e.launchUrl,companionProfileKey:r,companionConsumerKey:n,port:e.metroPreparePort,listenHost:e.metroListenHost,statusHost:e.metroStatusHost,startupTimeoutMs:e.metroStartupTimeoutMs,probeTimeoutMs:e.metroProbeTimeoutMs,reuseExisting:!e.metroNoReuseExisting&&void 0,installDependenciesIfNeeded:!e.metroNoInstallDeps&&void 0,runtimeFilePath:e.metroRuntimeFile});return{runtime:"ios"===e.platform?s.iosRuntime:s.androidRuntime,cleanup:e.metroProxyBaseUrl?{projectRoot:s.projectRoot,profileKey:r,consumerKey:n}:void 0}}async function rt(e){if(e)try{await em(e)}catch{}}async function rr(e){try{await tx({projectRoot:process.cwd(),stateDir:e.stateDir,profileKey:e.state.remoteConfigPath,consumerKey:e.state.session})}catch{}}async function rn(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 ro(e,t){if(t.leaseId)try{await rn(e,t)}catch{}}async function rs(e,t,r){if(r)try{await e.leases.release({tenant:t.tenant,runId:t.runId,leaseId:r.leaseId,leaseBackend:t.leaseBackend??r.backend,leaseProvider:t.leaseProvider??r.leaseProvider,clientId:t.clientId??r.clientId,deviceKey:t.deviceKey??r.deviceKey})}catch{}}function ra(e){return e.leaseBackend?e.leaseBackend:"android"===e.platform?"android-instance":"ios"===e.platform?"ios-instance":void 0}function ri(e){let t=e.metroKind;return!!(e.metroPublicBaseUrl||e.metroProxyBaseUrl||e.metroProjectRoot||t)}function rl(e,t){return!e.platform||!t||"ios"!==t&&"android"!==t||e.platform===t}async function rc(e,t,r,n,o){if(t.leaseId&&t.leaseBackend===r){let o=await rf(e,t.leaseId,{tenant:t.tenant,runId:t.runId,leaseBackend:r,leaseProvider:t.leaseProvider,clientId:t.clientId,deviceKey:t.deviceKey,ttlMs:n.ttlMs(t)});if(o)return{lease:o,acquired:!1}}return{lease:await e.leases.allocate({tenant:t.tenant,runId:t.runId,leaseBackend:r,leaseProvider:t.leaseProvider,clientId:t.clientId,deviceKey:t.deviceKey,ttlMs:n.ttlMs(t),platform:t.platform??o.platform,target:t.target??o.target,device:o.device,udid:o.udid,serial:o.serial,providerApp:o.providerApp,providerOsVersion:o.providerOsVersion,providerProject:o.providerProject,providerBuild:o.providerBuild,providerSessionName:o.providerSessionName,awsProjectArn:o.awsProjectArn,awsDeviceArn:o.awsDeviceArn,awsAppArn:o.awsAppArn,awsRegion:o.awsRegion,awsInteractionMode:o.awsInteractionMode}),acquired:!0}}async function rd(e){var t,r;if(!t8.has(e.command)){if(e.state.leaseId&&e.state.deviceKey)return{state:e.state};throw new R("INVALID_ARGS","No active proxy device lease for this session; run open first.")}let n=await ru(e.client,e.flags),o=(t=n,`${er(t)}:${t.target??"mobile"}:${t.id}`);return{state:{...e.state,deviceKey:o,leaseBackend:e.state.leaseBackend??e.leaseBackend??(ee(r=n)?"ios-instance":"android"===r.platform?"android-instance":void 0),platform:e.state.platform??n.platform,target:e.state.target??n.target,updatedAt:new Date().toISOString()},device:n}}async function ru(e,t){let r=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});return await et(r.map(e=>({...X(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})}async function rf(e,t,r){try{return await e.leases.heartbeat({tenant:r.tenant,runId:r.runId,leaseId:t,leaseBackend:r.leaseBackend,leaseProvider:r.leaseProvider,clientId:r.clientId,deviceKey:r.deviceKey,ttlMs:r.ttlMs})}catch(e){var n;if((n=e)instanceof R&&"UNAUTHORIZED"===n.code&&(n.details?.reason==="LEASE_NOT_FOUND"||n.details?.reason==="LEASE_EXPIRED"||n.details?.reason==="LEASE_REVOKED"))return;throw e}}async function rp(e,t){let r=await e.text(),n={};if(r.trim().length>0)try{n=JSON.parse(r)}catch(r){throw new R("COMMAND_FAILED",t.invalidJsonMessage,{status:e.status},r instanceof Error?r:void 0)}if(!e.ok)throw new R("UNAUTHORIZED",t.rejectedMessage,{status:e.status,response:n});return n}async function rm(e){return await rg({command:e.command,flags:e.flags,stateDir:e.stateDir,allowInteractiveLogin:"connect"===e.command&&!e.flags.noLogin,env:e.env})}async function rg(e){let t=e.env??e.io?.env??process.env;if(!e.flags.daemonBaseUrl)return{flags:e.flags,source:"none"};if(rN(e.flags.daemonAuthToken))return{flags:e.flags,source:"flag"};if(rN(t.AGENT_DEVICE_DAEMON_AUTH_TOKEN))return{flags:e.flags,source:"env"};if(!function(e,t){if("1"===t.AGENT_DEVICE_CLOUD_AUTH||"true"===t.AGENT_DEVICE_CLOUD_AUTH||rN(t.AGENT_DEVICE_CLOUD_BASE_URL))return!0;try{let t=new URL(e).hostname.toLowerCase();return"agent-device.dev"===t||t.endsWith(".agent-device.dev")}catch{return!1}}(e.flags.daemonBaseUrl,t))return{flags:e.flags,source:"none"};let r=await rI({stateDir:e.stateDir,flags:e.flags,env:t,io:e.io});if(r)return{flags:{...e.flags,daemonAuthToken:r.accessToken},source:"cli-session"};if(!e.allowInteractiveLogin){if(e.flags.noLogin)throw new R("UNAUTHORIZED","Remote daemon authentication is required.",{hint:"Run agent-device auth login, unset --no-login, or set AGENT_DEVICE_DAEMON_AUTH_TOKEN."});throw r_(e.command,t)}let n=await rv({stateDir:e.stateDir,flags:e.flags,env:t,io:e.io});return{flags:{...e.flags,daemonAuthToken:n.accessToken},source:"login"}}async function rh(e){let t=e.env??e.io?.env??process.env;if(rN(e.flags.daemonAuthToken))return{accessToken:e.flags.daemonAuthToken,cloudBaseUrl:rD(t)};if(rN(t.AGENT_DEVICE_DAEMON_AUTH_TOKEN))return{accessToken:t.AGENT_DEVICE_DAEMON_AUTH_TOKEN,cloudBaseUrl:rD(t)};let r=await rI({stateDir:e.stateDir,flags:e.flags,env:t,io:e.io});if(r)return{accessToken:r.accessToken,cloudBaseUrl:r.cloudBaseUrl};if(e.flags.noLogin)throw new R("UNAUTHORIZED","Cloud connection profile authentication is required.",{hint:"Run agent-device auth login, unset --no-login, or set AGENT_DEVICE_DAEMON_AUTH_TOKEN."});let n=await rv({stateDir:e.stateDir,flags:e.flags,env:t,io:e.io,commandLabel:"agent-device connect"});return{accessToken:n.accessToken,cloudBaseUrl:n.session.cloudBaseUrl}}async function rv(e){let r,o,s,a=e.env??e.io?.env??process.env,i=(d=a,u=e.io,r=u?.stdinIsTTY??process.stdin.isTTY,o=u?.stdoutIsTTY??process.stdout.isTTY,"true"!==(f=d).CI&&"true"!==f.GITHUB_ACTIONS&&"true"!==f.BUILDKITE&&r&&o?(p=d).SSH_TTY||p.SSH_CONNECTION||"true"===p.CODESPACES||p.GITPOD_WORKSPACE_ID||"true"===p.REMOTE_CONTAINERS?"device-code":"local-browser":"non-interactive");if("non-interactive"===i)throw r_(e.commandLabel??"agent-device connect",a);let l=rD(a),c=await rk({baseUrl:l,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});var d,u,f,p,m,g,h=c;if(!rN(h.deviceCode)||!rN(h.userCode)||!rN(h.verificationUri))throw new R("COMMAND_FAILED","Cloud auth start returned an unusable response.");let v=c.verificationUriComplete??c.verificationUri,y="local-browser"===i?c.verificationUri:(m=c.verificationUri,g=c.userCode,(s=new URL(m)).searchParams.set("user_code",g),s.toString());"local-browser"===i?(rC(e.io,`Opening ${c.verificationUri}...
15
- `),await rb(v,e.io)):rC(e.io,`Open this URL on your machine:
16
- ${y}
17
-
18
- Waiting for approval for 10 minutes...
19
- `);let w=await rS({cloudBaseUrl:l,deviceCode:c.deviceCode,expiresIn:c.expiresIn,interval:c.interval,fetchImpl:e.io?.fetch,now:e.io?.now}),I=w.cliSession?.refreshCredential??w.cliSession?.refreshToken;if(!rN(w.accessToken)||!rN(I))throw new R("UNAUTHORIZED","Device authorization did not return CLI credentials.");let A=new Date(e.io?.now?.()??Date.now()).toISOString(),S={version:1,id:w.cliSession?.id??`cli-${Date.now().toString(36)}`,cloudBaseUrl:l,workspaceId:w.cliSession?.workspaceId,accountId:w.cliSession?.accountId,name:w.cliSession?.name,refreshCredential:I,createdAt:A,expiresAt:w.cliSession?.expiresAt};return function(e){let r=rw(e.stateDir);t.mkdirSync(n.dirname(r),{recursive:!0,mode:448}),t.writeFileSync(r,`${JSON.stringify(e.session,null,2)}
20
- `,{mode:384});try{t.chmodSync(r,384)}catch{}}({stateDir:e.stateDir,session:S}),{accessToken:w.accessToken,expiresAt:w.expiresAt,session:S}}function ry(e){let r=rw(e.stateDir);if(!t.existsSync(r))return null;try{let e=JSON.parse(t.readFileSync(r,"utf8"));if(1!==e.version||!rN(e.id)||!rN(e.cloudBaseUrl)||!rN(e.refreshCredential)||!rN(e.createdAt))return null;return e}catch{return null}}function rw(e){return n.join(e,"auth","cli-session.json")}async function rI(e){let t=ry({stateDir:e.stateDir});return!t||r$(t.expiresAt,e.io?.now)?null:{accessToken:(await rA({session:t,flags:e.flags,env:e.env,io:e.io})).accessToken,cloudBaseUrl:rD(e.env,t.cloudBaseUrl)}}async function rA(e){let t=rD(e.env,e.session.cloudBaseUrl),r=await rk({baseUrl:t,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(rN(r.accessToken))return{accessToken:r.accessToken,expiresAt:r.expiresAt};if("revoked"===r.status||"revoked"===r.error)throw new R("UNAUTHORIZED","Stored cloud CLI session was revoked.",{hint:"Run agent-device auth login again, or set AGENT_DEVICE_DAEMON_AUTH_TOKEN.",status:r.status,error:r.error});throw new R("UNAUTHORIZED","Failed to refresh CLI session.",{hint:"Run agent-device auth login again, or set AGENT_DEVICE_DAEMON_AUTH_TOKEN.",status:r.status,error:r.error})}async function rS(e){let t=e.now??Date.now,r=Math.min((e.expiresIn??600)*1e3,6e5),n=t()+r,o=Math.max(1e3,(e.interval??5)*1e3);for(;t()<n;){let t=await rk({baseUrl:e.cloudBaseUrl,pathName:"/api/control-plane/device-auth/poll",body:{deviceCode:e.deviceCode},fetchImpl:e.fetchImpl});if("approved"===t.status||rN(t.accessToken))return t;if("slow_down"===t.status||"slow_down"===t.error)o+=1e3;else if("authorization_pending"!==t.status&&"authorization_pending"!==t.error)throw new R("UNAUTHORIZED","Device authorization was not approved.",{status:t.status,error:t.error});await rR(o)}throw new R("TIMEOUT","Device authorization expired before approval.")}async function rk(e){let t=e.fetchImpl??fetch,r=await t(new URL(e.pathName,e.baseUrl),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e.body),signal:AbortSignal.timeout(15e3)});return await rp(r,{invalidJsonMessage:`Cloud auth endpoint returned invalid JSON (${r.status}).`,rejectedMessage:"Cloud auth endpoint rejected the request."})}function r_(e,t){let r=rD(t);return new R("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 rD(e,t){let r=e.AGENT_DEVICE_CLOUD_BASE_URL??t??"https://cloud.agent-device.dev";try{return new URL(r).toString().replace(/\/+$/,"")}catch(e){throw new R("INVALID_ARGS","Invalid AGENT_DEVICE_CLOUD_BASE_URL.",{cloudBaseUrl:r},e instanceof Error?e:void 0)}}async function rb(e,t){if(t?.openBrowser)return void await t.openBrowser(e);let r=process.platform;try{"darwin"===r?await g("open",[e],{allowFailure:!0,timeoutMs:5e3}):"win32"===r?await g("cmd",["/c","start","",e],{allowFailure:!0,timeoutMs:5e3}):await g("xdg-open",[e],{allowFailure:!0,timeoutMs:5e3})}catch{rC(t,`Open this URL on your machine:
21
- ${e}
22
- `)}}function rC(e,t){(e?.stderr??process.stderr).write(t)}function r$(e,t){if(!e)return!1;let r=Date.parse(e);return!Number.isFinite(r)||r<=(t?.()??Date.now())}function rN(e){return"string"==typeof e&&e.trim().length>0}async function rR(e){await new Promise(t=>setTimeout(t,e))}let rP=new Set(["daemonAuthToken","metroBearerToken"]);function rx(e){let r=function(e){try{return tL(e)}catch(r){let t=$(r);throw new R("COMMAND_FAILED",`${e.provider} connection profile returned invalid remote config.`,{generatedConfigPath:e.configPath,cause:t.message},t)}}({configPath:function(e){var r;let s=function e(t){return Array.isArray(t)?t.map(e):t&&"object"==typeof t?Object.fromEntries(Object.entries(t).filter(([,e])=>void 0!==e).sort(([e],[t])=>e.localeCompare(t)).map(([t,r])=>[t,e(r)])):t}(Object.fromEntries(Object.entries(e.profile).filter(([e])=>!rP.has(e)))),a=n.join(e.stateDir,"remote-connections","generated");t.mkdirSync(a,{recursive:!0,mode:448});let i=n.join(a,`${e.provider.replaceAll(/[^a-zA-Z0-9._-]/g,"_")||"generated"}-${(r=s,o.createHash("sha256").update(JSON.stringify(r)).digest("hex").slice(0,16))}.json`);t.writeFileSync(i,`${JSON.stringify(s,null,2)}
23
- `,{mode:384});try{t.chmodSync(i,384)}catch{}return i}({stateDir:e.stateDir,provider:e.provider,profile:e.profile}),cwd:e.cwd,env:e.env,provider:function(e){let[t="",...r]=e;return`${t.toUpperCase()}${r.join("")}`}(e.provider)});return{flags:{...tQ(r.profile),...e.flags,...e.extraFlags??{},remoteConfig:r.resolvedPath},remoteConfigPath:r.resolvedPath}}async function rE(e){var t;let r=await rh({stateDir:e.stateDir,flags:e.flags,env:e.env,io:{env:e.env,fetch:e.fetchImpl}}),n=await rT({cloudBaseUrl:r.cloudBaseUrl,accessToken:r.accessToken,fetchImpl:e.fetchImpl}),s=(t={stateDir:e.stateDir,cloudBaseUrl:r.cloudBaseUrl,daemonBaseUrl:"string"==typeof n.daemonBaseUrl?n.daemonBaseUrl:"",session:e.flags.session},o.createHash("sha256").update(`${t.stateDir}\0${t.cloudBaseUrl}\0${t.daemonBaseUrl}\0${t.session??""}`).digest("hex").slice(0,16));return rx({stateDir:e.stateDir,provider:"cloud",profile:{...n,leaseProvider:n.leaseProvider??"cloud",clientId:n.clientId??s,runId:n.runId??`cloud-${s}`},cwd:e.cwd,env:e.env,flags:e.flags,extraFlags:{daemonAuthToken:r.accessToken}})}async function rT(e){let t=e.fetchImpl??fetch,r=await t(new URL("/api/control-plane/connection-profile",e.cloudBaseUrl),{method:"GET",headers:{authorization:`Bearer ${e.accessToken}`},signal:AbortSignal.timeout(15e3)});var n=await rp(r,{invalidJsonMessage:`Cloud connection profile endpoint returned invalid JSON (${r.status}).`,rejectedMessage:"Cloud connection profile endpoint rejected the request."});if(!n||"object"!=typeof n||Array.isArray(n))throw new R("COMMAND_FAILED","Cloud connection profile response is invalid.");let o=n.connection;if(!o||"object"!=typeof o)throw new R("COMMAND_FAILED","Cloud connection profile response is missing profile.");if(void 0!==o.remoteConfigProfile){var s=o.remoteConfigProfile;if(!s||"object"!=typeof s||Array.isArray(s))throw new R("COMMAND_FAILED","Cloud connection profile remoteConfigProfile is invalid.");if(0===Object.keys(s).length)throw new R("COMMAND_FAILED","Cloud connection profile remoteConfigProfile is empty.");return s}throw new R("COMMAND_FAILED","Cloud connection profile did not include remoteConfigProfile.")}function rU(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}}let rM=[{provider:el.browserStack,buildProfileFields:function(e){rO(e.env,"BROWSERSTACK_USERNAME","connect browserstack"),rO(e.env,"BROWSERSTACK_ACCESS_KEY","connect browserstack");let t=rL(e.flags.platform,"connect browserstack requires --platform ios|android."),r=rB(e.flags.device,"connect browserstack requires --device <name>.");return{platform:t,device:r,providerOsVersion:rB(e.flags.providerOsVersion,"connect browserstack requires --provider-os-version <version>."),providerApp:rB(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}}},{provider:el.awsDeviceFarm,buildProfileFields:function(e){let{env:t,flags:r}=e;return{platform:rL(r.platform,"connect aws-device-farm requires --platform ios|android."),device:r.device,awsProjectArn:function(e,t,r,n){return rB(rV(e,t,r),n)}(r.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:function(e,t,r,n){return rB(rV(e,t,r),n)}(r.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:rV(r.awsAppArn,t,["AGENT_DEVICE_AWS_DEVICE_FARM_APP_ARN","AWS_DEVICE_FARM_APP_ARN"]),awsRegion:rV(r.awsRegion,t,["AWS_REGION","AWS_DEFAULT_REGION"]),awsInteractionMode:r.awsInteractionMode,providerSessionName:r.providerSessionName}}}];function rL(e,t){if("android"===e||"ios"===e)return e;throw new R("INVALID_ARGS",t)}function rB(e,t){if(e)return e;throw new R("INVALID_ARGS",t)}function rO(e,t,r){let n=e?.[t];if(n)return n;throw new R("INVALID_ARGS",`${r} requires ${t} in the environment.`)}function rV(e,t,r){return e||r.map(e=>t?.[e]).find(e=>!!e)}function rj(e,t,r){var n;if(e.json)return void J({success:!0,data:t});let o=r?.();o&&(n=o,process.stdout.write(n.endsWith("\n")?n:`${n}
24
- `))}let rG=async({positionals:e,flags:t,client:r})=>{let n,s,a=ep(t.stateDir).baseDir,i=function(e){let t=e[0];if(void 0!==t){if(e.length>1)throw new R("INVALID_ARGS","connect accepts at most one provider positional.");if("cloud"===t||"proxy"===t||ei(t))return t;throw new R("INVALID_ARGS",`Unknown connect provider: ${t}. Supported providers: ${["cloud","proxy",el.browserStack,el.awsDeviceFarm].join(", ")}.`)}}(e);var l=i,c=t;if(l&&c.remoteConfig)throw new R("INVALID_ARGS","connect provider positional and --remote-config are mutually exclusive.");let d=await rF({provider:i,flags:t,stateDir:a}),u=d.flags,f=Object.values(s={leaseProvider:(n=tL({configPath:d.remoteConfigPath,cwd:process.cwd(),env:process.env}).profile).leaseProvider,clientId:n.clientId,deviceKey:n.deviceKey}).some(e=>void 0!==e)?s:void 0,p=function(e,t){if(!e.tenant)throw new R("INVALID_ARGS","connect requires tenant in remote config or via --tenant <id>.");if(!e.runId)throw new R("INVALID_ARGS","connect requires runId in remote config or via --run-id <id>.");if(!e.daemonBaseUrl&&!ei(t?.leaseProvider))throw new R("INVALID_ARGS","connect requires daemonBaseUrl in remote config, config, env, or --daemon-base-url.");return{tenant:e.tenant,runId:e.runId}}(u,f),m=function(e){let{stateDir:t,flags:r,remoteConfigPath:n}=e,s=r.session?null:tJ({stateDir:t}),a=r.session??s?.session??function(e){for(let t=0;t<8;t+=1){let t=`adc-${o.randomBytes(3).toString("hex")}`;if(!tj({stateDir:e,session:t}))return t}return`adc-${Date.now().toString(36)}-${o.randomBytes(2).toString("hex")}`}(t),i=s?.session===a?s:tj({stateDir:t,session:a});return{session:a,previous:i,remoteConfigHash:tH(n),daemon:tF(r)}}({stateDir:a,flags:u,remoteConfigPath:d.remoteConfigPath});!function(e,t){var r,n,o,s,a,i,l,c;if(!(!e||(r=e,n=t,o=r,s=n,[[o.remoteConfigPath,s.remoteConfigPath],[o.remoteConfigHash,s.remoteConfigHash],[o.session,s.session],[o.tenant,s.flags.tenant],[o.runId,s.flags.runId]].every(([e,t])=>e===t)&&(a=r,i=n,[[a.leaseBackend,i.desiredLeaseBackend],[a.platform,i.flags.platform],[a.target,i.flags.target],[a.leaseProvider,i.connection?.leaseProvider],[a.clientId,i.connection?.clientId]].every(([e,t])=>void 0===t||e===t))&&(l=r.daemon,c=n.daemon,["baseUrl","transport","serverMode"].every(e=>(l?.[e]??void 0)===(c?.[e]??void 0)))))&&!t.flags.force)throw new R("INVALID_ARGS","A different remote connection is already active for this session. Re-run connect with --force to replace it.",{session:t.session,remoteConfig:e.remoteConfigPath})}(m.previous,{flags:u,session:m.session,remoteConfigPath:d.remoteConfigPath,remoteConfigHash:m.remoteConfigHash,desiredLeaseBackend:ra(u),connection:f,daemon:m.daemon});let g=function(e){var t,r,n,o,s,a,i;let{flags:l,scope:c,connectionMetadata:d,context:u,remoteConfigPath:f}=e,p=(t=l,u.previous&&!t.force)?u.previous:null,m=new Date().toISOString(),g=(r=l,n=p,o=d,{leaseId:n?.leaseId,leaseBackend:n?.leaseBackend??ra(r),leaseProvider:o?.leaseProvider??n?.leaseProvider,clientId:o?.clientId??n?.clientId,deviceKey:n?.deviceKey??o?.deviceKey}),h=(s=l,a=p,i=m,{platform:s.platform??a?.platform,target:s.target??a?.target,runtime:a?.runtime,metro:a?.metro,connectedAt:a?.connectedAt??i});return{version:1,session:u.session,remoteConfigPath:f,remoteConfigHash:u.remoteConfigHash,daemon:u.daemon,tenant:c.tenant,runId:c.runId,...g,...h,updatedAt:m}}({flags:u,scope:p,connectionMetadata:f,context:m,remoteConfigPath:d.remoteConfigPath});tG({stateDir:a,state:g}),await rK(r,a,u,m.previous);let h=rz(g),v=function(e,t){if(!t.runtime&&(ri(e)||rY(t.remoteConfigPath)))return rZ(t.remoteConfigPath)}(u,g);return rj(u,rX(g,v),()=>[`Connected remote session "${m.session}" tenant "${p.tenant}" run "${p.runId}" ${g.leaseId?`lease ${g.leaseId}`:"lease pending"}`,h?.message,v?.message].filter(e=>!!e).join("\n")),!0};async function rF(e){let{provider:t,flags:r,stateDir:n}=e;if(r.remoteConfig){var s,a,i,l,c,d,u=r;if(!u.remoteConfig)throw new R("INVALID_ARGS","connect requires --remote-config <path>.");let e=tL({configPath:u.remoteConfig,cwd:process.cwd(),env:process.env});return{flags:u,remoteConfigPath:e.resolvedPath}}if(ei(t)){let e,d,u;return e=(function(e){let t=rM.find(t=>t.provider===e)?.buildProfileFields;if(t)return t;throw new R("INVALID_ARGS",`Unsupported cloud WebDriver provider "${e}".`)})((s={provider:t,flags:r,stateDir:n,cwd:process.cwd(),env:process.env}).provider)(s),a=s.provider,i=s.stateDir,l=s.flags.session,c=e.device,d=o.createHash("sha256").update(`${a}\0${i}\0${l??""}\0${c??""}`).digest("hex").slice(0,16),u={tenant:s.flags.tenant??s.provider,sessionIsolation:s.flags.sessionIsolation??"tenant",runId:s.flags.runId??`${s.provider}-${d}`,leaseProvider:s.provider,clientId:d,leaseBackend:s.flags.leaseBackend??ra(s.flags),target:s.flags.target??"mobile",session:s.flags.session,...e,...rU(s.flags)},rx({stateDir:s.stateDir,provider:s.provider,profile:u,cwd:s.cwd,env:s.env,flags:s.flags})}return"proxy"===t||!t&&(d=r).daemonBaseUrl&&!d.tenant&&!d.runId&&!d.leaseId&&!d.leaseBackend&&function(e){try{return new URL(e).pathname.replace(/\/+$/,"").endsWith("/agent-device")}catch{return!1}}(d.daemonBaseUrl)?function(e){var t,r,n;let s=e.flags.daemonBaseUrl??e.env?.AGENT_DEVICE_DAEMON_BASE_URL;if(!s)throw new R("INVALID_ARGS","connect proxy requires --daemon-base-url <url> or AGENT_DEVICE_DAEMON_BASE_URL.");let a=(t=e.stateDir,r=s,n=e.flags.session,o.createHash("sha256").update(`${t}\0${r}\0${n??""}`).digest("hex").slice(0,16)),i={daemonBaseUrl:s,daemonTransport:e.flags.daemonTransport??"http",daemonServerMode:e.flags.daemonServerMode,tenant:e.flags.tenant??"proxy",sessionIsolation:e.flags.sessionIsolation??"tenant",runId:e.flags.runId??`proxy-${a}`,leaseProvider:"proxy",clientId:a,leaseBackend:e.flags.leaseBackend??ra(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,...rU(e.flags)};return rx({stateDir:e.stateDir,provider:"proxy",profile:i,cwd:e.cwd,env:e.env,flags:e.flags,extraFlags:{daemonBaseUrl:s,daemonTransport:e.flags.daemonTransport??"http"}})}({flags:r,stateDir:n,cwd:process.cwd(),env:process.env}):await rE({flags:r,stateDir:n,cwd:process.cwd(),env:process.env})}async function rK(e,t,r,n){n&&r.force&&(await rt(n.metro),await rr({stateDir:t,state:n}),await ro(e,n))}let rH=async({flags:e,client:t})=>{let r,{session:n,stateDir:o,state:s}=rW(e);if(!s)return rJ(e,n),!0;let a=s.session;try{r=(await t.sessions.close({session:a,shutdown:e.shutdown})).provider}catch{}await rt(s.metro),await rr({stateDir:o,state:s});let i=!1;if(s.leaseId)try{let e=await rn(t,s);i=e.released,r??=e.provider}catch{}return tK({stateDir:o,session:a}),rj(e,{connected:!1,session:a,released:i,...r?{provider:r}:{}},()=>{var e,t,n;return e=a,[`Disconnected remote session "${e}".`,...(n=t=r,(Array.isArray(n?.warnings)?n.warnings:[]).flatMap(e=>{let t=function(e){if(!e||"object"!=typeof e||"string"!=typeof e.message||0===e.message.length)return;let t="string"==typeof e.code&&e.code.length>0?` (${e.code})`:"";return`Provider release warning${t}: ${e.message}`}(e);return t?[t]:[]})),...(t?.cloudArtifacts?.cloudArtifacts??[]).filter(e=>(e.availability??"ready")==="ready"&&e.url).slice(0,3).map(e=>`${e.name}: ${e.url}`)].join("\n")}),!0},rq=async({positionals:e,flags:t})=>{if("status"!==e[0])throw new R("INVALID_ARGS","connection accepts only: status");let{session:r,state:n}=rW(t);if(!n)return rJ(t,r),!0;let o=rz(n),s=function(e){if(!e.runtime&&rY(e.remoteConfigPath))return rZ(e.remoteConfigPath)}(n);return rj(t,rX(n,s),()=>[`Connected remote session "${n.session}".`,`tenant=${n.tenant} runId=${n.runId} leaseId=${n.leaseId??"pending"} backend=${n.leaseBackend??"pending"}`,`remoteConfig=${n.remoteConfigPath}`,n.runtime?"metro=prepared":"metro=not-prepared",o?.message,s?.message].filter(e=>!!e).join("\n")),!0};function rW(e){let t=e.session??"default",r=ep(e.stateDir).baseDir;return{session:t,stateDir:r,state:tj({stateDir:r,session:t})??(e.session?null:tJ({stateDir:r}))}}function rJ(e,t){rj(e,{connected:!1,session:t},()=>`No remote connection for "${t}".`)}function rz(e){var t;if(e.leaseId)return;let r="proxy"===(t=e.leaseProvider)?"proxy":ei(t)?"direct-device-provider":"remote-provider";return"proxy"===r?{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."}:"direct-device-provider"===r?{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."+(void 0===e.platform&&void 0===e.leaseBackend?" Add --platform ios|android if the profile does not set a platform.":"")}}function rZ(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 rY(e){try{let t=tL({configPath:e,cwd:process.cwd(),env:process.env}).profile;return!!(t.metroPublicBaseUrl||t.metroProxyBaseUrl||t.metroProjectRoot||t.metroKind)}catch{return!1}}function rX(e,t){let r=rz(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:function(e){if(e)return o.createHash("sha256").update(e).digest("hex").slice(0,12)}(e.daemon?.baseUrl),metro:e.metro?{prepared:!0,projectRoot:e.metro.projectRoot}:{prepared:!1},...r?{leasePreparation:r}:{},...t?{runtimePreparation:t}:{},connectedAt:e.connectedAt,updatedAt:e.updatedAt}}let rQ=async({positionals:e,flags:r})=>{let n=e[0]??"status",o=ep(r.stateDir).baseDir;if("status"===n){var s;let e,t=(e=ry({stateDir:(s={stateDir:o}).stateDir}))?{authenticated:!0,source:"cli-session",sessionId:e.id,cloudBaseUrl:e.cloudBaseUrl,workspaceId:e.workspaceId,accountId:e.accountId,name:e.name,createdAt:e.createdAt,expiresAt:e.expiresAt,expired:r$(e.expiresAt,s.now)}:{authenticated:!1,source:"none"};return rj(r,t,()=>{var e;return(e=t).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("\n"):"Not authenticated."}),!0}if("login"===n){let e=await rv({stateDir:o,flags:r,commandLabel:"agent-device auth login"});return rj(r,{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("logout"===n){let e,n=(e=rw({stateDir:o}.stateDir),!!t.existsSync(e)&&(t.rmSync(e,{force:!0}),!0));return rj(r,{authenticated:!1,removed:n},()=>n?"Removed stored cloud CLI session.":"No stored cloud CLI session."),!0}throw new R("INVALID_ARGS","auth accepts only: status, login, logout")},r0=`${eS}/`,r1=["content-type","content-range","x-artifact-type","x-artifact-filename","x-artifact-hash","x-artifact-hash-algorithm"],r8=["content-type","content-disposition","x-request-id"];async function r3(e,t,r){var n,o,s,a,i,l,c,d,u;let f,p,m,g=(f=new URL(e.url??"/","http://127.0.0.1").pathname)===eS?"/":f.startsWith(r0)?`/${f.slice(r0.length)}`:f;if("GET"===e.method&&"/health"===g)return void await r2(t,r);if(n=g,o=e.method,"/rpc"===n?"POST"!==o:(s=n,a=o,("/upload"===s||nt(s)||"/upload/finalize"===s?"POST"!==a:!s.startsWith("/upload/direct/")||"PUT"!==a)&&(!("/artifacts"===n||"/artifacts/"===n||n.startsWith("/artifacts/"))||"GET"!==o))){t.statusCode=404,t.end("Not found");return}("/rpc"===g&&(m=(await ef(e,r.maxRpcBodyBytes,"Proxy request body is too large.")).toString("utf8")),i=e,l=r.clientToken,(p=function(e,t){let r="string"==typeof e.headers.authorization?e.headers.authorization:"";if(r.toLowerCase().startsWith("bearer "))return r.slice(7);let n=e.headers["x-agent-device-token"];if("string"==typeof n)return n;if(t){let e=function(e){try{let t=JSON.parse(e);return"string"==typeof t.params?.token?t.params.token:""}catch{return""}}(t);if(e)return e}return""}(i,m)).length>0&&ec(p,l))?await r5({req:e,res:t,route:g,options:r,rpcBody:m}):(c=t,d=g,u=function(e){if(!e)return null;try{return JSON.parse(e).id??null}catch{return null}}(m),(c.statusCode=401,c.setHeader("content-type","application/json"),"/rpc"===d)?c.end(JSON.stringify({jsonrpc:"2.0",id:u,error:{code:-32001,message:"Invalid proxy token",data:N(new R("UNAUTHORIZED","Invalid proxy token"))}})):c.end(JSON.stringify({ok:!1,error:"Invalid proxy token",code:"UNAUTHORIZED"})))}async function r2(e,t){let r=await r4(t);e.statusCode=200,e.setHeader("content-type","application/json"),e.end(JSON.stringify(eu("agent-device-proxy",{upstream:r})))}async function r4(e){let t=new URL(eI(e.upstreamBaseUrl,"health")),r=await e.fetchImpl(t,{method:"GET",headers:nr({headers:{}},e.upstreamToken,"/health"),signal:AbortSignal.timeout(e.upstreamTimeoutMs)}),n=await r.text();try{return n?JSON.parse(n):{ok:r.ok,status:r.status}}catch{return{ok:r.ok,status:r.status}}}async function r5(e){var t,r,n;let o,s,{req:a,res:i,route:l,options:c,rpcBody:d}=e,u=(t=c.upstreamBaseUrl,r=l,n=a.url??"/",o=new URL(eI(t,r)),(s=n.indexOf("?"))>=0&&(o.search=n.slice(s)),o),f=a.method??"GET",p=nr(a,c.upstreamToken,l),m=function(e,t,r,n){if("GET"!==e.method&&"HEAD"!==e.method){var o,s;let a;return"/rpc"===t?(o=r??"",s=n,(a=JSON.parse(o)).params={...a.params??{},token:s},JSON.stringify(a)):e}}(a,l,d,c.upstreamToken),g=await c.fetchImpl(u,{method:f,headers:p,signal:AbortSignal.timeout(c.upstreamTimeoutMs),...m?{body:m,duplex:"half"}:{}});await r6({req:a,res:i,route:l,response:g,clientToken:c.clientToken})}async function r6(e){var t,r;let n,{req:o,res:s,route:i,response:l,clientToken:c}=e;(s.statusCode=l.status,function(e,t){for(let r of r8){let n=e.headers.get(r);n&&t.setHeader(r,n)}}(l,s),t=o,(r=s).hasHeader("x-request-id")||r.setHeader("x-request-id","string"==typeof(n=t.headers["x-request-id"])&&n.trim()?n.trim().slice(0,128):a()),nt(i))?await r9({req:o,res:s,response:l,clientToken:c}):await r7(l,s)}async function r9(e){let{req:t,res:r,response:n,clientToken:o}=e,s=await n.text();r.setHeader("content-type",n.headers.get("content-type")??"application/json"),r.end(function(e,t,r){let n;try{n=JSON.parse(e)}catch{return e}if(!n||"object"!=typeof n)return e;let o=n;if(!o.upload||"string"!=typeof o.upload.url)return e;let s=function(e,t){let r;try{r=new URL(e)}catch{return null}if(!r.pathname.startsWith("/upload/"))return null;let n="string"==typeof t.headers.host?t.headers.host:"";if(!n)return null;let o=new URL(t.url??"/","http://127.0.0.1").pathname,s=o.lastIndexOf("/upload/preflight"),a=s>=0?o.slice(0,s):"",i=t.headers["x-forwarded-proto"],l=Array.isArray(i)?i[0]:i,c=new URL(`${l||"http"}://${n}`);return c.pathname=`${a}${r.pathname}`,c.search=r.search,c.toString()}(o.upload.url,t);if(!s)return e;let a=o.upload.headers&&"object"==typeof o.upload.headers?{...o.upload.headers}:{};return Object.assign(a,eg(r)),JSON.stringify({...n,upload:{...o.upload,url:s,headers:a}})}(s,t,o))}async function r7(e,t){e.body?await c(l.fromWeb(e.body),t):t.end()}function ne(e,t){let r=e.trim();if(!r)throw new R("INVALID_ARGS",`Proxy ${t} is required.`);return r}function nt(e){return"/upload/preflight"===e}function nr(e,t,r){let n=new Headers;for(let t of r1){let r=e.headers[t];"string"==typeof r&&r.trim()&&n.set(t,r)}for(let[e,o]of("/rpc"!==r||n.has("content-type")||n.set("content-type","application/json"),Object.entries(eg(t))))n.set(e,o);return n}let nn=async({positionals:e,flags:t})=>{if(e.length>0)throw new R("INVALID_ARGS","proxy does not accept positional arguments.");let r=await no(t);return rj(t,r,()=>(function(e,t={}){let r=t.useColor??K(),n=ns("✓","green",r),o=ns(e.proxyBaseUrl,"cyan",r),s=ns("<tunnel URL>","cyan",r),a=ns(e.token,"yellow",r);return`${n} Proxy listening at ${o}
25
-
26
- Provide this to the agent-device instance connecting:
27
-
28
- Daemon base URL: ${s}
29
- Daemon auth token: ${a}`})(r)),await new Promise(()=>{}),!0};async function no(e){var t,r,n,o,a,l;let c,d=eA({session:"default",command:"proxy",positionals:[],flags:{stateDir:e.stateDir,daemonBaseUrl:"",daemonTransport:"http",daemonServerMode:"http"}}),u=await ev(d),f=function(e){if(!e)throw new R("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}`}(u.info.httpPort),p=(t=e,t.daemonAuthToken?.trim()||s(32).toString("hex")),m=(c={upstreamBaseUrl:function(e,t){try{let t=new URL(e);if("http:"!==t.protocol&&"https:"!==t.protocol)throw Error("unsupported protocol");return t.toString().replace(/\/+$/,"")}catch(r){throw new R("INVALID_ARGS",`Invalid ${t}`,{[t]:e},r)}}((r={upstreamBaseUrl:f,upstreamToken:u.info.token,clientToken:p}).upstreamBaseUrl,"upstreamBaseUrl"),upstreamToken:ne(r.upstreamToken,"upstreamToken"),clientToken:ne(r.clientToken,"clientToken"),maxRpcBodyBytes:r.maxRpcBodyBytes??1048576,upstreamTimeoutMs:r.upstreamTimeoutMs??3e5,fetchImpl:r.fetchImpl??fetch},i.createServer((e,t)=>{r3(e,t,c).catch(e=>{!function(e,t){if(e.headersSent)return e.destroy(t instanceof Error?t:void 0);let r=N(t);e.statusCode="INVALID_ARGS"===r.code?400:500,e.setHeader("content-type","application/json"),e.end(JSON.stringify({ok:!1,error:r.message,code:r.code}))}(t,e)})})),g=e.proxyHost?.trim()||"127.0.0.1",h=e.proxyPort??0;await (n=m,o=g,a=h,new Promise((e,t)=>{n.once("error",t),n.listen(a,o,()=>{n.off("error",t),e()})}));let v=m.address();if(!v||"string"==typeof v)throw new R("COMMAND_FAILED","Proxy did not bind to a TCP address.");let y=`http://${(l=v.address).includes(":")&&!l.startsWith("[")?`[${l}]`:l}:${v.port}`;return{proxyBaseUrl:y,agentDeviceBaseUrl:ew(y),token:p,upstreamBaseUrl:f,stateDir:d.paths.baseDir}}function ns(e,t,r){return r?L(e,t,{validateStream:!1}):e}let na=new Set(["id","text","label"]),ni=new Set(["enabled","selected"]),nl={open:function(e){var t,r,n;let o,s,a,[i,l]=e.positionals;if(!i)return{kind:"unsupported",message:"open requires an app id or URL"};if(nv(i))return{kind:"commands",commands:[{openLink:i}]};let c=(t=e,r=i,(a=(n=t,o=n.flags?.launchArgs,s={},n.flags?.relaunch===!0&&(s.stopApp=!0),n.flags?.clearAppState===!0&&(s.clearState=!0),Array.isArray(o)&&o.length>0&&(s.launchArguments=o),Object.keys(s).length>0?s:void 0))?{launchApp:{appId:r,...a}}:"launchApp");return l&&nv(l)?{kind:"config",appId:i,commands:[c,{openLink:l}]}:l?{kind:"unsupported",message:"open with a non-URL second argument is unsupported"}:{kind:"config",appId:i,commands:[c]}},click:nc,press:nc,longpress:function(e){let[t,r]=e.positionals;if(!t)return{kind:"unsupported",message:"longpress requires a target"};let n=nf(t,r);return n?{kind:"commands",commands:[{longPressOn:n}],warnings:(function(e){let[t,r,n]=e.positionals,o=ny(t)&&ny(r)?n:r;return o&&ny(o)?[Number(o)]:[]})(e).map(nd)}:{kind:"unsupported",message:"longpress target is not Maestro-compatible"}},fill:function(e){let[t,r]=e.positionals;if(!t||void 0===r)return{kind:"unsupported",message:"fill requires a target and text"};let n=nf(t);return n?{kind:"commands",commands:[{tapOn:n},{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"}},type:function(e){var t;let[r]=e.positionals;if(void 0===r)return{kind:"unsupported",message:"type requires text"};let n=0!==(t=r).length&&[...t].every(e=>"\b"===e)?t.length:null;return null!==n?{kind:"commands",commands:[{eraseText:n}]}:{kind:"commands",commands:[{inputText:r}]}},keyboard:function(e){let[t]=e.positionals;return"dismiss"===t?{kind:"commands",commands:["hideKeyboard"]}:"enter"===t||"return"===t?{kind:"commands",commands:[{pressKey:"Enter"}]}:{kind:"unsupported",message:`keyboard ${t??""}`.trim()}},back:()=>({kind:"commands",commands:["back"]}),wait:function(e){let[t,r]=e.positionals;if(!t)return{kind:"unsupported",message:"wait requires a target or duration"};if(ny(t))return{kind:"commands",commands:[{waitForAnimationToEnd:{timeout:Number(t)}}],warnings:["wait <ms> exports as waitForAnimationToEnd and may return before the full duration"]};if("text"===t&&r)return{kind:"commands",commands:[{extendedWaitUntil:{visible:r,timeout:ng(e,17e3)}}]};let n=np(t);return n?{kind:"commands",commands:[{extendedWaitUntil:{visible:n,timeout:ng(e,17e3)}}]}:{kind:"unsupported",message:"wait selector is not Maestro-compatible"}},find:function(e){let[t,r,n]=e.positionals;return"text"===t&&r&&n?"exists"===n?{kind:"commands",commands:[{assertVisible:r}]}:"missing"===n||"not-exists"===n?{kind:"commands",commands:[{assertNotVisible:r}]}:{kind:"unsupported",message:`find text assertion "${n}" is unsupported`}:{kind:"unsupported",message:"only find text <query> exists|missing exports to Maestro"}},screenshot:function(e){let[t]=e.positionals;return t?{kind:"commands",commands:[{takeScreenshot:t}]}:{kind:"unsupported",message:"screenshot requires an output path"}},scroll:function(e){let[t]=e.positionals;return t&&"down"!==t?{kind:"unsupported",message:`scroll ${t} is not exported yet`}:{kind:"commands",commands:["scroll"]}},swipe:function(e){var t,r;let n,o=function(e){let[t,r,n,o,s]=e.positionals;if(ny(t)&&ny(r)&&ny(n)&&ny(o))return{start:eD(t,r),end:eD(n,o),...s&&ny(s)?{duration:Number(s)}:{}}}(e);if(!o)return{kind:"unsupported",message:"only coordinate swipe exports to Maestro"};let s=(t=e,Number.isInteger(n=t.flags?.count??1)&&n>=1?n:null);if(null===s)return{kind:"unsupported",message:"swipe count must be a positive integer"};let a=(r=e,r.flags?.pauseMs!==void 0?"swipe --pause-ms has no Maestro equivalent":r.flags?.pattern&&"one-way"!==r.flags.pattern?"swipe ping-pong pattern has no Maestro equivalent":void 0);return a?{kind:"unsupported",message:a}:{kind:"commands",commands:Array.from({length:s},()=>({swipe:o}))}}};function nc(e){var t,r,n,o,s;let a,i,[l,c]=e.positionals;if(!l)return{kind:"unsupported",message:`${e.command} requires a target`};let d=nf(l,c);if(!d)return{kind:"unsupported",message:"tap target is not Maestro-compatible"};let u=(a=(r=t=e,r.flags?.jitterPx!==void 0?"tap --jitter-px has no Maestro equivalent":r.flags?.clickButton&&"primary"!==r.flags.clickButton?`tap --button ${r.flags.clickButton} has no Maestro equivalent`:void 0))?{ok:!1,message:a}:{ok:!0,options:(n=t,i={},"number"==typeof n.flags?.count&&n.flags.count>1&&(i.repeat=n.flags.count),"number"==typeof n.flags?.intervalMs&&n.flags.intervalMs>0&&(i.delay=n.flags.intervalMs),i)};return u.ok?e.flags?.doubleTap===!0?{kind:"commands",commands:[{doubleTapOn:d}],warnings:nu(e,"doubleTapOn")}:"number"==typeof e.flags?.holdMs?{kind:"commands",commands:[{longPressOn:d}],warnings:[nd(e.flags.holdMs),...nu(e,"longPressOn")]}:{kind:"commands",commands:[(o=d,0===Object.keys(s=u.options).length?{tapOn:o}:"string"==typeof o?{tapOn:{text:o,...s}}:o&&"object"==typeof o&&!Array.isArray(o)?{tapOn:{...o,...s}}:{tapOn:o})]}:{kind:"unsupported",message:u.message}}function nd(e){return`long-press duration exports as Maestro longPressOn; Maestro uses its default long-press duration instead of ${e}ms`}function nu(e,t){let r=[];return"number"==typeof e.flags?.count&&e.flags.count>1&&r.push(`tap --count ${e.flags.count} is not represented by Maestro ${t}`),"number"==typeof e.flags?.intervalMs&&e.flags.intervalMs>0&&r.push(`tap --interval-ms ${e.flags.intervalMs} is not represented by Maestro ${t}`),r}function nf(e,t){return ny(e)&&ny(t)?{point:eD(e,t)}:e.startsWith("@")?null:np(e)}function np(e){let t;try{t=ex(e)}catch{return e.includes("=")||e.includes("||")?null:e}let r=function(e){if(e.length<=1)return null;let t=e.flatMap(e=>1===e.terms.length&&na.has(e.terms[0].key)?[e.terms[0].value]:[]);if(t.length!==e.length||0===t.length)return null;let r=t[0];return"string"!=typeof r?null:t.every(e=>e===r)?r:null}(t.selectors);return null!==r?r:1!==t.selectors.length?null:function(e){let t={};for(let o of e.terms){var r,n;if(r=t,n=o,na.has(n.key)?"string"!=typeof n.value||!!r.id||!!r.text||!!r.label||(r[n.key]=n.value,!!0):!ni.has(n.key)||"boolean"!=typeof n.value||(r[n.key]=n.value,!!0))return null}return Object.keys(t).length>0?t:null}(t.selectors[0])}function nm(e,t,r,n){for(let o of t??[])e.warnings.push({line:n,action:nh(r),message:o})}function ng(e,t){let r=e.positionals.at(-1);return r&&ny(r)?Number(r):t}function nh(e){return[e.command,...e.positionals??[]].join(" ").trim()}function nv(e){return/^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(e)}function ny(e){return void 0!==e&&Number.isFinite(Number(e))}let nw=async e=>{let{positionals:t}=e;return"export"!==t[0]?function({positionals:e,flags:t}){if(e.length>1)throw new R("INVALID_ARGS","replay accepts exactly one input path: replay <path>");if(void 0!==t.replayExportFormat||void 0!==t.out)throw new R("INVALID_ARGS","replay --format/--out are only supported with replay export.");return!1}(e):await nI(e)};async function nI({positionals:e,flags:r}){let o;var s,a=e,i=r;if(a.length>2)throw new R("INVALID_ARGS","replay export accepts exactly one input path: replay export <file.ad>");if(i.replayUpdate)throw new R("INVALID_ARGS","replay export does not support --update.");if(i.replayMaestro)throw new R("INVALID_ARGS","replay export reads .ad files; omit --maestro.");if(i.replayEnv?.length)throw new R("INVALID_ARGS","replay export does not evaluate --env substitutions.");let l=i.replayExportFormat??"maestro";if("maestro"!==l)throw new R("INVALID_ARGS",`Unsupported replay export format: ${l}`);let c=e[1];if(!c)throw new R("INVALID_ARGS","replay export requires an input path.");let d=eo(c),u=function(e,t={}){var r,n,o,s;let a={config:(r=t.metadata,r?.env&&Object.keys(r.env).length>0?{env:r.env}:{}),warnings:[],unsupported:[]},i=[];for(let[r,o]of e.entries()){let e=t.actionLines?.[r]??r+1,s=(n=o,nl[n.command]?.(n)??{kind:"unsupported",message:`${n.command} has no Maestro equivalent`});switch(s.kind){case"commands":i.push(...s.commands),nm(a,s.warnings,o,e);break;case"config":(function(e,t,r,n){if(!e.config.appId){e.config.appId=t;return}e.config.appId!==t&&e.unsupported.push({line:n,action:nh(r),message:`multiple app ids cannot be represented in one Maestro config (${e.config.appId} vs ${t})`})})(a,s.appId,o,e),i.push(...s.commands),nm(a,s.warnings,o,e);break;case"unsupported":a.unsupported.push({line:e,action:nh(o),message:s.message})}}if(a.unsupported.length>0)throw new R("INVALID_ARGS",`Cannot export replay to Maestro YAML: unsupported .ad action ${a.unsupported.map(e=>`line ${e.line} (${e.action}): ${e.message}`).join("; ")}.`,{unsupported:a.unsupported});return{yaml:(o=a.config,s=i,ek(Object.keys(o).length>0?[o,s]:[s])),warnings:a.warnings}}((o=e_(s=t.readFileSync(d,"utf8"))).actions,{actionLines:o.actionLines,metadata:eb(s)}),f="string"==typeof r.out?eo(r.out):void 0;for(let e of(f&&(t.mkdirSync(n.dirname(f),{recursive:!0}),t.writeFileSync(f,u.yaml)),u.warnings))process.stderr.write(`Warning: line ${e.line}: ${e.message}
30
- `);return rj(r,{format:r.replayExportFormat??"maestro",sourcePath:d,...f?{path:f}:{yaml:u.yaml},warnings:u.warnings},()=>f??u.yaml),!0}let nA=M();function nS(e,t,r){let n=nA[e];if(!n)throw Error(`Missing CLI reader for command: ${e}`);return n(t,r)}async function nk(e){return(await n_(e)).result}async function n_(e){let t=nS(e.command,e.positionals,e.flags),r=await e$(e.client,e.command,t);return{result:r,cliOutput:eC({name:e.command,input:t,result:r})}}let nD={connect:rG,disconnect:rH,connection:rq,auth:rQ,proxy:nn,replay:nw,screenshot:async({positionals:e,flags:t,client:r})=>{let n=await nk({client:r,command:"screenshot",positionals:e,flags:t});return en(t.responseLevel)?rj(t,n,()=>JSON.stringify(n,null,2)):rj(t,{path:n.path,...n.overlayRefs?{overlayRefs:n.overlayRefs}:{}},()=>n.overlayRefs?`Annotated ${n.overlayRefs.length} refs onto ${n.path}`:n.path),!0},diff:async({positionals:e,flags:t,client:r})=>{var n;if("snapshot"===e[0]){let n=await nk({client:r,command:"diff",positionals:e,flags:t});return rj(t,n,()=>G(n)),!0}if("screenshot"!==e[0])return!1;let o=t.baseline;if(!o||"string"!=typeof o)throw new R("INVALID_ARGS","diff screenshot requires --baseline <path>");let s=eo(o),a="string"==typeof t.out?eo(t.out):void 0,i=e[1];if(e.length>2)throw new R("INVALID_ARGS","diff screenshot accepts at most one current screenshot path");let l=ed({backend:(n=r,{platform:function(e){switch(e.platform){case"android":case"linux":case"macos":return e.platform;default:return"ios"}}(t),captureScreenshot:async(e,t,r)=>{let o=await n.capture.screenshot({path:t,session:e.session,overlayRefs:r?.overlayRefs,fullscreen:r?.fullscreen,normalizeStatusBar:r?.normalizeStatusBar,stabilize:r?.stabilize,surface:r?.surface});return{path:o.path,...o.overlayRefs?{overlayRefs:o.overlayRefs}:{}}}}),artifacts:eN(),sessions:{get:e=>({name:e}),set:()=>{}},policy:ea()}),c=await l.capture.diffScreenshot({session:t.session,baseline:{kind:"path",path:s},current:i?{kind:"path",path:eo(i)}:{kind:"live"},...a?{out:{kind:"path",path:a}}:{},threshold:function(e){if(null!=e&&""!==e)return Number(e)}(t.threshold),overlayRefs:t.overlayRefs,normalizeStatusBar:t.screenshotNormalizeStatusBar,surface:t.surface});return rj(t,c,()=>O(c)),!0}};async function nb(e){let t={...e.flags},r=nD[e.command];return!!(r&&await r({...e,flags:t}))||!!w(e.command)&&await nC({...e,command:e.command,flags:t})}async function nC(e){let{runGenericClientBackedCommand:t}=await import("./generic.js");return await t(e)}function n$(e,t,r){return r||(e.push(t),"")}async function nN(e,t,r){let{flags:n}=t,o=function(e){if(!e?.metroProxyBaseUrl||!tB(e.leaseBackend))return null;let t=[],r={serverBaseUrl:n$(t,"metroProxyBaseUrl",e.metroProxyBaseUrl),bearerToken:n$(t,"metroBearerToken",e.metroBearerToken),tenantId:n$(t,"tenant",e.tenant),runId:n$(t,"runId",e.runId),leaseId:n$(t,"leaseId",e.leaseId)};if(t.length>0)throw new R("INVALID_ARGS",`react-devtools remote bridge requires ${t.join(", ")}.`,{missing:t});return r}(n);if(!o)return r();let s=t.stateDir??process.cwd(),a=t.session??n?.session??"default",i=n?.remoteConfig??`${o.tenantId}:${o.runId}:${o.leaseId}`;if("stop"===e[0])try{return await r()}finally{await tx({projectRoot:t.cwd??process.cwd(),stateDir:s,profileKey:i,consumerKey:a})}return await tP({projectRoot:t.cwd??process.cwd(),stateDir:s,serverBaseUrl:o.serverBaseUrl,bearerToken:o.bearerToken,bridgeScope:{tenantId:o.tenantId,runId:o.runId,leaseId:o.leaseId},session:a,profileKey:i,consumerKey:a,env:t.env??process.env}),await r()}async function nR(e,t={}){let r=t.cwd??process.cwd(),n=t.env??process.env,o=await nN(e,t,async()=>(await u("npm",["exec","--yes","--package","agent-react-devtools@0.4.0","--","agent-react-devtools",...e],{cwd:r,env:n,allowFailure:!0,onStdoutChunk:e=>{process.stdout.write(e)},onStderrChunk:e=>{process.stderr.write(e)}})).exitCode);var s,a=t.flags;return 0!==o&&"wait"===(s=e)[0]&&s.includes("--connected")&&"ios-instance"===a?.leaseBackend&&process.stderr.write("Hint: Remote iOS React DevTools connects during JavaScript startup.\nIf 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`.\n"),o}async function nP(e,t){var r,n,o,s,a,i,l;switch(e[0]){case"setup":{t.flags.json||process.stdout.write("Setting up managed agent-browser backend (downloads if needed)...\n");let{setupManagedAgentBrowser:e}=await import("./8391.js"),o=await e({stateDir:t.stateDir});return r=t.flags.json,n=o,r?J({success:!0,data:{status:nx(n)}}):process.stdout.write(`Managed web backend installed.
31
- agent-browser available at: ${n.binaryPath}
32
- `),0}case"doctor":{let e,{doctorManagedAgentBrowser:r}=await import("./8391.js"),n=await r({stateDir:t.stateDir});return o=t.flags.json,s=0===n.exitCode?"Web backend is healthy.":"Web backend doctor reported issues.",a=n,o?J({success:!0,data:"object"==typeof(l=e=(i=a).status)&&null!==l&&"socketDir"in l&&"installDir"in l&&"binaryPath"in l?{...i,status:nx(e)}:i}):process.stdout.write(`${s}
33
- `),n.exitCode}default:throw new R("INVALID_ARGS","web requires setup or doctor")}}function nx(e){let{socketDir:t,...r}=e;return r}function nE(e,t={}){let r=nT(t),n={...e};return r.defaultPlatform&&void 0===n.platform&&(n.platform=r.defaultPlatform),n}function nT(e){var t,r,n,o;let s,a=e.env??process.env,i=e.inheritedPlatform??e.configuredPlatform??function(e){if(void 0===e)return;let t=e.trim().toLowerCase();if(t){if("ios"===t||"android"===t||"apple"===t)return t;throw new R("INVALID_ARGS",`Invalid AGENT_DEVICE_PLATFORM: ${e}. Use ios, android, or apple.`)}}(a.AGENT_DEVICE_PLATFORM),l="string"==typeof(t=e.configuredSession??a.AGENT_DEVICE_SESSION)&&t.trim().length>0;return{defaultPlatform:i,lockPolicy:(r=e.policyOverrides,n=a,o=l,(s=r?.sessionLock??r?.sessionLockConflicts??function(e){if(void 0===e)return;let t=e.trim().toLowerCase();if(t){if("reject"===t||"strip"===t)return t;throw new R("INVALID_ARGS",`Invalid session lock mode: ${e}. Use reject or strip.`)}}(n.AGENT_DEVICE_SESSION_LOCK))||(r?.sessionLocked===!0||o?"reject":void 0))}}let nU={sendToDaemon:eh},nM=new Set(["launchUrl","kind","metroBearerToken","metroKind","metroListenHost","metroNoInstallDeps","metroNoReuseExisting","metroPreparePort","metroProbeTimeoutMs","metroProjectRoot","metroProxyBaseUrl","metroPublicBaseUrl","metroRuntimeFile","metroStartupTimeoutMs","metroStatusHost"]),nL=new Set(["connect","connection","close","disconnect","metro","proxy","session"]);async function nB(e,r=nU){let o=d(),s=eR(),a=function(e){try{let t=eV(e);return nO(t.command??"",t.providedFlags)}catch{return e.includes("--debug")||e.includes("-v")||e.includes("--verbose")}}(e),i=e.includes("--json"),l=function(e){for(let t=0;t<e.length;t+=1){let r=e[t];if(r.startsWith("--session=")){let e=r.slice(10).trim();return e.length>0?e:null}if("--session"===r){let r=e[t+1]?.trim();if(r&&!r.startsWith("-"))return r;break}}return null}(e)??process.env.AGENT_DEVICE_SESSION??"default";await p({session:l,requestId:o,command:e[0],debug:a},async()=>{var l,c,d,u,f,p,g,w,I,A,S,D,C,U,M,L,O;let V,j,G,K,H,z,Z;try{let r,o,s,a,i,m,h,y;l={cwd:process.cwd(),env:process.env},r=eV(e),o=l?.env??process.env,s=l?.cwd??process.cwd(),u=r.command,a=null!==u&&(c={remoteConfig:r.flags.remoteConfig,cwd:s,env:o}).remoteConfig?{...tQ(tL({configPath:c.remoteConfig,cwd:c.cwd,env:c.env}).profile),remoteConfig:c.remoteConfig}:{},h=eE((i=(d={command:r.command,cwd:s,cliFlags:r.flags,env:o}).env??process.env,m=eE({},function(e){let r={};for(let n of e)eE(r,function(e,r){let n,o;if(!t.existsSync(e)){if(r)throw new R("INVALID_ARGS",`Config file not found: ${e}`);return{}}try{n=t.readFileSync(e,"utf8")}catch(t){throw new R("INVALID_ARGS",`Failed to read config file: ${e}`,{cause:t instanceof Error?t.message:String(t)})}try{o=JSON.parse(n)}catch(t){throw new R("INVALID_ARGS",`Invalid JSON in config file: ${e}`,{cause:t instanceof Error?t.message:String(t)})}if(!o||"object"!=typeof o||Array.isArray(o))throw new R("INVALID_ARGS",`Config file must contain a JSON object: ${e}`);return function(e,t){let r={};for(let[n,o]of Object.entries(e)){if("installSource"===n){r.installSource=B(o,t);continue}let e=eL.get(n);if(!e)throw new R("INVALID_ARGS",`Unknown config key "${n}" in ${t}.`);if(!e.config.enabled)throw new R("INVALID_ARGS",`Unsupported config key "${n}" in ${t}.`);r[n]=v(eO(e),o,t,n)}return r}(o,`config file ${e}`)}(n.path,n.required));return r}((f=d.cwd,p=d.cliFlags.config,g=i,(y=p??g.AGENT_DEVICE_CONFIG)?[{path:(w=y,I=f,A=g,eo(w,{cwd:I,env:A})),required:!0}]:[{path:(S=g,n.join(es("~",{env:S}),".agent-device","config.json")),required:!1},{path:n.resolve(f,"agent-device.json"),required:!1}]))),eE(m,function(e,t){var r,n,o;let s={};for(let a of eM.filter(e=>e.config.enabled&&e.supportsCommand(t))){if("installSource"===a.key)continue;let t=a.env.names.map(t=>({name:t,value:e[t]})).find(e=>"string"==typeof e.value&&e.value.trim().length>0);t&&(s[a.key]=(r=t.value,n=`environment variable ${t.name}`,o=t.name,v(eO(a),r,n,o)))}return s}(i,d.command))),a),V={...function(e,t){let r=t?.strictFlags??!0,n=[...e.warnings],o=eE({json:!1,help:!1,version:!1},t?.defaultFlags??{});eE(o,e.flags);let s=e.providedFlags.filter(t=>!eB(t.key,e.command));if(s.length>0){var a,i;let t=s.map(e=>e.token),l=(a=e.command,i=t,a?1===i.length?`Flag ${i[0]} is not supported for command ${a}.`:`Flags ${i.join(", ")} are not supported for command ${a}.`:1===i.length?`Flag ${i[0]} requires a command that supports it.`:`Flags ${i.join(", ")} require a command that supports them.`);if(r)throw new R("INVALID_ARGS",l);for(let e of(n.push(l),s))delete o[e.key]}for(let t of Object.keys(o))void 0!==o[t]&&(eB(t,e.command)||delete o[t]);if(function(e){if("back"===e.command&&!(new Set(e.providedFlags.filter(e=>"backMode"===e.key).map(e=>e.token)).size<=1))throw new R("INVALID_ARGS","back accepts only one explicit mode flag: use either --in-app or --system.")}(e),b(e.command,o),"batch"===e.command&&1!=+!!o.steps+ +!!o.stepsFile)throw new R("INVALID_ARGS","batch requires exactly one step source: --steps or --steps-file.");return function(e){if(e.flags.help)return e;if("snapshot"===e.command&&e.flags.snapshotDiff){let{snapshotDiff:t,...r}=e.flags;return{command:"diff",positionals:["snapshot",...e.positionals],flags:r,warnings:e.warnings}}return e}({command:e.command,positionals:e.positionals,flags:o,warnings:n})}(r,{strictFlags:l?.strictFlags,defaultFlags:h}),providedFlags:r.providedFlags}}catch(t){y({level:"error",phase:"cli_parse_failed",data:{error:t instanceof Error?t.message:String(t)}});let e=N(t,{diagnosticId:m().diagnosticId,logPath:h({force:!0})??void 0});i?J({success:!1,error:e}):T(e,{showDetails:a}),process.exit(1);return}for(let e of V.warnings)process.stderr.write(`Warning: ${e}
34
- `);V.flags.version&&(process.stdout.write(`${s}
35
- `),process.exit(0));let Y="help"===V.command,X=V.flags.help;if(Y||X){Y&&V.positionals.length>1&&(T(new R("INVALID_ARGS","help accepts at most one command.")),process.exit(1));let e=Y?V.positionals[0]:V.command;e||(process.stdout.write(`${x()}
36
- `),process.exit(0));let t=P(eK(e));t&&(process.stdout.write(t),process.exit(0)),T(new R("INVALID_ARGS",`Unknown command: ${e}`)),process.stdout.write(`${x()}
37
- `),process.exit(1)}V.command||(process.stdout.write(`${x()}
38
- `),process.exit(1));let{command:Q,positionals:ee}=V,et=nO(Q,V.providedFlags),er=new Set(V.providedFlags.map(e=>e.key));try{G=(j=nT({policyOverrides:V.flags,configuredPlatform:V.flags.platform,configuredSession:V.flags.session})).lockPolicy?{...V.flags}:nE(V.flags,{policyOverrides:V.flags,configuredPlatform:V.flags.platform,configuredSession:V.flags.session}),K=ep(G.stateDir),H=G.session??"default",D={command:Q,explicitFlagKeys:er,stateDir:K.baseDir,session:H,remoteConfig:G.remoteConfig,hasResolvedSession:void 0!==G.session},Z=(z="connect"===D.command||"connection"===D.command||"proxy"===D.command?null:function(e){let t=e.validateRemoteConfigHash??!0,r=e.remoteConfig?tM({configPath:e.remoteConfig,cwd:e.cwd,env:e.env}):void 0,n=tj(e)??(e.allowActiveFallback?tJ({stateDir:e.stateDir}):null);if(!n||r&&n.remoteConfigPath!==r)return null;if(t&&tH(n.remoteConfigPath)!==n.remoteConfigHash)throw new R("INVALID_ARGS","Active remote connection config changed. Run agent-device connect --force to refresh it.",{remoteConfig:n.remoteConfigPath});let o=function(e,t){try{return tL({configPath:e.remoteConfigPath,cwd:t.cwd,env:t.env}).profile}catch(e){if(!1===t.validateRemoteConfigHash)return{};throw e}}(n,e),s=F(n);return{runtime:n.runtime,connection:W(s),flags:{...o,remoteConfig:n.remoteConfigPath,daemonBaseUrl:n.daemon?.baseUrl??o.daemonBaseUrl,daemonAuthToken:n.daemon?.authToken??o.daemonAuthToken,daemonTransport:n.daemon?.transport??o.daemonTransport,daemonServerMode:n.daemon?.serverMode??o.daemonServerMode,...q(s),sessionIsolation:"tenant",session:n.session,platform:n.platform??o.platform,target:n.target??o.target}}}({stateDir:D.stateDir,session:D.session,remoteConfig:D.remoteConfig,cwd:process.cwd(),env:process.env,allowActiveFallback:!D.explicitFlagKeys.has("session")&&(!D.remoteConfig||"disconnect"===D.command||!D.hasResolvedSession),validateRemoteConfigHash:"disconnect"!==D.command}))?function(e,t,r){let n={...e};for(let[e,o]of Object.entries(t))void 0!==o&&(r.has(e)||(n[e]=o));return n}(G,z.flags,er):G}catch(t){let e=N($(t),{diagnosticId:m().diagnosticId,logPath:h({force:!0})??void 0});V.flags.json?J({success:!1,error:e}):T(e,{showDetails:et}),process.exit(1);return}let en=null;try{let e;if("react-devtools"===Q){let e=await nR(ee,{flags:Z,stateDir:K.baseDir,session:Z.session??H,cwd:process.cwd(),env:process.env});process.exit(e);return}if("web"===Q){let e=await nP(ee,{flags:Z,stateDir:K.baseDir});process.exit(e);return}eP({command:Q,currentVersion:s,stateDir:K.baseDir,flags:Z});let n=z?.runtime,a=z?.connection,i=(e,t,r)=>({session:e.session,requestId:o,stateDir:e.stateDir,daemonBaseUrl:e.daemonBaseUrl,daemonAuthToken:e.daemonAuthToken,daemonTransport:e.daemonTransport,daemonServerMode:e.daemonServerMode,tenant:e.tenant,sessionIsolation:e.sessionIsolation,runId:e.runId,leaseId:e.leaseId,leaseBackend:e.leaseBackend,leaseProvider:r?.leaseProvider,clientId:r?.clientId,deviceKey:r?.deviceKey,providerApp:e.providerApp,providerOsVersion:e.providerOsVersion,providerProject:e.providerProject,providerBuild:e.providerBuild,providerSessionName:e.providerSessionName,awsProjectArn:e.awsProjectArn,awsDeviceArn:e.awsDeviceArn,awsAppArn:e.awsAppArn,awsRegion:e.awsRegion,awsInteractionMode:e.awsInteractionMode,runtime:t,lockPolicy:j.lockPolicy,lockPlatform:j.defaultPlatform,cwd:process.cwd(),debug:et,cost:e.cost,responseLevel:e.responseLevel});if("batch"===Q){if(ee.length>0)throw new R("INVALID_ARGS","batch does not accept positional arguments.");e=function(e){let r,n,o,s="";if(e.steps)s=e.steps;else if(e.stepsFile)try{s=t.readFileSync(e.stepsFile,"utf8")}catch(r){let t=r instanceof Error?r.message:String(r);throw new R("INVALID_ARGS",`Failed to read --steps-file ${e.stepsFile}: ${t}`)}var a,i=s;try{o=JSON.parse(i)}catch{throw new R("INVALID_ARGS","Batch steps must be valid JSON.")}if(!Array.isArray(o)||0===o.length)throw new R("INVALID_ARGS","Batch steps must be a non-empty JSON array.");return a=o,r=!1,n=a.map((e,t)=>{var n,o,s;let a;if(n=e,_(n)&&"input"in n&&!("positionals"in n)&&!("flags"in n))return function(e,t){let r=k(e.runtime,t),{runtime:n,...o}=e;return{...o,...void 0===r?{}:{runtime:r}}}(e,t+1);let i=function(e,t){if(!_(e))throw new R("INVALID_ARGS",`Invalid batch step ${t}.`);var r=e,n=t;let o=Object.keys(r).filter(e=>!["command","positionals","flags","runtime"].includes(e));if(o.length>0)throw new R("INVALID_ARGS",`Batch step ${n} has unknown legacy field(s): ${o.join(", ")}.`);let s=function(e,t){let r="string"==typeof e?e.trim().toLowerCase():"";if(!r)throw new R("INVALID_ARGS",`Batch step ${t} requires command.`);if(E(r))return r;throw new R("INVALID_ARGS",`Batch step ${t} command is not available through command batch: ${String(e)}`)}(e.command,t),a=function(e,t){if(void 0!==e){if(!Array.isArray(e)||e.some(e=>"string"!=typeof e))throw new R("INVALID_ARGS",`Batch step ${t} positionals must contain only strings.`);return e}}(e.positionals,t),i=function(e,t){if(void 0!==e){if(!_(e))throw new R("INVALID_ARGS",`Batch step ${t} flags must be an object.`);return e}}(e.flags,t),l=k(e.runtime,t);return{command:s,...void 0===a?{}:{positionals:a},...void 0===i?{}:{flags:i},...void 0===l?{}:{runtime:l}}}(e,t+1);return r=!0,o=i,a=nS(o.command,o.positionals??[],(s=o.flags,{json:!1,help:!1,version:!1,...s})),{command:o.command,input:a,...void 0===o.runtime?{}:{runtime:o.runtime}}}),r&&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.\n'),n}(G)}if(C=Q,"auth"!==C&&"connection"!==C&&"proxy"!==C&&(Z=(await rm({command:Q,flags:Z,stateDir:K.baseDir,env:process.env})).flags),Z.remoteConfig&&(U=Q,!nL.has(U))){let t=ey(i(Z,n,a),{transport:nV(r.sendToDaemon)}),o=await t3({command:Q,flags:Z,client:t,runtime:n,positionals:ee,batchSteps:e,forceRuntimePrepare:function(e){for(let t of nM)if(e.has(t))return!0;return!1}(er)});Z=o.flags,n=o.runtime,a=o.connection}if(M={command:Q,flags:Z,runtime:n,explicitFlagKeys:er,hadConnectionDefaults:!!z},!("open"===M.command&&!M.runtime&&!M.flags.bundleUrl&&!M.flags.metroHost&&!M.flags.metroPort&&!M.flags.remoteConfig&&!M.hadConnectionDefaults&&((L=M.explicitFlagKeys).has("daemonBaseUrl")||L.has("daemonTransport")||L.has("tenant")||L.has("sessionIsolation")||L.has("runId")||L.has("leaseId")||L.has("leaseBackend")))||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.\n"),"cdp"===Q){let e=await tV(ee,{flags:Z,runtime:n,cwd:process.cwd(),env:process.env});process.exit(e);return}let l=Z.daemonBaseUrl;en=!et||Z.json||l?null:function(e){try{let r=t.existsSync(e)?t.statSync(e).size:0,n=!1,o=setInterval(()=>{if(!n&&t.existsSync(e))try{let n=t.statSync(e);if(n.size<r&&(r=0),n.size<=r)return;let o=t.openSync(e,"r");try{let e=Buffer.alloc(n.size-r);t.readSync(o,e,0,e.length,r),r=n.size,e.length>0&&process.stdout.write(e.toString("utf8"))}finally{t.closeSync(o)}}catch{}},200);return()=>{n=!0,clearInterval(o)}}catch{return null}}(K.logPath);let c="test"===Q?await t$({debug:et,verbose:Z.verbose,json:Z.json,reporter:Z.reporter,reportJunit:Z.reportJunit}):void 0,d=ey(i(Z,n,a),{transport:function(e){let{command:t,flags:r,replayTestReporterRuntime:n,transport:o}=e;return r.json?nV(o):async e=>await nj(o,{...e,meta:{...e.meta,requestProgress:"test"===t?"replay-test":"command"}},"test"===t&&n?{onProgress:n.onProgress}:void 0)}({command:Q,flags:Z,replayTestReporterRuntime:c,transport:r.sendToDaemon})});if("batch"===Q){if(!e)throw new R("INVALID_ARGS","batch requires --steps or --steps-file.");let t=e.map((e,t)=>({...e,input:j.lockPolicy&&void 0===G.platform?{...e.input}:nE(e.input,{policyOverrides:Z,configuredPlatform:Z.platform,configuredSession:Z.session,inheritedPlatform:Z.platform})}));if(await nb({command:Q,positionals:ee,flags:{...Z,batchSteps:t},client:d,debug:et,replayTestReporterRuntime:c}))return}else if("runtime"===Q)throw new R("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 nb({command:Q,positionals:ee,flags:Z,client:d,debug:et,replayTestReporterRuntime:c}))return;throw new R("INVALID_ARGS",`Unknown command: ${Q}`)}catch(n){let e=$(n),r=N(e,{diagnosticId:m().diagnosticId,logPath:h({force:!0})??void 0});if("close"===Q&&"COMMAND_FAILED"===(O=e).code&&(O.details?.kind==="daemon_startup_failed"||O.message.toLowerCase().includes("failed to start daemon")&&("string"==typeof O.details?.infoPath||"string"==typeof O.details?.lockPath))){Z.json&&J({success:!0,data:{closed:"session",source:"no-daemon"}});return}if(Z.json)J({success:!1,error:r});else if(T(r,{showDetails:et}),et)try{let e=K.logPath;if(t.existsSync(e)){let r=t.readFileSync(e,"utf8").split("\n"),n=r.slice(Math.max(0,r.length-200)).join("\n");n.trim().length>0&&process.stderr.write(`
39
- [daemon log]
40
- ${n}
41
- `)}}catch{}en&&en(),process.exit(1)}finally{en&&en()}})}function nO(e,t){return t.some(t=>"verbose"===t.key&&("--debug"===t.token||"-v"===t.token||"test"!==e))}function nV(e){return async t=>await nj(e,t)}async function nj(e,t,r){return await e(t,r)}e(process.argv[1]??"").href===import.meta.url&&nB(process.argv.slice(2)).catch(e=>{T(N($(e)),{showDetails:!0}),process.exit(1)});export{tC as renderReplayTestResponse,nB as runCli,n_ as runCliCommandWithOutput,rj as writeCommandOutput};
1
+ import{B as e,C as t,F as n,I as r,a as i,b as a,p as o,u as s}from"./sdk-contracts.js";import{A as c,E as l,I as u,M as d,N as f,O as p,S as m,j as h,v as g}from"./sdk-android-adb.js";import{b as _}from"./sdk-batch.js";import{$n as v,Gn as y,Hn as b,Kn as x,Mn as S,Nn as C,Qn as w,Un as T,Vn as E,Zn as D,er as ee,kn as te,qn as ne}from"./tv-remote.js";import{a as re,c as ie,i as ae,l as oe,n as se,o as ce,r as le,s as ue}from"./client.js";import{C as O,D as de,c as fe,o as pe}from"./snapshot-diagnostics.js";import{n as me}from"./version.js";import{n as k,t as he}from"./path-resolution.js";import{_ as ge,h as _e,l as ve,u as ye,v as be}from"./registry.js";import{a as xe,l as Se}from"./sdk-batch-runner.js";import{v as Ce}from"./url.js";import{i as we,r as Te}from"./client-metro-companion.js";import"./selectors2.js";import{n as Ee}from"./command-metadata.js";import{n as De}from"./metro2.js";import{n as Oe,r as ke,t as A}from"./providers.js";import{n as Ae,r as je,t as Me}from"./command-schema.js";import{t as Ne}from"./update-check.js";import{i as Pe,n as Fe,r as Ie,t as Le}from"./sdk-remote-config.js";import{i as j,r as Re,t as ze}from"./cli-runner.js";import{_ as Be,t as Ve,v as He,y as Ue}from"./points.js";import M,{randomBytes as We,randomUUID as Ge}from"node:crypto";import N from"node:fs";import P from"node:path";import Ke from"node:http";import{pipeline as qe}from"node:stream/promises";import{Readable as Je}from"node:stream";import{pathToFileURL as Ye}from"node:url";function F(e,t){for(let[n,r]of Object.entries(t))r!==void 0&&(e[n]=r);return e}const Xe=new Set([`config`,`remoteConfig`,`help`,`version`,`batchSteps`,`githubActionsArtifact`]),Ze=new Set([`appsFilter`,`iosSimulatorDeviceSet`,`sessionLocked`,`sessionLockConflicts`]),Qe=rt(),$e=new Map(Qe.map(e=>[e.key,e]));function et(e){return $e.get(e)}function tt(e){return Qe.filter(t=>t.config.enabled&&t.supportsCommand(e))}function I(e,t){return et(e)?.supportsCommand(t)??!1}function nt(e,t,n,r){return p(at(e),t,n,r)}function rt(){let e=new Map;for(let t of be()){let n=e.get(t.key);n?n.push(t):e.set(t.key,[t])}let t=new Map;for(let e of _e)t.set(e,new Set([`*`]));for(let e of ee()){let n=Ae(e);for(let r of[...n.allowedFlags??[],...n.supportedFlags??[]]){let n=t.get(r);n&&n.has(`*`)||(n?n.add(e):t.set(r,new Set([e])))}}return[...e.entries()].map(([e,n])=>({key:e,flagDefinitions:n,config:{enabled:!Xe.has(e),key:e},env:{names:Ze.has(e)?[]:[l(e)]},supportsCommand(n){let r=t.get(e);return r?r.has(`*`)?!0:n?r.has(n):!1:!1}})).sort((e,t)=>e.key.localeCompare(t.key))}function it(e){let t=e.flagDefinitions[0];if(!t)throw Error(`Missing flag definition for option ${e.key}`);return t}function at(e){let t=e.flagDefinitions.find(e=>e.setValue===void 0);if(t)return t;let n=it(e);if(n.type===`enum`){let t=n.enumValues??e.flagDefinitions.map(e=>e.setValue).filter(e=>e!==void 0);return{...n,setValue:void 0,enumValues:t}}return n}function ot(e){let t={json:!1,help:!1,version:!1},r=null,i=[],a=[],o=[],s=!0;for(let a=0;a<e.length;a+=1){let c=e[a];if(s&&c===`--`){s=!1;continue}if(!s){r?i.push(c):r=Et(c);continue}if(lt(r)){i.push(c);continue}let l=c.startsWith(`--`),u=c.startsWith(`-`)&&c.length>1;if(!l&&!u){r?i.push(c):r=Et(c);continue}let[d,f]=l?pt(c):[c,void 0];if(st(r,d))continue;let p=ut(d,r);if(ct(r,p)){i.push(c);continue}if(!p){if(vt(r,i,c)){r?i.push(c):r=c;continue}throw new n(`INVALID_ARGS`,`Unknown flag: ${d}`)}let m=mt(p,d,f,e[a+1]);m.consumeNext&&(a+=1);let h=t[p.key];if(p.multiple){let e=Array.isArray(h)?[...h,m.value]:h===void 0?[m.value]:[h,m.value];t[p.key]=e}else t[p.key]=m.value;o.push({key:p.key,token:d})}return{command:r,positionals:i,flags:t,warnings:a,providedFlags:o}}function st(e,t){return t===`-c`&&(e===`snapshot`||e===`diff`)}function ct(e,t){return e===`react-devtools`?t?!I(t.key,e):!0:!1}function lt(e){return e===`cdp`}function ut(e,t){let n=be().filter(t=>t.names.includes(e));if(n.length<=1)return n[0]??ge(e);if(t){let e=n.find(e=>I(e.key,t));if(e)return e}return ge(e)}function dt(e,t){let r=t?.strictFlags??!0,i=[...e.warnings],a=F({json:!1,help:!1,version:!1},t?.defaultFlags??{});if(F(a,e.flags),e.command&&!v(e.command)&&!a.help){let t=St(e.command);throw new n(`INVALID_ARGS`,t?`Unknown command: ${e.command}. Did you mean ${t}?`:`Unknown command: ${e.command}`)}let o=e.providedFlags.filter(t=>!I(t.key,e.command));if(o.length>0){let t=o.map(e=>e.token),s=Ct(e.command,t);if(r)throw new n(`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&&(I(t,e.command)||delete a[t]);if(ft(e),Me(e.command,a),e.command===`batch`&&+!!a.steps+ +!!a.stepsFile!=1)throw new n(`INVALID_ARGS`,`batch requires exactly one step source: --steps or --steps-file.`);return bt({command:e.command,positionals:e.positionals,flags:a,warnings:i})}function ft(e){if(e.command!==`back`)return;let t=e.providedFlags.filter(e=>e.key===`backMode`);if(!(new Set(t.map(e=>e.token)).size<=1))throw new n(`INVALID_ARGS`,`back accepts only one explicit mode flag: use either --in-app or --system.`)}function pt(e){let t=e.indexOf(`=`);return t===-1?[e,void 0]:[e.slice(0,t),e.slice(t+1)]}function mt(e,t,r,i){if(e.setValue!==void 0){if(r!==void 0)throw new n(`INVALID_ARGS`,`Flag ${t} does not take a value.`);return{value:e.setValue,consumeNext:!1}}if(e.type===`boolean`){if(r!==void 0)throw new n(`INVALID_ARGS`,`Flag ${t} 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 n(`INVALID_ARGS`,`Flag ${t} requires a non-empty value when provided.`);return{value:r,consumeNext:!1}}return i===void 0||gt(i)?{value:!0,consumeNext:!1}:_t(i)?{value:i,consumeNext:!0}:{value:!0,consumeNext:!1}}let a=r??i;if(a===void 0||r===void 0&&gt(a))throw new n(`INVALID_ARGS`,`Flag ${t} 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 n(`INVALID_ARGS`,`Invalid ${ht(t)}: ${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 n(`INVALID_ARGS`,`Invalid ${ht(t)}: ${a}`);return{value:Math.floor(o),consumeNext:r===void 0}}function ht(e){return e.replace(/^-+/,``)}function gt(e){if(!e.startsWith(`-`)||e===`-`)return!1;let[t]=e.startsWith(`--`)?pt(e):[e,void 0];return ge(t)!==void 0}function _t(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 vt(e,t,n){if(!yt(n)||!e)return!1;let r=je(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 yt(e){return/^-\d+(\.\d+)?$/.test(e)}function bt(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}const xt={tap:`press or click`};function St(e){return xt[e]}function Ct(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 wt(){let{buildUsageText:e}=await import(`./cli-help.js`);return e()}async function Tt(e){let{buildCommandUsageText:t}=await import(`./cli-help.js`);return t(Et(e))}function Et(e){return e===`long-press`?`longpress`:e===`metrics`?`perf`:e===`tap`?`press`:e}const Dt={slug:`react-devtools-companion`,runArg:Ce,displayName:`React DevTools companion`};async function Ot(e){return await Te({...e,definition:Dt,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 kt(e){return await we({...e,definition:Dt})}function At(e){let t=e.env??process.env,r=Nt(e);if(!N.existsSync(r))throw new n(`INVALID_ARGS`,`Remote config file not found: ${r}`);let i;try{i=N.readFileSync(r,`utf8`)}catch(e){throw new n(`INVALID_ARGS`,`Failed to read remote config file: ${r}`,{cause:e instanceof Error?e.message:String(e)})}let a;try{a=JSON.parse(i)}catch(e){throw new n(`INVALID_ARGS`,`Invalid JSON in remote config file: ${r}`,{cause:e instanceof Error?e.message:String(e)})}if(!a||typeof a!=`object`||Array.isArray(a))throw new n(`INVALID_ARGS`,`Remote config file must contain a JSON object: ${r}`);let o={},s=a,c=P.dirname(r);for(let[e,i]of Object.entries(s)){let a=Pe(e);if(!a)throw new n(`INVALID_ARGS`,`Unsupported remote config key "${e}" in remote config file ${r}.`);let s=p(a,i,`remote config file ${r}`,e);o[a.key]=typeof s==`string`&&`path`in a&&a.path?k(s,{cwd:c,env:t}):s}return{resolvedPath:r,profile:o}}function jt(e=process.env){let t={};for(let n of Fe){let r=Ie(n.key).map(t=>({name:t,value:e[t]})).find(e=>typeof e.value==`string`&&e.value.trim().length>0);r&&(t[n.key]=p(n,r.value,`environment variable ${r.name}`,r.name))}return t}function Mt(...e){let t={};for(let n of e)if(n)for(let e of Fe){let r=n[e.key];r!==void 0&&(t[e.key]=r)}return t}function Nt(e){let t=e.env??process.env;return k(e.configPath,{cwd:e.cwd,env:t})}function L(e){let t=At(e);return{resolvedPath:t.resolvedPath,profile:Mt(jt(e.env),t.profile)}}function Pt(e){return e===`android-instance`||e===`ios-instance`}function Ft(e){return[`exec`,`--yes`,`--package`,`agent-cdp@1.6.1`,`--`,`agent-cdp`,...e]}function It(e){return e.some(e=>e===`--url`||e.startsWith(`--url=`))}function Lt(e){return e[0]===`target`&&(e[1]===`list`||e[1]===`select`)&&!It(e)}function Rt(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 zt(e){let t=e?.metroPublicBaseUrl?.trim();return t?Rt(t):null}function Bt(e,t={}){if(!Lt(e)||!t.flags?.metroProxyBaseUrl||!Pt(t.flags.leaseBackend))return e;let r=zt(t.flags);if(!r)throw new n(`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 Vt(e,t={}){return(await m(`npm`,Ft(Bt(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 R(e){let t=B(e);if(!N.existsSync(t))return null;let n;try{n=JSON.parse(N.readFileSync(t,`utf8`))}catch(t){return Qt(e,t),null}return en(n)?n:(Qt(e),null)}function Ht(e){let t=B({stateDir:e.stateDir,session:e.state.session});N.mkdirSync(P.dirname(t),{recursive:!0}),Xt(t,e.state),Xt(V(e.stateDir),{session:e.state.session})}function Ut(e){return{baseUrl:Zt(e.daemonBaseUrl),authToken:e.daemonAuthToken,transport:e.daemonTransport,serverMode:e.daemonServerMode}}function Wt(e){N.rmSync(B(e),{force:!0});let t=V(e.stateDir);qt(e.stateDir)===e.session&&N.rmSync(t,{force:!0})}function Gt(e){let t=e.validateRemoteConfigHash??!0,r=e.remoteConfig?Nt({configPath:e.remoteConfig,cwd:e.cwd,env:e.env}):void 0,i=R(e)??(e.allowActiveFallback?H({stateDir:e.stateDir}):null);if(!i||r&&i.remoteConfigPath!==r)return null;if(t&&z(i.remoteConfigPath)!==i.remoteConfigHash)throw new n(`INVALID_ARGS`,`Active remote connection config changed. Run agent-device connect --force to refresh it.`,{remoteConfig:i.remoteConfigPath});let a=Yt(i,e),o=te(i);return{runtime:i.runtime,connection:C(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,...S(o),sessionIsolation:`tenant`,session:i.session,platform:i.platform??a.platform,target:i.target??a.target}}}function Kt(e){return C(te(e))}function z(e){try{return M.createHash(`sha256`).update(N.readFileSync(e)).digest(`hex`)}catch(t){throw new n(`INVALID_ARGS`,`Remote config file not found: ${e}`,{cause:t instanceof Error?t.message:String(t)})}}function B(e){return P.join(e.stateDir,`remote-connections`,`${$t(e.session)}.json`)}function V(e){return P.join(e,`remote-connections`,`.active-session.json`)}function H(e){let t=qt(e.stateDir);return t?R({stateDir:e.stateDir,session:t}):null}function qt(e){let t=V(e);if(N.existsSync(t))try{let e=JSON.parse(N.readFileSync(t,`utf8`));return typeof e.session==`string`?e.session:void 0}catch{return}}function Jt(e){if(e)return M.createHash(`sha256`).update(e).digest(`hex`).slice(0,12)}function Yt(e,t){try{return L({configPath:e.remoteConfigPath,cwd:t.cwd,env:t.env}).profile}catch(e){if(t.validateRemoteConfigHash===!1)return{};throw e}}function Xt(e,t){N.writeFileSync(e,`${JSON.stringify(t,null,2)}\n`,{encoding:`utf8`,mode:384}),N.chmodSync(e,384)}function Zt(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 Qt(e,t){h({level:`warn`,phase:`remote_connection_state_invalid`,data:{session:e.session,cause:t instanceof Error?t.message:t?String(t):void 0}}),Wt(e)}function $t(e){let t=e.replaceAll(/[^a-zA-Z0-9._-]/g,`_`);return t?t===e?t:`${t}-${M.createHash(`sha256`).update(e).digest(`hex`).slice(0,8)}`:`default`}function en(e){if(!e||typeof e!=`object`||Array.isArray(e))return!1;let t=e;return t.version===1&&tn(t,[`session`,`remoteConfigPath`,`remoteConfigHash`,`tenant`,`runId`,`connectedAt`,`updatedAt`])&&nn(t,[`leaseId`,`leaseBackend`,`leaseProvider`,`deviceKey`,`clientId`])&&rn(t.daemon)}function tn(e,t){return t.every(t=>typeof e[t]==`string`)}function nn(e,t){return t.every(t=>e[t]===void 0||typeof e[t]==`string`)}function rn(e){return e===void 0?!0:!e||typeof e!=`object`||Array.isArray(e)?!1:an(e)}function an(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 on=Le.map(e=>e.key);function U(e){let t={};for(let n of on){let r=e[n];r!==void 0&&(t[n]=r)}return t}function sn(e){return e.remoteConfig?{...U(L({configPath:e.remoteConfig,cwd:e.cwd,env:e.env}).profile),remoteConfig:e.remoteConfig}:{}}function cn(e){return e===`cloud`||e===`proxy`||Oe(e)}function W(e){return Oe(e)}function ln(){return[`cloud`,`proxy`,A.browserStack,A.awsDeviceFarm].join(`, `)}function un(e){return!W(e)}function dn(e){return e===`proxy`?`proxy`:W(e)?`direct-device-provider`:`remote-provider`}const G=new Set([`artifacts`,`connect`,`connection`,`close`,`disconnect`,`metro`,`session`]),fn=new Set([`open`]),pn=new Set([w.open,w.install,w.reinstall,D.installSource]);async function mn(e){let{command:t,flags:r,client:i}=e;if(!r.remoteConfig)return{flags:r,runtime:e.runtime};let a=O(r.stateDir).baseDir,o=L({configPath:r.remoteConfig,cwd:process.cwd(),env:process.env}),s={...U(o.profile),...r,remoteConfig:o.resolvedPath},c=R({stateDir:a,session:s.session??`default`});if(c&&c.remoteConfigPath!==o.resolvedPath)throw new n(`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??Ln(s,o.resolvedPath,o.profile),u={...s,session:l.session},d=In(l.runtime,u.platform)??e.runtime,f=l,p=!c,m,h=Sn(f);if(h.shouldAllocate(t)){let e=await yn({command:t,client:i,state:l,nextState:f,nextFlags:u,policy:h});f=e.state,p||=e.changed,m=e.acquiredLeaseForCleanup}let g=await hn({command:t,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 vn({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:Kt(f)}}async function hn(e){let{command:t,flags:r,state:i,client:a}=e,o=gn(e.nextState,r),s=e.runtime;if(!Mn(t,r,e.batchSteps,e.positionals)||!Nn(r)||!_n(e.forceRuntimePrepare,s,r.platform))return{state:o,runtime:s,changed:!1};if(!o.leaseId)throw new n(`INVALID_ARGS`,`${t} requires a resolved remote lease before Metro runtime can be prepared.`);let c=await En(r,a,i.remoteConfigPath,i.session,{tenantId:i.tenant,runId:i.runId,leaseId:o.leaseId}),l=!Fn(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 gn(e,t){return e.leaseId||!t.leaseId?e:{...e,leaseId:t.leaseId,leaseBackend:t.leaseBackend}}function _n(e,t,n){return e===!0||!t||!Pn(t,n)}async function vn(e){if(e.changed)try{Ht({stateDir:e.stateDir,state:e.state})}catch(t){throw await K(e.preparedMetroCleanupOnFailure),await An(e.client,e.state,e.acquiredLeaseForCleanup),t}await K(e.metroCleanupToStop)}async function yn(e){let{command:t,client:n,state:r,nextFlags:i,policy:a}=e,o=r.leaseBackend??q(i),s=e.nextState,c=await a.resolveLeaseState({command:t,client:n,state:s,flags:i,leaseBackend:o});s=c.state,c.device&&Bn(i,c.device);let l=s.leaseBackend??o??jn(i,t);Wn(r,i,l);let u=await Rn(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,bn(s,d,l)?{state:s,changed:!1,acquiredLeaseForCleanup:u.acquired?d:void 0}:{state:xn(s,d,l,i),changed:!0,acquiredLeaseForCleanup:u.acquired?d:void 0}}function bn(e,t,n){return e.leaseId===t.leaseId&&e.leaseBackend===n&&e.deviceKey===(t.deviceKey??e.deviceKey)}function xn(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 Sn(e){return e.leaseProvider===`proxy`?wn:Oe(e.leaseProvider)?Tn:Cn}const Cn={shouldAllocate:e=>!G.has(e),ttlMs:()=>void 0,resolveLeaseState:async e=>({state:e.state})},wn={shouldAllocate:e=>e!==`devices`&&!G.has(e),ttlMs:()=>3e5,resolveLeaseState:zn},Tn={shouldAllocate:e=>!G.has(e),ttlMs:()=>6e5,resolveLeaseState:async e=>({state:e.state})};async function En(e,t,r,i,a){if(!e.metroProjectRoot&&!e.metroPublicBaseUrl&&!e.metroProxyBaseUrl)return{};if(e.platform!==`ios`&&e.platform!==`android`)throw new n(`INVALID_ARGS`,`Deferred Metro preparation requires platform "ios" or "android".`);if(!e.metroPublicBaseUrl&&!e.metroProxyBaseUrl)throw new n(`INVALID_ARGS`,`Deferred Metro preparation requires metroPublicBaseUrl or metroProxyBaseUrl when Metro settings are provided.`);let o=await t.metro.prepare({projectRoot:e.metroProjectRoot,kind:ve(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 K(e){if(e)try{await De(e)}catch{}}async function Dn(e){try{await kt({projectRoot:process.cwd(),stateDir:e.stateDir,profileKey:e.state.remoteConfigPath,consumerKey:e.state.session})}catch{}}async function On(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 kn(e,t){if(t.leaseId)try{await On(e,t)}catch{}}async function An(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 q(e){if(e.leaseBackend)return e.leaseBackend;if(e.platform===`android`)return`android-instance`;if(e.platform===`ios`)return`ios-instance`}function jn(e,t){let r=q(e);if(r)return r;throw new n(`INVALID_ARGS`,`${t} requires --platform ios|android or --lease-backend when the remote connection has not resolved a lease yet.`)}function Mn(e,t,n,r=[]){return e===`cdp`?Lt(r)&&!!t.metroPublicBaseUrl:fn.has(e)?!0:e!==`batch`||!n?!1:n.some(e=>{let t=e.command.trim().toLowerCase();return fn.has(t)&&e.runtime===void 0})}function Nn(e){let t=e.metroKind;return!!(e.metroPublicBaseUrl||e.metroProxyBaseUrl||e.metroProjectRoot||t)}function Pn(e,t){return!e.platform||!t||t!==`ios`&&t!==`android`?!0:e.platform===t}function Fn(e,t){return e?.projectRoot===t?.projectRoot&&e?.profileKey===t?.profileKey&&e?.consumerKey===t?.consumerKey}function In(e,t){if(e)return Pn(e,t)?e:void 0}function Ln(e,t,r={}){if(!e.tenant)throw new n(`INVALID_ARGS`,`remote command requires tenant in remote config or via --tenant <id>.`);if(!e.runId)throw new n(`INVALID_ARGS`,`remote command requires runId in remote config or via --run-id <id>.`);if(!e.daemonBaseUrl&&un(r.leaseProvider))throw new n(`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:t,remoteConfigHash:z(t),daemon:Ut(e),tenant:e.tenant,runId:e.runId,leaseId:e.leaseId,leaseBackend:e.leaseBackend??q(e),leaseProvider:r.leaseProvider,clientId:r.clientId,deviceKey:r.deviceKey,platform:e.platform,target:e.target,connectedAt:i,updatedAt:i}}async function Rn(e,t,n,r,i){if(t.leaseId&&t.leaseBackend===n){let i=await Gn(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 zn(e){if(!pn.has(e.command)){if(e.state.leaseId&&e.state.deviceKey)return{state:e.state};throw new n(`INVALID_ARGS`,`No active proxy device lease for this session; run open first.`)}let t=await Vn(e.client,e.flags),r=Hn(t);return{state:{...e.state,deviceKey:r,leaseBackend:e.state.leaseBackend??e.leaseBackend??Un(t),platform:e.state.platform??t.platform,target:e.state.target??t.target,updatedAt:new Date().toISOString()},device:t}}function Bn(e,t){if(e.platform=t.platform,e.target=t.target??e.target,o(t)){e.udid=t.id;return}t.platform===`android`&&(e.serial=t.id)}async function Vn(e,n){return await t((await e.devices.list({platform:n.platform,target:n.target,device:n.device,udid:n.udid,serial:n.serial,iosSimulatorDeviceSet:n.iosSimulatorDeviceSet,androidDeviceAllowlist:n.androidDeviceAllowlist})).map(e=>({...s(e.platform),id:e.id,name:e.name,kind:e.kind,target:e.target,booted:e.booted})),{platform:n.platform,target:n.target,deviceName:n.device,udid:n.udid,serial:n.serial})}function Hn(e){return`${a(e)}:${e.target??`mobile`}:${e.id}`}function Un(e){if(o(e))return`ios-instance`;if(e.platform===`android`)return`android-instance`}function Wn(e,t,r){if(e.leaseBackend&&e.leaseBackend!==r)throw new n(`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&&t.platform&&e.platform!==t.platform)throw new n(`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&&t.target&&e.target!==t.target)throw new n(`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 Gn(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(Kn(e))return;throw e}}function Kn(e){return!(e instanceof n)||e.code!==`UNAUTHORIZED`?!1:e.details?.reason===`LEASE_NOT_FOUND`||e.details?.reason===`LEASE_EXPIRED`||e.details?.reason===`LEASE_REVOKED`}function qn(e){return Ee(e)}async function Jn(e,t){let r=await e.text(),i={};if(r.trim().length>0)try{i=JSON.parse(r)}catch(r){throw new n(`COMMAND_FAILED`,t.invalidJsonMessage,{status:e.status},r instanceof Error?r:void 0)}if(!e.ok)throw new n(`UNAUTHORIZED`,t.rejectedMessage,{status:e.status,response:i});return i}const Yn=1e3;async function Xn(e){return await Zn({command:e.command,flags:e.flags,stateDir:e.stateDir,allowInteractiveLogin:e.command===`connect`&&!e.flags.noLogin,env:e.env})}async function Zn(e){let t=e.env??e.io?.env??process.env;if(!e.flags.daemonBaseUrl)return{flags:e.flags,source:`none`};if(Y(e.flags.daemonAuthToken))return{flags:e.flags,source:`flag`};if(Y(t.AGENT_DEVICE_DAEMON_AUTH_TOKEN))return{flags:e.flags,source:`env`};if(!mr(e.flags.daemonBaseUrl,t))return{flags:e.flags,source:`none`};let r=await ar({stateDir:e.stateDir,flags:e.flags,env:t,io:e.io});if(r)return{flags:{...e.flags,daemonAuthToken:r.accessToken},source:`cli-session`};if(!e.allowInteractiveLogin)throw e.flags.noLogin?new n(`UNAUTHORIZED`,`Remote daemon authentication is required.`,{hint:`Run agent-device auth login, unset --no-login, or set AGENT_DEVICE_DAEMON_AUTH_TOKEN.`}):pr(e.command,t);let i=await $n({stateDir:e.stateDir,flags:e.flags,env:t,io:e.io});return{flags:{...e.flags,daemonAuthToken:i.accessToken},source:`login`}}async function Qn(e){let t=e.env??e.io?.env??process.env;if(Y(e.flags.daemonAuthToken))return{accessToken:e.flags.daemonAuthToken,cloudBaseUrl:J(t)};if(Y(t.AGENT_DEVICE_DAEMON_AUTH_TOKEN))return{accessToken:t.AGENT_DEVICE_DAEMON_AUTH_TOKEN,cloudBaseUrl:J(t)};let r=await ar({stateDir:e.stateDir,flags:e.flags,env:t,io:e.io});if(r)return{accessToken:r.accessToken,cloudBaseUrl:r.cloudBaseUrl};if(e.flags.noLogin)throw new n(`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 $n({stateDir:e.stateDir,flags:e.flags,env:t,io:e.io,commandLabel:`agent-device connect`});return{accessToken:i.accessToken,cloudBaseUrl:i.session.cloudBaseUrl}}async function $n(e){let t=e.env??e.io?.env??process.env,r=ur(t,e.io);if(r===`non-interactive`)throw pr(e.commandLabel??`agent-device connect`,t);let i=J(t),a=await cr({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});lr(a);let o=a.verificationUriComplete??a.verificationUri,s=r===`local-browser`?a.verificationUri:hr(a.verificationUri,a.userCode);r===`local-browser`?(_r(e.io,`Opening ${a.verificationUri}...\n`),await gr(o,e.io)):_r(e.io,`Open this URL on your machine:\n${s}\n\nWaiting for approval for 10 minutes...\n`);let c=await sr({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(!Y(c.accessToken)||!Y(l))throw new n(`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 tr({stateDir:e.stateDir,session:d}),{accessToken:c.accessToken,expiresAt:c.expiresAt,session:d}}function er(e){let t=rr(e.stateDir);if(!N.existsSync(t))return null;try{let e=JSON.parse(N.readFileSync(t,`utf8`));return e.version!==1||!Y(e.id)||!Y(e.cloudBaseUrl)||!Y(e.refreshCredential)||!Y(e.createdAt)?null:e}catch{return null}}function tr(e){let t=rr(e.stateDir);N.mkdirSync(P.dirname(t),{recursive:!0,mode:448}),N.writeFileSync(t,`${JSON.stringify(e.session,null,2)}\n`,{mode:384});try{N.chmodSync(t,384)}catch{}}function nr(e){let t=rr(e.stateDir);return N.existsSync(t)?(N.rmSync(t,{force:!0}),!0):!1}function rr(e){return P.join(e,`auth`,`cli-session.json`)}function ir(e){let t=er({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:vr(t.expiresAt,e.now)}:{authenticated:!1,source:`none`}}async function ar(e){let t=er({stateDir:e.stateDir});return!t||vr(t.expiresAt,e.io?.now)?null:{accessToken:(await or({session:t,flags:e.flags,env:e.env,io:e.io})).accessToken,cloudBaseUrl:J(e.env,t.cloudBaseUrl)}}async function or(e){let t=await cr({baseUrl:J(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(Y(t.accessToken))return{accessToken:t.accessToken,expiresAt:t.expiresAt};throw t.status===`revoked`||t.error===`revoked`?new n(`UNAUTHORIZED`,`Stored cloud CLI session was revoked.`,{hint:`Run agent-device auth login again, or set AGENT_DEVICE_DAEMON_AUTH_TOKEN.`,status:t.status,error:t.error}):new n(`UNAUTHORIZED`,`Failed to refresh CLI session.`,{hint:`Run agent-device auth login again, or set AGENT_DEVICE_DAEMON_AUTH_TOKEN.`,status:t.status,error:t.error})}async function sr(e){let t=e.now??Date.now,r=Math.min((e.expiresIn??600)*1e3,6e5),i=t()+r,a=Math.max(Yn,(e.interval??5e3/1e3)*1e3);for(;t()<i;){let t=await cr({baseUrl:e.cloudBaseUrl,pathName:`/api/control-plane/device-auth/poll`,body:{deviceCode:e.deviceCode},fetchImpl:e.fetchImpl});if(t.status===`approved`||Y(t.accessToken))return t;if(t.status===`slow_down`||t.error===`slow_down`)a+=Yn;else if(t.status!==`authorization_pending`&&t.error!==`authorization_pending`)throw new n(`UNAUTHORIZED`,`Device authorization was not approved.`,{status:t.status,error:t.error});await yr(a)}throw new n(`TIMEOUT`,`Device authorization expired before approval.`)}async function cr(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 Jn(t,{invalidJsonMessage:`Cloud auth endpoint returned invalid JSON (${t.status}).`,rejectedMessage:`Cloud auth endpoint rejected the request.`})}function lr(e){if(!Y(e.deviceCode)||!Y(e.userCode)||!Y(e.verificationUri))throw new n(`COMMAND_FAILED`,`Cloud auth start returned an unusable response.`)}function ur(e,t){let n=t?.stdinIsTTY??process.stdin.isTTY,r=t?.stdoutIsTTY??process.stdout.isTTY;return dr(e)||!n||!r?`non-interactive`:fr(e)?`device-code`:`local-browser`}function dr(e){return e.CI===`true`||e.GITHUB_ACTIONS===`true`||e.BUILDKITE===`true`}function fr(e){return!!(e.SSH_TTY||e.SSH_CONNECTION||e.CODESPACES===`true`||e.GITPOD_WORKSPACE_ID||e.REMOTE_CONTAINERS===`true`)}function pr(e,t){let r=J(t);return new n(`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 J(e,t){let r=e.AGENT_DEVICE_CLOUD_BASE_URL??t??`https://cloud.agent-device.dev`;try{return new URL(r).toString().replace(/\/+$/,``)}catch(e){throw new n(`INVALID_ARGS`,`Invalid AGENT_DEVICE_CLOUD_BASE_URL.`,{cloudBaseUrl:r},e instanceof Error?e:void 0)}}function mr(e,t){if(t.AGENT_DEVICE_CLOUD_AUTH===`1`||t.AGENT_DEVICE_CLOUD_AUTH===`true`||Y(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 hr(e,t){let n=new URL(e);return n.searchParams.set(`user_code`,t),n.toString()}async function gr(e,t){if(t?.openBrowser){await t.openBrowser(e);return}let n=process.platform;try{n===`darwin`?await g(`open`,[e],{allowFailure:!0,timeoutMs:5e3}):n===`win32`?await g(`cmd`,[`/c`,`start`,``,e],{allowFailure:!0,timeoutMs:5e3}):await g(`xdg-open`,[e],{allowFailure:!0,timeoutMs:5e3})}catch{_r(t,`Open this URL on your machine:\n${e}\n`)}}function _r(e,t){(e?.stderr??process.stderr).write(t)}function vr(e,t){if(!e)return!1;let n=Date.parse(e);return Number.isFinite(n)?n<=(t?.()??Date.now()):!0}function Y(e){return typeof e==`string`&&e.trim().length>0}async function yr(e){await new Promise(t=>setTimeout(t,e))}const br=new Set([`daemonAuthToken`,`metroBearerToken`]);function xr(e){let t=Er(wr(e.profile)),n=P.join(e.stateDir,`remote-connections`,`generated`);N.mkdirSync(n,{recursive:!0,mode:448});let r=P.join(n,`${Dr(e.provider)}-${Tr(t)}.json`);N.writeFileSync(r,`${JSON.stringify(t,null,2)}\n`,{mode:384});try{N.chmodSync(r,384)}catch{}return r}function Sr(e){try{return L(e)}catch(t){let i=r(t);throw new n(`COMMAND_FAILED`,`${e.provider} connection profile returned invalid remote config.`,{generatedConfigPath:e.configPath,cause:i.message},i)}}function Cr(e){let t=Sr({configPath:xr({stateDir:e.stateDir,provider:e.provider,profile:e.profile}),cwd:e.cwd,env:e.env,provider:Or(e.provider)});return{flags:{...U(t.profile),...e.flags,...e.extraFlags??{},remoteConfig:t.resolvedPath},remoteConfigPath:t.resolvedPath}}function wr(e){return Object.fromEntries(Object.entries(e).filter(([e])=>!br.has(e)))}function Tr(e){return M.createHash(`sha256`).update(JSON.stringify(e)).digest(`hex`).slice(0,16)}function Er(e){return Array.isArray(e)?e.map(Er):e&&typeof e==`object`?Object.fromEntries(Object.entries(e).filter(([,e])=>e!==void 0).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>[e,Er(t)])):e}function Dr(e){return e.replaceAll(/[^a-zA-Z0-9._-]/g,`_`)||`generated`}function Or(e){let[t=``,...n]=e;return`${t.toUpperCase()}${n.join(``)}`}async function kr(e){let t=await Qn({stateDir:e.stateDir,flags:e.flags,env:e.env,io:{env:e.env,fetch:e.fetchImpl}}),n=await Ar({cloudBaseUrl:t.cloudBaseUrl,accessToken:t.accessToken,fetchImpl:e.fetchImpl}),r=Nr({stateDir:e.stateDir,cloudBaseUrl:t.cloudBaseUrl,daemonBaseUrl:typeof n.daemonBaseUrl==`string`?n.daemonBaseUrl:``,session:e.flags.session});return Cr({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 Ar(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 jr(await Jn(t,{invalidJsonMessage:`Cloud connection profile endpoint returned invalid JSON (${t.status}).`,rejectedMessage:`Cloud connection profile endpoint rejected the request.`}))}function jr(e){if(!e||typeof e!=`object`||Array.isArray(e))throw new n(`COMMAND_FAILED`,`Cloud connection profile response is invalid.`);let t=e.connection;if(!t||typeof t!=`object`)throw new n(`COMMAND_FAILED`,`Cloud connection profile response is missing profile.`);if(t.remoteConfigProfile!==void 0)return Mr(t.remoteConfigProfile);throw new n(`COMMAND_FAILED`,`Cloud connection profile did not include remoteConfigProfile.`)}function Mr(e){if(!e||typeof e!=`object`||Array.isArray(e))throw new n(`COMMAND_FAILED`,`Cloud connection profile remoteConfigProfile is invalid.`);if(Object.keys(e).length===0)throw new n(`COMMAND_FAILED`,`Cloud connection profile remoteConfigProfile is empty.`);return e}function Nr(e){return M.createHash(`sha256`).update(`${e.stateDir}\0${e.cloudBaseUrl}\0${e.daemonBaseUrl}\0${e.session??``}`).digest(`hex`).slice(0,16)}function Pr(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}}function Fr(e){let t=Lr(e.provider)(e),n=Wr(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??q(e.flags),target:e.flags.target??`mobile`,session:e.flags.session,...t,...Pr(e.flags)};return Cr({stateDir:e.stateDir,provider:e.provider,profile:r,cwd:e.cwd,env:e.env,flags:e.flags})}const Ir=[{provider:A.browserStack,buildProfileFields:Rr},{provider:A.awsDeviceFarm,buildProfileFields:zr}];function Lr(e){let t=Ir.find(t=>t.provider===e)?.buildProfileFields;if(t)return t;throw new n(`INVALID_ARGS`,`Unsupported cloud WebDriver provider "${e}".`)}function Rr(e){return Vr(e.env,`BROWSERSTACK_USERNAME`,`connect browserstack`),Vr(e.env,`BROWSERSTACK_ACCESS_KEY`,`connect browserstack`),{platform:Br(e.flags.platform,`connect browserstack requires --platform ios|android.`),device:X(e.flags.device,`connect browserstack requires --device <name>.`),providerOsVersion:X(e.flags.providerOsVersion,`connect browserstack requires --provider-os-version <version>.`),providerApp:X(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 zr(e){let{env:t,flags:n}=e;return{platform:Br(n.platform,`connect aws-device-farm requires --platform ios|android.`),device:n.device,awsProjectArn:Hr(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:Hr(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:Ur(n.awsAppArn,t,[`AGENT_DEVICE_AWS_DEVICE_FARM_APP_ARN`,`AWS_DEVICE_FARM_APP_ARN`]),awsRegion:Ur(n.awsRegion,t,[`AWS_REGION`,`AWS_DEFAULT_REGION`]),awsInteractionMode:n.awsInteractionMode,providerSessionName:n.providerSessionName}}function Br(e,t){if(e===`android`||e===`ios`)return e;throw new n(`INVALID_ARGS`,t)}function X(e,t){if(e)return e;throw new n(`INVALID_ARGS`,t)}function Vr(e,t,r){let i=e?.[t];if(i)return i;throw new n(`INVALID_ARGS`,`${r} requires ${t} in the environment.`)}function Hr(e,t,n,r){return X(Ur(e,t,n),r)}function Ur(e,t,n){return e||n.map(e=>t?.[e]).find(e=>!!e)}function Wr(e,t,n,r){return M.createHash(`sha256`).update(`${e}\0${t}\0${n??``}\0${r??``}`).digest(`hex`).slice(0,16)}function Gr(e){let t=e.flags.daemonBaseUrl??e.env?.AGENT_DEVICE_DAEMON_BASE_URL;if(!t)throw new n(`INVALID_ARGS`,`connect proxy requires --daemon-base-url <url> or AGENT_DEVICE_DAEMON_BASE_URL.`);let r=Kr(e.stateDir,t,e.flags.session),i={daemonBaseUrl:t,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??q(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,...Pr(e.flags)};return Cr({stateDir:e.stateDir,provider:`proxy`,profile:i,cwd:e.cwd,env:e.env,flags:e.flags,extraFlags:{daemonBaseUrl:t,daemonTransport:e.flags.daemonTransport??`http`}})}function Kr(e,t,n){return M.createHash(`sha256`).update(`${e}\0${t}\0${n??``}`).digest(`hex`).slice(0,16)}const qr=async({positionals:e,flags:t,client:n})=>{let r=O(t.stateDir).baseDir,i=pi(e);Yr(i,t);let a=await Jr({provider:i,flags:t,stateDir:r}),o=a.flags,s=ai(a.remoteConfigPath),c=Xr(o,s),l=Zr({stateDir:r,flags:o,remoteConfigPath:a.remoteConfigPath});Qr(l.previous,{flags:o,session:l.session,remoteConfigPath:a.remoteConfigPath,remoteConfigHash:l.remoteConfigHash,desiredLeaseBackend:q(o),connection:s,daemon:l.daemon});let u=$r({flags:o,scope:c,connectionMetadata:s,context:l,remoteConfigPath:a.remoteConfigPath});Ht({stateDir:r,state:u}),await ri(n,r,o,l.previous);let d=Ti(u),f=Ci(o,u);return j(o,Oi(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 Jr(e){let{provider:t,flags:n,stateDir:r}=e;return n.remoteConfig?ii(n):W(t)?Fr({provider:t,flags:n,stateDir:r,cwd:process.cwd(),env:process.env}):t===`proxy`||!t&&mi(n)?Gr({flags:n,stateDir:r,cwd:process.cwd(),env:process.env}):await kr({flags:n,stateDir:r,cwd:process.cwd(),env:process.env})}function Yr(e,t){if(!(!e||!t.remoteConfig))throw new n(`INVALID_ARGS`,`connect provider positional and --remote-config are mutually exclusive.`)}function Xr(e,t){if(!e.tenant)throw new n(`INVALID_ARGS`,`connect requires tenant in remote config or via --tenant <id>.`);if(!e.runId)throw new n(`INVALID_ARGS`,`connect requires runId in remote config or via --run-id <id>.`);if(!e.daemonBaseUrl&&un(t?.leaseProvider))throw new n(`INVALID_ARGS`,`connect requires daemonBaseUrl in remote config, config, env, or --daemon-base-url.`);return{tenant:e.tenant,runId:e.runId}}function Zr(e){let{stateDir:t,flags:n,remoteConfigPath:r}=e,i=n.session?null:H({stateDir:t}),a=n.session??i?.session??ci(t);return{session:a,previous:i?.session===a?i:R({stateDir:t,session:a}),remoteConfigHash:z(r),daemon:Si(n)}}function Qr(e,t){if(!(!e||vi(e,t))&&!t.flags.force)throw new n(`INVALID_ARGS`,`A different remote connection is already active for this session. Re-run connect with --force to replace it.`,{session:t.session,remoteConfig:e.remoteConfigPath})}function $r(e){let{flags:t,scope:n,connectionMetadata:r,context:i,remoteConfigPath:a}=e,o=ni(t,i.previous)?i.previous:null,s=new Date().toISOString(),c=ei(t,o,r),l=ti(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 ei(e,t,n){return{leaseId:t?.leaseId,leaseBackend:t?.leaseBackend??q(e),leaseProvider:n?.leaseProvider??t?.leaseProvider,clientId:n?.clientId??t?.clientId,deviceKey:t?.deviceKey??n?.deviceKey}}function ti(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 ni(e,t){return!!(t&&!e.force)}async function ri(e,t,n,r){!r||!n.force||(await K(r.metro),await Dn({stateDir:t,state:r}),await kn(e,r))}function ii(e){if(!e.remoteConfig)throw new n(`INVALID_ARGS`,`connect requires --remote-config <path>.`);return{flags:e,remoteConfigPath:L({configPath:e.remoteConfig,cwd:process.cwd(),env:process.env}).resolvedPath}}function ai(e){let t=L({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 oi=async({flags:e,client:t})=>{let{session:n,stateDir:r,state:i}=gi(e);if(!i)return _i(e,n),!0;let a=i.session,o;try{o=(await t.sessions.close({session:a,shutdown:e.shutdown})).provider}catch{}await K(i.metro),await Dn({stateDir:r,state:i});let s=!1;if(i.leaseId)try{let e=await On(t,i);s=e.released,o??=e.provider}catch{}return Wt({stateDir:r,session:a}),j(e,{connected:!1,session:a,released:s,...o?{provider:o}:{}},()=>li(a,o)),!0},si=async({positionals:e,flags:t})=>{if(e[0]!==`status`)throw new n(`INVALID_ARGS`,`connection accepts only: status`);let{session:r,state:i}=gi(t);if(!i)return _i(t,r),!0;let a=Ti(i),o=wi(i);return j(t,Oi(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 ci(e){for(let t=0;t<8;t+=1){let t=`adc-${M.randomBytes(3).toString(`hex`)}`;if(!R({stateDir:e,session:t}))return t}return`adc-${Date.now().toString(36)}-${M.randomBytes(2).toString(`hex`)}`}function li(e,t){return[`Disconnected remote session "${e}".`,...ui(t),...fi(t?.cloudArtifacts?.cloudArtifacts)].join(`
4
+ `)}function ui(e){return(Array.isArray(e?.warnings)?e.warnings:[]).flatMap(e=>{let t=di(e);return t?[t]:[]})}function di(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 fi(e){return(e??[]).filter(e=>(e.availability??`ready`)===`ready`&&e.url).slice(0,3).map(e=>`${e.name}: ${e.url}`)}function pi(e){let t=e[0];if(t!==void 0){if(e.length>1)throw new n(`INVALID_ARGS`,`connect accepts at most one provider positional.`);if(cn(t))return t;throw new n(`INVALID_ARGS`,`Unknown connect provider: ${t}. Supported providers: ${ln()}.`)}}function mi(e){return!e.daemonBaseUrl||e.tenant||e.runId||e.leaseId||e.leaseBackend?!1:hi(e.daemonBaseUrl)}function hi(e){try{return new URL(e).pathname.replace(/\/+$/,``).endsWith(`/agent-device`)}catch{return!1}}function gi(e){let t=e.session??`default`,n=O(e.stateDir).baseDir;return{session:t,stateDir:n,state:R({stateDir:n,session:t})??(e.session?null:H({stateDir:n}))}}function _i(e,t){j(e,{connected:!1,session:t},()=>`No remote connection for "${t}".`)}function vi(e,t){return yi(e,t)&&bi(e,t)&&xi(e.daemon,t.daemon)}function yi(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 bi(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 xi(e,t){return[`baseUrl`,`transport`,`serverMode`].every(n=>(e?.[n]??void 0)===(t?.[n]??void 0))}function Si(e){return Ut(e)}function Ci(e,t){if(!t.runtime&&!(!Nn(e)&&!Di(t.remoteConfigPath)))return Ei(t.remoteConfigPath)}function wi(e){if(!(e.runtime||!Di(e.remoteConfigPath)))return Ei(e.remoteConfigPath)}function Ti(e){if(e.leaseId)return;let t=dn(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 Ei(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 Di(e){try{let t=L({configPath:e,cwd:process.cwd(),env:process.env}).profile;return!!(t.metroPublicBaseUrl||t.metroProxyBaseUrl||t.metroProjectRoot||t.metroKind)}catch{return!1}}function Oi(e,t){let n=Ti(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:Jt(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 ki=async({positionals:e,flags:t})=>{let r=e[0]??`status`,i=O(t.stateDir).baseDir;if(r===`status`){let e=ir({stateDir:i});return j(t,e,()=>Ai(e)),!0}if(r===`login`){let e=await $n({stateDir:i,flags:t,commandLabel:`agent-device auth login`});return j(t,{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=nr({stateDir:i});return j(t,{authenticated:!1,removed:e},()=>e?`Removed stored cloud CLI session.`:`No stored cloud CLI session.`),!0}throw new n(`INVALID_ARGS`,`auth accepts only: status, login, logout`)};function Ai(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.`}const ji=`${ce}/`,Mi=[`content-type`,`content-range`,`x-artifact-type`,`x-artifact-filename`,`x-artifact-hash`,`x-artifact-hash-algorithm`],Ni=[`content-type`,`content-disposition`,`x-request-id`];function Pi(e){let t=Ki(e);return Ke.createServer((e,n)=>{Fi(e,n,t).catch(e=>{la(n,e)})})}async function Fi(e,t,n){let r=Yi(e.url??`/`);if(e.method===`GET`&&r===`/health`){await Ii(t,n);return}if(!Xi(r,e.method)){t.statusCode=404,t.end(`Not found`);return}let i;if(r===`/rpc`&&(i=(await de(e,n.maxRpcBodyBytes,`Proxy request body is too large.`)).toString(`utf8`)),!na(e,n.clientToken,i)){ca(t,r,oa(i));return}await Ri({req:e,res:t,route:r,options:n,rpcBody:i})}async function Ii(e,t){let n=await Li(t);e.statusCode=200,e.setHeader(`content-type`,`application/json`),e.end(JSON.stringify(fe(`agent-device-proxy`,{upstream:n})))}async function Li(e){let t=new URL(oe(e.upstreamBaseUrl,`health`)),n=await e.fetchImpl(t,{method:`GET`,headers:ea({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 Ri(e){let{req:t,res:n,route:r,options:i,rpcBody:a}=e,o=$i(i.upstreamBaseUrl,r,t.url??`/`),s=t.method??`GET`,c=ea(t,i.upstreamToken,r),l=ta(t,r,a,i.upstreamToken);await zi({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 zi(e){let{req:t,res:n,route:r,response:i,clientToken:a}=e;if(n.statusCode=i.status,Bi(i,n),Vi(t,n),Qi(r)){await Hi({req:t,res:n,response:i,clientToken:a});return}await Gi(i,n)}function Bi(e,t){for(let n of Ni){let r=e.headers.get(n);r&&t.setHeader(n,r)}}function Vi(e,t){t.hasHeader(`x-request-id`)||t.setHeader(`x-request-id`,sa(e))}async function Hi(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(Ui(a,t,i))}function Ui(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=Wi(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,ue(n)),JSON.stringify({...r,upload:{...i.upload,url:a,headers:o}})}function Wi(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 Gi(e,t){if(!e.body){t.end();return}await qe(Je.fromWeb(e.body),t)}function Ki(e){return{upstreamBaseUrl:qi(e.upstreamBaseUrl,`upstreamBaseUrl`),upstreamToken:Ji(e.upstreamToken,`upstreamToken`),clientToken:Ji(e.clientToken,`clientToken`),maxRpcBodyBytes:e.maxRpcBodyBytes??1048576,upstreamTimeoutMs:e.upstreamTimeoutMs??3e5,fetchImpl:e.fetchImpl??fetch}}function qi(e,t){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 n(`INVALID_ARGS`,`Invalid ${t}`,{[t]:e},r)}}function Ji(e,t){let r=e.trim();if(!r)throw new n(`INVALID_ARGS`,`Proxy ${t} is required.`);return r}function Yi(e){let t=new URL(e,`http://127.0.0.1`).pathname;return t===`/agent-device`?`/`:t.startsWith(ji)?`/${t.slice(ji.length)}`:t}function Xi(e,t){return e===`/rpc`?t===`POST`:Zi(e,t)?!0:e===`/artifacts`||e===`/artifacts/`||e.startsWith(`/artifacts/`)?t===`GET`:!1}function Zi(e,t){return e===`/upload`||Qi(e)||e===`/upload/finalize`?t===`POST`:e.startsWith(`/upload/direct/`)?t===`PUT`:!1}function Qi(e){return e===`/upload/preflight`}function $i(e,t,n){let r=new URL(oe(e,t)),i=n.indexOf(`?`);return i>=0&&(r.search=n.slice(i)),r}function ea(e,t,n){let r=new Headers;for(let t of Mi){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(ue(t)))r.set(e,n);return r}function ta(e,t,n,r){if(!(e.method===`GET`||e.method===`HEAD`))return t===`/rpc`?ia(n??``,r):e}function na(e,t,n){let r=ra(e,n);return r.length>0&&ke(r,t)}function ra(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 ia(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 oa(e){if(!e)return null;try{return JSON.parse(e).id??null}catch{return null}}function sa(e){let t=e.headers[`x-request-id`];return typeof t==`string`&&t.trim()?t.trim().slice(0,128):Ge()}function ca(t,r,i){if(t.statusCode=401,t.setHeader(`content-type`,`application/json`),r===`/rpc`){t.end(JSON.stringify({jsonrpc:`2.0`,id:i,error:{code:-32001,message:`Invalid proxy token`,data:e(new n(`UNAUTHORIZED`,`Invalid proxy token`))}}));return}t.end(JSON.stringify({ok:!1,error:`Invalid proxy token`,code:`UNAUTHORIZED`}))}function la(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 ua=async({positionals:e,flags:t})=>{if(e.length>0)throw new n(`INVALID_ARGS`,`proxy does not accept positional arguments.`);let r=await da(t);return j(t,r,()=>ga(r)),await _a(),!0};async function da(e){let t=re({session:`default`,command:`proxy`,positionals:[],flags:{stateDir:e.stateDir,daemonBaseUrl:``,daemonTransport:`http`,daemonServerMode:`http`}}),r=await ae(t),i=fa(r.info.httpPort),a=pa(e),o=Pi({upstreamBaseUrl:i,upstreamToken:r.info.token,clientToken:a});await ma(o,e.proxyHost?.trim()||`127.0.0.1`,e.proxyPort??0);let s=o.address();if(!s||typeof s==`string`)throw new n(`COMMAND_FAILED`,`Proxy did not bind to a TCP address.`);let c=`http://${ha(s.address)}:${s.port}`;return{proxyBaseUrl:c,agentDeviceBaseUrl:ie(c),token:a,upstreamBaseUrl:i,stateDir:t.paths.baseDir}}function fa(e){if(!e)throw new n(`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 pa(e){return e.daemonAuthToken?.trim()||We(32).toString(`hex`)}function ma(e,t,n){return new Promise((r,i)=>{e.once(`error`,i),e.listen(n,t,()=>{e.off(`error`,i),r()})})}function ha(e){return e.includes(`:`)&&!e.startsWith(`[`)?`[${e}]`:e}function ga(e,t={}){let n=t.useColor??ne(),r=Z(`✓`,`green`,n),i=Z(e.proxyBaseUrl,`cyan`,n),a=Z(`<tunnel URL>`,`cyan`,n),o=Z(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(`
6
+ `)}function Z(e,t,n){return n?E(e,t,{validateStream:!1}):e}function _a(){return new Promise(()=>{})}const va=new Set([`id`,`text`,`label`]),ya=new Set([`enabled`,`selected`]);function ba(e){let t=He(e);return xa(t.actions,{actionLines:t.actionLines,metadata:Ue(e)})}function xa(e,t={}){let r={config:Sa(t.metadata),warnings:[],unsupported:[]},i=[];for(let[n,a]of e.entries()){let e=t.actionLines?.[n]??n+1,o=wa(a);switch(o.kind){case`commands`:i.push(...o.commands),to(r,o.warnings,a,e);break;case`config`:$a(r,o.appId,a,e),i.push(...o.commands),to(r,o.warnings,a,e);break;case`unsupported`:r.unsupported.push({line:e,action:ao(a),message:o.message});break}}if(r.unsupported.length>0)throw new n(`INVALID_ARGS`,`Cannot export replay to Maestro YAML: unsupported .ad action ${io(r.unsupported)}.`,{unsupported:r.unsupported});return{yaml:ro(r.config,i),warnings:r.warnings}}function Sa(e){return e?.env&&Object.keys(e.env).length>0?{env:e.env}:{}}const Ca={open:Ta,click:Oa,press:Oa,longpress:ka,fill:Na,type:Pa,keyboard:Fa,back:()=>({kind:`commands`,commands:[`back`]}),wait:Ia,find:La,screenshot:Ra,scroll:za,swipe:Ba};function wa(e){return Ca[e.command]?.(e)??{kind:`unsupported`,message:`${e.command} has no Maestro equivalent`}}function Ta(e){let[t,n]=e.positionals;if(!t)return{kind:`unsupported`,message:`open requires an app id or URL`};if(oo(t))return{kind:`commands`,commands:[{openLink:t}]};let r=Ea(e,t);return n&&oo(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 Ea(e,t){let n=Da(e);return n?{launchApp:{appId:t,...n}}:`launchApp`}function Da(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 Oa(e){let[t,n]=e.positionals;if(!t)return{kind:`unsupported`,message:`${e.command} requires a target`};let r=Wa(t,n);if(!r)return{kind:`unsupported`,message:`tap target is not Maestro-compatible`};let i=Ya(e);return i.ok?e.flags?.doubleTap===!0?{kind:`commands`,commands:[{doubleTapOn:r}],warnings:Ma(e,`doubleTapOn`)}:typeof e.flags?.holdMs==`number`?{kind:`commands`,commands:[{longPressOn:r}],warnings:[ja(e.flags.holdMs),...Ma(e,`longPressOn`)]}:{kind:`commands`,commands:[Qa(r,i.options)]}:{kind:`unsupported`,message:i.message}}function ka(e){let[t,n]=e.positionals;if(!t)return{kind:`unsupported`,message:`longpress requires a target`};let r=Wa(t,n);return r?{kind:`commands`,commands:[{longPressOn:r}],warnings:Aa(e).map(ja)}:{kind:`unsupported`,message:`longpress target is not Maestro-compatible`}}function Aa(e){let[t,n,r]=e.positionals,i=Q(t)&&Q(n)?r:n;return i&&Q(i)?[Number(i)]:[]}function ja(e){return`long-press duration exports as Maestro longPressOn; Maestro uses its default long-press duration instead of ${e}ms`}function Ma(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 Na(e){let[t,n]=e.positionals;if(!t||n===void 0)return{kind:`unsupported`,message:`fill requires a target and text`};let r=Wa(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 Pa(e){let[t]=e.positionals;if(t===void 0)return{kind:`unsupported`,message:`type requires text`};let n=eo(t);return n===null?{kind:`commands`,commands:[{inputText:t}]}:{kind:`commands`,commands:[{eraseText:n}]}}function Fa(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 Ia(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:no(e,17e3)}}]};let r=Ga(t);return r?{kind:`commands`,commands:[{extendedWaitUntil:{visible:r,timeout:no(e,17e3)}}]}:{kind:`unsupported`,message:`wait selector is not Maestro-compatible`}}function La(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 Ra(e){let[t]=e.positionals;return t?{kind:`commands`,commands:[{takeScreenshot:t}]}:{kind:`unsupported`,message:`screenshot requires an output path`}}function za(e){let[t]=e.positionals;return!t||t===`down`?{kind:`commands`,commands:[`scroll`]}:{kind:`unsupported`,message:`scroll ${t} is not exported yet`}}function Ba(e){let t=Va(e);if(!t)return{kind:`unsupported`,message:`only coordinate swipe exports to Maestro`};let n=Ha(e);if(n===null)return{kind:`unsupported`,message:`swipe count must be a positive integer`};let r=Ua(e);return r?{kind:`unsupported`,message:r}:{kind:`commands`,commands:Array.from({length:n},()=>({swipe:t}))}}function Va(e){let[t,n,r,i,a]=e.positionals;if(!(!Q(t)||!Q(n)||!Q(r)||!Q(i)))return{start:Ve(t,n),end:Ve(r,i),...a&&Q(a)?{duration:Number(a)}:{}}}function Ha(e){let t=e.flags?.count??1;return Number.isInteger(t)&&t>=1?t:null}function Ua(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 Wa(e,t){return Q(e)&&Q(t)?{point:Ve(e,t)}:e.startsWith(`@`)?null:Ga(e)}function Ga(e){let t;try{t=_(e)}catch{return e.includes(`=`)||e.includes(`||`)?null:e}let n=Ka(t.selectors);return n===null?t.selectors.length===1?qa(t.selectors[0]):null:n}function Ka(e){if(e.length<=1)return null;let t=e.flatMap(e=>e.terms.length===1&&va.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 qa(e){let t={};for(let n of e.terms)if(!Ja(t,n))return null;return Object.keys(t).length>0?t:null}function Ja(e,t){return va.has(t.key)?typeof t.value!=`string`||e.id||e.text||e.label?!1:(e[t.key]=t.value,!0):ya.has(t.key)&&typeof t.value==`boolean`?(e[t.key]=t.value,!0):!1}function Ya(e){let t=Za(e);return t?{ok:!1,message:t}:{ok:!0,options:Xa(e)}}function Xa(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 Za(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 Qa(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 $a(e,t,n,r){if(!e.config.appId){e.config.appId=t;return}e.config.appId!==t&&e.unsupported.push({line:r,action:ao(n),message:`multiple app ids cannot be represented in one Maestro config (${e.config.appId} vs ${t})`})}function eo(e){return e.length===0||![...e].every(e=>e===`\b`)?null:e.length}function to(e,t,n,r){for(let i of t??[])e.warnings.push({line:r,action:ao(n),message:i})}function no(e,t){let n=e.positionals.at(-1);return n&&Q(n)?Number(n):t}function ro(e,t){return Be(Object.keys(e).length>0?[e,t]:[t])}function io(e){return e.map(e=>`line ${e.line} (${e.action}): ${e.message}`).join(`; `)}function ao(e){return[e.command,...e.positionals??[]].join(` `).trim()}function oo(e){return/^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(e)}function Q(e){return e!==void 0&&Number.isFinite(Number(e))}const so=async e=>{let{positionals:t}=e;return t[0]===`export`?await lo(e):co(e)};function co({positionals:e,flags:t}){if(e.length>1)throw new n(`INVALID_ARGS`,`replay accepts exactly one input path: replay <path>`);if(t.replayExportFormat!==void 0||t.out!==void 0)throw new n(`INVALID_ARGS`,`replay --format/--out are only supported with replay export.`);return!1}async function lo({positionals:e,flags:t}){uo(e,t);let r=e[1];if(!r)throw new n(`INVALID_ARGS`,`replay export requires an input path.`);let i=k(r),a=ba(N.readFileSync(i,`utf8`)),o=typeof t.out==`string`?k(t.out):void 0;o&&(N.mkdirSync(P.dirname(o),{recursive:!0}),N.writeFileSync(o,a.yaml));for(let e of a.warnings)process.stderr.write(`Warning: line ${e.line}: ${e.message}\n`);return j(t,{format:t.replayExportFormat??`maestro`,sourcePath:i,...o?{path:o}:{yaml:a.yaml},warnings:a.warnings},()=>o??a.yaml),!0}function uo(e,t){if(e.length>2)throw new n(`INVALID_ARGS`,`replay export accepts exactly one input path: replay export <file.ad>`);if(t.replayUpdate)throw new n(`INVALID_ARGS`,`replay export does not support --update.`);if(t.replayMaestro)throw new n(`INVALID_ARGS`,`replay export reads .ad files; omit --maestro.`);if(t.replayEnv?.length)throw new n(`INVALID_ARGS`,`replay export does not evaluate --env substitutions.`);let r=t.replayExportFormat??`maestro`;if(r!==`maestro`)throw new n(`INVALID_ARGS`,`Unsupported replay export format: ${r}`)}const fo=async({positionals:e,flags:t,client:n})=>{let r=await ze({client:n,command:`screenshot`,positionals:e,flags:t});return i(t.responseLevel)?(j(t,r,()=>JSON.stringify(r,null,2)),!0):(j(t,pe(r),()=>r.overlayRefs?`Annotated ${r.overlayRefs.length} refs onto ${r.path}`:ho(r)),!0)},po=async({positionals:e,flags:t,client:r})=>{if(e[0]===`snapshot`){let n=await ze({client:r,command:`diff`,positionals:e,flags:t});return j(t,n,()=>T(n)),!0}if(e[0]!==`screenshot`)return!1;let i=t.baseline;if(!i||typeof i!=`string`)throw new n(`INVALID_ARGS`,`diff screenshot requires --baseline <path>`);let a=k(i),o=typeof t.out==`string`?k(t.out):void 0,s=e[1];if(e.length>2)throw new n(`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:mo(r,t),artifacts:u(),sessions:{get:e=>({name:e}),set:()=>{}},policy:l()}).capture.diffScreenshot({session:t.session,baseline:{kind:`path`,path:a},current:s?{kind:`path`,path:k(s)}:{kind:`live`},...o?{out:{kind:`path`,path:o}}:{},threshold:_o(t.threshold),overlayRefs:t.overlayRefs,normalizeStatusBar:t.screenshotNormalizeStatusBar,surface:t.surface});return j(t,d,()=>b(d)),!0};function mo(e,t){return{platform:go(t),captureScreenshot:async(t,n,r)=>pe(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 ho(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 go(e){switch(e.platform){case`android`:case`linux`:case`macos`:return e.platform;default:return`ios`}}function _o(e){if(!(e==null||e===``))return Number(e)}const vo={connect:qr,disconnect:oi,connection:si,auth:ki,proxy:ua,replay:so,screenshot:fo,diff:po};async function yo(e){let t={...e.flags},n=vo[e.command];return n&&await n({...e,flags:t})?!0:qn(e.command)?await bo({...e,command:e.command,flags:t}):!1}async function bo(e){let{runGenericClientBackedCommand:t}=await import(`./generic.js`);return await t(e)}function xo(e){return[`exec`,`--yes`,`--package`,`agent-react-devtools@0.4.0`,`--`,`agent-react-devtools`,...e]}function So(e){return e===`ios-instance`}function Co(e){return e[0]===`wait`&&e.includes(`--connected`)}function wo(e,t,n){n===0||!Co(e)||!So(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(`
7
+ `))}function $(e,t,n){return n||(e.push(t),``)}function To(e){if(!e?.metroProxyBaseUrl||!Pt(e.leaseBackend))return null;let t=[],r={serverBaseUrl:$(t,`metroProxyBaseUrl`,e.metroProxyBaseUrl),bearerToken:$(t,`metroBearerToken`,e.metroBearerToken),tenantId:$(t,`tenant`,e.tenant),runId:$(t,`runId`,e.runId),leaseId:$(t,`leaseId`,e.leaseId)};if(t.length>0)throw new n(`INVALID_ARGS`,`react-devtools remote bridge requires ${t.join(`, `)}.`,{missing:t});return r}async function Eo(e,t,n){let{flags:r}=t,i=To(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 kt({projectRoot:t.cwd??process.cwd(),stateDir:a,profileKey:s,consumerKey:o})}return await Ot({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()}async function Do(e,t={}){let n=t.cwd??process.cwd(),r=t.env??process.env,i=await Eo(e,t,async()=>(await m(`npm`,xo(e),{cwd:n,env:r,allowFailure:!0,onStdoutChunk:e=>{process.stdout.write(e)},onStderrChunk:e=>{process.stderr.write(e)}})).exitCode);return wo(e,t.flags,i),i}async function Oo(e,t){switch(e[0]){case`setup`:{ko(t.flags.json);let{setupManagedAgentBrowser:e}=await import(`./agent-browser-tool.js`).then(e=>e.t),n=await e({stateDir:t.stateDir});return Ao(t.flags.json,n),0}case`doctor`:{let{doctorManagedAgentBrowser:e}=await import(`./agent-browser-tool.js`).then(e=>e.t),n=await e({stateDir:t.stateDir});return jo(t.flags.json,n.exitCode===0?`Web backend is healthy.`:`Web backend doctor reported issues.`,n),n.exitCode}default:throw new n(`INVALID_ARGS`,`web requires setup or doctor`)}}function ko(e){e||process.stdout.write(`Setting up managed agent-browser backend (downloads if needed)...
8
+ `)}function Ao(e,t){if(e){x({success:!0,data:{status:Mo(t)}});return}process.stdout.write(`Managed web backend installed.\nagent-browser available at: ${t.binaryPath}\n`)}function jo(e,t,n){if(e){x({success:!0,data:No(n)});return}process.stdout.write(`${t}\n`)}function Mo(e){let{socketDir:t,...n}=e;return n}function No(e){let t=e.status;return Po(t)?{...e,status:Mo(t)}:e}function Po(e){return typeof e==`object`&&!!e&&`socketDir`in e&&`installDir`in e&&`binaryPath`in e}function Fo(e){let t;try{t=JSON.parse(e)}catch{throw new n(`INVALID_ARGS`,`Batch steps must be valid JSON.`)}if(!Array.isArray(t)||t.length===0)throw new n(`INVALID_ARGS`,`Batch steps must be a non-empty JSON array.`);return Io(t)}function Io(e){let t=!1,n=e.map((e,n)=>{if(Ro(e))return zo(e,n+1);let r=Bo(e,n+1);return t=!0,Lo(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.
9
+ `),n}function Lo(e){let t=Re(e.command,e.positionals??[],Go(e.flags));return{command:e.command,input:t,...e.runtime===void 0?{}:{runtime:e.runtime}}}function Ro(e){return Se(e)&&`input`in e&&!(`positionals`in e)&&!(`flags`in e)}function zo(e,t){let n=xe(e.runtime,t),{runtime:r,...i}=e;return{...i,...n===void 0?{}:{runtime:n}}}function Bo(e,t){if(!Se(e))throw new n(`INVALID_ARGS`,`Invalid batch step ${t}.`);Ho(e,t);let r=Vo(e.command,t),i=Uo(e.positionals,t),a=Wo(e.flags,t),o=xe(e.runtime,t);return{command:r,...i===void 0?{}:{positionals:i},...a===void 0?{}:{flags:a},...o===void 0?{}:{runtime:o}}}function Vo(e,t){let r=typeof e==`string`?e.trim().toLowerCase():``;if(!r)throw new n(`INVALID_ARGS`,`Batch step ${t} requires command.`);if(Ee(r))return r;throw new n(`INVALID_ARGS`,`Batch step ${t} command is not available through command batch: ${String(e)}`)}function Ho(e,t){let r=Object.keys(e).filter(e=>![`command`,`positionals`,`flags`,`runtime`].includes(e));if(r.length>0)throw new n(`INVALID_ARGS`,`Batch step ${t} has unknown legacy field(s): ${r.join(`, `)}.`)}function Uo(e,t){if(e!==void 0){if(!Array.isArray(e)||e.some(e=>typeof e!=`string`))throw new n(`INVALID_ARGS`,`Batch step ${t} positionals must contain only strings.`);return e}}function Wo(e,t){if(e!==void 0){if(!Se(e))throw new n(`INVALID_ARGS`,`Batch step ${t} flags must be an object.`);return e}}function Go(e){return{json:!1,help:!1,version:!1,...e}}function Ko(e,t={}){let n=qo(t),r={...e};return n.defaultPlatform&&r.platform===void 0&&(r.platform=n.defaultPlatform),r}function qo(e){let t=e.env??process.env,n=e.inheritedPlatform??e.configuredPlatform??Yo(t.AGENT_DEVICE_PLATFORM),r=Zo(e.configuredSession??t.AGENT_DEVICE_SESSION);return{defaultPlatform:n,lockPolicy:Jo(e.policyOverrides,t,r)}}function Jo(e,t,n){let r=e?.sessionLock??e?.sessionLockConflicts??Xo(t.AGENT_DEVICE_SESSION_LOCK);if(r)return r;if(e?.sessionLocked===!0||n)return`reject`}function Yo(e){if(e===void 0)return;let t=e.trim().toLowerCase();if(t){if(t===`ios`||t===`android`||t===`apple`)return t;throw new n(`INVALID_ARGS`,`Invalid AGENT_DEVICE_PLATFORM: ${e}. Use ios, android, or apple.`)}}function Xo(e){if(e===void 0)return;let t=e.trim().toLowerCase();if(t){if(t===`reject`||t===`strip`)return t;throw new n(`INVALID_ARGS`,`Invalid session lock mode: ${e}. Use reject or strip.`)}}function Zo(e){return typeof e==`string`&&e.trim().length>0}function Qo(e){let t=e.env??process.env;return F(F({},ns($o(e.cwd,e.cliFlags.config,t))),as(t,e.command))}function $o(e,t,n){let r=t??n.AGENT_DEVICE_CONFIG;return r?[{path:ts(r,e,n),required:!0}]:[{path:es(n),required:!1},{path:P.resolve(e,`agent-device.json`),required:!1}]}function es(e){return P.join(he(`~`,{env:e}),`.agent-device`,`config.json`)}function ts(e,t,n){return k(e,{cwd:t,env:n})}function ns(e){let t={};for(let n of e)F(t,rs(n.path,n.required));return t}function rs(e,t){if(!N.existsSync(e)){if(t)throw new n(`INVALID_ARGS`,`Config file not found: ${e}`);return{}}let r;try{r=N.readFileSync(e,`utf8`)}catch(t){throw new n(`INVALID_ARGS`,`Failed to read config file: ${e}`,{cause:t instanceof Error?t.message:String(t)})}let i;try{i=JSON.parse(r)}catch(t){throw new n(`INVALID_ARGS`,`Invalid JSON in config file: ${e}`,{cause:t instanceof Error?t.message:String(t)})}if(!i||typeof i!=`object`||Array.isArray(i))throw new n(`INVALID_ARGS`,`Config file must contain a JSON object: ${e}`);return is(i,`config file ${e}`)}function is(e,t){let r={};for(let[i,a]of Object.entries(e)){if(i===`installSource`){r.installSource=ye(a,t);continue}let e=i,o=et(e);if(!o)throw new n(`INVALID_ARGS`,`Unknown config key "${i}" in ${t}.`);if(!o.config.enabled)throw new n(`INVALID_ARGS`,`Unsupported config key "${i}" in ${t}.`);r[e]=nt(o,a,t,i)}return r}function as(e,t){let n={};for(let r of tt(t)){if(r.key===`installSource`)continue;let t=r.env.names.map(t=>({name:t,value:e[t]})).find(e=>typeof e.value==`string`&&e.value.trim().length>0);t&&(n[r.key]=nt(r,t.value,`environment variable ${t.name}`,t.name))}return n}function os(e,t){let n=ot(e),r=t?.env??process.env,i=t?.cwd??process.cwd(),a=ss(n.command)?sn({remoteConfig:n.flags.remoteConfig,cwd:i,env:r}):{},o=F(Qo({command:n.command,cwd:i,cliFlags:n.flags,env:r}),a);return{...dt(n,{strictFlags:t?.strictFlags,defaultFlags:o}),providedFlags:n.providedFlags}}function ss(e){return e!==null}const cs={sendToDaemon:le},ls=new Set([`launchUrl`,`kind`,`metroBearerToken`,`metroKind`,`metroListenHost`,`metroNoInstallDeps`,`metroNoReuseExisting`,`metroPreparePort`,`metroProbeTimeoutMs`,`metroProjectRoot`,`metroProxyBaseUrl`,`metroPublicBaseUrl`,`metroRuntimeFile`,`metroStartupTimeoutMs`,`metroStatusHost`]),us=new Set([`connect`,`connection`,`close`,`disconnect`,`metro`,`proxy`,`session`]);async function ds(t,i=cs){let a=c(),o=me(),s=fs(t),l=t.includes(`--json`);await u({session:Ds(t)??process.env.AGENT_DEVICE_SESSION??`default`,requestId:a,command:t[0],debug:s},async()=>{let c;try{c=os(t,{cwd:process.cwd(),env:process.env})}catch(t){h({level:`error`,phase:`cli_parse_failed`,data:{error:t instanceof Error?t.message:String(t)}});let n=e(t,{diagnosticId:f().diagnosticId,logPath:d({force:!0})??void 0});l?x({success:!1,error:n}):y(n,{showDetails:s}),process.exit(1);return}for(let e of c.warnings)process.stderr.write(`Warning: ${e}\n`);c.flags.version&&(process.stdout.write(`${o}\n`),process.exit(0));let u=c.command===`help`,p=c.flags.help;if(u||p){u&&c.positionals.length>1&&(y(new n(`INVALID_ARGS`,`help accepts at most one command.`)),process.exit(1));let e=u?c.positionals[0]:c.command;e||(process.stdout.write(`${await wt()}\n`),process.exit(0));let t=await Tt(e);t&&(process.stdout.write(t),process.exit(0)),y(new n(`INVALID_ARGS`,`Unknown command: ${e}`)),process.stdout.write(`${await wt()}\n`),process.exit(1)}c.command||(process.stdout.write(`${await wt()}\n`),process.exit(1));let{command:m,positionals:g}=c,_=ms(m,c.providedFlags),v,b,S,C,w,T,E=new Set(c.providedFlags.map(e=>e.key));try{v=qo({policyOverrides:c.flags,configuredPlatform:c.flags.platform,configuredSession:c.flags.session}),b=v.lockPolicy?{...c.flags}:Ko(c.flags,{policyOverrides:c.flags,configuredPlatform:c.flags.platform,configuredSession:c.flags.session}),S=O(b.stateDir),C=b.session??`default`,w=_s({command:m,explicitFlagKeys:E,stateDir:S.baseDir,session:C,remoteConfig:b.remoteConfig,hasResolvedSession:b.session!==void 0}),T=w?Ss(b,w.flags,E):b}catch(t){let n=e(r(t),{diagnosticId:f().diagnosticId,logPath:d({force:!0})??void 0});c.flags.json?x({success:!1,error:n}):y(n,{showDetails:_}),process.exit(1);return}let D=null;try{if(m===`react-devtools`){let e=await Do(g,{flags:T,stateDir:S.baseDir,session:T.session??C,cwd:process.cwd(),env:process.env});process.exit(e);return}if(m===`web`){let e=await Oo(g,{flags:T,stateDir:S.baseDir});process.exit(e);return}Ne({command:m,currentVersion:o,stateDir:S.baseDir,flags:T});let e=w?.runtime,t=w?.connection,r=(e,t,n)=>({session:e.session,requestId:a,stateDir:e.stateDir,daemonBaseUrl:e.daemonBaseUrl,daemonAuthToken:e.daemonAuthToken,daemonTransport:e.daemonTransport,daemonServerMode:e.daemonServerMode,tenant:e.tenant,sessionIsolation:e.sessionIsolation,runId:e.runId,leaseId:e.leaseId,leaseBackend:e.leaseBackend,leaseProvider:n?.leaseProvider,clientId:n?.clientId,deviceKey:n?.deviceKey,providerApp:e.providerApp,providerOsVersion:e.providerOsVersion,providerProject:e.providerProject,providerBuild:e.providerBuild,providerSessionName:e.providerSessionName,awsProjectArn:e.awsProjectArn,awsDeviceArn:e.awsDeviceArn,awsAppArn:e.awsAppArn,awsRegion:e.awsRegion,awsInteractionMode:e.awsInteractionMode,runtime:t,lockPolicy:v.lockPolicy,lockPlatform:v.defaultPlatform,cwd:process.cwd(),debug:_,cost:e.cost,responseLevel:e.responseLevel}),s;if(m===`batch`){if(g.length>0)throw new n(`INVALID_ARGS`,`batch does not accept positional arguments.`);s=hs(b)}if(ys(m)&&(T=(await Xn({command:m,flags:T,stateDir:S.baseDir,env:process.env})).flags),T.remoteConfig&&vs(m)){let n=se(r(T,e,t),{transport:Ts(i.sendToDaemon)}),a=await mn({command:m,flags:T,client:n,runtime:e,positionals:g,batchSteps:s,forceRuntimePrepare:Cs(E)});T=a.flags,e=a.runtime,t=a.connection}if(bs({command:m,flags:T,runtime:e,explicitFlagKeys:E,hadConnectionDefaults:!!w})&&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.
10
+ `),m===`cdp`){let t=await Vt(g,{flags:T,runtime:e,cwd:process.cwd(),env:process.env});process.exit(t);return}let c=T.daemonBaseUrl;D=_&&!T.json&&!c?Os(S.logPath):null;let l=m===`test`?await import(`./reporting.js`).then(({createReplayTestReporterRuntime:e})=>e({debug:_,verbose:T.verbose,json:T.json,reporter:T.reporter,reportJunit:T.reportJunit})):void 0,u=se(r(T,e,t),{transport:ws({command:m,flags:T,replayTestReporterRuntime:l,transport:i.sendToDaemon})});if(m===`batch`){if(!s)throw new n(`INVALID_ARGS`,`batch requires --steps or --steps-file.`);let e=s.map((e,t)=>({...e,input:v.lockPolicy&&b.platform===void 0?{...e.input}:Ko(e.input,{policyOverrides:T,configuredPlatform:T.platform,configuredSession:T.session,inheritedPlatform:T.platform})}));if(await yo({command:m,positionals:g,flags:{...T,batchSteps:e},client:u,debug:_,replayTestReporterRuntime:l}))return}else if(m===`runtime`)throw new n(`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 yo({command:m,positionals:g,flags:T,client:u,debug:_,replayTestReporterRuntime:l}))return;throw new n(`INVALID_ARGS`,ps(m))}catch(t){let n=r(t),i=e(n,{diagnosticId:f().diagnosticId,logPath:d({force:!0})??void 0});if(m===`close`&&gs(n)){T.json&&x({success:!0,data:{closed:`session`,source:`no-daemon`}});return}if(T.json)x({success:!1,error:i});else if(y(i,{showDetails:_}),_)try{let e=S.logPath;if(N.existsSync(e)){let t=N.readFileSync(e,`utf8`).split(`
11
+ `),n=t.slice(Math.max(0,t.length-200)).join(`
12
+ `);n.trim().length>0&&process.stderr.write(`\n[daemon log]\n${n}\n`)}}catch{}D&&D(),process.exit(1)}finally{D&&D()}})}function fs(e){try{let t=ot(e);return ms(t.command??``,t.providedFlags)}catch{return e.includes(`--debug`)||e.includes(`-v`)||e.includes(`--verbose`)}}function ps(e){return v(e)?(h({level:`error`,phase:`cli_known_command_unhandled`,data:{command:e}}),`Command is registered but no CLI handler accepted it: ${e}`):`Unknown command: ${e}`}function ms(e,t){return t.some(t=>t.key===`verbose`&&(t.token===`--debug`||t.token===`-v`||e!==`test`))}function hs(e){let t=``;if(e.steps)t=e.steps;else if(e.stepsFile)try{t=N.readFileSync(e.stepsFile,`utf8`)}catch(t){let r=t instanceof Error?t.message:String(t);throw new n(`INVALID_ARGS`,`Failed to read --steps-file ${e.stepsFile}: ${r}`)}return Fo(t)}function gs(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 _s(e){return e.command===`connect`||e.command===`connection`||e.command===`proxy`?null:Gt({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 vs(e){return!us.has(e)}function ys(e){return e!==`auth`&&e!==`connection`&&e!==`proxy`}function bs(e){return e.command!==`open`||e.runtime||e.flags.bundleUrl||e.flags.metroHost||e.flags.metroPort||e.flags.remoteConfig||e.hadConnectionDefaults?!1:xs(e.explicitFlagKeys)}function xs(e){return e.has(`daemonBaseUrl`)||e.has(`daemonTransport`)||e.has(`tenant`)||e.has(`sessionIsolation`)||e.has(`runId`)||e.has(`leaseId`)||e.has(`leaseBackend`)}function Ss(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 Cs(e){for(let t of ls)if(e.has(t))return!0;return!1}function ws(e){let{command:t,flags:n,replayTestReporterRuntime:r,transport:i}=e;return n.json?Ts(i):async e=>await Es(i,{...e,meta:{...e.meta,requestProgress:t===`test`?`replay-test`:`command`}},t===`test`&&r?{onProgress:r.onProgress}:void 0)}function Ts(e){return async t=>await Es(e,t)}async function Es(e,t,n){return await e(t,n)}function Ds(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}Ye(process.argv[1]??``).href===import.meta.url&&ds(process.argv.slice(2)).catch(t=>{y(e(r(t)),{showDetails:!0}),process.exit(1)});function Os(e){try{let t=N.existsSync(e)?N.statSync(e).size:0,n=!1,r=setInterval(()=>{if(!n&&N.existsSync(e))try{let n=N.statSync(e);if(n.size<t&&(t=0),n.size<=t)return;let r=N.openSync(e,`r`);try{let e=Buffer.alloc(n.size-t);N.readSync(r,e,0,e.length,t),t=n.size,e.length>0&&process.stdout.write(e.toString(`utf8`))}finally{N.closeSync(r)}}catch{}},200);return()=>{n=!0,clearInterval(r)}}catch{return null}}export{ds as runCli};
@@ -0,0 +1 @@
1
+ import{b as e}from"./sdk-android-adb.js";import{a as t,n,o as r,u as i}from"./host-process.js";import{a,c as o,d as s,f as c,g as l,h as u,i as d,l as f,m as p,n as m,o as h,p as g,s as _,u as v}from"./url.js";import{createHash as y}from"node:crypto";import b from"node:fs";import x from"node:path";import{fileURLToPath as S}from"node:url";const C=`companion-tunnel`;function w(e){return y(`sha256`).update(e).digest(`hex`)}function T(e){return e?.trim()?e.trim():void 0}function E(e){if(!e||typeof e!=`object`||Array.isArray(e))return;let t=e;if(!(typeof t.tenantId!=`string`||typeof t.runId!=`string`||typeof t.leaseId!=`string`))return{tenantId:t.tenantId,runId:t.runId,leaseId:t.leaseId}}function D(e,t){return e.tenantId===t.tenantId&&e.runId===t.runId&&e.leaseId===t.leaseId}function O(e,t,n,r){let i=r??x.join(e,`.agent-device`);if(!n)return{statePath:x.join(i,`${t.slug}.json`),logPath:x.join(i,`${t.slug}.log`)};let a=w(n).slice(0,12),o=x.join(i,t.slug);return{statePath:x.join(o,`${t.slug}-${a}.json`),logPath:x.join(o,`${t.slug}-${a}.log`)}}function k(e){try{let t=JSON.parse(b.readFileSync(e,`utf8`));if(!Number.isInteger(t.pid)||Number(t.pid)<=0||typeof t.serverBaseUrl!=`string`||typeof t.localBaseUrl!=`string`||typeof t.tokenHash!=`string`||t.tokenHash.length===0)return null;let n=Array.isArray(t.consumers)?t.consumers.filter(e=>typeof e==`string`&&e.length>0):[];return{pid:Number(t.pid),startTime:typeof t.startTime==`string`?t.startTime:void 0,command:typeof t.command==`string`?t.command:void 0,serverBaseUrl:t.serverBaseUrl,localBaseUrl:t.localBaseUrl,launchUrl:T(typeof t.launchUrl==`string`?t.launchUrl:void 0),registerPath:T(typeof t.registerPath==`string`?t.registerPath:void 0),unregisterPath:T(typeof t.unregisterPath==`string`?t.unregisterPath:void 0),devicePort:Number.isInteger(t.devicePort)?Number(t.devicePort):void 0,session:T(typeof t.session==`string`?t.session:void 0),bridgeScope:E(t.bridgeScope),tokenHash:t.tokenHash,consumers:n}}catch{return null}}function A(e,t){b.mkdirSync(x.dirname(e),{recursive:!0}),b.writeFileSync(e,`${JSON.stringify(t,null,2)}\n`,`utf8`)}function j(e){b.mkdirSync(x.dirname(e),{recursive:!0}),b.closeSync(b.openSync(e,`a`))}function M(e){try{b.unlinkSync(e)}catch{}}function N(e){try{b.unlinkSync(e)}catch{}}function P(e){try{b.readdirSync(e).length===0&&b.rmdirSync(e)}catch{}}function F(e,t){let n=x.dirname(e.statePath),r=x.dirname(e.logPath);M(e.statePath),N(e.logPath),P(n),r!==n&&P(r),x.basename(n)===t.slug&&P(x.dirname(n))}function I(e,t){return e.includes(t.runArg)}function L(e,i){if(!n(e.pid))return!1;if(e.startTime){let t=r(e.pid);if(!t||t!==e.startTime)return!1}let a=t(e.pid);return!a||!I(a,i.definition)||!e.bridgeScope?!1:e.serverBaseUrl===m(i.serverBaseUrl)&&e.localBaseUrl===m(i.localBaseUrl)&&e.launchUrl===T(i.launchUrl)&&e.registerPath===T(i.registerPath)&&e.unregisterPath===T(i.unregisterPath)&&e.devicePort===i.devicePort&&e.session===T(i.session)&&D(e.bridgeScope,i.bridgeScope)&&e.tokenHash===w(i.bearerToken)}function R(e){return T(e.consumerKey)??T(e.profileKey)??null}function z(e,t){return!t||e.consumers.includes(t)?e:{...e,consumers:[...e.consumers,t]}}function B(e,t){return t?{...e,consumers:e.consumers.filter(e=>e!==t)}:{...e,consumers:[]}}async function V(e,r){if(!n(e.pid))return;let a=t(e.pid);if(!(!a||!I(a,r))){try{process.kill(e.pid,`SIGTERM`)}catch(e){let t=e.code;if(t===`ESRCH`||t===`EPERM`)return;throw e}if(!await i(e.pid,1e3)){try{process.kill(e.pid,`SIGKILL`)}catch(e){let t=e.code;if(t===`ESRCH`||t===`EPERM`)return;throw e}await i(e.pid,1e3)}}}function H(e,t){let n={...t};return n[c]=m(e.serverBaseUrl),n[d]=e.bearerToken,n[_]=m(e.localBaseUrl),n[p]=O(e.projectRoot,e.definition,e.profileKey,e.stateDir).statePath,n[s]=e.bridgeScope.tenantId,n[v]=e.bridgeScope.runId,n[f]=e.bridgeScope.leaseId,e.launchUrl?.trim()?n[h]=e.launchUrl.trim():delete n[h],e.registerPath?.trim()?n[o]=e.registerPath.trim():delete n[o],e.unregisterPath?.trim()?n[u]=e.unregisterPath.trim():delete n[u],e.devicePort===void 0?delete n[a]:n[a]=String(e.devicePort),e.session?.trim()?n[g]=e.session.trim():delete n[g],n}function U(e){let t=S(import.meta.url),n=x.extname(t)||`.js`,r=[x.join(x.dirname(t),`${C}${n}`),x.join(x.dirname(t),`internal`,`${C}${n}`)].find(e=>b.existsSync(e));if(!r)throw Error(`${e.displayName} entrypoint not found. Rebuild the package to include the companion worker entry.`);return r}function W(n,i){let a=U(n.definition),o=a.endsWith(`.ts`)?[`--experimental-strip-types`]:[];b.mkdirSync(x.dirname(i),{recursive:!0});let s=b.openSync(i,`a`),c=0;try{c=e(process.execPath,[...o,a,n.definition.runArg],{env:H(n,n.env??process.env),stdio:[`ignore`,s,s]})}finally{b.closeSync(s)}if(!Number.isInteger(c)||c<=0)throw Error(`Failed to start ${n.definition.displayName} process.`);return{pid:c,startTime:r(c)??void 0,command:t(c)??void 0,serverBaseUrl:m(n.serverBaseUrl),localBaseUrl:m(n.localBaseUrl),launchUrl:T(n.launchUrl),registerPath:T(n.registerPath),unregisterPath:T(n.unregisterPath),devicePort:n.devicePort,session:T(n.session),bridgeScope:n.bridgeScope,tokenHash:w(n.bearerToken),consumers:[]}}async function G(e){let t=R(e),n=O(e.projectRoot,e.definition,e.profileKey,e.stateDir),r=k(n.statePath);if(r&&L(r,e)){let e=z(r,t);return e!==r&&A(n.statePath,e),{pid:r.pid,spawned:!1,statePath:n.statePath,logPath:n.logPath}}r&&(await V(r,e.definition),F(n,e.definition)),j(n.statePath);let i;try{i=W(e,n.logPath),A(n.statePath,z(i,t))}catch(t){throw i&&await V(i,e.definition).catch(()=>{}),F(n,e.definition),t}return{pid:i.pid,spawned:!0,statePath:n.statePath,logPath:n.logPath}}async function K(e){let t=R(e),n=O(e.projectRoot,e.definition,e.profileKey,e.stateDir),r=k(n.statePath);if(!r)return F(n,e.definition),{stopped:!1,statePath:n.statePath};let i=B(r,t);return i.consumers.length>0?(A(n.statePath,i),{stopped:!1,statePath:n.statePath}):(await V(r,e.definition),F(n,e.definition),{stopped:!0,statePath:n.statePath})}const q={slug:`metro-companion`,runArg:l,displayName:`Metro companion`};async function J(e){return await G({...e,definition:q,registerPath:e.registerPath??`/api/metro/companion/register`})}async function Y(e){return await K({...e,definition:q})}export{K as i,Y as n,G as r,J as t};