agent-device 0.20.9 → 0.20.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.9.apk → agent-device-android-ime-helper-0.20.10.apk} +0 -0
  2. package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.10.apk.sha256 +1 -0
  3. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.9.manifest.json → agent-device-android-ime-helper-0.20.10.manifest.json} +4 -4
  4. package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.9.apk → agent-device-android-snapshot-helper-0.20.10.apk} +0 -0
  5. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.10.apk.sha256 +1 -0
  6. package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.9.manifest.json → agent-device-android-snapshot-helper-0.20.10.manifest.json} +6 -6
  7. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +6 -5
  8. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +4 -4
  9. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+FlatSnapshotFiltering.swift +94 -1
  10. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +22 -23
  11. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +3 -23
  12. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Navigation.swift +10 -11
  13. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+PrivateAXPresentation.swift +30 -12
  14. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollGesture.swift +8 -5
  15. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +133 -63
  16. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +13 -12
  17. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotPresentation.swift +183 -0
  18. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotPresentationTests.swift +0 -0
  19. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SystemModal.swift +20 -18
  20. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextInputCandidatePolicy.swift +19 -0
  21. package/dist/src/agent-device-client.js +2 -2
  22. package/dist/src/ai-sdk.d.ts +61 -0
  23. package/dist/src/ai-sdk.js +1 -0
  24. package/dist/src/android-adb.d.ts +1 -1
  25. package/dist/src/app-lifecycle.js +1 -1
  26. package/dist/src/app-log-reconnect.js +1 -1
  27. package/dist/src/app-log-runtime.js +3 -3
  28. package/dist/src/app-resolution.js +2 -2
  29. package/dist/src/apps.js +5 -5
  30. package/dist/src/audio-probe.js +1 -1
  31. package/dist/src/boot-diagnostics.js +2 -2
  32. package/dist/src/cli-config.js +1 -1
  33. package/dist/src/cli-help.js +30 -23
  34. package/dist/src/cli-runner.js +1 -1
  35. package/dist/src/cli.js +7 -7
  36. package/dist/src/client-metro.js +1 -1
  37. package/dist/src/client-types.d.ts +1582 -0
  38. package/dist/src/command-tools.js +2 -0
  39. package/dist/src/connection-runtime.js +1 -1
  40. package/dist/src/contracts.d.ts +1 -1
  41. package/dist/src/contracts.js +1 -1
  42. package/dist/src/daemon-shutdown-report.js +1 -1
  43. package/dist/src/daemon.js +1 -1
  44. package/dist/src/debug-symbols.js +1 -1
  45. package/dist/src/device-input-state.js +1 -1
  46. package/dist/src/dispatch.js +1 -1
  47. package/dist/src/find.js +1 -1
  48. package/dist/src/finders.js +1 -1
  49. package/dist/src/generic-settle.js +1 -1
  50. package/dist/src/generic.js +1 -1
  51. package/dist/src/helper-package-install.js +1 -1
  52. package/dist/src/helper.js +1 -1
  53. package/dist/src/ime-lifecycle.js +1 -1
  54. package/dist/src/ime-recovery-marker.js +1 -1
  55. package/dist/src/index.d.ts +2 -1578
  56. package/dist/src/index.js +1 -1
  57. package/dist/src/input-actions.js +1 -1
  58. package/dist/src/input-actions3.js +1 -1
  59. package/dist/src/install-source2.js +1 -1
  60. package/dist/src/interaction-common.js +1 -1
  61. package/dist/src/interaction-runtime.js +1 -1
  62. package/dist/src/interaction-snapshot.js +1 -1
  63. package/dist/src/interaction.js +1 -1
  64. package/dist/src/interaction2.js +1 -1
  65. package/dist/src/interactor.js +2 -2
  66. package/dist/src/interactor2.js +1 -1
  67. package/dist/src/interactors.js +1 -1
  68. package/dist/src/internal/bin.js +2 -2
  69. package/dist/src/internal/daemon.js +4 -4
  70. package/dist/src/internal/png-worker.js +1 -1
  71. package/dist/src/lease-context.js +1 -1
  72. package/dist/src/lease.js +1 -1
  73. package/dist/src/limrun.d.ts +10 -2
  74. package/dist/src/linux.js +1 -1
  75. package/dist/src/location-coordinates.js +1 -1
  76. package/dist/src/{screenshot-geometry.js → mobile-snapshot-semantics.js} +1 -1
  77. package/dist/src/perf.js +1 -1
  78. package/dist/src/platform-runtime-open-target.js +1 -1
  79. package/dist/src/platform-runtime-operation-host.js +4 -4
  80. package/dist/src/platform-runtime.js +1 -1
  81. package/dist/src/platform-runtime2.js +1 -1
  82. package/dist/src/png-resize.js +1 -1
  83. package/dist/src/provider.js +1 -1
  84. package/dist/src/proxy.js +1 -1
  85. package/dist/src/react-native.js +1 -1
  86. package/dist/src/record-runtime.js +1 -1
  87. package/dist/src/registry.js +27 -27
  88. package/dist/src/remote-config2.js +1 -1
  89. package/dist/src/replay.js +2 -2
  90. package/dist/src/reporting.js +5 -5
  91. package/dist/src/runner-client.js +1 -1
  92. package/dist/src/runner-disposal.js +1 -1
  93. package/dist/src/runner-sequence.js +1 -1
  94. package/dist/src/runtime.js +3 -3
  95. package/dist/src/runtime2.js +4 -4
  96. package/dist/src/runtime3.js +1 -1
  97. package/dist/src/runtime4.js +3 -3
  98. package/dist/src/runtime5.js +1 -1
  99. package/dist/src/runtime6.js +1 -1
  100. package/dist/src/runtime7.js +1 -1
  101. package/dist/src/runtime8.js +1 -1
  102. package/dist/src/runtime9.js +1 -1
  103. package/dist/src/screenshot-result.js +4 -4
  104. package/dist/src/screenshot.js +1 -1
  105. package/dist/src/script-source-bundle.js +16 -0
  106. package/dist/src/sdk-android-adb.d.ts +40 -40
  107. package/dist/src/sdk-android-adb.js +4 -4
  108. package/dist/src/sdk-batch-runner.js +3 -3
  109. package/dist/src/sdk-contracts.d.ts +122 -85
  110. package/dist/src/sdk-contracts.js +2 -2
  111. package/dist/src/sdk-finders.d.ts +1 -1
  112. package/dist/src/sdk-finders.js +1 -1
  113. package/dist/src/sdk-selectors.d.ts +89 -77
  114. package/dist/src/sdk-selectors.js +1 -1
  115. package/dist/src/selector-runtime.js +1 -1
  116. package/dist/src/selectors.js +1 -1
  117. package/dist/src/server.js +10 -3
  118. package/dist/src/session-target-evidence.js +1 -1
  119. package/dist/src/session2.js +7 -8
  120. package/dist/src/shared.js +1 -1
  121. package/dist/src/snapshot-runtime.js +1 -1
  122. package/dist/src/snapshot-scope.js +1 -0
  123. package/dist/src/snapshot.js +6 -6
  124. package/dist/src/snapshot2.js +1 -1
  125. package/dist/src/snapshot3.js +1 -1
  126. package/dist/src/src.js +1 -1
  127. package/dist/src/src2.js +1 -1
  128. package/dist/src/src3.js +1 -1
  129. package/dist/src/src4.js +1 -0
  130. package/dist/src/tool-provider2.js +1 -1
  131. package/dist/src/tool-provider3.js +1 -0
  132. package/dist/src/verified-file.js +1 -1
  133. package/dist/src/web.js +1 -1
  134. package/package.json +21 -8
  135. package/server.json +2 -2
  136. package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.9.apk.sha256 +0 -1
  137. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.9.apk.sha256 +0 -1
  138. package/dist/src/cancel.js +0 -1
  139. package/dist/src/prepare-kind.js +0 -15
  140. package/dist/src/selector-vocabulary.js +0 -1
