agent-device 0.13.1 → 0.13.3

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 (38) hide show
  1. package/bin/agent-device.mjs +6 -2
  2. package/dist/src/113.js +1 -1
  3. package/dist/src/1974.js +2 -2
  4. package/dist/src/2301.js +1 -0
  5. package/dist/src/3918.js +29 -29
  6. package/dist/src/7847.js +1 -1
  7. package/dist/src/8161.js +3 -0
  8. package/dist/src/8656.js +1 -1
  9. package/dist/src/9152.js +1 -1
  10. package/dist/src/940.js +1 -0
  11. package/dist/src/9542.js +2 -2
  12. package/dist/src/index.d.ts +168 -1925
  13. package/dist/src/index.js +1 -1
  14. package/dist/src/internal/bin.js +105 -0
  15. package/dist/src/internal/companion-tunnel.js +1 -0
  16. package/dist/src/{daemon.js → internal/daemon.js} +10 -10
  17. package/dist/src/internal/update-check-entry.js +1 -0
  18. package/dist/src/metro.d.ts +7 -5
  19. package/dist/src/metro.js +1 -1
  20. package/dist/src/selectors.js +1 -1
  21. package/package.json +1 -13
  22. package/skills/agent-device/references/remote-tenancy.md +6 -7
  23. package/dist/src/320.js +0 -1
  24. package/dist/src/8564.js +0 -3
  25. package/dist/src/9076.js +0 -1
  26. package/dist/src/backend.d.ts +0 -527
  27. package/dist/src/backend.js +0 -1
  28. package/dist/src/bin.js +0 -97
  29. package/dist/src/commands/index.d.ts +0 -1883
  30. package/dist/src/commands/index.js +0 -1
  31. package/dist/src/metro-companion.js +0 -1
  32. package/dist/src/testing/conformance.d.ts +0 -753
  33. package/dist/src/testing/conformance.js +0 -1
  34. package/dist/src/update-check-entry.js +0 -1
  35. /package/dist/src/{bin.d.ts → internal/bin.d.ts} +0 -0
  36. /package/dist/src/{daemon.d.ts → internal/companion-tunnel.d.ts} +0 -0
  37. /package/dist/src/{metro-companion.d.ts → internal/daemon.d.ts} +0 -0
  38. /package/dist/src/{update-check-entry.d.ts → internal/update-check-entry.d.ts} +0 -0
@@ -4,9 +4,13 @@ import { dirname, join } from 'node:path';
4
4
  import { fileURLToPath, pathToFileURL } from 'node:url';
5
5
 
6
6
  const here = dirname(fileURLToPath(import.meta.url));
7
- const distPath = join(here, '..', 'dist', 'src', 'bin.js');
7
+ const distPaths = [
8
+ join(here, '..', 'dist', 'src', 'internal', 'bin.js'),
9
+ join(here, '..', 'dist', 'src', 'bin.js'),
10
+ ];
11
+ const distPath = distPaths.find((candidate) => existsSync(candidate));
8
12
 
