agent-device 0.14.5 → 0.14.7
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.
- package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.14.5.apk → agent-device-android-snapshot-helper-0.14.7.apk} +0 -0
- package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.14.7.apk.sha256 +1 -0
- package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.14.5.manifest.json → agent-device-android-snapshot-helper-0.14.7.manifest.json} +6 -6
- package/dist/src/1974.js +2 -2
- package/dist/src/9542.js +1 -1
- package/dist/src/internal/bin.js +70 -61
- package/package.json +1 -1
- package/skills/react-devtools/SKILL.md +10 -1
- package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.14.5.apk.sha256 +0 -1
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
cf52647a87d8724c94c1be073fdee6dd87fd509d2a45111678100c9045ff51ae agent-device-android-snapshot-helper-0.14.7.apk
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "android-snapshot-helper",
|
|
3
|
-
"version": "0.14.
|
|
4
|
-
"releaseTag": "v0.14.
|
|
5
|
-
"assetName": "agent-device-android-snapshot-helper-0.14.
|
|
3
|
+
"version": "0.14.7",
|
|
4
|
+
"releaseTag": "v0.14.7",
|
|
5
|
+
"assetName": "agent-device-android-snapshot-helper-0.14.7.apk",
|
|
6
6
|
"apkUrl": null,
|
|
7
|
-
"sha256": "
|
|
8
|
-
"checksumName": "agent-device-android-snapshot-helper-0.14.
|
|
7
|
+
"sha256": "cf52647a87d8724c94c1be073fdee6dd87fd509d2a45111678100c9045ff51ae",
|
|
8
|
+
"checksumName": "agent-device-android-snapshot-helper-0.14.7.apk.sha256",
|
|
9
9
|
"packageName": "com.callstack.agentdevice.snapshothelper",
|
|
10
|
-
"versionCode":
|
|
10
|
+
"versionCode": 14007,
|
|
11
11
|
"instrumentationRunner": "com.callstack.agentdevice.snapshothelper/.SnapshotInstrumentation",
|
|
12
12
|
"minSdk": 23,
|
|
13
13
|
"targetSdk": 36,
|
package/dist/src/1974.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
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
|
|
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};
|
|
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 i,runCmdSync as o}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,i){let o=i??r.join(e,".agent-device");if(!n)return{statePath:r.join(o,`${t.slug}.json`),logPath:r.join(o,`${t.slug}.log`)};let a=$(n).slice(0,12),s=r.join(o,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 i=r.dirname(t.statePath),o=r.dirname(t.logPath);var a=t.statePath;try{e.unlinkSync(a)}catch{}var s=t.logPath;try{e.unlinkSync(s)}catch{}j(i),o!==i&&j(o),r.basename(i)===n.slug&&j(r.dirname(i))}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){var o;let s,l=K(t),S=R(t.projectRoot,t.definition,t.profileKey,t.stateDir),w=x(S.statePath);if(w&&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 i=a(e.pid);return!!i&&!!B(i,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)}(w,t)){let e=D(w,l);return e!==w&&T(S.statePath,e),{pid:w.pid,spawned:!1,statePath:S.statePath,logPath:S.logPath}}w&&(await H(w,t.definition),C(S,t.definition)),o=S.statePath,e.mkdirSync(r.dirname(o),{recursive:!0}),e.closeSync(e.openSync(o,"a"));try{s=function(t,o){let s=function(t){let i=n(import.meta.url),o=r.extname(i)||".js",a=[r.join(r.dirname(i),`${N}${o}`),r.join(r.dirname(i),"internal",`${N}${o}`)].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(o),{recursive:!0});let u=e.openSync(o,"a"),S=0;try{let e;S=i(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),T(S.statePath,D(s,l))}catch(e){throw s&&await H(s,t.definition).catch(()=>{}),C(S,t.definition),e}return{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 i=r?{...n,consumers:n.consumers.filter(e=>e!==r)}:{...n,consumers:[]};return i.consumers.length>0?(T(t.statePath,i),{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 ei(e,r){let t=Error(e);return t.retryable=r,t}function eo(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 ei(`/api/metro/bridge timed out after ${e.timeoutMs}ms calling ${e.baseUrl}/api/metro/bridge`,!0);throw ei(r instanceof Error?r.message:String(r),!0)}let i=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(o){let n=e.slice(0,200),i=o instanceof Error?o.message:String(o);throw ei(`/api/metro/bridge returned invalid JSON (${r}) from ${t}: ${i}. body=${JSON.stringify(n)}`,eo(r,e))}}(await r.text(),r.status,e.baseUrl);if(!r.ok)throw ei(`/api/metro/bridge failed (${r.status}): ${JSON.stringify(i)}`,eo(r.status,i));var o=i;let a=o.data??o;if(!a||"object"!=typeof a||Array.isArray(a))throw ei("/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 ei(`/api/metro/bridge returned malformed descriptor: ${e instanceof Error?e.message:String(e)}`,!1)}}function el(e,r,t,n,i){let o=[`Metro bridge is required for this run but could not be configured via ${e}/api/metro/bridge.`];return r&&o.push(`bridgeError=${r}`),t?.probe.reachable===!1&&o.push(`bridgeProbe=${t.probe.detail||`unreachable (status ${t.probe.statusCode||0})`}`),n&&n!==r&&o.push(`initialBridgeError=${n}`),i&&o.push(`metroCompanionLog=${i}`),o.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 i=Math.min(500,Math.max(n-Date.now(),0));i>0&&await ee(i)}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 i=Math.min(1e3,Math.max(r-Date.now(),0));i>0&&await ee(i)}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 i=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({...i.dependencies??{},...i.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 i=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 o(i.command,i.installArgs,{cwd:t,env:n}),{installed:!0,packageManager:i.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,o,a,s,l){let u="expo"===n?{command:"npx",installArgs:["expo","start","--host","lan","--port",String(o)]}:{command:"npx",installArgs:["react-native","start","--host",a,"--port",String(o)]};e.mkdirSync(r.dirname(s),{recursive:!0});let c=e.openSync(s,"a"),d=0;try{d=i(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,i=!!q(e.bundleUrl),o=!!q(n),a=l({metroHost:q(e.metroHost)??(i?void 0:q(e.runtime?.metroHost))??(o?void 0:"localhost"),metroPort:void 0!==e.metroPort?Y(e.metroPort,8081):i?void 0:e.runtime?.metroPort??(o?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};
|
package/dist/src/9542.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import e from"node:net";import t from"node:http";import a from"node:https";import r from"node:fs";import o from"node:path";import{pipeline as n}from"node:stream/promises";import i from"node:os";import{createHash as s,randomUUID as l}from"node:crypto";import{Writable as d}from"node:stream";import{toAppErrorCode as c,AppError as u}from"./9152.js";import{runCmdSync as p,runCmd as m,runCmdDetached as f}from"./9818.js";import{buildDeviceIdentifiers as h,resolveDaemonPaths as y,readVersion as w,findProjectRoot as v,resolveDaemonServerMode as g,computeDaemonCodeSignature as I,resolveDaemonTransportPreference as b,buildAppIdentifiers as A}from"./180.js";import{createRequestId as _,withDiagnosticTimer as M,emitDiagnostic as S}from"./7599.js";import{isAgentDeviceDaemonProcess as k,stopProcessForTakeover as E}from"./8656.js";import{sleep as D}from"./4829.js";import{tryParseSelectorChain as P}from"./940.js";import{reloadMetro as T,prepareMetroRuntime as N}from"./1974.js";let U="sha256";async function x(e){let t=await C(e.localPath,e.platform),a=e.baseUrl.endsWith("/")?e.baseUrl:`${e.baseUrl}/`;try{let r=await F({normalizedBase:a,token:e.token,artifact:t});if(r?.kind==="cache-hit")return r.uploadId;if(r?.kind==="direct-upload")try{return await B(t.payloadPath,r),await j({normalizedBase:a,token:e.token,uploadId:r.uploadId})}catch{}return await L({normalizedBase:a,token:e.token,artifact:t})}finally{t.cleanup()}}async function C(e,t){var a,n,i;let s,l=r.statSync(e),d=o.basename(e),c=l.isDirectory(),u=("ios"===(a=t)||"android"===a?a:void 0)??(n=e,i=l,s=n.toLowerCase(),i.isDirectory()&&s.endsWith(".app")||s.endsWith(".ipa")?"ios":s.endsWith(".apk")||s.endsWith(".aab")?"android":void 0),p=[];try{let t=c?await R(e,p):e,a=r.statSync(t);return{payloadPath:t,fileName:d,artifactType:c?"app-bundle":"file",platform:u,contentType:c?"application/gzip":"application/octet-stream",sha256:await z(t),sizeBytes:a.size,cleanup:()=>O(p)}}catch(e){throw O(p),e}}async function R(e,t){let a=r.mkdtempSync(o.join(i.tmpdir(),`agent-device-upload-${l()}-`));t.push(a);let n=o.join(a,`${o.basename(e)}.tar.gz`);return await m("tar",["czf",n,"-C",o.dirname(e),o.basename(e)]),n}function O(e){for(let t of e)r.rmSync(t,{recursive:!0,force:!0})}async function L(e){let{normalizedBase:t,token:a,artifact:r}=e,o=new URL("upload",t),n={"content-type":r.contentType,"x-artifact-type":r.artifactType,"x-artifact-filename":r.fileName,"x-artifact-hash":r.sha256,"x-artifact-hash-algorithm":U,"transfer-encoding":"chunked"};a&&(n.authorization=`Bearer ${a}`,n["x-agent-device-token"]=a);let i=await q({url:o,method:"POST",headers:n,payloadPath:r.payloadPath,timeoutMessage:"Artifact upload timed out",timeoutHint:"The upload to the remote daemon exceeded the 5-minute timeout.",errorMessage:"Failed to upload artifact to remote daemon",errorHint:"Verify the remote daemon is reachable and supports artifact uploads."});try{let e=JSON.parse(i.body);if(!e.ok||!e.uploadId)throw new u("COMMAND_FAILED",`Upload failed: ${i.body}`);return e.uploadId}catch(e){if(e instanceof u)throw e;throw new u("COMMAND_FAILED",`Invalid upload response: ${i.body}`)}}async function F(e){let t=new URL("upload/preflight",e.normalizedBase),a={"content-type":"application/json"};e.token&&(a.authorization=`Bearer ${e.token}`,a["x-agent-device-token"]=e.token);let r=await fetch(t,{method:"POST",headers:a,signal:AbortSignal.timeout(3e4),body:JSON.stringify({sha256:e.artifact.sha256,fileName:e.artifact.fileName,sizeBytes:e.artifact.sizeBytes,artifactType:e.artifact.artifactType,...e.artifact.platform?{platform:e.artifact.platform}:{},contentType:e.artifact.contentType})}).catch(()=>void 0);if(r?.ok)return function(e){var t;if(!e||"object"!=typeof e||!0!==e.ok||"string"!=typeof e.uploadId)return;if(!0===e.cacheHit)return{kind:"cache-hit",uploadId:e.uploadId};let a=e.upload;if(!a||"string"!=typeof a.url)return;let r=a.headers??{};if(!(!(t=r)||"object"!=typeof t||Array.isArray(t))&&Object.values(t).every(e=>"string"==typeof e))return{kind:"direct-upload",uploadId:e.uploadId,url:a.url,headers:r}}(await r.json().catch(()=>void 0))}async function B(e,t){let a=await q({url:new URL(t.url),method:"PUT",headers:t.headers,payloadPath:e,timeoutMessage:"Direct artifact upload timed out",timeoutHint:"The direct upload ticket did not accept the artifact within the timeout.",errorMessage:"Failed to upload artifact with direct upload ticket"});if(a.statusCode<200||a.statusCode>=300)throw new u("COMMAND_FAILED","Direct artifact upload failed",{statusCode:a.statusCode,statusMessage:a.statusMessage})}async function q(e){let o="https:"===e.url.protocol?a:t;return await new Promise((t,a)=>{let i=o.request({protocol:e.url.protocol,host:e.url.hostname,port:e.url.port,method:e.method,path:e.url.pathname+e.url.search,headers:e.headers},e=>{let a="";e.setEncoding("utf8"),e.on("data",e=>{a+=e}),e.on("end",()=>{clearTimeout(s),t({statusCode:e.statusCode??500,statusMessage:e.statusMessage,body:a})})}),s=setTimeout(()=>{i.destroy(),a(new u("COMMAND_FAILED",e.timeoutMessage,{timeoutMs:3e5,...e.timeoutHint?{hint:e.timeoutHint}:{}}))},3e5);i.on("error",t=>{clearTimeout(s),a(new u("COMMAND_FAILED",e.errorMessage,e.errorHint?{hint:e.errorHint}:{},t))}),i.on("close",()=>clearTimeout(s)),n(r.createReadStream(e.payloadPath),i).catch(e=>{i.destroy(),a(new u("COMMAND_FAILED","Failed to read local artifact",{},e instanceof Error?e:Error(String(e))))})})}async function j(e){let t=new URL("upload/finalize",e.normalizedBase),a={"content-type":"application/json"};e.token&&(a.authorization=`Bearer ${e.token}`,a["x-agent-device-token"]=e.token);let r=await fetch(t,{method:"POST",headers:a,signal:AbortSignal.timeout(3e4),body:JSON.stringify({uploadId:e.uploadId})}).catch(e=>{throw new u("COMMAND_FAILED","Failed to finalize direct artifact upload",{},e)});if(!r.ok)throw new u("COMMAND_FAILED","Direct artifact upload finalize failed",{status:r.status,statusText:r.statusText});let o=await r.json().catch(()=>void 0);if(!o?.ok||!o.uploadId)throw new u("COMMAND_FAILED","Invalid upload finalize response");return o.uploadId}async function z(e){let t=s(U),a=new d({write(e,a,r){t.update(e),r()}});return await n(r.createReadStream(e),a).catch(e=>{throw new u("COMMAND_FAILED","Failed to read local artifact",{},e instanceof Error?e:void 0)}),t.digest("hex")}let $=eA(),H=function(e=process.env.AGENT_DEVICE_DAEMON_STARTUP_TIMEOUT_MS){if(!e)return 15e3;let t=Number(e);return Number.isFinite(t)?Math.max(1e3,Math.floor(t)):15e3}(),V=function(e=process.env.AGENT_DEVICE_DAEMON_STARTUP_ATTEMPTS){if(!e)return 2;let t=Number(e);return Number.isFinite(t)?Math.min(5,Math.max(1,Math.floor(t))):2}(),G=["xcodebuild .*AgentDeviceRunnerUITests/RunnerTests/testCommand","xcodebuild .*AgentDeviceRunner\\.env\\.session-","xcodebuild build-for-testing .*ios-runner/AgentDeviceRunner/AgentDeviceRunner\\.xcodeproj"],K=new e.BlockList;async function J(t){let a=t.meta?.requestId??_(),r=!!(t.meta?.debug||t.flags?.verbose),o=function(t){let a,r=t.flags?.stateDir??process.env.AGENT_DEVICE_STATE_DIR,o=function(e){let t;if(e){try{t=new URL(e)}catch(t){throw new u("INVALID_ARGS","Invalid daemon base URL",{daemonBaseUrl:e},t instanceof Error?t:void 0)}if("http:"!==t.protocol&&"https:"!==t.protocol)throw new u("INVALID_ARGS","Daemon base URL must use http or https",{daemonBaseUrl:e});return t.toString().replace(/\/+$/,"")}}(t.flags?.daemonBaseUrl??process.env.AGENT_DEVICE_DAEMON_BASE_URL),n=t.flags?.daemonAuthToken??process.env.AGENT_DEVICE_DAEMON_AUTH_TOKEN;var i=o,s=n;if(!(!i||"localhost"===(a=new URL(i).hostname.trim().toLowerCase().replace(/^\[(.*)\]$/,"$1"))||(e.isIPv4(a)?K.check(a,"ipv4"):!!e.isIPv6(a)&&K.check(a,"ipv6")))&&("string"!=typeof s||!(s.trim().length>0)))throw new u("INVALID_ARGS","Remote daemon base URL for non-loopback hosts requires daemon authentication",{daemonBaseUrl:i,hint:"Provide --daemon-auth-token or AGENT_DEVICE_DAEMON_AUTH_TOKEN when using a non-loopback remote daemon URL."});let l=t.flags?.daemonTransport??process.env.AGENT_DEVICE_DAEMON_TRANSPORT,d=b(l);if(o&&"socket"===d)throw new u("INVALID_ARGS","Remote daemon base URL only supports HTTP transport. Remove --daemon-transport socket.",{daemonBaseUrl:o});let c=g(t.flags?.daemonServerMode??process.env.AGENT_DEVICE_DAEMON_SERVER_MODE??("dual"===l?"dual":void 0));return{paths:y(r),transportPreference:d,serverMode:c,remoteBaseUrl:o,remoteAuthToken:n}}(t),n=function(e,t=process.env.AGENT_DEVICE_DAEMON_TIMEOUT_MS){if("test"!==e)return eA(t)}(t.command),i=await M("daemon_startup",async()=>await Z(o),{requestId:a,session:t.session}),s=await W(t,i),l={...t,positionals:s.positionals,flags:s.flags,token:i.token,meta:{...t.meta??{},requestId:a,debug:r,cwd:t.meta?.cwd,tenantId:t.meta?.tenantId??t.flags?.tenant,runId:t.meta?.runId??t.flags?.runId,leaseId:t.meta?.leaseId??t.flags?.leaseId,sessionIsolation:t.meta?.sessionIsolation??t.flags?.sessionIsolation,lockPolicy:t.meta?.lockPolicy,lockPlatform:t.meta?.lockPlatform,...s.uploadedArtifactId?{uploadedArtifactId:s.uploadedArtifactId}:{},...s.clientArtifactPaths?{clientArtifactPaths:s.clientArtifactPaths}:{},...s.installSource?{installSource:s.installSource}:{}}};return S({level:"info",phase:"daemon_request_prepare",data:{requestId:a,command:t.command,session:t.session}}),await M("daemon_request",async()=>await eu(i,l,o.transportPreference,n),{requestId:a,command:t.command})}async function W(e,t){let a,n=[...e.positionals??[]],i=e.flags?{...e.flags}:void 0,s=e.meta?.installSource,l={};if(ev(t)){let r=function(e,t){if("screenshot"===e.command){let a=X(e,"path",".png");return t[0]?{field:"path",localPath:a,positionalIndex:0,positionalPath:Y("screenshot",".png")}:{field:"path",localPath:a,positionalIndex:0,flagPath:Y("screenshot",".png")}}if("record"===e.command&&"start"===(t[0]??"").toLowerCase()){let t=X(e,"outPath",".mp4",1);return{field:"outPath",localPath:t,positionalIndex:1,positionalPath:Y("recording",o.extname(t)||".mp4")}}return null}(e,n);r&&(void 0!==r.positionalPath&&(n[r.positionalIndex]=r.positionalPath),void 0!==r.flagPath&&((i??={}).out=r.flagPath),l[r.field]=r.localPath);let d=await Q(e,t);d&&(s=d.installSource,a=d.uploadedArtifactId??a)}if(!ev(t)||"install"!==e.command&&"reinstall"!==e.command||n.length<2)return{positionals:n,flags:i,installSource:s,uploadedArtifactId:a,...Object.keys(l).length>0?{clientArtifactPaths:l}:{}};let d=n[1];if(d.startsWith("remote:"))return n[1]=d.slice(7),{positionals:n,flags:i,...Object.keys(l).length>0?{clientArtifactPaths:l}:{}};let c=o.isAbsolute(d)?d:o.resolve(e.meta?.cwd??process.cwd(),d);return r.existsSync(c)?{positionals:n,flags:i,installSource:s,uploadedArtifactId:a=await x({localPath:c,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform}),...Object.keys(l).length>0?{clientArtifactPaths:l}:{}}:{positionals:n,flags:i,...Object.keys(l).length>0?{clientArtifactPaths:l}:{}}}async function Q(e,t){let a=e.meta?.installSource;if("install_source"!==e.command||!a||"path"!==a.kind)return null;let n=a.path.trim();if(!n)return{installSource:a};if(n.startsWith("remote:"))return{installSource:{...a,path:n.slice(7)}};let i=o.isAbsolute(n)?n:o.resolve(e.meta?.cwd??process.cwd(),n);if(!r.existsSync(i))return{installSource:{...a,path:i}};let s=await x({localPath:i,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform});return{installSource:{...a,path:i},uploadedArtifactId:s}}function X(e,t,a,r=0){let n=e.positionals?.[r]??e.flags?.out,i=`${"path"===t?"screenshot":"recording"}-${Date.now()}${a}`,s=n&&n.trim().length>0?n:i;return o.isAbsolute(s)?s:o.resolve(e.meta?.cwd??process.cwd(),s)}function Y(e,t){let a=t.startsWith(".")?t:`.${t}`;return o.posix.join("/tmp",`agent-device-${e}-${Date.now()}-${Math.random().toString(36).slice(2,8)}${a}`)}async function Z(e){let t;if(e.remoteBaseUrl){let t={transport:"http",token:e.remoteAuthToken??"",pid:0,baseUrl:e.remoteBaseUrl};if(await el(t,"http"))return t;throw new u("COMMAND_FAILED","Remote daemon is unavailable",{daemonBaseUrl:e.remoteBaseUrl,hint:"Verify AGENT_DEVICE_DAEMON_BASE_URL points to a reachable daemon with GET /health and POST /rpc."})}let a=er(e.paths.infoPath),r=w(),o=I((t=ec()).useSrc?t.srcPath:t.distPath,t.root),n=!!a&&await el(a,e.transportPreference);if(a&&a.version===r&&a.codeSignature===o&&n)return a;a&&(a.version!==r||a.codeSignature!==o||!n)&&(await ea(a),es(e.paths.infoPath)),function(e){let t=en(e);if(!t.hasLock||t.hasInfo)return;let a=eo(e.lockPath);if(!a)return es(e.lockPath);k(a.pid,a.processStartTime)||es(e.lockPath)}(e.paths);let i=0;for(let t=1;t<=V;t+=1){await ed(e);let a=await ee(H,e);if(a)return a;if(await et(e.paths)){i+=1;continue}let r=en(e.paths);if(!(t<V))break;if(!r.hasInfo&&!r.hasLock){await D(150);continue}}let s=en(e.paths);throw new u("COMMAND_FAILED","Failed to start daemon",{kind:"daemon_startup_failed",infoPath:e.paths.infoPath,lockPath:e.paths.lockPath,startupTimeoutMs:H,startupAttempts:V,lockRecoveryCount:i,metadataState:s,hint:function(e,t=y(process.env.AGENT_DEVICE_STATE_DIR)){return e.hasLock&&!e.hasInfo?`Detected ${t.lockPath} without ${t.infoPath}. If no agent-device daemon process is running, delete ${t.lockPath} and retry.`:e.hasLock&&e.hasInfo?`Daemon metadata may be stale. If no agent-device daemon process is running, delete ${t.infoPath} and ${t.lockPath}, then retry.`:`Daemon metadata is missing or stale. Delete ${t.infoPath} if present and retry.`}(s,e.paths)})}async function ee(e,t){let a=Date.now();for(;Date.now()-a<e;){let e=er(t.paths.infoPath);if(e&&await el(e,t.transportPreference))return e;await D(100)}return null}async function et(e){let t=en(e);if(!t.hasLock||t.hasInfo)return!1;let a=eo(e.lockPath);return a&&k(a.pid,a.processStartTime)&&await E(a.pid,{termTimeoutMs:3e3,killTimeoutMs:1e3,expectedStartTime:a.processStartTime}),es(e.lockPath),!0}async function ea(e){await E(e.pid,{termTimeoutMs:3e3,killTimeoutMs:1e3,expectedStartTime:e.processStartTime})}function er(e){let t=ei(e);if(!t||"object"!=typeof t)return null;let a="string"==typeof t.token&&t.token.length>0?t.token:null;if(!a)return null;let r=Number.isInteger(t.port)&&Number(t.port)>0,o=Number.isInteger(t.httpPort)&&Number(t.httpPort)>0;if(!r&&!o)return null;let n=t.transport,i="string"==typeof t.version?t.version:void 0,s="string"==typeof t.codeSignature?t.codeSignature:void 0,l="string"==typeof t.processStartTime?t.processStartTime:void 0,d=Number.isInteger(t.pid)&&Number(t.pid)>0;return{token:a,port:r?Number(t.port):void 0,httpPort:o?Number(t.httpPort):void 0,transport:"socket"===n||"http"===n||"dual"===n?n:void 0,pid:d?Number(t.pid):0,version:i,codeSignature:s,processStartTime:l}}function eo(e){let t=ei(e);return t&&"object"==typeof t&&Number.isInteger(t.pid)&&Number(t.pid)>0?{pid:Number(t.pid),processStartTime:"string"==typeof t.processStartTime?t.processStartTime:void 0,startedAt:"number"==typeof t.startedAt?t.startedAt:void 0}:null}K.addSubnet("127.0.0.0",8,"ipv4"),K.addAddress("::1","ipv6"),K.addSubnet("::ffff:127.0.0.0",104,"ipv6");function en(e){return{hasInfo:r.existsSync(e.infoPath),hasLock:r.existsSync(e.lockPath)}}function ei(e){if(!r.existsSync(e))return null;try{return JSON.parse(r.readFileSync(e,"utf8"))}catch{return null}}function es(e){try{r.existsSync(e)&&r.unlinkSync(e)}catch{}}async function el(r,o){var n;return"http"===ep(r,o)?await function(e){let r=e.baseUrl?eg(e.baseUrl,"health"):e.httpPort?`http://127.0.0.1:${e.httpPort}/health`:null;if(!r)return Promise.resolve(!1);let o=new URL(r),n="https:"===o.protocol?a:t,i=e.baseUrl?3e3:500;return new Promise(e=>{let t=n.request({protocol:o.protocol,host:o.hostname,port:o.port,path:o.pathname+o.search,method:"GET",timeout:i},t=>{t.resume(),e((t.statusCode??500)<500)});t.on("timeout",()=>{t.destroy(),e(!1)}),t.on("error",()=>{e(!1)}),t.end()})}(r):await ((n=r.port)?new Promise(t=>{let a=e.createConnection({host:"127.0.0.1",port:n},()=>{a.destroy(),t(!0)});a.on("error",()=>{t(!1)})}):Promise.resolve(!1))}async function ed(e){let t=ec(),a=t.useSrc?["--experimental-strip-types",t.srcPath]:[t.distPath],r={...process.env,AGENT_DEVICE_STATE_DIR:e.paths.baseDir,AGENT_DEVICE_DAEMON_SERVER_MODE:e.serverMode};f(process.execPath,a,{env:r})}function ec(){let e=v(),t=[o.join(e,"dist","src","internal","daemon.js"),o.join(e,"dist","src","daemon.js")],a=t.find(e=>r.existsSync(e))??t[0],n=o.join(e,"src","daemon.ts"),i=t.some(e=>r.existsSync(e)),s=r.existsSync(n);if(!i&&!s)throw new u("COMMAND_FAILED","Daemon entry not found",{distPaths:t,srcPath:n});return{root:e,distPath:a,distPaths:t,srcPath:n,useSrc:process.execArgv.includes("--experimental-strip-types")?s:!i&&s}}async function eu(e,t,a,r){return"http"===ep(e,a)?await ew(e,t,r):await ey(e,t,r)}function ep(e,t){if(e.baseUrl){if("socket"===t)throw new u("COMMAND_FAILED","Remote daemon endpoint only supports HTTP transport",{daemonBaseUrl:e.baseUrl});return"http"}if("http"===t||"socket"===t){var a=e,r=t;if(em(a,r))return r;throw new u("COMMAND_FAILED","http"===r?"Daemon HTTP endpoint is unavailable":"Daemon socket endpoint is unavailable")}let o=("socket"===e.transport||"dual"===e.transport?["socket","http"]:["http","socket"]).find(t=>em(e,t));if(o)return o;throw new u("COMMAND_FAILED","Daemon metadata has no reachable transport")}function em(e,t){return"http"===t?!!e.httpPort:!!e.port}function ef(e,t,a,r,o,n){let i=o?{terminated:0}:function(){let e=0;try{for(let t of G){let a=p("pkill",["-f",t],{allowFailure:!0});0===a.exitCode&&(e+=1)}return{terminated:e}}catch(t){return{terminated:e,error:t instanceof Error?t.message:String(t)}}}(),s=o?{forcedKill:!1}:function(e,t){let a=!1;try{k(e.pid,e.processStartTime)&&(process.kill(e.pid,"SIGKILL"),a=!0)}catch{E(e.pid,{termTimeoutMs:3e3,killTimeoutMs:1e3,expectedStartTime:e.processStartTime})}finally{es(t.infoPath),es(t.lockPath)}return{forcedKill:a}}(e,t);return S({level:"error",phase:"daemon_request_timeout",data:{timeoutMs:n,requestId:a,command:r,timedOutRunnerPidsTerminated:i.terminated,timedOutRunnerCleanupError:i.error,daemonPidReset:o?void 0:e.pid,daemonPidForceKilled:o?void 0:s.forcedKill,daemonBaseUrl:e.baseUrl}}),new u("COMMAND_FAILED","Daemon request timed out",{timeoutMs:n,requestId:a,hint:o?"Retry with --debug and verify the remote daemon URL, auth token, and remote host logs.":"Retry with --debug and check daemon diagnostics logs. Timed-out iOS runner xcodebuild processes were terminated when detected."})}function eh(e,t,a){return S({level:"error",phase:"daemon_request_socket_error",data:{requestId:t,message:e instanceof Error?e.message:String(e)}}),new u("COMMAND_FAILED","Failed to communicate with daemon",{requestId:t,hint:a?"Retry command. If this persists, verify the remote daemon URL, auth token, and remote host reachability.":"Retry command. If this persists, clean stale daemon metadata and start a fresh session."},e instanceof Error?e:void 0)}async function ey(t,a,r){let o=t.port;if(!o)throw new u("COMMAND_FAILED","Daemon socket endpoint is unavailable");return new Promise((n,i)=>{let s=e.createConnection({host:"127.0.0.1",port:o},()=>{s.write(`${JSON.stringify(a)}
|
|
1
|
+
import e from"node:net";import t from"node:http";import a from"node:https";import r from"node:fs";import o from"node:path";import{pipeline as n}from"node:stream/promises";import i from"node:os";import{createHash as s,randomUUID as l}from"node:crypto";import{Writable as d}from"node:stream";import{toAppErrorCode as c,AppError as u}from"./9152.js";import{runCmdSync as p,runCmd as m,runCmdDetached as f}from"./9818.js";import{buildDeviceIdentifiers as h,resolveDaemonPaths as y,readVersion as w,findProjectRoot as v,resolveDaemonServerMode as g,computeDaemonCodeSignature as I,resolveDaemonTransportPreference as b,buildAppIdentifiers as A}from"./180.js";import{createRequestId as _,withDiagnosticTimer as M,emitDiagnostic as S}from"./7599.js";import{isAgentDeviceDaemonProcess as k,stopProcessForTakeover as E}from"./8656.js";import{sleep as D}from"./4829.js";import{tryParseSelectorChain as P}from"./940.js";import{reloadMetro as T,prepareMetroRuntime as N}from"./1974.js";let U="sha256";async function x(e){let t=await C(e.localPath,e.platform),a=e.baseUrl.endsWith("/")?e.baseUrl:`${e.baseUrl}/`;try{let r=await F({normalizedBase:a,token:e.token,artifact:t});if(r?.kind==="cache-hit")return r.uploadId;if(r?.kind==="direct-upload")try{return await B(t.payloadPath,r),await j({normalizedBase:a,token:e.token,uploadId:r.uploadId})}catch{}return await L({normalizedBase:a,token:e.token,artifact:t})}finally{t.cleanup()}}async function C(e,t){var a,n,i;let s,l=r.statSync(e),d=o.basename(e),c=l.isDirectory(),u=("ios"===(a=t)||"android"===a?a:void 0)??(n=e,i=l,s=n.toLowerCase(),i.isDirectory()&&s.endsWith(".app")||s.endsWith(".ipa")?"ios":s.endsWith(".apk")||s.endsWith(".aab")?"android":void 0),p=[];try{let t=c?await R(e,p):e,a=r.statSync(t);return{payloadPath:t,fileName:d,artifactType:c?"app-bundle":"file",platform:u,contentType:c?"application/gzip":"application/octet-stream",sha256:await z(t),sizeBytes:a.size,cleanup:()=>O(p)}}catch(e){throw O(p),e}}async function R(e,t){let a=r.mkdtempSync(o.join(i.tmpdir(),`agent-device-upload-${l()}-`));t.push(a);let n=o.join(a,`${o.basename(e)}.tar.gz`);return await m("tar",["czf",n,"-C",o.dirname(e),o.basename(e)],{env:{...process.env,COPYFILE_DISABLE:"1"}}),n}function O(e){for(let t of e)r.rmSync(t,{recursive:!0,force:!0})}async function L(e){let{normalizedBase:t,token:a,artifact:r}=e,o=new URL("upload",t),n={"content-type":r.contentType,"x-artifact-type":r.artifactType,"x-artifact-filename":r.fileName,"x-artifact-hash":r.sha256,"x-artifact-hash-algorithm":U,"transfer-encoding":"chunked"};a&&(n.authorization=`Bearer ${a}`,n["x-agent-device-token"]=a);let i=await q({url:o,method:"POST",headers:n,payloadPath:r.payloadPath,timeoutMessage:"Artifact upload timed out",timeoutHint:"The upload to the remote daemon exceeded the 5-minute timeout.",errorMessage:"Failed to upload artifact to remote daemon",errorHint:"Verify the remote daemon is reachable and supports artifact uploads."});try{let e=JSON.parse(i.body);if(!e.ok||!e.uploadId)throw new u("COMMAND_FAILED",`Upload failed: ${i.body}`);return e.uploadId}catch(e){if(e instanceof u)throw e;throw new u("COMMAND_FAILED",`Invalid upload response: ${i.body}`)}}async function F(e){let t=new URL("upload/preflight",e.normalizedBase),a={"content-type":"application/json"};e.token&&(a.authorization=`Bearer ${e.token}`,a["x-agent-device-token"]=e.token);let r=await fetch(t,{method:"POST",headers:a,signal:AbortSignal.timeout(3e4),body:JSON.stringify({sha256:e.artifact.sha256,fileName:e.artifact.fileName,sizeBytes:e.artifact.sizeBytes,artifactType:e.artifact.artifactType,...e.artifact.platform?{platform:e.artifact.platform}:{},contentType:e.artifact.contentType})}).catch(()=>void 0);if(r?.ok)return function(e){var t;if(!e||"object"!=typeof e||!0!==e.ok||"string"!=typeof e.uploadId)return;if(!0===e.cacheHit)return{kind:"cache-hit",uploadId:e.uploadId};let a=e.upload;if(!a||"string"!=typeof a.url)return;let r=a.headers??{};if(!(!(t=r)||"object"!=typeof t||Array.isArray(t))&&Object.values(t).every(e=>"string"==typeof e))return{kind:"direct-upload",uploadId:e.uploadId,url:a.url,headers:r}}(await r.json().catch(()=>void 0))}async function B(e,t){let a=await q({url:new URL(t.url),method:"PUT",headers:t.headers,payloadPath:e,timeoutMessage:"Direct artifact upload timed out",timeoutHint:"The direct upload ticket did not accept the artifact within the timeout.",errorMessage:"Failed to upload artifact with direct upload ticket"});if(a.statusCode<200||a.statusCode>=300)throw new u("COMMAND_FAILED","Direct artifact upload failed",{statusCode:a.statusCode,statusMessage:a.statusMessage})}async function q(e){let o="https:"===e.url.protocol?a:t;return await new Promise((t,a)=>{let i=o.request({protocol:e.url.protocol,host:e.url.hostname,port:e.url.port,method:e.method,path:e.url.pathname+e.url.search,headers:e.headers},e=>{let a="";e.setEncoding("utf8"),e.on("data",e=>{a+=e}),e.on("end",()=>{clearTimeout(s),t({statusCode:e.statusCode??500,statusMessage:e.statusMessage,body:a})})}),s=setTimeout(()=>{i.destroy(),a(new u("COMMAND_FAILED",e.timeoutMessage,{timeoutMs:3e5,...e.timeoutHint?{hint:e.timeoutHint}:{}}))},3e5);i.on("error",t=>{clearTimeout(s),a(new u("COMMAND_FAILED",e.errorMessage,e.errorHint?{hint:e.errorHint}:{},t))}),i.on("close",()=>clearTimeout(s)),n(r.createReadStream(e.payloadPath),i).catch(e=>{i.destroy(),a(new u("COMMAND_FAILED","Failed to read local artifact",{},e instanceof Error?e:Error(String(e))))})})}async function j(e){let t=new URL("upload/finalize",e.normalizedBase),a={"content-type":"application/json"};e.token&&(a.authorization=`Bearer ${e.token}`,a["x-agent-device-token"]=e.token);let r=await fetch(t,{method:"POST",headers:a,signal:AbortSignal.timeout(3e4),body:JSON.stringify({uploadId:e.uploadId})}).catch(e=>{throw new u("COMMAND_FAILED","Failed to finalize direct artifact upload",{},e)});if(!r.ok)throw new u("COMMAND_FAILED","Direct artifact upload finalize failed",{status:r.status,statusText:r.statusText});let o=await r.json().catch(()=>void 0);if(!o?.ok||!o.uploadId)throw new u("COMMAND_FAILED","Invalid upload finalize response");return o.uploadId}async function z(e){let t=s(U),a=new d({write(e,a,r){t.update(e),r()}});return await n(r.createReadStream(e),a).catch(e=>{throw new u("COMMAND_FAILED","Failed to read local artifact",{},e instanceof Error?e:void 0)}),t.digest("hex")}let $=eA(),H=function(e=process.env.AGENT_DEVICE_DAEMON_STARTUP_TIMEOUT_MS){if(!e)return 15e3;let t=Number(e);return Number.isFinite(t)?Math.max(1e3,Math.floor(t)):15e3}(),V=function(e=process.env.AGENT_DEVICE_DAEMON_STARTUP_ATTEMPTS){if(!e)return 2;let t=Number(e);return Number.isFinite(t)?Math.min(5,Math.max(1,Math.floor(t))):2}(),G=["xcodebuild .*AgentDeviceRunnerUITests/RunnerTests/testCommand","xcodebuild .*AgentDeviceRunner\\.env\\.session-","xcodebuild build-for-testing .*ios-runner/AgentDeviceRunner/AgentDeviceRunner\\.xcodeproj"],K=new e.BlockList;async function J(t){let a=t.meta?.requestId??_(),r=!!(t.meta?.debug||t.flags?.verbose),o=function(t){let a,r=t.flags?.stateDir??process.env.AGENT_DEVICE_STATE_DIR,o=function(e){let t;if(e){try{t=new URL(e)}catch(t){throw new u("INVALID_ARGS","Invalid daemon base URL",{daemonBaseUrl:e},t instanceof Error?t:void 0)}if("http:"!==t.protocol&&"https:"!==t.protocol)throw new u("INVALID_ARGS","Daemon base URL must use http or https",{daemonBaseUrl:e});return t.toString().replace(/\/+$/,"")}}(t.flags?.daemonBaseUrl??process.env.AGENT_DEVICE_DAEMON_BASE_URL),n=t.flags?.daemonAuthToken??process.env.AGENT_DEVICE_DAEMON_AUTH_TOKEN;var i=o,s=n;if(!(!i||"localhost"===(a=new URL(i).hostname.trim().toLowerCase().replace(/^\[(.*)\]$/,"$1"))||(e.isIPv4(a)?K.check(a,"ipv4"):!!e.isIPv6(a)&&K.check(a,"ipv6")))&&("string"!=typeof s||!(s.trim().length>0)))throw new u("INVALID_ARGS","Remote daemon base URL for non-loopback hosts requires daemon authentication",{daemonBaseUrl:i,hint:"Provide --daemon-auth-token or AGENT_DEVICE_DAEMON_AUTH_TOKEN when using a non-loopback remote daemon URL."});let l=t.flags?.daemonTransport??process.env.AGENT_DEVICE_DAEMON_TRANSPORT,d=b(l);if(o&&"socket"===d)throw new u("INVALID_ARGS","Remote daemon base URL only supports HTTP transport. Remove --daemon-transport socket.",{daemonBaseUrl:o});let c=g(t.flags?.daemonServerMode??process.env.AGENT_DEVICE_DAEMON_SERVER_MODE??("dual"===l?"dual":void 0));return{paths:y(r),transportPreference:d,serverMode:c,remoteBaseUrl:o,remoteAuthToken:n}}(t),n=function(e,t=process.env.AGENT_DEVICE_DAEMON_TIMEOUT_MS){if("test"!==e)return eA(t)}(t.command),i=await M("daemon_startup",async()=>await Z(o),{requestId:a,session:t.session}),s=await W(t,i),l={...t,positionals:s.positionals,flags:s.flags,token:i.token,meta:{...t.meta??{},requestId:a,debug:r,cwd:t.meta?.cwd,tenantId:t.meta?.tenantId??t.flags?.tenant,runId:t.meta?.runId??t.flags?.runId,leaseId:t.meta?.leaseId??t.flags?.leaseId,sessionIsolation:t.meta?.sessionIsolation??t.flags?.sessionIsolation,lockPolicy:t.meta?.lockPolicy,lockPlatform:t.meta?.lockPlatform,...s.uploadedArtifactId?{uploadedArtifactId:s.uploadedArtifactId}:{},...s.clientArtifactPaths?{clientArtifactPaths:s.clientArtifactPaths}:{},...s.installSource?{installSource:s.installSource}:{}}};return S({level:"info",phase:"daemon_request_prepare",data:{requestId:a,command:t.command,session:t.session}}),await M("daemon_request",async()=>await eu(i,l,o.transportPreference,n),{requestId:a,command:t.command})}async function W(e,t){let a,n=[...e.positionals??[]],i=e.flags?{...e.flags}:void 0,s=e.meta?.installSource,l={};if(ev(t)){let r=function(e,t){if("screenshot"===e.command){let a=Q(e,"path",".png");return t[0]?{field:"path",localPath:a,positionalIndex:0,positionalPath:X("screenshot",".png")}:{field:"path",localPath:a,positionalIndex:0,flagPath:X("screenshot",".png")}}if("record"===e.command&&"start"===(t[0]??"").toLowerCase()){let t=Q(e,"outPath",".mp4",1);return{field:"outPath",localPath:t,positionalIndex:1,positionalPath:X("recording",o.extname(t)||".mp4")}}return null}(e,n);r&&(void 0!==r.positionalPath&&(n[r.positionalIndex]=r.positionalPath),void 0!==r.flagPath&&((i??={}).out=r.flagPath),l[r.field]=r.localPath);let d=await Y(e,t);d&&(s=d.installSource,a=d.uploadedArtifactId??a)}if(!ev(t)||"install"!==e.command&&"reinstall"!==e.command||n.length<2)return{positionals:n,flags:i,installSource:s,uploadedArtifactId:a,...Object.keys(l).length>0?{clientArtifactPaths:l}:{}};let d=n[1];if(d.startsWith("remote:"))return n[1]=d.slice(7),{positionals:n,flags:i,...Object.keys(l).length>0?{clientArtifactPaths:l}:{}};let c=o.isAbsolute(d)?d:o.resolve(e.meta?.cwd??process.cwd(),d);return r.existsSync(c)?{positionals:n,flags:i,installSource:s,uploadedArtifactId:a=await x({localPath:c,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform}),...Object.keys(l).length>0?{clientArtifactPaths:l}:{}}:{positionals:n,flags:i,...Object.keys(l).length>0?{clientArtifactPaths:l}:{}}}async function Y(e,t){let a=e.meta?.installSource;if("install_source"!==e.command||!a||"path"!==a.kind)return null;let n=a.path.trim();if(!n)return{installSource:a};if(n.startsWith("remote:"))return{installSource:{...a,path:n.slice(7)}};let i=o.isAbsolute(n)?n:o.resolve(e.meta?.cwd??process.cwd(),n);if(!r.existsSync(i))return{installSource:{...a,path:i}};let s=await x({localPath:i,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform});return{installSource:{...a,path:i},uploadedArtifactId:s}}function Q(e,t,a,r=0){let n=e.positionals?.[r]??e.flags?.out,i=`${"path"===t?"screenshot":"recording"}-${Date.now()}${a}`,s=n&&n.trim().length>0?n:i;return o.isAbsolute(s)?s:o.resolve(e.meta?.cwd??process.cwd(),s)}function X(e,t){let a=t.startsWith(".")?t:`.${t}`;return o.posix.join("/tmp",`agent-device-${e}-${Date.now()}-${Math.random().toString(36).slice(2,8)}${a}`)}async function Z(e){let t;if(e.remoteBaseUrl){let t={transport:"http",token:e.remoteAuthToken??"",pid:0,baseUrl:e.remoteBaseUrl};if(await el(t,"http"))return t;throw new u("COMMAND_FAILED","Remote daemon is unavailable",{daemonBaseUrl:e.remoteBaseUrl,hint:"Verify AGENT_DEVICE_DAEMON_BASE_URL points to a reachable daemon with GET /health and POST /rpc."})}let a=er(e.paths.infoPath),r=w(),o=I((t=ec()).useSrc?t.srcPath:t.distPath,t.root),n=!!a&&await el(a,e.transportPreference);if(a&&a.version===r&&a.codeSignature===o&&n)return a;a&&(a.version!==r||a.codeSignature!==o||!n)&&(await ea(a),es(e.paths.infoPath)),function(e){let t=en(e);if(!t.hasLock||t.hasInfo)return;let a=eo(e.lockPath);if(!a)return es(e.lockPath);k(a.pid,a.processStartTime)||es(e.lockPath)}(e.paths);let i=0;for(let t=1;t<=V;t+=1){await ed(e);let a=await ee(H,e);if(a)return a;if(await et(e.paths)){i+=1;continue}let r=en(e.paths);if(!(t<V))break;if(!r.hasInfo&&!r.hasLock){await D(150);continue}}let s=en(e.paths);throw new u("COMMAND_FAILED","Failed to start daemon",{kind:"daemon_startup_failed",infoPath:e.paths.infoPath,lockPath:e.paths.lockPath,startupTimeoutMs:H,startupAttempts:V,lockRecoveryCount:i,metadataState:s,hint:function(e,t=y(process.env.AGENT_DEVICE_STATE_DIR)){return e.hasLock&&!e.hasInfo?`Detected ${t.lockPath} without ${t.infoPath}. If no agent-device daemon process is running, delete ${t.lockPath} and retry.`:e.hasLock&&e.hasInfo?`Daemon metadata may be stale. If no agent-device daemon process is running, delete ${t.infoPath} and ${t.lockPath}, then retry.`:`Daemon metadata is missing or stale. Delete ${t.infoPath} if present and retry.`}(s,e.paths)})}async function ee(e,t){let a=Date.now();for(;Date.now()-a<e;){let e=er(t.paths.infoPath);if(e&&await el(e,t.transportPreference))return e;await D(100)}return null}async function et(e){let t=en(e);if(!t.hasLock||t.hasInfo)return!1;let a=eo(e.lockPath);return a&&k(a.pid,a.processStartTime)&&await E(a.pid,{termTimeoutMs:3e3,killTimeoutMs:1e3,expectedStartTime:a.processStartTime}),es(e.lockPath),!0}async function ea(e){await E(e.pid,{termTimeoutMs:3e3,killTimeoutMs:1e3,expectedStartTime:e.processStartTime})}function er(e){let t=ei(e);if(!t||"object"!=typeof t)return null;let a="string"==typeof t.token&&t.token.length>0?t.token:null;if(!a)return null;let r=Number.isInteger(t.port)&&Number(t.port)>0,o=Number.isInteger(t.httpPort)&&Number(t.httpPort)>0;if(!r&&!o)return null;let n=t.transport,i="string"==typeof t.version?t.version:void 0,s="string"==typeof t.codeSignature?t.codeSignature:void 0,l="string"==typeof t.processStartTime?t.processStartTime:void 0,d=Number.isInteger(t.pid)&&Number(t.pid)>0;return{token:a,port:r?Number(t.port):void 0,httpPort:o?Number(t.httpPort):void 0,transport:"socket"===n||"http"===n||"dual"===n?n:void 0,pid:d?Number(t.pid):0,version:i,codeSignature:s,processStartTime:l}}function eo(e){let t=ei(e);return t&&"object"==typeof t&&Number.isInteger(t.pid)&&Number(t.pid)>0?{pid:Number(t.pid),processStartTime:"string"==typeof t.processStartTime?t.processStartTime:void 0,startedAt:"number"==typeof t.startedAt?t.startedAt:void 0}:null}K.addSubnet("127.0.0.0",8,"ipv4"),K.addAddress("::1","ipv6"),K.addSubnet("::ffff:127.0.0.0",104,"ipv6");function en(e){return{hasInfo:r.existsSync(e.infoPath),hasLock:r.existsSync(e.lockPath)}}function ei(e){if(!r.existsSync(e))return null;try{return JSON.parse(r.readFileSync(e,"utf8"))}catch{return null}}function es(e){try{r.existsSync(e)&&r.unlinkSync(e)}catch{}}async function el(r,o){var n;return"http"===ep(r,o)?await function(e){let r=e.baseUrl?eg(e.baseUrl,"health"):e.httpPort?`http://127.0.0.1:${e.httpPort}/health`:null;if(!r)return Promise.resolve(!1);let o=new URL(r),n="https:"===o.protocol?a:t,i=e.baseUrl?3e3:500;return new Promise(e=>{let t=n.request({protocol:o.protocol,host:o.hostname,port:o.port,path:o.pathname+o.search,method:"GET",timeout:i},t=>{t.resume(),e((t.statusCode??500)<500)});t.on("timeout",()=>{t.destroy(),e(!1)}),t.on("error",()=>{e(!1)}),t.end()})}(r):await ((n=r.port)?new Promise(t=>{let a=e.createConnection({host:"127.0.0.1",port:n},()=>{a.destroy(),t(!0)});a.on("error",()=>{t(!1)})}):Promise.resolve(!1))}async function ed(e){let t=ec(),a=t.useSrc?["--experimental-strip-types",t.srcPath]:[t.distPath],r={...process.env,AGENT_DEVICE_STATE_DIR:e.paths.baseDir,AGENT_DEVICE_DAEMON_SERVER_MODE:e.serverMode};f(process.execPath,a,{env:r})}function ec(){let e=v(),t=[o.join(e,"dist","src","internal","daemon.js"),o.join(e,"dist","src","daemon.js")],a=t.find(e=>r.existsSync(e))??t[0],n=o.join(e,"src","daemon.ts"),i=t.some(e=>r.existsSync(e)),s=r.existsSync(n);if(!i&&!s)throw new u("COMMAND_FAILED","Daemon entry not found",{distPaths:t,srcPath:n});return{root:e,distPath:a,distPaths:t,srcPath:n,useSrc:process.execArgv.includes("--experimental-strip-types")?s:!i&&s}}async function eu(e,t,a,r){return"http"===ep(e,a)?await ew(e,t,r):await ey(e,t,r)}function ep(e,t){if(e.baseUrl){if("socket"===t)throw new u("COMMAND_FAILED","Remote daemon endpoint only supports HTTP transport",{daemonBaseUrl:e.baseUrl});return"http"}if("http"===t||"socket"===t){var a=e,r=t;if(em(a,r))return r;throw new u("COMMAND_FAILED","http"===r?"Daemon HTTP endpoint is unavailable":"Daemon socket endpoint is unavailable")}let o=("socket"===e.transport||"dual"===e.transport?["socket","http"]:["http","socket"]).find(t=>em(e,t));if(o)return o;throw new u("COMMAND_FAILED","Daemon metadata has no reachable transport")}function em(e,t){return"http"===t?!!e.httpPort:!!e.port}function ef(e,t,a,r,o,n){let i=o?{terminated:0}:function(){let e=0;try{for(let t of G){let a=p("pkill",["-f",t],{allowFailure:!0});0===a.exitCode&&(e+=1)}return{terminated:e}}catch(t){return{terminated:e,error:t instanceof Error?t.message:String(t)}}}(),s=o?{forcedKill:!1}:function(e,t){let a=!1;try{k(e.pid,e.processStartTime)&&(process.kill(e.pid,"SIGKILL"),a=!0)}catch{E(e.pid,{termTimeoutMs:3e3,killTimeoutMs:1e3,expectedStartTime:e.processStartTime})}finally{es(t.infoPath),es(t.lockPath)}return{forcedKill:a}}(e,t);return S({level:"error",phase:"daemon_request_timeout",data:{timeoutMs:n,requestId:a,command:r,timedOutRunnerPidsTerminated:i.terminated,timedOutRunnerCleanupError:i.error,daemonPidReset:o?void 0:e.pid,daemonPidForceKilled:o?void 0:s.forcedKill,daemonBaseUrl:e.baseUrl}}),new u("COMMAND_FAILED","Daemon request timed out",{timeoutMs:n,requestId:a,hint:o?"Retry with --debug and verify the remote daemon URL, auth token, and remote host logs.":"Retry with --debug and check daemon diagnostics logs. Timed-out iOS runner xcodebuild processes were terminated when detected."})}function eh(e,t,a){return S({level:"error",phase:"daemon_request_socket_error",data:{requestId:t,message:e instanceof Error?e.message:String(e)}}),new u("COMMAND_FAILED","Failed to communicate with daemon",{requestId:t,hint:a?"Retry command. If this persists, verify the remote daemon URL, auth token, and remote host reachability.":"Retry command. If this persists, clean stale daemon metadata and start a fresh session."},e instanceof Error?e:void 0)}async function ey(t,a,r){let o=t.port;if(!o)throw new u("COMMAND_FAILED","Daemon socket endpoint is unavailable");return new Promise((n,i)=>{let s=e.createConnection({host:"127.0.0.1",port:o},()=>{s.write(`${JSON.stringify(a)}
|
|
2
2
|
`)}),l=y(a.flags?.stateDir??process.env.AGENT_DEVICE_STATE_DIR),d="number"==typeof r?setTimeout(()=>{s.destroy(),i(ef(t,l,a.meta?.requestId,a.command,!1,r))},r):void 0,c="";s.setEncoding("utf8"),s.on("data",e=>{let t=(c+=e).indexOf("\n");if(-1===t)return;let r=c.slice(0,t).trim();if(r)try{let e=JSON.parse(r);s.end(),d&&clearTimeout(d),n(e)}catch(e){d&&clearTimeout(d),i(new u("COMMAND_FAILED","Invalid daemon response",{requestId:a.meta?.requestId,line:r},e instanceof Error?e:void 0))}}),s.on("error",e=>{d&&clearTimeout(d),i(eh(e,a.meta?.requestId,!1))})})}async function ew(e,r,o){var n,i,s;let l,d=e.baseUrl?new URL(eg(e.baseUrl,"rpc")):e.httpPort?new URL(`http://127.0.0.1:${e.httpPort}/rpc`):null;if(!d)throw new u("COMMAND_FAILED","Daemon HTTP endpoint is unavailable");let p=JSON.stringify((n=r,i={includeTokenParam:!e.baseUrl},l=n.meta?.requestId??_(),"lease_allocate"!==(s=n.command)&&"lease_heartbeat"!==s&&"lease_release"!==s?{jsonrpc:"2.0",id:l,method:"agent_device.command",params:n}:{jsonrpc:"2.0",id:l,method:function(e){switch(e){case"lease_allocate":return"agent_device.lease.allocate";case"lease_heartbeat":return"agent_device.lease.heartbeat";case"lease_release":return"agent_device.lease.release"}}(n.command),params:function(e,t,a){let r={...a.includeTokenParam?{token:e.token}:{},session:e.session,tenantId:e.meta?.tenantId,runId:e.meta?.runId};switch(t){case"lease_allocate":return{...r,ttlMs:e.meta?.leaseTtlMs,backend:e.meta?.leaseBackend};case"lease_heartbeat":return{...r,leaseId:e.meta?.leaseId,ttlMs:e.meta?.leaseTtlMs};case"lease_release":return{...r,leaseId:e.meta?.leaseId}}}(n,n.command,i)})),m={"content-type":"application/json","content-length":Buffer.byteLength(p)};return e.baseUrl&&e.token&&(m.authorization=`Bearer ${e.token}`,m["x-agent-device-token"]=e.token),await new Promise((n,i)=>{let s=y(r.flags?.stateDir??process.env.AGENT_DEVICE_STATE_DIR),l=("https:"===d.protocol?a:t).request({protocol:d.protocol,host:d.hostname,port:d.port,method:"POST",path:d.pathname+d.search,headers:m},t=>{let a="";t.setEncoding("utf8"),t.on("data",e=>{a+=e}),t.on("end",()=>{h&&clearTimeout(h);try{let t=JSON.parse(a);if(t.error){let e=t.error.data??{};i(new u(c(null!=e.code?String(e.code):void 0,"COMMAND_FAILED"),String(e.message??t.error.message??"Daemon RPC request failed"),{..."object"==typeof e.details&&e.details?e.details:{},hint:"string"==typeof e.hint?e.hint:void 0,diagnosticId:"string"==typeof e.diagnosticId?e.diagnosticId:void 0,logPath:"string"==typeof e.logPath?e.logPath:void 0,requestId:r.meta?.requestId}));return}if(!t.result||"object"!=typeof t.result)return void i(new u("COMMAND_FAILED","Invalid daemon RPC response",{requestId:r.meta?.requestId}));if(e.baseUrl&&t.result.ok)return void eI(e,r,t.result).then(n).catch(i);n(t.result)}catch(e){h&&clearTimeout(h),i(new u("COMMAND_FAILED","Invalid daemon response",{requestId:r.meta?.requestId,line:a},e instanceof Error?e:void 0))}})}),f=ev(e),h="number"==typeof o?setTimeout(()=>{l.destroy(),i(ef(e,s,r.meta?.requestId,r.command,f,o))},o):void 0;l.on("error",e=>{h&&clearTimeout(h),i(eh(e,r.meta?.requestId,f))}),l.write(p),l.end()})}function ev(e){return"string"==typeof e.baseUrl&&e.baseUrl.length>0}function eg(e,t){return new URL(t,e.endsWith("/")?e:`${e}/`).toString()}async function eI(e,t,a){let r=Array.isArray(a.data?.artifacts)?a.data.artifacts:[];if(0===r.length||!e.baseUrl)return a;let n=a.data?{...a.data}:{},i=[];for(let a of r){if(!a||"object"!=typeof a||"string"!=typeof a.artifactId){i.push(a);continue}let r=function(e,t){if(e.localPath&&e.localPath.trim().length>0)return e.localPath;let a=e.fileName?.trim()||`${e.field}-${Date.now()}`;return o.resolve(t.meta?.cwd??process.cwd(),a)}(a,t);await eb({baseUrl:e.baseUrl,token:e.token,artifactId:a.artifactId,destinationPath:r,requestId:t.meta?.requestId}),n[a.field]=r,i.push({...a,localPath:r})}return n.artifacts=i,{ok:!0,data:n}}async function eb(e){var i,s;let l,d=new URL((i=e.baseUrl,s=e.artifactId,l=i.endsWith("/")?i:`${i}/`,new URL(`artifacts/${encodeURIComponent(s)}`,l).toString())),c="https:"===d.protocol?a:t;await r.promises.mkdir(o.dirname(e.destinationPath),{recursive:!0}),await new Promise((t,a)=>{let o=!1,i=e.timeoutMs??$,s=n=>{if(!o){if(o=!0,clearTimeout(p),n)return void r.promises.rm(e.destinationPath,{force:!0}).finally(()=>a(n));t()}},l=c.request({protocol:d.protocol,host:d.hostname,port:d.port,method:"GET",path:d.pathname+d.search,headers:e.token?{authorization:`Bearer ${e.token}`,"x-agent-device-token":e.token}:void 0},t=>{if((t.statusCode??500)>=400){let a="";t.setEncoding("utf8"),t.on("data",e=>{a+=e}),t.on("end",()=>{s(new u("COMMAND_FAILED","Failed to download remote artifact",{artifactId:e.artifactId,statusCode:t.statusCode,requestId:e.requestId,body:a}))});return}t.on("aborted",()=>{s(new u("COMMAND_FAILED","Remote artifact download was interrupted",{artifactId:e.artifactId,requestId:e.requestId}))}),n(t,r.createWriteStream(e.destinationPath)).then(()=>s(),e=>s(e instanceof Error?e:Error(String(e))))}),p=setTimeout(()=>{l.destroy(new u("COMMAND_FAILED","Remote artifact download timed out",{artifactId:e.artifactId,requestId:e.requestId,timeoutMs:i}))},i);l.on("error",t=>{t instanceof u?s(t):s(new u("COMMAND_FAILED","Failed to download remote artifact",{artifactId:e.artifactId,requestId:e.requestId,timeoutMs:i},t instanceof Error?t:void 0))}),l.end()})}function eA(e=process.env.AGENT_DEVICE_DAEMON_TIMEOUT_MS){if(!e)return 9e4;let t=Number(e);return Number.isFinite(t)?Math.max(1e3,Math.floor(t)):9e4}let e_={alert:"alert",appState:"appstate",appSwitcher:"app-switcher",apps:"apps",back:"back",batch:"batch",boot:"boot",click:"click",clipboard:"clipboard",devices:"devices",diff:"diff",fill:"fill",find:"find",focus:"focus",get:"get",home:"home",is:"is",keyboard:"keyboard",logs:"logs",longPress:"longpress",network:"network",perf:"perf",pinch:"pinch",press:"press",push:"push",record:"record",replay:"replay",rotate:"rotate",scroll:"scroll",screenshot:"screenshot",settings:"settings",snapshot:"snapshot",swipe:"swipe",test:"test",trace:"trace",triggerAppEvent:"trigger-app-event",type:"type",wait:"wait"};function eM(e,t,a,r){let o=a(e[t]);if(void 0===o)throw new u("COMMAND_FAILED",r,{response:e});return o}function eS(e,t){return eM(e,t,eN,`Daemon response is missing "${t}".`)}function ek(e,t){return eN(e[t])}function eE(e,t){var a;let r;return a=eN,null===(r=e[t])?null:a(r)}function eD(e,t){return eM(e,t,ex,`Daemon response has invalid "${t}".`)}function eP(e,t){return function(e){return"tv"===e||"mobile"===e||"desktop"===e?e:void 0}(e[t])??"mobile"}function eT(e,t){let a=e[t];if(!eO(a))return;let r="number"==typeof a.x?a.x:void 0,o="number"==typeof a.y?a.y:void 0,n="number"==typeof a.width?a.width:void 0,i="number"==typeof a.height?a.height:void 0;if(void 0!==r&&void 0!==o&&void 0!==n&&void 0!==i)return{x:r,y:o,width:n,height:i}}function eN(e){return"string"==typeof e&&e.length>0?e:void 0}function eU(e){return"number"==typeof e&&Number.isFinite(e)?e:void 0}function ex(e){return"ios"===e||"macos"===e||"android"===e?e:void 0}function eC(e){return"simulator"===e||"emulator"===e||"device"===e?e:void 0}function eR(e){if(!eO(e))throw new u("COMMAND_FAILED","Daemon returned an unexpected response shape.",{value:e});return e}function eO(e){return"object"==typeof e&&null!==e}function eL(e){let t={};for(let[a,r]of Object.entries(e))void 0!==r&&(t[a]=r);return t}function eF(e,t){let a=ek(e,"bundleId"),r=ek(e,"package");return{app:eS(e,"app"),appPath:eS(e,"appPath"),platform:eD(e,"platform"),appId:a??r,bundleId:a,package:r,identifiers:A({session:t,bundleId:a,packageName:r})}}function eB(e){let t=eR(e),a=eD(t,"platform"),r=eS(t,"id"),o=eS(t,"name");return{platform:a,target:eP(t,"target"),kind:eM(t,"kind",eC,'Daemon response has invalid "kind".'),id:r,name:o,booted:"boolean"==typeof t.booted?t.booted:void 0,identifiers:h(a,r,o),ios:"ios"===a?{udid:r}:void 0,android:"android"===a?{serial:r}:void 0}}function eq(e){let t=eR(e),a=eD(t,"platform"),r=eS(t,"id"),o=eS(t,"name"),n=eP(t,"target"),i=eS(t,"device"),s={session:o,...h(a,r,i)};return{name:o,createdAt:eM(t,"createdAt",eU,'Daemon response is missing numeric "createdAt".'),device:{platform:a,target:n,id:r,name:i,identifiers:s,ios:"ios"===a?{udid:r,simulatorSetPath:eE(t,"ios_simulator_device_set")}:void 0,android:"android"===a?{serial:r}:void 0},identifiers:s}}function ej(e){return e??"default"}function ez(e={},t={}){var a;let r,o=t.transport??J,n=async(t,a=[],r={})=>{var n,i;let s=(n=e,i=r,{...n,...i}),l=await o({session:ej(s.session),command:t,positionals:a,flags:eL({stateDir:s.stateDir,daemonBaseUrl:s.daemonBaseUrl,daemonAuthToken:s.daemonAuthToken,daemonTransport:s.daemonTransport,daemonServerMode:s.daemonServerMode,tenant:s.tenant,sessionIsolation:s.sessionIsolation,runId:s.runId,leaseId:s.leaseId,leaseBackend:s.leaseBackend,platform:s.platform,target:s.target,device:s.device,udid:s.udid,serial:s.serial,iosSimulatorDeviceSet:s.iosSimulatorDeviceSet,androidDeviceAllowlist:s.androidDeviceAllowlist,runtime:s.simulatorRuntimeId,boot:s.boot,reuseExisting:s.reuseExisting,surface:s.surface,activity:s.activity,relaunch:s.relaunch,shutdown:s.shutdown,saveScript:s.saveScript,noRecord:s.noRecord,backMode:s.backMode,metroHost:s.metroHost,metroPort:s.metroPort,bundleUrl:s.bundleUrl,launchUrl:s.launchUrl,snapshotInteractiveOnly:s.interactiveOnly,snapshotCompact:s.compact,snapshotDepth:s.depth,snapshotScope:s.scope,snapshotRaw:s.raw,screenshotFullscreen:s.screenshotFullscreen,screenshotMaxSize:s.screenshotMaxSize,overlayRefs:s.overlayRefs,appsFilter:s.appsFilter,out:s.out,count:s.count,fps:s.fps,quality:s.quality,hideTouches:s.hideTouches,intervalMs:s.intervalMs,delayMs:s.delayMs,holdMs:s.holdMs,jitterPx:s.jitterPx,pixels:s.pixels,doubleTap:s.doubleTap,clickButton:s.clickButton,pauseMs:s.pauseMs,pattern:s.pattern,headless:s.headless,restart:s.restart,replayUpdate:s.replayUpdate,replayEnv:s.replayEnv,replayShellEnv:s.replayShellEnv,failFast:s.failFast,timeoutMs:s.timeoutMs,retries:s.retries,artifactsDir:s.artifactsDir,reportJunit:s.reportJunit,findFirst:s.findFirst,findLast:s.findLast,networkInclude:s.networkInclude,batchOnError:s.batchOnError,batchMaxSteps:s.batchMaxSteps,batchSteps:s.batchSteps,verbose:s.debug}),runtime:s.runtime,meta:eL({requestId:s.requestId,cwd:s.cwd,debug:s.debug,lockPolicy:s.lockPolicy,lockPlatform:s.lockPlatform,tenantId:s.tenant,runId:s.runId,leaseId:s.leaseId,leaseBackend:s.leaseBackend,leaseTtlMs:s.leaseTtlMs,sessionIsolation:s.sessionIsolation,installSource:s.installSource,retainMaterializedPaths:s.retainMaterializedPaths,materializedPathRetentionMs:s.materializedPathRetentionMs,materializationId:s.materializationId})});return l.ok||function(e){throw new u(c(e.code),e.message,{...e.details??{},hint:e.hint,diagnosticId:e.diagnosticId,logPath:e.logPath})}(l.error),l.data??{}},i=async(e={})=>{let t=await n("session_list",[],e);return(Array.isArray(t.sessions)?t.sessions:[]).map(eq)},s=async(e,t=[],a={})=>await n(e,t,a),l=(t={})=>{var a,r;return ej((a=e,r=t,{...a,...r}).session)};return{command:(a=async e=>await n(e.command,e.positionals,e.options),r=async e=>await a(e),{wait:async e=>await r(function(e){if(1!==[void 0!==e.durationMs?"durationMs":void 0,void 0!==e.text?"text":void 0,void 0!==e.ref?"ref":void 0,void 0!==e.selector?"selector":void 0].filter(Boolean).length)throw new u("INVALID_ARGS","wait command requires exactly one of durationMs, text, ref, or selector.");if(void 0!==e.durationMs)return{command:e_.wait,positionals:[String(e.durationMs)],options:e};let t=void 0!==e.timeoutMs?[String(e.timeoutMs)]:[];if(void 0!==e.text)return{command:e_.wait,positionals:["text",e.text,...t],options:e};if(void 0!==e.ref)return{command:e_.wait,positionals:[e.ref,...t],options:e};let a=e.selector;return function(e){if(!P(e))throw new u("INVALID_ARGS",`Invalid wait selector: ${e}`)}(a),{command:e_.wait,positionals:[a,...t],options:e}}(e)),alert:async(e={})=>{var t;let a;return await r((a=(t=e).action??"get",{command:e_.alert,positionals:[a,...void 0!==t.timeoutMs?[String(t.timeoutMs)]:[]],options:t}))},appState:async(e={})=>await r({command:e_.appState,positionals:[],options:e}),back:async(e={})=>await r({command:e_.back,positionals:[],options:{...e,backMode:e.mode}}),home:async(e={})=>await r({command:e_.home,positionals:[],options:e}),rotate:async e=>await r({command:e_.rotate,positionals:[e.orientation],options:e}),appSwitcher:async(e={})=>await r({command:e_.appSwitcher,positionals:[],options:e}),keyboard:async(e={})=>await r({command:e_.keyboard,positionals:e.action?[e.action]:[],options:e}),clipboard:async e=>{var t;return await r("read"===(t=e).action?{command:e_.clipboard,positionals:["read"],options:t}:{command:e_.clipboard,positionals:["write",t.text],options:t})}}),devices:{list:async(e={})=>{let t=await n(e_.devices,[],e);return(Array.isArray(t.devices)?t.devices:[]).map(eB)},boot:async(e={})=>await s(e_.boot,[],e)},sessions:{list:async(e={})=>await i(e),close:async(e={})=>{let t=l(e),a=(await n("close",[],e)).shutdown;return{session:t,shutdown:"object"==typeof a&&null!==a?a:void 0,identifiers:{session:t}}}},simulators:{ensure:async e=>{let{runtime:t,...a}=e,r=await n("ensure-simulator",[],{...a,simulatorRuntimeId:t}),o=eS(r,"udid"),i=eS(r,"device");return{udid:o,device:i,runtime:eS(r,"runtime"),created:!0===r.created,booted:!0===r.booted,iosSimulatorDeviceSet:eE(r,"ios_simulator_device_set"),identifiers:{deviceId:o,deviceName:i,udid:o}}}},apps:{install:async e=>eF(await n("install",[e.app,e.appPath],e),l(e)),reinstall:async e=>eF(await n("reinstall",[e.app,e.appPath],e),l(e)),installFromSource:async e=>(function(e,t){let a=ek(e,"bundleId"),r=ek(e,"packageName"),o=a??r??ek(e,"appId"),n=ek(e,"launchTarget")??r??a??o;if(!n)throw new u("COMMAND_FAILED",'Daemon response is missing "launchTarget".',{response:e});return{appName:ek(e,"appName"),appId:o,bundleId:a,packageName:r,launchTarget:n,installablePath:ek(e,"installablePath"),archivePath:ek(e,"archivePath"),materializationId:ek(e,"materializationId"),materializationExpiresAt:ek(e,"materializationExpiresAt"),identifiers:A({session:t,bundleId:a,packageName:r,appId:o})}})(await n("install_source",[],{...e,installSource:e.source,retainMaterializedPaths:e.retainPaths,materializedPathRetentionMs:e.retentionMs}),l(e)),list:async(e={})=>{let t=await n(e_.apps,[],e);return Array.isArray(t.apps)?t.apps.filter(e=>"string"==typeof e):[]},open:async e=>{let t=l(e),a=e.app?e.url?[e.app,e.url]:[e.app]:[],r=await n("open",a,e),o=function(e){let t=e.platform,a=ek(e,"id"),r=ek(e,"device");if("ios"!==t&&"macos"!==t&&"android"!==t||!a||!r)return;let o=eP(e,"target"),n=h(t,a,r);return{platform:t,target:o,id:a,name:r,identifiers:n,ios:"ios"===t?{udid:ek(e,"device_udid")??a,simulatorSetPath:eE(e,"ios_simulator_device_set")}:void 0,android:"android"===t?{serial:ek(e,"serial")??a}:void 0}}(r),i=ek(r,"appBundleId");return{session:t,appName:ek(r,"appName"),appBundleId:i,appId:i,startup:function(e){if(eO(e)&&"number"==typeof e.durationMs&&"string"==typeof e.measuredAt&&"string"==typeof e.method)return{durationMs:e.durationMs,measuredAt:e.measuredAt,method:e.method,appTarget:ek(e,"appTarget"),appBundleId:ek(e,"appBundleId")}}(r.startup),runtime:function(e){if(!eO(e))return;let t=e.platform,a=ek(e,"metroHost"),r="number"==typeof e.metroPort?e.metroPort:void 0;return{platform:"ios"===t||"android"===t?t:void 0,metroHost:a,metroPort:r,bundleUrl:ek(e,"bundleUrl"),launchUrl:ek(e,"launchUrl")}}(r.runtime),device:o,identifiers:{session:t,deviceId:o?.id,deviceName:o?.name,udid:o?.ios?.udid,serial:o?.android?.serial,appId:i,appBundleId:i}}},close:async(e={})=>{let t=l(e),a=(await n("close",e.app?[e.app]:[],e)).shutdown;return{session:t,closedApp:e.app,shutdown:"object"==typeof a&&null!==a?a:void 0,identifiers:{session:t}}},push:async e=>{var t;return await s(e_.push,[e.app,"string"==typeof(t=e.payload)?t:JSON.stringify(t)],e)},triggerEvent:async e=>{var t;return await s(e_.triggerAppEvent,[(t=e).event,...t.payload?[JSON.stringify(t.payload)]:[]],e)}},materializations:{release:async e=>{var t;return{released:!0===(t=await n("release_materialized_paths",[],{...e,materializationId:e.materializationId})).released,materializationId:eS(t,"materializationId"),identifiers:{}}}},leases:{allocate:async e=>eK(await n("lease_allocate",[],{...e,leaseId:void 0,leaseTtlMs:e.ttlMs})),heartbeat:async e=>eK(await n("lease_heartbeat",[],{...e,leaseTtlMs:e.ttlMs})),release:async e=>({released:!0===(await n("lease_release",[],e)).released})},metro:{prepare:async t=>await N({projectRoot:t.projectRoot??e.cwd,kind:t.kind,publicBaseUrl:t.publicBaseUrl,proxyBaseUrl:t.proxyBaseUrl,proxyBearerToken:t.bearerToken,bridgeScope:t.bridgeScope,launchUrl:t.launchUrl,companionProfileKey:t.companionProfileKey,companionConsumerKey:t.companionConsumerKey,metroPort:t.port,listenHost:t.listenHost,statusHost:t.statusHost,startupTimeoutMs:t.startupTimeoutMs,probeTimeoutMs:t.probeTimeoutMs,reuseExisting:t.reuseExisting,installDependenciesIfNeeded:t.installDependenciesIfNeeded,runtimeFilePath:t.runtimeFilePath,logPath:t.logPath}),reload:async(t={})=>await T({metroHost:t.metroHost,metroPort:t.metroPort,bundleUrl:t.bundleUrl,runtime:e.runtime,timeoutMs:t.timeoutMs})},capture:{snapshot:async(e={})=>{var t;let a=l(e),r=await n(e_.snapshot,[],e),o=ek(r,"appBundleId"),i="object"==typeof r.visibility&&null!==r.visibility?r.visibility:void 0,s="object"==typeof r.androidSnapshot&&null!==r.androidSnapshot?r.androidSnapshot:void 0;return{nodes:Array.isArray(t=r.nodes)?t:[],truncated:!0===r.truncated,appName:ek(r,"appName"),appBundleId:o,...i?{visibility:i}:{},...s?{androidSnapshot:s}:{},warnings:Array.isArray(r.warnings)?r.warnings.filter(e=>"string"==typeof e):void 0,identifiers:{session:a,appId:o,appBundleId:o}}},screenshot:async(e={})=>{let t=l(e),a=await n(e_.screenshot,e.path?[e.path]:[],{...e,screenshotFullscreen:e.fullscreen,screenshotMaxSize:e.maxSize});return{path:eS(a,"path"),overlayRefs:function(e){let t=e.overlayRefs;if(!Array.isArray(t))return;let a=[];for(let e of t){if(!eO(e))continue;let t=ek(e,"ref"),r=eT(e,"rect"),o=eT(e,"overlayRect"),n=function(e,t){let a=e[t];if(!eO(a))return;let r="number"==typeof a.x?a.x:void 0,o="number"==typeof a.y?a.y:void 0;if(void 0!==r&&void 0!==o)return{x:r,y:o}}(e,"center");t&&r&&o&&n&&a.push({ref:t,label:ek(e,"label"),rect:r,overlayRect:o,center:n})}return a}(a),identifiers:{session:t}}},diff:async e=>await s(e_.diff,[e.kind],{...e,interactiveOnly:e.interactiveOnly,compact:e.compact,depth:e.depth,scope:e.scope,raw:e.raw})},interactions:{click:async e=>await s(e_.click,e$(e),{...e,clickButton:e.button}),press:async e=>await s(e_.press,e$(e),e),longPress:async e=>await s(e_.longPress,[String(e.x),String(e.y),...eV(e.durationMs)],e),swipe:async e=>await s(e_.swipe,[String(e.from.x),String(e.from.y),String(e.to.x),String(e.to.y),...eV(e.durationMs)],e),focus:async e=>await s(e_.focus,[String(e.x),String(e.y)],e),type:async e=>await s(e_.type,[e.text],e),fill:async e=>await s(e_.fill,[...e$(e),e.text],e),scroll:async e=>await s(e_.scroll,[e.direction,...eV(e.amount)],e),pinch:async e=>await s(e_.pinch,[String(e.scale),...eV(e.x),...eV(e.y)],e),get:async e=>{var t;return await s(e_.get,[e.format,...void 0!==(t=e).ref?[t.ref,...eH(t.label)]:[t.selector]],e)},is:async e=>await s(e_.is,[e.predicate,e.selector,..."text"===e.predicate?[e.value]:[]],e),find:async e=>await s(e_.find,function(e){let t=e.locator&&"any"!==e.locator?[e.locator,e.query]:[e.query];switch(e.action){case void 0:case"click":case"focus":case"exists":return e.action?[...t,e.action]:t;case"getText":return[...t,"get","text"];case"getAttrs":return[...t,"get","attrs"];case"wait":return[...t,"wait",...eV(e.timeoutMs)];case"fill":case"type":return[...t,e.action,e.value]}}(e),{...e,findFirst:e.first,findLast:e.last})},replay:{run:async e=>await s(e_.replay,[e.path],{...e,replayUpdate:e.update,replayEnv:e.env,replayShellEnv:eG(process.env)}),test:async e=>await s(e_.test,e.paths,{...e,replayUpdate:e.update,replayEnv:e.env,replayShellEnv:eG(process.env)})},batch:{run:async e=>await s(e_.batch,[],{...e,batchSteps:e.steps,batchOnError:e.onError,batchMaxSteps:e.maxSteps})},observability:{perf:async(e={})=>await s(e_.perf,[],e),logs:async(e={})=>{var t;return await s(e_.logs,[(t=e).action??"path",...eH(t.message)],e)},network:async(e={})=>{var t;return await s(e_.network,[...(t=e).action?[t.action]:[],...eV(t.limit)],{...e,networkInclude:e.include})}},recording:{record:async e=>await s(e_.record,[e.action,...eH(e.path)],e),trace:async e=>await s(e_.trace,[e.action,...eH(e.path)],e)},settings:{update:async e=>await s(e_.settings,[e.setting,e.state,..."permission"in e?[e.permission]:[],..."mode"in e&&e.mode?[e.mode]:[]],e)}}}function e$(e){return void 0!==e.ref?[e.ref,...eH(e.label)]:void 0!==e.selector?[e.selector]:[String(e.x),String(e.y)]}function eH(e){return void 0===e?[]:[e]}function eV(e){return void 0===e?[]:[String(e)]}function eG(e){let t={};for(let[a,r]of Object.entries(e))"string"==typeof r&&a.startsWith("AD_VAR_")&&(t[a]=r);return t}function eK(e){let t=e.lease;if(!t||"object"!=typeof t||Array.isArray(t))throw Error("Invalid lease response from daemon");return{leaseId:eS(t,"leaseId"),tenantId:eS(t,"tenantId"),runId:eS(t,"runId"),backend:eS(t,"backend"),createdAt:"number"==typeof t.createdAt?t.createdAt:void 0,heartbeatAt:"number"==typeof t.heartbeatAt?t.heartbeatAt:void 0,expiresAt:"number"==typeof t.expiresAt?t.expiresAt:void 0}}export{e_ as CLIENT_COMMANDS,ez as createAgentDeviceClient,J as sendToDaemon};
|