agent-device 0.17.0 → 0.17.2
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/README.md +1 -1
- package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.17.0.apk → agent-device-android-multitouch-helper-0.17.2.apk} +0 -0
- package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.17.2.apk.sha256 +1 -0
- package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.17.0.manifest.json → agent-device-android-multitouch-helper-0.17.2.manifest.json} +4 -4
- package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.17.0.apk → agent-device-android-snapshot-helper-0.17.2.apk} +0 -0
- package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.17.2.apk.sha256 +1 -0
- package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.17.0.manifest.json → agent-device-android-snapshot-helper-0.17.2.manifest.json} +6 -6
- package/dist/src/123.js +1 -0
- package/dist/src/1352.js +1 -1
- package/dist/src/1534.js +1 -0
- package/dist/src/1620.js +1 -0
- package/dist/src/1644.js +2 -0
- package/dist/src/2284.js +1 -0
- package/dist/src/2403.js +3 -0
- package/dist/src/2415.js +28 -29
- package/dist/src/2474.js +1 -0
- package/dist/src/2672.js +1 -0
- package/dist/src/3393.js +1 -0
- package/dist/src/4778.js +1 -1
- package/dist/src/5898.js +1 -0
- package/dist/src/7556.js +1 -1
- package/dist/src/7847.js +1 -1
- package/dist/src/8173.js +27 -0
- package/dist/src/8407.js +1 -0
- package/dist/src/8699.js +1 -1
- package/dist/src/8806.js +3 -3
- package/dist/src/9010.js +1 -0
- package/dist/src/9238.js +3 -3
- package/dist/src/9471.js +1 -1
- package/dist/src/9542.js +3 -3
- package/dist/src/9616.js +1 -0
- package/dist/src/9673.js +1 -0
- package/dist/src/9974.js +1 -0
- package/dist/src/android-adb.d.ts +12 -6
- package/dist/src/android-adb.js +1 -1
- package/dist/src/android-snapshot-helper.d.ts +15 -7
- package/dist/src/android.js +1 -1
- package/dist/src/apple.js +1 -1
- package/dist/src/apps.js +2 -2
- package/dist/src/args.js +2 -2
- package/dist/src/batch.d.ts +16 -4
- package/dist/src/cli.js +18 -42
- package/dist/src/command-surface.js +1 -1
- package/dist/src/contracts.d.ts +28 -4
- package/dist/src/contracts.js +1 -1
- package/dist/src/find.js +1 -1
- package/dist/src/finders.d.ts +3 -1
- package/dist/src/generic.js +13 -11
- package/dist/src/index.d.ts +142 -73
- package/dist/src/index.js +1 -1
- package/dist/src/input-actions.js +1 -1
- package/dist/src/interaction.js +1 -1
- package/dist/src/internal/png-worker.d.ts +26 -0
- package/dist/src/internal/png-worker.js +1 -0
- package/dist/src/metro.d.ts +3 -1
- package/dist/src/react-native.js +1 -1
- package/dist/src/record-trace-recording.js +26 -0
- package/dist/src/record-trace.js +1 -26
- package/dist/src/remote-config.d.ts +33 -7
- package/dist/src/selector-runtime.js +1 -1
- package/dist/src/selectors.d.ts +3 -3
- package/dist/src/selectors.js +1 -1
- package/dist/src/server.js +2 -2
- package/dist/src/session.js +10 -11
- package/dist/src/snapshot.js +1 -1
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +6 -2
- package/package.json +7 -4
- package/server.json +2 -2
- package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.17.0.apk.sha256 +0 -1
- package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.17.0.apk.sha256 +0 -1
- package/dist/src/1998.js +0 -1
- package/dist/src/2805.js +0 -1
- package/dist/src/4057.js +0 -1
- package/dist/src/5792.js +0 -1
- package/dist/src/6085.js +0 -1
- package/dist/src/6232.js +0 -1
- package/dist/src/8020.js +0 -1
- package/dist/src/8502.js +0 -1
- package/dist/src/940.js +0 -1
- package/dist/src/9404.js +0 -1
- package/dist/src/9533.js +0 -1
- package/dist/src/command-metadata.js +0 -1
- /package/dist/src/{1393.js → 3675.js} +0 -0
- /package/dist/src/{5310.js → 695.js} +0 -0
package/dist/src/cli.js
CHANGED
|
@@ -1,46 +1,22 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
`),
|
|
4
|
-
|
|
5
|
-
`),n.logPath&&process.stderr.write(`Diagnostics Log: ${n.logPath}
|
|
6
|
-
`),t.showDetails&&n.details&&process.stderr.write(`${JSON.stringify(n.details,null,2)}
|
|
7
|
-
`)}function eN(e){return e&&e.summaryLines.length>0?`
|
|
8
|
-
${e.summaryLines.join("\n")}`:""}function eP(e){return`x=${e.x},y=${e.y},w=${e.width},h=${e.height}`}function ek(e){return e>0?`+${e}`:String(e)}function eR(e){let t=e.nearestText?` near ${JSON.stringify(e.nearestText)}`:"",n=e.regionIndex?` r${e.regionIndex}`:"";return`${e.likelyKind}${t}${n}`}function eU(e){return e.min===e.max?ek(e.min):`${ek(e.min)}..${ek(e.max)}`}function eE(t){let n=process.cwd(),r=e.relative(n,t);return""!==r&&(r.startsWith("..")||e.isAbsolute(r))?t:""===r?".":`.${e.sep}${r}`}function eT(e){return"number"==typeof e&&Number.isFinite(e)?e:0}function eB(){let e=process.env.FORCE_COLOR;return"string"==typeof e?"0"!==e:"string"!=typeof process.env.NO_COLOR&&!!process.stdout.isTTY}function eM(e,n){return n?t("dim",e):e}function eL(e){let t=e.warnings;return Array.isArray(t)?t.filter(e=>"string"==typeof e&&e.length>0):[]}function eO(e,t){var n;let r="scroll-area"===(n=e.type)||"list"===n||"collection"===n||"table"===n?n:null;if(!r)return[];let o=[];if(e.node.hiddenContentAbove&&"below"!==t&&o.push(`[content above ${r} hidden]`),e.node.hiddenContentBelow&&"above"!==t&&o.push(`[content below ${r} hidden]`),0===o.length)return[];let i=" ".repeat(e.depth+1);return o.map(e=>`${i}${e}`)}let ej={slug:"react-devtools-companion",runArg:g,displayName:"React DevTools companion"};async function eH(e){return await m({...e,definition:ej,localBaseUrl:e.localBaseUrl??"http://127.0.0.1:8097",registerPath:"/api/react-devtools/companion/register",unregisterPath:"/api/react-devtools/companion/unregister",devicePort:e.devicePort??8097})}async function eK(e){return await h({...e,definition:ej})}function eF(e){var t;let n,o=ez(e);if(!r.existsSync(o))return null;try{n=JSON.parse(r.readFileSync(o,"utf8"))}catch(t){return eQ(e,t),null}return!(!(t=n)||"object"!=typeof t||Array.isArray(t))&&1===t.version&&"string"==typeof t.session&&"string"==typeof t.remoteConfigPath&&"string"==typeof t.remoteConfigHash&&(void 0===t.daemon||"object"==typeof t.daemon&&null!==t.daemon&&!Array.isArray(t.daemon))&&"string"==typeof t.tenant&&"string"==typeof t.runId&&(void 0===t.leaseId||"string"==typeof t.leaseId)&&(void 0===t.leaseBackend||"string"==typeof t.leaseBackend)&&"string"==typeof t.connectedAt&&"string"==typeof t.updatedAt?n:(eQ(e),null)}function eG(t){let n=ez({stateDir:t.stateDir,session:t.state.session});r.mkdirSync(e.dirname(n),{recursive:!0}),eX(n,t.state),eX(eW(t.stateDir),{session:t.state.session})}function eV(e){return{baseUrl:function(e){if(!e)return;let t=new URL(e);for(let e of(t.username="",t.password="",[...t.searchParams.keys()]))/(auth|key|password|secret|token)/i.test(e)&&t.searchParams.delete(e);return t.toString().replace(/\/+$/,"")}(e.daemonBaseUrl),transport:e.daemonTransport,serverMode:e.daemonServerMode}}function eq(e){r.rmSync(ez(e),{force:!0});let t=eW(e.stateDir);eY(e.stateDir)===e.session&&r.rmSync(t,{force:!0})}function eJ(e){try{return o.createHash("sha256").update(r.readFileSync(e)).digest("hex")}catch(t){throw new p("INVALID_ARGS",`Remote config file not found: ${e}`,{cause:t instanceof Error?t.message:String(t)})}}function ez(t){return e.join(t.stateDir,"remote-connections",`${function(e){let t=e.replaceAll(/[^a-zA-Z0-9._-]/g,"_");if(!t)return"default";if(t===e)return t;let n=o.createHash("sha256").update(e).digest("hex").slice(0,8);return`${t}-${n}`}(t.session)}.json`)}function eW(t){return e.join(t,"remote-connections",".active-session.json")}function eZ(e){let t=eY(e.stateDir);return t?eF({stateDir:e.stateDir,session:t}):null}function eY(e){let t=eW(e);if(r.existsSync(t))try{let e=JSON.parse(r.readFileSync(t,"utf8"));return"string"==typeof e.session?e.session:void 0}catch{return}}function eX(e,t){r.writeFileSync(e,`${JSON.stringify(t,null,2)}
|
|
9
|
-
`,{encoding:"utf8",mode:384}),r.chmodSync(e,384)}function eQ(e,t){C({level:"warn",phase:"remote_connection_state_invalid",data:{session:e.session,cause:t instanceof Error?t.message:t?String(t):void 0}}),eq(e)}let e0=v.map(e=>e.key);function e1(e){let t={};for(let n of e0){let r=e[n];void 0!==r&&(t[n]=r)}return t}let e2=new Set(["connect","connection","close","disconnect","metro","session"]),e3=new Set(["open"]);async function e8(e){let t,n,{command:r,flags:o,client:i}=e;if(!o.remoteConfig)return{flags:o,runtime:e.runtime};let s=x(o.stateDir).baseDir,a=w({configPath:o.remoteConfig,cwd:process.cwd(),env:process.env}),l={...e1(a.profile),...o,remoteConfig:a.resolvedPath},c=eF({stateDir:s,session:l.session??"default"});if(c&&c.remoteConfigPath!==a.resolvedPath)throw new p("INVALID_ARGS","A different remote connection is already active for this session. Run connect --force or disconnect before using a different --remote-config.",{session:c.session,activeRemoteConfig:c.remoteConfigPath,requestedRemoteConfig:a.resolvedPath});let d=c??function(e,t){if(!e.tenant)throw new p("INVALID_ARGS","remote command requires tenant in remote config or via --tenant <id>.");if(!e.runId)throw new p("INVALID_ARGS","remote command requires runId in remote config or via --run-id <id>.");if(!e.daemonBaseUrl)throw new p("INVALID_ARGS","remote command requires daemonBaseUrl in remote config, config, env, or --daemon-base-url.");let n=new Date().toISOString();return{version:1,session:e.session??"default",remoteConfigPath:t,remoteConfigHash:eJ(t),daemon:eV(e),tenant:e.tenant,runId:e.runId,leaseId:e.leaseId,leaseBackend:e.leaseBackend??e7(e),platform:e.platform,target:e.target,connectedAt:n,updatedAt:n}}(l,a.resolvedPath),u={...l,session:d.session},f=function(e,t){if(e)return tt(e,t)?e:void 0}(d.runtime,u.platform)??e.runtime,m=d,h=!c;if(g=r,!e2.has(g)){let e=d.leaseBackend??function(e,t){let n=e7(e);if(n)return n;throw new p("INVALID_ARGS",`${t} requires --platform ios|android or --lease-backend when the remote connection has not resolved a lease yet.`)}(o,r);var g,v,y,I,$,A=d,S=o,C=e;if(A.leaseBackend&&A.leaseBackend!==C)throw new p("INVALID_ARGS","Active remote connection is already bound to a different lease backend. Re-run connect --force to replace it.",{session:A.session,leaseBackend:A.leaseBackend});if(A.platform&&S.platform&&A.platform!==S.platform)throw new p("INVALID_ARGS","Active remote connection is already bound to a different platform. Re-run connect --force to replace it.",{session:A.session,platform:A.platform});if(A.target&&S.target&&A.target!==S.target)throw new p("INVALID_ARGS","Active remote connection is already bound to a different target. Re-run connect --force to replace it.",{session:A.session,target:A.target});let t=await tn(i,m,e);u.leaseId=t.leaseId,u.leaseBackend=e,u.platform=m.platform??u.platform,u.target=m.target??u.target,(m.leaseId!==t.leaseId||m.leaseBackend!==e)&&(m={...m,leaseId:t.leaseId,leaseBackend:e,platform:m.platform??o.platform,target:m.target??o.target,updatedAt:new Date().toISOString()},h=!0)}if(v=r,y=e.batchSteps,(e3.has(v)||"batch"===v&&y&&y.some(e=>{let t=e.command.trim().toLowerCase();return e3.has(t)&&void 0===e.runtime}))&&te(u)&&(!m.leaseId&&u.leaseId&&(m={...m,leaseId:u.leaseId,leaseBackend:u.leaseBackend}),e.forceRuntimePrepare||!f||!tt(f,u.platform))){if(!m.leaseId)throw new p("INVALID_ARGS",`${r} requires a resolved remote lease before Metro runtime can be prepared.`);let e=await e5(u,i,d.remoteConfigPath,d.session,{tenantId:d.tenant,runId:d.runId,leaseId:m.leaseId});f=e.runtime;let o=(I=m.metro,$=e.cleanup,I?.projectRoot!==$?.projectRoot||I?.profileKey!==$?.profileKey||I?.consumerKey!==$?.consumerKey);t=o?m.metro:void 0,n=o?e.cleanup:void 0,m={...m,runtime:e.runtime,metro:e.cleanup,updatedAt:new Date().toISOString()},h=!0}if(h)try{eG({stateDir:s,state:m})}catch(e){throw await e9(n),e}return await e9(t),{flags:{...u,session:m.session,leaseId:m.leaseId,leaseBackend:m.leaseBackend,platform:m.platform??u.platform,target:m.target??u.target},runtime:f}}async function e5(e,t,n,r,o){if(!e.metroProjectRoot&&!e.metroPublicBaseUrl&&!e.metroProxyBaseUrl)return{};if("ios"!==e.platform&&"android"!==e.platform)throw new p("INVALID_ARGS",'Deferred Metro preparation requires platform "ios" or "android".');if(!e.metroPublicBaseUrl&&!e.metroProxyBaseUrl)throw new p("INVALID_ARGS","Deferred Metro preparation requires metroPublicBaseUrl or metroProxyBaseUrl when Metro settings are provided.");let i=await t.metro.prepare({projectRoot:e.metroProjectRoot,kind:e.metroKind,publicBaseUrl:e.metroPublicBaseUrl,proxyBaseUrl:e.metroProxyBaseUrl,bearerToken:e.metroBearerToken,bridgeScope:o,launchUrl:e.launchUrl,companionProfileKey:n,companionConsumerKey:r,port:e.metroPreparePort,listenHost:e.metroListenHost,statusHost:e.metroStatusHost,startupTimeoutMs:e.metroStartupTimeoutMs,probeTimeoutMs:e.metroProbeTimeoutMs,reuseExisting:!e.metroNoReuseExisting&&void 0,installDependenciesIfNeeded:!e.metroNoInstallDeps&&void 0,runtimeFilePath:e.metroRuntimeFile});return{runtime:"ios"===e.platform?i.iosRuntime:i.androidRuntime,cleanup:e.metroProxyBaseUrl?{projectRoot:i.projectRoot,profileKey:n,consumerKey:r}:void 0}}async function e9(e){if(e)try{await b(e)}catch{}}async function e6(e){try{await eK({projectRoot:process.cwd(),stateDir:e.stateDir,profileKey:e.state.remoteConfigPath,consumerKey:e.state.session})}catch{}}async function e4(e,t){if(t.leaseId)try{await e.leases.release({tenant:t.tenant,runId:t.runId,leaseId:t.leaseId,daemonBaseUrl:t.daemon?.baseUrl,daemonTransport:t.daemon?.transport,daemonServerMode:t.daemon?.serverMode})}catch{}}function e7(e){return e.leaseBackend?e.leaseBackend:"android"===e.platform?"android-instance":"ios"===e.platform?"ios-instance":void 0}function te(e){return!!(e.metroPublicBaseUrl||e.metroProxyBaseUrl||e.metroProjectRoot||e.metroKind)}function tt(e,t){return!e.platform||!t||"ios"!==t&&"android"!==t||e.platform===t}async function tn(e,t,n){if(t.leaseId&&t.leaseBackend===n){let r=await tr(e,t.leaseId,{tenant:t.tenant,runId:t.runId,leaseBackend:n});if(r)return r}return await e.leases.allocate({tenant:t.tenant,runId:t.runId,leaseBackend:n})}async function tr(e,t,n){try{return await e.leases.heartbeat({tenant:n.tenant,runId:n.runId,leaseId:t,leaseBackend:n.leaseBackend})}catch(e){var r;if((r=e)instanceof p&&"UNAUTHORIZED"===r.code&&(r.details?.reason==="LEASE_NOT_FOUND"||r.details?.reason==="LEASE_EXPIRED"||r.details?.reason==="LEASE_REVOKED"))return;throw e}}async function to(e){return await ti({command:e.command,flags:e.flags,stateDir:e.stateDir,allowInteractiveLogin:"connect"===e.command&&!e.flags.noLogin,env:e.env})}async function ti(e){let t=e.env??e.io?.env??process.env;if(!e.flags.daemonBaseUrl)return{flags:e.flags,source:"none"};if(ty(e.flags.daemonAuthToken))return{flags:e.flags,source:"flag"};if(ty(t.AGENT_DEVICE_DAEMON_AUTH_TOKEN))return{flags:e.flags,source:"env"};if(!function(e,t){if("1"===t.AGENT_DEVICE_CLOUD_AUTH||"true"===t.AGENT_DEVICE_CLOUD_AUTH||ty(t.AGENT_DEVICE_CLOUD_BASE_URL))return!0;try{let t=new URL(e).hostname.toLowerCase();return"agent-device.dev"===t||t.endsWith(".agent-device.dev")}catch{return!1}}(e.flags.daemonBaseUrl,t))return{flags:e.flags,source:"none"};let n=await td({stateDir:e.stateDir,flags:e.flags,env:t,io:e.io});if(n)return{flags:{...e.flags,daemonAuthToken:n.accessToken},source:"cli-session"};if(!e.allowInteractiveLogin){if(e.flags.noLogin)throw new p("UNAUTHORIZED","Remote daemon authentication is required.",{hint:"Run agent-device auth login, unset --no-login, or set AGENT_DEVICE_DAEMON_AUTH_TOKEN."});throw tm(e.command,t)}let r=await ta({stateDir:e.stateDir,flags:e.flags,env:t,io:e.io});return{flags:{...e.flags,daemonAuthToken:r.accessToken},source:"login"}}async function ts(e){let t=e.env??e.io?.env??process.env;if(ty(e.flags.daemonAuthToken))return{accessToken:e.flags.daemonAuthToken,cloudBaseUrl:th(t)};if(ty(t.AGENT_DEVICE_DAEMON_AUTH_TOKEN))return{accessToken:t.AGENT_DEVICE_DAEMON_AUTH_TOKEN,cloudBaseUrl:th(t)};let n=await td({stateDir:e.stateDir,flags:e.flags,env:t,io:e.io});if(n)return{accessToken:n.accessToken,cloudBaseUrl:n.cloudBaseUrl};if(e.flags.noLogin)throw new p("UNAUTHORIZED","Cloud connection profile authentication is required.",{hint:"Run agent-device auth login, unset --no-login, or set AGENT_DEVICE_DAEMON_AUTH_TOKEN."});let r=await ta({stateDir:e.stateDir,flags:e.flags,env:t,io:e.io,commandLabel:"agent-device connect"});return{accessToken:r.accessToken,cloudBaseUrl:r.session.cloudBaseUrl}}async function ta(t){let n,o,i,s=t.env??t.io?.env??process.env,a=(d=s,u=t.io,n=u?.stdinIsTTY??process.stdin.isTTY,o=u?.stdoutIsTTY??process.stdout.isTTY,"true"!==(f=d).CI&&"true"!==f.GITHUB_ACTIONS&&"true"!==f.BUILDKITE&&n&&o?(m=d).SSH_TTY||m.SSH_CONNECTION||"true"===m.CODESPACES||m.GITPOD_WORKSPACE_ID||"true"===m.REMOTE_CONTAINERS?"device-code":"local-browser":"non-interactive");if("non-interactive"===a)throw tm(t.commandLabel??"agent-device connect",s);let l=th(s),c=await tp({baseUrl:l,pathName:"/api/control-plane/device-auth/start",body:{client:"agent-device",tenant:t.flags.tenant,runId:t.flags.runId,daemonBaseUrl:t.flags.daemonBaseUrl,session:t.flags.session},fetchImpl:t.io?.fetch});var d,u,f,m,h,g,v=c;if(!ty(v.deviceCode)||!ty(v.userCode)||!ty(v.verificationUri))throw new p("COMMAND_FAILED","Cloud auth start returned an unusable response.");let w=c.verificationUriComplete??c.verificationUri,y="local-browser"===a?c.verificationUri:(h=c.verificationUri,g=c.userCode,(i=new URL(h)).searchParams.set("user_code",g),i.toString());"local-browser"===a?(tv(t.io,`Opening ${c.verificationUri}...
|
|
10
|
-
`),await tg(w,t.io)):tv(t.io,`Open this URL on your machine:
|
|
11
|
-
${y}
|
|
1
|
+
import{pathToFileURL as e}from"node:url";import t from"node:fs";import n from"node:crypto";import r from"node:path";import{ensureCompanionTunnel as o,stopCompanionTunnel as s}from"./1974.js";import{REACT_DEVTOOLS_COMPANION_RUN_ARG as a}from"./2301.js";import{REMOTE_CONFIG_FIELD_SPECS as i,resolveRemoteConfigProfile as l,resolveRemoteConfigPath as c}from"./208.js";import{asAppError as d,normalizeError as u,AppError as f}from"./9152.js";import{createRequestId as m,withDiagnosticsScope as p,getDiagnosticsMeta as g,flushDiagnosticsToSessionFile as h,emitDiagnostic as w}from"./7599.js";import{resolveDaemonPaths as v}from"./9238.js";import{stopMetroTunnel as I}from"./metro.js";import{runCmdStreaming as y,runCmd as A}from"./9818.js";import{formatSnapshotDiffText as _,isCommandName as S,formatScreenshotDiffText as D,printHumanError as C,printJson as k,formatCliOutput as N}from"./8173.js";import"./7847.js";import{stringifyMaestroYamlDocuments as b,parseReplayScriptDetailed as U,formatMaestroPoint as R,readReplayScriptMetadata as E}from"./2403.js";import{resolveUserPath as P,expandUserHomePath as T}from"./3267.js";import{captureCliReaders as B,interactionCliReaders as L,replayCliReaders as x,gestureCliReaders as M,observabilityCliReaders as O,appCliReaders as $,commonInputFromFlags as j,selectorCliReaders as G,parseInstallSourceConfig as V,systemCliReaders as K}from"./8699.js";import{runCommand as H}from"./command-surface.js";import{createLocalArtifactAdapter as F}from"./7719.js";import{localCommandPolicy as q,createAgentDevice as J}from"./123.js";import{isClientBackedCliCommandName as z}from"./5898.js";import{mergeDefinedFlags as W,parseOptionValueFromSource as Z,getConfigurableOptionSpecs as Y,getOptionSpec as X,usage as Q,parseRawArgs as ee,usageForCommand as et,finalizeParsedArgs as en}from"./args.js";import{readVersion as er}from"./9671.js";import{createAgentDeviceClient as eo,sendToDaemon as es}from"./9542.js";import{maybeRunUpgradeNotifier as ea}from"./113.js";import{parseSelectorChain as ei}from"./8407.js";let el={slug:"react-devtools-companion",runArg:a,displayName:"React DevTools companion"};async function ec(e){return await o({...e,definition:el,localBaseUrl:e.localBaseUrl??"http://127.0.0.1:8097",registerPath:"/api/react-devtools/companion/register",unregisterPath:"/api/react-devtools/companion/unregister",devicePort:e.devicePort??8097})}async function ed(e){return await s({...e,definition:el})}function eu(e){var n;let r,o=eh(e);if(!t.existsSync(o))return null;try{r=JSON.parse(t.readFileSync(o,"utf8"))}catch(t){return eA(e,t),null}return!(!(n=r)||"object"!=typeof n||Array.isArray(n))&&1===n.version&&"string"==typeof n.session&&"string"==typeof n.remoteConfigPath&&"string"==typeof n.remoteConfigHash&&(void 0===n.daemon||"object"==typeof n.daemon&&null!==n.daemon&&!Array.isArray(n.daemon))&&"string"==typeof n.tenant&&"string"==typeof n.runId&&(void 0===n.leaseId||"string"==typeof n.leaseId)&&(void 0===n.leaseBackend||"string"==typeof n.leaseBackend)&&"string"==typeof n.connectedAt&&"string"==typeof n.updatedAt?r:(eA(e),null)}function ef(e){let n=eh({stateDir:e.stateDir,session:e.state.session});t.mkdirSync(r.dirname(n),{recursive:!0}),ey(n,e.state),ey(ew(e.stateDir),{session:e.state.session})}function em(e){return{baseUrl:function(e){if(!e)return;let t=new URL(e);for(let e of(t.username="",t.password="",[...t.searchParams.keys()]))/(auth|key|password|secret|token)/i.test(e)&&t.searchParams.delete(e);return t.toString().replace(/\/+$/,"")}(e.daemonBaseUrl),transport:e.daemonTransport,serverMode:e.daemonServerMode}}function ep(e){t.rmSync(eh(e),{force:!0});let n=ew(e.stateDir);eI(e.stateDir)===e.session&&t.rmSync(n,{force:!0})}function eg(e){try{return n.createHash("sha256").update(t.readFileSync(e)).digest("hex")}catch(t){throw new f("INVALID_ARGS",`Remote config file not found: ${e}`,{cause:t instanceof Error?t.message:String(t)})}}function eh(e){return r.join(e.stateDir,"remote-connections",`${function(e){let t=e.replaceAll(/[^a-zA-Z0-9._-]/g,"_");if(!t)return"default";if(t===e)return t;let r=n.createHash("sha256").update(e).digest("hex").slice(0,8);return`${t}-${r}`}(e.session)}.json`)}function ew(e){return r.join(e,"remote-connections",".active-session.json")}function ev(e){let t=eI(e.stateDir);return t?eu({stateDir:e.stateDir,session:t}):null}function eI(e){let n=ew(e);if(t.existsSync(n))try{let e=JSON.parse(t.readFileSync(n,"utf8"));return"string"==typeof e.session?e.session:void 0}catch{return}}function ey(e,n){t.writeFileSync(e,`${JSON.stringify(n,null,2)}
|
|
2
|
+
`,{encoding:"utf8",mode:384}),t.chmodSync(e,384)}function eA(e,t){w({level:"warn",phase:"remote_connection_state_invalid",data:{session:e.session,cause:t instanceof Error?t.message:t?String(t):void 0}}),ep(e)}let e_=i.map(e=>e.key);function eS(e){let t={};for(let n of e_){let r=e[n];void 0!==r&&(t[n]=r)}return t}let eD=new Set(["connect","connection","close","disconnect","metro","session"]),eC=new Set(["open"]);async function ek(e){let t,n,{command:r,flags:o,client:s}=e;if(!o.remoteConfig)return{flags:o,runtime:e.runtime};let a=v(o.stateDir).baseDir,i=l({configPath:o.remoteConfig,cwd:process.cwd(),env:process.env}),c={...eS(i.profile),...o,remoteConfig:i.resolvedPath},d=eu({stateDir:a,session:c.session??"default"});if(d&&d.remoteConfigPath!==i.resolvedPath)throw new f("INVALID_ARGS","A different remote connection is already active for this session. Run connect --force or disconnect before using a different --remote-config.",{session:d.session,activeRemoteConfig:d.remoteConfigPath,requestedRemoteConfig:i.resolvedPath});let u=d??function(e,t){if(!e.tenant)throw new f("INVALID_ARGS","remote command requires tenant in remote config or via --tenant <id>.");if(!e.runId)throw new f("INVALID_ARGS","remote command requires runId in remote config or via --run-id <id>.");if(!e.daemonBaseUrl)throw new f("INVALID_ARGS","remote command requires daemonBaseUrl in remote config, config, env, or --daemon-base-url.");let n=new Date().toISOString();return{version:1,session:e.session??"default",remoteConfigPath:t,remoteConfigHash:eg(t),daemon:em(e),tenant:e.tenant,runId:e.runId,leaseId:e.leaseId,leaseBackend:e.leaseBackend??eE(e),platform:e.platform,target:e.target,connectedAt:n,updatedAt:n}}(c,i.resolvedPath),m={...c,session:u.session},p=function(e,t){if(e)return eT(e,t)?e:void 0}(u.runtime,m.platform)??e.runtime,g=u,h=!d;if(w=r,!eD.has(w)){let e=u.leaseBackend??function(e,t){let n=eE(e);if(n)return n;throw new f("INVALID_ARGS",`${t} requires --platform ios|android or --lease-backend when the remote connection has not resolved a lease yet.`)}(o,r);var w,I,y,A,_,S=u,D=o,C=e;if(S.leaseBackend&&S.leaseBackend!==C)throw new f("INVALID_ARGS","Active remote connection is already bound to a different lease backend. Re-run connect --force to replace it.",{session:S.session,leaseBackend:S.leaseBackend});if(S.platform&&D.platform&&S.platform!==D.platform)throw new f("INVALID_ARGS","Active remote connection is already bound to a different platform. Re-run connect --force to replace it.",{session:S.session,platform:S.platform});if(S.target&&D.target&&S.target!==D.target)throw new f("INVALID_ARGS","Active remote connection is already bound to a different target. Re-run connect --force to replace it.",{session:S.session,target:S.target});let t=await eB(s,g,e);m.leaseId=t.leaseId,m.leaseBackend=e,m.platform=g.platform??m.platform,m.target=g.target??m.target,(g.leaseId!==t.leaseId||g.leaseBackend!==e)&&(g={...g,leaseId:t.leaseId,leaseBackend:e,platform:g.platform??o.platform,target:g.target??o.target,updatedAt:new Date().toISOString()},h=!0)}if(I=r,y=e.batchSteps,(eC.has(I)||"batch"===I&&y&&y.some(e=>{let t=e.command.trim().toLowerCase();return eC.has(t)&&void 0===e.runtime}))&&eP(m)&&(!g.leaseId&&m.leaseId&&(g={...g,leaseId:m.leaseId,leaseBackend:m.leaseBackend}),e.forceRuntimePrepare||!p||!eT(p,m.platform))){if(!g.leaseId)throw new f("INVALID_ARGS",`${r} requires a resolved remote lease before Metro runtime can be prepared.`);let e=await eN(m,s,u.remoteConfigPath,u.session,{tenantId:u.tenant,runId:u.runId,leaseId:g.leaseId});p=e.runtime;let o=(A=g.metro,_=e.cleanup,A?.projectRoot!==_?.projectRoot||A?.profileKey!==_?.profileKey||A?.consumerKey!==_?.consumerKey);t=o?g.metro:void 0,n=o?e.cleanup:void 0,g={...g,runtime:e.runtime,metro:e.cleanup,updatedAt:new Date().toISOString()},h=!0}if(h)try{ef({stateDir:a,state:g})}catch(e){throw await eb(n),e}return await eb(t),{flags:{...m,session:g.session,leaseId:g.leaseId,leaseBackend:g.leaseBackend,platform:g.platform??m.platform,target:g.target??m.target},runtime:p}}async function eN(e,t,n,r,o){if(!e.metroProjectRoot&&!e.metroPublicBaseUrl&&!e.metroProxyBaseUrl)return{};if("ios"!==e.platform&&"android"!==e.platform)throw new f("INVALID_ARGS",'Deferred Metro preparation requires platform "ios" or "android".');if(!e.metroPublicBaseUrl&&!e.metroProxyBaseUrl)throw new f("INVALID_ARGS","Deferred Metro preparation requires metroPublicBaseUrl or metroProxyBaseUrl when Metro settings are provided.");let s=await t.metro.prepare({projectRoot:e.metroProjectRoot,kind:e.metroKind,publicBaseUrl:e.metroPublicBaseUrl,proxyBaseUrl:e.metroProxyBaseUrl,bearerToken:e.metroBearerToken,bridgeScope:o,launchUrl:e.launchUrl,companionProfileKey:n,companionConsumerKey:r,port:e.metroPreparePort,listenHost:e.metroListenHost,statusHost:e.metroStatusHost,startupTimeoutMs:e.metroStartupTimeoutMs,probeTimeoutMs:e.metroProbeTimeoutMs,reuseExisting:!e.metroNoReuseExisting&&void 0,installDependenciesIfNeeded:!e.metroNoInstallDeps&&void 0,runtimeFilePath:e.metroRuntimeFile});return{runtime:"ios"===e.platform?s.iosRuntime:s.androidRuntime,cleanup:e.metroProxyBaseUrl?{projectRoot:s.projectRoot,profileKey:n,consumerKey:r}:void 0}}async function eb(e){if(e)try{await I(e)}catch{}}async function eU(e){try{await ed({projectRoot:process.cwd(),stateDir:e.stateDir,profileKey:e.state.remoteConfigPath,consumerKey:e.state.session})}catch{}}async function eR(e,t){if(t.leaseId)try{await e.leases.release({tenant:t.tenant,runId:t.runId,leaseId:t.leaseId,daemonBaseUrl:t.daemon?.baseUrl,daemonTransport:t.daemon?.transport,daemonServerMode:t.daemon?.serverMode})}catch{}}function eE(e){return e.leaseBackend?e.leaseBackend:"android"===e.platform?"android-instance":"ios"===e.platform?"ios-instance":void 0}function eP(e){return!!(e.metroPublicBaseUrl||e.metroProxyBaseUrl||e.metroProjectRoot||e.metroKind)}function eT(e,t){return!e.platform||!t||"ios"!==t&&"android"!==t||e.platform===t}async function eB(e,t,n){if(t.leaseId&&t.leaseBackend===n){let r=await eL(e,t.leaseId,{tenant:t.tenant,runId:t.runId,leaseBackend:n});if(r)return r}return await e.leases.allocate({tenant:t.tenant,runId:t.runId,leaseBackend:n})}async function eL(e,t,n){try{return await e.leases.heartbeat({tenant:n.tenant,runId:n.runId,leaseId:t,leaseBackend:n.leaseBackend})}catch(e){var r;if((r=e)instanceof f&&"UNAUTHORIZED"===r.code&&(r.details?.reason==="LEASE_NOT_FOUND"||r.details?.reason==="LEASE_EXPIRED"||r.details?.reason==="LEASE_REVOKED"))return;throw e}}async function ex(e,t){let n=await e.text(),r={};if(n.trim().length>0)try{r=JSON.parse(n)}catch(n){throw new f("COMMAND_FAILED",t.invalidJsonMessage,{status:e.status},n instanceof Error?n:void 0)}if(!e.ok)throw new f("UNAUTHORIZED",t.rejectedMessage,{status:e.status,response:r});return r}async function eM(e){return await eO({command:e.command,flags:e.flags,stateDir:e.stateDir,allowInteractiveLogin:"connect"===e.command&&!e.flags.noLogin,env:e.env})}async function eO(e){let t=e.env??e.io?.env??process.env;if(!e.flags.daemonBaseUrl)return{flags:e.flags,source:"none"};if(eX(e.flags.daemonAuthToken))return{flags:e.flags,source:"flag"};if(eX(t.AGENT_DEVICE_DAEMON_AUTH_TOKEN))return{flags:e.flags,source:"env"};if(!function(e,t){if("1"===t.AGENT_DEVICE_CLOUD_AUTH||"true"===t.AGENT_DEVICE_CLOUD_AUTH||eX(t.AGENT_DEVICE_CLOUD_BASE_URL))return!0;try{let t=new URL(e).hostname.toLowerCase();return"agent-device.dev"===t||t.endsWith(".agent-device.dev")}catch{return!1}}(e.flags.daemonBaseUrl,t))return{flags:e.flags,source:"none"};let n=await eK({stateDir:e.stateDir,flags:e.flags,env:t,io:e.io});if(n)return{flags:{...e.flags,daemonAuthToken:n.accessToken},source:"cli-session"};if(!e.allowInteractiveLogin){if(e.flags.noLogin)throw new f("UNAUTHORIZED","Remote daemon authentication is required.",{hint:"Run agent-device auth login, unset --no-login, or set AGENT_DEVICE_DAEMON_AUTH_TOKEN."});throw eJ(e.command,t)}let r=await ej({stateDir:e.stateDir,flags:e.flags,env:t,io:e.io});return{flags:{...e.flags,daemonAuthToken:r.accessToken},source:"login"}}async function e$(e){let t=e.env??e.io?.env??process.env;if(eX(e.flags.daemonAuthToken))return{accessToken:e.flags.daemonAuthToken,cloudBaseUrl:ez(t)};if(eX(t.AGENT_DEVICE_DAEMON_AUTH_TOKEN))return{accessToken:t.AGENT_DEVICE_DAEMON_AUTH_TOKEN,cloudBaseUrl:ez(t)};let n=await eK({stateDir:e.stateDir,flags:e.flags,env:t,io:e.io});if(n)return{accessToken:n.accessToken,cloudBaseUrl:n.cloudBaseUrl};if(e.flags.noLogin)throw new f("UNAUTHORIZED","Cloud connection profile authentication is required.",{hint:"Run agent-device auth login, unset --no-login, or set AGENT_DEVICE_DAEMON_AUTH_TOKEN."});let r=await ej({stateDir:e.stateDir,flags:e.flags,env:t,io:e.io,commandLabel:"agent-device connect"});return{accessToken:r.accessToken,cloudBaseUrl:r.session.cloudBaseUrl}}async function ej(e){let n,o,s,a=e.env??e.io?.env??process.env,i=(d=a,u=e.io,n=u?.stdinIsTTY??process.stdin.isTTY,o=u?.stdoutIsTTY??process.stdout.isTTY,"true"!==(m=d).CI&&"true"!==m.GITHUB_ACTIONS&&"true"!==m.BUILDKITE&&n&&o?(p=d).SSH_TTY||p.SSH_CONNECTION||"true"===p.CODESPACES||p.GITPOD_WORKSPACE_ID||"true"===p.REMOTE_CONTAINERS?"device-code":"local-browser":"non-interactive");if("non-interactive"===i)throw eJ(e.commandLabel??"agent-device connect",a);let l=ez(a),c=await eq({baseUrl:l,pathName:"/api/control-plane/device-auth/start",body:{client:"agent-device",tenant:e.flags.tenant,runId:e.flags.runId,daemonBaseUrl:e.flags.daemonBaseUrl,session:e.flags.session},fetchImpl:e.io?.fetch});var d,u,m,p,g,h,w=c;if(!eX(w.deviceCode)||!eX(w.userCode)||!eX(w.verificationUri))throw new f("COMMAND_FAILED","Cloud auth start returned an unusable response.");let v=c.verificationUriComplete??c.verificationUri,I="local-browser"===i?c.verificationUri:(g=c.verificationUri,h=c.userCode,(s=new URL(g)).searchParams.set("user_code",h),s.toString());"local-browser"===i?(eZ(e.io,`Opening ${c.verificationUri}...
|
|
3
|
+
`),await eW(v,e.io)):eZ(e.io,`Open this URL on your machine:
|
|
4
|
+
${I}
|
|
12
5
|
|
|
13
6
|
Waiting for approval for 10 minutes...
|
|
14
|
-
`);let
|
|
15
|
-
`,{mode:384});try{
|
|
7
|
+
`);let y=await eF({cloudBaseUrl:l,deviceCode:c.deviceCode,expiresIn:c.expiresIn,interval:c.interval,fetchImpl:e.io?.fetch,now:e.io?.now}),A=y.cliSession?.refreshCredential??y.cliSession?.refreshToken;if(!eX(y.accessToken)||!eX(A))throw new f("UNAUTHORIZED","Device authorization did not return CLI credentials.");let _=new Date(e.io?.now?.()??Date.now()).toISOString(),S={version:1,id:y.cliSession?.id??`cli-${Date.now().toString(36)}`,cloudBaseUrl:l,workspaceId:y.cliSession?.workspaceId,accountId:y.cliSession?.accountId,name:y.cliSession?.name,refreshCredential:A,createdAt:_,expiresAt:y.cliSession?.expiresAt};return function(e){let n=eV(e.stateDir);t.mkdirSync(r.dirname(n),{recursive:!0,mode:448}),t.writeFileSync(n,`${JSON.stringify(e.session,null,2)}
|
|
8
|
+
`,{mode:384});try{t.chmodSync(n,384)}catch{}}({stateDir:e.stateDir,session:S}),{accessToken:y.accessToken,expiresAt:y.expiresAt,session:S}}function eG(e){let n=eV(e.stateDir);if(!t.existsSync(n))return null;try{let e=JSON.parse(t.readFileSync(n,"utf8"));if(1!==e.version||!eX(e.id)||!eX(e.cloudBaseUrl)||!eX(e.refreshCredential)||!eX(e.createdAt))return null;return e}catch{return null}}function eV(e){return r.join(e,"auth","cli-session.json")}async function eK(e){let t=eG({stateDir:e.stateDir});return!t||eY(t.expiresAt,e.io?.now)?null:{accessToken:(await eH({session:t,flags:e.flags,env:e.env,io:e.io})).accessToken,cloudBaseUrl:ez(e.env,t.cloudBaseUrl)}}async function eH(e){let t=ez(e.env,e.session.cloudBaseUrl),n=await eq({baseUrl:t,pathName:"/api/control-plane/cli-session/refresh",body:{refreshCredential:e.session.refreshCredential,tenant:e.flags.tenant,runId:e.flags.runId,daemonBaseUrl:e.flags.daemonBaseUrl,session:e.flags.session},fetchImpl:e.io?.fetch});if(eX(n.accessToken))return{accessToken:n.accessToken,expiresAt:n.expiresAt};if("revoked"===n.status||"revoked"===n.error)throw new f("UNAUTHORIZED","Stored cloud CLI session was revoked.",{hint:"Run agent-device auth login again, or set AGENT_DEVICE_DAEMON_AUTH_TOKEN.",status:n.status,error:n.error});throw new f("UNAUTHORIZED","Failed to refresh CLI session.",{hint:"Run agent-device auth login again, or set AGENT_DEVICE_DAEMON_AUTH_TOKEN.",status:n.status,error:n.error})}async function eF(e){let t=e.now??Date.now,n=Math.min((e.expiresIn??600)*1e3,6e5),r=t()+n,o=Math.max(1e3,(e.interval??5)*1e3);for(;t()<r;){let t=await eq({baseUrl:e.cloudBaseUrl,pathName:"/api/control-plane/device-auth/poll",body:{deviceCode:e.deviceCode},fetchImpl:e.fetchImpl});if("approved"===t.status||eX(t.accessToken))return t;if("slow_down"===t.status||"slow_down"===t.error)o+=1e3;else if("authorization_pending"!==t.status&&"authorization_pending"!==t.error)throw new f("UNAUTHORIZED","Device authorization was not approved.",{status:t.status,error:t.error});await eQ(o)}throw new f("TIMEOUT","Device authorization expired before approval.")}async function eq(e){let t=e.fetchImpl??fetch,n=await t(new URL(e.pathName,e.baseUrl),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e.body),signal:AbortSignal.timeout(15e3)});return await ex(n,{invalidJsonMessage:`Cloud auth endpoint returned invalid JSON (${n.status}).`,rejectedMessage:"Cloud auth endpoint rejected the request."})}function eJ(e,t){let n=ez(t);return new f("UNAUTHORIZED",`${e} cannot perform interactive login in CI or a non-interactive shell.`,{hint:`Create a service/API token: ${new URL("/api-keys",n).toString()} Then set AGENT_DEVICE_DAEMON_AUTH_TOKEN=adc_live_...`})}function ez(e,t){let n=e.AGENT_DEVICE_CLOUD_BASE_URL??t??"https://cloud.agent-device.dev";try{return new URL(n).toString().replace(/\/+$/,"")}catch(e){throw new f("INVALID_ARGS","Invalid AGENT_DEVICE_CLOUD_BASE_URL.",{cloudBaseUrl:n},e instanceof Error?e:void 0)}}async function eW(e,t){if(t?.openBrowser)return void await t.openBrowser(e);let n=process.platform;try{"darwin"===n?await A("open",[e],{allowFailure:!0,timeoutMs:5e3}):"win32"===n?await A("cmd",["/c","start","",e],{allowFailure:!0,timeoutMs:5e3}):await A("xdg-open",[e],{allowFailure:!0,timeoutMs:5e3})}catch{eZ(t,`Open this URL on your machine:
|
|
16
9
|
${e}
|
|
17
|
-
`)}}function
|
|
18
|
-
`,{mode:384});try{
|
|
19
|
-
`))}let tC=async({flags:e,client:t})=>{var n,r,i,s;let a=x(e.stateDir).baseDir,l=e.remoteConfig?function(e){if(!e.remoteConfig)throw new p("INVALID_ARGS","connect requires --remote-config <path>.");let t=w({configPath:e.remoteConfig,cwd:process.cwd(),env:process.env});return{flags:e,remoteConfigPath:t.resolvedPath}}(e):await t$({flags:e,stateDir:a,cwd:process.cwd(),env:process.env}),c=l.flags,d=c.tenant,u=c.runId;if(!d)throw new p("INVALID_ARGS","connect requires tenant in remote config or via --tenant <id>.");if(!u)throw new p("INVALID_ARGS","connect requires runId in remote config or via --run-id <id>.");if(!c.daemonBaseUrl)throw new p("INVALID_ARGS","connect requires daemonBaseUrl in remote config, config, env, or --daemon-base-url.");let f=c.session?null:eZ({stateDir:a}),m=c.session??f?.session??function(e){for(let t=0;t<8;t+=1){let t=`adc-${o.randomBytes(3).toString("hex")}`;if(!eF({stateDir:e,session:t}))return t}return`adc-${Date.now().toString(36)}-${o.randomBytes(2).toString("hex")}`}(a),h=eJ(l.remoteConfigPath),g=eV(c),v=f?.session===m?f:eF({stateDir:a,session:m});if(v&&(n=v,r={flags:c,session:m,remoteConfigPath:l.remoteConfigPath,remoteConfigHash:h,desiredLeaseBackend:e7(c),daemon:g},n.remoteConfigPath!==r.remoteConfigPath||n.remoteConfigHash!==r.remoteConfigHash||n.session!==r.session||n.tenant!==r.flags.tenant||n.runId!==r.flags.runId||void 0!==r.desiredLeaseBackend&&n.leaseBackend!==r.desiredLeaseBackend||void 0!==r.flags.platform&&n.platform!==r.flags.platform||void 0!==r.flags.target&&n.target!==r.flags.target||(i=n.daemon,s=r.daemon,(i?.baseUrl??void 0)!==(s?.baseUrl??void 0)||(i?.transport??void 0)!==(s?.transport??void 0)||(i?.serverMode??void 0)!==(s?.serverMode??void 0)))&&!c.force)throw new p("INVALID_ARGS","A different remote connection is already active for this session. Re-run connect with --force to replace it.",{session:m,remoteConfig:v.remoteConfigPath});let y=new Date().toISOString(),I={version:1,session:m,remoteConfigPath:l.remoteConfigPath,remoteConfigHash:h,daemon:g,tenant:d,runId:u,leaseId:v&&!c.force?v.leaseId:void 0,leaseBackend:v&&!c.force?v.leaseBackend:e7(c),platform:c.platform??(v&&!c.force?v.platform:void 0),target:c.target??(v&&!c.force?v.target:void 0),runtime:v&&!c.force?v.runtime:void 0,metro:v&&!c.force?v.metro:void 0,connectedAt:v&&!c.force?v.connectedAt:y,updatedAt:y};eG({stateDir:a,state:I}),v&&c.force&&(await e9(v.metro),await e6({stateDir:a,state:v}),await e4(t,v));let $=tN(I),A=function(e,t){if(!t.runtime&&(te(e)||tk(t.remoteConfigPath)))return tP(t.remoteConfigPath)}(c,I);return tS(c,tR(I,A),()=>[`Connected remote session "${m}" tenant "${d}" run "${u}" ${I.leaseId?`lease ${I.leaseId}`:"lease pending"}`,$?.message,A?.message].filter(e=>!!e).join("\n")),!0},tx=async({flags:e,client:t})=>{let{session:n,stateDir:r,state:o}=t_(e);if(!o)return tD(e,n),!0;let i=o.session;try{await t.sessions.close({shutdown:e.shutdown})}catch{}await e9(o.metro),await e6({stateDir:r,state:o});let s=!1;if(o.leaseId)try{s=(await t.leases.release({tenant:o.tenant,runId:o.runId,leaseId:o.leaseId})).released}catch{}return eq({stateDir:r,session:i}),tS(e,{connected:!1,session:i,released:s},()=>`Disconnected remote session "${i}".`),!0},tb=async({positionals:e,flags:t})=>{if("status"!==e[0])throw new p("INVALID_ARGS","connection accepts only: status");let{session:n,state:r}=t_(t);if(!r)return tD(t,n),!0;let o=tN(r),i=function(e){if(!e.runtime&&tk(e.remoteConfigPath))return tP(e.remoteConfigPath)}(r);return tS(t,tR(r,i),()=>[`Connected remote session "${r.session}".`,`tenant=${r.tenant} runId=${r.runId} leaseId=${r.leaseId??"pending"} backend=${r.leaseBackend??"pending"}`,`remoteConfig=${r.remoteConfigPath}`,r.runtime?"metro=prepared":"metro=not-prepared",o?.message,i?.message].filter(e=>!!e).join("\n")),!0};function t_(e){let t=e.session??"default",n=x(e.stateDir).baseDir;return{session:t,stateDir:n,state:eF({stateDir:n,session:t})??(e.session?null:eZ({stateDir:n}))}}function tD(e,t){tS(e,{connected:!1,session:t},()=>`No remote connection for "${t}".`)}function tN(e){if(!e.leaseId)return{status:"deferred",nextSteps:["agent-device install-from-source <artifact-url> --platform ios|android","agent-device open <app-id> --relaunch","agent-device snapshot -i","agent-device devices"],message:"Lease allocation is pending; run install-from-source, open, snapshot, or devices when ready to allocate or refresh the lease."+(void 0===e.platform&&void 0===e.leaseBackend?" Add --platform ios|android if the profile does not set a platform.":"")}}function tP(e){let t=`agent-device metro prepare --remote-config ${e}`;return{status:"deferred",nextStep:t,message:`Metro runtime is not prepared yet; it will be prepared automatically on first open, or run "${t}" to inspect it before launch.`}}function tk(e){try{let t=w({configPath:e,cwd:process.cwd(),env:process.env}).profile;return!!(t.metroPublicBaseUrl||t.metroProxyBaseUrl||t.metroProjectRoot||t.metroKind)}catch{return!1}}function tR(e,t){let n=tN(e);return{connected:!0,session:e.session,tenant:e.tenant,runId:e.runId,leaseAllocated:!!e.leaseId,leaseId:e.leaseId,leaseBackend:e.leaseBackend,platform:e.platform,target:e.target,remoteConfig:e.remoteConfigPath,remoteConfigHash:e.remoteConfigHash,daemonBaseUrlFingerprint:function(e){if(e)return o.createHash("sha256").update(e).digest("hex").slice(0,12)}(e.daemon?.baseUrl),metro:e.metro?{prepared:!0,projectRoot:e.metro.projectRoot}:{prepared:!1},...n?{leasePreparation:n}:{},...t?{runtimePreparation:t}:{},connectedAt:e.connectedAt,updatedAt:e.updatedAt}}let tU=async({positionals:e,flags:t})=>{let n=e[0]??"status",o=x(t.stateDir).baseDir;if("status"===n){var i;let e,n=(e=tl({stateDir:(i={stateDir:o}).stateDir}))?{authenticated:!0,source:"cli-session",sessionId:e.id,cloudBaseUrl:e.cloudBaseUrl,workspaceId:e.workspaceId,accountId:e.accountId,name:e.name,createdAt:e.createdAt,expiresAt:e.expiresAt,expired:tw(e.expiresAt,i.now)}:{authenticated:!1,source:"none"};return tS(t,n,()=>{var e;return(e=n).authenticated?["Authenticated with cloud CLI session.",`cloud=${e.cloudBaseUrl}`,`session=${e.sessionId}`,e.workspaceId?`workspace=${e.workspaceId}`:null,e.accountId?`account=${e.accountId}`:null,e.expiresAt?`expiresAt=${e.expiresAt}`:null,e.expired?"status=expired":null].filter(e=>!!e).join("\n"):"Not authenticated."}),!0}if("login"===n){let e=await ta({stateDir:o,flags:t,commandLabel:"agent-device auth login"});return tS(t,{authenticated:!0,source:"cli-session",sessionId:e.session.id,cloudBaseUrl:e.session.cloudBaseUrl,workspaceId:e.session.workspaceId,accountId:e.session.accountId,expiresAt:e.session.expiresAt,agentTokenExpiresAt:e.expiresAt},()=>"Authenticated with cloud CLI session."),!0}if("logout"===n){let e,n=(e=tc({stateDir:o}.stateDir),!!r.existsSync(e)&&(r.rmSync(e,{force:!0}),!0));return tS(t,{authenticated:!1,removed:n},()=>n?"Removed stored cloud CLI session.":"No stored cloud CLI session."),!0}throw new p("INVALID_ARGS","auth accepts only: status, login, logout")};function tE(e){return tB(E(e))}function tT(e){let t=e.ref??"",n=e.x,r=e.y;return t&&"number"==typeof n&&"number"==typeof r?{data:e,text:`Tapped @${t} (${n}, ${r})`}:tB(e)}function tB(e){return{data:e,text:B(e)}}function tM(e){let t=e.kind?` ${e.kind}`:"",n=e.target?` target=${e.target}`:"",r="boolean"==typeof e.booted?` booted=${e.booted}`:"";return`${e.name} (${e.platform}${t}${n})${r}`}function tL(e,t,n){"string"==typeof n&&e.push(` ${t}: ${n}`)}function tO(e,t){return t.map(t=>void 0!==e[t]&&null!==e[t]?`${t}=${e[t]}`:"").filter(Boolean).join(" ")||void 0}function tj(e){if(!Array.isArray(e))return;let t=e.filter(e=>"string"==typeof e&&e.length>0);return t.length>0?t.join("\n"):void 0}function tH(e){return e.filter(e=>!!e).join("\n")||void 0}function tK(e,t){return e?`Performance: ${e}`:`Frame health: unavailable - ${t}`}function tF(e){return e&&"object"==typeof e&&!Array.isArray(e)?e:void 0}function tG(e){return"number"==typeof e&&Number.isFinite(e)?e:void 0}function tV(e){return`${Number.isInteger(e)?e:e.toFixed(1)}%`}function tq(e){let t=Math.max(0,Math.round(e));if(t<1e3)return`${t}ms`;let n=Math.round(t/1e3);if(n<60)return`${n}s`;let r=Math.floor(n/60),o=n%60;return o>0?`${r}m ${o}s`:`${r}m`}function tJ(e){return({result:t})=>e(t)}let tz=tJ(function(e){return tB(e)}),tW={boot:tJ(function(e){let t=e.platform??"unknown",n=e.device??e.id??"unknown";return{data:e,text:`Boot ready: ${n} (${t})`}}),click:tJ(tT),press:tJ(tT),batch:tJ(function(e){let t="number"==typeof e.total?e.total:0,n="number"==typeof e.executed?e.executed:0,r="number"==typeof e.totalDurationMs?e.totalDurationMs:void 0,o=[`Batch completed: ${n}/${t} steps${void 0!==r?` in ${r}ms`:""}`];for(let t of Array.isArray(e.results)?e.results:[]){let e=function(e){let t=tF(e);if(!t)return;let n="number"==typeof t.step?t.step:void 0,r="string"==typeof t.command?t.command:"step",o=!1!==t.ok,i=function(e,t,n){var r;return t?B(tF(e.data))??n:(r=tF(e.error),("string"==typeof r?.message&&r.message.length>0?r.message:null)??n)}(t,o,r),s=void 0!==n?`${n}. `:"- ",a="number"==typeof t.durationMs?t.durationMs:void 0,l=void 0!==a?` (${a}ms)`:"";return`${s}${o?"OK":"FAILED"} ${i}${l}`}(t);e&&o.push(e)}return{data:e,text:o.join("\n")}}),devices:tJ(function(e){return{data:{devices:e.map(R)},text:e.map(tM).join("\n")}}),apps:({input:e,result:t})=>{var n;return{data:{apps:(n={result:t,appsFilter:e.appsFilter}).result},stderr:"all"===n.appsFilter?"Showing all apps, including system apps.\n":"Showing user-installed apps. Use --all to include system apps.\n",text:n.result.length>0?n.result.join("\n"):"all"===n.appsFilter?"No apps found.":"No user-installed apps found."}},session:tJ(function(e){let t={sessions:e.sessions.map(U)};return{data:t,text:JSON.stringify(t,null,2)}}),open:tJ(function(e){let t=P(e),n=[B(t)].filter(e=>!!e);return"string"==typeof t.sessionStateDir&&n.push(`Session state: ${t.sessionStateDir}`),{data:t,text:n.join("\n")||null}}),close:tJ(function(e){return tB(N(e))}),install:tJ(tE),reinstall:tJ(tE),"install-from-source":tJ(function(e){return tB(k(e))}),snapshot:({input:e,result:t})=>{var n;let r;return{data:r=T((n={result:t,raw:e.raw,interactiveOnly:e.interactiveOnly,scope:e.scope,depth:e.depth}).result),jsonData:function(e){let{unchanged:t,...n}=e;return n}(r),text:function(e,t={}){var n,r,o,l;let c,u,f,p,m,h=e.nodes,g=Array.isArray(h)?h:[],v="string"==typeof e.backend?e.backend:void 0,w=function(e,t,n){let r;if(n.raw||!((r=e.androidSnapshot)&&"object"==typeof r&&"android-helper"===r.backend))return{nodes:t,filteredCount:0};let o=function(e){var t,n;if(0===e.length)return e;let r=new Set,o=new Map,i=new Map(e.map(e=>[e.index,e]));(function(e,t){for(let n of e)!n.rect||eu(n.rect)||ep(n)||ey(e,n.index,t)})(e,r),function(e,t,n,r){for(let o of e){if(n.has(o.index)||o.rect||ep(o))continue;let i=function(e,t,n){let r=e;for(;"number"==typeof r.parentIndex;){let e=t.get(r.parentIndex);if(!e)break;if(n(e))return e;r=e}return null}(o,t,eh);i&&function(e,t,n){if(!n)return;let r=e.get(t.index)??t;e.set(t.index,{...r,hiddenContentAbove:!0===r.hiddenContentAbove||"above"===n||void 0,hiddenContentBelow:!0===r.hiddenContentBelow||"below"===n||void 0})}(r,i,function(e,t){let n=t.filter(t=>t.parentIndex===e.parentIndex&&t.rect&&eu(t.rect)).map(e=>e.index);return 0===n.length?null:e.index<Math.min(...n)?"above":e.index>Math.max(...n)?"below":null}(o,e)),ey(e,o.index,n)}}(e,i,r,o);for(let n of e){if(r.has(n.index)||!(!0===(t=n).hittable&&!em(t)&&t.rect&&eu(t.rect)&&0===eg(t).trim().length))continue;let i=function(e,t,n){let r=[],o=[],i=new Set;for(let s of e){if(n.has(s.index)||!eA(s)||!ef(s.rect,t.rect))continue;let e=eg(s).trim().replace(/\s+/g," "),a=ev(e);o.push(s.index),!e||!a||i.has(a)||(i.add(a),r.push(e))}return{label:r.join(", "),removableIndexes:o}}(ew(e,n.index),n,r);if(i.label)for(let t of(o.set(n.index,{...n,...o.get(n.index),label:i.label}),i.removableIndexes))ey(e,t,r)}for(let t of e){if(r.has(t.index)||!(!0===(n=t).hittable&&!em(n)&&n.rect&&eu(n.rect)&&ev(eg(n))))continue;let o=ev(eg(t));if(!o)continue;let i=ew(e,t.index).filter(e=>!r.has(e.index)&&function(e,t,n){if(!eS(t)||!ef(t.rect,e.rect))return!1;let r=ev(eg(t));return!!(r&&n!==r&&n.includes(r))}(t,e,o));for(let t of i.filter(eA))ey(e,t.index,r);let s=i.filter(e=>!eA(e)),a=new Set(s.map(e=>ev(eg(e))).filter(e=>!!e));if(!(s.length<2)&&!(a.size<2))for(let t of s)ey(e,t.index,r)}let s=new Map;for(let t of e){if(r.has(t.index)||!eS(t))continue;let n=ev(eg(t));if(!n)continue;let i=s.get(n);if(i&&function(e,t,n){var r,o,i,s;return!n.has(e.index)&&(r=e.rect,o=t.rect,!r||!o||Math.abs(r.y+r.height/2-(o.y+o.height/2))<=Math.max(r.height,o.height,1))&&(i=e,s=t,(i.parentIndex===s.parentIndex?3>=Math.abs(i.index-s.index):i.parentIndex!==s.index&&s.parentIndex!==i.index&&1>=Math.abs((i.depth??0)-(s.depth??0))&&2>=Math.abs(i.index-s.index))||function(e,t){let n=e.parentIndex===t.index?t:t.parentIndex===e.index?e:null,r=n?.index===e.index?t:n?.index===t.index?e:null;return!!n&&!!r&&eC(n,r).index===n.index}(e,t))}(i,t,r)){let a=function(e,t,n,r,o){var i,s,a;let l=eC(t,n),c=l.index===t.index?n:t,d=(c.type??"").toLowerCase().includes("image")?"has image":null,u=o.get(l.index)??l,f=o.get(c.index)?.presentationHints??c.presentationHints;return o.set(l.index,{...u,presentationHints:(i=u.presentationHints,s=f,a=d,[...new Set([...Array.isArray(i)?i:[],...Array.isArray(s)?s:[],...a?[a]:[]])])}),ey(e,c.index,r),o.get(l.index)??l}(e,i,t,r,o);s.set(n,a);continue}s.set(n,t)}return e.filter(e=>!r.has(e.index)).map(e=>o.get(e.index)??e)}(t);return{nodes:o,filteredCount:t.length-o.length}}(e,g,t),y=(c="string"==typeof(n=e).appName?n.appName:void 0,u="string"==typeof n.appBundleId?n.appBundleId:void 0,f=[],c&&f.push(`Page: ${c}`),u&&f.push(`App: ${u}`),f.length>0?`${f.join("\n")}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
`}
|
|
26
|
-
|
|
27
|
-
${$}${g.map(e=>JSON.stringify(e)).join("\n")}
|
|
28
|
-
`:t.flatten?`${y}${_}
|
|
29
|
-
${$}${a(x,{summarizeTextSurfaces:!0}).flatMap(e=>[d(e.node,0,!1,e.type,{summarizeTextSurfaces:!0}),...eO({...e,depth:0})]).join("\n")}${eN(S)}
|
|
30
|
-
`:`${y}${_}
|
|
31
|
-
${$}${(function(e){let t=[],n=[],r=new Map(e.map(e=>[e.node.index,e.node])),o=e=>{for(var o,i,s;n.length>0&&(!e||(o=e,i=n[n.length-1],s=r,!function(e,t,n){let r=e;for(;"number"==typeof r.parentIndex;){if(r.parentIndex===t.index)return!0;let e=n.get(r.parentIndex);if(!e)break;r=e}return!1}(o.node,i.node,s)&&o.depth<=i.depth));)t.push(...eO(n.pop(),"below"))};for(let r of e)o(r),t.push(r.text),t.push(...eO(r,"above")),r.node.hiddenContentBelow&&n.push(r);return o(),t})(a(x,{summarizeTextSurfaces:!0})).join("\n")}${eN(S)}
|
|
32
|
-
`}(r,{raw:n.raw,flatten:n.interactiveOnly,scoped:"string"==typeof n.scope&&n.scope.trim().length>0,depthLimited:"number"==typeof n.depth})}},wait:tz,alert:tz,appstate:tJ(function(e){return{data:e,text:function(e){if("ios"===e.platform){let t=[`Foreground app: ${e.appName??e.appBundleId??"unknown"}`];return e.appBundleId&&t.push(`Bundle: ${e.appBundleId}`),e.source&&t.push(`Source: ${e.source}`),t.join("\n")}if("android"===e.platform){let t=[`Foreground app: ${e.package??"unknown"}`];return e.activity&&t.push(`Activity: ${e.activity}`),t.join("\n")}return null}(e)}}),back:tz,home:tz,rotate:tz,"app-switcher":tz,keyboard:tJ(function(e){if("android"===e.platform&&"status"===e.action){var t;let n=[`Keyboard visible: ${!0===e.visible?"yes":"no"}`,`Input type: ${e.type??e.inputType??"unknown"}`,`Input owner: ${e.inputOwner??"unknown"}`];return e.inputMethodPackage&&n.push(`Input method: ${e.inputMethodPackage}`),e.focusedPackage&&n.push(`Focused package: ${e.focusedPackage}`),e.focusedResourceId&&n.push(`Focused resource: ${e.focusedResourceId}`),n.push(`Next action: ${(t=e.visible,"ime"===e.inputOwner?"Focused input appears to be owned by the keyboard/IME; dismiss or change the IME before retrying text entry.":!0===t?"Keyboard is visible and focused input appears app-owned; fill/type can proceed.":"Keyboard is hidden; focus an app field before type, or use fill with a concrete target.")}`),{data:e,text:n.join("\n")}}return tB(e)}),clipboard:tJ(function(e){return"read"===e.action?{data:e,text:e.text}:tB(e)}),get:({input:e,result:t})=>{var n;let r;return r=(n={result:t,format:e.format}).result,"text"===n.format?{data:r,text:"string"==typeof r.text?r.text:""}:"attrs"===n.format?{data:r,text:JSON.stringify(r.node??{},null,2)}:tB(r)},is:tJ(function(e){return{data:e,text:`Passed: is ${e.predicate??"assertion"}`}}),find:tJ(function(e){return"string"==typeof e.text?{data:e,text:e.text}:"boolean"==typeof e.found?{data:e,text:`Found: ${e.found}`}:e.node?{data:e,text:JSON.stringify(e.node,null,2)}:tB(e)}),perf:tJ(function(e){return{data:e,text:function(e){var t,n,r;let o,i=tF(e.metrics),s=tF(i?.fps),a=(t=i,(o=[function(e){if(e?.available!==!0)return;let t=tG(e.usagePercent);return void 0!==t?`CPU ${tV(t)}`:void 0}(tF(t?.cpu)),function(e){let t;if(e?.available!==!0)return;let n=tG(e.residentMemoryKb)??tG(e.totalPssKb)??tG(e.totalRssKb);return void 0!==n?`memory ${t=n/1024,`${t>=10?Math.round(t):t.toFixed(1)}MB`}`:void 0}(tF(t?.memory))].filter(e=>!!e)).length>0?o.join(", "):void 0);if(!s)return tK(a,"missing frame metric");if(!1===s.available){return tK(a,"string"==typeof(n=s).reason&&n.reason.length>0?n.reason:"not available")}let l=function(e){let t=tG(e.droppedFramePercent),n=tG(e.droppedFrameCount);if(void 0!==t&&void 0!==n){var r,o,i;return[`dropped ${tV(t)}`,(r=n,void 0!==(o=tG(e.totalFrameCount))?`(${Math.round(r)}/${Math.round(o)} frames)`:`(${Math.round(r)} dropped frames)`),void 0!==(i=tG(e.sampleWindowMs))?`window ${tq(i)}`:""].filter(Boolean).join(" ")}}(s);if(!l)return tK(a,"missing dropped-frame summary");let c=[`Frame health: ${l}`],d=(Array.isArray(r=s.worstWindows)?r.filter(e=>!!e&&"object"==typeof e&&!Array.isArray(e)):[]).flatMap(e=>{let t=function(e){let t=tG(e.startOffsetMs),n=tG(e.endOffsetMs),r=tG(e.missedDeadlineFrameCount);if(void 0===t||void 0===n||void 0===r)return;let o=tG(e.worstFrameMs),i=void 0===o?"":`, worst ${tq(o)}`;return`- +${tq(t)}-+${tq(n)}: ${Math.round(r)} missed-deadline frames${i}`}(e);return t?[t]:[]});return d.length>0&&c.push("Worst windows:",...d),c.join("\n")}(e)}}),prepare:tz,logs:tJ(function(e){var t;return{data:e,text:"string"==typeof e.path?e.path:"",stderr:tH([tO(e,["active","state","backend","sizeBytes"]),(t=e,["started","stopped","marked","cleared","restarted","removedRotatedFiles"].map(e=>{var n,r;return n=e,!0===(r=t[e])?`${n}=true`:"number"==typeof r?`${n}=${r}`:""}).filter(Boolean).join(" ")||void 0),"string"==typeof e.hint?e.hint:void 0,tj(e.notes)])}}),network:tJ(function(e){let t=[],n="string"==typeof e.path?e.path:"";n&&t.push(n);let r=Array.isArray(e.entries)?e.entries:[];if(0===r.length)t.push("No recent HTTP(s) entries found.");else for(let e of r)t.push(...function(e){let t=tF(e)??{},n="string"==typeof t.method?t.method:"HTTP",r="string"==typeof t.url?t.url:"<unknown-url>",o="number"==typeof t.status?` status=${t.status}`:"",i="string"==typeof t.timestamp?`${t.timestamp} `:"",s="number"==typeof t.durationMs?` durationMs=${t.durationMs}`:"",a=[`${i}${n} ${r}${o}${s}`];return tL(a,"headers",t.headers),tL(a,"request",t.requestBody),tL(a,"response",t.responseBody),a}(e));return{data:e,text:t.join("\n"),stderr:tH([tO(e,["active","state","backend","include","scannedLines","matchedLines"]),tj(e.notes)])}}),record:tJ(function(e){let t,n="string"==typeof e.outPath?e.outPath:"",r=Array.isArray(t=e.chunks)?t.flatMap(e=>e&&"object"==typeof e?"number"!=typeof e.index||"string"!=typeof e.path?[]:[{index:e.index,path:e.path}]:[]):[];if(r.length<=1){var o,i;let t;return{data:e,text:(o=e,t=[],(i=n)&&t.push(i),"string"==typeof o.sessionStateDir&&t.push(`Session state: ${o.sessionStateDir}`),"string"==typeof o.warning&&t.push(`Warning: ${o.warning}`),"string"==typeof o.overlayWarning&&t.push(`Overlay warning: ${o.overlayWarning}`),t.join("\n"))}}let s=["Recording chunks:"];for(let e of r)s.push(` ${e.index}: ${e.path}`);return"string"==typeof e.telemetryPath&&s.push(`Telemetry: ${e.telemetryPath}`),"string"==typeof e.warning&&s.push(`Warning: ${e.warning}`),"string"==typeof e.overlayWarning&&s.push(`Overlay warning: ${e.overlayWarning}`),{data:e,text:s.join("\n")}}),metro:({input:e,result:t})=>{var n;return{data:(n={result:t,action:e.action}).result,text:"reload"===n.action?`Reloaded React Native apps via ${n.result.reloadUrl}`:JSON.stringify(n.result,null,2)}}},tZ={...F,...G,...q,...M,...L,...K,...j,...H,metro:function(e,t){let n=(e[0]??"").toLowerCase();if("prepare"!==n&&"reload"!==n)throw new p("INVALID_ARGS","metro requires a subcommand: prepare or reload");if("reload"===n)return{action:n,metroHost:t.metroHost,metroPort:t.metroPort,bundleUrl:t.bundleUrl,timeoutMs:t.metroProbeTimeoutMs};if(!t.metroPublicBaseUrl&&!t.metroProxyBaseUrl)throw new p("INVALID_ARGS","metro prepare requires --public-base-url <url> or --proxy-base-url <url>.");return{action:n,projectRoot:t.metroProjectRoot,kind:t.metroKind,port:t.metroPreparePort,listenHost:t.metroListenHost,statusHost:t.metroStatusHost,publicBaseUrl:t.metroPublicBaseUrl,proxyBaseUrl:t.metroProxyBaseUrl,bearerToken:t.metroBearerToken,bridgeScope:t.tenant&&t.runId&&t.leaseId?{tenantId:t.tenant,runId:t.runId,leaseId:t.leaseId}:void 0,startupTimeoutMs:t.metroStartupTimeoutMs,probeTimeoutMs:t.metroProbeTimeoutMs,reuseExisting:!t.metroNoReuseExisting&&void 0,installDependenciesIfNeeded:!t.metroNoInstallDeps&&void 0,runtimeFilePath:t.metroRuntimeFile}},batch:(e,t)=>({...V(t),steps:t.batchSteps??[],onError:t.batchOnError,maxSteps:t.batchMaxSteps,out:t.out})};async function tY(e){return(await tX(e)).result}async function tX(e){var t,n,r,o;let i=(t=e.command,n=e.positionals,r=e.flags,tZ[t](n,r)),s=await J(e.client,e.command,i);return{result:s,cliOutput:(o={name:e.command,input:i,result:s},tW[o.name]?.({input:o.input??{},result:o.result}))}}let tQ={connect:tC,disconnect:tx,connection:tb,auth:tU,screenshot:async({positionals:e,flags:t,client:n})=>{let r=await tY({client:n,command:"screenshot",positionals:e,flags:t});return tS(t,{path:r.path,...r.overlayRefs?{overlayRefs:r.overlayRefs}:{}},()=>r.overlayRefs?`Annotated ${r.overlayRefs.length} refs onto ${r.path}`:r.path),!0},diff:async({positionals:e,flags:n,client:r})=>{var o;if("snapshot"===e[0]){let o=await tY({client:r,command:"diff",positionals:e,flags:n});return tS(n,o,()=>(function(e){var n;let r=!0===e.baselineInitialized,o=e.summary??{},i=eT(o.additions),s=eT(o.removals),a=eT(o.unchanged),l=eB(),c=eL(e),d=c.length>0?`${c.join("\n")}
|
|
33
|
-
`:"";if(r)return`${d}Baseline initialized (${a} lines).
|
|
34
|
-
`;let u=(function(e){if(0===e.length)return e;let t=e.map((e,t)=>({index:t,kind:e.kind})).filter(e=>"added"===e.kind||"removed"===e.kind).map(e=>e.index);if(0===t.length)return e;let n=Array(e.length).fill(!1);for(let r of t){let t=Math.max(0,r-1),o=Math.min(e.length-1,r+1);for(let e=t;e<=o;e+=1)n[e]=!0}return e.filter((e,t)=>n[t])})(Array.isArray(e.lines)?e.lines:[]).map(e=>{let n="string"==typeof e.text?e.text:"";if("added"===e.kind){let e=n.startsWith(" ")?`+${n}`:`+ ${n}`;return l?t("green",e):e}if("removed"===e.kind){let e=n.startsWith(" ")?`-${n}`:`- ${n}`;return l?t("red",e):e}return l?t("dim",n):n}),f=u.length>0?`${u.join("\n")}
|
|
35
|
-
`:"";if(!l)return`${d}${f}${i} additions, ${s} removals, ${a} unchanged
|
|
36
|
-
`;let p=`${(n=String(i),t("green",n))} additions, ${t("red",String(s))} removals, ${t("dim",String(a))} unchanged`;return`${d}${f}${p}
|
|
37
|
-
`})(o)),!0}if("screenshot"!==e[0])return!1;let i=n.baseline;if(!i||"string"!=typeof i)throw new p("INVALID_ARGS","diff screenshot requires --baseline <path>");let s=z(i),a="string"==typeof n.out?z(n.out):void 0,d=e[1];if(e.length>2)throw new p("INVALID_ARGS","diff screenshot accepts at most one current screenshot path");let u=c({backend:(o=r,{platform:function(e){switch(e.platform){case"android":case"linux":case"macos":return e.platform;default:return"ios"}}(n),captureScreenshot:async(e,t,n)=>{let r=await o.capture.screenshot({path:t,session:e.session,overlayRefs:n?.overlayRefs,fullscreen:n?.fullscreen,stabilize:n?.stabilize,surface:n?.surface});return{path:r.path,...r.overlayRefs?{overlayRefs:r.overlayRefs}:{}}}}),artifacts:Z(),sessions:{get:e=>({name:e}),set:()=>{}},policy:l()}),f=await u.capture.diffScreenshot({session:n.session,baseline:{kind:"path",path:s},current:d?{kind:"path",path:z(d)}:{kind:"live"},...a?{out:{kind:"path",path:a}}:{},threshold:function(e){if(null!=e&&""!==e)return Number(e)}(n.threshold),overlayRefs:n.overlayRefs,surface:n.surface});return tS(n,f,()=>{var e,n,r,o;let i,s,a,l,c,d,u,p;return i=eB(),s=!0===f.match,a=f.dimensionMismatch,(l=[]).push(...function(e,n){if(!0===e.match){let e=n?t("green","✓"):"✓";return[`${e} Screenshots match.`]}let r=e.dimensionMismatch,o=n?t("red","✗"):"✗";if(r){let e=r.expected,t=r.actual;return[`${o} Screenshots have different dimensions: expected ${e?.width}x${e?.height}, got ${t?.width}x${t?.height}`]}let i=eT(e.differentPixels),s=eT(e.mismatchPercentage),a=0===s&&i>0?"<0.01":String(s),l=`${a}% pixels differ`;return[`${o} ${n?t("red",l):l}`]}(f,i)),l.push(...function(e,n,r){if(n)return[];let o=[];if(e.diffPath){let n=eE(e.diffPath),i=r?t("dim","Diff image:"):"Diff image:",s=r?t("green",n):n;o.push(` ${i} ${s}`)}if(e.currentOverlayPath){let n=eE(e.currentOverlayPath),i=r?t("dim","Current overlay:"):"Current overlay:",s=r?t("green",n):n,a=eT(e.currentOverlayRefCount),l=a>0?` (${a} refs)`:"";o.push(` ${i} ${s}${l}`)}return o}(f,s,i)),s||a||(l.push(...(e=f,n=i,c=eT(e.differentPixels),d=eT(e.totalPixels),u=n?t("red",String(c)):String(c),[` ${u} different / ${d} total pixels`])),l.push(...(r=f,o=i,0===(p=function(e){let t=[];for(let n of(e.ocr?.movementClusters??[]).slice(0,2))t.push(`text movement cluster: ${function(e){let t=e.slice(0,4).map(e=>JSON.stringify(e)),n=e.length>t.length?` +${e.length-t.length} more`:"";return`${t.join(", ")}${n}`}(n.texts)} dx=${eU(n.xRange)}px dy=${eU(n.yRange)}px`);let n=(e.nonTextDeltas??[]).filter(e=>["icon","toggle","chevron"].includes(e.likelyKind)).slice(0,3);n.length>0&&t.push(`non-text controls: ${n.map(eR).join("; ")}`);let r=(e.nonTextDeltas??[]).filter(e=>"separator"===e.likelyKind).slice(0,2);return r.length>0&&t.push(`non-text boundaries: ${r.map(eR).join("; ")}`),t.slice(0,6)}(r)).length?[]:[` ${eM("Hints:",o)}`,...p.map(e=>` - ${e}`)])),l.push(...function(e,t){let n=Array.isArray(e.regions)?e.regions:[];if(0===n.length)return[];let r=[` ${eM("Changed regions:",t)}`];for(let e of n.slice(0,5))r.push(...function(e){let t=0===e.shareOfDiffPercentage&&e.differentPixels>0?"<0.01":String(e.shareOfDiffPercentage),n=e.rect,r=[` ${e.index}. ${e.location} x=${n.x} y=${n.y} ${n.width}x${n.height}, ${t}% of diff, change=${e.dominantChange}`],o=function(e){let t=[e.size?`size=${e.size}`:null,e.shape?`shape=${e.shape}`:null,"number"==typeof e.densityPercentage?`density=${e.densityPercentage}%`:null,e.averageBaselineColorHex&&e.averageCurrentColorHex?`avgColor=${e.averageBaselineColorHex}->${e.averageCurrentColorHex}`:null,"number"==typeof e.baselineLuminance&&"number"==typeof e.currentLuminance?`luminance=${e.baselineLuminance}->${e.currentLuminance}`:null].filter(e=>null!==e);return t.length>0?t.join(" "):null}(e);o&&r.push(` ${o}`);let i=e.currentOverlayMatches?.[0];if(i){let e=i.label?` "${i.label}"`:"";r.push(` overlaps @${i.ref}${e}, ${i.regionCoveragePercentage}% of region`)}return r}(e));return r}(f,i)),l.push(...function(e,t){let n=e.ocr?.matches??[];if(0===n.length)return[];let r=n.slice(0,8),o=[` ${eM(`OCR text deltas (${e.ocr?.provider}; baselineBlocks=${e.ocr?.baselineBlocks} currentBlocks=${e.ocr?.currentBlocks}; showing ${r.length}/${n.length}; px):`,t)}`,` ${eM("item | text | movePx | sizeDeltaPx | bboxBaseline | bboxCurrent | confidence | issueHint",t)}`];for(let[e,t]of r.entries()){let n=t.delta;o.push(` ${e+1} | ${JSON.stringify(t.text)} | ${ek(n.x)},${ek(n.y)} | ${ek(n.width)},${ek(n.height)} | ${eP(t.baselineRect)} | ${eP(t.currentRect)} | ${t.confidence} | ${t.possibleTextMetricMismatch?"ocr-bbox-size-change":"-"}`)}return o}(f,i)),l.push(...function(e,t){let n=e.nonTextDeltas??[];if(0===n.length)return[];let r=n.slice(0,8),o=[` ${eM(`Non-text visual deltas (showing ${r.length}/${n.length}; px):`,t)}`,` ${eM("item | region | slot | kind | bboxCurrent | nearestText",t)}`];for(let e of r)o.push(` ${e.index} | ${e.regionIndex?`r${e.regionIndex}`:"-"} | ${e.slot} | ${e.likelyKind} | ${eP(e.rect)} | ${e.nearestText?JSON.stringify(e.nearestText):"-"}`);return o}(f,i))),`${l.join("\n")}
|
|
38
|
-
`}),!0}};async function t0(e){let t={...e.flags},n=tQ[e.command];return n?await n({...e,flags:t}):!!Y(e.command)&&await t1({...e,command:e.command,flags:t})}async function t1(e){let{runGenericClientBackedCommand:t}=await import("./generic.js");return await t(e)}function t2(e,t,n){return n||(e.push(t),"")}async function t3(e,t,n){let{flags:r}=t,o=function(e){var t;if(!e?.metroProxyBaseUrl||"android-instance"!==(t=e.leaseBackend)&&"ios-instance"!==t)return null;let n=[],r={serverBaseUrl:t2(n,"metroProxyBaseUrl",e.metroProxyBaseUrl),bearerToken:t2(n,"metroBearerToken",e.metroBearerToken),tenantId:t2(n,"tenant",e.tenant),runId:t2(n,"runId",e.runId),leaseId:t2(n,"leaseId",e.leaseId)};if(n.length>0)throw new p("INVALID_ARGS",`react-devtools remote bridge requires ${n.join(", ")}.`,{missing:n});return r}(r);if(!o)return n();let i=t.stateDir??process.cwd(),s=t.session??r?.session??"default",a=r?.remoteConfig??`${o.tenantId}:${o.runId}:${o.leaseId}`;if("stop"===e[0])try{return await n()}finally{await eK({projectRoot:t.cwd??process.cwd(),stateDir:i,profileKey:a,consumerKey:s})}return await eH({projectRoot:t.cwd??process.cwd(),stateDir:i,serverBaseUrl:o.serverBaseUrl,bearerToken:o.bearerToken,bridgeScope:{tenantId:o.tenantId,runId:o.runId,leaseId:o.leaseId},session:s,profileKey:a,consumerKey:s,env:t.env??process.env}),await n()}async function t8(e,t={}){let n=t.cwd??process.cwd(),r=t.env??process.env,o=await t3(e,t,async()=>(await _("npm",["exec","--yes","--package","agent-react-devtools@0.4.0","--","agent-react-devtools",...e],{cwd:n,env:r,allowFailure:!0,onStdoutChunk:e=>{process.stdout.write(e)},onStderrChunk:e=>{process.stderr.write(e)}})).exitCode);var i,s=t.flags;return 0!==o&&"wait"===(i=e)[0]&&i.includes("--connected")&&"ios-instance"===s?.leaseBackend&&process.stderr.write("Hint: Remote iOS React DevTools connects during JavaScript startup.\nIf the app was already open before `agent-device react-devtools start`, relaunch it with `agent-device open <bundle-id> --platform ios --relaunch`, then retry `agent-device react-devtools wait --connected`.\n"),o}function t5(e,t={}){let n=t9(t),r={...e};return n.defaultPlatform&&void 0===r.platform&&(r.platform=n.defaultPlatform),r}function t9(e){var t,n,r,o;let i,s=e.env??process.env,a=e.inheritedPlatform??e.configuredPlatform??function(e){if(void 0===e)return;let t=e.trim().toLowerCase();if(t){if("ios"===t||"android"===t||"apple"===t)return t;throw new p("INVALID_ARGS",`Invalid AGENT_DEVICE_PLATFORM: ${e}. Use ios, android, or apple.`)}}(s.AGENT_DEVICE_PLATFORM),l="string"==typeof(t=e.configuredSession??s.AGENT_DEVICE_SESSION)&&t.trim().length>0;return{defaultPlatform:a,lockPolicy:(n=e.policyOverrides,r=s,o=l,(i=n?.sessionLock??n?.sessionLockConflicts??function(e){if(void 0===e)return;let t=e.trim().toLowerCase();if(t){if("reject"===t||"strip"===t)return t;throw new p("INVALID_ARGS",`Invalid session lock mode: ${e}. Use reject or strip.`)}}(r.AGENT_DEVICE_SESSION_LOCK))||(n?.sessionLocked===!0||o?"reject":void 0))}}let t6={sendToDaemon:ec},t4=new Set(["launchUrl","metroBearerToken","metroKind","metroListenHost","metroNoInstallDeps","metroNoReuseExisting","metroPreparePort","metroProbeTimeoutMs","metroProjectRoot","metroProxyBaseUrl","metroPublicBaseUrl","metroRuntimeFile","metroStartupTimeoutMs","metroStatusHost"]),t7=new Set(["connect","connection","close","disconnect","metro","session"]);async function ne(t,n=t6){let o=I(),i=ea(),s=function(e){try{let t=eo(e);return nt(t.command??"",t.providedFlags)}catch{return e.includes("--debug")||e.includes("-v")||e.includes("--verbose")}}(t),a=t.includes("--json"),l=function(e){for(let t=0;t<e.length;t+=1){let n=e[t];if(n.startsWith("--session=")){let e=n.slice(10).trim();return e.length>0?e:null}if("--session"===n){let n=e[t+1]?.trim();if(n&&!n.startsWith("-"))return n;break}}return null}(t)??process.env.AGENT_DEVICE_SESSION??"default";await $({session:l,requestId:o,command:t[0],debug:s},async()=>{var l,c,d,m,h,g,v,I,$,b,_,D,N,P,k,R,U;let E,T,B,M,L,j,H;try{let n,o,i,s,a,u,f,y;l={cwd:process.cwd(),env:process.env},n=eo(t),o=l?.env??process.env,i=l?.cwd??process.cwd(),m=n.command,s=null!==m&&(c={remoteConfig:n.flags.remoteConfig,cwd:i,env:o}).remoteConfig?{...e1(w({configPath:c.remoteConfig,cwd:c.cwd,env:c.env}).profile),remoteConfig:c.remoteConfig}:{},f=Q((a=(d={command:n.command,cwd:i,cliFlags:n.flags,env:o}).env??process.env,u=Q({},function(e){let t={};for(let n of e)Q(t,function(e,t){let n,o;if(!r.existsSync(e)){if(t)throw new p("INVALID_ARGS",`Config file not found: ${e}`);return{}}try{n=r.readFileSync(e,"utf8")}catch(t){throw new p("INVALID_ARGS",`Failed to read config file: ${e}`,{cause:t instanceof Error?t.message:String(t)})}try{o=JSON.parse(n)}catch(t){throw new p("INVALID_ARGS",`Invalid JSON in config file: ${e}`,{cause:t instanceof Error?t.message:String(t)})}if(!o||"object"!=typeof o||Array.isArray(o))throw new p("INVALID_ARGS",`Config file must contain a JSON object: ${e}`);return function(e,t){let n={};for(let[r,o]of Object.entries(e)){if("installSource"===r){n.installSource=O(o,t);continue}let e=en(r);if(!e)throw new p("INVALID_ARGS",`Unknown config key "${r}" in ${t}.`);if(!e.config.enabled)throw new p("INVALID_ARGS",`Unsupported config key "${r}" in ${t}.`);n[r]=ee(e,o,t,r)}return n}(o,`config file ${e}`)}(n.path,n.required));return t}((h=d.cwd,g=d.cliFlags.config,v=a,(y=g??v.AGENT_DEVICE_CONFIG)?[{path:(I=y,$=h,b=v,z(I,{cwd:$,env:b})),required:!0}]:[{path:(_=v,e.join(W("~",{env:_}),".agent-device","config.json")),required:!1},{path:e.resolve(h,"agent-device.json"),required:!1}]))),Q(u,function(e,t){let n={};for(let r of et(t)){if("installSource"===r.key)continue;let t=r.env.names.map(t=>({name:t,value:e[t]})).find(e=>"string"==typeof e.value&&e.value.trim().length>0);t&&(n[r.key]=ee(r,t.value,`environment variable ${t.name}`,t.name))}return n}(a,d.command))),s),E={...es(n,{strictFlags:l?.strictFlags,defaultFlags:f}),providedFlags:n.providedFlags}}catch(t){C({level:"error",phase:"cli_parse_failed",data:{error:t instanceof Error?t.message:String(t)}});let e=f(t,{diagnosticId:A().diagnosticId,logPath:S({force:!0})??void 0});a?e_({success:!1,error:e}):eD(e,{showDetails:s}),process.exit(1);return}for(let e of E.warnings)process.stderr.write(`Warning: ${e}
|
|
39
|
-
`);E.flags.version&&(process.stdout.write(`${i}
|
|
40
|
-
`),process.exit(0));let K="help"===E.command,F=E.flags.help;if(K||F){K&&E.positionals.length>1&&(eD(new p("INVALID_ARGS","help accepts at most one command.")),process.exit(1));let e=K?E.positionals[0]:E.command;e||(process.stdout.write(`${er()}
|
|
41
|
-
`),process.exit(0));let t=ei(e);t&&(process.stdout.write(t),process.exit(0)),eD(new p("INVALID_ARGS",`Unknown command: ${e}`)),process.stdout.write(`${er()}
|
|
42
|
-
`),process.exit(1)}E.command||(process.stdout.write(`${er()}
|
|
43
|
-
`),process.exit(1));let{command:G,positionals:V}=E,q=nt(G,E.providedFlags),J=new Set(E.providedFlags.map(e=>e.key));try{B=(T=t9({policyOverrides:E.flags,configuredPlatform:E.flags.platform,configuredSession:E.flags.session})).lockPolicy?{...E.flags}:t5(E.flags,{policyOverrides:E.flags,configuredPlatform:E.flags.platform,configuredSession:E.flags.session}),M=x(B.stateDir),L=B.session??"default",D={command:G,explicitFlagKeys:J,stateDir:M.baseDir,session:L,remoteConfig:B.remoteConfig,hasResolvedSession:void 0!==B.session},H=(j="connect"===D.command||"connection"===D.command?null:function(e){let t=e.validateRemoteConfigHash??!0,n=e.remoteConfig?y({configPath:e.remoteConfig,cwd:e.cwd,env:e.env}):void 0,r=eF(e)??(e.allowActiveFallback?eZ({stateDir:e.stateDir}):null);if(!r||n&&r.remoteConfigPath!==n)return null;if(t&&eJ(r.remoteConfigPath)!==r.remoteConfigHash)throw new p("INVALID_ARGS","Active remote connection config changed. Run agent-device connect --force to refresh it.",{remoteConfig:r.remoteConfigPath});let o=function(e,t){try{return w({configPath:e.remoteConfigPath,cwd:t.cwd,env:t.env}).profile}catch(e){if(!1===t.validateRemoteConfigHash)return{};throw e}}(r,e);return{runtime:r.runtime,flags:{...o,remoteConfig:r.remoteConfigPath,daemonBaseUrl:r.daemon?.baseUrl??o.daemonBaseUrl,daemonTransport:r.daemon?.transport??o.daemonTransport,daemonServerMode:r.daemon?.serverMode??o.daemonServerMode,tenant:r.tenant,sessionIsolation:"tenant",runId:r.runId,leaseId:r.leaseId,leaseBackend:r.leaseBackend,session:r.session,platform:r.platform??o.platform,target:r.target??o.target}}}({stateDir:D.stateDir,session:D.session,remoteConfig:D.remoteConfig,cwd:process.cwd(),env:process.env,allowActiveFallback:!D.explicitFlagKeys.has("session")&&(!D.remoteConfig||"disconnect"===D.command||!D.hasResolvedSession),validateRemoteConfigHash:"disconnect"!==D.command}))?function(e,t,n){let r={...e};for(let[e,o]of Object.entries(t))void 0!==o&&(n.has(e)||(r[e]=o));return r}(B,j.flags,J):B}catch(t){let e=f(u(t),{diagnosticId:A().diagnosticId,logPath:S({force:!0})??void 0});E.flags.json?e_({success:!1,error:e}):eD(e,{showDetails:q}),process.exit(1);return}let Z=null;try{let e;if("react-devtools"===G){let e=await t8(V,{flags:H,stateDir:M.baseDir,session:H.session??L,cwd:process.cwd(),env:process.env});process.exit(e);return}ed({command:G,currentVersion:i,stateDir:M.baseDir,flags:H});let t=j?.runtime,s=(e,t)=>({session:e.session,requestId:o,stateDir:e.stateDir,daemonBaseUrl:e.daemonBaseUrl,daemonAuthToken:e.daemonAuthToken,daemonTransport:e.daemonTransport,daemonServerMode:e.daemonServerMode,tenant:e.tenant,sessionIsolation:e.sessionIsolation,runId:e.runId,leaseId:e.leaseId,leaseBackend:e.leaseBackend,runtime:t,lockPolicy:T.lockPolicy,lockPlatform:T.defaultPlatform,cwd:process.cwd(),debug:q});if("batch"===G){if(V.length>0)throw new p("INVALID_ARGS","batch does not accept positional arguments.");e=function(e){let t,n,o,i="";if(e.steps)i=e.steps;else if(e.stepsFile)try{i=r.readFileSync(e.stepsFile,"utf8")}catch(n){let t=n instanceof Error?n.message:String(n);throw new p("INVALID_ARGS",`Failed to read --steps-file ${e.stepsFile}: ${t}`)}var s,a=i;try{o=JSON.parse(a)}catch{throw new p("INVALID_ARGS","Batch steps must be valid JSON.")}if(!Array.isArray(o)||0===o.length)throw new p("INVALID_ARGS","Batch steps must be a non-empty JSON array.");return s=o,t=!1,n=s.map((e,n)=>{var r,o,i,s,a,l;let c;if(r=e,null!==r&&"object"==typeof r&&!Array.isArray(r)&&"input"in r&&!("positionals"in r)&&!("flags"in r))return e;let d=function(e,t){if(!e||"object"!=typeof e||Array.isArray(e))throw new p("INVALID_ARGS",`Invalid batch step ${t}.`);var n=e,r=t;let o=Object.keys(n).filter(e=>!["command","positionals","flags","runtime"].includes(e));if(o.length>0)throw new p("INVALID_ARGS",`Batch step ${r} has unknown legacy field(s): ${o.join(", ")}.`);let i=function(e,t){let n="string"==typeof e?e.trim().toLowerCase():"";if(!n)throw new p("INVALID_ARGS",`Batch step ${t} requires command.`);if(X(n))return n;throw new p("INVALID_ARGS",`Batch step ${t} command is not available through command batch: ${String(e)}`)}(e.command,t),s=function(e,t){if(void 0!==e){if(!Array.isArray(e)||e.some(e=>"string"!=typeof e))throw new p("INVALID_ARGS",`Batch step ${t} positionals must contain only strings.`);return e}}(e.positionals,t),a=function(e,t){if(void 0!==e){if(!e||"object"!=typeof e||Array.isArray(e))throw new p("INVALID_ARGS",`Batch step ${t} flags must be an object.`);return e}}(e.flags,t);return{command:i,...void 0===s?{}:{positionals:s},...void 0===a?{}:{flags:a},...void 0===e.runtime?{}:{runtime:e.runtime}}}(e,n+1);return t=!0,c=(i=(o=d).command,s=o.positionals??[],l=o.flags,a={json:!1,help:!1,version:!1,...l},tZ[i](s,a)),{command:o.command,input:c,...void 0===o.runtime?{}:{runtime:o.runtime}}}),t&&process.stderr.write('Warning: batch steps using positionals/flags are deprecated and will be removed in the next major version. Use {"command":"...","input":{...}} steps instead.\n'),n}(B)}if(N=G,"auth"!==N&&"connection"!==N&&(H=(await to({command:G,flags:H,stateDir:M.baseDir,env:process.env})).flags),H.remoteConfig&&(P=G,!t7.has(P))){let r=el(s(H,t),{transport:n.sendToDaemon}),o=await e8({command:G,flags:H,client:r,runtime:t,batchSteps:e,forceRuntimePrepare:function(e){for(let t of t4)if(e.has(t))return!0;return!1}(J)});H=o.flags,t=o.runtime}k={command:G,flags:H,runtime:t,explicitFlagKeys:J,hadConnectionDefaults:!!j},!("open"===k.command&&!k.runtime&&!k.flags.bundleUrl&&!k.flags.metroHost&&!k.flags.metroPort&&!k.flags.remoteConfig&&!k.hadConnectionDefaults&&((R=k.explicitFlagKeys).has("daemonBaseUrl")||R.has("daemonTransport")||R.has("tenant")||R.has("sessionIsolation")||R.has("runId")||R.has("leaseId")||R.has("leaseBackend")))||process.stderr.write("Warning: open is using explicit remote daemon or tenant flags without saved Metro runtime hints. React Native apps may launch without bundle/runtime hints; prefer connect --remote-config <path> first or pass --remote-config <path> on this command.\n");let a=H.daemonBaseUrl;Z=!q||H.json||a?null:function(e){try{let t=r.existsSync(e)?r.statSync(e).size:0,n=!1,o=setInterval(()=>{if(!n&&r.existsSync(e))try{let n=r.statSync(e);if(n.size<t&&(t=0),n.size<=t)return;let o=r.openSync(e,"r");try{let e=Buffer.alloc(n.size-t);r.readSync(o,e,0,e.length,t),t=n.size,e.length>0&&process.stdout.write(e.toString("utf8"))}finally{r.closeSync(o)}}catch{}},200);return()=>{n=!0,clearInterval(o)}}catch{return null}}(M.logPath);let l=el(s(H,t),{transport:function(e){let{command:t,flags:n,transport:r}=e;return"test"!==t||n.json?r:async e=>await r({...e,meta:{...e.meta,requestProgress:"replay-test"}})}({command:G,flags:H,transport:n.sendToDaemon})});if("batch"===G){if(!e)throw new p("INVALID_ARGS","batch requires --steps or --steps-file.");let t=e.map((e,t)=>({...e,input:T.lockPolicy&&void 0===B.platform?{...e.input}:t5(e.input,{policyOverrides:H,configuredPlatform:H.platform,configuredSession:H.session,inheritedPlatform:H.platform})}));if(await t0({command:G,positionals:V,flags:{...H,batchSteps:t},client:l}))return}else if("runtime"===G)throw new p("INVALID_ARGS","runtime command was removed. Use connect --remote-config <path> for remote runs, or metro prepare --remote-config <path> for inspection.");else if(await t0({command:G,positionals:V,flags:H,client:l}))return;throw new p("INVALID_ARGS",`Unknown command: ${G}`)}catch(n){let e=u(n),t=f(e,{diagnosticId:A().diagnosticId,logPath:S({force:!0})??void 0});if("close"===G&&"COMMAND_FAILED"===(U=e).code&&(U.details?.kind==="daemon_startup_failed"||U.message.toLowerCase().includes("failed to start daemon")&&("string"==typeof U.details?.infoPath||"string"==typeof U.details?.lockPath))){H.json&&e_({success:!0,data:{closed:"session",source:"no-daemon"}});return}if(H.json)e_({success:!1,error:t});else if(eD(t,{showDetails:q}),q)try{let e=M.logPath;if(r.existsSync(e)){let t=r.readFileSync(e,"utf8").split("\n"),n=t.slice(Math.max(0,t.length-200)).join("\n");n.trim().length>0&&process.stderr.write(`
|
|
10
|
+
`)}}function eZ(e,t){(e?.stderr??process.stderr).write(t)}function eY(e,t){if(!e)return!1;let n=Date.parse(e);return!Number.isFinite(n)||n<=(t?.()??Date.now())}function eX(e){return"string"==typeof e&&e.trim().length>0}async function eQ(e){await new Promise(t=>setTimeout(t,e))}async function e0(e){let o=await e$({stateDir:e.stateDir,flags:e.flags,env:e.env,io:{env:e.env,fetch:e.fetchImpl}}),s=await e1({cloudBaseUrl:o.cloudBaseUrl,accessToken:o.accessToken,fetchImpl:e.fetchImpl}),a=function(e){try{return l(e)}catch(n){let t=d(n);throw new f("COMMAND_FAILED","Cloud connection profile returned invalid remote config.",{generatedConfigPath:e.configPath,cause:t.message},t)}}({configPath:function(e){var o;let s=function e(t){return Array.isArray(t)?t.map(e):t&&"object"==typeof t?Object.fromEntries(Object.entries(t).filter(([,e])=>void 0!==e).sort(([e],[t])=>e.localeCompare(t)).map(([t,n])=>[t,e(n)])):t}(e.profile),a=r.join(e.stateDir,"remote-connections","generated");t.mkdirSync(a,{recursive:!0,mode:448});let i=r.join(a,`cloud-${(o=s,n.createHash("sha256").update(JSON.stringify(o)).digest("hex").slice(0,16))}.json`);t.writeFileSync(i,`${JSON.stringify(s,null,2)}
|
|
11
|
+
`,{mode:384});try{t.chmodSync(i,384)}catch{}return i}({stateDir:e.stateDir,profile:s}),cwd:e.cwd,env:e.env});return{flags:{...eS(a.profile),...e.flags,remoteConfig:a.resolvedPath,daemonAuthToken:o.accessToken},remoteConfigPath:a.resolvedPath}}async function e1(e){let t=e.fetchImpl??fetch,n=await t(new URL("/api/control-plane/connection-profile",e.cloudBaseUrl),{method:"GET",headers:{authorization:`Bearer ${e.accessToken}`},signal:AbortSignal.timeout(15e3)});var r=await ex(n,{invalidJsonMessage:`Cloud connection profile endpoint returned invalid JSON (${n.status}).`,rejectedMessage:"Cloud connection profile endpoint rejected the request."});if(!r||"object"!=typeof r||Array.isArray(r))throw new f("COMMAND_FAILED","Cloud connection profile response is invalid.");let o=r.connection;if(!o||"object"!=typeof o)throw new f("COMMAND_FAILED","Cloud connection profile response is missing profile.");if(void 0!==o.remoteConfigProfile){var s=o.remoteConfigProfile;if(!s||"object"!=typeof s||Array.isArray(s))throw new f("COMMAND_FAILED","Cloud connection profile remoteConfigProfile is invalid.");if(0===Object.keys(s).length)throw new f("COMMAND_FAILED","Cloud connection profile remoteConfigProfile is empty.");return s}throw new f("COMMAND_FAILED","Cloud connection profile did not include remoteConfigProfile.")}function e3(e,t,n){var r;if(e.json)return void k({success:!0,data:t});let o=n?.();o&&(r=o,process.stdout.write(r.endsWith("\n")?r:`${r}
|
|
12
|
+
`))}let e8=async({flags:e,client:t})=>{var r,o,s,a;let i=v(e.stateDir).baseDir,c=e.remoteConfig?function(e){if(!e.remoteConfig)throw new f("INVALID_ARGS","connect requires --remote-config <path>.");let t=l({configPath:e.remoteConfig,cwd:process.cwd(),env:process.env});return{flags:e,remoteConfigPath:t.resolvedPath}}(e):await e0({flags:e,stateDir:i,cwd:process.cwd(),env:process.env}),d=c.flags,u=d.tenant,m=d.runId;if(!u)throw new f("INVALID_ARGS","connect requires tenant in remote config or via --tenant <id>.");if(!m)throw new f("INVALID_ARGS","connect requires runId in remote config or via --run-id <id>.");if(!d.daemonBaseUrl)throw new f("INVALID_ARGS","connect requires daemonBaseUrl in remote config, config, env, or --daemon-base-url.");let p=d.session?null:ev({stateDir:i}),g=d.session??p?.session??function(e){for(let t=0;t<8;t+=1){let t=`adc-${n.randomBytes(3).toString("hex")}`;if(!eu({stateDir:e,session:t}))return t}return`adc-${Date.now().toString(36)}-${n.randomBytes(2).toString("hex")}`}(i),h=eg(c.remoteConfigPath),w=em(d),I=p?.session===g?p:eu({stateDir:i,session:g});if(I&&(r=I,o={flags:d,session:g,remoteConfigPath:c.remoteConfigPath,remoteConfigHash:h,desiredLeaseBackend:eE(d),daemon:w},r.remoteConfigPath!==o.remoteConfigPath||r.remoteConfigHash!==o.remoteConfigHash||r.session!==o.session||r.tenant!==o.flags.tenant||r.runId!==o.flags.runId||void 0!==o.desiredLeaseBackend&&r.leaseBackend!==o.desiredLeaseBackend||void 0!==o.flags.platform&&r.platform!==o.flags.platform||void 0!==o.flags.target&&r.target!==o.flags.target||(s=r.daemon,a=o.daemon,(s?.baseUrl??void 0)!==(a?.baseUrl??void 0)||(s?.transport??void 0)!==(a?.transport??void 0)||(s?.serverMode??void 0)!==(a?.serverMode??void 0)))&&!d.force)throw new f("INVALID_ARGS","A different remote connection is already active for this session. Re-run connect with --force to replace it.",{session:g,remoteConfig:I.remoteConfigPath});let y=new Date().toISOString(),A={version:1,session:g,remoteConfigPath:c.remoteConfigPath,remoteConfigHash:h,daemon:w,tenant:u,runId:m,leaseId:I&&!d.force?I.leaseId:void 0,leaseBackend:I&&!d.force?I.leaseBackend:eE(d),platform:d.platform??(I&&!d.force?I.platform:void 0),target:d.target??(I&&!d.force?I.target:void 0),runtime:I&&!d.force?I.runtime:void 0,metro:I&&!d.force?I.metro:void 0,connectedAt:I&&!d.force?I.connectedAt:y,updatedAt:y};ef({stateDir:i,state:A}),I&&d.force&&(await eb(I.metro),await eU({stateDir:i,state:I}),await eR(t,I));let _=e5(A),S=function(e,t){if(!t.runtime&&(eP(e)||te(t.remoteConfigPath)))return e6(t.remoteConfigPath)}(d,A);return e3(d,tt(A,S),()=>[`Connected remote session "${g}" tenant "${u}" run "${m}" ${A.leaseId?`lease ${A.leaseId}`:"lease pending"}`,_?.message,S?.message].filter(e=>!!e).join("\n")),!0},e2=async({flags:e,client:t})=>{let{session:n,stateDir:r,state:o}=e7(e);if(!o)return e4(e,n),!0;let s=o.session;try{await t.sessions.close({shutdown:e.shutdown})}catch{}await eb(o.metro),await eU({stateDir:r,state:o});let a=!1;if(o.leaseId)try{a=(await t.leases.release({tenant:o.tenant,runId:o.runId,leaseId:o.leaseId})).released}catch{}return ep({stateDir:r,session:s}),e3(e,{connected:!1,session:s,released:a},()=>`Disconnected remote session "${s}".`),!0},e9=async({positionals:e,flags:t})=>{if("status"!==e[0])throw new f("INVALID_ARGS","connection accepts only: status");let{session:n,state:r}=e7(t);if(!r)return e4(t,n),!0;let o=e5(r),s=function(e){if(!e.runtime&&te(e.remoteConfigPath))return e6(e.remoteConfigPath)}(r);return e3(t,tt(r,s),()=>[`Connected remote session "${r.session}".`,`tenant=${r.tenant} runId=${r.runId} leaseId=${r.leaseId??"pending"} backend=${r.leaseBackend??"pending"}`,`remoteConfig=${r.remoteConfigPath}`,r.runtime?"metro=prepared":"metro=not-prepared",o?.message,s?.message].filter(e=>!!e).join("\n")),!0};function e7(e){let t=e.session??"default",n=v(e.stateDir).baseDir;return{session:t,stateDir:n,state:eu({stateDir:n,session:t})??(e.session?null:ev({stateDir:n}))}}function e4(e,t){e3(e,{connected:!1,session:t},()=>`No remote connection for "${t}".`)}function e5(e){if(!e.leaseId)return{status:"deferred",nextSteps:["agent-device install-from-source <artifact-url> --platform ios|android","agent-device open <app-id> --relaunch","agent-device snapshot -i","agent-device devices"],message:"Lease allocation is pending; run install-from-source, open, snapshot, or devices when ready to allocate or refresh the lease."+(void 0===e.platform&&void 0===e.leaseBackend?" Add --platform ios|android if the profile does not set a platform.":"")}}function e6(e){let t=`agent-device metro prepare --remote-config ${e}`;return{status:"deferred",nextStep:t,message:`Metro runtime is not prepared yet; it will be prepared automatically on first open, or run "${t}" to inspect it before launch.`}}function te(e){try{let t=l({configPath:e,cwd:process.cwd(),env:process.env}).profile;return!!(t.metroPublicBaseUrl||t.metroProxyBaseUrl||t.metroProjectRoot||t.metroKind)}catch{return!1}}function tt(e,t){let r=e5(e);return{connected:!0,session:e.session,tenant:e.tenant,runId:e.runId,leaseAllocated:!!e.leaseId,leaseId:e.leaseId,leaseBackend:e.leaseBackend,platform:e.platform,target:e.target,remoteConfig:e.remoteConfigPath,remoteConfigHash:e.remoteConfigHash,daemonBaseUrlFingerprint:function(e){if(e)return n.createHash("sha256").update(e).digest("hex").slice(0,12)}(e.daemon?.baseUrl),metro:e.metro?{prepared:!0,projectRoot:e.metro.projectRoot}:{prepared:!1},...r?{leasePreparation:r}:{},...t?{runtimePreparation:t}:{},connectedAt:e.connectedAt,updatedAt:e.updatedAt}}let tn=async({positionals:e,flags:n})=>{let r=e[0]??"status",o=v(n.stateDir).baseDir;if("status"===r){var s;let e,t=(e=eG({stateDir:(s={stateDir:o}).stateDir}))?{authenticated:!0,source:"cli-session",sessionId:e.id,cloudBaseUrl:e.cloudBaseUrl,workspaceId:e.workspaceId,accountId:e.accountId,name:e.name,createdAt:e.createdAt,expiresAt:e.expiresAt,expired:eY(e.expiresAt,s.now)}:{authenticated:!1,source:"none"};return e3(n,t,()=>{var e;return(e=t).authenticated?["Authenticated with cloud CLI session.",`cloud=${e.cloudBaseUrl}`,`session=${e.sessionId}`,e.workspaceId?`workspace=${e.workspaceId}`:null,e.accountId?`account=${e.accountId}`:null,e.expiresAt?`expiresAt=${e.expiresAt}`:null,e.expired?"status=expired":null].filter(e=>!!e).join("\n"):"Not authenticated."}),!0}if("login"===r){let e=await ej({stateDir:o,flags:n,commandLabel:"agent-device auth login"});return e3(n,{authenticated:!0,source:"cli-session",sessionId:e.session.id,cloudBaseUrl:e.session.cloudBaseUrl,workspaceId:e.session.workspaceId,accountId:e.session.accountId,expiresAt:e.session.expiresAt,agentTokenExpiresAt:e.expiresAt},()=>"Authenticated with cloud CLI session."),!0}if("logout"===r){let e,r=(e=eV({stateDir:o}.stateDir),!!t.existsSync(e)&&(t.rmSync(e,{force:!0}),!0));return e3(n,{authenticated:!1,removed:r},()=>r?"Removed stored cloud CLI session.":"No stored cloud CLI session."),!0}throw new f("INVALID_ARGS","auth accepts only: status, login, logout")},tr=new Set(["id","text","label"]),to=new Set(["enabled","selected"]),ts={open:function(e){var t,n,r;let o,s,a,[i,l]=e.positionals;if(!i)return{kind:"unsupported",message:"open requires an app id or URL"};if(tp(i))return{kind:"commands",commands:[{openLink:i}]};let c=(t=e,n=i,(a=(r=t,o=r.flags?.launchArgs,s={},r.flags?.relaunch===!0&&(s.stopApp=!0),r.flags?.clearAppState===!0&&(s.clearState=!0),Array.isArray(o)&&o.length>0&&(s.launchArguments=o),Object.keys(s).length>0?s:void 0))?{launchApp:{appId:n,...a}}:"launchApp");return l&&tp(l)?{kind:"config",appId:i,commands:[c,{openLink:l}]}:l?{kind:"unsupported",message:"open with a non-URL second argument is unsupported"}:{kind:"config",appId:i,commands:[c]}},click:ta,press:ta,longpress:function(e){let[t,n]=e.positionals;if(!t)return{kind:"unsupported",message:"longpress requires a target"};let r=tc(t,n);return r?{kind:"commands",commands:[{longPressOn:r}],warnings:(function(e){let[t,n,r]=e.positionals,o=tg(t)&&tg(n)?r:n;return o&&tg(o)?[Number(o)]:[]})(e).map(ti)}:{kind:"unsupported",message:"longpress target is not Maestro-compatible"}},fill:function(e){let[t,n]=e.positionals;if(!t||void 0===n)return{kind:"unsupported",message:"fill requires a target and text"};let r=tc(t);return r?{kind:"commands",commands:[{tapOn:r},{inputText:n}],warnings:["fill exports as tapOn + inputText; Maestro may append text instead of replacing existing field contents"]}:{kind:"unsupported",message:"fill target is not Maestro-compatible"}},type:function(e){var t;let[n]=e.positionals;if(void 0===n)return{kind:"unsupported",message:"type requires text"};let r=0!==(t=n).length&&[...t].every(e=>"\b"===e)?t.length:null;return null!==r?{kind:"commands",commands:[{eraseText:r}]}:{kind:"commands",commands:[{inputText:n}]}},keyboard:function(e){let[t]=e.positionals;return"dismiss"===t?{kind:"commands",commands:["hideKeyboard"]}:"enter"===t||"return"===t?{kind:"commands",commands:[{pressKey:"Enter"}]}:{kind:"unsupported",message:`keyboard ${t??""}`.trim()}},back:()=>({kind:"commands",commands:["back"]}),wait:function(e){let[t,n]=e.positionals;if(!t)return{kind:"unsupported",message:"wait requires a target or duration"};if(tg(t))return{kind:"commands",commands:[{waitForAnimationToEnd:{timeout:Number(t)}}],warnings:["wait <ms> exports as waitForAnimationToEnd and may return before the full duration"]};if("text"===t&&n)return{kind:"commands",commands:[{extendedWaitUntil:{visible:n,timeout:tf(e,17e3)}}]};let r=td(t);return r?{kind:"commands",commands:[{extendedWaitUntil:{visible:r,timeout:tf(e,17e3)}}]}:{kind:"unsupported",message:"wait selector is not Maestro-compatible"}},find:function(e){let[t,n,r]=e.positionals;return"text"===t&&n&&r?"exists"===r?{kind:"commands",commands:[{assertVisible:n}]}:"missing"===r||"not-exists"===r?{kind:"commands",commands:[{assertNotVisible:n}]}:{kind:"unsupported",message:`find text assertion "${r}" is unsupported`}:{kind:"unsupported",message:"only find text <query> exists|missing exports to Maestro"}},screenshot:function(e){let[t]=e.positionals;return t?{kind:"commands",commands:[{takeScreenshot:t}]}:{kind:"unsupported",message:"screenshot requires an output path"}},scroll:function(e){let[t]=e.positionals;return t&&"down"!==t?{kind:"unsupported",message:`scroll ${t} is not exported yet`}:{kind:"commands",commands:["scroll"]}},swipe:function(e){var t,n;let r,o=function(e){let[t,n,r,o,s]=e.positionals;if(tg(t)&&tg(n)&&tg(r)&&tg(o))return{start:R(t,n),end:R(r,o),...s&&tg(s)?{duration:Number(s)}:{}}}(e);if(!o)return{kind:"unsupported",message:"only coordinate swipe exports to Maestro"};let s=(t=e,Number.isInteger(r=t.flags?.count??1)&&r>=1?r:null);if(null===s)return{kind:"unsupported",message:"swipe count must be a positive integer"};let a=(n=e,n.flags?.pauseMs!==void 0?"swipe --pause-ms has no Maestro equivalent":n.flags?.pattern&&"one-way"!==n.flags.pattern?"swipe ping-pong pattern has no Maestro equivalent":void 0);return a?{kind:"unsupported",message:a}:{kind:"commands",commands:Array.from({length:s},()=>({swipe:o}))}}};function ta(e){var t,n,r,o,s;let a,i,[l,c]=e.positionals;if(!l)return{kind:"unsupported",message:`${e.command} requires a target`};let d=tc(l,c);if(!d)return{kind:"unsupported",message:"tap target is not Maestro-compatible"};let u=(a=(n=t=e,n.flags?.jitterPx!==void 0?"tap --jitter-px has no Maestro equivalent":n.flags?.clickButton&&"primary"!==n.flags.clickButton?`tap --button ${n.flags.clickButton} has no Maestro equivalent`:void 0))?{ok:!1,message:a}:{ok:!0,options:(r=t,i={},"number"==typeof r.flags?.count&&r.flags.count>1&&(i.repeat=r.flags.count),"number"==typeof r.flags?.intervalMs&&r.flags.intervalMs>0&&(i.delay=r.flags.intervalMs),i)};return u.ok?e.flags?.doubleTap===!0?{kind:"commands",commands:[{doubleTapOn:d}],warnings:tl(e,"doubleTapOn")}:"number"==typeof e.flags?.holdMs?{kind:"commands",commands:[{longPressOn:d}],warnings:[ti(e.flags.holdMs),...tl(e,"longPressOn")]}:{kind:"commands",commands:[(o=d,0===Object.keys(s=u.options).length?{tapOn:o}:"string"==typeof o?{tapOn:{text:o,...s}}:o&&"object"==typeof o&&!Array.isArray(o)?{tapOn:{...o,...s}}:{tapOn:o})]}:{kind:"unsupported",message:u.message}}function ti(e){return`long-press duration exports as Maestro longPressOn; Maestro uses its default long-press duration instead of ${e}ms`}function tl(e,t){let n=[];return"number"==typeof e.flags?.count&&e.flags.count>1&&n.push(`tap --count ${e.flags.count} is not represented by Maestro ${t}`),"number"==typeof e.flags?.intervalMs&&e.flags.intervalMs>0&&n.push(`tap --interval-ms ${e.flags.intervalMs} is not represented by Maestro ${t}`),n}function tc(e,t){return tg(e)&&tg(t)?{point:R(e,t)}:e.startsWith("@")?null:td(e)}function td(e){let t;try{t=ei(e)}catch{return e.includes("=")||e.includes("||")?null:e}let n=function(e){if(e.length<=1)return null;let t=e.flatMap(e=>1===e.terms.length&&tr.has(e.terms[0].key)?[e.terms[0].value]:[]);if(t.length!==e.length||0===t.length)return null;let n=t[0];return"string"!=typeof n?null:t.every(e=>e===n)?n:null}(t.selectors);return null!==n?n:1!==t.selectors.length?null:function(e){let t={};for(let o of e.terms){var n,r;if(n=t,r=o,tr.has(r.key)?"string"!=typeof r.value||!!n.id||!!n.text||!!n.label||(n[r.key]=r.value,!!0):!to.has(r.key)||"boolean"!=typeof r.value||(n[r.key]=r.value,!!0))return null}return Object.keys(t).length>0?t:null}(t.selectors[0])}function tu(e,t,n,r){for(let o of t??[])e.warnings.push({line:r,action:tm(n),message:o})}function tf(e,t){let n=e.positionals.at(-1);return n&&tg(n)?Number(n):t}function tm(e){return[e.command,...e.positionals??[]].join(" ").trim()}function tp(e){return/^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(e)}function tg(e){return void 0!==e&&Number.isFinite(Number(e))}let th=async e=>{let{positionals:t}=e;return"export"!==t[0]?function({positionals:e,flags:t}){if(e.length>1)throw new f("INVALID_ARGS","replay accepts exactly one input path: replay <path>");if(void 0!==t.replayExportFormat||void 0!==t.out)throw new f("INVALID_ARGS","replay --format/--out are only supported with replay export.");return!1}(e):await tw(e)};async function tw({positionals:e,flags:n}){let o;var s,a=e,i=n;if(a.length>2)throw new f("INVALID_ARGS","replay export accepts exactly one input path: replay export <file.ad>");if(i.replayUpdate)throw new f("INVALID_ARGS","replay export does not support --update.");if(i.replayMaestro)throw new f("INVALID_ARGS","replay export reads .ad files; omit --maestro.");if(i.replayEnv?.length)throw new f("INVALID_ARGS","replay export does not evaluate --env substitutions.");let l=i.replayExportFormat??"maestro";if("maestro"!==l)throw new f("INVALID_ARGS",`Unsupported replay export format: ${l}`);let c=e[1];if(!c)throw new f("INVALID_ARGS","replay export requires an input path.");let d=P(c),u=function(e,t={}){var n,r,o,s;let a={config:(n=t.metadata,n?.env&&Object.keys(n.env).length>0?{env:n.env}:{}),warnings:[],unsupported:[]},i=[];for(let[n,o]of e.entries()){let e=t.actionLines?.[n]??n+1,s=(r=o,ts[r.command]?.(r)??{kind:"unsupported",message:`${r.command} has no Maestro equivalent`});switch(s.kind){case"commands":i.push(...s.commands),tu(a,s.warnings,o,e);break;case"config":(function(e,t,n,r){if(!e.config.appId){e.config.appId=t;return}e.config.appId!==t&&e.unsupported.push({line:r,action:tm(n),message:`multiple app ids cannot be represented in one Maestro config (${e.config.appId} vs ${t})`})})(a,s.appId,o,e),i.push(...s.commands),tu(a,s.warnings,o,e);break;case"unsupported":a.unsupported.push({line:e,action:tm(o),message:s.message})}}if(a.unsupported.length>0)throw new f("INVALID_ARGS",`Cannot export replay to Maestro YAML: unsupported .ad action ${a.unsupported.map(e=>`line ${e.line} (${e.action}): ${e.message}`).join("; ")}.`,{unsupported:a.unsupported});return{yaml:(o=a.config,s=i,b(Object.keys(o).length>0?[o,s]:[s])),warnings:a.warnings}}((o=U(s=t.readFileSync(d,"utf8"))).actions,{actionLines:o.actionLines,metadata:E(s)}),m="string"==typeof n.out?P(n.out):void 0;for(let e of(m&&(t.mkdirSync(r.dirname(m),{recursive:!0}),t.writeFileSync(m,u.yaml)),u.warnings))process.stderr.write(`Warning: line ${e.line}: ${e.message}
|
|
13
|
+
`);return e3(n,{format:n.replayExportFormat??"maestro",sourcePath:d,...m?{path:m}:{yaml:u.yaml},warnings:u.warnings},()=>m??u.yaml),!0}let tv={...$,...B,...L,...M,...G,...O,...x,...K,metro:function(e,t){let n=(e[0]??"").toLowerCase();if("prepare"!==n&&"reload"!==n)throw new f("INVALID_ARGS","metro requires a subcommand: prepare or reload");if("reload"===n)return{action:n,metroHost:t.metroHost,metroPort:t.metroPort,bundleUrl:t.bundleUrl,timeoutMs:t.metroProbeTimeoutMs};if(!t.metroPublicBaseUrl&&!t.metroProxyBaseUrl)throw new f("INVALID_ARGS","metro prepare requires --public-base-url <url> or --proxy-base-url <url>.");return{action:n,projectRoot:t.metroProjectRoot,kind:t.metroKind,port:t.metroPreparePort,listenHost:t.metroListenHost,statusHost:t.metroStatusHost,publicBaseUrl:t.metroPublicBaseUrl,proxyBaseUrl:t.metroProxyBaseUrl,bearerToken:t.metroBearerToken,bridgeScope:t.tenant&&t.runId&&t.leaseId?{tenantId:t.tenant,runId:t.runId,leaseId:t.leaseId}:void 0,startupTimeoutMs:t.metroStartupTimeoutMs,probeTimeoutMs:t.metroProbeTimeoutMs,reuseExisting:!t.metroNoReuseExisting&&void 0,installDependenciesIfNeeded:!t.metroNoInstallDeps&&void 0,runtimeFilePath:t.metroRuntimeFile}},batch:(e,t)=>({...j(t),steps:t.batchSteps??[],onError:t.batchOnError,maxSteps:t.batchMaxSteps,out:t.out})};async function tI(e){return(await ty(e)).result}async function ty(e){var t,n,r;let o=(t=e.command,n=e.positionals,r=e.flags,tv[t](n,r)),s=await H(e.client,e.command,o);return{result:s,cliOutput:N({name:e.command,input:o,result:s})}}let tA={connect:e8,disconnect:e2,connection:e9,auth:tn,replay:th,screenshot:async({positionals:e,flags:t,client:n})=>{let r=await tI({client:n,command:"screenshot",positionals:e,flags:t});return e3(t,{path:r.path,...r.overlayRefs?{overlayRefs:r.overlayRefs}:{}},()=>r.overlayRefs?`Annotated ${r.overlayRefs.length} refs onto ${r.path}`:r.path),!0},diff:async({positionals:e,flags:t,client:n})=>{var r;if("snapshot"===e[0]){let r=await tI({client:n,command:"diff",positionals:e,flags:t});return e3(t,r,()=>_(r)),!0}if("screenshot"!==e[0])return!1;let o=t.baseline;if(!o||"string"!=typeof o)throw new f("INVALID_ARGS","diff screenshot requires --baseline <path>");let s=P(o),a="string"==typeof t.out?P(t.out):void 0,i=e[1];if(e.length>2)throw new f("INVALID_ARGS","diff screenshot accepts at most one current screenshot path");let l=J({backend:(r=n,{platform:function(e){switch(e.platform){case"android":case"linux":case"macos":return e.platform;default:return"ios"}}(t),captureScreenshot:async(e,t,n)=>{let o=await r.capture.screenshot({path:t,session:e.session,overlayRefs:n?.overlayRefs,fullscreen:n?.fullscreen,stabilize:n?.stabilize,surface:n?.surface});return{path:o.path,...o.overlayRefs?{overlayRefs:o.overlayRefs}:{}}}}),artifacts:F(),sessions:{get:e=>({name:e}),set:()=>{}},policy:q()}),c=await l.capture.diffScreenshot({session:t.session,baseline:{kind:"path",path:s},current:i?{kind:"path",path:P(i)}:{kind:"live"},...a?{out:{kind:"path",path:a}}:{},threshold:function(e){if(null!=e&&""!==e)return Number(e)}(t.threshold),overlayRefs:t.overlayRefs,surface:t.surface});return e3(t,c,()=>D(c)),!0}};async function t_(e){let t={...e.flags},n=tA[e.command];return n?await n({...e,flags:t}):!!z(e.command)&&await tS({...e,command:e.command,flags:t})}async function tS(e){let{runGenericClientBackedCommand:t}=await import("./generic.js");return await t(e)}function tD(e,t,n){return n||(e.push(t),"")}async function tC(e,t,n){let{flags:r}=t,o=function(e){var t;if(!e?.metroProxyBaseUrl||"android-instance"!==(t=e.leaseBackend)&&"ios-instance"!==t)return null;let n=[],r={serverBaseUrl:tD(n,"metroProxyBaseUrl",e.metroProxyBaseUrl),bearerToken:tD(n,"metroBearerToken",e.metroBearerToken),tenantId:tD(n,"tenant",e.tenant),runId:tD(n,"runId",e.runId),leaseId:tD(n,"leaseId",e.leaseId)};if(n.length>0)throw new f("INVALID_ARGS",`react-devtools remote bridge requires ${n.join(", ")}.`,{missing:n});return r}(r);if(!o)return n();let s=t.stateDir??process.cwd(),a=t.session??r?.session??"default",i=r?.remoteConfig??`${o.tenantId}:${o.runId}:${o.leaseId}`;if("stop"===e[0])try{return await n()}finally{await ed({projectRoot:t.cwd??process.cwd(),stateDir:s,profileKey:i,consumerKey:a})}return await ec({projectRoot:t.cwd??process.cwd(),stateDir:s,serverBaseUrl:o.serverBaseUrl,bearerToken:o.bearerToken,bridgeScope:{tenantId:o.tenantId,runId:o.runId,leaseId:o.leaseId},session:a,profileKey:i,consumerKey:a,env:t.env??process.env}),await n()}async function tk(e,t={}){let n=t.cwd??process.cwd(),r=t.env??process.env,o=await tC(e,t,async()=>(await y("npm",["exec","--yes","--package","agent-react-devtools@0.4.0","--","agent-react-devtools",...e],{cwd:n,env:r,allowFailure:!0,onStdoutChunk:e=>{process.stdout.write(e)},onStderrChunk:e=>{process.stderr.write(e)}})).exitCode);var s,a=t.flags;return 0!==o&&"wait"===(s=e)[0]&&s.includes("--connected")&&"ios-instance"===a?.leaseBackend&&process.stderr.write("Hint: Remote iOS React DevTools connects during JavaScript startup.\nIf the app was already open before `agent-device react-devtools start`, relaunch it with `agent-device open <bundle-id> --platform ios --relaunch`, then retry `agent-device react-devtools wait --connected`.\n"),o}function tN(e,t={}){let n=tb(t),r={...e};return n.defaultPlatform&&void 0===r.platform&&(r.platform=n.defaultPlatform),r}function tb(e){var t,n,r,o;let s,a=e.env??process.env,i=e.inheritedPlatform??e.configuredPlatform??function(e){if(void 0===e)return;let t=e.trim().toLowerCase();if(t){if("ios"===t||"android"===t||"apple"===t)return t;throw new f("INVALID_ARGS",`Invalid AGENT_DEVICE_PLATFORM: ${e}. Use ios, android, or apple.`)}}(a.AGENT_DEVICE_PLATFORM),l="string"==typeof(t=e.configuredSession??a.AGENT_DEVICE_SESSION)&&t.trim().length>0;return{defaultPlatform:i,lockPolicy:(n=e.policyOverrides,r=a,o=l,(s=n?.sessionLock??n?.sessionLockConflicts??function(e){if(void 0===e)return;let t=e.trim().toLowerCase();if(t){if("reject"===t||"strip"===t)return t;throw new f("INVALID_ARGS",`Invalid session lock mode: ${e}. Use reject or strip.`)}}(r.AGENT_DEVICE_SESSION_LOCK))||(n?.sessionLocked===!0||o?"reject":void 0))}}let tU={sendToDaemon:es},tR=new Set(["launchUrl","metroBearerToken","metroKind","metroListenHost","metroNoInstallDeps","metroNoReuseExisting","metroPreparePort","metroProbeTimeoutMs","metroProjectRoot","metroProxyBaseUrl","metroPublicBaseUrl","metroRuntimeFile","metroStartupTimeoutMs","metroStatusHost"]),tE=new Set(["connect","connection","close","disconnect","metro","session"]);async function tP(e,n=tU){let o=m(),s=er(),a=function(e){try{let t=ee(e);return tT(t.command??"",t.providedFlags)}catch{return e.includes("--debug")||e.includes("-v")||e.includes("--verbose")}}(e),i=e.includes("--json"),I=function(e){for(let t=0;t<e.length;t+=1){let n=e[t];if(n.startsWith("--session=")){let e=n.slice(10).trim();return e.length>0?e:null}if("--session"===n){let n=e[t+1]?.trim();if(n&&!n.startsWith("-"))return n;break}}return null}(e)??process.env.AGENT_DEVICE_SESSION??"default";await p({session:I,requestId:o,command:e[0],debug:a},async()=>{var m,p,I,y,A,_,D,N,b,U,R,E,B,L,x,M,O;let $,j,G,K,H,F,q;try{let n,o,s,a,i,c,d,u;m={cwd:process.cwd(),env:process.env},n=ee(e),o=m?.env??process.env,s=m?.cwd??process.cwd(),y=n.command,a=null!==y&&(p={remoteConfig:n.flags.remoteConfig,cwd:s,env:o}).remoteConfig?{...eS(l({configPath:p.remoteConfig,cwd:p.cwd,env:p.env}).profile),remoteConfig:p.remoteConfig}:{},d=W((i=(I={command:n.command,cwd:s,cliFlags:n.flags,env:o}).env??process.env,c=W({},function(e){let n={};for(let r of e)W(n,function(e,n){let r,o;if(!t.existsSync(e)){if(n)throw new f("INVALID_ARGS",`Config file not found: ${e}`);return{}}try{r=t.readFileSync(e,"utf8")}catch(t){throw new f("INVALID_ARGS",`Failed to read config file: ${e}`,{cause:t instanceof Error?t.message:String(t)})}try{o=JSON.parse(r)}catch(t){throw new f("INVALID_ARGS",`Invalid JSON in config file: ${e}`,{cause:t instanceof Error?t.message:String(t)})}if(!o||"object"!=typeof o||Array.isArray(o))throw new f("INVALID_ARGS",`Config file must contain a JSON object: ${e}`);return function(e,t){let n={};for(let[r,o]of Object.entries(e)){if("installSource"===r){n.installSource=V(o,t);continue}let e=X(r);if(!e)throw new f("INVALID_ARGS",`Unknown config key "${r}" in ${t}.`);if(!e.config.enabled)throw new f("INVALID_ARGS",`Unsupported config key "${r}" in ${t}.`);n[r]=Z(e,o,t,r)}return n}(o,`config file ${e}`)}(r.path,r.required));return n}((A=I.cwd,_=I.cliFlags.config,D=i,(u=_??D.AGENT_DEVICE_CONFIG)?[{path:(N=u,b=A,U=D,P(N,{cwd:b,env:U})),required:!0}]:[{path:(R=D,r.join(T("~",{env:R}),".agent-device","config.json")),required:!1},{path:r.resolve(A,"agent-device.json"),required:!1}]))),W(c,function(e,t){let n={};for(let r of Y(t)){if("installSource"===r.key)continue;let t=r.env.names.map(t=>({name:t,value:e[t]})).find(e=>"string"==typeof e.value&&e.value.trim().length>0);t&&(n[r.key]=Z(r,t.value,`environment variable ${t.name}`,t.name))}return n}(i,I.command))),a),$={...en(n,{strictFlags:m?.strictFlags,defaultFlags:d}),providedFlags:n.providedFlags}}catch(t){w({level:"error",phase:"cli_parse_failed",data:{error:t instanceof Error?t.message:String(t)}});let e=u(t,{diagnosticId:g().diagnosticId,logPath:h({force:!0})??void 0});i?k({success:!1,error:e}):C(e,{showDetails:a}),process.exit(1);return}for(let e of $.warnings)process.stderr.write(`Warning: ${e}
|
|
14
|
+
`);$.flags.version&&(process.stdout.write(`${s}
|
|
15
|
+
`),process.exit(0));let J="help"===$.command,z=$.flags.help;if(J||z){J&&$.positionals.length>1&&(C(new f("INVALID_ARGS","help accepts at most one command.")),process.exit(1));let e=J?$.positionals[0]:$.command;e||(process.stdout.write(`${Q()}
|
|
16
|
+
`),process.exit(0));let t=et(e);t&&(process.stdout.write(t),process.exit(0)),C(new f("INVALID_ARGS",`Unknown command: ${e}`)),process.stdout.write(`${Q()}
|
|
17
|
+
`),process.exit(1)}$.command||(process.stdout.write(`${Q()}
|
|
18
|
+
`),process.exit(1));let{command:er,positionals:es}=$,ei=tT(er,$.providedFlags),el=new Set($.providedFlags.map(e=>e.key));try{G=(j=tb({policyOverrides:$.flags,configuredPlatform:$.flags.platform,configuredSession:$.flags.session})).lockPolicy?{...$.flags}:tN($.flags,{policyOverrides:$.flags,configuredPlatform:$.flags.platform,configuredSession:$.flags.session}),K=v(G.stateDir),H=G.session??"default",E={command:er,explicitFlagKeys:el,stateDir:K.baseDir,session:H,remoteConfig:G.remoteConfig,hasResolvedSession:void 0!==G.session},q=(F="connect"===E.command||"connection"===E.command?null:function(e){let t=e.validateRemoteConfigHash??!0,n=e.remoteConfig?c({configPath:e.remoteConfig,cwd:e.cwd,env:e.env}):void 0,r=eu(e)??(e.allowActiveFallback?ev({stateDir:e.stateDir}):null);if(!r||n&&r.remoteConfigPath!==n)return null;if(t&&eg(r.remoteConfigPath)!==r.remoteConfigHash)throw new f("INVALID_ARGS","Active remote connection config changed. Run agent-device connect --force to refresh it.",{remoteConfig:r.remoteConfigPath});let o=function(e,t){try{return l({configPath:e.remoteConfigPath,cwd:t.cwd,env:t.env}).profile}catch(e){if(!1===t.validateRemoteConfigHash)return{};throw e}}(r,e);return{runtime:r.runtime,flags:{...o,remoteConfig:r.remoteConfigPath,daemonBaseUrl:r.daemon?.baseUrl??o.daemonBaseUrl,daemonTransport:r.daemon?.transport??o.daemonTransport,daemonServerMode:r.daemon?.serverMode??o.daemonServerMode,tenant:r.tenant,sessionIsolation:"tenant",runId:r.runId,leaseId:r.leaseId,leaseBackend:r.leaseBackend,session:r.session,platform:r.platform??o.platform,target:r.target??o.target}}}({stateDir:E.stateDir,session:E.session,remoteConfig:E.remoteConfig,cwd:process.cwd(),env:process.env,allowActiveFallback:!E.explicitFlagKeys.has("session")&&(!E.remoteConfig||"disconnect"===E.command||!E.hasResolvedSession),validateRemoteConfigHash:"disconnect"!==E.command}))?function(e,t,n){let r={...e};for(let[e,o]of Object.entries(t))void 0!==o&&(n.has(e)||(r[e]=o));return r}(G,F.flags,el):G}catch(t){let e=u(d(t),{diagnosticId:g().diagnosticId,logPath:h({force:!0})??void 0});$.flags.json?k({success:!1,error:e}):C(e,{showDetails:ei}),process.exit(1);return}let ec=null;try{let e;if("react-devtools"===er){let e=await tk(es,{flags:q,stateDir:K.baseDir,session:q.session??H,cwd:process.cwd(),env:process.env});process.exit(e);return}ea({command:er,currentVersion:s,stateDir:K.baseDir,flags:q});let r=F?.runtime,a=(e,t)=>({session:e.session,requestId:o,stateDir:e.stateDir,daemonBaseUrl:e.daemonBaseUrl,daemonAuthToken:e.daemonAuthToken,daemonTransport:e.daemonTransport,daemonServerMode:e.daemonServerMode,tenant:e.tenant,sessionIsolation:e.sessionIsolation,runId:e.runId,leaseId:e.leaseId,leaseBackend:e.leaseBackend,runtime:t,lockPolicy:j.lockPolicy,lockPlatform:j.defaultPlatform,cwd:process.cwd(),debug:ei});if("batch"===er){if(es.length>0)throw new f("INVALID_ARGS","batch does not accept positional arguments.");e=function(e){let n,r,o,s="";if(e.steps)s=e.steps;else if(e.stepsFile)try{s=t.readFileSync(e.stepsFile,"utf8")}catch(n){let t=n instanceof Error?n.message:String(n);throw new f("INVALID_ARGS",`Failed to read --steps-file ${e.stepsFile}: ${t}`)}var a,i=s;try{o=JSON.parse(i)}catch{throw new f("INVALID_ARGS","Batch steps must be valid JSON.")}if(!Array.isArray(o)||0===o.length)throw new f("INVALID_ARGS","Batch steps must be a non-empty JSON array.");return a=o,n=!1,r=a.map((e,t)=>{var r,o,s,a,i,l;let c;if(r=e,null!==r&&"object"==typeof r&&!Array.isArray(r)&&"input"in r&&!("positionals"in r)&&!("flags"in r))return e;let d=function(e,t){if(!e||"object"!=typeof e||Array.isArray(e))throw new f("INVALID_ARGS",`Invalid batch step ${t}.`);var n=e,r=t;let o=Object.keys(n).filter(e=>!["command","positionals","flags","runtime"].includes(e));if(o.length>0)throw new f("INVALID_ARGS",`Batch step ${r} has unknown legacy field(s): ${o.join(", ")}.`);let s=function(e,t){let n="string"==typeof e?e.trim().toLowerCase():"";if(!n)throw new f("INVALID_ARGS",`Batch step ${t} requires command.`);if(S(n))return n;throw new f("INVALID_ARGS",`Batch step ${t} command is not available through command batch: ${String(e)}`)}(e.command,t),a=function(e,t){if(void 0!==e){if(!Array.isArray(e)||e.some(e=>"string"!=typeof e))throw new f("INVALID_ARGS",`Batch step ${t} positionals must contain only strings.`);return e}}(e.positionals,t),i=function(e,t){if(void 0!==e){if(!e||"object"!=typeof e||Array.isArray(e))throw new f("INVALID_ARGS",`Batch step ${t} flags must be an object.`);return e}}(e.flags,t);return{command:s,...void 0===a?{}:{positionals:a},...void 0===i?{}:{flags:i},...void 0===e.runtime?{}:{runtime:e.runtime}}}(e,t+1);return n=!0,c=(s=(o=d).command,a=o.positionals??[],l=o.flags,i={json:!1,help:!1,version:!1,...l},tv[s](a,i)),{command:o.command,input:c,...void 0===o.runtime?{}:{runtime:o.runtime}}}),n&&process.stderr.write('Warning: batch steps using positionals/flags are deprecated and will be removed in the next major version. Use {"command":"...","input":{...}} steps instead.\n'),r}(G)}if(function(e){if("session"!==e.command||"state-dir"!==e.positionals[0])return!1;if(e.positionals.length>1)throw new f("INVALID_ARGS","session state-dir does not accept additional arguments.");return e.flags.json?k({success:!0,data:{stateDir:e.daemonPaths.baseDir}}):process.stdout.write(`${e.daemonPaths.baseDir}
|
|
19
|
+
`),!0}({command:er,positionals:es,flags:q,daemonPaths:K}))return;if(B=er,"auth"!==B&&"connection"!==B&&(q=(await eM({command:er,flags:q,stateDir:K.baseDir,env:process.env})).flags),q.remoteConfig&&(L=er,!tE.has(L))){let t=eo(a(q,r),{transport:n.sendToDaemon}),o=await ek({command:er,flags:q,client:t,runtime:r,batchSteps:e,forceRuntimePrepare:function(e){for(let t of tR)if(e.has(t))return!0;return!1}(el)});q=o.flags,r=o.runtime}x={command:er,flags:q,runtime:r,explicitFlagKeys:el,hadConnectionDefaults:!!F},!("open"===x.command&&!x.runtime&&!x.flags.bundleUrl&&!x.flags.metroHost&&!x.flags.metroPort&&!x.flags.remoteConfig&&!x.hadConnectionDefaults&&((M=x.explicitFlagKeys).has("daemonBaseUrl")||M.has("daemonTransport")||M.has("tenant")||M.has("sessionIsolation")||M.has("runId")||M.has("leaseId")||M.has("leaseBackend")))||process.stderr.write("Warning: open is using explicit remote daemon or tenant flags without saved Metro runtime hints. React Native apps may launch without bundle/runtime hints; prefer connect --remote-config <path> first or pass --remote-config <path> on this command.\n");let i=q.daemonBaseUrl;ec=!ei||q.json||i?null:function(e){try{let n=t.existsSync(e)?t.statSync(e).size:0,r=!1,o=setInterval(()=>{if(!r&&t.existsSync(e))try{let r=t.statSync(e);if(r.size<n&&(n=0),r.size<=n)return;let o=t.openSync(e,"r");try{let e=Buffer.alloc(r.size-n);t.readSync(o,e,0,e.length,n),n=r.size,e.length>0&&process.stdout.write(e.toString("utf8"))}finally{t.closeSync(o)}}catch{}},200);return()=>{r=!0,clearInterval(o)}}catch{return null}}(K.logPath);let l=eo(a(q,r),{transport:function(e){let{command:t,flags:n,transport:r}=e;return"test"!==t||n.json?r:async e=>await r({...e,meta:{...e.meta,requestProgress:"replay-test"}})}({command:er,flags:q,transport:n.sendToDaemon})});if("batch"===er){if(!e)throw new f("INVALID_ARGS","batch requires --steps or --steps-file.");let t=e.map((e,t)=>({...e,input:j.lockPolicy&&void 0===G.platform?{...e.input}:tN(e.input,{policyOverrides:q,configuredPlatform:q.platform,configuredSession:q.session,inheritedPlatform:q.platform})}));if(await t_({command:er,positionals:es,flags:{...q,batchSteps:t},client:l}))return}else if("runtime"===er)throw new f("INVALID_ARGS","runtime command was removed. Use connect --remote-config <path> for remote runs, or metro prepare --remote-config <path> for inspection.");else if(await t_({command:er,positionals:es,flags:q,client:l}))return;throw new f("INVALID_ARGS",`Unknown command: ${er}`)}catch(r){let e=d(r),n=u(e,{diagnosticId:g().diagnosticId,logPath:h({force:!0})??void 0});if("close"===er&&"COMMAND_FAILED"===(O=e).code&&(O.details?.kind==="daemon_startup_failed"||O.message.toLowerCase().includes("failed to start daemon")&&("string"==typeof O.details?.infoPath||"string"==typeof O.details?.lockPath))){q.json&&k({success:!0,data:{closed:"session",source:"no-daemon"}});return}if(q.json)k({success:!1,error:n});else if(C(n,{showDetails:ei}),ei)try{let e=K.logPath;if(t.existsSync(e)){let n=t.readFileSync(e,"utf8").split("\n"),r=n.slice(Math.max(0,n.length-200)).join("\n");r.trim().length>0&&process.stderr.write(`
|
|
44
20
|
[daemon log]
|
|
45
|
-
${
|
|
46
|
-
`)}}catch{}
|
|
21
|
+
${r}
|
|
22
|
+
`)}}catch{}ec&&ec(),process.exit(1)}finally{ec&&ec()}})}function tT(e,t){return t.some(t=>"verbose"===t.key&&("--debug"===t.token||"-v"===t.token||"test"!==e))}e(process.argv[1]??"").href===import.meta.url&&tP(process.argv.slice(2)).catch(e=>{C(u(d(e)),{showDetails:!0}),process.exit(1)});export{tP as runCli,ty as runCliCommandWithOutput,e3 as writeCommandOutput};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{commonToClientOptions as e,optionalEnum as t,toClientElementTarget as r,toSelectorSnapshotOptions as a,toRepeatedOptions as n,toClientInteractionTarget as i}from"./9974.js";import{createBatchCommandMetadata as s,WAIT_KIND_VALUES as o,defineExecutableCommand as c,clientCommandMetadata as p,interactionCommandMetadata as d}from"./8173.js";import{batchCommandNames as l}from"./8699.js";let u=[c(m("devices"),(e,t)=>e.devices.list(t)),c(m("boot"),(e,t)=>e.devices.boot(t)),c(m("shutdown"),(e,t)=>e.devices.shutdown(t)),c(m("apps"),(e,t)=>e.apps.list(t)),c(m("session"),async(e,{action:t,...r})=>({sessions:await e.sessions.list(r)})),c(m("open"),(e,t)=>e.apps.open(t)),c(m("close"),(e,t)=>t.app?e.apps.close(t):e.sessions.close(function(e){let{app:t,...r}=e;return r}(t))),c(m("install"),(e,t)=>e.apps.install(t)),c(m("reinstall"),(e,t)=>e.apps.reinstall(t)),c(m("install-from-source"),(e,t)=>e.apps.installFromSource(t)),c(m("push"),(e,t)=>e.apps.push(t)),c(m("trigger-app-event"),(e,t)=>e.apps.triggerEvent(t)),c(m("snapshot"),(e,t)=>e.capture.snapshot(t)),c(m("screenshot"),(e,t)=>e.capture.screenshot(t)),c(m("diff"),(e,t)=>e.capture.diff(t)),c(m("wait"),(e,r)=>{var a;let n;return e.command.wait((t(a=r,"kind",o),n={...a},delete n.kind,n))}),c(m("alert"),(e,t)=>e.command.alert(t)),c(m("appstate"),(e,t)=>e.command.appState(t)),c(m("back"),(e,t)=>e.command.back(t)),c(m("home"),(e,t)=>e.command.home(t)),c(m("rotate"),(e,t)=>e.command.rotate(t)),c(m("app-switcher"),(e,t)=>e.command.appSwitcher(t)),c(m("keyboard"),(e,t)=>e.command.keyboard(t)),c(m("clipboard"),(e,t)=>e.command.clipboard(t)),c(m("react-native"),(e,t)=>e.command.reactNative(t)),c(m("prepare"),(e,t)=>e.command.prepare(t)),c(m("replay"),(e,t)=>e.replay.run(t)),c(m("test"),(e,t)=>e.replay.test(t)),c(m("perf"),(e,t)=>e.observability.perf(t)),c(m("logs"),(e,t)=>e.observability.logs(t)),c(m("network"),(e,t)=>e.observability.network(t)),c(m("record"),(e,t)=>e.recording.record(t)),c(m("trace"),(e,t)=>e.recording.trace(t)),c(m("settings"),(e,t)=>e.settings.update(t)),c(m("metro"),async(e,t)=>{var r,a,n;return"prepare"===t.action?await e.metro.prepare({projectRoot:(r=t).projectRoot,kind:r.kind,publicBaseUrl:r.publicBaseUrl,proxyBaseUrl:r.proxyBaseUrl,bearerToken:r.bearerToken,bridgeScope:r.bridgeScope??((a=r).tenant&&a.runId&&a.leaseId?{tenantId:a.tenant,runId:a.runId,leaseId:a.leaseId}:void 0),port:r.port,listenHost:r.listenHost,statusHost:r.statusHost,startupTimeoutMs:r.startupTimeoutMs,probeTimeoutMs:r.probeTimeoutMs,reuseExisting:r.reuseExisting,installDependenciesIfNeeded:r.installDependenciesIfNeeded,runtimeFilePath:r.runtimeFilePath}):await e.metro.reload({metroHost:(n=t).metroHost,metroPort:n.metroPort,bundleUrl:n.bundleUrl,timeoutMs:n.timeoutMs})})];function m(e){let t=p.find(t=>t.name===e);if(!t)throw Error(`Missing client command metadata for ${e}`);return t}function g(e){let t=d.find(t=>t.name===e);if(!t)throw Error(`Missing interaction command metadata for ${e}`);return t}let f=new Map([c(g("click"),(t,r)=>{var s;return t.interactions.click({...e(s=r),...i(s.target),...a(s),...n(s),button:s.button})}),c(g("press"),(t,r)=>{var s;return t.interactions.press({...e(s=r),...i(s.target),...a(s),...n(s)})}),c(g("fill"),(t,r)=>{var n;return t.interactions.fill({...e(n=r),...i(n.target),...a(n),text:n.text,delayMs:n.delayMs})}),c(g("longpress"),(t,r)=>{var n;return t.interactions.longPress({...e(n=r),...i(n.target),...a(n),durationMs:n.durationMs})}),c(g("swipe"),(e,t)=>e.interactions.swipe(t)),c(g("focus"),(e,t)=>e.interactions.focus(t)),c(g("type"),(e,t)=>e.interactions.type(t)),c(g("scroll"),(e,t)=>e.interactions.scroll(t)),c(g("get"),(t,n)=>{var i;return t.interactions.get({...e(i=n),...r(i.target),...a(i),format:i.format})}),c(g("is"),(e,t)=>e.interactions.is(t)),c(g("find"),(e,t)=>e.interactions.find(t)),c(g("gesture"),async(t,r)=>{var a,n,i,s,o,c;switch(r.kind){case"pan":return await t.interactions.pan({...e(a=r),x:a.origin.x,y:a.origin.y,dx:a.delta.x,dy:a.delta.y,durationMs:a.durationMs});case"fling":return await t.interactions.fling({...e(n=r),direction:n.direction,x:n.origin.x,y:n.origin.y,distance:n.distance,durationMs:n.durationMs});case"swipe":return await t.interactions.swipeGesture({...e(i=r),preset:i.preset,durationMs:i.durationMs});case"pinch":return await t.interactions.pinch({...e(s=r),scale:s.scale,x:s.origin?.x,y:s.origin?.y});case"rotate":return await t.interactions.rotateGesture({...e(o=r),degrees:o.degrees,x:o.origin?.x,y:o.origin?.y,velocity:o.velocity});case"transform":return await t.interactions.transformGesture({...e(c=r),x:c.origin.x,y:c.origin.y,dx:c.delta.x,dy:c.delta.y,scale:c.scale,degrees:c.degrees,durationMs:c.durationMs})}}),...u,c(s(l),(t,r)=>{var a;return t.batch.run({...e(a=r),steps:a.steps,onError:a.onError,maxSteps:a.maxSteps,out:a.out})})].map(e=>[e.name,e]));async function y(e,t,r){var a;return await (a=t,f.get(a)).invoke(e,r)}export{y as runCommand};
|
package/dist/src/contracts.d.ts
CHANGED
|
@@ -2,6 +2,12 @@ export declare type AppErrorCode = KnownAppErrorCode | (string & {});
|
|
|
2
2
|
|
|
3
3
|
export declare function centerOfRect(rect: Rect): Point;
|
|
4
4
|
|
|
5
|
+
export declare const DAEMON_LOCK_POLICIES: readonly ["reject", "strip"];
|
|
6
|
+
|
|
7
|
+
export declare const DAEMON_SERVER_MODES: readonly ["socket", "http", "dual"];
|
|
8
|
+
|
|
9
|
+
export declare const DAEMON_TRANSPORT_PREFERENCES: readonly ["auto", "socket", "http"];
|
|
10
|
+
|
|
5
11
|
export declare type DaemonArtifact = {
|
|
6
12
|
field: string;
|
|
7
13
|
artifactId?: string;
|
|
@@ -41,7 +47,7 @@ export declare type DaemonInstallSource = {
|
|
|
41
47
|
artifactName: string;
|
|
42
48
|
}));
|
|
43
49
|
|
|
44
|
-
export declare type DaemonLockPolicy =
|
|
50
|
+
export declare type DaemonLockPolicy = (typeof DAEMON_LOCK_POLICIES)[number];
|
|
45
51
|
|
|
46
52
|
export declare type DaemonRequest = {
|
|
47
53
|
token?: string;
|
|
@@ -63,7 +69,7 @@ export declare type DaemonRequestMeta = {
|
|
|
63
69
|
leaseId?: string;
|
|
64
70
|
leaseTtlMs?: number;
|
|
65
71
|
leaseBackend?: LeaseBackend;
|
|
66
|
-
sessionIsolation?:
|
|
72
|
+
sessionIsolation?: SessionIsolationMode;
|
|
67
73
|
uploadedArtifactId?: string;
|
|
68
74
|
clientArtifactPaths?: Record<string, string>;
|
|
69
75
|
installSource?: DaemonInstallSource;
|
|
@@ -71,7 +77,7 @@ export declare type DaemonRequestMeta = {
|
|
|
71
77
|
materializedPathRetentionMs?: number;
|
|
72
78
|
materializationId?: string;
|
|
73
79
|
lockPolicy?: DaemonLockPolicy;
|
|
74
|
-
lockPlatform?:
|
|
80
|
+
lockPlatform?: PlatformSelector;
|
|
75
81
|
requestProgress?: 'replay-test';
|
|
76
82
|
};
|
|
77
83
|
|
|
@@ -89,6 +95,10 @@ export declare type DaemonResponseData = Record<string, unknown> & {
|
|
|
89
95
|
|
|
90
96
|
export declare const daemonRuntimeSchema: RuntimeSchema<SessionRuntimeHints>;
|
|
91
97
|
|
|
98
|
+
export declare type DaemonServerMode = (typeof DAEMON_SERVER_MODES)[number];
|
|
99
|
+
|
|
100
|
+
export declare type DaemonTransportPreference = (typeof DAEMON_TRANSPORT_PREFERENCES)[number];
|
|
101
|
+
|
|
92
102
|
export declare function defaultHintForCode(code: string): string | undefined;
|
|
93
103
|
|
|
94
104
|
export declare type JsonRpcId = string | number | null;
|
|
@@ -104,6 +114,8 @@ export declare const jsonRpcRequestSchema: RuntimeSchema<JsonRpcRequestEnvelope<
|
|
|
104
114
|
|
|
105
115
|
declare type KnownAppErrorCode = 'INVALID_ARGS' | 'DEVICE_NOT_FOUND' | 'DEVICE_IN_USE' | 'TOOL_MISSING' | 'APP_NOT_INSTALLED' | 'UNSUPPORTED_PLATFORM' | 'UNSUPPORTED_OPERATION' | 'NOT_IMPLEMENTED' | 'COMMAND_FAILED' | 'SESSION_NOT_FOUND' | 'UNAUTHORIZED' | 'AMBIGUOUS_MATCH' | 'UNKNOWN';
|
|
106
116
|
|
|
117
|
+
export declare const LEASE_BACKENDS: readonly ["ios-simulator", "ios-instance", "android-instance"];
|
|
118
|
+
|
|
107
119
|
export declare type LeaseAllocatePayload = {
|
|
108
120
|
token?: string;
|
|
109
121
|
session?: string;
|
|
@@ -116,7 +128,7 @@ export declare type LeaseAllocatePayload = {
|
|
|
116
128
|
|
|
117
129
|
export declare const leaseAllocateSchema: RuntimeSchema<LeaseAllocatePayload>;
|
|
118
130
|
|
|
119
|
-
export declare type LeaseBackend =
|
|
131
|
+
export declare type LeaseBackend = (typeof LEASE_BACKENDS)[number];
|
|
120
132
|
|
|
121
133
|
export declare type LeaseHeartbeatPayload = {
|
|
122
134
|
token?: string;
|
|
@@ -141,6 +153,10 @@ export declare type LeaseReleasePayload = {
|
|
|
141
153
|
|
|
142
154
|
export declare const leaseReleaseSchema: RuntimeSchema<LeaseReleasePayload>;
|
|
143
155
|
|
|
156
|
+
export declare const NETWORK_INCLUDE_MODES: readonly ["summary", "headers", "body", "all"];
|
|
157
|
+
|
|
158
|
+
export declare type NetworkIncludeMode = (typeof NETWORK_INCLUDE_MODES)[number];
|
|
159
|
+
|
|
144
160
|
declare type NormalizedError = {
|
|
145
161
|
code: string;
|
|
146
162
|
message: string;
|
|
@@ -155,6 +171,10 @@ export declare function normalizeError(err: unknown, context?: {
|
|
|
155
171
|
logPath?: string;
|
|
156
172
|
}): NormalizedError;
|
|
157
173
|
|
|
174
|
+
declare const PLATFORM_SELECTORS: readonly ["ios", "macos", "android", "linux", "apple"];
|
|
175
|
+
|
|
176
|
+
declare type PlatformSelector = (typeof PLATFORM_SELECTORS)[number];
|
|
177
|
+
|
|
158
178
|
declare type Point = {
|
|
159
179
|
x: number;
|
|
160
180
|
y: number;
|
|
@@ -198,6 +218,10 @@ declare type RuntimeSchema<T> = {
|
|
|
198
218
|
parse(input: unknown): T;
|
|
199
219
|
};
|
|
200
220
|
|
|
221
|
+
export declare const SESSION_ISOLATION_MODES: readonly ["none", "tenant"];
|
|
222
|
+
|
|
223
|
+
export declare type SessionIsolationMode = (typeof SESSION_ISOLATION_MODES)[number];
|
|
224
|
+
|
|
201
225
|
export declare type SessionRuntimeHints = {
|
|
202
226
|
platform?: 'ios' | 'android';
|
|
203
227
|
metroHost?: string;
|
package/dist/src/contracts.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
export{DAEMON_LOCK_POLICIES,DAEMON_SERVER_MODES,DAEMON_TRANSPORT_PREFERENCES,LEASE_BACKENDS,NETWORK_INCLUDE_MODES,SESSION_ISOLATION_MODES,daemonCommandRequestSchema,daemonRuntimeSchema,jsonRpcRequestSchema,leaseAllocateSchema,leaseHeartbeatSchema,leaseReleaseSchema}from"./9616.js";export{centerOfRect}from"./1644.js";export{defaultHintForCode,normalizeError}from"./9152.js";
|