package/dist/src/cli.js CHANGED
@@ -1,7 +1,7 @@
1
- import{C as e,T as t,_ as n,v as r}from"./sdk-contracts.js";import{_ as i}from"./location-coordinates.js";import{kr as a,l as o}from"./sdk-batch-runner.js";import{mt as s,pt as c}from"./prepare-kind.js";import{n as l,r as u}from"./agent-device-client.js";import{_ as d}from"./screenshot-result.js";import{i as f,r as p,t as m}from"./command-catalog.js";import{S as h,x as g}from"./registry.js";import{n as _}from"./command-metadata.js";import{A as v,I as ee,M as y,N as te,j as b,k as ne,x as re}from"./sdk-android-adb.js";import{n as ie}from"./version.js";import{n as ae,t as x}from"./internal/bin.js";import{i as oe,n as S,t as se}from"./command-schema.js";import{t as ce}from"./update-check.js";import{n as C,r as w,t as le}from"./cli-config.js";import{exitAfterFlush as T}from"./process-exit.js";import{D as ue,E as de,S as fe,T as pe,h as me,n as he,w as ge}from"./connection-runtime.js";import{t as _e}from"./cli-grammar.js";import{i as ve}from"./auth-session.js";import E from"node:fs";import{pathToFileURL as ye}from"node:url";const D=`open <app> --relaunch`,O={start:{command:`open`,example:D},restart:{command:`open`,example:D},touch:{command:`press`,example:`press`},input:{command:`fill`,example:`fill`},settext:{command:`fill`,example:`fill`},entertext:{command:`fill`,example:`fill`},screencap:{command:`screenshot`,example:`screenshot`},capture:{command:`screenshot`,example:`screenshot`},dismiss:{command:`keyboard`,example:`keyboard dismiss`},"get-text":{command:`get`,example:`get text`},gettext:{command:`get`,example:`get text`},get_text:{command:`get`,example:`get text`},"open-url":{command:`open`,example:`open <url>`},"close-session":{command:`close`,example:`close`}};function k(e){if(e.length<=2)return[];let t=f(),n=t.filter(t=>t.startsWith(e));if(n.length>0)return n.sort((e,t)=>e.length-t.length||e.localeCompare(t)).slice(0,3);let r=A(e),i=t.map(t=>({name:t,distance:j(e,t)})).filter(e=>e.distance<=r);if(i.length===0)return[];let a=Math.min(...i.map(e=>e.distance));return i.filter(e=>e.distance===a).sort((e,t)=>e.name.localeCompare(t.name)).slice(0,3).map(e=>e.name)}function A(e){return e.length<4?1:e.length<=6?2:3}function j(e,t){return e===t?0:e.startsWith(t)||t.startsWith(e)?Math.abs(e.length-t.length):M(e,t)}function M(e,t){let n=e.length+1,r=t.length+1,i=Array.from({length:n},()=>Array(r).fill(0));for(let e=0;e<n;e+=1)i[e][0]=e;for(let e=0;e<r;e+=1)i[0][e]=e;for(let a=1;a<n;a+=1)for(let n=1;n<r;n+=1){let r=e[a-1]===t[n-1]?0:1;i[a][n]=Math.min(i[a-1][n]+1,i[a][n-1]+1,i[a-1][n-1]+r)}return i[n-1][r-1]}function N(e){let t=e.toLowerCase(),n=O[t]?.example;if(n)return n;let r=k(t);if(r.length!==0)return r.length===1?r[0]:`one of: ${r.join(`, `)}`}const P=new Set([`--bundle-id`,`--bundleid`,`--bundle`,`--package`,`--package-name`,`--packagename`,`--app-id`,`--appid`,`--pkg`]),be=new Set([`--session-locked`,`--session-lock-conflicts`]);function xe(e){return P.has(e.toLowerCase())?`Unknown flag: ${e}. The app or bundle id is a positional argument, e.g. ${D}.`:be.has(e.toLowerCase())?`Unknown flag: ${e}. Use --session-lock reject|strip instead.`:e.toLowerCase()===i.cliToken?`Unknown flag: ${e}. ${i.migration.screenshot}. ${i.migration.record}.`:`Unknown flag: ${e}`}function F(e){let t={json:!1,help:!1,version:!1},r=null,i=null,a=[],o=[],s=[],c=!0;for(let o=0;o<e.length;o+=1){let l=e[o];if(c&&l===`--`){c=!1;continue}if(!c){r?a.push(l):(i=l,r=B(l));continue}if(Te(r)){a.push(l);continue}let u=l.startsWith(`--`),d=l.startsWith(`-`)&&l.length>1;if(!u&&!d){r?a.push(l):(i=l,r=B(l));continue}let[f,p]=u?I(l):[l,void 0];if(Ce(r,f))continue;let m=Ee(f,r);if(we(r,m)){a.push(l);continue}if(!m){if(je(r,a,l)){r?a.push(l):r=l;continue}throw new n(`INVALID_ARGS`,xe(f))}let h=ke(m,f,p,e[o+1]);h.consumeNext&&(o+=1);let g=t[m.key];if(m.multiple){let e=Array.isArray(g)?[...g,h.value]:g===void 0?[h.value]:[g,h.value];t[m.key]=e}else t[m.key]=h.value;s.push({key:m.key,token:f})}return Se(i,t),{command:r,positionals:a,flags:t,warnings:o,providedFlags:s}}function Se(e,t){if(e)for(let n of x(e)?.impliedFlags??[])t[n]=!0}function Ce(e,t){return t===`-c`&&(e===`snapshot`||e===`diff`)}function we(e,t){return e===`react-devtools`?t?!C(t.key,e):!0:!1}function Te(e){return e===`cdp`}function Ee(e,t){let n=h().filter(t=>t.names.includes(e));if(n.length<=1)return n[0]??g(e);if(t){let e=n.find(e=>C(e.key,t));if(e)return e}return g(e)}function De(e,t){let r=t?.strictFlags??!0,i=[...e.warnings],a=w({json:!1,help:!1,version:!1},t?.defaultFlags??{});if(w(a,e.flags),e.command&&!p(e.command)&&!a.help){let t=N(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=>!C(t.key,e.command));if(o.length>0){let t=o.map(e=>e.token),s=Pe(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&&(C(t,e.command)||delete a[t]);Oe(e),se(e.command,a);let s=Ne({command:e.command,positionals:e.positionals,flags:a,warnings:i});if(S(s.command,s.positionals),s.command===`batch`&&+!!a.steps+ +!!a.stepsFile!=1)throw new n(`INVALID_ARGS`,`batch requires exactly one step source: --steps or --steps-file.`);return s}function Oe(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 I(e){let t=e.indexOf(`=`);return t===-1?[e,void 0]:[e.slice(0,t),e.slice(t+1)]}function ke(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||R(i)?{value:!0,consumeNext:!1}:Ae(i)?{value:i,consumeNext:!0}:{value:!0,consumeNext:!1}}let a=r??i;if(a===void 0||r===void 0&&R(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 ${L(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 ${L(t)}: ${a}`);return{value:e.type===`int`?Math.floor(o):o,consumeNext:r===void 0}}function L(e){return e.replace(/^-+/,``)}function R(e){if(!e.startsWith(`-`)||e===`-`)return!1;let[t]=e.startsWith(`--`)?I(e):[e,void 0];return g(t)!==void 0}function Ae(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 je(e,t,n){if(!Me(n)||!e)return!1;let r=oe(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 Me(e){return/^-\d+(\.\d+)?$/.test(e)}function Ne(e){if(e.flags.help)return e;if(e.command===`snapshot`&&e.flags.snapshotDiff){let{snapshotDiff:t,...n}=e.flags;return{command:`diff`,positionals:[`snapshot`,...e.positionals],flags:n,warnings:e.warnings}}return e}function Pe(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 z(){let{buildUsageText:e}=await import(`./cli-help.js`);return e()}async function Fe(e){let{buildCommandUsageText:t}=await import(`./cli-help.js`);return t(B(e))}function B(e){if(e.toLowerCase()===`rotate`)throw new n(`INVALID_ARGS`,`rotate was renamed to orientation; for the two-finger gesture use: gesture rotate`);return ae(e)}function Ie(e){return _(e)}const Le={connect:async()=>(await import(`./connection.js`)).connectCommand,disconnect:async()=>(await import(`./connection.js`)).disconnectCommand,connection:async()=>(await import(`./connection.js`)).connectionCommand,auth:async()=>(await import(`./auth.js`)).authCommand,daemon:async()=>(await import(`./daemon.js`)).daemonCommand,device:async()=>(await import(`./device2.js`)).deviceCommand,proxy:async()=>(await import(`./proxy.js`)).proxyCommand,replay:async()=>(await import(`./replay.js`)).replayCommand,screenshot:async()=>(await import(`./screenshot.js`)).screenshotCommand,diff:async()=>(await import(`./screenshot.js`)).diffCommand};async function V(e){let t={...e.flags},n=Le[e.command];return n&&await(await n())({...e,flags:t})?!0:Ie(e.command)?await Re({...e,command:e.command,flags:t}):!1}async function Re(e){let{runGenericClientBackedCommand:t}=await import(`./generic.js`);return await t(e)}function ze(e){return[`exec`,`--yes`,`--package`,`agent-react-devtools@0.4.0`,`--`,`agent-react-devtools`,...e]}function Be(e){return e===`ios-instance`}function Ve(e){return e[0]===`wait`&&e.includes(`--connected`)}function He(e,t,n){n===0||!Ve(e)||!Be(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(`
2
- `))}function H(e,t,n){return n||(e.push(t),``)}function Ue(e){if(!e?.metroProxyBaseUrl||!pe(e.leaseBackend))return null;let t=[],r={serverBaseUrl:H(t,`metroProxyBaseUrl`,e.metroProxyBaseUrl),bearerToken:H(t,`metroBearerToken`,e.metroBearerToken),tenantId:H(t,`tenant`,e.tenant),runId:H(t,`runId`,e.runId),leaseId:H(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 We(e,t,n){let{flags:r}=t,i=Ue(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 ue({projectRoot:t.cwd??process.cwd(),stateDir:a,profileKey:s,consumerKey:o})}return await de({projectRoot:t.cwd??process.cwd(),stateDir:a,serverBaseUrl:i.serverBaseUrl,bearerToken:i.bearerToken,bridgeScope:{tenantId:i.tenantId,runId:i.runId,leaseId:i.leaseId},session:o,profileKey:s,consumerKey:o,env:t.env??process.env}),await n()}function Ge(e,t){if(e[0]!==`start`)return!1;let{flags:n}=t;return n?n.leaseProvider===`limrun`&&n.leaseBackend===`android-instance`&&n.metroProxyBaseUrl===void 0&&t.configureDirectPortReverse!==void 0:!1}async function Ke(e,t={}){let n=t.cwd??process.cwd(),r=t.env??process.env,i=await We(e,t,async()=>(Ge(e,t)&&await t.configureDirectPortReverse?.(),(await re(`npm`,ze(e),{cwd:n,env:r,allowFailure:!0,onStdoutChunk:e=>{process.stdout.write(e)},onStderrChunk:e=>{process.stderr.write(e)}})).exitCode));return He(e,t.flags,i),i}async function qe(e,t){switch(e[0]){case`setup`:{Je(t.flags.json);let{setupManagedAgentBrowser:e}=await import(`./agent-browser-tool.js`).then(e=>e.t),n=await e({stateDir:t.stateDir});return Ye(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 Xe(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 Je(e){e||process.stdout.write(`Setting up managed agent-browser backend (downloads if needed)...
3
- `)}function Ye(e,t){if(e){s({success:!0,data:{status:U(t)}});return}process.stdout.write(`Managed web backend installed.\nagent-browser available at: ${t.binaryPath}\n`)}function Xe(e,t,n){if(e){s({success:!0,data:Ze(n)});return}process.stdout.write(`${t}\n`)}function U(e){let{socketDir:t,...n}=e;return n}function Ze(e){let t=e.status;return Qe(t)?{...e,status:U(t)}:e}function Qe(e){return typeof e==`object`&&!!e&&`socketDir`in e&&`installDir`in e&&`binaryPath`in e}function $e(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 et(t)}function et(e){let t=!1,n=e.map((e,n)=>{if(nt(e))return rt(e,n+1);let r=it(e,n+1);return t=!0,tt(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.
4
- `),n}function tt(e){let t=_e(e.command,e.positionals??[],lt(e.flags));return{command:e.command,input:t,...e.runtime===void 0?{}:{runtime:e.runtime}}}function nt(e){return a(e)&&`input`in e&&!(`positionals`in e)&&!(`flags`in e)}function rt(e,t){let n=o(e.runtime,t),{runtime:r,...i}=e;return{...i,...n===void 0?{}:{runtime:n}}}function it(e,t){if(!a(e))throw new n(`INVALID_ARGS`,`Invalid batch step ${t}.`);ot(e,t);let r=at(e.command,t),i=st(e.positionals,t);S(r,i??[],`Batch step ${t}`);let s=ct(e.flags,t),c=o(e.runtime,t);return{command:r,...i===void 0?{}:{positionals:i},...s===void 0?{}:{flags:s},...c===void 0?{}:{runtime:c}}}function at(e,t){let r=typeof e==`string`?e.trim().toLowerCase():``;if(!r)throw new n(`INVALID_ARGS`,`Batch step ${t} requires command.`);if(_(r))return r;throw new n(`INVALID_ARGS`,`Batch step ${t} command is not available through command batch: ${String(e)}`)}function ot(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 st(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 ct(e,t){if(e!==void 0){if(!a(e))throw new n(`INVALID_ARGS`,`Batch step ${t} flags must be an object.`);return e}}function lt(e){return{json:!1,help:!1,version:!1,...e}}function W(e,t={}){let n=G(t),r={...e};return n.defaultPlatform&&r.platform===void 0&&(r.platform=n.defaultPlatform),r}function G(e){let t=e.env??process.env,n=e.inheritedPlatform??e.configuredPlatform??dt(t.AGENT_DEVICE_PLATFORM),r=pt(e.configuredSession??t.AGENT_DEVICE_SESSION);return{defaultPlatform:n,lockPolicy:ut(e.policyOverrides,t,r)}}function ut(e,t,n){let r=e?.sessionLock??ft(t.AGENT_DEVICE_SESSION_LOCK);if(r)return r;if(n)return`reject`}function dt(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 ft(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 pt(e){return typeof e==`string`&&e.trim().length>0}function mt(e,t){let n=F(e),r=t?.env??process.env,i=t?.cwd??process.cwd(),a=ht(n.command)?me({remoteConfig:n.flags.remoteConfig,cwd:i,env:r}):{},o=w(le({command:n.command,cwd:i,cliFlags:n.flags,env:r}),a);return{...De(n,{strictFlags:t?.strictFlags,defaultFlags:o}),providedFlags:n.providedFlags}}function ht(e){return e!==null}m.runtime;async function gt(e){let{command:t,request:n,transport:r,transportOptions:i}=e;return await r({...n,command:t},i)}const _t={sendToDaemon:u},vt=new Set([`launchUrl`,`kind`,`metroBearerToken`,`metroKind`,`metroListenHost`,`metroNoInstallDeps`,`metroNoReuseExisting`,`metroPreparePort`,`metroProbeTimeoutMs`,`metroProjectRoot`,`metroProxyBaseUrl`,`metroPublicBaseUrl`,`metroRuntimeFile`,`metroStartupTimeoutMs`,`metroStatusHost`]),yt=new Set([`connect`,`connection`,`close`,`daemon`,`device`,`disconnect`,`metro`,`proxy`,`session`]);async function K(e,t=_t){let n=ne(),r=ie(),i=kt(e),a=e.includes(`--json`);await ee({session:Vt(e)??process.env.AGENT_DEVICE_SESSION??`default`,requestId:n,command:e[0],debug:i},async()=>{let{parsed:o,command:s,positionals:c}=await bt(e,{version:r,jsonRequested:a,debugEnabled:i}),u=X(s,o.providedFlags),d=await xt(o,{command:s,positionals:c,requestId:n,debugOutputEnabled:u});q(d.effectiveFlags);let f=null;try{if(s===`react-devtools`){await T(await St(d,t));return}if(s===`web`){await T(await qe(c,{flags:d.effectiveFlags,stateDir:d.daemonPaths.baseDir}));return}if(ce({command:s,currentVersion:r,stateDir:d.daemonPaths.baseDir,flags:d.effectiveFlags}),await Ct(d,t),q(d.effectiveFlags),s===`cdp`){await T(await ge(c,{flags:d.effectiveFlags,runtime:d.resolvedRuntime,cwd:process.cwd(),env:process.env}));return}f=wt(d);let e=await Tt(d);await Et(d,l(J(d),{transport:Bt({command:s,flags:d.effectiveFlags,replayTestReporterRuntime:e,transport:t.sendToDaemon})}),e)}catch(e){await Dt(e,d,f)}finally{f&&f()}})}function q(e){e.daemonAuthToken&&te(e.daemonAuthToken)}async function bt(t,r){let i;try{i=mt(t,{cwd:process.cwd(),env:process.env})}catch(t){v({level:`error`,phase:`cli_parse_failed`,data:{error:t instanceof Error?t.message:String(t)}});let n=e(t,{diagnosticId:y().diagnosticId,logPath:b({force:!0})??void 0});return r.jsonRequested?s({success:!1,error:n}):c(n,{showDetails:r.debugEnabled}),T(1)}for(let e of i.warnings)process.stderr.write(`Warning: ${e}\n`);if(i.flags.version)return process.stdout.write(`${r.version}\n`),T(0);let a=i.command===`help`,o=i.flags.help;if(a||o){if(a&&i.positionals.length>1)return c(new n(`INVALID_ARGS`,`help accepts at most one command.`)),T(1);let e=a?i.positionals[0]:i.command;if(!e)return process.stdout.write(`${await z()}\n`),T(0);let t=await Fe(e);return t?(process.stdout.write(t),T(0)):(c(new n(`INVALID_ARGS`,At(e))),process.stdout.write(`${await z()}\n`),T(1))}return i.command?{parsed:i,command:i.command,positionals:i.positionals}:(process.stdout.write(`${await z()}\n`),T(1))}async function xt(t,n){let i=new Set(t.providedFlags.map(e=>e.key));try{let e=G({policyOverrides:t.flags,configuredPlatform:t.flags.platform,configuredSession:t.flags.session}),r=e.lockPolicy?{...t.flags}:W(t.flags,{policyOverrides:t.flags,configuredPlatform:t.flags.platform,configuredSession:t.flags.session}),a=d(r.stateDir),o=r.session??`default`,s=Pt({command:n.command,explicitFlagKeys:i,stateDir:a.baseDir,session:o,remoteConfig:r.remoteConfig,hasResolvedSession:r.session!==void 0}),c=s?Rt(r,s.flags,i):r;return{...n,binding:e,flags:r,daemonPaths:a,sessionName:o,connectionDefaults:s,explicitFlagKeys:i,effectiveFlags:c,resolvedRuntime:s?.runtime,connectionMetadata:s?.connection,parsedBatchSteps:void 0}}catch(i){let a=e(r(i),{diagnosticId:y().diagnosticId,logPath:b({force:!0})??void 0});return t.flags.json?s({success:!1,error:a}):c(a,{showDetails:n.debugOutputEnabled}),T(1)}}async function St(e,n){let{daemonAuthToken:r,...i}=e.effectiveFlags;return await Ke(e.positionals,{flags:{...i,leaseProvider:e.connectionDefaults?.connection?.leaseProvider},stateDir:e.daemonPaths.baseDir,session:e.effectiveFlags.session??e.sessionName,cwd:process.cwd(),env:process.env,configureDirectPortReverse:async()=>{let a=await gt({route:`react-devtools`,command:m.runtime,request:{positionals:[`port-reverse`],flags:{...i,leaseProvider:e.connectionDefaults?.connection?.leaseProvider,devicePort:8097,hostPort:8097,portReverseName:`react-devtools`},session:e.effectiveFlags.session??e.sessionName},transport:n.sendToDaemon,transportOptions:{authToken:r}});a.ok||t(a.error)}})}async function Ct(e,t){if(e.command===`batch`){if(e.positionals.length>0)throw new n(`INVALID_ARGS`,`batch does not accept positional arguments.`);e.parsedBatchSteps=Mt(e.flags)}if(Ft(e.command)&&(e.effectiveFlags=(await ve({command:e.command,flags:e.effectiveFlags,stateDir:e.daemonPaths.baseDir,env:process.env})).flags),e.effectiveFlags.remoteConfig&&Z(e.command)){let n=l(J(e),{transport:Q(t.sendToDaemon)}),r=await he({command:e.command,flags:e.effectiveFlags,client:n,runtime:e.resolvedRuntime,positionals:e.positionals,batchSteps:e.parsedBatchSteps,forceRuntimePrepare:zt(e.explicitFlagKeys)});e.effectiveFlags=r.flags,e.resolvedRuntime=r.runtime,e.connectionMetadata=r.connection}It({command:e.command,flags:e.effectiveFlags,runtime:e.resolvedRuntime,explicitFlagKeys:e.explicitFlagKeys,hadConnectionDefaults:!!e.connectionDefaults})&&process.stderr.write(`Warning: open is using explicit remote daemon or tenant flags without saved Metro runtime hints. React Native apps may launch without bundle/runtime hints; prefer connect --remote-config <path> first or pass --remote-config <path> on this command.
5
- `)}function J(e){let t=e.effectiveFlags,n=e.connectionMetadata;return{session:t.session,requestId:e.requestId,stateDir:t.stateDir,daemonBaseUrl:t.daemonBaseUrl,daemonAuthToken:t.daemonAuthToken,daemonTransport:t.daemonTransport,daemonServerMode:t.daemonServerMode,tenant:t.tenant,sessionIsolation:t.sessionIsolation,runId:t.runId,leaseId:t.leaseId,leaseBackend:t.leaseBackend,leaseProvider:n?.leaseProvider,clientId:n?.clientId,deviceKey:n?.deviceKey,providerApp:t.providerApp,providerOsVersion:t.providerOsVersion,providerProject:t.providerProject,providerBuild:t.providerBuild,providerSessionName:t.providerSessionName,providerDeviceOrientation:t.providerDeviceOrientation,providerGeoLocation:t.providerGeoLocation,providerTimezone:t.providerTimezone,providerLanguage:t.providerLanguage,providerLocale:t.providerLocale,providerNetworkProfile:t.providerNetworkProfile,providerCustomNetwork:t.providerCustomNetwork,providerNoResignApp:t.providerNoResignApp,awsProjectArn:t.awsProjectArn,awsDeviceArn:t.awsDeviceArn,awsAppArn:t.awsAppArn,awsRegion:t.awsRegion,awsInteractionMode:t.awsInteractionMode,runtime:e.resolvedRuntime,lockPolicy:e.binding.lockPolicy,lockPlatform:e.binding.defaultPlatform,cwd:process.cwd(),debug:e.debugOutputEnabled,cost:t.cost,responseLevel:t.responseLevel}}function wt(e){let t=e.effectiveFlags.daemonBaseUrl;return e.debugOutputEnabled&&!e.effectiveFlags.json&&!t?Ht(e.daemonPaths.logPath):null}async function Tt(e){if(e.command!==`test`)return;let{createReplayTestReporterRuntime:t}=await import(`./reporting.js`);return t({debug:e.debugOutputEnabled,verbose:e.effectiveFlags.verbose,json:e.effectiveFlags.json,reporter:e.effectiveFlags.reporter,reportJunit:e.effectiveFlags.reportJunit})}async function Et(e,t,r){let{command:i,positionals:a,effectiveFlags:o}=e;if(i===`batch`){if(!e.parsedBatchSteps)throw new n(`INVALID_ARGS`,`batch requires --steps or --steps-file.`);let s=e.parsedBatchSteps.map((t,n)=>({...t,input:e.binding.lockPolicy&&e.flags.platform===void 0?{...t.input}:W(t.input,{policyOverrides:o,configuredPlatform:o.platform,configuredSession:o.session,inheritedPlatform:o.platform})}));if(await V({command:i,positionals:a,flags:{...o,batchSteps:s},client:t,debug:e.debugOutputEnabled,replayTestReporterRuntime:r}))return}else if(i===`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 V({command:i,positionals:a,flags:o,client:t,debug:e.debugOutputEnabled,replayTestReporterRuntime:r}))return;throw new n(`INVALID_ARGS`,jt(i))}async function Dt(t,n,i){let a=r(t),o=e(a,{diagnosticId:y().diagnosticId,logPath:b({force:!0})??void 0});if(n.command===`close`&&Nt(a)){n.effectiveFlags.json&&s({success:!0,data:{closed:`session`,source:`no-daemon`}});return}n.effectiveFlags.json?s({success:!1,error:o}):(c(o,{showDetails:n.debugOutputEnabled}),n.debugOutputEnabled&&Ot(n.daemonPaths.logPath)),i&&i(),await T(1)}const Y=64e3;function Ot(e){try{if(E.existsSync(e)){let t=E.readFileSync(e,`utf8`).split(`
6
- `),n=t.slice(Math.max(0,t.length-200)).join(`
7
- `);n.length>Y&&(n=n.slice(n.length-Y)),n.trim().length>0&&process.stderr.write(`\n[daemon log]\n${n}\n`)}}catch{}}function kt(e){try{let t=F(e);return X(t.command??``,t.providedFlags)}catch{return e.includes(`--debug`)||e.includes(`-v`)||e.includes(`--verbose`)}}function At(e){let t=N(e);return t?`Unknown command: ${e}. Did you mean ${t}?`:`Unknown command: ${e}`}function jt(e){return p(e)?(v({level:`error`,phase:`cli_known_command_unhandled`,data:{command:e}}),`Command is registered but no CLI handler accepted it: ${e}`):`Unknown command: ${e}`}function X(e,t){return t.some(t=>t.key===`verbose`&&(t.token===`--debug`||t.token===`-v`||e!==`test`))}function Mt(e){let t=``;if(e.steps)t=e.steps;else if(e.stepsFile)try{t=E.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 $e(t)}function Nt(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 Pt(e){return e.command===`connect`||e.command===`connection`||e.command===`daemon`||e.command===`proxy`?null:fe({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 Z(e){return!yt.has(e)}function Ft(e){return e!==`auth`&&e!==`connection`&&e!==`daemon`&&e!==`device`&&e!==`proxy`}function It(e){return e.command!==`open`||e.runtime||e.flags.bundleUrl||e.flags.metroHost||e.flags.metroPort||e.flags.remoteConfig||e.hadConnectionDefaults?!1:Lt(e.explicitFlagKeys)}function Lt(e){return e.has(`daemonBaseUrl`)||e.has(`daemonTransport`)||e.has(`tenant`)||e.has(`sessionIsolation`)||e.has(`runId`)||e.has(`leaseId`)||e.has(`leaseBackend`)}function Rt(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 zt(e){for(let t of vt)if(e.has(t))return!0;return!1}function Bt(e){let{command:t,flags:n,replayTestReporterRuntime:r,transport:i}=e;return n.json?Q(i):async(e,n)=>{let a=t===`test`&&r?{...n,onProgress:r.onProgress}:n;return await $(i,{...e,meta:{...e.meta,requestProgress:t===`test`?`replay-test`:`command`}},a)}}function Q(e){return async(t,n)=>await $(e,t,n)}async function $(e,t,n){return await e(t,n)}function Vt(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&&K(process.argv.slice(2)).catch(async t=>{c(e(r(t)),{showDetails:!0}),await T(1)});function Ht(e){try{let t=E.existsSync(e)?E.statSync(e).size:0,n=!1,r=setInterval(()=>{if(!n&&E.existsSync(e))try{let n=E.statSync(e);if(n.size<t&&(t=0),n.size<=t)return;let r=E.openSync(e,`r`);try{let e=Buffer.alloc(n.size-t);E.readSync(r,e,0,e.length,t),t=n.size,e.length>0&&process.stdout.write(e.toString(`utf8`))}finally{E.closeSync(r)}}catch{}},200);return()=>{n=!0,clearInterval(r)}}catch{return null}}export{K as runCli};
1
+ import{E as e,_ as t,k as n,v as r}from"./sdk-contracts.js";import{_ as i}from"./location-coordinates.js";import{Lr as a,l as o}from"./sdk-batch-runner.js";import{St as s,xt as c}from"./script-source-bundle.js";import{n as l,r as u}from"./agent-device-client.js";import{C as d,_ as f}from"./screenshot-result.js";import{i as p,r as m,t as h}from"./command-catalog.js";import{S as g,x as _}from"./registry.js";import{n as v}from"./command-metadata.js";import{A as y,I as ee,M as b,N as x,j as S,k as te,x as ne}from"./sdk-android-adb.js";import{n as re}from"./version.js";import{i as ie,n as C,t as ae}from"./command-schema.js";import{n as w,r as T,t as oe}from"./cli-config.js";import{n as se,t as ce}from"./internal/bin.js";import{t as le}from"./update-check.js";import{exitAfterFlush as E}from"./process-exit.js";import{D as ue,E as de,S as fe,T as pe,h as me,n as he,w as ge}from"./connection-runtime.js";import{t as _e}from"./cli-grammar.js";import{i as ve}from"./auth-session.js";import D from"node:fs";import{pathToFileURL as ye}from"node:url";const O=`open <app> --relaunch`,be={start:{command:`open`,example:O},restart:{command:`open`,example:O},touch:{command:`press`,example:`press`},input:{command:`fill`,example:`fill`},settext:{command:`fill`,example:`fill`},entertext:{command:`fill`,example:`fill`},screencap:{command:`screenshot`,example:`screenshot`},capture:{command:`screenshot`,example:`screenshot`},dismiss:{command:`keyboard`,example:`keyboard dismiss`},"get-text":{command:`get`,example:`get text`},gettext:{command:`get`,example:`get text`},get_text:{command:`get`,example:`get text`},"open-url":{command:`open`,example:`open <url>`},"close-session":{command:`close`,example:`close`}};function k(e){if(e.length<=2)return[];let t=p(),n=t.filter(t=>t.startsWith(e));if(n.length>0)return n.sort((e,t)=>e.length-t.length||e.localeCompare(t)).slice(0,3);let r=A(e),i=t.map(t=>({name:t,distance:j(e,t)})).filter(e=>e.distance<=r);if(i.length===0)return[];let a=Math.min(...i.map(e=>e.distance));return i.filter(e=>e.distance===a).sort((e,t)=>e.name.localeCompare(t.name)).slice(0,3).map(e=>e.name)}function A(e){return e.length<4?1:e.length<=6?2:3}function j(e,t){return e===t?0:e.startsWith(t)||t.startsWith(e)?Math.abs(e.length-t.length):M(e,t)}function M(e,t){let n=e.length+1,r=t.length+1,i=Array.from({length:n},()=>Array(r).fill(0));for(let e=0;e<n;e+=1)i[e][0]=e;for(let e=0;e<r;e+=1)i[0][e]=e;for(let a=1;a<n;a+=1)for(let n=1;n<r;n+=1){let r=e[a-1]===t[n-1]?0:1;i[a][n]=Math.min(i[a-1][n]+1,i[a][n-1]+1,i[a-1][n-1]+r)}return i[n-1][r-1]}function N(e){let t=e.toLowerCase(),n=be[t]?.example;if(n)return n;let r=k(t);if(r.length!==0)return r.length===1?r[0]:`one of: ${r.join(`, `)}`}const xe=new Set([`--bundle-id`,`--bundleid`,`--bundle`,`--package`,`--package-name`,`--packagename`,`--app-id`,`--appid`,`--pkg`]),Se=new Set([`--session-locked`,`--session-lock-conflicts`]);function Ce(e){return xe.has(e.toLowerCase())?`Unknown flag: ${e}. The app or bundle id is a positional argument, e.g. ${O}.`:Se.has(e.toLowerCase())?`Unknown flag: ${e}. Use --session-lock reject|strip instead.`:e.toLowerCase()===i.cliToken?`Unknown flag: ${e}. ${i.migration.screenshot}. ${i.migration.record}.`:`Unknown flag: ${e}`}function P(e){let n={json:!1,help:!1,version:!1},r=null,i=null,a=[],o=[],s=[],c=!0;for(let o=0;o<e.length;o+=1){let l=e[o];if(c&&l===`--`){c=!1;continue}if(!c){r?a.push(l):(i=l,r=z(l));continue}if(De(r)){a.push(l);continue}let u=l.startsWith(`--`),d=l.startsWith(`-`)&&l.length>1;if(!u&&!d){r?a.push(l):(i=l,r=z(l));continue}let[f,p]=u?F(l):[l,void 0];if(Te(r,f))continue;let m=Oe(f,r);if(Ee(r,m)){a.push(l);continue}if(!m){if(Ne(r,a,l)){r?a.push(l):r=l;continue}throw new t(`INVALID_ARGS`,Ce(f))}let h=je(m,f,p,e[o+1]);h.consumeNext&&(o+=1);let g=n[m.key];if(m.multiple){let e=Array.isArray(g)?[...g,h.value]:g===void 0?[h.value]:[g,h.value];n[m.key]=e}else n[m.key]=h.value;s.push({key:m.key,token:f})}return we(i,n),{command:r,positionals:a,flags:n,warnings:o,providedFlags:s}}function we(e,t){if(e)for(let n of ce(e)?.impliedFlags??[])t[n]=!0}function Te(e,t){return t===`-c`&&(e===`snapshot`||e===`diff`)}function Ee(e,t){return e===`react-devtools`?t?!T(t.key,e):!0:!1}function De(e){return e===`cdp`}function Oe(e,t){let n=g().filter(t=>t.names.includes(e));if(n.length<=1)return n[0]??_(e);if(t){let e=n.find(e=>T(e.key,t));if(e)return e}return _(e)}function ke(e,n){let r=n?.strictFlags??!0,i=[...e.warnings],a=w({json:!1,help:!1,version:!1},n?.defaultFlags??{});if(w(a,e.flags),e.command&&!m(e.command)&&!a.help){let n=N(e.command);throw new t(`INVALID_ARGS`,n?`Unknown command: ${e.command}. Did you mean ${n}?`:`Unknown command: ${e.command}`)}let o=e.providedFlags.filter(t=>!T(t.key,e.command));if(o.length>0){let n=o.map(e=>e.token),s=Ie(e.command,n);if(r)throw new t(`INVALID_ARGS`,s);i.push(s);for(let e of o)delete a[e.key]}for(let t of Object.keys(a))a[t]!==void 0&&(T(t,e.command)||delete a[t]);Ae(e),ae(e.command,a);let s=Fe({command:e.command,positionals:e.positionals,flags:a,warnings:i});if(C(s.command,s.positionals),s.command===`batch`&&+!!a.steps+ +!!a.stepsFile!=1)throw new t(`INVALID_ARGS`,`batch requires exactly one step source: --steps or --steps-file.`);return s}function Ae(e){if(e.command!==`back`)return;let n=e.providedFlags.filter(e=>e.key===`backMode`);if(!(new Set(n.map(e=>e.token)).size<=1))throw new t(`INVALID_ARGS`,`back accepts only one explicit mode flag: use either --in-app or --system.`)}function F(e){let t=e.indexOf(`=`);return t===-1?[e,void 0]:[e.slice(0,t),e.slice(t+1)]}function je(e,n,r,i){if(e.setValue!==void 0){if(r!==void 0)throw new t(`INVALID_ARGS`,`Flag ${n} does not take a value.`);return{value:e.setValue,consumeNext:!1}}if(e.type===`boolean`){if(r!==void 0)throw new t(`INVALID_ARGS`,`Flag ${n} does not take a value.`);return{value:!0,consumeNext:!1}}if(e.type===`booleanOrString`){if(r!==void 0){if(r.trim().length===0)throw new t(`INVALID_ARGS`,`Flag ${n} requires a non-empty value when provided.`);return{value:r,consumeNext:!1}}return i===void 0||L(i)?{value:!0,consumeNext:!1}:Me(i)?{value:i,consumeNext:!0}:{value:!0,consumeNext:!1}}let a=r??i;if(a===void 0||r===void 0&&L(a))throw new t(`INVALID_ARGS`,`Flag ${n} requires a value.`);if(e.type===`string`)return{value:a,consumeNext:r===void 0};if(e.type===`enum`){if(!e.enumValues?.includes(a))throw new t(`INVALID_ARGS`,`Invalid ${I(n)}: ${a}`);return{value:a,consumeNext:r===void 0}}let o=Number(a);if(!Number.isFinite(o)||typeof e.min==`number`&&o<e.min||typeof e.max==`number`&&o>e.max)throw new t(`INVALID_ARGS`,`Invalid ${I(n)}: ${a}`);return{value:e.type===`int`?Math.floor(o):o,consumeNext:r===void 0}}function I(e){return e.replace(/^-+/,``)}function L(e){if(!e.startsWith(`-`)||e===`-`)return!1;let[t]=e.startsWith(`--`)?F(e):[e,void 0];return _(t)!==void 0}function Me(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 Ne(e,t,n){if(!Pe(n)||!e)return!1;let r=ie(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 Pe(e){return/^-\d+(\.\d+)?$/.test(e)}function Fe(e){if(e.flags.help)return e;if(e.command===`snapshot`&&e.flags.snapshotDiff){let{snapshotDiff:t,...n}=e.flags;return{command:`diff`,positionals:[`snapshot`,...e.positionals],flags:n,warnings:e.warnings}}return e}function Ie(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 R(){let{buildUsageText:e}=await import(`./cli-help.js`).then(e=>e.r);return e()}async function Le(e){let{buildCommandUsageText:t}=await import(`./cli-help.js`).then(e=>e.r);return t(z(e))}function z(e){if(e.toLowerCase()===`rotate`)throw new t(`INVALID_ARGS`,`rotate was renamed to orientation; for the two-finger gesture use: gesture rotate`);return se(e)}function Re(e){return v(e)}const ze={connect:async()=>(await import(`./connection.js`)).connectCommand,disconnect:async()=>(await import(`./connection.js`)).disconnectCommand,connection:async()=>(await import(`./connection.js`)).connectionCommand,auth:async()=>(await import(`./auth.js`)).authCommand,daemon:async()=>(await import(`./daemon.js`)).daemonCommand,device:async()=>(await import(`./device2.js`)).deviceCommand,proxy:async()=>(await import(`./proxy.js`)).proxyCommand,replay:async()=>(await import(`./replay.js`)).replayCommand,screenshot:async()=>(await import(`./screenshot.js`)).screenshotCommand,diff:async()=>(await import(`./screenshot.js`)).diffCommand};async function B(e){let t={...e.flags},n=ze[e.command];return n&&await(await n())({...e,flags:t})?!0:Re(e.command)?await Be({...e,command:e.command,flags:t}):!1}async function Be(e){let{runGenericClientBackedCommand:t}=await import(`./generic.js`);return await t(e)}function Ve(e){return[`exec`,`--yes`,`--package`,`agent-react-devtools@0.4.0`,`--`,`agent-react-devtools`,...e]}function He(e){return e===`ios-instance`}function Ue(e){return e[0]===`wait`&&e.includes(`--connected`)}function We(e,t,n){n===0||!Ue(e)||!He(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(`
2
+ `))}function V(e,t,n){return n||(e.push(t),``)}function Ge(e){if(!e?.metroProxyBaseUrl||!pe(e.leaseBackend))return null;let n=[],r={serverBaseUrl:V(n,`metroProxyBaseUrl`,e.metroProxyBaseUrl),bearerToken:V(n,`metroBearerToken`,e.metroBearerToken),tenantId:V(n,`tenant`,e.tenant),runId:V(n,`runId`,e.runId),leaseId:V(n,`leaseId`,e.leaseId)};if(n.length>0)throw new t(`INVALID_ARGS`,`react-devtools remote bridge requires ${n.join(`, `)}.`,{missing:n});return r}async function Ke(e,t,n){let{flags:r}=t,i=Ge(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 ue({projectRoot:t.cwd??process.cwd(),stateDir:a,profileKey:s,consumerKey:o})}return await de({projectRoot:t.cwd??process.cwd(),stateDir:a,serverBaseUrl:i.serverBaseUrl,bearerToken:i.bearerToken,bridgeScope:{tenantId:i.tenantId,runId:i.runId,leaseId:i.leaseId},session:o,profileKey:s,consumerKey:o,env:t.env??process.env}),await n()}function qe(e,t){if(e[0]!==`start`)return!1;let{flags:n}=t;return n?n.leaseProvider===`limrun`&&n.leaseBackend===`android-instance`&&n.metroProxyBaseUrl===void 0&&t.configureDirectPortReverse!==void 0:!1}async function Je(e,t={}){let n=t.cwd??process.cwd(),r=t.env??process.env,i=await Ke(e,t,async()=>(qe(e,t)&&await t.configureDirectPortReverse?.(),(await ne(`npm`,Ve(e),{cwd:n,env:r,allowFailure:!0,onStdoutChunk:e=>{process.stdout.write(e)},onStderrChunk:e=>{process.stderr.write(e)}})).exitCode));return We(e,t.flags,i),i}async function Ye(e,n){switch(e[0]){case`setup`:{Xe(n.flags.json);let{setupManagedAgentBrowser:e}=await import(`./agent-browser-tool.js`).then(e=>e.t),t=await e({stateDir:n.stateDir});return Ze(n.flags.json,t),0}case`doctor`:{let{doctorManagedAgentBrowser:e}=await import(`./agent-browser-tool.js`).then(e=>e.t),t=await e({stateDir:n.stateDir});return Qe(n.flags.json,t.exitCode===0?`Web backend is healthy.`:`Web backend doctor reported issues.`,t),t.exitCode}default:throw new t(`INVALID_ARGS`,`web requires setup or doctor`)}}function Xe(e){e||process.stdout.write(`Setting up managed agent-browser backend (downloads if needed)...
3
+ `)}function Ze(e,t){if(e){s({success:!0,data:{status:H(t)}});return}process.stdout.write(`Managed web backend installed.\nagent-browser available at: ${t.binaryPath}\n`)}function Qe(e,t,n){if(e){s({success:!0,data:$e(n)});return}process.stdout.write(`${t}\n`)}function H(e){let{socketDir:t,...n}=e;return n}function $e(e){let t=e.status;return et(t)?{...e,status:H(t)}:e}function et(e){return typeof e==`object`&&!!e&&`socketDir`in e&&`installDir`in e&&`binaryPath`in e}function tt(e){let n;try{n=JSON.parse(e)}catch{throw new t(`INVALID_ARGS`,`Batch steps must be valid JSON.`)}if(!Array.isArray(n)||n.length===0)throw new t(`INVALID_ARGS`,`Batch steps must be a non-empty JSON array.`);return nt(n)}function nt(e){let t=!1,n=e.map((e,n)=>{if(it(e))return at(e,n+1);let r=ot(e,n+1);return t=!0,rt(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.
4
+ `),n}function rt(e){let t=_e(e.command,e.positionals??[],dt(e.flags));return{command:e.command,input:t,...e.runtime===void 0?{}:{runtime:e.runtime}}}function it(e){return a(e)&&`input`in e&&!(`positionals`in e)&&!(`flags`in e)}function at(e,t){let n=o(e.runtime,t),{runtime:r,...i}=e;return{...i,...n===void 0?{}:{runtime:n}}}function ot(e,n){if(!a(e))throw new t(`INVALID_ARGS`,`Invalid batch step ${n}.`);ct(e,n);let r=st(e.command,n),i=lt(e.positionals,n);C(r,i??[],`Batch step ${n}`);let s=ut(e.flags,n),c=o(e.runtime,n);return{command:r,...i===void 0?{}:{positionals:i},...s===void 0?{}:{flags:s},...c===void 0?{}:{runtime:c}}}function st(e,n){let r=typeof e==`string`?e.trim().toLowerCase():``;if(!r)throw new t(`INVALID_ARGS`,`Batch step ${n} requires command.`);if(v(r))return r;throw new t(`INVALID_ARGS`,`Batch step ${n} command is not available through command batch: ${String(e)}`)}function ct(e,n){let r=Object.keys(e).filter(e=>![`command`,`positionals`,`flags`,`runtime`].includes(e));if(r.length>0)throw new t(`INVALID_ARGS`,`Batch step ${n} has unknown legacy field(s): ${r.join(`, `)}.`)}function lt(e,n){if(e!==void 0){if(!Array.isArray(e)||e.some(e=>typeof e!=`string`))throw new t(`INVALID_ARGS`,`Batch step ${n} positionals must contain only strings.`);return e}}function ut(e,n){if(e!==void 0){if(!a(e))throw new t(`INVALID_ARGS`,`Batch step ${n} flags must be an object.`);return e}}function dt(e){return{json:!1,help:!1,version:!1,...e}}function U(e,t={}){let n=W(t),r={...e};return n.defaultPlatform&&r.platform===void 0&&(r.platform=n.defaultPlatform),r}function W(e){let t=e.env??process.env,n=e.inheritedPlatform??e.configuredPlatform??pt(t.AGENT_DEVICE_PLATFORM),r=ht(e.configuredSession??t.AGENT_DEVICE_SESSION);return{defaultPlatform:n,lockPolicy:ft(e.policyOverrides,t,r)}}function ft(e,t,n){let r=e?.sessionLock??mt(t.AGENT_DEVICE_SESSION_LOCK);if(r)return r;if(n)return`reject`}function pt(e){if(e===void 0)return;let n=e.trim().toLowerCase();if(n){if(n===`ios`||n===`android`||n===`apple`)return n;throw new t(`INVALID_ARGS`,`Invalid AGENT_DEVICE_PLATFORM: ${e}. Use ios, android, or apple.`)}}function mt(e){if(e===void 0)return;let n=e.trim().toLowerCase();if(n){if(n===`reject`||n===`strip`)return n;throw new t(`INVALID_ARGS`,`Invalid session lock mode: ${e}. Use reject or strip.`)}}function ht(e){return typeof e==`string`&&e.trim().length>0}function gt(e,t){let n=P(e),r=t?.env??process.env,i=t?.cwd??process.cwd(),a=_t(n.command)?me({remoteConfig:n.flags.remoteConfig,cwd:i,env:r}):{},o=w(oe({command:n.command,cwd:i,cliFlags:n.flags,env:r}),a);return{...ke(n,{strictFlags:t?.strictFlags,defaultFlags:o}),providedFlags:n.providedFlags}}function _t(e){return e!==null}h.runtime;async function vt(e){let{command:t,request:n,transport:r,transportOptions:i}=e;return await r({...n,command:t},i)}const yt={sendToDaemon:u},bt=new Set([`launchUrl`,`kind`,`metroBearerToken`,`metroKind`,`metroListenHost`,`metroNoInstallDeps`,`metroNoReuseExisting`,`metroPreparePort`,`metroProbeTimeoutMs`,`metroProjectRoot`,`metroProxyBaseUrl`,`metroPublicBaseUrl`,`metroRuntimeFile`,`metroStartupTimeoutMs`,`metroStatusHost`]),xt=new Set([`connect`,`connection`,`close`,`daemon`,`device`,`disconnect`,`metro`,`proxy`,`session`]);async function G(e,t=yt){let n=te(),r=re(),i=jt(e),a=e.includes(`--json`);await ee({session:Ut(e)??process.env.AGENT_DEVICE_SESSION??`default`,requestId:n,command:e[0],debug:i},async()=>{let{parsed:o,command:s,positionals:c}=await St(e,{version:r,jsonRequested:a,debugEnabled:i}),u=X(s,o.providedFlags),d=await Ct(o,{command:s,positionals:c,requestId:n,debugOutputEnabled:u});K(d.effectiveFlags);let f=null;try{if(s===`react-devtools`){await E(await wt(d,t));return}if(s===`web`){await E(await Ye(c,{flags:d.effectiveFlags,stateDir:d.daemonPaths.baseDir}));return}if(le({command:s,currentVersion:r,stateDir:d.daemonPaths.baseDir,flags:d.effectiveFlags}),await Tt(d,t),K(d.effectiveFlags),s===`cdp`){await E(await ge(c,{flags:d.effectiveFlags,runtime:d.resolvedRuntime,cwd:process.cwd(),env:process.env}));return}f=Et(d);let e=await Dt(d);await Ot(d,l(q(d),{transport:Ht({command:s,flags:d.effectiveFlags,replayTestReporterRuntime:e,transport:t.sendToDaemon})}),e)}catch(e){await kt(e,d,f)}finally{f&&f()}})}function K(e){e.daemonAuthToken&&x(e.daemonAuthToken)}async function St(n,r){let i;try{i=gt(n,{cwd:process.cwd(),env:process.env})}catch(t){y({level:`error`,phase:`cli_parse_failed`,data:{error:t instanceof Error?t.message:String(t)}});let n=e(t,{diagnosticId:b().diagnosticId,logPath:S({force:!0})?.path});return r.jsonRequested?s({success:!1,error:n}):c(n,{showDetails:r.debugEnabled}),E(1)}for(let e of i.warnings)process.stderr.write(`Warning: ${e}\n`);if(i.flags.version)return process.stdout.write(`${r.version}\n`),E(0);let a=i.command===`help`,o=i.flags.help;if(a||o){if(a&&i.positionals.length>1)return c(new t(`INVALID_ARGS`,`help accepts at most one command.`)),E(1);let e=a?i.positionals[0]:i.command;if(!e)return process.stdout.write(`${await R()}\n`),E(0);let n=await Le(e);return n?(process.stdout.write(n),E(0)):(c(new t(`INVALID_ARGS`,Mt(e))),process.stdout.write(`${await R()}\n`),E(1))}return i.command?{parsed:i,command:i.command,positionals:i.positionals}:(process.stdout.write(`${await R()}\n`),E(1))}async function Ct(t,n){let i=new Set(t.providedFlags.map(e=>e.key));try{let e=W({policyOverrides:t.flags,configuredPlatform:t.flags.platform,configuredSession:t.flags.session}),r=e.lockPolicy?{...t.flags}:U(t.flags,{policyOverrides:t.flags,configuredPlatform:t.flags.platform,configuredSession:t.flags.session}),a=f(r.stateDir),o=r.session??`default`,s=Z({command:n.command,explicitFlagKeys:i,stateDir:a.baseDir,session:o,remoteConfig:r.remoteConfig,hasResolvedSession:r.session!==void 0}),c=s?Bt(r,s.flags,i):r;return{...n,binding:e,flags:r,daemonPaths:a,sessionName:o,connectionDefaults:s,explicitFlagKeys:i,effectiveFlags:c,resolvedRuntime:s?.runtime,connectionMetadata:s?.connection,parsedBatchSteps:void 0}}catch(i){let a=e(r(i),{diagnosticId:b().diagnosticId,logPath:S({force:!0})?.path});return t.flags.json?s({success:!1,error:a}):c(a,{showDetails:n.debugOutputEnabled}),E(1)}}async function wt(e,t){let{daemonAuthToken:r,...i}=e.effectiveFlags;return await Je(e.positionals,{flags:{...i,leaseProvider:e.connectionDefaults?.connection?.leaseProvider},stateDir:e.daemonPaths.baseDir,session:e.effectiveFlags.session??e.sessionName,cwd:process.cwd(),env:process.env,configureDirectPortReverse:async()=>{let a=await vt({route:`react-devtools`,command:h.runtime,request:{positionals:[`port-reverse`],flags:{...i,leaseProvider:e.connectionDefaults?.connection?.leaseProvider,devicePort:8097,hostPort:8097,portReverseName:`react-devtools`},session:e.effectiveFlags.session??e.sessionName},transport:t.sendToDaemon,transportOptions:{authToken:r}});a.ok||n(a.error)}})}async function Tt(e,n){if(e.command===`batch`){if(e.positionals.length>0)throw new t(`INVALID_ARGS`,`batch does not accept positional arguments.`);e.parsedBatchSteps=Pt(e.flags)}if(Lt(e.command)&&(e.effectiveFlags=(await ve({command:e.command,flags:e.effectiveFlags,stateDir:e.daemonPaths.baseDir,env:process.env})).flags),e.effectiveFlags.remoteConfig&&It(e.command)){let t=l(q(e),{transport:Q(n.sendToDaemon)}),r=await he({command:e.command,flags:e.effectiveFlags,client:t,runtime:e.resolvedRuntime,positionals:e.positionals,batchSteps:e.parsedBatchSteps,forceRuntimePrepare:Vt(e.explicitFlagKeys)});e.effectiveFlags=r.flags,e.resolvedRuntime=r.runtime,e.connectionMetadata=r.connection}Rt({command:e.command,flags:e.effectiveFlags,runtime:e.resolvedRuntime,explicitFlagKeys:e.explicitFlagKeys,hadConnectionDefaults:!!e.connectionDefaults})&&process.stderr.write(`Warning: open is using explicit remote daemon or tenant flags without saved Metro runtime hints. React Native apps may launch without bundle/runtime hints; prefer connect --remote-config <path> first or pass --remote-config <path> on this command.
5
+ `)}function q(e){let t=e.effectiveFlags,n=e.connectionMetadata;return{session:t.session,requestId:e.requestId,stateDir:t.stateDir,daemonBaseUrl:t.daemonBaseUrl,daemonAuthToken:t.daemonAuthToken,daemonTransport:t.daemonTransport,daemonServerMode:t.daemonServerMode,tenant:t.tenant,sessionIsolation:t.sessionIsolation,runId:t.runId,leaseId:t.leaseId,leaseBackend:t.leaseBackend,leaseProvider:n?.leaseProvider,clientId:n?.clientId,deviceKey:n?.deviceKey,providerApp:t.providerApp,providerOsVersion:t.providerOsVersion,providerProject:t.providerProject,providerBuild:t.providerBuild,providerSessionName:t.providerSessionName,providerDeviceOrientation:t.providerDeviceOrientation,providerGeoLocation:t.providerGeoLocation,providerTimezone:t.providerTimezone,providerLanguage:t.providerLanguage,providerLocale:t.providerLocale,providerNetworkProfile:t.providerNetworkProfile,providerCustomNetwork:t.providerCustomNetwork,providerNoResignApp:t.providerNoResignApp,awsProjectArn:t.awsProjectArn,awsDeviceArn:t.awsDeviceArn,awsAppArn:t.awsAppArn,awsRegion:t.awsRegion,awsInteractionMode:t.awsInteractionMode,runtime:e.resolvedRuntime,lockPolicy:e.binding.lockPolicy,lockPlatform:e.binding.defaultPlatform,cwd:process.cwd(),debug:e.debugOutputEnabled,cost:t.cost,responseLevel:t.responseLevel}}function Et(e){let t=e.effectiveFlags.daemonBaseUrl;return e.debugOutputEnabled&&!e.effectiveFlags.json&&!t?Wt(e.daemonPaths.logPath):null}async function Dt(e){if(e.command!==`test`)return;let{createReplayTestReporterRuntime:t}=await import(`./reporting.js`);return t({debug:e.debugOutputEnabled,verbose:e.effectiveFlags.verbose,json:e.effectiveFlags.json,reporter:e.effectiveFlags.reporter,reportJunit:e.effectiveFlags.reportJunit})}async function Ot(e,n,r){let{command:i,positionals:a,effectiveFlags:o}=e;if(i===`batch`){if(!e.parsedBatchSteps)throw new t(`INVALID_ARGS`,`batch requires --steps or --steps-file.`);let s=e.parsedBatchSteps.map((t,n)=>({...t,input:e.binding.lockPolicy&&e.flags.platform===void 0?{...t.input}:U(t.input,{policyOverrides:o,configuredPlatform:o.platform,configuredSession:o.session,inheritedPlatform:o.platform})}));if(await B({command:i,positionals:a,flags:{...o,batchSteps:s},client:n,debug:e.debugOutputEnabled,replayTestReporterRuntime:r}))return}else if(i===`runtime`)throw new t(`INVALID_ARGS`,`runtime command was removed. Use connect --remote-config <path> for remote runs, or metro prepare --remote-config <path> for inspection.`);else if(await B({command:i,positionals:a,flags:o,client:n,debug:e.debugOutputEnabled,replayTestReporterRuntime:r}))return;throw new t(`INVALID_ARGS`,Nt(i))}async function kt(t,n,i){let a=r(t),o=e(a,{diagnosticId:b().diagnosticId,logPath:S({force:!0})?.path});if(n.command===`close`&&Ft(a)){n.effectiveFlags.json&&s({success:!0,data:{closed:`session`,source:`no-daemon`}});return}n.effectiveFlags.json?s({success:!1,error:o}):(c(o,{showDetails:n.debugOutputEnabled}),n.debugOutputEnabled&&At(n,o)),i&&i(),await E(1)}const J=64e3;function At(e,t){if(!e.effectiveFlags.daemonBaseUrl){Y(`daemon log`,e.daemonPaths.logPath);return}let n=t.diagnosticsRecord;n&&Y(`remote diagnostics`,d(e.daemonPaths.baseDir,n))}function Y(e,t){try{if(D.existsSync(t)){let n=D.readFileSync(t,`utf8`).split(`
6
+ `),r=n.slice(Math.max(0,n.length-200)).join(`
7
+ `);r.length>J&&(r=r.slice(r.length-J)),r.trim().length>0&&process.stderr.write(`\n[${e}]\n${r}\n`)}}catch{}}function jt(e){try{let t=P(e);return X(t.command??``,t.providedFlags)}catch{return e.includes(`--debug`)||e.includes(`-v`)||e.includes(`--verbose`)}}function Mt(e){let t=N(e);return t?`Unknown command: ${e}. Did you mean ${t}?`:`Unknown command: ${e}`}function Nt(e){return m(e)?(y({level:`error`,phase:`cli_known_command_unhandled`,data:{command:e}}),`Command is registered but no CLI handler accepted it: ${e}`):`Unknown command: ${e}`}function X(e,t){return t.some(t=>t.key===`verbose`&&(t.token===`--debug`||t.token===`-v`||e!==`test`))}function Pt(e){let n=``;if(e.steps)n=e.steps;else if(e.stepsFile)try{n=D.readFileSync(e.stepsFile,`utf8`)}catch(n){let r=n instanceof Error?n.message:String(n);throw new t(`INVALID_ARGS`,`Failed to read --steps-file ${e.stepsFile}: ${r}`)}return tt(n)}function Ft(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 Z(e){return e.command===`connect`||e.command===`connection`||e.command===`daemon`||e.command===`proxy`?null:fe({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 It(e){return!xt.has(e)}function Lt(e){return e!==`auth`&&e!==`connection`&&e!==`daemon`&&e!==`device`&&e!==`proxy`}function Rt(e){return e.command!==`open`||e.runtime||e.flags.bundleUrl||e.flags.metroHost||e.flags.metroPort||e.flags.remoteConfig||e.hadConnectionDefaults?!1:zt(e.explicitFlagKeys)}function zt(e){return e.has(`daemonBaseUrl`)||e.has(`daemonTransport`)||e.has(`tenant`)||e.has(`sessionIsolation`)||e.has(`runId`)||e.has(`leaseId`)||e.has(`leaseBackend`)}function Bt(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 Vt(e){for(let t of bt)if(e.has(t))return!0;return!1}function Ht(e){let{command:t,flags:n,replayTestReporterRuntime:r,transport:i}=e;return n.json?Q(i):async(e,n)=>{let a=t===`test`&&r?{...n,onProgress:r.onProgress}:n;return await $(i,{...e,meta:{...e.meta,requestProgress:t===`test`?`replay-test`:`command`}},a)}}function Q(e){return async(t,n)=>await $(e,t,n)}async function $(e,t,n){return await e(t,n)}function Ut(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&&G(process.argv.slice(2)).catch(async t=>{c(e(r(t)),{showDetails:!0}),await E(1)});function Wt(e){try{let t=D.existsSync(e)?D.statSync(e).size:0,n=!1,r=setInterval(()=>{if(!n&&D.existsSync(e))try{let n=D.statSync(e);if(n.size<t&&(t=0),n.size<=t)return;let r=D.openSync(e,`r`);try{let e=Buffer.alloc(n.size-t);D.readSync(r,e,0,e.length,t),t=n.size,e.length>0&&process.stdout.write(e.toString(`utf8`))}finally{D.closeSync(r)}}catch{}},200);return()=>{n=!0,clearInterval(r)}}catch{return null}}export{G as runCli};
@@ -1 +1 @@
1
- import{_ as e,v as t}from"./sdk-contracts.js";import{S as n,y as r}from"./sdk-android-adb.js";import{n as i}from"./path-resolution.js";import{t as a}from"./timeouts.js";import{c as o,d as s,n as c,s as l}from"./host-process.js";import{a as u,c as d,d as f,f as ee,g as te,h as p,i as ne,l as re,m as ie,n as m,o as h,p as g,s as ae,t as oe,u as se}from"./url.js";import{n as ce,r as le}from"./project-runtime.js";import{t as ue}from"./runtime-transport.js";import _ from"node:path";import{createHash as de}from"node:crypto";import v from"node:fs";import{fileURLToPath as fe}from"node:url";const y=`companion-tunnel`;function b(e){return de(`sha256`).update(e).digest(`hex`)}function x(e){return e?.trim()?e.trim():void 0}function pe(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 me(e,t){return e.tenantId===t.tenantId&&e.runId===t.runId&&e.leaseId===t.leaseId}function S(e,t,n,r){let i=r??_.join(e,`.agent-device`);if(!n)return{statePath:_.join(i,`${t.slug}.json`),logPath:_.join(i,`${t.slug}.log`)};let a=b(n).slice(0,12),o=_.join(i,t.slug);return{statePath:_.join(o,`${t.slug}-${a}.json`),logPath:_.join(o,`${t.slug}-${a}.log`)}}function C(e){try{let t=JSON.parse(v.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:x(typeof t.launchUrl==`string`?t.launchUrl:void 0),registerPath:x(typeof t.registerPath==`string`?t.registerPath:void 0),unregisterPath:x(typeof t.unregisterPath==`string`?t.unregisterPath:void 0),devicePort:Number.isInteger(t.devicePort)?Number(t.devicePort):void 0,session:x(typeof t.session==`string`?t.session:void 0),bridgeScope:pe(t.bridgeScope),tokenHash:t.tokenHash,consumers:n}}catch{return null}}function w(e,t){v.mkdirSync(_.dirname(e),{recursive:!0}),v.writeFileSync(e,`${JSON.stringify(t,null,2)}\n`,`utf8`)}function he(e){v.mkdirSync(_.dirname(e),{recursive:!0}),v.closeSync(v.openSync(e,`a`))}function ge(e){try{v.unlinkSync(e)}catch{}}function _e(e){try{v.unlinkSync(e)}catch{}}function T(e){try{v.readdirSync(e).length===0&&v.rmdirSync(e)}catch{}}function E(e,t){let n=_.dirname(e.statePath),r=_.dirname(e.logPath);ge(e.statePath),_e(e.logPath),T(n),r!==n&&T(r),_.basename(n)===t.slug&&T(_.dirname(n))}function D(e,t){return e.includes(t.runArg)}function ve(e,t){if(!c(e.pid))return!1;if(e.startTime){let t=o(e.pid);if(!t||t!==e.startTime)return!1}let n=l(e.pid);return!n||!D(n,t.definition)||!e.bridgeScope?!1:e.serverBaseUrl===m(t.serverBaseUrl)&&e.localBaseUrl===m(t.localBaseUrl)&&e.launchUrl===x(t.launchUrl)&&e.registerPath===x(t.registerPath)&&e.unregisterPath===x(t.unregisterPath)&&e.devicePort===t.devicePort&&e.session===x(t.session)&&me(e.bridgeScope,t.bridgeScope)&&e.tokenHash===b(t.bearerToken)}function O(e){return x(e.consumerKey)??x(e.profileKey)??null}function k(e,t){return!t||e.consumers.includes(t)?e:{...e,consumers:[...e.consumers,t]}}function ye(e,t){return t?{...e,consumers:e.consumers.filter(e=>e!==t)}:{...e,consumers:[]}}async function A(e,t){if(!c(e.pid))return;let n=l(e.pid);if(!(!n||!D(n,t))){try{process.kill(e.pid,`SIGTERM`)}catch(e){let t=e.code;if(t===`ESRCH`||t===`EPERM`)return;throw e}if(!await s(e.pid,1e3)){try{process.kill(e.pid,`SIGKILL`)}catch(e){let t=e.code;if(t===`ESRCH`||t===`EPERM`)return;throw e}await s(e.pid,1e3)}}}function be(e,t){let n={...t};return n[ee]=m(e.serverBaseUrl),n[ne]=e.bearerToken,n[ae]=m(e.localBaseUrl),n[ie]=S(e.projectRoot,e.definition,e.profileKey,e.stateDir).statePath,n[f]=e.bridgeScope.tenantId,n[se]=e.bridgeScope.runId,n[re]=e.bridgeScope.leaseId,e.launchUrl?.trim()?n[h]=e.launchUrl.trim():delete n[h],e.registerPath?.trim()?n[d]=e.registerPath.trim():delete n[d],e.unregisterPath?.trim()?n[p]=e.unregisterPath.trim():delete n[p],e.devicePort===void 0?delete n[u]:n[u]=String(e.devicePort),e.session?.trim()?n[g]=e.session.trim():delete n[g],n}function xe(e){let t=fe(import.meta.url),n=_.extname(t)||`.js`,r=[_.join(_.dirname(t),`${y}${n}`),_.join(_.dirname(t),`internal`,`${y}${n}`)].find(e=>v.existsSync(e));if(!r)throw Error(`${e.displayName} entrypoint not found. Rebuild the package to include the companion worker entry.`);return r}function Se(e,t){let n=xe(e.definition),i=n.endsWith(`.ts`)?[`--experimental-strip-types`]:[];v.mkdirSync(_.dirname(t),{recursive:!0});let a=v.openSync(t,`a`),s=0;try{s=r(process.execPath,[...i,n,e.definition.runArg],{env:be(e,e.env??process.env),stdio:[`ignore`,a,a]})}finally{v.closeSync(a)}if(!Number.isInteger(s)||s<=0)throw Error(`Failed to start ${e.definition.displayName} process.`);return{pid:s,startTime:o(s)??void 0,command:l(s)??void 0,serverBaseUrl:m(e.serverBaseUrl),localBaseUrl:m(e.localBaseUrl),launchUrl:x(e.launchUrl),registerPath:x(e.registerPath),unregisterPath:x(e.unregisterPath),devicePort:e.devicePort,session:x(e.session),bridgeScope:e.bridgeScope,tokenHash:b(e.bearerToken),consumers:[]}}async function j(e){let t=O(e),n=S(e.projectRoot,e.definition,e.profileKey,e.stateDir),r=C(n.statePath);if(r&&ve(r,e)){let e=k(r,t);return e!==r&&w(n.statePath,e),{pid:r.pid,spawned:!1,statePath:n.statePath,logPath:n.logPath}}r&&(await A(r,e.definition),E(n,e.definition)),he(n.statePath);let i;try{i=Se(e,n.logPath),w(n.statePath,k(i,t))}catch(t){throw i&&await A(i,e.definition).catch(()=>{}),E(n,e.definition),t}return{pid:i.pid,spawned:!0,statePath:n.statePath,logPath:n.logPath}}async function M(e){let t=O(e),n=S(e.projectRoot,e.definition,e.profileKey,e.stateDir),r=C(n.statePath);if(!r)return E(n,e.definition),{stopped:!1,statePath:n.statePath};let i=ye(r,t);return i.consumers.length>0?(w(n.statePath,i),{stopped:!1,statePath:n.statePath}):(await A(r,e.definition),E(n,e.definition),{stopped:!0,statePath:n.statePath})}const N={slug:`metro-companion`,runArg:te,displayName:`Metro companion`};async function Ce(e){return await j({...e,definition:N,registerPath:e.registerPath??`/api/metro/companion/register`})}async function we(e){return await M({...e,definition:N})}const P=8081,F=`.expo/.virtual-metro-entry.bundle`;function I(t,n){if(t==null||t===``)return n;let r=Number.parseInt(String(t),10);if(!Number.isInteger(r)||r<1||r>65535)throw new e(`INVALID_ARGS`,`Invalid Metro port: ${String(t)}. Use 1-65535.`);return r}function Te(t){let n=R(t.bundleUrl),r=n??t.runtime?.bundleUrl,i=!!n,a=!!R(r),o=ue({metroHost:Ee(t,i,a),metroPort:De(t,i,a),bundleUrl:r});if(!o)throw new e(`INVALID_ARGS`,`Unable to resolve Metro host and port for reload.`);let s=Oe(r);return{reloadUrl:L(o,o.scheme,`${s}/reload`),messageSocketUrl:L(o,o.scheme===`https`?`wss`:`ws`,`${s}/message`)}}function Ee(e,t,n){return R(e.metroHost)??(t?void 0:R(e.runtime?.metroHost))??(n?void 0:`localhost`)}function De(e,t,n){if(e.metroPort!==void 0)return I(e.metroPort,P);if(!t)return e.runtime?.metroPort??(n?void 0:P)}function Oe(e){let t=R(e);if(!t)return``;let n;try{n=new URL(t)}catch{return``}let r=n.pathname.replace(/\/+$/,``),i=`/${F}`;if(r.endsWith(i))return r.slice(0,-i.length);let a=r.lastIndexOf(`/`);return(a>=0?r.slice(a+1):r).endsWith(`.bundle`)&&a>0?r.slice(0,a):``}function L(e,t,n){let r=new URL(`${t}://localhost`);return r.hostname=e.host,r.port=String(e.port),r.pathname=n,r.toString()}function R(e){return typeof e==`string`&&e.trim()?e.trim():void 0}function z(e){return typeof e==`string`&&e.trim()?m(e.trim()):``}function B(e){return typeof e==`string`&&e.trim()?e.trim():void 0}function V(e,t,n){return i(e,{env:t,cwd:n})}function H(e){try{return v.accessSync(e,v.constants.F_OK),!0}catch{return!1}}function ke(e){try{return v.statSync(e).isDirectory()}catch{return!1}}function U(t){let n=_.join(t,`package.json`),r=le(t);if(!r)throw new e(`INVALID_ARGS`,`package.json not found at ${n}`);return r}const Ae=[{file:`pnpm-lock.yaml`,command:`pnpm`},{file:`yarn.lock`,command:`yarn`},{file:`bun.lock`,command:`bun`},{file:`bun.lockb`,command:`bun`},{file:`package-lock.json`,command:`npm`}];function je(e){let t=e;for(;;){for(let{file:e,command:n}of Ae)if(H(_.join(t,e)))return{command:n,installArgs:[`install`]};if(H(_.join(t,`.git`)))return null;let e=_.dirname(t);if(e===t)return null;t=e}}function Me(e){return je(e)??{command:`npm`,installArgs:[`install`]}}function Ne(e,t){if(t!==`auto`)return t;let n=ce(e);return n===`expo`||n===`repack`?n:`react-native`}function W(e,t){return typeof{...e.dependencies??{},...e.devDependencies??{}}[t]==`string`}function G(e,t){return[`js`,`mjs`,`cjs`,`ts`,`mts`,`cts`].some(n=>H(_.join(e,`${t}.config.${n}`)))}function Pe(e,t){return G(e,`rspack`)?`rspack`:G(e,`webpack`)?`webpack`:W(t,`@rspack/core`)?`rspack`:W(t,`webpack`)?`webpack`:`rspack`}function K(e,t,n){if(e==null||e===``)return t;let r=Number.parseInt(String(e),10);return Number.isInteger(r)?Math.max(r,n):t}function Fe(e){return e===`expo`?F:`index.bundle`}function q(e,t,n){return{platform:t,bundleUrl:oe(e,t,Fe(n))}}function J(e,t){return{platform:t,metroHost:B(e?.metro_host),metroPort:e?.metro_port,bundleUrl:B(e?.metro_bundle_url),launchUrl:B(e?.launch_url)}}function Ie(e,t){if(ke(_.join(e,`node_modules`)))return{installed:!1};let r=Me(e);try{n(r.command,r.installArgs,{cwd:e,env:t})}catch(e){throw Le(e,r)}return{installed:!0,packageManager:r.command}}function Le(n,r){let i=t(n),a=`Dependency install failed using detected package manager "${r.command}". If dependencies are already installed (for example via a monorepo root install), pass --no-install-deps to skip this step, or install manually with "${r.command} ${r.installArgs.join(` `)}" from the project root.`;return new e(i.code,i.message,{...i.details??{},hint:a,packageManager:r.command},i)}async function Y(e){await a(e)}async function X(t,n,r={}){try{let e=await fetch(t,{headers:r,signal:AbortSignal.timeout(n)});return{ok:e.ok,status:e.status,body:await e.text()}}catch(r){throw r instanceof Error&&r.name===`TimeoutError`?new e(`COMMAND_FAILED`,`Timed out fetching ${t} after ${n}ms`):r}}async function Re(e,t){try{let n=await X(e,t);return n.ok&&n.body.includes(`packager-status:running`)}catch{return!1}}function ze(e,t,n,r){return e===`expo`?{command:`npx`,installArgs:[`expo`,`start`,`--host`,`lan`,`--port`,String(n)]}:e===`repack`?{command:`npx`,installArgs:[`react-native`,t===`webpack`?`webpack-start`:`rspack-start`,`--host`,r,`--port`,String(n)]}:{command:`npx`,installArgs:[`react-native`,`start`,`--host`,r,`--port`,String(n)]}}function Be(t,n,i,a,o,s,c){let l=ze(n,i,a,o);v.mkdirSync(_.dirname(s),{recursive:!0});let u=v.openSync(s,`a`),d=0;try{d=r(l.command,l.installArgs,{cwd:t,env:c,stdio:[`ignore`,u,u]})}finally{v.closeSync(u)}if(!Number.isInteger(d)||d<=0)throw new e(`COMMAND_FAILED`,`Failed to start React Native dev server. Expected a detached child PID.`);return{pid:d}}async function Ve(e){if(!(!Number.isInteger(e)||e<=0)){try{process.kill(e,`SIGTERM`)}catch(e){let t=e.code;if(t===`ESRCH`||t===`EPERM`)return;throw e}if(!await s(e,1e3)){try{process.kill(e,`SIGKILL`)}catch(e){let t=e.code;if(t===`ESRCH`||t===`EPERM`)return;throw e}await s(e,1e3)}}}function He(e,t){return{Authorization:`Bearer ${t}`,"Content-Type":`application/json`,...e.includes(`ngrok`)?{"ngrok-skip-browser-warning":`1`}:{}}}function Z(t,n){let r=new e(`COMMAND_FAILED`,t);return r.retryable=n,r}function Ue(e,t){return!!(e>=500||e===408||e===425||e===429||JSON.stringify(t).includes(`Metro companion is not connected`))}function We(e){return!!(e&&typeof e==`object`&&`retryable`in e&&e.retryable===!0)}async function Q(e){let t;try{t=await fetch(`${e.baseUrl}/api/metro/bridge`,{method:`POST`,headers:He(e.baseUrl,e.bearerToken),body:JSON.stringify({...e.scope,...e.runtime?{ios_runtime:e.runtime}:{},timeout_ms:e.timeoutMs}),signal:AbortSignal.timeout(e.timeoutMs)})}catch(t){throw t instanceof Error&&t.name===`TimeoutError`?Z(`/api/metro/bridge timed out after ${e.timeoutMs}ms calling ${e.baseUrl}/api/metro/bridge`,!0):Z(t instanceof Error?t.message:String(t),!0)}let n=Ge(await t.text(),t.status,e.baseUrl);if(!t.ok)throw Z(`/api/metro/bridge failed (${t.status}): ${JSON.stringify(n)}`,Ue(t.status,n));return qe(n)}function Ge(e,t,n){if(!e)return{};try{let t=JSON.parse(e);if(!t||typeof t!=`object`||Array.isArray(t))throw Error(`Expected a JSON object`);return t}catch(r){let i=e.slice(0,200);throw Z(`/api/metro/bridge returned invalid JSON (${t}) from ${n}: ${r instanceof Error?r.message:String(r)}. body=${JSON.stringify(i)}`,Ue(t,e))}}function Ke(e){return{enabled:e.enabled,baseUrl:e.base_url,statusUrl:e.status_url??``,bundleUrl:e.bundle_url??``,iosRuntime:J(e.ios_runtime,`ios`),androidRuntime:J(e.android_runtime,`android`),upstream:{bundleUrl:e.upstream.bundle_url??``,host:e.upstream.host??``,port:e.upstream.port??0,statusUrl:e.upstream.status_url??``},probe:{reachable:e.probe.reachable,statusCode:e.probe.status_code,latencyMs:e.probe.latency_ms,detail:e.probe.detail}}}function qe(e){let t=e.data??e;if(!t||typeof t!=`object`||Array.isArray(t))throw Z(`/api/metro/bridge returned malformed descriptor: Expected a JSON object.`,!1);try{return Ke(t)}catch(e){throw Z(`/api/metro/bridge returned malformed descriptor: ${e instanceof Error?e.message:String(e)}`,!1)}}function $(e,t,n,r,i){let a=[`Metro bridge is required for this run but could not be configured via ${e}/api/metro/bridge.`];return t&&a.push(`bridgeError=${t}`),n?.probe.reachable===!1&&a.push(`bridgeProbe=${n.probe.detail||`unreachable (status ${n.probe.statusCode||0})`}`),r&&r!==t&&a.push(`initialBridgeError=${r}`),i&&a.push(`metroCompanionLog=${i}`),a.join(` `)}function Je(t,n){if(!n?.iosRuntime.bundleUrl)throw new e(`COMMAND_FAILED`,$(t,`bridge descriptor is missing ios_runtime.metro_bundle_url`,n))}function Ye(t,n,r){let i=n||B(r.AGENT_DEVICE_METRO_BEARER_TOKEN)||``,a=i||t&&B(r.AGENT_DEVICE_DAEMON_AUTH_TOKEN)||``;if(t&&!a)throw new e(`INVALID_ARGS`,`metro prepare requires proxy auth when --proxy-base-url is provided. Pass --bearer-token or set AGENT_DEVICE_METRO_BEARER_TOKEN or AGENT_DEVICE_DAEMON_AUTH_TOKEN.`);if(!t&&i)throw new e(`INVALID_ARGS`,`metro prepare requires --proxy-base-url when proxy auth is provided.`);return{proxyEnabled:!!(t&&a),proxyBaseUrl:t,proxyBearerToken:a}}function Xe(t){if(!t?.tenantId||!t.runId||!t.leaseId)throw new e(`INVALID_ARGS`,`metro prepare with proxy requires tenantId, runId, and leaseId bridge scope.`);return t}function Ze(t,n){if(!(t||n))throw new e(`INVALID_ARGS`,`metro prepare requires --public-base-url <url> or --proxy-base-url <url>.`)}function Qe(e,t,n){return e.runtimeFilePath?V(e.runtimeFilePath,t,n):null}function $e(e,t,n,r){return V(e.logPath??_.join(r,`.agent-device`,`metro.log`),t,n)}function et(e){let t=e.env??process.env,n=process.cwd(),r=V(e.projectRoot??n,t,n),i=e.kind??`auto`,a=null,o;i===`auto`?(a=U(r),o=Ne(a,i)):o=i;let s=null;o===`repack`&&(a??=U(r),s=Pe(r,a));let c=z(e.publicBaseUrl),l=z(e.proxyBaseUrl);Ze(c,l);let{proxyEnabled:u,proxyBaseUrl:d,proxyBearerToken:f}=Ye(l,B(e.proxyBearerToken)??``,t);return{env:t,projectRoot:r,kind:o,repackBundler:s,metroPort:I(e.metroPort??8081,8081),listenHost:B(e.listenHost)??`0.0.0.0`,statusHost:B(e.statusHost)??`127.0.0.1`,publicBaseUrl:c,proxyBaseUrl:d,proxyBearerToken:f,bridgeScope:u?Xe(e.bridgeScope):null,startupTimeoutMs:K(e.startupTimeoutMs,18e4,3e4),probeTimeoutMs:K(e.probeTimeoutMs,1e4,1e3),reuseExisting:e.reuseExisting??!0,installProjectDeps:e.installDependenciesIfNeeded??!0,runtimeFilePath:Qe(e,t,n),logPath:$e(e,t,n,r)}}async function tt(e,t,n){let r=Date.now()+t;for(;Date.now()<r;){let t=r-Date.now();if(await Re(e,Math.min(n,Math.max(t,1))))return!0;let i=Math.min(500,Math.max(r-Date.now(),0));i>0&&await Y(i)}return!1}async function nt(t){let n=Date.now()+t.startupTimeoutMs,r=null,i=null;for(;Date.now()<n;){try{let e=await Q({baseUrl:t.baseUrl,bearerToken:t.bearerToken,scope:t.scope,runtime:t.runtime,timeoutMs:t.probeTimeoutMs});if(e.probe.reachable!==!1)return e;r=e,i=null}catch(n){if(i=n instanceof Error?n.message:String(n),!We(n))throw new e(`COMMAND_FAILED`,$(t.baseUrl,i,r,t.initialBridgeError,t.companionLogPath),void 0,n)}let a=Math.min(1e3,Math.max(n-Date.now(),0));a>0&&await Y(a)}throw new e(`COMMAND_FAILED`,$(t.baseUrl,i,r,t.initialBridgeError,t.companionLogPath))}async function rt(t){let n=`http://${t.statusHost}:${t.metroPort}/status`;if(t.reuseExisting&&await Re(n,t.probeTimeoutMs))return{started:!1,reused:!0,pid:0,statusUrl:n};let r=Be(t.projectRoot,t.kind,t.repackBundler,t.metroPort,t.listenHost,t.logPath,t.env);if(await tt(n,t.startupTimeoutMs,t.probeTimeoutMs))return{started:!0,reused:!1,pid:r.pid,statusUrl:n};throw await Ve(r.pid).catch(()=>{}),new e(`COMMAND_FAILED`,`React Native dev server did not become ready at ${n} within ${t.startupTimeoutMs}ms. Check ${t.logPath}.`,{logPath:t.logPath})}async function it(e,t){let n=t.bridgeScope;if(!n)return null;let r=null,i=null;try{r=await Q({baseUrl:t.proxyBaseUrl,bearerToken:t.proxyBearerToken,scope:n,timeoutMs:t.probeTimeoutMs})}catch(e){if(!We(e))throw e;i=e instanceof Error?e.message:String(e)}return(!r||r.probe.reachable===!1)&&(r=await at(e,t,n,r,i)),Je(t.proxyBaseUrl,r),r}async function at(t,n,r,i,a){let o;try{o=(await Ce({projectRoot:n.projectRoot,serverBaseUrl:n.proxyBaseUrl,bearerToken:n.proxyBearerToken,bridgeScope:r,localBaseUrl:`http://${n.statusHost}:${n.metroPort}`,launchUrl:B(t.launchUrl),profileKey:B(t.companionProfileKey),consumerKey:B(t.companionConsumerKey),env:n.env})).logPath}catch(t){throw new e(`COMMAND_FAILED`,$(n.proxyBaseUrl,t instanceof Error?t.message:String(t),i,a),void 0,t)}try{return await nt({baseUrl:n.proxyBaseUrl,bearerToken:n.proxyBearerToken,scope:r,probeTimeoutMs:n.probeTimeoutMs,startupTimeoutMs:n.startupTimeoutMs,initialBridgeError:a,companionLogPath:o})}catch(e){throw e instanceof Error?e:Error(String(e))}}function ot(e,t){return{baseIosRuntime:e?q(e,`ios`,t):{platform:`ios`},baseAndroidRuntime:e?q(e,`android`,t):{platform:`android`}}}function st(e,t){e&&(v.mkdirSync(_.dirname(e),{recursive:!0}),v.writeFileSync(e,JSON.stringify(t,null,2)))}async function ct(e={}){let t=et(e),n=t.installProjectDeps?Ie(t.projectRoot,t.env):{installed:!1},r=await rt(t),{baseIosRuntime:i,baseAndroidRuntime:a}=ot(t.publicBaseUrl,t.kind),o=await it(e,t),s=o?.iosRuntime??i,c=o?.androidRuntime??a,l={projectRoot:t.projectRoot,kind:t.kind,dependenciesInstalled:n.installed,packageManager:n.packageManager??null,started:r.started,reused:r.reused,pid:r.pid,logPath:t.logPath,statusUrl:r.statusUrl,runtimeFilePath:t.runtimeFilePath,iosRuntime:s,androidRuntime:c,bridge:o};return st(t.runtimeFilePath,l),l}function lt(e){let t=e.trimStart().slice(0,15).toLowerCase();return t.startsWith(`<!doctype`)||t.startsWith(`<html`)}async function ut(t,n){await new Promise((r,i)=>{let a=new WebSocket(t),o=t=>{clearTimeout(s);try{a.close()}catch{}i(new e(`COMMAND_FAILED`,t))},s=setTimeout(()=>{o(`Timed out broadcasting reload to ${t} after ${n}ms`)},n);a.addEventListener(`open`,()=>{a.send(JSON.stringify({version:2,method:`reload`}));let e=()=>{if(a.bufferedAmount===0){clearTimeout(s),a.close(),r();return}setTimeout(e,20)};e()}),a.addEventListener(`error`,()=>{o(`Failed to reach the dev server message socket at ${t}`)})})}async function dt(t={}){let n=K(t.timeoutMs,1e4,1e3),{reloadUrl:r,messageSocketUrl:i}=Te(t),a=await X(r,n);if(a.ok&&!lt(a.body))return{reloaded:!0,reloadUrl:r,status:a.status,body:a.body,transport:`http`};try{await ut(i,n)}catch(t){throw new e(`COMMAND_FAILED`,`React Native dev server reload failed (${a.status}).`,{reloadUrl:r,status:a.status,body:a.body.slice(0,500),messageSocketUrl:i,hint:`Verify Metro or Re.Pack is running and the target React Native app is connected to this dev server instance.`},t instanceof Error?t:void 0)}return{reloaded:!0,reloadUrl:i,status:a.status,body:``,transport:`message-socket`}}export{M as a,j as i,dt as n,we as r,ct as t};
1
+ import{_ as e,v as t}from"./sdk-contracts.js";import{n}from"./path-resolution.js";import{S as r,y as i}from"./sdk-android-adb.js";import{t as a}from"./timeouts.js";import{c as o,d as s,n as c,s as l}from"./host-process.js";import{a as u,c as d,d as f,f as ee,g as te,h as p,i as ne,l as re,m as ie,n as m,o as h,p as g,s as ae,t as oe,u as se}from"./url.js";import{n as ce,r as le}from"./project-runtime.js";import{t as ue}from"./runtime-transport.js";import _ from"node:path";import{createHash as de}from"node:crypto";import v from"node:fs";import{fileURLToPath as fe}from"node:url";const y=`companion-tunnel`;function b(e){return de(`sha256`).update(e).digest(`hex`)}function x(e){return e?.trim()?e.trim():void 0}function pe(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 me(e,t){return e.tenantId===t.tenantId&&e.runId===t.runId&&e.leaseId===t.leaseId}function S(e,t,n,r){let i=r??_.join(e,`.agent-device`);if(!n)return{statePath:_.join(i,`${t.slug}.json`),logPath:_.join(i,`${t.slug}.log`)};let a=b(n).slice(0,12),o=_.join(i,t.slug);return{statePath:_.join(o,`${t.slug}-${a}.json`),logPath:_.join(o,`${t.slug}-${a}.log`)}}function C(e){try{let t=JSON.parse(v.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:x(typeof t.launchUrl==`string`?t.launchUrl:void 0),registerPath:x(typeof t.registerPath==`string`?t.registerPath:void 0),unregisterPath:x(typeof t.unregisterPath==`string`?t.unregisterPath:void 0),devicePort:Number.isInteger(t.devicePort)?Number(t.devicePort):void 0,session:x(typeof t.session==`string`?t.session:void 0),bridgeScope:pe(t.bridgeScope),tokenHash:t.tokenHash,consumers:n}}catch{return null}}function w(e,t){v.mkdirSync(_.dirname(e),{recursive:!0}),v.writeFileSync(e,`${JSON.stringify(t,null,2)}\n`,`utf8`)}function he(e){v.mkdirSync(_.dirname(e),{recursive:!0}),v.closeSync(v.openSync(e,`a`))}function ge(e){try{v.unlinkSync(e)}catch{}}function _e(e){try{v.unlinkSync(e)}catch{}}function T(e){try{v.readdirSync(e).length===0&&v.rmdirSync(e)}catch{}}function E(e,t){let n=_.dirname(e.statePath),r=_.dirname(e.logPath);ge(e.statePath),_e(e.logPath),T(n),r!==n&&T(r),_.basename(n)===t.slug&&T(_.dirname(n))}function D(e,t){return e.includes(t.runArg)}function ve(e,t){if(!c(e.pid))return!1;if(e.startTime){let t=o(e.pid);if(!t||t!==e.startTime)return!1}let n=l(e.pid);return!n||!D(n,t.definition)||!e.bridgeScope?!1:e.serverBaseUrl===m(t.serverBaseUrl)&&e.localBaseUrl===m(t.localBaseUrl)&&e.launchUrl===x(t.launchUrl)&&e.registerPath===x(t.registerPath)&&e.unregisterPath===x(t.unregisterPath)&&e.devicePort===t.devicePort&&e.session===x(t.session)&&me(e.bridgeScope,t.bridgeScope)&&e.tokenHash===b(t.bearerToken)}function O(e){return x(e.consumerKey)??x(e.profileKey)??null}function k(e,t){return!t||e.consumers.includes(t)?e:{...e,consumers:[...e.consumers,t]}}function ye(e,t){return t?{...e,consumers:e.consumers.filter(e=>e!==t)}:{...e,consumers:[]}}async function A(e,t){if(!c(e.pid))return;let n=l(e.pid);if(!(!n||!D(n,t))){try{process.kill(e.pid,`SIGTERM`)}catch(e){let t=e.code;if(t===`ESRCH`||t===`EPERM`)return;throw e}if(!await s(e.pid,1e3)){try{process.kill(e.pid,`SIGKILL`)}catch(e){let t=e.code;if(t===`ESRCH`||t===`EPERM`)return;throw e}await s(e.pid,1e3)}}}function be(e,t){let n={...t};return n[ee]=m(e.serverBaseUrl),n[ne]=e.bearerToken,n[ae]=m(e.localBaseUrl),n[ie]=S(e.projectRoot,e.definition,e.profileKey,e.stateDir).statePath,n[f]=e.bridgeScope.tenantId,n[se]=e.bridgeScope.runId,n[re]=e.bridgeScope.leaseId,e.launchUrl?.trim()?n[h]=e.launchUrl.trim():delete n[h],e.registerPath?.trim()?n[d]=e.registerPath.trim():delete n[d],e.unregisterPath?.trim()?n[p]=e.unregisterPath.trim():delete n[p],e.devicePort===void 0?delete n[u]:n[u]=String(e.devicePort),e.session?.trim()?n[g]=e.session.trim():delete n[g],n}function xe(e){let t=fe(import.meta.url),n=_.extname(t)||`.js`,r=[_.join(_.dirname(t),`${y}${n}`),_.join(_.dirname(t),`internal`,`${y}${n}`)].find(e=>v.existsSync(e));if(!r)throw Error(`${e.displayName} entrypoint not found. Rebuild the package to include the companion worker entry.`);return r}function Se(e,t){let n=xe(e.definition),r=n.endsWith(`.ts`)?[`--experimental-strip-types`]:[];v.mkdirSync(_.dirname(t),{recursive:!0});let a=v.openSync(t,`a`),s=0;try{s=i(process.execPath,[...r,n,e.definition.runArg],{env:be(e,e.env??process.env),stdio:[`ignore`,a,a]})}finally{v.closeSync(a)}if(!Number.isInteger(s)||s<=0)throw Error(`Failed to start ${e.definition.displayName} process.`);return{pid:s,startTime:o(s)??void 0,command:l(s)??void 0,serverBaseUrl:m(e.serverBaseUrl),localBaseUrl:m(e.localBaseUrl),launchUrl:x(e.launchUrl),registerPath:x(e.registerPath),unregisterPath:x(e.unregisterPath),devicePort:e.devicePort,session:x(e.session),bridgeScope:e.bridgeScope,tokenHash:b(e.bearerToken),consumers:[]}}async function j(e){let t=O(e),n=S(e.projectRoot,e.definition,e.profileKey,e.stateDir),r=C(n.statePath);if(r&&ve(r,e)){let e=k(r,t);return e!==r&&w(n.statePath,e),{pid:r.pid,spawned:!1,statePath:n.statePath,logPath:n.logPath}}r&&(await A(r,e.definition),E(n,e.definition)),he(n.statePath);let i;try{i=Se(e,n.logPath),w(n.statePath,k(i,t))}catch(t){throw i&&await A(i,e.definition).catch(()=>{}),E(n,e.definition),t}return{pid:i.pid,spawned:!0,statePath:n.statePath,logPath:n.logPath}}async function M(e){let t=O(e),n=S(e.projectRoot,e.definition,e.profileKey,e.stateDir),r=C(n.statePath);if(!r)return E(n,e.definition),{stopped:!1,statePath:n.statePath};let i=ye(r,t);return i.consumers.length>0?(w(n.statePath,i),{stopped:!1,statePath:n.statePath}):(await A(r,e.definition),E(n,e.definition),{stopped:!0,statePath:n.statePath})}const N={slug:`metro-companion`,runArg:te,displayName:`Metro companion`};async function Ce(e){return await j({...e,definition:N,registerPath:e.registerPath??`/api/metro/companion/register`})}async function we(e){return await M({...e,definition:N})}const P=8081,F=`.expo/.virtual-metro-entry.bundle`;function I(t,n){if(t==null||t===``)return n;let r=Number.parseInt(String(t),10);if(!Number.isInteger(r)||r<1||r>65535)throw new e(`INVALID_ARGS`,`Invalid Metro port: ${String(t)}. Use 1-65535.`);return r}function Te(t){let n=R(t.bundleUrl),r=n??t.runtime?.bundleUrl,i=!!n,a=!!R(r),o=ue({metroHost:Ee(t,i,a),metroPort:De(t,i,a),bundleUrl:r});if(!o)throw new e(`INVALID_ARGS`,`Unable to resolve Metro host and port for reload.`);let s=Oe(r);return{reloadUrl:L(o,o.scheme,`${s}/reload`),messageSocketUrl:L(o,o.scheme===`https`?`wss`:`ws`,`${s}/message`)}}function Ee(e,t,n){return R(e.metroHost)??(t?void 0:R(e.runtime?.metroHost))??(n?void 0:`localhost`)}function De(e,t,n){if(e.metroPort!==void 0)return I(e.metroPort,P);if(!t)return e.runtime?.metroPort??(n?void 0:P)}function Oe(e){let t=R(e);if(!t)return``;let n;try{n=new URL(t)}catch{return``}let r=n.pathname.replace(/\/+$/,``),i=`/${F}`;if(r.endsWith(i))return r.slice(0,-i.length);let a=r.lastIndexOf(`/`);return(a>=0?r.slice(a+1):r).endsWith(`.bundle`)&&a>0?r.slice(0,a):``}function L(e,t,n){let r=new URL(`${t}://localhost`);return r.hostname=e.host,r.port=String(e.port),r.pathname=n,r.toString()}function R(e){return typeof e==`string`&&e.trim()?e.trim():void 0}function z(e){return typeof e==`string`&&e.trim()?m(e.trim()):``}function B(e){return typeof e==`string`&&e.trim()?e.trim():void 0}function V(e,t,r){return n(e,{env:t,cwd:r})}function H(e){try{return v.accessSync(e,v.constants.F_OK),!0}catch{return!1}}function ke(e){try{return v.statSync(e).isDirectory()}catch{return!1}}function U(t){let n=_.join(t,`package.json`),r=le(t);if(!r)throw new e(`INVALID_ARGS`,`package.json not found at ${n}`);return r}const Ae=[{file:`pnpm-lock.yaml`,command:`pnpm`},{file:`yarn.lock`,command:`yarn`},{file:`bun.lock`,command:`bun`},{file:`bun.lockb`,command:`bun`},{file:`package-lock.json`,command:`npm`}];function je(e){let t=e;for(;;){for(let{file:e,command:n}of Ae)if(H(_.join(t,e)))return{command:n,installArgs:[`install`]};if(H(_.join(t,`.git`)))return null;let e=_.dirname(t);if(e===t)return null;t=e}}function Me(e){return je(e)??{command:`npm`,installArgs:[`install`]}}function Ne(e,t){if(t!==`auto`)return t;let n=ce(e);return n===`expo`||n===`repack`?n:`react-native`}function W(e,t){return typeof{...e.dependencies??{},...e.devDependencies??{}}[t]==`string`}function G(e,t){return[`js`,`mjs`,`cjs`,`ts`,`mts`,`cts`].some(n=>H(_.join(e,`${t}.config.${n}`)))}function Pe(e,t){return G(e,`rspack`)?`rspack`:G(e,`webpack`)?`webpack`:W(t,`@rspack/core`)?`rspack`:W(t,`webpack`)?`webpack`:`rspack`}function K(e,t,n){if(e==null||e===``)return t;let r=Number.parseInt(String(e),10);return Number.isInteger(r)?Math.max(r,n):t}function Fe(e){return e===`expo`?F:`index.bundle`}function q(e,t,n){return{platform:t,bundleUrl:oe(e,t,Fe(n))}}function J(e,t){return{platform:t,metroHost:B(e?.metro_host),metroPort:e?.metro_port,bundleUrl:B(e?.metro_bundle_url),launchUrl:B(e?.launch_url)}}function Ie(e,t){if(ke(_.join(e,`node_modules`)))return{installed:!1};let n=Me(e);try{r(n.command,n.installArgs,{cwd:e,env:t})}catch(e){throw Le(e,n)}return{installed:!0,packageManager:n.command}}function Le(n,r){let i=t(n),a=`Dependency install failed using detected package manager "${r.command}". If dependencies are already installed (for example via a monorepo root install), pass --no-install-deps to skip this step, or install manually with "${r.command} ${r.installArgs.join(` `)}" from the project root.`;return new e(i.code,i.message,{...i.details??{},hint:a,packageManager:r.command},i)}async function Y(e){await a(e)}async function X(t,n,r={}){try{let e=await fetch(t,{headers:r,signal:AbortSignal.timeout(n)});return{ok:e.ok,status:e.status,body:await e.text()}}catch(r){throw r instanceof Error&&r.name===`TimeoutError`?new e(`COMMAND_FAILED`,`Timed out fetching ${t} after ${n}ms`):r}}async function Re(e,t){try{let n=await X(e,t);return n.ok&&n.body.includes(`packager-status:running`)}catch{return!1}}function ze(e,t,n,r){return e===`expo`?{command:`npx`,installArgs:[`expo`,`start`,`--host`,`lan`,`--port`,String(n)]}:e===`repack`?{command:`npx`,installArgs:[`react-native`,t===`webpack`?`webpack-start`:`rspack-start`,`--host`,r,`--port`,String(n)]}:{command:`npx`,installArgs:[`react-native`,`start`,`--host`,r,`--port`,String(n)]}}function Be(t,n,r,a,o,s,c){let l=ze(n,r,a,o);v.mkdirSync(_.dirname(s),{recursive:!0});let u=v.openSync(s,`a`),d=0;try{d=i(l.command,l.installArgs,{cwd:t,env:c,stdio:[`ignore`,u,u]})}finally{v.closeSync(u)}if(!Number.isInteger(d)||d<=0)throw new e(`COMMAND_FAILED`,`Failed to start React Native dev server. Expected a detached child PID.`);return{pid:d}}async function Ve(e){if(!(!Number.isInteger(e)||e<=0)){try{process.kill(e,`SIGTERM`)}catch(e){let t=e.code;if(t===`ESRCH`||t===`EPERM`)return;throw e}if(!await s(e,1e3)){try{process.kill(e,`SIGKILL`)}catch(e){let t=e.code;if(t===`ESRCH`||t===`EPERM`)return;throw e}await s(e,1e3)}}}function He(e,t){return{Authorization:`Bearer ${t}`,"Content-Type":`application/json`,...e.includes(`ngrok`)?{"ngrok-skip-browser-warning":`1`}:{}}}function Z(t,n){let r=new e(`COMMAND_FAILED`,t);return r.retryable=n,r}function Ue(e,t){return!!(e>=500||e===408||e===425||e===429||JSON.stringify(t).includes(`Metro companion is not connected`))}function We(e){return!!(e&&typeof e==`object`&&`retryable`in e&&e.retryable===!0)}async function Q(e){let t;try{t=await fetch(`${e.baseUrl}/api/metro/bridge`,{method:`POST`,headers:He(e.baseUrl,e.bearerToken),body:JSON.stringify({...e.scope,...e.runtime?{ios_runtime:e.runtime}:{},timeout_ms:e.timeoutMs}),signal:AbortSignal.timeout(e.timeoutMs)})}catch(t){throw t instanceof Error&&t.name===`TimeoutError`?Z(`/api/metro/bridge timed out after ${e.timeoutMs}ms calling ${e.baseUrl}/api/metro/bridge`,!0):Z(t instanceof Error?t.message:String(t),!0)}let n=Ge(await t.text(),t.status,e.baseUrl);if(!t.ok)throw Z(`/api/metro/bridge failed (${t.status}): ${JSON.stringify(n)}`,Ue(t.status,n));return qe(n)}function Ge(e,t,n){if(!e)return{};try{let t=JSON.parse(e);if(!t||typeof t!=`object`||Array.isArray(t))throw Error(`Expected a JSON object`);return t}catch(r){let i=e.slice(0,200);throw Z(`/api/metro/bridge returned invalid JSON (${t}) from ${n}: ${r instanceof Error?r.message:String(r)}. body=${JSON.stringify(i)}`,Ue(t,e))}}function Ke(e){return{enabled:e.enabled,baseUrl:e.base_url,statusUrl:e.status_url??``,bundleUrl:e.bundle_url??``,iosRuntime:J(e.ios_runtime,`ios`),androidRuntime:J(e.android_runtime,`android`),upstream:{bundleUrl:e.upstream.bundle_url??``,host:e.upstream.host??``,port:e.upstream.port??0,statusUrl:e.upstream.status_url??``},probe:{reachable:e.probe.reachable,statusCode:e.probe.status_code,latencyMs:e.probe.latency_ms,detail:e.probe.detail}}}function qe(e){let t=e.data??e;if(!t||typeof t!=`object`||Array.isArray(t))throw Z(`/api/metro/bridge returned malformed descriptor: Expected a JSON object.`,!1);try{return Ke(t)}catch(e){throw Z(`/api/metro/bridge returned malformed descriptor: ${e instanceof Error?e.message:String(e)}`,!1)}}function $(e,t,n,r,i){let a=[`Metro bridge is required for this run but could not be configured via ${e}/api/metro/bridge.`];return t&&a.push(`bridgeError=${t}`),n?.probe.reachable===!1&&a.push(`bridgeProbe=${n.probe.detail||`unreachable (status ${n.probe.statusCode||0})`}`),r&&r!==t&&a.push(`initialBridgeError=${r}`),i&&a.push(`metroCompanionLog=${i}`),a.join(` `)}function Je(t,n){if(!n?.iosRuntime.bundleUrl)throw new e(`COMMAND_FAILED`,$(t,`bridge descriptor is missing ios_runtime.metro_bundle_url`,n))}function Ye(t,n,r){let i=n||B(r.AGENT_DEVICE_METRO_BEARER_TOKEN)||``,a=i||t&&B(r.AGENT_DEVICE_DAEMON_AUTH_TOKEN)||``;if(t&&!a)throw new e(`INVALID_ARGS`,`metro prepare requires proxy auth when --proxy-base-url is provided. Pass --bearer-token or set AGENT_DEVICE_METRO_BEARER_TOKEN or AGENT_DEVICE_DAEMON_AUTH_TOKEN.`);if(!t&&i)throw new e(`INVALID_ARGS`,`metro prepare requires --proxy-base-url when proxy auth is provided.`);return{proxyEnabled:!!(t&&a),proxyBaseUrl:t,proxyBearerToken:a}}function Xe(t){if(!t?.tenantId||!t.runId||!t.leaseId)throw new e(`INVALID_ARGS`,`metro prepare with proxy requires tenantId, runId, and leaseId bridge scope.`);return t}function Ze(t,n){if(!(t||n))throw new e(`INVALID_ARGS`,`metro prepare requires --public-base-url <url> or --proxy-base-url <url>.`)}function Qe(e,t,n){return e.runtimeFilePath?V(e.runtimeFilePath,t,n):null}function $e(e,t,n,r){return V(e.logPath??_.join(r,`.agent-device`,`metro.log`),t,n)}function et(e){let t=e.env??process.env,n=process.cwd(),r=V(e.projectRoot??n,t,n),i=e.kind??`auto`,a=null,o;i===`auto`?(a=U(r),o=Ne(a,i)):o=i;let s=null;o===`repack`&&(a??=U(r),s=Pe(r,a));let c=z(e.publicBaseUrl),l=z(e.proxyBaseUrl);Ze(c,l);let{proxyEnabled:u,proxyBaseUrl:d,proxyBearerToken:f}=Ye(l,B(e.proxyBearerToken)??``,t);return{env:t,projectRoot:r,kind:o,repackBundler:s,metroPort:I(e.metroPort??8081,8081),listenHost:B(e.listenHost)??`0.0.0.0`,statusHost:B(e.statusHost)??`127.0.0.1`,publicBaseUrl:c,proxyBaseUrl:d,proxyBearerToken:f,bridgeScope:u?Xe(e.bridgeScope):null,startupTimeoutMs:K(e.startupTimeoutMs,18e4,3e4),probeTimeoutMs:K(e.probeTimeoutMs,1e4,1e3),reuseExisting:e.reuseExisting??!0,installProjectDeps:e.installDependenciesIfNeeded??!0,runtimeFilePath:Qe(e,t,n),logPath:$e(e,t,n,r)}}async function tt(e,t,n){let r=Date.now()+t;for(;Date.now()<r;){let t=r-Date.now();if(await Re(e,Math.min(n,Math.max(t,1))))return!0;let i=Math.min(500,Math.max(r-Date.now(),0));i>0&&await Y(i)}return!1}async function nt(t){let n=Date.now()+t.startupTimeoutMs,r=null,i=null;for(;Date.now()<n;){try{let e=await Q({baseUrl:t.baseUrl,bearerToken:t.bearerToken,scope:t.scope,runtime:t.runtime,timeoutMs:t.probeTimeoutMs});if(e.probe.reachable!==!1)return e;r=e,i=null}catch(n){if(i=n instanceof Error?n.message:String(n),!We(n))throw new e(`COMMAND_FAILED`,$(t.baseUrl,i,r,t.initialBridgeError,t.companionLogPath),void 0,n)}let a=Math.min(1e3,Math.max(n-Date.now(),0));a>0&&await Y(a)}throw new e(`COMMAND_FAILED`,$(t.baseUrl,i,r,t.initialBridgeError,t.companionLogPath))}async function rt(t){let n=`http://${t.statusHost}:${t.metroPort}/status`;if(t.reuseExisting&&await Re(n,t.probeTimeoutMs))return{started:!1,reused:!0,pid:0,statusUrl:n};let r=Be(t.projectRoot,t.kind,t.repackBundler,t.metroPort,t.listenHost,t.logPath,t.env);if(await tt(n,t.startupTimeoutMs,t.probeTimeoutMs))return{started:!0,reused:!1,pid:r.pid,statusUrl:n};throw await Ve(r.pid).catch(()=>{}),new e(`COMMAND_FAILED`,`React Native dev server did not become ready at ${n} within ${t.startupTimeoutMs}ms. Check ${t.logPath}.`,{logPath:t.logPath})}async function it(e,t){let n=t.bridgeScope;if(!n)return null;let r=null,i=null;try{r=await Q({baseUrl:t.proxyBaseUrl,bearerToken:t.proxyBearerToken,scope:n,timeoutMs:t.probeTimeoutMs})}catch(e){if(!We(e))throw e;i=e instanceof Error?e.message:String(e)}return(!r||r.probe.reachable===!1)&&(r=await at(e,t,n,r,i)),Je(t.proxyBaseUrl,r),r}async function at(t,n,r,i,a){let o;try{o=(await Ce({projectRoot:n.projectRoot,serverBaseUrl:n.proxyBaseUrl,bearerToken:n.proxyBearerToken,bridgeScope:r,localBaseUrl:`http://${n.statusHost}:${n.metroPort}`,launchUrl:B(t.launchUrl),profileKey:B(t.companionProfileKey),consumerKey:B(t.companionConsumerKey),env:n.env})).logPath}catch(t){throw new e(`COMMAND_FAILED`,$(n.proxyBaseUrl,t instanceof Error?t.message:String(t),i,a),void 0,t)}try{return await nt({baseUrl:n.proxyBaseUrl,bearerToken:n.proxyBearerToken,scope:r,probeTimeoutMs:n.probeTimeoutMs,startupTimeoutMs:n.startupTimeoutMs,initialBridgeError:a,companionLogPath:o})}catch(e){throw e instanceof Error?e:Error(String(e))}}function ot(e,t){return{baseIosRuntime:e?q(e,`ios`,t):{platform:`ios`},baseAndroidRuntime:e?q(e,`android`,t):{platform:`android`}}}function st(e,t){e&&(v.mkdirSync(_.dirname(e),{recursive:!0}),v.writeFileSync(e,JSON.stringify(t,null,2)))}async function ct(e={}){let t=et(e),n=t.installProjectDeps?Ie(t.projectRoot,t.env):{installed:!1},r=await rt(t),{baseIosRuntime:i,baseAndroidRuntime:a}=ot(t.publicBaseUrl,t.kind),o=await it(e,t),s=o?.iosRuntime??i,c=o?.androidRuntime??a,l={projectRoot:t.projectRoot,kind:t.kind,dependenciesInstalled:n.installed,packageManager:n.packageManager??null,started:r.started,reused:r.reused,pid:r.pid,logPath:t.logPath,statusUrl:r.statusUrl,runtimeFilePath:t.runtimeFilePath,iosRuntime:s,androidRuntime:c,bridge:o};return st(t.runtimeFilePath,l),l}function lt(e){let t=e.trimStart().slice(0,15).toLowerCase();return t.startsWith(`<!doctype`)||t.startsWith(`<html`)}async function ut(t,n){await new Promise((r,i)=>{let a=new WebSocket(t),o=t=>{clearTimeout(s);try{a.close()}catch{}i(new e(`COMMAND_FAILED`,t))},s=setTimeout(()=>{o(`Timed out broadcasting reload to ${t} after ${n}ms`)},n);a.addEventListener(`open`,()=>{a.send(JSON.stringify({version:2,method:`reload`}));let e=()=>{if(a.bufferedAmount===0){clearTimeout(s),a.close(),r();return}setTimeout(e,20)};e()}),a.addEventListener(`error`,()=>{o(`Failed to reach the dev server message socket at ${t}`)})})}async function dt(t={}){let n=K(t.timeoutMs,1e4,1e3),{reloadUrl:r,messageSocketUrl:i}=Te(t),a=await X(r,n);if(a.ok&&!lt(a.body))return{reloaded:!0,reloadUrl:r,status:a.status,body:a.body,transport:`http`};try{await ut(i,n)}catch(t){throw new e(`COMMAND_FAILED`,`React Native dev server reload failed (${a.status}).`,{reloadUrl:r,status:a.status,body:a.body.slice(0,500),messageSocketUrl:i,hint:`Verify Metro or Re.Pack is running and the target React Native app is connected to this dev server instance.`},t instanceof Error?t:void 0)}return{reloaded:!0,reloadUrl:i,status:a.status,body:``,transport:`message-socket`}}export{M as a,j as i,dt as n,we as r,ct as t};