9
- if (!existsSync(distPath)) {
13
+ if (!distPath) {
10
14
  process.stderr.write('Missing dist build. Run `pnpm build` before using the binary.\n');
11
15
  process.exit(1);
12
16
  }
package/dist/src/113.js CHANGED
@@ -1,3 +1,3 @@
1
1
  import e from"node:fs";import t from"node:path";import{fileURLToPath as r}from"node:url";import{runCmdDetached as n}from"./9818.js";let i="agent-device",o="--agent-device-run-update-check";function a(a){var c,p,u,m,h,f,g;let k,v,y;if(!(!(!(c=a).command||"help"===c.command||"test"===c.command||c.flags.help||c.flags.version||c.flags.json||process.env.CI?.trim()||"test"===process.env.NODE_ENV||process.env.AGENT_DEVICE_NO_UPDATE_NOTIFIER?.trim())&&process.stderr.isTTY))return;let S=Date.now(),V=t.join(a.stateDir,"update-check.json"),w=s(V);p=w,u=a.currentVersion,!p.latestVersion||0>=l(p.latestVersion,u)||!0===p.prompted||(process.stderr.write(`Update available: ${i} ${a.currentVersion} -> ${w.latestVersion}. Run \`npm install -g ${i}@latest\` to upgrade the CLI and bundled skills.
2
- `),d(V,{...w,prompted:!0})),m=w,h=S,(void 0===(k=function(e){if(!e)return;let t=Date.parse(e);return Number.isNaN(t)?void 0:t}(m.checkedAt))||h-k>=12096e5)&&(f=V,g=a.currentVersion,y=(v=function(){let n=r(import.meta.url),i=t.extname(n)||".js",o=t.join(t.dirname(n),`update-check-entry${i}`);if(!e.existsSync(o))throw Error(`Update check entrypoint not found at ${o}. Rebuild the package to include the update-check worker entry.`);return o}()).endsWith(".ts")?["--experimental-strip-types"]:[],n(process.execPath,[...y,v,o,f,g]))}async function c(e){let t=Date.now(),r=s(e.cachePath);try{let n=await p()??void 0;if(!n||0>=l(n,e.currentVersion))return void d(e.cachePath,{checkedAt:new Date(t).toISOString()});d(e.cachePath,{checkedAt:new Date(t).toISOString(),latestVersion:n,prompted:r.latestVersion===n&&!0===r.prompted})}catch{d(e.cachePath,{...r,checkedAt:new Date(t).toISOString()})}}function s(t){try{let r=JSON.parse(e.readFileSync(t,"utf8"));return{checkedAt:"string"==typeof r.checkedAt?r.checkedAt:void 0,latestVersion:"string"==typeof r.latestVersion?r.latestVersion:void 0,prompted:!0===r.prompted}}catch{return{}}}function d(r,n){try{e.mkdirSync(t.dirname(r),{recursive:!0}),e.writeFileSync(r,`${JSON.stringify(n,null,2)}
2
+ `),d(V,{...w,prompted:!0})),m=w,h=S,(void 0===(k=function(e){if(!e)return;let t=Date.parse(e);return Number.isNaN(t)?void 0:t}(m.checkedAt))||h-k>=12096e5)&&(f=V,g=a.currentVersion,y=(v=function(){let n=r(import.meta.url),i=t.extname(n)||".js",o=[t.join(t.dirname(n),`update-check-entry${i}`),t.join(t.dirname(n),"internal",`update-check-entry${i}`)].find(t=>e.existsSync(t));if(!o)throw Error("Update check entrypoint not found. Rebuild the package to include the update-check worker entry.");return o}()).endsWith(".ts")?["--experimental-strip-types"]:[],n(process.execPath,[...y,v,o,f,g]))}async function c(e){let t=Date.now(),r=s(e.cachePath);try{let n=await p()??void 0;if(!n||0>=l(n,e.currentVersion))return void d(e.cachePath,{checkedAt:new Date(t).toISOString()});d(e.cachePath,{checkedAt:new Date(t).toISOString(),latestVersion:n,prompted:r.latestVersion===n&&!0===r.prompted})}catch{d(e.cachePath,{...r,checkedAt:new Date(t).toISOString()})}}function s(t){try{let r=JSON.parse(e.readFileSync(t,"utf8"));return{checkedAt:"string"==typeof r.checkedAt?r.checkedAt:void 0,latestVersion:"string"==typeof r.latestVersion?r.latestVersion:void 0,prompted:!0===r.prompted}}catch{return{}}}function d(r,n){try{e.mkdirSync(t.dirname(r),{recursive:!0}),e.writeFileSync(r,`${JSON.stringify(n,null,2)}
3
3
  `,"utf8")}catch{}}async function p(){let e=await fetch(`https://registry.npmjs.org/${i}/latest`,{signal:AbortSignal.timeout(3500),headers:{accept:"application/json"}});if(!e.ok)return;let t=await e.json();return"string"==typeof t.version&&t.version.trim().length>0?t.version.trim():void 0}function l(e,t){return e.localeCompare(t,void 0,{numeric:!0})}function u(e){if(e[0]!==o)return null;let t=e[1]?.trim(),r=e[2]?.trim();return t&&r?{cachePath:t,currentVersion:r}:null}export{a as maybeRunUpgradeNotifier,u as readUpdateCheckWorkerArgs,c as runUpdateCheckWorker};
package/dist/src/1974.js CHANGED
@@ -1,2 +1,2 @@
1
- import e from"node:fs";import t from"node:path";import{createHash as r}from"node:crypto";import{fileURLToPath as n}from"node:url";import{runCmdDetached as o,runCmdSync as i}from"./9818.js";import{readProcessCommand as a,waitForProcessExit as s,resolveRuntimeTransportHints as l,isProcessAlive as u,readProcessStartTime as c}from"./8656.js";import{normalizeBaseUrl as d,ENV_REGISTER_PATH as m,ENV_UNREGISTER_PATH as p,ENV_LOCAL_BASE_URL as h,ENV_STATE_PATH as f,ENV_SESSION as g,ENV_BEARER_TOKEN as y,METRO_COMPANION_RUN_ARG as b,buildBundleUrl as S,ENV_SERVER_BASE_URL as w,ENV_LAUNCH_URL as P,ENV_SCOPE_TENANT_ID as v,ENV_SCOPE_RUN_ID as U,ENV_SCOPE_LEASE_ID as _,REACT_DEVTOOLS_COMPANION_RUN_ARG as I,ENV_DEVICE_PORT as E}from"./320.js";import{AppError as k}from"./9152.js";import{resolveUserPath as M}from"./3267.js";import{sleep as N}from"./4829.js";let A="metro-companion";function R(e){return r("sha256").update(e).digest("hex")}function $(e){return e?.trim()?e.trim():void 0}function x(e,r,n="metro",o){let i="react-devtools"===n?{stateFile:"react-devtools-companion.json",logFile:"react-devtools-companion.log",stateDir:"react-devtools-companion"}:{stateFile:"metro-companion.json",logFile:"metro-companion.log",stateDir:A},a=o??t.join(e,".agent-device");if(!r)return{statePath:t.join(a,i.stateFile),logPath:t.join(a,i.logFile)};let s=R(r).slice(0,12),l=t.join(a,i.stateDir);return{statePath:t.join(l,`${i.stateDir}-${s}.json`),logPath:t.join(l,`${i.stateDir}-${s}.log`)}}function j(t){try{let r=JSON.parse(e.readFileSync(t,"utf8"));if(!Number.isInteger(r.pid)||0>=Number(r.pid)||"string"!=typeof r.serverBaseUrl||"string"!=typeof r.localBaseUrl||"string"!=typeof r.tokenHash||0===r.tokenHash.length)return null;let n=Array.isArray(r.consumers)?r.consumers.filter(e=>"string"==typeof e&&e.length>0):[];return{pid:Number(r.pid),startTime:"string"==typeof r.startTime?r.startTime:void 0,command:"string"==typeof r.command?r.command:void 0,serverBaseUrl:r.serverBaseUrl,localBaseUrl:r.localBaseUrl,launchUrl:$("string"==typeof r.launchUrl?r.launchUrl:void 0),registerPath:$("string"==typeof r.registerPath?r.registerPath:void 0),unregisterPath:$("string"==typeof r.unregisterPath?r.unregisterPath:void 0),devicePort:Number.isInteger(r.devicePort)?Number(r.devicePort):void 0,session:$("string"==typeof r.session?r.session:void 0),bridgeScope:function(e){if(!(!e||"object"!=typeof e||Array.isArray(e))&&"string"==typeof e.tenantId&&"string"==typeof e.runId&&"string"==typeof e.leaseId)return{tenantId:e.tenantId,runId:e.runId,leaseId:e.leaseId}}(r.bridgeScope),tokenHash:r.tokenHash,consumers:n}}catch{return null}}function D(r,n){e.mkdirSync(t.dirname(r),{recursive:!0}),e.writeFileSync(r,`${JSON.stringify(n,null,2)}
2
- `,"utf8")}function T(t){try{let r=e.readdirSync(t);0===r.length&&e.rmdirSync(t)}catch{}}function C(r){let n=t.dirname(r.statePath),o=t.dirname(r.logPath);var i=r.statePath;try{e.unlinkSync(i)}catch{}var a=r.logPath;try{e.unlinkSync(a)}catch{}T(n),o!==n&&T(o),t.basename(n)===A&&T(t.dirname(n))}function B(e){return e.includes(b)||e.includes(I)}function K(e){return $(e.consumerKey)??$(e.profileKey)??null}function H(e,t){return!t||e.consumers.includes(t)?e:{...e,consumers:[...e.consumers,t]}}async function O(e){if(!u(e.pid))return;let t=a(e.pid);if(t&&B(t)){try{process.kill(e.pid,"SIGTERM")}catch(t){let e=t.code;if("ESRCH"===e||"EPERM"===e)return;throw t}if(!await s(e.pid,1e3)){try{process.kill(e.pid,"SIGKILL")}catch(t){let e=t.code;if("ESRCH"===e||"EPERM"===e)return;throw t}await s(e.pid,1e3)}}}async function F(r){let i=K(r),s=x(r.projectRoot,r.profileKey,r.kind,r.stateDir),l=j(s.statePath);if(l&&function(e,t){var r,n;if(!u(e.pid))return!1;if(e.startTime){let t=c(e.pid);if(!t||t!==e.startTime)return!1}let o=a(e.pid);return!!o&&!!B(o)&&!!e.bridgeScope&&e.serverBaseUrl===d(t.serverBaseUrl)&&e.localBaseUrl===d(t.localBaseUrl)&&e.launchUrl===$(t.launchUrl)&&e.registerPath===$(t.registerPath)&&e.unregisterPath===$(t.unregisterPath)&&e.devicePort===t.devicePort&&e.session===$(t.session)&&(r=e.bridgeScope,n=t.bridgeScope,r.tenantId===n.tenantId&&r.runId===n.runId&&r.leaseId===n.leaseId)&&e.tokenHash===R(t.bearerToken)}(l,r)){let e=H(l,i);return e!==l&&D(s.statePath,e),{pid:l.pid,spawned:!1,statePath:s.statePath,logPath:s.logPath}}l&&(await O(l),C(s));let S=function(r,i){let s=function(){let r=n(import.meta.url),o=t.extname(r)||".js",i=t.join(t.dirname(r),`metro-companion${o}`);if(!e.existsSync(i))throw Error(`Metro companion entrypoint not found at ${i}. Rebuild the package to include the companion worker entry.`);return i}(),l=s.endsWith(".ts")?["--experimental-strip-types"]:[],u="react-devtools"===r.kind?I:b;e.mkdirSync(t.dirname(i),{recursive:!0});let S=e.openSync(i,"a"),k=0;try{let e;k=o(process.execPath,[...l,s,u],{env:((e={...r.env??process.env,[w]:d(r.serverBaseUrl),[y]:r.bearerToken,[h]:d(r.localBaseUrl),[f]:x(r.projectRoot,r.profileKey,r.kind,r.stateDir).statePath})[v]=r.bridgeScope.tenantId,e[U]=r.bridgeScope.runId,e[_]=r.bridgeScope.leaseId,r.launchUrl?.trim()?e[P]=r.launchUrl.trim():delete e[P],r.registerPath?.trim()?e[m]=r.registerPath.trim():delete e[m],r.unregisterPath?.trim()?e[p]=r.unregisterPath.trim():delete e[p],void 0!==r.devicePort?e[E]=String(r.devicePort):delete e[E],r.session?.trim()?e[g]=r.session.trim():delete e[g],e),stdio:["ignore",S,S]})}finally{e.closeSync(S)}if(!Number.isInteger(k)||k<=0)throw Error("Failed to start Metro companion process.");return{pid:k,startTime:c(k)??void 0,command:a(k)??void 0,serverBaseUrl:d(r.serverBaseUrl),localBaseUrl:d(r.localBaseUrl),launchUrl:$(r.launchUrl),registerPath:$(r.registerPath),unregisterPath:$(r.unregisterPath),devicePort:r.devicePort,session:$(r.session),bridgeScope:r.bridgeScope,tokenHash:R(r.bearerToken),consumers:[]}}(r,s.logPath);return D(s.statePath,H(S,i)),{pid:S.pid,spawned:!0,statePath:s.statePath,logPath:s.logPath}}async function L(e){let t=K(e),r=x(e.projectRoot,e.profileKey,e.kind,e.stateDir),n=j(r.statePath);if(!n)return C(r),{stopped:!1,statePath:r.statePath};let o=t?{...n,consumers:n.consumers.filter(e=>e!==t)}:{...n,consumers:[]};return o.consumers.length>0?(D(r.statePath,o),{stopped:!1,statePath:r.statePath}):(await O(n),C(r),{stopped:!0,statePath:r.statePath})}function G(e){return"string"==typeof e&&e.trim()?d(e.trim()):""}function J(e){return"string"==typeof e&&e.trim()?e.trim():void 0}function V(e,t,r){return M(e,{env:t,cwd:r})}function q(t){try{return e.accessSync(t,e.constants.F_OK),!0}catch{return!1}}function W(e,t,r){if(null==e||""===e)return t;let n=Number.parseInt(String(e),10);return Number.isInteger(n)?Math.max(n,r):t}function z(e,t){if(null==e||""===e)return t;let r=Number.parseInt(String(e),10);if(!Number.isInteger(r)||r<1||r>65535)throw new k("INVALID_ARGS",`Invalid Metro port: ${String(e)}. Use 1-65535.`);return r}function X(e,t){return{platform:t,bundleUrl:S(e,t)}}function Y(e,t){return{platform:t,metroHost:J(e?.metro_host),metroPort:e?.metro_port,bundleUrl:J(e?.metro_bundle_url),launchUrl:J(e?.launch_url)}}async function Q(e){await N(e)}async function Z(e,t,r={}){try{let n=await fetch(e,{headers:r,signal:AbortSignal.timeout(t)});return{ok:n.ok,status:n.status,body:await n.text()}}catch(r){if(r instanceof Error&&"TimeoutError"===r.name)throw Error(`Timed out fetching ${e} after ${t}ms`);throw r}}async function ee(e,t){try{let r=await Z(e,t);return r.ok&&r.body.includes("packager-status:running")}catch{return!1}}async function et(e){if(Number.isInteger(e)&&!(e<=0)){try{process.kill(e,"SIGTERM")}catch(t){let e=t.code;if("ESRCH"===e||"EPERM"===e)return;throw t}if(!await s(e,1e3)){try{process.kill(e,"SIGKILL")}catch(t){let e=t.code;if("ESRCH"===e||"EPERM"===e)return;throw t}await s(e,1e3)}}}function er(e,t){let r=Error(e);return r.retryable=t,r}function en(e,t){return!!(e>=500||408===e||425===e||429===e||JSON.stringify(t).includes("Metro companion is not connected"))}function eo(e){return!!(e&&"object"==typeof e&&"retryable"in e&&!0===e.retryable)}async function ei(e){let t;try{var r,n;t=await fetch(`${e.baseUrl}/api/metro/bridge`,{method:"POST",headers:(r=e.baseUrl,n=e.bearerToken,{Authorization:`Bearer ${n}`,"Content-Type":"application/json",...r.includes("ngrok")?{"ngrok-skip-browser-warning":"1"}:{}}),body:JSON.stringify({...e.scope,...e.runtime?{ios_runtime:e.runtime}:{},timeout_ms:e.timeoutMs}),signal:AbortSignal.timeout(e.timeoutMs)})}catch(t){if(t instanceof Error&&"TimeoutError"===t.name)throw er(`/api/metro/bridge timed out after ${e.timeoutMs}ms calling ${e.baseUrl}/api/metro/bridge`,!0);throw er(t instanceof Error?t.message:String(t),!0)}let o=function(e,t,r){if(!e)return{};try{let t=JSON.parse(e);if(!t||"object"!=typeof t||Array.isArray(t))throw Error("Expected a JSON object");return t}catch(i){let n=e.slice(0,200),o=i instanceof Error?i.message:String(i);throw er(`/api/metro/bridge returned invalid JSON (${t}) from ${r}: ${o}. body=${JSON.stringify(n)}`,en(t,e))}}(await t.text(),t.status,e.baseUrl);if(!t.ok)throw er(`/api/metro/bridge failed (${t.status}): ${JSON.stringify(o)}`,en(t.status,o));var i=o;let a=i.data??i;if(!a||"object"!=typeof a||Array.isArray(a))throw er("/api/metro/bridge returned malformed descriptor: Expected a JSON object.",!1);try{return{enabled:a.enabled,baseUrl:a.base_url,statusUrl:a.status_url??"",bundleUrl:a.bundle_url??"",iosRuntime:Y(a.ios_runtime,"ios"),androidRuntime:Y(a.android_runtime,"android"),upstream:{bundleUrl:a.upstream.bundle_url??"",host:a.upstream.host??"",port:a.upstream.port??0,statusUrl:a.upstream.status_url??""},probe:{reachable:a.probe.reachable,statusCode:a.probe.status_code,latencyMs:a.probe.latency_ms,detail:a.probe.detail}}}catch(e){throw er(`/api/metro/bridge returned malformed descriptor: ${e instanceof Error?e.message:String(e)}`,!1)}}function ea(e,t,r,n,o){let i=[`Metro bridge is required for this run but could not be configured via ${e}/api/metro/bridge.`];return t&&i.push(`bridgeError=${t}`),r?.probe.reachable===!1&&i.push(`bridgeProbe=${r.probe.detail||`unreachable (status ${r.probe.statusCode||0})`}`),n&&n!==t&&i.push(`initialBridgeError=${n}`),o&&i.push(`metroCompanionLog=${o}`),i.join(" ")}async function es(e,t,r){let n=Date.now()+t;for(;Date.now()<n;){let t=Math.min(r,Math.max(n-Date.now(),1));if(await ee(e,t))return!0;let o=Math.min(500,Math.max(n-Date.now(),0));o>0&&await Q(o)}return!1}async function el(e){let t=Date.now()+e.startupTimeoutMs,r=null,n=null;for(;Date.now()<t;){try{let t=await ei({baseUrl:e.baseUrl,bearerToken:e.bearerToken,scope:e.scope,runtime:e.runtime,timeoutMs:e.probeTimeoutMs});if(!1!==t.probe.reachable)return t;r=t,n=null}catch(e){if(n=e instanceof Error?e.message:String(e),!eo(e))break}let o=Math.min(1e3,Math.max(t-Date.now(),0));o>0&&await Q(o)}throw Error(ea(e.baseUrl,n,r,e.initialBridgeError,e.companionLogPath))}async function eu(r={}){let n=r.env??process.env,a=process.cwd(),s=V(r.projectRoot??a,n,a),l=function(r,n){if("auto"!==n)return n;let o=function(r){let n=t.join(r,"package.json");if(!q(n))throw new k("INVALID_ARGS",`package.json not found at ${n}`);return JSON.parse(e.readFileSync(n,"utf8"))}(r);return"string"==typeof({...o.dependencies??{},...o.devDependencies??{}}).expo?"expo":"react-native"}(s,r.kind??"auto"),u=z(r.metroPort??8081,8081),c=J(r.listenHost)??"0.0.0.0",d=J(r.statusHost)??"127.0.0.1",m=G(r.publicBaseUrl),p=W(r.startupTimeoutMs,18e4,3e4),h=W(r.probeTimeoutMs,1e4,1e3),f=r.reuseExisting??!0,g=r.installDependenciesIfNeeded??!0,y=r.runtimeFilePath?V(r.runtimeFilePath,n,a):null,b=V(r.logPath??t.join(s,".agent-device","metro.log"),n,a);if(!m&&!G(r.proxyBaseUrl))throw new k("INVALID_ARGS","metro prepare requires --public-base-url <url>.");let{proxyEnabled:S,proxyBaseUrl:w,proxyBearerToken:P}=function(e,t){if(e&&!t)throw new k("INVALID_ARGS","metro prepare requires proxy auth when --proxy-base-url is provided. Pass --bearer-token or set AGENT_DEVICE_PROXY_TOKEN.");if(!e&&t)throw new k("INVALID_ARGS","metro prepare requires --proxy-base-url when proxy auth is provided.");return{proxyEnabled:!!(e&&t),proxyBaseUrl:e,proxyBearerToken:t}}(G(r.proxyBaseUrl),J(r.proxyBearerToken)??""),v=S?function(e){if(!e?.tenantId||!e.runId||!e.leaseId)throw new k("INVALID_ARGS","metro prepare with proxy requires tenantId, runId, and leaseId bridge scope.");return e}(r.bridgeScope):null,U=g?function(r,n){if(function(t){try{return e.statSync(t).isDirectory()}catch{return!1}}(t.join(r,"node_modules")))return{installed:!1};let o=q(t.join(r,"pnpm-lock.yaml"))?{command:"pnpm",installArgs:["install"]}:q(t.join(r,"yarn.lock"))?{command:"yarn",installArgs:["install"]}:{command:"npm",installArgs:["install"]};return i(o.command,o.installArgs,{cwd:r,env:n}),{installed:!0,packageManager:o.command}}(s,n):{installed:!1},_=`http://${d}:${u}/status`,I=!1,E=!1,M=0;if(f&&await ee(_,h))E=!0;else if(I=!0,M=function(r,n,i,a,s,l){let u="expo"===n?{command:"npx",installArgs:["expo","start","--host","lan","--port",String(i)]}:{command:"npx",installArgs:["react-native","start","--host",a,"--port",String(i)]};e.mkdirSync(t.dirname(s),{recursive:!0});let c=e.openSync(s,"a"),d=0;try{d=o(u.command,u.installArgs,{cwd:r,env:l,stdio:["ignore",c,c]})}finally{e.closeSync(c)}if(!Number.isInteger(d)||d<=0)throw Error("Failed to start Metro. Expected a detached child PID.");return{pid:d}}(s,l,u,c,b,n).pid,!await es(_,p,h))throw await et(M).catch(()=>{}),Error(`Metro did not become ready at ${_} within ${p}ms. Check ${b}.`);let N=m?X(m,"ios"):{platform:"ios"},A=m?X(m,"android"):{platform:"android"},R=null,$=null;if(v)try{R=await ei({baseUrl:w,bearerToken:P,scope:v,timeoutMs:h})}catch(e){if(!eo(e))throw e;$=e instanceof Error?e.message:String(e)}if(v&&(!R||!1===R.probe.reachable)){let e;try{e=(await F({projectRoot:s,serverBaseUrl:w,bearerToken:P,bridgeScope:v,localBaseUrl:`http://${d}:${u}`,launchUrl:J(r.launchUrl),profileKey:J(r.companionProfileKey),consumerKey:J(r.companionConsumerKey),env:n})).logPath}catch(e){throw Error(ea(w,e instanceof Error?e.message:String(e),R,$))}try{R=await el({baseUrl:w,bearerToken:P,scope:v,probeTimeoutMs:h,startupTimeoutMs:p,initialBridgeError:$,companionLogPath:e})}catch(e){throw e instanceof Error?e:Error(String(e))}}v&&function(e,t){if(!t?.iosRuntime.bundleUrl)throw Error(ea(e,"bridge descriptor is missing ios_runtime.metro_bundle_url",t))}(w,R);let x=R?.iosRuntime??N,j=R?.androidRuntime??A,D={projectRoot:s,kind:l,dependenciesInstalled:U.installed,packageManager:U.packageManager??null,started:I,reused:E,pid:M,logPath:b,statusUrl:_,runtimeFilePath:y,iosRuntime:x,androidRuntime:j,bridge:R};return y&&(e.mkdirSync(t.dirname(y),{recursive:!0}),e.writeFileSync(y,JSON.stringify(D,null,2))),D}async function ec(e={}){let t=W(e.timeoutMs,1e4,1e3),r=function(e){var t;let r,n=J(e.bundleUrl)??e.runtime?.bundleUrl,o=!!J(e.bundleUrl),i=!!J(n),a=l({metroHost:J(e.metroHost)??(o?void 0:J(e.runtime?.metroHost))??(i?void 0:"localhost"),metroPort:void 0!==e.metroPort?z(e.metroPort,8081):o?void 0:e.runtime?.metroPort??(i?void 0:8081),bundleUrl:n});if(!a)throw new k("INVALID_ARGS","Unable to resolve Metro host and port for reload.");return t=function(e){let t=J(e);if(!t)return"/reload";let r=new URL(t).pathname.replace(/\/+$/,"");return r.endsWith("/index.bundle")?`${r.slice(0,-13)}/reload`:"/reload"}(n),(r=new URL(`${a.scheme}://localhost`)).hostname=a.host,r.port=String(a.port),r.pathname=t,r.toString()}(e),n=await Z(r,t);if(!n.ok)throw new k("COMMAND_FAILED",`Metro reload failed (${n.status}).`,{reloadUrl:r,status:n.status,body:n.body,hint:"Verify Metro is running and the target React Native app is connected to this Metro instance."});return{reloaded:!0,reloadUrl:r,status:n.status,body:n.body}}export{X as buildMetroRuntimeHints,F as ensureMetroCompanion,eu as prepareMetroRuntime,ec as reloadMetro,L as stopMetroCompanion};
1
+ import e from"node:fs";import r from"node:path";import{createHash as t}from"node:crypto";import{fileURLToPath as n}from"node:url";import{runCmdDetached as o,runCmdSync as i}from"./9818.js";import{readProcessCommand as a,waitForProcessExit as s,resolveRuntimeTransportHints as l,isProcessAlive as u,readProcessStartTime as c}from"./8656.js";import{normalizeBaseUrl as d,ENV_COMPANION_TUNNEL_BEARER_TOKEN as m,ENV_COMPANION_TUNNEL_SERVER_BASE_URL as p,ENV_COMPANION_TUNNEL_STATE_PATH as f,ENV_COMPANION_TUNNEL_LAUNCH_URL as h,ENV_COMPANION_TUNNEL_SCOPE_LEASE_ID as g,ENV_COMPANION_TUNNEL_SCOPE_TENANT_ID as y,ENV_COMPANION_TUNNEL_DEVICE_PORT as b,buildBundleUrl as S,METRO_COMPANION_RUN_ARG as w,ENV_COMPANION_TUNNEL_SESSION as P,ENV_COMPANION_TUNNEL_SCOPE_RUN_ID as v,ENV_COMPANION_TUNNEL_REGISTER_PATH as U,ENV_COMPANION_TUNNEL_LOCAL_BASE_URL as _,ENV_COMPANION_TUNNEL_UNREGISTER_PATH as I}from"./2301.js";import{AppError as E}from"./9152.js";import{resolveUserPath as M}from"./3267.js";import{sleep as k}from"./4829.js";let N="companion-tunnel";function $(e){return t("sha256").update(e).digest("hex")}function A(e){return e?.trim()?e.trim():void 0}function R(e,t,n,o){let i=o??r.join(e,".agent-device");if(!n)return{statePath:r.join(i,`${t.slug}.json`),logPath:r.join(i,`${t.slug}.log`)};let a=$(n).slice(0,12),s=r.join(i,t.slug);return{statePath:r.join(s,`${t.slug}-${a}.json`),logPath:r.join(s,`${t.slug}-${a}.log`)}}function x(r){try{let t=JSON.parse(e.readFileSync(r,"utf8"));if(!Number.isInteger(t.pid)||0>=Number(t.pid)||"string"!=typeof t.serverBaseUrl||"string"!=typeof t.localBaseUrl||"string"!=typeof t.tokenHash||0===t.tokenHash.length)return null;let n=Array.isArray(t.consumers)?t.consumers.filter(e=>"string"==typeof e&&e.length>0):[];return{pid:Number(t.pid),startTime:"string"==typeof t.startTime?t.startTime:void 0,command:"string"==typeof t.command?t.command:void 0,serverBaseUrl:t.serverBaseUrl,localBaseUrl:t.localBaseUrl,launchUrl:A("string"==typeof t.launchUrl?t.launchUrl:void 0),registerPath:A("string"==typeof t.registerPath?t.registerPath:void 0),unregisterPath:A("string"==typeof t.unregisterPath?t.unregisterPath:void 0),devicePort:Number.isInteger(t.devicePort)?Number(t.devicePort):void 0,session:A("string"==typeof t.session?t.session:void 0),bridgeScope:function(e){if(!(!e||"object"!=typeof e||Array.isArray(e))&&"string"==typeof e.tenantId&&"string"==typeof e.runId&&"string"==typeof e.leaseId)return{tenantId:e.tenantId,runId:e.runId,leaseId:e.leaseId}}(t.bridgeScope),tokenHash:t.tokenHash,consumers:n}}catch{return null}}function T(t,n){e.mkdirSync(r.dirname(t),{recursive:!0}),e.writeFileSync(t,`${JSON.stringify(n,null,2)}
2
+ `,"utf8")}function j(r){try{let t=e.readdirSync(r);0===t.length&&e.rmdirSync(r)}catch{}}function C(t,n){let o=r.dirname(t.statePath),i=r.dirname(t.logPath);var a=t.statePath;try{e.unlinkSync(a)}catch{}var s=t.logPath;try{e.unlinkSync(s)}catch{}j(o),i!==o&&j(i),r.basename(o)===n.slug&&j(r.dirname(o))}function B(e,r){return e.includes(r.runArg)}function K(e){return A(e.consumerKey)??A(e.profileKey)??null}function D(e,r){return!r||e.consumers.includes(r)?e:{...e,consumers:[...e.consumers,r]}}async function H(e,r){if(!u(e.pid))return;let t=a(e.pid);if(t&&B(t,r)){try{process.kill(e.pid,"SIGTERM")}catch(r){let e=r.code;if("ESRCH"===e||"EPERM"===e)return;throw r}if(!await s(e.pid,1e3)){try{process.kill(e.pid,"SIGKILL")}catch(r){let e=r.code;if("ESRCH"===e||"EPERM"===e)return;throw r}await s(e.pid,1e3)}}}async function O(t){let i=K(t),s=R(t.projectRoot,t.definition,t.profileKey,t.stateDir),l=x(s.statePath);if(l&&function(e,r){var t,n;if(!u(e.pid))return!1;if(e.startTime){let r=c(e.pid);if(!r||r!==e.startTime)return!1}let o=a(e.pid);return!!o&&!!B(o,r.definition)&&!!e.bridgeScope&&e.serverBaseUrl===d(r.serverBaseUrl)&&e.localBaseUrl===d(r.localBaseUrl)&&e.launchUrl===A(r.launchUrl)&&e.registerPath===A(r.registerPath)&&e.unregisterPath===A(r.unregisterPath)&&e.devicePort===r.devicePort&&e.session===A(r.session)&&(t=e.bridgeScope,n=r.bridgeScope,t.tenantId===n.tenantId&&t.runId===n.runId&&t.leaseId===n.leaseId)&&e.tokenHash===$(r.bearerToken)}(l,t)){let e=D(l,i);return e!==l&&T(s.statePath,e),{pid:l.pid,spawned:!1,statePath:s.statePath,logPath:s.logPath}}l&&(await H(l,t.definition),C(s,t.definition));let S=function(t,i){let s=function(t){let o=n(import.meta.url),i=r.extname(o)||".js",a=[r.join(r.dirname(o),`${N}${i}`),r.join(r.dirname(o),"internal",`${N}${i}`)].find(r=>e.existsSync(r));if(!a)throw Error(`${t.displayName} entrypoint not found. Rebuild the package to include the companion worker entry.`);return a}(t.definition),l=s.endsWith(".ts")?["--experimental-strip-types"]:[];e.mkdirSync(r.dirname(i),{recursive:!0});let u=e.openSync(i,"a"),S=0;try{let e;S=o(process.execPath,[...l,s,t.definition.runArg],{env:((e={...t.env??process.env})[p]=d(t.serverBaseUrl),e[m]=t.bearerToken,e[_]=d(t.localBaseUrl),e[f]=R(t.projectRoot,t.definition,t.profileKey,t.stateDir).statePath,e[y]=t.bridgeScope.tenantId,e[v]=t.bridgeScope.runId,e[g]=t.bridgeScope.leaseId,t.launchUrl?.trim()?e[h]=t.launchUrl.trim():delete e[h],t.registerPath?.trim()?e[U]=t.registerPath.trim():delete e[U],t.unregisterPath?.trim()?e[I]=t.unregisterPath.trim():delete e[I],void 0!==t.devicePort?e[b]=String(t.devicePort):delete e[b],t.session?.trim()?e[P]=t.session.trim():delete e[P],e),stdio:["ignore",u,u]})}finally{e.closeSync(u)}if(!Number.isInteger(S)||S<=0)throw Error(`Failed to start ${t.definition.displayName} process.`);return{pid:S,startTime:c(S)??void 0,command:a(S)??void 0,serverBaseUrl:d(t.serverBaseUrl),localBaseUrl:d(t.localBaseUrl),launchUrl:A(t.launchUrl),registerPath:A(t.registerPath),unregisterPath:A(t.unregisterPath),devicePort:t.devicePort,session:A(t.session),bridgeScope:t.bridgeScope,tokenHash:$(t.bearerToken),consumers:[]}}(t,s.logPath);return T(s.statePath,D(S,i)),{pid:S.pid,spawned:!0,statePath:s.statePath,logPath:s.logPath}}async function L(e){let r=K(e),t=R(e.projectRoot,e.definition,e.profileKey,e.stateDir),n=x(t.statePath);if(!n)return C(t,e.definition),{stopped:!1,statePath:t.statePath};let o=r?{...n,consumers:n.consumers.filter(e=>e!==r)}:{...n,consumers:[]};return o.consumers.length>0?(T(t.statePath,o),{stopped:!1,statePath:t.statePath}):(await H(n,e.definition),C(t,e.definition),{stopped:!0,statePath:t.statePath})}let G={slug:"metro-companion",runArg:w,displayName:"Metro companion"};async function J(e){return await O({...e,definition:G,registerPath:e.registerPath??"/api/metro/companion/register"})}async function F(e){return await L({...e,definition:G})}function V(e){return"string"==typeof e&&e.trim()?d(e.trim()):""}function q(e){return"string"==typeof e&&e.trim()?e.trim():void 0}function W(e,r,t){return M(e,{env:r,cwd:t})}function z(r){try{return e.accessSync(r,e.constants.F_OK),!0}catch{return!1}}function X(e,r,t){if(null==e||""===e)return r;let n=Number.parseInt(String(e),10);return Number.isInteger(n)?Math.max(n,t):r}function Y(e,r){if(null==e||""===e)return r;let t=Number.parseInt(String(e),10);if(!Number.isInteger(t)||t<1||t>65535)throw new E("INVALID_ARGS",`Invalid Metro port: ${String(e)}. Use 1-65535.`);return t}function Q(e,r){return{platform:r,bundleUrl:S(e,r)}}function Z(e,r){return{platform:r,metroHost:q(e?.metro_host),metroPort:e?.metro_port,bundleUrl:q(e?.metro_bundle_url),launchUrl:q(e?.launch_url)}}async function ee(e){await k(e)}async function er(e,r,t={}){try{let n=await fetch(e,{headers:t,signal:AbortSignal.timeout(r)});return{ok:n.ok,status:n.status,body:await n.text()}}catch(t){if(t instanceof Error&&"TimeoutError"===t.name)throw Error(`Timed out fetching ${e} after ${r}ms`);throw t}}async function et(e,r){try{let t=await er(e,r);return t.ok&&t.body.includes("packager-status:running")}catch{return!1}}async function en(e){if(Number.isInteger(e)&&!(e<=0)){try{process.kill(e,"SIGTERM")}catch(r){let e=r.code;if("ESRCH"===e||"EPERM"===e)return;throw r}if(!await s(e,1e3)){try{process.kill(e,"SIGKILL")}catch(r){let e=r.code;if("ESRCH"===e||"EPERM"===e)return;throw r}await s(e,1e3)}}}function eo(e,r){let t=Error(e);return t.retryable=r,t}function ei(e,r){return!!(e>=500||408===e||425===e||429===e||JSON.stringify(r).includes("Metro companion is not connected"))}function ea(e){return!!(e&&"object"==typeof e&&"retryable"in e&&!0===e.retryable)}async function es(e){let r;try{var t,n;r=await fetch(`${e.baseUrl}/api/metro/bridge`,{method:"POST",headers:(t=e.baseUrl,n=e.bearerToken,{Authorization:`Bearer ${n}`,"Content-Type":"application/json",...t.includes("ngrok")?{"ngrok-skip-browser-warning":"1"}:{}}),body:JSON.stringify({...e.scope,...e.runtime?{ios_runtime:e.runtime}:{},timeout_ms:e.timeoutMs}),signal:AbortSignal.timeout(e.timeoutMs)})}catch(r){if(r instanceof Error&&"TimeoutError"===r.name)throw eo(`/api/metro/bridge timed out after ${e.timeoutMs}ms calling ${e.baseUrl}/api/metro/bridge`,!0);throw eo(r instanceof Error?r.message:String(r),!0)}let o=function(e,r,t){if(!e)return{};try{let r=JSON.parse(e);if(!r||"object"!=typeof r||Array.isArray(r))throw Error("Expected a JSON object");return r}catch(i){let n=e.slice(0,200),o=i instanceof Error?i.message:String(i);throw eo(`/api/metro/bridge returned invalid JSON (${r}) from ${t}: ${o}. body=${JSON.stringify(n)}`,ei(r,e))}}(await r.text(),r.status,e.baseUrl);if(!r.ok)throw eo(`/api/metro/bridge failed (${r.status}): ${JSON.stringify(o)}`,ei(r.status,o));var i=o;let a=i.data??i;if(!a||"object"!=typeof a||Array.isArray(a))throw eo("/api/metro/bridge returned malformed descriptor: Expected a JSON object.",!1);try{return{enabled:a.enabled,baseUrl:a.base_url,statusUrl:a.status_url??"",bundleUrl:a.bundle_url??"",iosRuntime:Z(a.ios_runtime,"ios"),androidRuntime:Z(a.android_runtime,"android"),upstream:{bundleUrl:a.upstream.bundle_url??"",host:a.upstream.host??"",port:a.upstream.port??0,statusUrl:a.upstream.status_url??""},probe:{reachable:a.probe.reachable,statusCode:a.probe.status_code,latencyMs:a.probe.latency_ms,detail:a.probe.detail}}}catch(e){throw eo(`/api/metro/bridge returned malformed descriptor: ${e instanceof Error?e.message:String(e)}`,!1)}}function el(e,r,t,n,o){let i=[`Metro bridge is required for this run but could not be configured via ${e}/api/metro/bridge.`];return r&&i.push(`bridgeError=${r}`),t?.probe.reachable===!1&&i.push(`bridgeProbe=${t.probe.detail||`unreachable (status ${t.probe.statusCode||0})`}`),n&&n!==r&&i.push(`initialBridgeError=${n}`),o&&i.push(`metroCompanionLog=${o}`),i.join(" ")}async function eu(e,r,t){let n=Date.now()+r;for(;Date.now()<n;){let r=Math.min(t,Math.max(n-Date.now(),1));if(await et(e,r))return!0;let o=Math.min(500,Math.max(n-Date.now(),0));o>0&&await ee(o)}return!1}async function ec(e){let r=Date.now()+e.startupTimeoutMs,t=null,n=null;for(;Date.now()<r;){try{let r=await es({baseUrl:e.baseUrl,bearerToken:e.bearerToken,scope:e.scope,runtime:e.runtime,timeoutMs:e.probeTimeoutMs});if(!1!==r.probe.reachable)return r;t=r,n=null}catch(e){if(n=e instanceof Error?e.message:String(e),!ea(e))break}let o=Math.min(1e3,Math.max(r-Date.now(),0));o>0&&await ee(o)}throw Error(el(e.baseUrl,n,t,e.initialBridgeError,e.companionLogPath))}async function ed(t={}){let n=t.env??process.env,a=process.cwd(),s=W(t.projectRoot??a,n,a),l=function(t,n){if("auto"!==n)return n;let o=function(t){let n=r.join(t,"package.json");if(!z(n))throw new E("INVALID_ARGS",`package.json not found at ${n}`);return JSON.parse(e.readFileSync(n,"utf8"))}(t);return"string"==typeof({...o.dependencies??{},...o.devDependencies??{}}).expo?"expo":"react-native"}(s,t.kind??"auto"),u=Y(t.metroPort??8081,8081),c=q(t.listenHost)??"0.0.0.0",d=q(t.statusHost)??"127.0.0.1",m=V(t.publicBaseUrl),p=X(t.startupTimeoutMs,18e4,3e4),f=X(t.probeTimeoutMs,1e4,1e3),h=t.reuseExisting??!0,g=t.installDependenciesIfNeeded??!0,y=t.runtimeFilePath?W(t.runtimeFilePath,n,a):null,b=W(t.logPath??r.join(s,".agent-device","metro.log"),n,a);if(!m&&!V(t.proxyBaseUrl))throw new E("INVALID_ARGS","metro prepare requires --public-base-url <url>.");let{proxyEnabled:S,proxyBaseUrl:w,proxyBearerToken:P}=function(e,r){if(e&&!r)throw new E("INVALID_ARGS","metro prepare requires proxy auth when --proxy-base-url is provided. Pass --bearer-token or set AGENT_DEVICE_PROXY_TOKEN.");if(!e&&r)throw new E("INVALID_ARGS","metro prepare requires --proxy-base-url when proxy auth is provided.");return{proxyEnabled:!!(e&&r),proxyBaseUrl:e,proxyBearerToken:r}}(V(t.proxyBaseUrl),q(t.proxyBearerToken)??""),v=S?function(e){if(!e?.tenantId||!e.runId||!e.leaseId)throw new E("INVALID_ARGS","metro prepare with proxy requires tenantId, runId, and leaseId bridge scope.");return e}(t.bridgeScope):null,U=g?function(t,n){if(function(r){try{return e.statSync(r).isDirectory()}catch{return!1}}(r.join(t,"node_modules")))return{installed:!1};let o=z(r.join(t,"pnpm-lock.yaml"))?{command:"pnpm",installArgs:["install"]}:z(r.join(t,"yarn.lock"))?{command:"yarn",installArgs:["install"]}:{command:"npm",installArgs:["install"]};return i(o.command,o.installArgs,{cwd:t,env:n}),{installed:!0,packageManager:o.command}}(s,n):{installed:!1},_=`http://${d}:${u}/status`,I=!1,M=!1,k=0;if(h&&await et(_,f))M=!0;else if(I=!0,k=function(t,n,i,a,s,l){let u="expo"===n?{command:"npx",installArgs:["expo","start","--host","lan","--port",String(i)]}:{command:"npx",installArgs:["react-native","start","--host",a,"--port",String(i)]};e.mkdirSync(r.dirname(s),{recursive:!0});let c=e.openSync(s,"a"),d=0;try{d=o(u.command,u.installArgs,{cwd:t,env:l,stdio:["ignore",c,c]})}finally{e.closeSync(c)}if(!Number.isInteger(d)||d<=0)throw Error("Failed to start Metro. Expected a detached child PID.");return{pid:d}}(s,l,u,c,b,n).pid,!await eu(_,p,f))throw await en(k).catch(()=>{}),Error(`Metro did not become ready at ${_} within ${p}ms. Check ${b}.`);let N=m?Q(m,"ios"):{platform:"ios"},$=m?Q(m,"android"):{platform:"android"},A=null,R=null;if(v)try{A=await es({baseUrl:w,bearerToken:P,scope:v,timeoutMs:f})}catch(e){if(!ea(e))throw e;R=e instanceof Error?e.message:String(e)}if(v&&(!A||!1===A.probe.reachable)){let e;try{e=(await J({projectRoot:s,serverBaseUrl:w,bearerToken:P,bridgeScope:v,localBaseUrl:`http://${d}:${u}`,launchUrl:q(t.launchUrl),profileKey:q(t.companionProfileKey),consumerKey:q(t.companionConsumerKey),env:n})).logPath}catch(e){throw Error(el(w,e instanceof Error?e.message:String(e),A,R))}try{A=await ec({baseUrl:w,bearerToken:P,scope:v,probeTimeoutMs:f,startupTimeoutMs:p,initialBridgeError:R,companionLogPath:e})}catch(e){throw e instanceof Error?e:Error(String(e))}}v&&function(e,r){if(!r?.iosRuntime.bundleUrl)throw Error(el(e,"bridge descriptor is missing ios_runtime.metro_bundle_url",r))}(w,A);let x=A?.iosRuntime??N,T=A?.androidRuntime??$,j={projectRoot:s,kind:l,dependenciesInstalled:U.installed,packageManager:U.packageManager??null,started:I,reused:M,pid:k,logPath:b,statusUrl:_,runtimeFilePath:y,iosRuntime:x,androidRuntime:T,bridge:A};return y&&(e.mkdirSync(r.dirname(y),{recursive:!0}),e.writeFileSync(y,JSON.stringify(j,null,2))),j}async function em(e={}){let r=X(e.timeoutMs,1e4,1e3),t=function(e){var r;let t,n=q(e.bundleUrl)??e.runtime?.bundleUrl,o=!!q(e.bundleUrl),i=!!q(n),a=l({metroHost:q(e.metroHost)??(o?void 0:q(e.runtime?.metroHost))??(i?void 0:"localhost"),metroPort:void 0!==e.metroPort?Y(e.metroPort,8081):o?void 0:e.runtime?.metroPort??(i?void 0:8081),bundleUrl:n});if(!a)throw new E("INVALID_ARGS","Unable to resolve Metro host and port for reload.");return r=function(e){let r=q(e);if(!r)return"/reload";let t=new URL(r).pathname.replace(/\/+$/,"");return t.endsWith("/index.bundle")?`${t.slice(0,-13)}/reload`:"/reload"}(n),(t=new URL(`${a.scheme}://localhost`)).hostname=a.host,t.port=String(a.port),t.pathname=r,t.toString()}(e),n=await er(t,r);if(!n.ok)throw new E("COMMAND_FAILED",`Metro reload failed (${n.status}).`,{reloadUrl:t,status:n.status,body:n.body,hint:"Verify Metro is running and the target React Native app is connected to this Metro instance."});return{reloaded:!0,reloadUrl:t,status:n.status,body:n.body}}export{Q as buildMetroRuntimeHints,O as ensureCompanionTunnel,J as ensureMetroCompanion,ed as prepareMetroRuntime,em as reloadMetro,L as stopCompanionTunnel,F as stopMetroCompanion};
@@ -0,0 +1 @@
1
+ let N="--agent-device-run-metro-companion",_="--agent-device-run-react-devtools-companion",E="AGENT_DEVICE_COMPANION_TUNNEL_SERVER_BASE_URL",O="AGENT_DEVICE_COMPANION_TUNNEL_BEARER_TOKEN",A="AGENT_DEVICE_COMPANION_TUNNEL_LOCAL_BASE_URL",T="AGENT_DEVICE_COMPANION_TUNNEL_LAUNCH_URL",C="AGENT_DEVICE_COMPANION_TUNNEL_STATE_PATH",I="AGENT_DEVICE_COMPANION_TUNNEL_SCOPE_TENANT_ID",P="AGENT_DEVICE_COMPANION_TUNNEL_SCOPE_RUN_ID",U="AGENT_DEVICE_COMPANION_TUNNEL_SCOPE_LEASE_ID",L="AGENT_DEVICE_COMPANION_TUNNEL_REGISTER_PATH",e="AGENT_DEVICE_COMPANION_TUNNEL_UNREGISTER_PATH",n="AGENT_DEVICE_COMPANION_TUNNEL_DEVICE_PORT",R="AGENT_DEVICE_COMPANION_TUNNEL_SESSION";class r extends Error{name="MissingCompanionEnvError"}function M(N){let _=N.length;for(;_>0&&47===N.charCodeAt(_-1);)_-=1;return _===N.length?N:N.slice(0,_)}function V(N,_){let E=new URL(`${M(N)}/index.bundle`);return E.searchParams.set("platform",_),E.searchParams.set("dev","true"),E.searchParams.set("minify","false"),E.toString()}export{O as ENV_COMPANION_TUNNEL_BEARER_TOKEN,n as ENV_COMPANION_TUNNEL_DEVICE_PORT,T as ENV_COMPANION_TUNNEL_LAUNCH_URL,A as ENV_COMPANION_TUNNEL_LOCAL_BASE_URL,L as ENV_COMPANION_TUNNEL_REGISTER_PATH,U as ENV_COMPANION_TUNNEL_SCOPE_LEASE_ID,P as ENV_COMPANION_TUNNEL_SCOPE_RUN_ID,I as ENV_COMPANION_TUNNEL_SCOPE_TENANT_ID,E as ENV_COMPANION_TUNNEL_SERVER_BASE_URL,R as ENV_COMPANION_TUNNEL_SESSION,C as ENV_COMPANION_TUNNEL_STATE_PATH,e as ENV_COMPANION_TUNNEL_UNREGISTER_PATH,N as METRO_COMPANION_RUN_ARG,r as MissingCompanionEnvError,_ as REACT_DEVTOOLS_COMPANION_RUN_ARG,V as buildBundleUrl,M as normalizeBaseUrl};