agent-device 0.20.7 → 0.20.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.7.apk → agent-device-android-ime-helper-0.20.8.apk} +0 -0
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.8.apk.sha256 +1 -0
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.7.manifest.json → agent-device-android-ime-helper-0.20.8.manifest.json} +4 -4
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.7.apk → agent-device-android-snapshot-helper-0.20.8.apk} +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.8.apk.sha256 +1 -0
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.7.manifest.json → agent-device-android-snapshot-helper-0.20.8.manifest.json} +6 -6
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +5 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+RecordingTests.swift +4 -0
- package/dist/src/agent-browser-tool.js +1 -1
- package/dist/src/agent-device-client.js +2 -2
- package/dist/src/android.js +1 -1
- package/dist/src/app-lifecycle.js +7 -7
- package/dist/src/app-lifecycle2.js +1 -1
- package/dist/src/app-log-reconnect.js +1 -1
- package/dist/src/app-log-runtime.js +3 -3
- package/dist/src/app-resolution.js +2 -2
- package/dist/src/apps.js +5 -5
- package/dist/src/auth-session.js +1 -1
- package/dist/src/boot-diagnostics.js +1 -1
- package/dist/src/cli-config.js +1 -1
- package/dist/src/cli-help.js +1 -1
- package/dist/src/cli.js +4 -4
- package/dist/src/client-metro.js +1 -1
- package/dist/src/connection-runtime.js +1 -1
- package/dist/src/debug-symbols.js +3 -3
- package/dist/src/device-claim-inspection.js +1 -1
- package/dist/src/device-input-state.js +1 -1
- package/dist/src/device-ready.js +1 -0
- package/dist/src/dispatch.js +1 -0
- package/dist/src/find.js +1 -1
- package/dist/src/finders.js +1 -1
- package/dist/src/generic-settle.js +1 -1
- package/dist/src/handler-utils.js +1 -0
- package/dist/src/harmonyos.js +1 -1
- package/dist/src/hdc.js +1 -0
- package/dist/src/helper.js +1 -1
- package/dist/src/host-process.js +3 -2
- package/dist/src/ime-lifecycle.js +5 -5
- package/dist/src/index.d.ts +21 -21
- package/dist/src/input-actions.js +4 -4
- package/dist/src/input-actions2.js +1 -1
- package/dist/src/install-artifact.js +1 -1
- package/dist/src/interaction-runtime.js +1 -1
- package/dist/src/interaction-snapshot.js +1 -1
- package/dist/src/interaction-touch-reference-frame.js +1 -1
- package/dist/src/interaction.js +1 -1
- package/dist/src/interactor.js +1 -1
- package/dist/src/interactor2.js +1 -1
- package/dist/src/internal/bin.js +1 -1
- package/dist/src/internal/daemon.js +7 -29
- package/dist/src/inventory2.js +1 -1
- package/dist/src/lease-context.js +1 -1
- package/dist/src/lease.js +1 -1
- package/dist/src/limrun-runtime-dependencies.js +1 -1
- package/dist/src/linux.js +1 -1
- package/dist/src/manifest.js +1 -1
- package/dist/src/notifications.js +1 -1
- package/dist/src/output-path.js +1 -0
- package/dist/src/owner-identity.js +1 -1
- package/dist/src/physical-device-control.js +1 -1
- package/dist/src/platform-runtime-app-log-process.js +1 -1
- package/dist/src/platform-runtime-host.js +1 -1
- package/dist/src/platform-runtime-network-web-transport.js +1 -1
- package/dist/src/platform-runtime-operation-host.js +4 -4
- package/dist/src/platform-runtime-screen-recording-android-host.js +1 -0
- package/dist/src/platform-runtime-screen-recording-apple-host.js +1 -0
- package/dist/src/platform-runtime-screen-recording-apple-runner-host.js +1 -0
- package/dist/src/platform-runtime-screen-recording-apple-runner-transport.js +1 -0
- package/dist/src/platform-runtime-screen-recording-apple-simulator-host.js +1 -0
- package/dist/src/platform-runtime-screen-recording-apple-transport.js +1 -0
- package/dist/src/platform-runtime-screen-recording-finalizer-host.js +1 -0
- package/dist/src/platform-runtime-screen-recording-harmony-host.js +1 -0
- package/dist/src/platform-runtime-screen-recording-output-host.js +1 -0
- package/dist/src/platform-runtime-screen-recording-web-host.js +1 -0
- package/dist/src/platform-runtime-toolchain-host.js +1 -1
- package/dist/src/platform-runtime.js +1 -1
- package/dist/src/prepare-kind.js +13 -13
- package/dist/src/provider-webdriver.js +1 -1
- package/dist/src/proxy.js +1 -1
- package/dist/src/react-native.js +1 -1
- package/dist/src/record-runtime.js +1 -0
- package/dist/src/record-trace.js +1 -1
- package/dist/src/recording-telemetry.js +1 -0
- package/dist/src/registry.js +4 -4
- package/dist/src/remote-config2.js +1 -1
- package/dist/src/replay.js +2 -2
- package/dist/src/runner-disposal.js +1 -1
- package/dist/src/runner-lease.js +1 -1
- package/dist/src/runtime.js +3 -3
- package/dist/src/runtime2.js +3 -3
- package/dist/src/runtime3.js +3 -3
- package/dist/src/runtime4.js +1 -1
- package/dist/src/runtime7.js +1 -1
- package/dist/src/screenshot-result.js +4 -4
- package/dist/src/sdk-android-adb.js +4 -4
- package/dist/src/sdk-batch-runner.js +2 -2
- package/dist/src/sdk-finders.js +1 -1
- package/dist/src/sdk-remote-config.js +1 -1
- package/dist/src/sdk-selectors.d.ts +5 -1
- package/dist/src/sdk-selectors.js +1 -1
- package/dist/src/selector-runtime.js +1 -1
- package/dist/src/selectors.js +1 -1
- package/dist/src/server.js +2 -2
- package/dist/src/session-target-evidence.js +1 -1
- package/dist/src/session.js +10 -10
- package/dist/src/simulator.js +1 -1
- package/dist/src/snapshot-runtime.js +1 -1
- package/dist/src/snapshot-session.js +1 -1
- package/dist/src/snapshot.js +1 -1
- package/dist/src/snapshot2.js +1 -1
- package/dist/src/src.js +1 -1
- package/dist/src/src2.js +2 -2
- package/dist/src/src3.js +1 -1
- package/dist/src/text-surface.js +1 -1
- package/dist/src/tool-provider.js +3 -3
- package/dist/src/tool-provider2.js +1 -1
- package/dist/src/tool-provider3.js +1 -1
- package/dist/src/update-check.js +1 -1
- package/dist/src/version.js +1 -1
- package/dist/src/video.js +23 -0
- package/dist/src/web.js +1 -1
- package/package.json +2 -4
- package/server.json +2 -2
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.7.apk.sha256 +0 -1
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.7.apk.sha256 +0 -1
- package/dist/src/context.js +0 -1
- package/dist/src/provider.js +0 -1
- package/dist/src/runner-client.js +0 -1
- package/dist/src/runner-provider.js +0 -1
- package/skills/agent-device/SKILL.md +0 -20
- package/skills/dogfood/SKILL.md +0 -27
|
@@ -1 +1 @@
|
|
|
1
|
-
import{_ as e}from"./sdk-contracts.js";import{_ as t,a as n,b as r,c as i}from"./sdk-device.js";import{Tn as a,Xt as o,Yt as s,t as c,wn as l,xn as u}from"./prepare-kind.js";import{_ as d}from"./screenshot-result.js";import{t as f}from"./sdk-remote-config.js";import{A as p,x as m}from"./sdk-android-adb.js";import{v as h}from"./url.js";import{a as g,i as _}from"./client-metro.js";import{n as ee}from"./metro2.js";import{n as te,r as v,t as ne}from"./remote-config2.js";import{a as y,i as b}from"./src3.js";import x from"node:path";import S from"node:crypto";import C from"node:fs";const w={slug:`react-devtools-companion`,runArg:h,displayName:`React DevTools companion`};async function T(e){return await _({...e,definition:w,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 E(e){return await g({...e,definition:w})}function D(e){return e===`android-instance`||e===`ios-instance`}function re(e){return[`exec`,`--yes`,`--package`,`agent-cdp@1.6.1`,`--`,`agent-cdp`,...e]}function ie(e){return e.some(e=>e===`--url`||e.startsWith(`--url=`))}function O(e){return e[0]===`target`&&(e[1]===`list`||e[1]===`select`)&&!ie(e)}function ae(e){let t=new URL(e);t.search=``,t.hash=``;let n=t.pathname.replace(/\/+$/,``);return t.pathname=n.endsWith(`/index.bundle`)?n.slice(0,-13)||`/`:n||`/`,t.toString().replace(/\/+$/,``)}function oe(e){let t=e?.metroPublicBaseUrl?.trim();return t?ae(t):null}function se(t,n={}){if(!O(t)||!n.flags?.metroProxyBaseUrl||!D(n.flags.leaseBackend))return t;let r=oe(n.flags);if(!r)throw new e(`INVALID_ARGS`,`cdp remote bridge target discovery requires a React Native dev-server public base URL.`,{hint:`Include metroPublicBaseUrl in the remote config so cdp can reach the local or tunneled Metro/Re.Pack CDP endpoint without bridge proxy authentication.`});return[...t,`--url`,r]}async function ce(e,t={}){return(await m(`npm`,re(se(e,t)),{cwd:t.cwd??process.cwd(),env:t.env??process.env,allowFailure:!0,onStdoutChunk:e=>{process.stdout.write(e)},onStderrChunk:e=>{process.stderr.write(e)}})).exitCode}function k(e){let t=P(e);if(!C.existsSync(t))return null;let n;try{n=JSON.parse(C.readFileSync(t,`utf8`))}catch(t){return z(e,t),null}return me(n)?n:(z(e),null)}function A(e){let t=P({stateDir:e.stateDir,session:e.state.session});C.mkdirSync(x.dirname(t),{recursive:!0}),R(t,e.state),R(F(e.stateDir),{session:e.state.session})}function j(e){return{baseUrl:pe(e.daemonBaseUrl),transport:e.daemonTransport,serverMode:e.daemonServerMode}}function M(e){C.rmSync(P(e),{force:!0});let t=F(e.stateDir);L(e.stateDir)===e.session&&C.rmSync(t,{force:!0})}function le(t){let n=t.validateRemoteConfigHash??!0,r=t.remoteConfig?te({configPath:t.remoteConfig,cwd:t.cwd,env:t.env}):void 0,i=k(t)??(t.allowActiveFallback?I({stateDir:t.stateDir}):null);if(!i||r&&i.remoteConfigPath!==r)return null;if(n&&N(i.remoteConfigPath)!==i.remoteConfigHash)throw new e(`INVALID_ARGS`,`Active remote connection config changed. Run agent-device connect --force to refresh it.`,{remoteConfig:i.remoteConfigPath});let o=fe(i,t),s=u(i);return{runtime:i.runtime,connection:a(s),flags:{...o,remoteConfig:i.remoteConfigPath,daemonBaseUrl:i.daemon?.baseUrl??o.daemonBaseUrl,daemonAuthToken:o.daemonAuthToken,daemonTransport:i.daemon?.transport??o.daemonTransport,daemonServerMode:i.daemon?.serverMode??o.daemonServerMode,...l(s),sessionIsolation:`tenant`,session:i.session,platform:i.platform??o.platform,target:i.target??o.target}}}function ue(e){return a(u(e))}function N(t){try{return S.createHash(`sha256`).update(C.readFileSync(t)).digest(`hex`)}catch(n){throw new e(`INVALID_ARGS`,`Remote config file not found: ${t}`,{cause:n instanceof Error?n.message:String(n)})}}function P(e){return x.join(e.stateDir,`remote-connections`,`${B(e.session)}.json`)}function F(e){return x.join(e,`remote-connections`,`.active-session.json`)}function I(e){let t=L(e.stateDir);return t?k({stateDir:e.stateDir,session:t}):null}function L(e){let t=F(e);if(C.existsSync(t))try{let e=JSON.parse(C.readFileSync(t,`utf8`));return typeof e.session==`string`?e.session:void 0}catch{return}}function de(e){if(e)return S.createHash(`sha256`).update(e).digest(`hex`).slice(0,12)}function fe(e,t){try{return v({configPath:e.remoteConfigPath,cwd:t.cwd,env:t.env}).profile}catch(e){if(t.validateRemoteConfigHash===!1)return{};throw e}}function R(e,t){let n=`${e}.${process.pid}.${S.randomUUID()}.tmp`;try{C.writeFileSync(n,`${JSON.stringify(t,null,2)}\n`,{encoding:`utf8`,mode:384}),C.renameSync(n,e)}catch(e){throw C.rmSync(n,{force:!0}),e}}function pe(e){if(!e)return;let t=new URL(e);t.username=``,t.password=``;for(let e of[...t.searchParams.keys()])/(auth|key|password|secret|token)/i.test(e)&&t.searchParams.delete(e);return t.toString().replace(/\/+$/,``)}function z(e,t){p({level:`warn`,phase:`remote_connection_state_invalid`,data:{session:e.session,cause:t instanceof Error?t.message:t?String(t):void 0}}),M(e)}function B(e){let t=e.replaceAll(/[^a-zA-Z0-9._-]/g,`_`);return t?t===e?t:`${t}-${S.createHash(`sha256`).update(e).digest(`hex`).slice(0,8)}`:`default`}function me(e){if(!e||typeof e!=`object`||Array.isArray(e))return!1;let t=e;return t.version===1&&he(t,[`session`,`remoteConfigPath`,`remoteConfigHash`,`tenant`,`runId`,`connectedAt`,`updatedAt`])&&ge(t,[`leaseId`,`leaseBackend`,`leaseProvider`,`deviceKey`,`clientId`])&&_e(t.daemon)}function he(e,t){return t.every(t=>typeof e[t]==`string`)}function ge(e,t){return t.every(t=>e[t]===void 0||typeof e[t]==`string`)}function _e(e){return e===void 0?!0:!e||typeof e!=`object`||Array.isArray(e)?!1:ve(e)}function ve(e){let t=e;return(t.baseUrl===void 0||typeof t.baseUrl==`string`)&&(t.authToken===void 0||typeof t.authToken==`string`)&&(t.transport===void 0||typeof t.transport==`string`)&&(t.serverMode===void 0||typeof t.serverMode==`string`)}const ye=f.map(e=>e.key);function V(e){let t={};for(let n of ye){let r=e[n];r!==void 0&&(t[n]=r)}return t}function be(e){return e.remoteConfig?{...V(v({configPath:e.remoteConfig,cwd:e.cwd,env:e.env}).profile),remoteConfig:e.remoteConfig}:{}}function xe(e){return e===`cloud`||e===`proxy`||H(e)}function H(e){return e===`limrun`||y(e)}function Se(){return[`cloud`,`proxy`,b.browserStack,b.awsDeviceFarm,`limrun`].join(`, `)}function U(e){return!H(e)}function Ce(e){return e===`proxy`?`proxy`:H(e)?`direct-device-provider`:`remote-provider`}function W(e){return{providerDeviceOrientation:e.providerDeviceOrientation,providerGeoLocation:e.providerGeoLocation,providerTimezone:e.providerTimezone,providerLanguage:e.providerLanguage,providerLocale:e.providerLocale,providerNetworkProfile:e.providerNetworkProfile,providerCustomNetwork:e.providerCustomNetwork,providerNoResignApp:e.providerNoResignApp}}function we(e){return{metroProjectRoot:e.metroProjectRoot,metroKind:e.metroKind,metroPublicBaseUrl:e.metroPublicBaseUrl,metroProxyBaseUrl:e.metroProxyBaseUrl,metroPreparePort:e.metroPreparePort,metroListenHost:e.metroListenHost,metroStatusHost:e.metroStatusHost,metroStartupTimeoutMs:e.metroStartupTimeoutMs,metroProbeTimeoutMs:e.metroProbeTimeoutMs,metroRuntimeFile:e.metroRuntimeFile,metroNoReuseExisting:e.metroNoReuseExisting,metroNoInstallDeps:e.metroNoInstallDeps,launchUrl:e.launchUrl}}const G=new Set([`artifacts`,`connect`,`connection`,`close`,`disconnect`,`metro`,`session`]),K=new Set([`open`]),Te=new Set([o.open,o.install,o.reinstall,s.installSource]);async function Ee(t){let{command:n,flags:r,client:i}=t;if(!r.remoteConfig)return{flags:r,runtime:t.runtime};let a=d(r.stateDir).baseDir,o=v({configPath:r.remoteConfig,cwd:process.cwd(),env:process.env}),s={...V(o.profile),...r,remoteConfig:o.resolvedPath},c=k({stateDir:a,session:s.session??`default`});if(c&&c.remoteConfigPath!==o.resolvedPath)throw new e(`INVALID_ARGS`,`A different remote connection is already active for this session. Run connect --force or disconnect before using a different --remote-config.`,{session:c.session,activeRemoteConfig:c.remoteConfigPath,requestedRemoteConfig:o.resolvedPath});let l=c??Ye(s,o.resolvedPath,o.profile),u={...s,session:l.session},f=Je(l.runtime,u.platform)??t.runtime,p=l,m=!c,h,g=Pe(p);if(g.shouldAllocate(n)){let e=await je({command:n,client:i,state:l,nextState:p,nextFlags:u,policy:g});p=e.state,m||=e.changed,h=e.acquiredLeaseForCleanup}let _=await De({command:n,flags:u,client:i,state:l,nextState:p,runtime:f,positionals:t.positionals,batchSteps:t.batchSteps,forceRuntimePrepare:t.forceRuntimePrepare});return p=_.state,f=_.runtime,m||=_.changed,await Ae({changed:m,stateDir:a,state:p,client:i,acquiredLeaseForCleanup:h,preparedMetroCleanupOnFailure:_.preparedMetroCleanupOnFailure,metroCleanupToStop:_.metroCleanupToStop}),{flags:{...u,session:p.session,leaseId:p.leaseId,leaseBackend:p.leaseBackend,platform:p.platform??u.platform,target:p.target??u.target},runtime:f,connection:ue(p)}}async function De(t){let{command:n,flags:r,state:i,client:a}=t,o=Oe(t.nextState,r),s=t.runtime;if(!Ke(n,r,t.batchSteps,t.positionals)||!Z(r)||!ke(t.forceRuntimePrepare,s,r.platform))return{state:o,runtime:s,changed:!1};if(!o.leaseId)throw new e(`INVALID_ARGS`,`${n} requires a resolved remote lease before Metro runtime can be prepared.`);let c=await Re(r,a,i.remoteConfigPath,i.session,{tenantId:i.tenant,runId:i.runId,leaseId:o.leaseId}),l=!qe(o.metro,c.cleanup);return o={...o,runtime:c.runtime,metro:c.cleanup,updatedAt:new Date().toISOString()},{state:o,runtime:c.runtime,changed:!0,metroCleanupToStop:l?t.nextState.metro:void 0,preparedMetroCleanupOnFailure:l?c.cleanup:void 0}}function Oe(e,t){return e.leaseId||!t.leaseId?e:{...e,leaseId:t.leaseId,leaseBackend:t.leaseBackend}}function ke(e,t,n){return e===!0||!t||!Q(t,n)}async function Ae(e){if(e.changed)try{A({stateDir:e.stateDir,state:e.state})}catch(t){throw await q(e.preparedMetroCleanupOnFailure),await We(e.client,e.state,e.acquiredLeaseForCleanup),t}await q(e.metroCleanupToStop)}async function je(e){let{command:t,client:n,state:r,nextFlags:i,policy:a}=e,o=r.leaseBackend??X(i),s=e.nextState,c=await a.resolveLeaseState({command:t,client:n,state:s,flags:i,leaseBackend:o});s=c.state,c.device&&$(i,c.device);let l=s.leaseBackend??o??Ge(i,t);tt(r,i,l);let u=await Xe(n,s,l,a,i),d=u.lease;return i.leaseId=d.leaseId,i.leaseBackend=l,i.platform=s.platform??i.platform,i.target=s.target??i.target,Me(s,d,l)?{state:s,changed:!1,acquiredLeaseForCleanup:u.acquired?d:void 0}:{state:Ne(s,d,l,i),changed:!0,acquiredLeaseForCleanup:u.acquired?d:void 0}}function Me(e,t,n){return e.leaseId===t.leaseId&&e.leaseBackend===n&&e.deviceKey===(t.deviceKey??e.deviceKey)}function Ne(e,t,n,r){return{...e,leaseId:t.leaseId,leaseBackend:n,leaseProvider:t.leaseProvider??e.leaseProvider,clientId:t.clientId??e.clientId,deviceKey:t.deviceKey??e.deviceKey,platform:e.platform??r.platform,target:e.target??r.target,updatedAt:new Date().toISOString()}}function Pe(e){return e.leaseProvider===`proxy`?Ie:y(e.leaseProvider)?Le:Fe}const Fe={shouldAllocate:e=>!G.has(e),ttlMs:()=>void 0,resolveLeaseState:async e=>({state:e.state})},Ie={shouldAllocate:e=>e!==`devices`&&!G.has(e),ttlMs:()=>3e5,resolveLeaseState:Ze},Le={shouldAllocate:e=>!G.has(e),ttlMs:()=>6e5,resolveLeaseState:async e=>({state:e.state})};async function Re(t,n,r,i,a){if(!t.metroProjectRoot&&!t.metroPublicBaseUrl&&!t.metroProxyBaseUrl)return{};if(t.platform!==`ios`&&t.platform!==`android`)throw new e(`INVALID_ARGS`,`Deferred Metro preparation requires platform "ios" or "android".`);if(!t.metroPublicBaseUrl&&!t.metroProxyBaseUrl)throw new e(`INVALID_ARGS`,`Deferred Metro preparation requires metroPublicBaseUrl or metroProxyBaseUrl when Metro settings are provided.`);let o=await n.metro.prepare({projectRoot:t.metroProjectRoot,kind:c(t.metroKind),publicBaseUrl:t.metroPublicBaseUrl,proxyBaseUrl:t.metroProxyBaseUrl,bearerToken:t.metroBearerToken,bridgeScope:a,launchUrl:t.launchUrl,companionProfileKey:r,companionConsumerKey:i,port:t.metroPreparePort,listenHost:t.metroListenHost,statusHost:t.metroStatusHost,startupTimeoutMs:t.metroStartupTimeoutMs,probeTimeoutMs:t.metroProbeTimeoutMs,reuseExisting:t.metroNoReuseExisting?!1:void 0,installDependenciesIfNeeded:t.metroNoInstallDeps?!1:void 0,runtimeFilePath:t.metroRuntimeFile});return{runtime:t.platform===`ios`?o.iosRuntime:o.androidRuntime,cleanup:t.metroProxyBaseUrl?{projectRoot:o.projectRoot,profileKey:r,consumerKey:i}:void 0}}async function q(e){if(e)try{await ee(e)}catch{}}async function ze(e){try{await E({projectRoot:process.cwd(),stateDir:e.stateDir,profileKey:e.state.remoteConfigPath,consumerKey:e.state.session})}catch{}}async function J(e,t,n){return t.leaseId?await e.leases.release({tenant:t.tenant,runId:t.runId,leaseId:t.leaseId,leaseBackend:t.leaseBackend,daemonBaseUrl:t.daemon?.baseUrl,daemonAuthToken:n,daemonTransport:t.daemon?.transport,daemonServerMode:t.daemon?.serverMode,leaseProvider:t.leaseProvider,clientId:t.clientId,deviceKey:t.deviceKey}):{released:!1}}function Be(e){let t=Ve(e.previous,e.cwd,e.env);return t?{canAuthenticate:!0,daemonAuthToken:t}:e.previous.daemon?.baseUrl===e.nextDaemonBaseUrl?{canAuthenticate:!0,daemonAuthToken:e.ambientDaemonAuthToken}:{canAuthenticate:!1}}function Ve(e,t,n){try{let{profile:r}=ne({configPath:e.remoteConfigPath,cwd:t,env:n});return r.daemonAuthToken&&He(e,r.daemonBaseUrl)?r.daemonAuthToken:void 0}catch{return}}function He(e,t){let n=j({daemonBaseUrl:t})?.baseUrl;return n!==void 0&&n===e.daemon?.baseUrl}async function Ue(e,t,n){if(!t.leaseId)return;let r=Be({previous:t,nextDaemonBaseUrl:n.nextDaemonBaseUrl,ambientDaemonAuthToken:n.ambientDaemonAuthToken,cwd:n.cwd,env:n.env});if(!r.canAuthenticate)return Y(t,`no credential known to belong to that endpoint was available`);try{await J(e,t,r.daemonAuthToken);return}catch{return Y(t,`the release request failed`)}}function Y(e,t){return{status:`unreleased`,message:`Could not release the previous lease ${e.leaseId} (tenant ${e.tenant}, run ${e.runId}) at ${e.daemon?.baseUrl??`its daemon`}: ${t}. It was left in place — release it manually if it is still active.`}}async function We(e,t,n){if(n)try{await e.leases.release({tenant:t.tenant,runId:t.runId,leaseId:n.leaseId,leaseBackend:t.leaseBackend??n.backend,leaseProvider:t.leaseProvider??n.leaseProvider,clientId:t.clientId??n.clientId,deviceKey:t.deviceKey??n.deviceKey})}catch{}}function X(e){if(e.leaseBackend)return e.leaseBackend;if(e.platform===`android`)return`android-instance`;if(e.platform===`ios`)return`ios-instance`}function Ge(t,n){let r=X(t);if(r)return r;throw new e(`INVALID_ARGS`,`${n} requires --platform ios|android or --lease-backend when the remote connection has not resolved a lease yet.`)}function Ke(e,t,n,r=[]){return e===`cdp`?O(r)&&!!t.metroPublicBaseUrl:K.has(e)?!0:e!==`batch`||!n?!1:n.some(e=>{let t=e.command.trim().toLowerCase();return K.has(t)&&e.runtime===void 0})}function Z(e){let t=e.metroKind;return!!(e.metroPublicBaseUrl||e.metroProxyBaseUrl||e.metroProjectRoot||t)}function Q(e,t){return!e.platform||!t||t!==`ios`&&t!==`android`?!0:e.platform===t}function qe(e,t){return e?.projectRoot===t?.projectRoot&&e?.profileKey===t?.profileKey&&e?.consumerKey===t?.consumerKey}function Je(e,t){if(e)return Q(e,t)?e:void 0}function Ye(t,n,r={}){if(!t.tenant)throw new e(`INVALID_ARGS`,`remote command requires tenant in remote config or via --tenant <id>.`);if(!t.runId)throw new e(`INVALID_ARGS`,`remote command requires runId in remote config or via --run-id <id>.`);if(!t.daemonBaseUrl&&U(r.leaseProvider))throw new e(`INVALID_ARGS`,`remote command requires daemonBaseUrl in remote config, config, env, or --daemon-base-url.`);let i=new Date().toISOString();return{version:1,session:t.session??`default`,remoteConfigPath:n,remoteConfigHash:N(n),daemon:j(t),tenant:t.tenant,runId:t.runId,leaseId:t.leaseId,leaseBackend:t.leaseBackend??X(t),leaseProvider:r.leaseProvider,clientId:r.clientId,deviceKey:r.deviceKey,platform:t.platform,target:t.target,connectedAt:i,updatedAt:i}}async function Xe(e,t,n,r,i){if(t.leaseId&&t.leaseBackend===n){let i=await nt(e,t.leaseId,{tenant:t.tenant,runId:t.runId,leaseBackend:n,leaseProvider:t.leaseProvider,clientId:t.clientId,deviceKey:t.deviceKey,ttlMs:r.ttlMs(t)});if(i)return{lease:i,acquired:!1}}return{lease:await e.leases.allocate({tenant:t.tenant,runId:t.runId,leaseBackend:n,leaseProvider:t.leaseProvider,clientId:t.clientId,deviceKey:t.deviceKey,ttlMs:r.ttlMs(t),platform:t.platform??i.platform,target:t.target??i.target,device:i.device,udid:i.udid,serial:i.serial,providerApp:i.providerApp,providerOsVersion:i.providerOsVersion,providerProject:i.providerProject,providerBuild:i.providerBuild,providerSessionName:i.providerSessionName,...W(i),awsProjectArn:i.awsProjectArn,awsDeviceArn:i.awsDeviceArn,awsAppArn:i.awsAppArn,awsRegion:i.awsRegion,awsInteractionMode:i.awsInteractionMode}),acquired:!0}}async function Ze(t){if(!Te.has(t.command)){if(t.state.leaseId&&t.state.deviceKey)return{state:t.state};throw new e(`INVALID_ARGS`,`No active proxy device lease for this session; run open first.`)}let n=await Qe(t.client,t.flags),r=$e(n);return{state:{...t.state,deviceKey:r,leaseBackend:t.state.leaseBackend??t.leaseBackend??et(n),platform:t.state.platform??n.platform,target:t.state.target??n.target,updatedAt:new Date().toISOString()},device:n}}function $(e,t){if(e.platform=t.platform,e.target=t.target??e.target,i(t)){e.udid=t.id;return}t.platform===`android`&&(e.serial=t.id)}async function Qe(e,t){return await r((await e.devices.list({platform:t.platform,target:t.target,device:t.device,udid:t.udid,serial:t.serial,iosSimulatorDeviceSet:t.iosSimulatorDeviceSet,androidDeviceAllowlist:t.androidDeviceAllowlist})).map(e=>({...n(e.platform),id:e.id,name:e.name,kind:e.kind,target:e.target,booted:e.booted})),{platform:t.platform,target:t.target,deviceName:t.device,udid:t.udid,serial:t.serial})}function $e(e){return`${t(e)}:${e.target??`mobile`}:${e.id}`}function et(e){if(i(e))return`ios-instance`;if(e.platform===`android`)return`android-instance`}function tt(t,n,r){if(t.leaseBackend&&t.leaseBackend!==r)throw new e(`INVALID_ARGS`,`Active remote connection is already bound to a different lease backend. Re-run connect --force to replace it.`,{session:t.session,leaseBackend:t.leaseBackend});if(t.platform&&n.platform&&t.platform!==n.platform)throw new e(`INVALID_ARGS`,`Active remote connection is already bound to a different platform. Re-run connect --force to replace it.`,{session:t.session,platform:t.platform});if(t.target&&n.target&&t.target!==n.target)throw new e(`INVALID_ARGS`,`Active remote connection is already bound to a different target. Re-run connect --force to replace it.`,{session:t.session,target:t.target})}async function nt(e,t,n){try{return await e.leases.heartbeat({tenant:n.tenant,runId:n.runId,leaseId:t,leaseBackend:n.leaseBackend,leaseProvider:n.leaseProvider,clientId:n.clientId,deviceKey:n.deviceKey,ttlMs:n.ttlMs})}catch(e){if(rt(e))return;throw e}}function rt(t){return!(t instanceof e)||t.code!==`UNAUTHORIZED`?!1:t.details?.reason===`LEASE_NOT_FOUND`||t.details?.reason===`LEASE_EXPIRED`||t.details?.reason===`LEASE_REVOKED`}export{A as C,E as D,T as E,le as S,D as T,de as _,X as a,k as b,W as c,Ce as d,U as f,j as g,be as h,J as i,we as l,V as m,Ee as n,q as o,xe as p,Ue as r,ze as s,Z as t,Se as u,N as v,ce as w,M as x,I as y};
|
|
1
|
+
import{_ as e}from"./sdk-contracts.js";import{_ as t,a as n,b as r,c as i}from"./sdk-device.js";import{Tn as a,Xt as o,Yt as s,t as c,wn as l,xn as u}from"./prepare-kind.js";import{_ as d}from"./screenshot-result.js";import{t as f}from"./sdk-remote-config.js";import{S as p,j as m}from"./sdk-android-adb.js";import{v as h}from"./url.js";import{a as g,i as _}from"./client-metro.js";import{n as ee}from"./metro2.js";import{n as te,r as v,t as ne}from"./remote-config2.js";import{a as y,i as b}from"./src3.js";import x from"node:path";import S from"node:crypto";import C from"node:fs";const w={slug:`react-devtools-companion`,runArg:h,displayName:`React DevTools companion`};async function T(e){return await _({...e,definition:w,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 E(e){return await g({...e,definition:w})}function D(e){return e===`android-instance`||e===`ios-instance`}function re(e){return[`exec`,`--yes`,`--package`,`agent-cdp@1.6.1`,`--`,`agent-cdp`,...e]}function ie(e){return e.some(e=>e===`--url`||e.startsWith(`--url=`))}function O(e){return e[0]===`target`&&(e[1]===`list`||e[1]===`select`)&&!ie(e)}function ae(e){let t=new URL(e);t.search=``,t.hash=``;let n=t.pathname.replace(/\/+$/,``);return t.pathname=n.endsWith(`/index.bundle`)?n.slice(0,-13)||`/`:n||`/`,t.toString().replace(/\/+$/,``)}function oe(e){let t=e?.metroPublicBaseUrl?.trim();return t?ae(t):null}function se(t,n={}){if(!O(t)||!n.flags?.metroProxyBaseUrl||!D(n.flags.leaseBackend))return t;let r=oe(n.flags);if(!r)throw new e(`INVALID_ARGS`,`cdp remote bridge target discovery requires a React Native dev-server public base URL.`,{hint:`Include metroPublicBaseUrl in the remote config so cdp can reach the local or tunneled Metro/Re.Pack CDP endpoint without bridge proxy authentication.`});return[...t,`--url`,r]}async function ce(e,t={}){return(await p(`npm`,re(se(e,t)),{cwd:t.cwd??process.cwd(),env:t.env??process.env,allowFailure:!0,onStdoutChunk:e=>{process.stdout.write(e)},onStderrChunk:e=>{process.stderr.write(e)}})).exitCode}function k(e){let t=P(e);if(!C.existsSync(t))return null;let n;try{n=JSON.parse(C.readFileSync(t,`utf8`))}catch(t){return z(e,t),null}return me(n)?n:(z(e),null)}function A(e){let t=P({stateDir:e.stateDir,session:e.state.session});C.mkdirSync(x.dirname(t),{recursive:!0}),R(t,e.state),R(F(e.stateDir),{session:e.state.session})}function j(e){return{baseUrl:pe(e.daemonBaseUrl),transport:e.daemonTransport,serverMode:e.daemonServerMode}}function M(e){C.rmSync(P(e),{force:!0});let t=F(e.stateDir);L(e.stateDir)===e.session&&C.rmSync(t,{force:!0})}function le(t){let n=t.validateRemoteConfigHash??!0,r=t.remoteConfig?te({configPath:t.remoteConfig,cwd:t.cwd,env:t.env}):void 0,i=k(t)??(t.allowActiveFallback?I({stateDir:t.stateDir}):null);if(!i||r&&i.remoteConfigPath!==r)return null;if(n&&N(i.remoteConfigPath)!==i.remoteConfigHash)throw new e(`INVALID_ARGS`,`Active remote connection config changed. Run agent-device connect --force to refresh it.`,{remoteConfig:i.remoteConfigPath});let o=fe(i,t),s=u(i);return{runtime:i.runtime,connection:a(s),flags:{...o,remoteConfig:i.remoteConfigPath,daemonBaseUrl:i.daemon?.baseUrl??o.daemonBaseUrl,daemonAuthToken:o.daemonAuthToken,daemonTransport:i.daemon?.transport??o.daemonTransport,daemonServerMode:i.daemon?.serverMode??o.daemonServerMode,...l(s),sessionIsolation:`tenant`,session:i.session,platform:i.platform??o.platform,target:i.target??o.target}}}function ue(e){return a(u(e))}function N(t){try{return S.createHash(`sha256`).update(C.readFileSync(t)).digest(`hex`)}catch(n){throw new e(`INVALID_ARGS`,`Remote config file not found: ${t}`,{cause:n instanceof Error?n.message:String(n)})}}function P(e){return x.join(e.stateDir,`remote-connections`,`${B(e.session)}.json`)}function F(e){return x.join(e,`remote-connections`,`.active-session.json`)}function I(e){let t=L(e.stateDir);return t?k({stateDir:e.stateDir,session:t}):null}function L(e){let t=F(e);if(C.existsSync(t))try{let e=JSON.parse(C.readFileSync(t,`utf8`));return typeof e.session==`string`?e.session:void 0}catch{return}}function de(e){if(e)return S.createHash(`sha256`).update(e).digest(`hex`).slice(0,12)}function fe(e,t){try{return v({configPath:e.remoteConfigPath,cwd:t.cwd,env:t.env}).profile}catch(e){if(t.validateRemoteConfigHash===!1)return{};throw e}}function R(e,t){let n=`${e}.${process.pid}.${S.randomUUID()}.tmp`;try{C.writeFileSync(n,`${JSON.stringify(t,null,2)}\n`,{encoding:`utf8`,mode:384}),C.renameSync(n,e)}catch(e){throw C.rmSync(n,{force:!0}),e}}function pe(e){if(!e)return;let t=new URL(e);t.username=``,t.password=``;for(let e of[...t.searchParams.keys()])/(auth|key|password|secret|token)/i.test(e)&&t.searchParams.delete(e);return t.toString().replace(/\/+$/,``)}function z(e,t){m({level:`warn`,phase:`remote_connection_state_invalid`,data:{session:e.session,cause:t instanceof Error?t.message:t?String(t):void 0}}),M(e)}function B(e){let t=e.replaceAll(/[^a-zA-Z0-9._-]/g,`_`);return t?t===e?t:`${t}-${S.createHash(`sha256`).update(e).digest(`hex`).slice(0,8)}`:`default`}function me(e){if(!e||typeof e!=`object`||Array.isArray(e))return!1;let t=e;return t.version===1&&he(t,[`session`,`remoteConfigPath`,`remoteConfigHash`,`tenant`,`runId`,`connectedAt`,`updatedAt`])&&ge(t,[`leaseId`,`leaseBackend`,`leaseProvider`,`deviceKey`,`clientId`])&&_e(t.daemon)}function he(e,t){return t.every(t=>typeof e[t]==`string`)}function ge(e,t){return t.every(t=>e[t]===void 0||typeof e[t]==`string`)}function _e(e){return e===void 0?!0:!e||typeof e!=`object`||Array.isArray(e)?!1:ve(e)}function ve(e){let t=e;return(t.baseUrl===void 0||typeof t.baseUrl==`string`)&&(t.authToken===void 0||typeof t.authToken==`string`)&&(t.transport===void 0||typeof t.transport==`string`)&&(t.serverMode===void 0||typeof t.serverMode==`string`)}const ye=f.map(e=>e.key);function V(e){let t={};for(let n of ye){let r=e[n];r!==void 0&&(t[n]=r)}return t}function be(e){return e.remoteConfig?{...V(v({configPath:e.remoteConfig,cwd:e.cwd,env:e.env}).profile),remoteConfig:e.remoteConfig}:{}}function xe(e){return e===`cloud`||e===`proxy`||H(e)}function H(e){return e===`limrun`||y(e)}function Se(){return[`cloud`,`proxy`,b.browserStack,b.awsDeviceFarm,`limrun`].join(`, `)}function U(e){return!H(e)}function Ce(e){return e===`proxy`?`proxy`:H(e)?`direct-device-provider`:`remote-provider`}function W(e){return{providerDeviceOrientation:e.providerDeviceOrientation,providerGeoLocation:e.providerGeoLocation,providerTimezone:e.providerTimezone,providerLanguage:e.providerLanguage,providerLocale:e.providerLocale,providerNetworkProfile:e.providerNetworkProfile,providerCustomNetwork:e.providerCustomNetwork,providerNoResignApp:e.providerNoResignApp}}function we(e){return{metroProjectRoot:e.metroProjectRoot,metroKind:e.metroKind,metroPublicBaseUrl:e.metroPublicBaseUrl,metroProxyBaseUrl:e.metroProxyBaseUrl,metroPreparePort:e.metroPreparePort,metroListenHost:e.metroListenHost,metroStatusHost:e.metroStatusHost,metroStartupTimeoutMs:e.metroStartupTimeoutMs,metroProbeTimeoutMs:e.metroProbeTimeoutMs,metroRuntimeFile:e.metroRuntimeFile,metroNoReuseExisting:e.metroNoReuseExisting,metroNoInstallDeps:e.metroNoInstallDeps,launchUrl:e.launchUrl}}const G=new Set([`artifacts`,`connect`,`connection`,`close`,`disconnect`,`metro`,`session`]),K=new Set([`open`]),Te=new Set([o.open,o.install,o.reinstall,s.installSource]);async function Ee(t){let{command:n,flags:r,client:i}=t;if(!r.remoteConfig)return{flags:r,runtime:t.runtime};let a=d(r.stateDir).baseDir,o=v({configPath:r.remoteConfig,cwd:process.cwd(),env:process.env}),s={...V(o.profile),...r,remoteConfig:o.resolvedPath},c=k({stateDir:a,session:s.session??`default`});if(c&&c.remoteConfigPath!==o.resolvedPath)throw new e(`INVALID_ARGS`,`A different remote connection is already active for this session. Run connect --force or disconnect before using a different --remote-config.`,{session:c.session,activeRemoteConfig:c.remoteConfigPath,requestedRemoteConfig:o.resolvedPath});let l=c??Ye(s,o.resolvedPath,o.profile),u={...s,session:l.session},f=Je(l.runtime,u.platform)??t.runtime,p=l,m=!c,h,g=Pe(p);if(g.shouldAllocate(n)){let e=await je({command:n,client:i,state:l,nextState:p,nextFlags:u,policy:g});p=e.state,m||=e.changed,h=e.acquiredLeaseForCleanup}let _=await De({command:n,flags:u,client:i,state:l,nextState:p,runtime:f,positionals:t.positionals,batchSteps:t.batchSteps,forceRuntimePrepare:t.forceRuntimePrepare});return p=_.state,f=_.runtime,m||=_.changed,await Ae({changed:m,stateDir:a,state:p,client:i,acquiredLeaseForCleanup:h,preparedMetroCleanupOnFailure:_.preparedMetroCleanupOnFailure,metroCleanupToStop:_.metroCleanupToStop}),{flags:{...u,session:p.session,leaseId:p.leaseId,leaseBackend:p.leaseBackend,platform:p.platform??u.platform,target:p.target??u.target},runtime:f,connection:ue(p)}}async function De(t){let{command:n,flags:r,state:i,client:a}=t,o=Oe(t.nextState,r),s=t.runtime;if(!Ke(n,r,t.batchSteps,t.positionals)||!Z(r)||!ke(t.forceRuntimePrepare,s,r.platform))return{state:o,runtime:s,changed:!1};if(!o.leaseId)throw new e(`INVALID_ARGS`,`${n} requires a resolved remote lease before Metro runtime can be prepared.`);let c=await Re(r,a,i.remoteConfigPath,i.session,{tenantId:i.tenant,runId:i.runId,leaseId:o.leaseId}),l=!qe(o.metro,c.cleanup);return o={...o,runtime:c.runtime,metro:c.cleanup,updatedAt:new Date().toISOString()},{state:o,runtime:c.runtime,changed:!0,metroCleanupToStop:l?t.nextState.metro:void 0,preparedMetroCleanupOnFailure:l?c.cleanup:void 0}}function Oe(e,t){return e.leaseId||!t.leaseId?e:{...e,leaseId:t.leaseId,leaseBackend:t.leaseBackend}}function ke(e,t,n){return e===!0||!t||!Q(t,n)}async function Ae(e){if(e.changed)try{A({stateDir:e.stateDir,state:e.state})}catch(t){throw await q(e.preparedMetroCleanupOnFailure),await We(e.client,e.state,e.acquiredLeaseForCleanup),t}await q(e.metroCleanupToStop)}async function je(e){let{command:t,client:n,state:r,nextFlags:i,policy:a}=e,o=r.leaseBackend??X(i),s=e.nextState,c=await a.resolveLeaseState({command:t,client:n,state:s,flags:i,leaseBackend:o});s=c.state,c.device&&$(i,c.device);let l=s.leaseBackend??o??Ge(i,t);tt(r,i,l);let u=await Xe(n,s,l,a,i),d=u.lease;return i.leaseId=d.leaseId,i.leaseBackend=l,i.platform=s.platform??i.platform,i.target=s.target??i.target,Me(s,d,l)?{state:s,changed:!1,acquiredLeaseForCleanup:u.acquired?d:void 0}:{state:Ne(s,d,l,i),changed:!0,acquiredLeaseForCleanup:u.acquired?d:void 0}}function Me(e,t,n){return e.leaseId===t.leaseId&&e.leaseBackend===n&&e.deviceKey===(t.deviceKey??e.deviceKey)}function Ne(e,t,n,r){return{...e,leaseId:t.leaseId,leaseBackend:n,leaseProvider:t.leaseProvider??e.leaseProvider,clientId:t.clientId??e.clientId,deviceKey:t.deviceKey??e.deviceKey,platform:e.platform??r.platform,target:e.target??r.target,updatedAt:new Date().toISOString()}}function Pe(e){return e.leaseProvider===`proxy`?Ie:y(e.leaseProvider)?Le:Fe}const Fe={shouldAllocate:e=>!G.has(e),ttlMs:()=>void 0,resolveLeaseState:async e=>({state:e.state})},Ie={shouldAllocate:e=>e!==`devices`&&!G.has(e),ttlMs:()=>3e5,resolveLeaseState:Ze},Le={shouldAllocate:e=>!G.has(e),ttlMs:()=>6e5,resolveLeaseState:async e=>({state:e.state})};async function Re(t,n,r,i,a){if(!t.metroProjectRoot&&!t.metroPublicBaseUrl&&!t.metroProxyBaseUrl)return{};if(t.platform!==`ios`&&t.platform!==`android`)throw new e(`INVALID_ARGS`,`Deferred Metro preparation requires platform "ios" or "android".`);if(!t.metroPublicBaseUrl&&!t.metroProxyBaseUrl)throw new e(`INVALID_ARGS`,`Deferred Metro preparation requires metroPublicBaseUrl or metroProxyBaseUrl when Metro settings are provided.`);let o=await n.metro.prepare({projectRoot:t.metroProjectRoot,kind:c(t.metroKind),publicBaseUrl:t.metroPublicBaseUrl,proxyBaseUrl:t.metroProxyBaseUrl,bearerToken:t.metroBearerToken,bridgeScope:a,launchUrl:t.launchUrl,companionProfileKey:r,companionConsumerKey:i,port:t.metroPreparePort,listenHost:t.metroListenHost,statusHost:t.metroStatusHost,startupTimeoutMs:t.metroStartupTimeoutMs,probeTimeoutMs:t.metroProbeTimeoutMs,reuseExisting:t.metroNoReuseExisting?!1:void 0,installDependenciesIfNeeded:t.metroNoInstallDeps?!1:void 0,runtimeFilePath:t.metroRuntimeFile});return{runtime:t.platform===`ios`?o.iosRuntime:o.androidRuntime,cleanup:t.metroProxyBaseUrl?{projectRoot:o.projectRoot,profileKey:r,consumerKey:i}:void 0}}async function q(e){if(e)try{await ee(e)}catch{}}async function ze(e){try{await E({projectRoot:process.cwd(),stateDir:e.stateDir,profileKey:e.state.remoteConfigPath,consumerKey:e.state.session})}catch{}}async function J(e,t,n){return t.leaseId?await e.leases.release({tenant:t.tenant,runId:t.runId,leaseId:t.leaseId,leaseBackend:t.leaseBackend,daemonBaseUrl:t.daemon?.baseUrl,daemonAuthToken:n,daemonTransport:t.daemon?.transport,daemonServerMode:t.daemon?.serverMode,leaseProvider:t.leaseProvider,clientId:t.clientId,deviceKey:t.deviceKey}):{released:!1}}function Be(e){let t=Ve(e.previous,e.cwd,e.env);return t?{canAuthenticate:!0,daemonAuthToken:t}:e.previous.daemon?.baseUrl===e.nextDaemonBaseUrl?{canAuthenticate:!0,daemonAuthToken:e.ambientDaemonAuthToken}:{canAuthenticate:!1}}function Ve(e,t,n){try{let{profile:r}=ne({configPath:e.remoteConfigPath,cwd:t,env:n});return r.daemonAuthToken&&He(e,r.daemonBaseUrl)?r.daemonAuthToken:void 0}catch{return}}function He(e,t){let n=j({daemonBaseUrl:t})?.baseUrl;return n!==void 0&&n===e.daemon?.baseUrl}async function Ue(e,t,n){if(!t.leaseId)return;let r=Be({previous:t,nextDaemonBaseUrl:n.nextDaemonBaseUrl,ambientDaemonAuthToken:n.ambientDaemonAuthToken,cwd:n.cwd,env:n.env});if(!r.canAuthenticate)return Y(t,`no credential known to belong to that endpoint was available`);try{await J(e,t,r.daemonAuthToken);return}catch{return Y(t,`the release request failed`)}}function Y(e,t){return{status:`unreleased`,message:`Could not release the previous lease ${e.leaseId} (tenant ${e.tenant}, run ${e.runId}) at ${e.daemon?.baseUrl??`its daemon`}: ${t}. It was left in place — release it manually if it is still active.`}}async function We(e,t,n){if(n)try{await e.leases.release({tenant:t.tenant,runId:t.runId,leaseId:n.leaseId,leaseBackend:t.leaseBackend??n.backend,leaseProvider:t.leaseProvider??n.leaseProvider,clientId:t.clientId??n.clientId,deviceKey:t.deviceKey??n.deviceKey})}catch{}}function X(e){if(e.leaseBackend)return e.leaseBackend;if(e.platform===`android`)return`android-instance`;if(e.platform===`ios`)return`ios-instance`}function Ge(t,n){let r=X(t);if(r)return r;throw new e(`INVALID_ARGS`,`${n} requires --platform ios|android or --lease-backend when the remote connection has not resolved a lease yet.`)}function Ke(e,t,n,r=[]){return e===`cdp`?O(r)&&!!t.metroPublicBaseUrl:K.has(e)?!0:e!==`batch`||!n?!1:n.some(e=>{let t=e.command.trim().toLowerCase();return K.has(t)&&e.runtime===void 0})}function Z(e){let t=e.metroKind;return!!(e.metroPublicBaseUrl||e.metroProxyBaseUrl||e.metroProjectRoot||t)}function Q(e,t){return!e.platform||!t||t!==`ios`&&t!==`android`?!0:e.platform===t}function qe(e,t){return e?.projectRoot===t?.projectRoot&&e?.profileKey===t?.profileKey&&e?.consumerKey===t?.consumerKey}function Je(e,t){if(e)return Q(e,t)?e:void 0}function Ye(t,n,r={}){if(!t.tenant)throw new e(`INVALID_ARGS`,`remote command requires tenant in remote config or via --tenant <id>.`);if(!t.runId)throw new e(`INVALID_ARGS`,`remote command requires runId in remote config or via --run-id <id>.`);if(!t.daemonBaseUrl&&U(r.leaseProvider))throw new e(`INVALID_ARGS`,`remote command requires daemonBaseUrl in remote config, config, env, or --daemon-base-url.`);let i=new Date().toISOString();return{version:1,session:t.session??`default`,remoteConfigPath:n,remoteConfigHash:N(n),daemon:j(t),tenant:t.tenant,runId:t.runId,leaseId:t.leaseId,leaseBackend:t.leaseBackend??X(t),leaseProvider:r.leaseProvider,clientId:r.clientId,deviceKey:r.deviceKey,platform:t.platform,target:t.target,connectedAt:i,updatedAt:i}}async function Xe(e,t,n,r,i){if(t.leaseId&&t.leaseBackend===n){let i=await nt(e,t.leaseId,{tenant:t.tenant,runId:t.runId,leaseBackend:n,leaseProvider:t.leaseProvider,clientId:t.clientId,deviceKey:t.deviceKey,ttlMs:r.ttlMs(t)});if(i)return{lease:i,acquired:!1}}return{lease:await e.leases.allocate({tenant:t.tenant,runId:t.runId,leaseBackend:n,leaseProvider:t.leaseProvider,clientId:t.clientId,deviceKey:t.deviceKey,ttlMs:r.ttlMs(t),platform:t.platform??i.platform,target:t.target??i.target,device:i.device,udid:i.udid,serial:i.serial,providerApp:i.providerApp,providerOsVersion:i.providerOsVersion,providerProject:i.providerProject,providerBuild:i.providerBuild,providerSessionName:i.providerSessionName,...W(i),awsProjectArn:i.awsProjectArn,awsDeviceArn:i.awsDeviceArn,awsAppArn:i.awsAppArn,awsRegion:i.awsRegion,awsInteractionMode:i.awsInteractionMode}),acquired:!0}}async function Ze(t){if(!Te.has(t.command)){if(t.state.leaseId&&t.state.deviceKey)return{state:t.state};throw new e(`INVALID_ARGS`,`No active proxy device lease for this session; run open first.`)}let n=await Qe(t.client,t.flags),r=$e(n);return{state:{...t.state,deviceKey:r,leaseBackend:t.state.leaseBackend??t.leaseBackend??et(n),platform:t.state.platform??n.platform,target:t.state.target??n.target,updatedAt:new Date().toISOString()},device:n}}function $(e,t){if(e.platform=t.platform,e.target=t.target??e.target,i(t)){e.udid=t.id;return}t.platform===`android`&&(e.serial=t.id)}async function Qe(e,t){return await r((await e.devices.list({platform:t.platform,target:t.target,device:t.device,udid:t.udid,serial:t.serial,iosSimulatorDeviceSet:t.iosSimulatorDeviceSet,androidDeviceAllowlist:t.androidDeviceAllowlist})).map(e=>({...n(e.platform),id:e.id,name:e.name,kind:e.kind,target:e.target,booted:e.booted})),{platform:t.platform,target:t.target,deviceName:t.device,udid:t.udid,serial:t.serial})}function $e(e){return`${t(e)}:${e.target??`mobile`}:${e.id}`}function et(e){if(i(e))return`ios-instance`;if(e.platform===`android`)return`android-instance`}function tt(t,n,r){if(t.leaseBackend&&t.leaseBackend!==r)throw new e(`INVALID_ARGS`,`Active remote connection is already bound to a different lease backend. Re-run connect --force to replace it.`,{session:t.session,leaseBackend:t.leaseBackend});if(t.platform&&n.platform&&t.platform!==n.platform)throw new e(`INVALID_ARGS`,`Active remote connection is already bound to a different platform. Re-run connect --force to replace it.`,{session:t.session,platform:t.platform});if(t.target&&n.target&&t.target!==n.target)throw new e(`INVALID_ARGS`,`Active remote connection is already bound to a different target. Re-run connect --force to replace it.`,{session:t.session,target:t.target})}async function nt(e,t,n){try{return await e.leases.heartbeat({tenant:n.tenant,runId:n.runId,leaseId:t,leaseBackend:n.leaseBackend,leaseProvider:n.leaseProvider,clientId:n.clientId,deviceKey:n.deviceKey,ttlMs:n.ttlMs})}catch(e){if(rt(e))return;throw e}}function rt(t){return!(t instanceof e)||t.code!==`UNAUTHORIZED`?!1:t.details?.reason===`LEASE_NOT_FOUND`||t.details?.reason===`LEASE_EXPIRED`||t.details?.reason===`LEASE_REVOKED`}export{A as C,E as D,T as E,le as S,D as T,de as _,X as a,k as b,W as c,Ce as d,U as f,j as g,be as h,J as i,we as l,V as m,Ee as n,q as o,xe as p,Ue as r,ze as s,Z as t,Se as u,N as v,ce as w,M as x,I as y};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{_ as e}from"./sdk-contracts.js";import{
|
|
1
|
+
import{_ as e}from"./sdk-contracts.js";import{Gn as t}from"./sdk-batch-runner.js";import{h as n,v as r}from"./sdk-android-adb.js";import i from"node:path";import a from"node:fs/promises";const o=/^[0-9a-fA-F-]{32,36}$/;function s(e){if(!(!e||!o.test(e)))return e.replaceAll(`-`,``).toUpperCase()}function c(e,t){return`${e.uuid}:${l(t)}`}function l(e){return`0x${e.toString(16)}`}function u(e){return typeof e==`string`&&e.length>0?e:void 0}function d(...e){for(let t of e){let e=u(t);if(e)return e}}function f(e){let t=e.filter(e=>!!e);return t.length>0?t.join(` `):void 0}function p(e){try{let n=JSON.parse(e);return t(n)?n:null}catch{return null}}function m(e){if(typeof e==`number`&&Number.isSafeInteger(e))return e;if(typeof e==`string`){let t=e.startsWith(`0x`)?Number.parseInt(e,16):Number(e);return Number.isSafeInteger(t)?t:void 0}}function h(e,t,n){if(!Object.hasOwn(e,t))return;let r=m(e[t]);if(r!==void 0)return r;v(n,t)}function g(e,t,n){if(!Object.hasOwn(e,t))return;let r=_(e[t]);if(r!==void 0)return r;v(n,t)}function _(e){if(typeof e==`bigint`)return e;if(typeof e==`number`&&Number.isSafeInteger(e)||typeof e==`string`&&/^(?:0x[0-9a-fA-F]+|\d+)$/.test(e))return BigInt(e)}function v(t,n){throw new e(`INVALID_ARGS`,`Invalid ${t} numeric field: ${n}`,{hint:`Crash artifact numeric fields must be integer numbers or integer numeric strings.`})}function y(e){return e.length===1?e[0]:void 0}function b(e){return[...new Set(e)]}function x(e){let t=e.match(/^(.*) \+ (\d+)$/);return t?{symbol:t[1],location:Number(t[2])}:{symbol:e}}const S=/^(?:arm64e?|arm64_32|x86_64|armv7[sk]?|i386)$/;function ee(e){return te(e)??w(e)}function te(e){let t=ne(e);if(!t)return null;let n=(Array.isArray(t.payload.usedImages)?t.payload.usedImages:[]).flatMap((e,t)=>C(e,t));if(n.length===0)return null;let r=re(Array.isArray(t.payload.threads)?t.payload.threads:[],n);return{format:`ips`,images:n,addresses:r.map(({frame:e,...t})=>t),document:t,frameMatches:r,write:e=>oe(t,r,e)}}function ne(e){let t=p(e);if(t)return{payload:t};let n=e.indexOf(`
|
|
2
2
|
`);if(n===-1)return null;let r=e.slice(0,n),i=p(e.slice(n+1));return i?{header:r,payload:i}:null}function re(e,t){let n=new Map(t.map(e=>[e.index,e]));return e.flatMap((e,t)=>ie(e).flatMap((e,r)=>ae(e,n,t,r)))}function ie(e){return!t(e)||!Array.isArray(e.frames)?[]:e.frames.filter(t)}function ae(e,t,n,r){let i=h(e,`imageIndex`,`IPS frame`),a=g(e,`imageOffset`,`IPS frame`);if(i===void 0||a===void 0)return[];let o=t.get(i);return o?[{frame:e,frameIndex:r,threadIndex:n,image:o,address:o.base+a}]:[]}function oe(e,t,n){for(let e of t){let t=n.get(c(e.image,e.address))?.text;t&&se(e.frame,t)}e.payload.agentDeviceSymbolication={tool:`agent-device debug symbols`,symbolicatedFrames:[...n.values()].filter(e=>e.text).length};let r=`${JSON.stringify(e.payload,null,2)}\n`;return e.header?`${e.header}\n${r}`:r}function se(e,t){let n=x(t);e.symbol=n.symbol,n.location!==void 0&&(e.symbolLocation=n.location)}function C(e,n){if(!t(e))return[];let r=s(u(e.uuid)),a=g(e,`base`,`IPS usedImages`);if(!r||a===void 0)return[];let o=u(e.path);return[{index:n,name:u(e.name)??(o?i.basename(o):`image-${n}`),uuid:r,arch:u(e.arch),base:a,path:o}]}function w(e){let t=e.split(`
|
|
3
3
|
`),n=T(t);if(n.length===0)return null;let r=O(t,n);return{format:`text`,images:n,addresses:r,lines:t,frameMatches:r,write(e){let n=new Map(r.map(e=>[e.lineIndex,e]));return t.map((t,r)=>{let i=n.get(r);if(!i)return t;let a=e.get(c(i.image,i.address))?.text;return!a||t.includes(a)?t:`${t} // ${a}`}).join(`
|
|
4
|
-
`)}}}function T(e){let t=[],n=e.findIndex(e=>/^Binary Images:/i.test(e.trim()));if(n===-1)return t;for(let r of e.slice(n+1)){let e=E(r);e&&t.push(e)}return t}function E(e){let t=e.match(/^\s*(0x[0-9a-fA-F]+)\s*-\s*(0x[0-9a-fA-F]+)\s+\+?(.+?)\s+<([0-9a-fA-F-]{32,36})>\s+(.+)$/);if(!t)return null;let n=s(t[4]);if(!n)return null;let r=D(t[3].trim(),t[5].trim());return{name:r.name,arch:r.arch,uuid:n,base:BigInt(t[1]),end:BigInt(t[2]),path:t[5].trim()}}function D(e,t){let n=e.split(/\s+/),r=n.at(-1);if(r&&S.test(r))return{name:n.slice(0,-1).join(` `).trim(),arch:r};let a=i.basename(t);return{name:e.startsWith(a)?a:e}}function O(e,t){let n=[],r;for(let[i,a]of e.entries()){let e=a.match(/^Thread\s+(\d+)\s+Crashed:/);e?r=Number(e[1]):(a.trim().length===0||/^Thread\s+\d+/.test(a))&&(r=void 0);let o=k(a,t),s=a.match(/^\s*(\d+)/);o&&s&&n.push({...o,frameIndex:Number(s[1]),lineIndex:i,threadIndex:r})}return n}function k(e,t){let n=e.match(/^\s*\d+\s+(.+?)\s+(0x[0-9a-fA-F]+)\b/);if(!n)return null;let r=n[1].trim(),i=BigInt(n[2]),a=A(t,r,i);return a?{image:a,address:i}:null}function A(e,t,n){let r=e.filter(e=>e.name===t);return r.find(e=>j(e,n))??y(r)}function j(e,t){return e.end!==void 0&&e.base<=t&&t<=e.end}const M=1e4;async function N(e){return e.dsym&&e.searchPath?[H(e.cwd,e.dsym),...await P(H(e.cwd,e.searchPath))]:e.dsym?[H(e.cwd,e.dsym)]:e.searchPath?await P(H(e.cwd,e.searchPath)):[]}async function P(t){let n=[],r=0;async function o(s){if(n.length>=200)return;if(r+=1,r>M)throw new e(`COMMAND_FAILED`,`debug symbols search-path scan exceeded bounds.`,{searchPath:t,maxEntries:M,hint:`Pass --dsym <App.dSYM> directly or narrow --search-path to the build products directory.`});if(!(await F(s,t)).isDirectory()){s===t&&I(t);return}if(s.endsWith(`.dSYM`)){n.push(s);return}let c=await a.readdir(s,{withFileTypes:!0});for(let e of c)e.isDirectory()&&await o(i.join(s,e.name))}return await o(t),n}async function F(t,n){try{return await a.stat(t)}catch{throw new e(`INVALID_ARGS`,`debug symbols search path does not exist: ${n}`,{hint:`Pass an existing build products directory to --search-path, or pass --dsym <App.dSYM> directly.`})}}function I(t){throw new e(`INVALID_ARGS`,`debug symbols search path is not a directory: ${t}`,{hint:`Pass an existing build products directory to --search-path, or pass --dsym <App.dSYM> directly.`})}async function L(t,n){let r=(await Promise.all(b(t).map(e=>R(e,n)))).flat();if(r.length===0)throw new e(`COMMAND_FAILED`,`No UUIDs found in dSYM bundle.`,{hint:`Verify the path points to a built .dSYM bundle with DWARF contents.`});return r}async function R(e,t){return await z(e),B(e,
|
|
5
|
-
`).flatMap(t=>{let n=t.match(/^UUID:\s+([0-9a-fA-F-]{32,36})\s+\(([^)]+)\)\s+(.+)$/),r=s(n?.[1]);return n&&r?[{dsymPath:e,uuid:r,arch:n[2],binaryPath:n[3].trim()}]:[]})}function V(t,n,r){let i=new Map;for(let e of t){let t=n.find(t=>t.uuid===e.uuid&&(e.arch===void 0||t.arch===void 0||t.arch===e.arch));t&&i.set(e.uuid,{image:e,dsym:t})}if(i.size>0)return i;let a=b(t.map(e=>e.uuid)),o=b(n.map(e=>e.uuid));throw new e(`COMMAND_FAILED`,r?`dSYM UUID does not match any Apple image in the crash artifact.`:`No matching dSYM UUID found under search path.`,{artifactUuidCount:a.length,artifactUuidSample:a.slice(0,5),dsymUuidCount:o.length,dsymUuidSample:o.slice(0,5),hint:`Use dwarfdump --uuid <App.dSYM> and compare it with the crash Binary Images or usedImages UUID, then pass the matching dSYM/search path.`})}function H(e,t){return i.resolve(e,t)}function U(e,t){return e.format===`ips`?W(e.document,e.frameMatches,t):ve(e.lines,e.frameMatches,t)}function W(e,t,n){let r=me(e.payload),i={format:`ips`,...G(e),crashedThread:r,topFrames:_e(t,r,n),findings:[]};return{...i,findings:Y(i)}}function G(e){let t=e.payload,n=pe(e.header);return{appName:K(t,n),bundleId:ce(t,n),version:le(t,n),incident:ue(t,n),timestamp:de(t,n),exceptionType:fe(t.exception),exceptionCodes:he(t.exception),terminationReason:ge(t.termination)}}function K(e,t){return d(e.procName,t?.app_name,t?.name)}function ce(e,n){return d((t(e.bundleInfo)?e.bundleInfo:void 0)?.CFBundleIdentifier,n?.bundleID)}function le(e,n){return d((t(e.bundleInfo)?e.bundleInfo:void 0)?.CFBundleShortVersionString,n?.app_version)}function ue(e,t){return d(e.incident,t?.incident_id)}function de(e,t){return d(e.captureTime,t?.timestamp)}function fe(e){return t(e)?u(e.type):void 0}function pe(e){return e?p(e):null}function me(e){let n=m(e.faultingThread);if(n!==void 0)return n;let r=(Array.isArray(e.threads)?e.threads:[]).findIndex(e=>t(e)&&e.triggered===!0);return r===-1?void 0:r}function he(e){return t(e)?d(e.codes,e.rawCodes):void 0}function ge(e){if(t(e))return f([u(e.namespace),u(e.code),u(e.reason)])}function _e(e,t,n){return e.filter(e=>t===void 0||e.threadIndex===t).slice(0,5).map(e=>J(e.frameIndex,e.image,e.address,n))}function ve(e,t,n){let r=be(e),i={format:`text`,appName:ye(e),bundleId:q(e,`Identifier`),version:q(e,`Version`),incident:q(e,`Incident Identifier`),timestamp:q(e,`Date/Time`),exceptionType:q(e,`Exception Type`),exceptionCodes:q(e,`Exception Codes`),terminationReason:q(e,`Termination Reason`),crashedThread:r,topFrames:xe(t,r,n),findings:[]};return{...i,findings:Y(i)}}function ye(e){return q(e,`Process`)?.replace(/\s+\[\d+\]$/,``)}function q(e,t){let n=`${t}:`,r=e.find(e=>e.trimStart().startsWith(n));return r&&r.slice(r.indexOf(`:`)+1).trim()||void 0}function be(e){let t=q(e,`Triggered by Thread`),n=t?Number.parseInt(t,10):NaN;if(Number.isSafeInteger(n))return n;for(let t of e){let e=t.match(/^Thread\s+(\d+)\s+Crashed:/);if(e)return Number(e[1])}}function xe(e,t,n){return t===void 0?[]:e.filter(e=>e.threadIndex===t).slice(0,5).map(e=>J(e.frameIndex,e.image,e.address,n))}function J(e,t,n,r){return{index:e,image:t.name,address:l(n),symbol:r.get(c(t,n))?.text}}function Y(e){return[Se(e),e.exceptionType?`Exception: ${e.exceptionType}`:void 0,e.terminationReason?`Termination: ${e.terminationReason}`:void 0].filter(e=>!!e).slice(0,3)}function Se(e){let t=e.topFrames.find(e=>e.symbol);return t?`Start with ${t.symbol} in ${t.image}; it is the first symbolicated frame captured on the crashed thread.`:e.topFrames.length>0?`No symbolicated frame was found on the crashed thread; verify matching dSYMs for the top images.`:void 0}async function Ce(e,t,n){let r=new Map;for(let i of we(e,t).values())for(let e of await Te(n,i))r.set(c(e.image,e.address),e);return r}function we(e,t){let n=new Map;for(let r of e){let e=t.get(r.image.uuid);if(!e)continue;let i=`${r.image.uuid}:${e.dsym.binaryPath}`,a=n.get(i)??{...e,addresses:[]};a.addresses.push(r.address),n.set(i,a)}return n}async function Te(e,t){let i=b(t.addresses.map(l)),a=
|
|
4
|
+
`)}}}function T(e){let t=[],n=e.findIndex(e=>/^Binary Images:/i.test(e.trim()));if(n===-1)return t;for(let r of e.slice(n+1)){let e=E(r);e&&t.push(e)}return t}function E(e){let t=e.match(/^\s*(0x[0-9a-fA-F]+)\s*-\s*(0x[0-9a-fA-F]+)\s+\+?(.+?)\s+<([0-9a-fA-F-]{32,36})>\s+(.+)$/);if(!t)return null;let n=s(t[4]);if(!n)return null;let r=D(t[3].trim(),t[5].trim());return{name:r.name,arch:r.arch,uuid:n,base:BigInt(t[1]),end:BigInt(t[2]),path:t[5].trim()}}function D(e,t){let n=e.split(/\s+/),r=n.at(-1);if(r&&S.test(r))return{name:n.slice(0,-1).join(` `).trim(),arch:r};let a=i.basename(t);return{name:e.startsWith(a)?a:e}}function O(e,t){let n=[],r;for(let[i,a]of e.entries()){let e=a.match(/^Thread\s+(\d+)\s+Crashed:/);e?r=Number(e[1]):(a.trim().length===0||/^Thread\s+\d+/.test(a))&&(r=void 0);let o=k(a,t),s=a.match(/^\s*(\d+)/);o&&s&&n.push({...o,frameIndex:Number(s[1]),lineIndex:i,threadIndex:r})}return n}function k(e,t){let n=e.match(/^\s*\d+\s+(.+?)\s+(0x[0-9a-fA-F]+)\b/);if(!n)return null;let r=n[1].trim(),i=BigInt(n[2]),a=A(t,r,i);return a?{image:a,address:i}:null}function A(e,t,n){let r=e.filter(e=>e.name===t);return r.find(e=>j(e,n))??y(r)}function j(e,t){return e.end!==void 0&&e.base<=t&&t<=e.end}const M=1e4;async function N(e){return e.dsym&&e.searchPath?[H(e.cwd,e.dsym),...await P(H(e.cwd,e.searchPath))]:e.dsym?[H(e.cwd,e.dsym)]:e.searchPath?await P(H(e.cwd,e.searchPath)):[]}async function P(t){let n=[],r=0;async function o(s){if(n.length>=200)return;if(r+=1,r>M)throw new e(`COMMAND_FAILED`,`debug symbols search-path scan exceeded bounds.`,{searchPath:t,maxEntries:M,hint:`Pass --dsym <App.dSYM> directly or narrow --search-path to the build products directory.`});if(!(await F(s,t)).isDirectory()){s===t&&I(t);return}if(s.endsWith(`.dSYM`)){n.push(s);return}let c=await a.readdir(s,{withFileTypes:!0});for(let e of c)e.isDirectory()&&await o(i.join(s,e.name))}return await o(t),n}async function F(t,n){try{return await a.stat(t)}catch{throw new e(`INVALID_ARGS`,`debug symbols search path does not exist: ${n}`,{hint:`Pass an existing build products directory to --search-path, or pass --dsym <App.dSYM> directly.`})}}function I(t){throw new e(`INVALID_ARGS`,`debug symbols search path is not a directory: ${t}`,{hint:`Pass an existing build products directory to --search-path, or pass --dsym <App.dSYM> directly.`})}async function L(t,n){let r=(await Promise.all(b(t).map(e=>R(e,n)))).flat();if(r.length===0)throw new e(`COMMAND_FAILED`,`No UUIDs found in dSYM bundle.`,{hint:`Verify the path points to a built .dSYM bundle with DWARF contents.`});return r}async function R(e,t){return await z(e),B(e,n(await r(t,[`--uuid`,e],{timeoutMs:15e3,allowFailure:!0}),`Failed to inspect dSYM UUIDs: ${e}`,{hint:`Verify the dSYM bundle is valid and readable.`}).stdout)}async function z(t){if(!((await a.stat(t).catch(()=>null))?.isDirectory()&&t.endsWith(`.dSYM`)))throw new e(`INVALID_ARGS`,`Not a .dSYM bundle: ${t}`,{hint:`Pass the .dSYM bundle path, not the DWARF executable inside it.`})}function B(e,t){return t.split(`
|
|
5
|
+
`).flatMap(t=>{let n=t.match(/^UUID:\s+([0-9a-fA-F-]{32,36})\s+\(([^)]+)\)\s+(.+)$/),r=s(n?.[1]);return n&&r?[{dsymPath:e,uuid:r,arch:n[2],binaryPath:n[3].trim()}]:[]})}function V(t,n,r){let i=new Map;for(let e of t){let t=n.find(t=>t.uuid===e.uuid&&(e.arch===void 0||t.arch===void 0||t.arch===e.arch));t&&i.set(e.uuid,{image:e,dsym:t})}if(i.size>0)return i;let a=b(t.map(e=>e.uuid)),o=b(n.map(e=>e.uuid));throw new e(`COMMAND_FAILED`,r?`dSYM UUID does not match any Apple image in the crash artifact.`:`No matching dSYM UUID found under search path.`,{artifactUuidCount:a.length,artifactUuidSample:a.slice(0,5),dsymUuidCount:o.length,dsymUuidSample:o.slice(0,5),hint:`Use dwarfdump --uuid <App.dSYM> and compare it with the crash Binary Images or usedImages UUID, then pass the matching dSYM/search path.`})}function H(e,t){return i.resolve(e,t)}function U(e,t){return e.format===`ips`?W(e.document,e.frameMatches,t):ve(e.lines,e.frameMatches,t)}function W(e,t,n){let r=me(e.payload),i={format:`ips`,...G(e),crashedThread:r,topFrames:_e(t,r,n),findings:[]};return{...i,findings:Y(i)}}function G(e){let t=e.payload,n=pe(e.header);return{appName:K(t,n),bundleId:ce(t,n),version:le(t,n),incident:ue(t,n),timestamp:de(t,n),exceptionType:fe(t.exception),exceptionCodes:he(t.exception),terminationReason:ge(t.termination)}}function K(e,t){return d(e.procName,t?.app_name,t?.name)}function ce(e,n){return d((t(e.bundleInfo)?e.bundleInfo:void 0)?.CFBundleIdentifier,n?.bundleID)}function le(e,n){return d((t(e.bundleInfo)?e.bundleInfo:void 0)?.CFBundleShortVersionString,n?.app_version)}function ue(e,t){return d(e.incident,t?.incident_id)}function de(e,t){return d(e.captureTime,t?.timestamp)}function fe(e){return t(e)?u(e.type):void 0}function pe(e){return e?p(e):null}function me(e){let n=m(e.faultingThread);if(n!==void 0)return n;let r=(Array.isArray(e.threads)?e.threads:[]).findIndex(e=>t(e)&&e.triggered===!0);return r===-1?void 0:r}function he(e){return t(e)?d(e.codes,e.rawCodes):void 0}function ge(e){if(t(e))return f([u(e.namespace),u(e.code),u(e.reason)])}function _e(e,t,n){return e.filter(e=>t===void 0||e.threadIndex===t).slice(0,5).map(e=>J(e.frameIndex,e.image,e.address,n))}function ve(e,t,n){let r=be(e),i={format:`text`,appName:ye(e),bundleId:q(e,`Identifier`),version:q(e,`Version`),incident:q(e,`Incident Identifier`),timestamp:q(e,`Date/Time`),exceptionType:q(e,`Exception Type`),exceptionCodes:q(e,`Exception Codes`),terminationReason:q(e,`Termination Reason`),crashedThread:r,topFrames:xe(t,r,n),findings:[]};return{...i,findings:Y(i)}}function ye(e){return q(e,`Process`)?.replace(/\s+\[\d+\]$/,``)}function q(e,t){let n=`${t}:`,r=e.find(e=>e.trimStart().startsWith(n));return r&&r.slice(r.indexOf(`:`)+1).trim()||void 0}function be(e){let t=q(e,`Triggered by Thread`),n=t?Number.parseInt(t,10):NaN;if(Number.isSafeInteger(n))return n;for(let t of e){let e=t.match(/^Thread\s+(\d+)\s+Crashed:/);if(e)return Number(e[1])}}function xe(e,t,n){return t===void 0?[]:e.filter(e=>e.threadIndex===t).slice(0,5).map(e=>J(e.frameIndex,e.image,e.address,n))}function J(e,t,n,r){return{index:e,image:t.name,address:l(n),symbol:r.get(c(t,n))?.text}}function Y(e){return[Se(e),e.exceptionType?`Exception: ${e.exceptionType}`:void 0,e.terminationReason?`Termination: ${e.terminationReason}`:void 0].filter(e=>!!e).slice(0,3)}function Se(e){let t=e.topFrames.find(e=>e.symbol);return t?`Start with ${t.symbol} in ${t.image}; it is the first symbolicated frame captured on the crashed thread.`:e.topFrames.length>0?`No symbolicated frame was found on the crashed thread; verify matching dSYMs for the top images.`:void 0}async function Ce(e,t,n){let r=new Map;for(let i of we(e,t).values())for(let e of await Te(n,i))r.set(c(e.image,e.address),e);return r}function we(e,t){let n=new Map;for(let r of e){let e=t.get(r.image.uuid);if(!e)continue;let i=`${r.image.uuid}:${e.dsym.binaryPath}`,a=n.get(i)??{...e,addresses:[]};a.addresses.push(r.address),n.set(i,a)}return n}async function Te(e,t){let i=b(t.addresses.map(l)),a=n(await r(e,Ee(t,i),{timeoutMs:3e4,allowFailure:!0}),`atos failed while symbolicating crash frames.`,{hint:`Verify the crash artifact and dSYM were produced from the same build and architecture.`});return De(t.image,i,a.stdout)}function Ee(e,t){return[`-arch`,e.image.arch??e.dsym.arch??`arm64`,`-o`,e.dsym.binaryPath,`-l`,l(e.image.base),...t]}function De(e,t,n){let r=Oe(n);return t.map((t,n)=>{let i=r[n]?.trim();return{image:e,address:BigInt(t),text:ke(i,t)?i:void 0}})}function Oe(e){let t=e.split(/\r?\n/);return t.at(-1)===``&&t.pop(),t}function ke(e,t){if(!e)return!1;let n=e.trim().toLowerCase();return!n||n===`??`||n===t.toLowerCase()?!1:!n.startsWith(`0x`)}async function Ae(){return{dwarfdump:await X(`dwarfdump`),atos:await X(`atos`)}}async function X(t){try{let e=await r(`xcrun`,[`--find`,t],{timeoutMs:5e3,allowFailure:!0}),n=e.stdout.trim();if(e.exitCode===0&&n.length>0)return n}catch{}throw new e(`TOOL_MISSING`,`Apple symbolication tool not found: ${t}`,{hint:`Install Xcode Command Line Tools and verify xcrun --find dwarfdump and xcrun --find atos succeed.`})}const Z=64*1024*1024;async function je(t){if(t.action!==void 0&&t.action!==`symbols`)throw new e(`INVALID_ARGS`,`debug supports only the symbols workflow.`,{hint:`Use debug symbols --artifact <crash.ips|crash.log> --dsym <App.dSYM> or --search-path <dir> --out <path>.`});let n=t.cwd??process.cwd(),r=$(n,t.artifact),o=$(n,t.out??Pe(r)),s=ee(await Me(r,`crash artifact`));s||Q();let c=await N({cwd:n,dsym:t.dsym,searchPath:t.searchPath});if(c.length===0)throw new e(`INVALID_ARGS`,`debug symbols requires --dsym or --search-path.`,{hint:`Pass a matching .dSYM bundle directly, or pass --search-path <dir> so agent-device can match crash image UUIDs to local dSYMs.`});let l=await Ae(),u=await L(c,l.dwarfdump),d=V(s.images,u,!!t.dsym),f=await Ce(s.addresses,d,l.atos),p=s.write(f);await a.mkdir(i.dirname(o),{recursive:!0}),await a.writeFile(o,p,`utf8`);let m=[...d.values()].map(({image:e,dsym:t})=>({name:e.name,uuid:e.uuid,arch:e.arch??t.arch,dsymPath:t.dsymPath,binaryPath:t.binaryPath})),h=[...f.values()].filter(e=>e.text).length,g=s.images.length-m.length,_=g>0?[`${g} Apple image${g===1?``:`s`} had no matching dSYM and were left unchanged.`]:void 0;return{kind:`debugSymbols`,platform:`apple`,artifactPath:r,outPath:o,crash:U(s,f),matchedImages:m,symbolicatedFrames:h,skippedImages:g,warnings:_,message:`Symbolicated ${h} frame${h===1?``:`s`} -> ${o}`}}function Q(){throw new e(`UNSUPPORTED_OPERATION`,`debug symbols currently supports Apple crash artifacts with Binary Images or IPS usedImages.`,{hint:`For Android Java/R8 crashes, use retrace with mapping.txt. For Android native crashes, use ndk-stack or addr2line with unstripped .so symbols. Capture the crash with logs, then symbolicate externally until Android support is added.`})}async function Me(t,n){await Ne(t,n);try{return await a.readFile(t,`utf8`)}catch(r){let i=r instanceof Error?r.message:String(r);throw new e(`INVALID_ARGS`,`Failed to read ${n}: ${t}`,{message:i})}}async function Ne(t,n){try{let r=await a.stat(t);if(r.size<=Z)return;throw new e(`INVALID_ARGS`,`${n} is too large: ${t}`,{actualBytes:r.size,maxBytes:Z,hint:`Pass a bounded Apple .ips/.crash artifact. For very large logs, first narrow the log to the crash report, or use logs grep/tail for lead-up context.`})}catch(r){if(r instanceof e)throw r;let i=r instanceof Error?r.message:String(r);throw new e(`INVALID_ARGS`,`Failed to read ${n}: ${t}`,{message:i})}}function $(e,t){return i.resolve(e,t)}function Pe(e){let t=i.extname(e);return`${t?e.slice(0,-t.length):e}-symbolicated${t||`.log`}`}export{je as symbolicateCrashArtifact};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e,g as t}from"./sdk-device.js";import{
|
|
1
|
+
import{a as e,g as t}from"./sdk-device.js";import{o as n}from"./host-process.js";import{n as r}from"./owner-identity.js";import i from"node:path";import a from"node:crypto";import o from"node:fs";import s from"node:os";function c(){let e=process.env.AGENT_DEVICE_CLAIMS_DIR?.trim();return e?i.resolve(e):i.join(s.homedir(),`.agent-device`,`device-claims`)}function l(e){let t=a.createHash(`sha256`).update(e).digest(`hex`);return i.join(c(),`${t}.json`)}function u(e){let t=c(),r=d(t);if(`claims`in r)return r.claims;let a=r.entries.filter(e=>e.isFile()&&e.name.endsWith(`.json`)).map(e=>_(i.join(t,e.name))).filter(e=>e!==null).filter(t=>f(t.claim,e)),o=n(a.flatMap(e=>e.claim?[e.claim.ownerPid]:[]));return a.map(e=>y(e,e.claim?o.get(e.claim.ownerPid)??null:null))}function d(e){try{return{entries:o.readdirSync(e,{withFileTypes:!0})}}catch(t){let n=t.code;return n===`ENOENT`||n===`ENOTDIR`?{claims:[]}:{claims:[{fileName:i.basename(e),classification:`unknown`,error:String(t)}]}}}function f(e,t){return e?[p(e,t.udid??t.serial),m(e,t.device),h(e,t.platform)].every(Boolean):!0}function p(e,t){return!t||e.device.id===t}function m(e,t){return!t||e.device.name===t||e.device.id===t}function h(n,r){return t({...e(n.device.platform),appleOs:n.device.appleOs},r)}function g(e){let t=_(e);return t?.claim?y(t,n([t.claim.ownerPid]).get(t.claim.ownerPid)??null):t}function _(e){let t=i.basename(e);try{return v(t,o.readFileSync(e,`utf8`))}catch(e){let n=e.code;return n===`ENOENT`||n===`ENOTDIR`?null:{fileName:t,classification:`unknown`,error:String(e)}}}function v(e,t){try{let n=b(JSON.parse(t));return n?{fileName:e,deviceKey:n.deviceKey,claim:n,classification:`unknown`}:{fileName:e,classification:`inconsistent`}}catch(t){return{fileName:e,classification:`inconsistent`,error:String(t)}}}function y(e,t){return e.claim?{...e,classification:r({owner:{pid:e.claim.ownerPid,startTime:e.claim.ownerStartTime},stateDir:e.claim.stateDir},t)}:e}function b(e){if(!x(e))return null;let t=e;return S(t)?t:null}function x(e){return!!e&&typeof e==`object`&&!Array.isArray(e)}function S(e){return e.schemaVersion===1&&C(e.device)&&[e.deviceKey,e.session,e.workspace,e.stateDir,e.ownerToken].every(w)&&T(e.ownerPid)&&E(e.createdAtMs)&&E(e.updatedAtMs)}function C(e){if(!x(e))return!1;let t=e;return[t.id,t.name,t.platform,t.kind].every(w)}function w(e){return typeof e==`string`&&e.length>0}function T(e){return typeof e==`number`&&Number.isInteger(e)&&e>0}function E(e){return typeof e==`number`&&Number.isFinite(e)}export{c as i,u as n,l as r,g as t};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{o as e}from"./png-worker-contract.js";import{_ as t}from"./sdk-contracts.js";import{
|
|
1
|
+
import{o as e}from"./png-worker-contract.js";import{_ as t}from"./sdk-contracts.js";import{at as n,it as r,ot as i,tt as a}from"./sdk-batch-runner.js";import{j as o,n as s,o as c}from"./sdk-android-adb.js";import{n as l}from"./shell-quote.js";import{t as u}from"./timeouts.js";import{r as d}from"./install-artifact.js";var f=e({dismissAndroidKeyboard:()=>y,dismissAndroidKeyboardWithAdb:()=>b,getAndroidKeyboardState:()=>_,getAndroidKeyboardStatusWithAdb:()=>v,readAndroidClipboardText:()=>j,readAndroidClipboardWithAdb:()=>M,writeAndroidClipboardText:()=>N,writeAndroidClipboardWithAdb:()=>P});const p=[`mInputShown`,`mIsInputViewShown`,`isInputViewShown`,`mDecorViewVisible`,`mWindowVisible`,`mInShowWindow`],m=new Map([[2,`number`],[3,`phone`],[4,`datetime`]]),h=new Set([32,208]),g=new Set([128,224,144]);async function _(e){return await v(c(e))}async function v(e){let t=await e([`shell`,`dumpsys`,`input_method`],{allowFailure:!0});if(t.exitCode!==0)throw s(`Failed to query Android keyboard state`,t);return x(t.stdout)}async function y(e){return await b(c(e))}async function b(e){let n=await v(e),r=n,i=0;for(;r.visible&&i<2;)await e([`shell`,`input`,`keyevent`,`111`]),i+=1,await u(120),r=await v(e);if(n.visible&&r.visible)throw new t(`UNSUPPORTED_OPERATION`,`Android keyboard dismiss is unavailable for the current IME without back navigation.`,{attempts:i,inputType:r.inputType,type:r.type,inputMethodPackage:r.inputMethodPackage,focusedPackage:r.focusedPackage,focusedResourceId:r.focusedResourceId,inputOwner:r.inputOwner});return{attempts:i,wasVisible:n.visible,dismissed:n.visible&&!r.visible,visible:r.visible,inputType:r.inputType,type:r.type,inputMethodPackage:r.inputMethodPackage,focusedPackage:r.focusedPackage,focusedResourceId:r.focusedResourceId,inputOwner:r.inputOwner}}function x(e){let t=E(e)??S(e),n=C(e),r=w(e,/\bpackageName=([A-Za-z0-9_.]+)\b/g),o=w(e,/\b(?:resourceId|resource-id)=([^\s,}]+)/g),s=i(e),c=a(r,o,s);return T(r,o,s),{visible:t??!1,inputType:n,type:n?A(n):void 0,inputMethodPackage:s,focusedPackage:r,focusedResourceId:o,inputOwner:c}}function S(e){let t=e.match(/\bmImeWindowVis=0x([0-9a-fA-F]+)\b/)?.[1];if(!t)return null;let n=Number.parseInt(t,16);return Number.isNaN(n)?null:(n&1)!=0}function C(e){let t=w(e,/\binputType=0x([0-9a-fA-F]+)\b/gi);return t?`0x${t.toLowerCase()}`:void 0}function w(e,t){let n;for(let r of e.matchAll(t))n=r[1];return n}function T(e,t,i){i||!r(e)&&!n(t)||o({level:`warn`,phase:`android_input_ownership_fallback`,data:{focusedPackage:e,focusedResourceId:t}})}function E(e){return O(D(e,p))}function D(e,t){let n=new Map,r=RegExp(`\\b(${t.join(`|`)})=([a-zA-Z]+)\\b`,`g`);for(let t of e.matchAll(r)){let e=t[1],r=t[2]?.toLowerCase();!e||r!==`true`&&r!==`false`||n.set(e,r===`true`)}return n}function O(e){if(e.size===0)return null;let t=k(e,[`mWindowVisible`,`mDecorViewVisible`,`mInShowWindow`]);if(t!==void 0)return t;let n=e.get(`mInputShown`);return n===void 0?k(e,[`mIsInputViewShown`,`isInputViewShown`])??null:n}function k(e,t){for(let n of t){let t=e.get(n);if(t!==void 0)return t}}function A(e){let t=Number.parseInt(e.replace(/^0x/i,``),16);if(Number.isNaN(t))return`unknown`;let n=t&15,r=m.get(n);if(r)return r;if(n!==1)return`unknown`;let i=t&4080;return h.has(i)?`email`:g.has(i)?`password`:`text`}async function j(e){return await M(c(e))}async function M(e){return I(await F(e,[`shell`,`cmd`,`clipboard`,`get`,`text`],`read`))}async function N(e,t){await P(c(e),t)}async function P(e,t){await F(e,[`shell`,`cmd`,`clipboard`,`set`,`text`,l(t)],`write`)}async function F(e,n,r){let i=await e(n,{allowFailure:!0});if(d(i.stdout,i.stderr))throw new t(`UNSUPPORTED_OPERATION`,`Android shell clipboard ${r} is not supported on this device.`);if(i.exitCode!==0)throw s(`Failed to ${r} Android clipboard text`,i);return i.stdout}function I(e){let t=e.replace(/\r\n/g,`
|
|
2
2
|
`).replace(/\n$/,``),n=t.match(/^clipboard text:\s*(.*)$/i);return n?n[1]??``:t.trim().toLowerCase()===`null`?``:t}export{j as a,P as c,v as i,b as n,M as o,_ as r,N as s,f as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{c as e}from"./sdk-device.js";import{E as t}from"./dispatch.js";import{N as n,n as r}from"./physical-device-control.js";const i=n({ttlMs:5e3});async function a(n,a={}){if(t(n))return;let c=s(n);if(i.get(c)===!0){if(!a.focusExisting)return;i.delete(c)}if(e(n)){if(n.kind===`simulator`){let{ensureBootedSimulator:e}=await import(`./simulator.js`).then(e=>e.a);await e(n,{deviceHub:a.deviceHub,focusExisting:a.focusExisting,onColdBootStart:a.onIosSimulatorColdBootStart}),o(c);return}if(n.kind===`device`){await r(n).ensureReady(n),o(c);return}}if(n.platform===`android`){let{waitForAndroidBoot:e}=await import(`./install-artifact.js`).then(e=>e.a);await e(n.id),o(c)}}function o(e){i.set(e,!0)}function s(e){let t=e.kind===`simulator`?e.simulatorSetPath??``:``;return JSON.stringify([e.platform,e.kind,e.id,e.target??``,t])}export{a as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as e}from"./sdk-contracts.js";import{A as t,Ft as n,M as r,N as i,P as a,dt as o,ft as s,j as c,p as l,st as u,w as d}from"./version.js";import{G as f,Y as ee,a as te,h as ne,s as p}from"./sdk-batch-runner.js";import{_ as m,b as re,c as h,h as ie,l as g,m as _,s as v,x as y,y as ae}from"./sdk-device.js";import{Gt as oe,Kt as se,Xt as b,_n as x,dt as ce,ft as le,gn as S,n as ue,pt as de,ut as C}from"./prepare-kind.js";import{A as fe}from"./screenshot-result.js";import{a as pe}from"./device.js";import{f as me}from"./runtime.js";import{I as he,j as w}from"./sdk-android-adb.js";import{t as ge}from"./timeouts.js";import{F as _e}from"./runner-disposal.js";import{H as ve,U as ye}from"./physical-device-control.js";import be from"node:path";import{AsyncLocalStorage as T}from"node:async_hooks";import xe,{promises as Se}from"node:fs";let Ce=[];const E=new T;async function we(e,t){return await E.run([...e],t)}function Te(e,t){for(let n of O()){if(!n.ownsDevice(e))continue;let r=n.getInteractor(e,t);if(r)return r}}function D(e){return O().some(t=>t.ownsDevice(e))}async function Ee(e,t,n,r){for(let i of O()){if(!i.ownsDevice(e))continue;if(!i.installApp)throw j(i,e,`install`);let a=await i.installApp?.(e,t,n,r);if(a)return a;throw j(i,e,`install`)}}async function De(e,t,n){for(let r of O()){if(!r.ownsDevice(e))continue;if(!r.installInstallablePath)throw j(r,e,`install_from_source`);let i=await r.installInstallablePath?.(e,t,n);if(i)return i;throw j(r,e,`install_from_source`)}}async function Oe(e){for(let t of O()){if(!A(t,e.provider))continue;let n=await t.configurePortReverse?.(e);if(n)return n}}function O(){return E.getStore()??Ce}function ke(e,t={}){ze(e);let n=e.map(e=>e.provider);return{providerRuntimeIds:n,providerRuntimeRequiredIds:Fe([...n,...t.providerRuntimeRequiredIds??[]]),leaseLifecycleProvider:Ie(e),recoverableProviderIds:e.filter(e=>e.recoverExpiredLease!==void 0).map(e=>e.provider),recoverExpiredLease:Pe(e),cloudArtifactProvider:Le(e),deviceInventorySource:Re(e),appleRunnerProvider:je(e),appleRunnerScreenRecordingTransport:Ae(e),providerDeviceRuntimeScope:async t=>await we(e,t)}}function Ae(e){if(e.some(Ne))return t=>{for(let n of e){if(!Ne(n)||!n.ownsDevice(t.device))continue;let e=n.getAppleRunnerScreenRecordingTransport(t.device);if(e)return e}}}function je(e){if(e.some(Me))return t=>{for(let n of e){if(!Me(n)||!n.ownsDevice(t.device))continue;let e=n.getAppleRunnerProvider(t.device);if(e)return e}}}function Me(e){return`getAppleRunnerProvider`in e&&typeof e.getAppleRunnerProvider==`function`}function Ne(e){return`getAppleRunnerScreenRecordingTransport`in e&&typeof e.getAppleRunnerScreenRecordingTransport==`function`}function Pe(t){if(t.some(e=>e.recoverExpiredLease!==void 0))return async n=>{let r=t.find(e=>A(e,n.leaseProvider));if(!r?.recoverExpiredLease)throw new e(`UNSUPPORTED_OPERATION`,`Provider ${n.leaseProvider??`unknown`} cannot recover an expired lease.`,{provider:n.leaseProvider,leaseId:n.leaseId});await r.recoverExpiredLease(n)}}function Fe(e){return[...new Set(e)]}function Ie(e){if(e.length!==0)return{allocate:async(t,n)=>await k(e,`allocate`,t,n),heartbeat:async(t,n)=>await k(e,`heartbeat`,t,n),release:async(t,n)=>await k(e,`release`,t,n)}}function Le(e){if(e.length!==0)return{listCloudArtifacts:async t=>await Be(e,t)}}function Re(e){if(e.length!==0)return{discover:async(t,n)=>{n.throwIfAborted();for(let r of e){if(!A(r,t.leaseProvider))continue;let e=await r.deviceInventoryProvider(t,n);if(n.throwIfAborted(),e!=null)return{kind:`inventory`,devices:e}}return{kind:`declined`}}}}function ze(e){let t=new Set;for(let n of e){if(t.has(n.provider))throw TypeError(`Duplicate provider device runtime: ${n.provider}`);t.add(n.provider)}}async function Be(e,t){for(let n of e){if(!A(n,t.provider))continue;let e=await n.cloudArtifacts?.listCloudArtifacts?.(t);if(e)return e}}async function k(e,t,n,r){for(let i of e){if(!A(i,n.leaseProvider))continue;let e=i.leaseLifecycle[t],a=e?await e(n,r):void 0;if(a)return a}}function A(e,t){return e.provider===t}function j(t,n,r){throw new e(`UNSUPPORTED_OPERATION`,`Provider device runtime ${t.provider} does not support ${r} for this device.`,{provider:t.provider,deviceId:n.id,platform:m(n)})}const Ve=`device_inventory_context_unavailable`,He=new T;async function Ue(e,t){return await He.run(e,t)}async function We(e){return await qe(`providerFirst`,e)}async function Ge(e){let t=Je(),n=await t.providerFirst.discoverWithSource(e,t.requestScope);return{devices:n.devices.map(e=>({...e})),source:n.source}}async function Ke(e){return await qe(`localOnly`,e)}async function qe(e,t){let n=Je();return(await n[e].discover(t,n.requestScope)).map(e=>({...e}))}function Je(){let t=He.getStore();if(!t)throw new e(`COMMAND_FAILED`,`Device inventory gateway is unavailable outside request execution`,{reason:Ve});return t}function Ye(t){return _e(t)||t instanceof e&&t.code===`COMMAND_FAILED`&&t.details?.reason===Ve?!0:t instanceof Error&&t.name===`AbortError`}const M=new T;async function Xe(t,n,r){let i=await Ze(t,n,r);if(i)return i;let a=await $e(t,n,r);if(r.allowLocalSimulatorFallback!==!1&&tt(n,a)){let e;try{[e]=await Ke({platform:n.platform??`ios`,target:n.target,iosSimulatorSetPath:r.simulatorSetPath,kind:`simulator`})}catch(e){if(Ye(e))throw e}if(e)return e}if(a)return a;throw new e(`DEVICE_NOT_FOUND`,`No devices found`,{selector:n})}async function Ze(t,n,r){let i=r.appleSimulatorAppTarget?.trim();if(!i||N(n)||r.allowLocalSimulatorFallback===!1)return;let a=t.filter(e=>ie(e,n)&&h(e)&&e.kind===`simulator`&&e.booted===!0);if(a.length<2)return;let{findIosSimulatorInstalledApp:o}=await import(`./apps.js`).then(e=>e.t),s=(await Promise.all(a.map(async e=>await o(e,i)?e:void 0))).filter(e=>e!==void 0);if(s.length===1)return s[0];throw s.length===0?new e(`APP_NOT_INSTALLED`,`No booted iOS simulator has ${i} installed`,{appTarget:i,...Qe(a),hint:`Install the app on a booted simulator, or pass --udid to select the intended device explicitly.`}):new e(`AMBIGUOUS_MATCH`,`Multiple booted iOS simulators have ${i} installed`,{appTarget:i,...Qe(s),hint:`Pass --udid to select the intended simulator explicitly.`})}function Qe(e){return{devices:e.map(e=>({id:e.id,name:e.name}))}}async function $e(e,t,n){try{return await re(e,t,n)}catch(e){if(et(e,t))return;throw e}}function et(t,n){return!N(n)&&t instanceof e&&t.code===`DEVICE_NOT_FOUND`}function tt(e,t){return!N(e)&&(!e.platform||e.platform===`apple`||e.platform===`ios`)&&e.target!==`desktop`&&(!t||t.kind===`device`)}function N(e){return!!(e.udid||e.serial||e.deviceName)}async function nt(e,t={}){let n=rt(e),{iosSimulatorSetPath:r,...i}=n,a=lt(n,t),o={simulatorSetPath:r,allowStoppedAndroidAvdPlaceholders:t.allowStoppedAndroidAvdPlaceholders},s={platform:n.platform,target:e.target,cacheHit:!1};return await he(`resolve_target_device`,async()=>{let e=st(a);if(e)return s.cacheHit=!0,e;let c=await Ge(n),l=[...c.devices];return ot(i)?ct(a,await Xe(l,i,{simulatorSetPath:r,allowLocalSimulatorFallback:c.source===`local`||n.leaseProvider===void 0,appleSimulatorAppTarget:t.appleSimulatorAppTarget})):ct(a,await re(l,i,o))},s)}function rt(t){let n=t.platform;if(t.target&&!n)throw new e(`INVALID_ARGS`,`Device target selector requires --platform. Use --platform ios|macos|android|vega|linux|apple with --target mobile|tv|desktop.`);let r=ae({simulatorSetPath:ye(t.iosSimulatorDeviceSet),platform:n,target:t.target}),i=ve(t.androidDeviceAllowlist);return{platform:n,target:t.target,deviceName:t.device,udid:t.udid,serial:t.serial,leaseId:t.leaseId,leaseProvider:t.leaseProvider,deviceKey:t.deviceKey,clientId:t.clientId,iosSimulatorSetPath:r,androidSerialAllowlist:i?Array.from(i).sort():void 0}}async function it(e){return M.getStore()?await e():await M.run(new Map,e)}function at(e){return v(e.platform)}function ot(e){return at(e)}function st(e){let t=M.getStore()?.get(e);if(t)return{...t}}function ct(e,t){return M.getStore()?.set(e,{...t}),t}function lt(e,t){let{appleSimulatorAppTarget:n,...r}=t;return JSON.stringify({request:e,options:r})}const P=new Map;function ut(e){for(let t of e.platforms){if(P.has(t))throw Error(`PlatformPlugin already registered for platform "${t}"`);P.set(t,e)}}function dt(t){let n=P.get(t);if(!n)throw new e(`UNSUPPORTED_PLATFORM`,`Unsupported platform: ${t}`);return n}function F(e){return P.get(e)}const I={appAndDeviceLifecycle:!0,keyboard:!0,orientation:!0,physicalDeviceSurfaces:!1},ft={ios:I,ipados:I,visionos:{appAndDeviceLifecycle:!0,keyboard:!0,orientation:!0,physicalDeviceSurfaces:!1},tvos:{appAndDeviceLifecycle:!0,keyboard:!1,orientation:!1,physicalDeviceSurfaces:!1},macos:{appAndDeviceLifecycle:!1,keyboard:!1,orientation:!1,physicalDeviceSurfaces:!0},watchos:{appAndDeviceLifecycle:!1,keyboard:!1,orientation:!1,physicalDeviceSurfaces:!1}};function L(e){return v(e.platform)?ft[y(e)]:void 0}const R=e=>{let t=L(e);return t?t.appAndDeviceLifecycle:!0},z=e=>e.platform!==`apple`||e.kind!==`device`||e.iosPhysicalDeviceBackend!==`xctest`,B=e=>R(e)&&z(e),pt=e=>{let t=L(e);return t?t.keyboard:e.platform===`android`},mt=e=>{let t=L(e);return t?t.orientation:e.platform===`android`},V=e=>{let t=L(e);return t&&t.physicalDeviceSurfaces||e.kind===`simulator`},ht=e=>e.platform===`android`||e.platform===`apple`&&y(e)===`ios`||V(e),gt=e=>e.platform===`android`?e.target===`tv`:_(e),_t={[b.boot]:R,[b.apps]:z,[b.install]:B,[b.reinstall]:B,[b.installFromSource]:B,[b.perf]:z,[b.push]:R,[b.home]:R,[b.appSwitcher]:R,[b.clipboard]:e=>e.platform===`android`||e.platform===`linux`||V(e),[b.keyboard]:pt,[b.orientation]:mt,[b.tvRemote]:gt,[b.alert]:ht,[b.settings]:e=>e.platform===`android`||V(e),[b.audio]:f},vt={[b.apps]:H,[b.install]:H,[b.reinstall]:H,[b.installFromSource]:H,[b.perf]:H,[b.viewport]:e=>e.platform===`apple`?`viewport resizes web targets only (--platform web). Apple screen geometry is fixed by the selected simulator or device type — open a different simulator to test another screen size.`:void 0,[b.tvRemote]:e=>e.platform===`android`?e.target===`tv`?void 0:`tv-remote is supported only on Android TV targets.`:L(e)?_(e)?void 0:`tv-remote is supported only on tvOS devices.`:void 0};function H(e){if(!z(e))return`This command requires a CoreDevice-backed physical iOS device. The selected XCTest backend supports open, close, interactions, snapshots, and screenshots.`}const yt={id:`apple`,platforms:[`apple`],familySelector:`apple`,capability:{bucket:`apple`,supportsByDefault:_t,unsupportedHintByDefault:vt},perf:{supportsMetrics:()=>!0,metricsSamplerTag:()=>`apple`},providers:{platformGatedResolvers:[`appleRunnerProvider`,`appleToolProvider`]},createInteractor:async(e,t)=>{let{createAppleInteractor:n}=await import(`./interactor.js`);return n(e,t)}},bt=[b.open,b.close,b.back,b.home,b.tvRemote],xt=e=>e.target===`tv`,St=e=>e.kind===`emulator`&&xt(e),Ct={id:`vega`,platforms:[`vega`],capability:{bucket:`vega`,supportsByDefault:Object.fromEntries(bt.map(e=>[e,xt])),unsupportedHintByDefault:Object.fromEntries(bt.map(e=>[e,t=>St(t)?void 0:`${e} currently supports only Vega Virtual Devices.`]))},providers:{platformGatedResolvers:[`vegaToolProvider`]},createInteractor:async(e,t)=>{let{createVegaInteractor:n}=await import(`./interactor2.js`);return n(e,t)}},wt=[yt,{id:`android`,platforms:[`android`],capability:{bucket:`android`,supportsByDefault:{[b.audio]:f,[b.tvRemote]:e=>e.target===`tv`},unsupportedHintByDefault:{[b.tvRemote]:e=>e.target===`tv`?void 0:`tv-remote is supported only on Android TV targets.`}},perf:{supportsMetrics:()=>!0,metricsSamplerTag:()=>`android`},providers:{platformGatedResolvers:[`androidAdbProvider`]},createInteractor:async(e,t)=>{let{createAndroidInteractor:n}=await import(`./android.js`).then(e=>e.t);return n(e,void 0,t)}},{id:`harmonyos`,platforms:[`harmonyos`],capability:{bucket:`harmonyos`},perf:{supportsMetrics:()=>!0,metricsSamplerTag:()=>`harmonyos`},createInteractor:async(e,t)=>{let{createHarmonyInteractor:n}=await import(`./harmonyos.js`);return n(e,t)}},Ct,{id:`linux`,platforms:[`linux`],capability:{bucket:`linux`},providers:{platformGatedResolvers:[`linuxToolProvider`]},createInteractor:async()=>{let{createLinuxInteractor:e}=await import(`./linux.js`);return e()}},{id:`web`,platforms:[`web`],capability:{bucket:`web`},providers:{platformGatedResolvers:[`webProvider`]},createInteractor:async()=>{let{createWebInteractor:e}=await import(`./web.js`);return e()}}];let Tt=!1;function U(){if(!Tt){for(let e of wt)ut(e);Tt=!0}}U();const Et={device:!0},Dt={emulator:!0,device:!0},Ot=new Set(`open.perf.close.back.apps.appstate.app-switcher.click.fill.find.focus.get.home.gesture.install.keyboard.is.longpress.press.reinstall.screenshot.scroll.settings.snapshot.swipe.type.wait`.split(`.`)),kt=[`open`,`close`],At=[`audio`,`find`,`get`,`is`,`screenshot`,`snapshot`,`wait`],jt=[`click`,`fill`,`focus`,`press`,`scroll`,`type`],Mt=[`viewport`],Nt=new Set([...kt,...At,...jt,...Mt]),Pt=Ft(te(ne));function Ft(e){let t={};for(let[n,r]of Object.entries(e))t[n]=Ot.has(n)?{...r,harmonyos:Dt}:r;return It(t)}function It(e){let t={};for(let[n,r]of Object.entries(e))t[n]=Nt.has(n)?{...r,web:Et}:r;for(let t of Nt)if(!(t in e))throw Error(`Web command "${t}" missing from capability matrix`);return t}function Lt(e,t){let n=Pt[e];if(!n)return!0;let r=F(t.platform);if(!r)return!1;let i=n[r.capability.bucket];if(!i)return!1;let a=r.capability.supportsByDefault?.[e];return a&&!a(t)?!1:i[t.kind??`unknown`]===!0}function Rt(e,t){return F(t.platform)?.capability.unsupportedHintByDefault?.[e]?.(t)}function zt(){return ne.filter(e=>`capability`in e&&e.capability!==void 0||e.platformExecution.kind===`device-runtime`).map(e=>e.name).sort()}function Bt(e){let t=Pt[e];if(!t)return[];let n=[`apple`,`android`,`harmonyos`,`vega`,`linux`,`web`],r=[];for(let e of n){let n=t[e];n&&Object.values(n).some(e=>e===!0)&&r.push(e)}return r}function Vt(e,t){if(e.intent===`drag`){Ht(e,t);return}if(t.platform===`web`||t.appleOs===`watchos`)throw G(e,W(e,t));if(Wt(e)){Gt(e,t);return}if(t.appleOs===`visionos`)throw G(e,W(e,t));if(e.intent===`fling`&&`direction`in e&&t.platform===`linux`)throw G(e,`gesture fling is not supported on Linux`)}function Ht(e,t){if(!Ut(t))throw G(e,W(e,t),`Target-authored drag requires an adapter that preserves source hold, timed movement, and destination hold; it is supported on Android touch devices and iOS/iPadOS.`)}function Ut(e){return e.platform===`android`?e.target!==`tv`:e.platform===`apple`?e.appleOs===void 0?e.target!==`desktop`&&e.target!==`tv`:e.appleOs===`ios`||e.appleOs===`ipados`:!1}function Wt(e){return e.intent===`pan`?(`pointerCount`in e?e.pointerCount:1)===2:e.intent===`pinch`||e.intent===`rotate`||e.intent===`transform`}function Gt(e,t){if(t.platform===`android`){if(t.target!==`tv`)return;throw G(e,`gesture ${e.intent} is not supported on Android TV`,`Android TV has no touch input — this gesture is supported on Android phones, tablets, and the iOS simulator only.`)}if(t.platform!==`apple`)throw G(e,W(e,t));ee(t,e.intent)}function W(e,t){return`gesture ${e.intent} is not supported on ${t.appleOs??t.platform}`}function G(t,n,r){return new e(`UNSUPPORTED_OPERATION`,n,{gesture:t.intent,...r?{hint:r}:{}})}const Kt=`No active session. Run open first.`;function qt(e,t,n){return{ok:!1,error:{code:e,message:t,...n?{details:n}:{}}}}function Jt(){return qt(`SESSION_NOT_FOUND`,Kt)}function Yt(e,t,n){if(Lt(e,t))return null;let r=n?.hint?Rt(e,t):void 0;return{ok:!1,error:{code:`UNSUPPORTED_OPERATION`,message:n?.message??`${e} is not supported on this device`,...r?{hint:r}:{}}}}const Xt=/^[A-Za-z0-9_.:-]{1,64}$/,Zt=8*1024,Qt=4*1024;function $t(t){let n=t[0]?.trim(),r=t[1]?.trim();if(!n)throw new e(`INVALID_ARGS`,`trigger-app-event requires <event> [payloadJson]`);if(!Xt.test(n))throw new e(`INVALID_ARGS`,`Invalid trigger-app-event event name: ${n}`,{hint:`Use 1-64 chars: letters, numbers, underscore, dot, colon, or dash.`});if(t.length>2)throw new e(`INVALID_ARGS`,`trigger-app-event accepts at most two arguments: <event> [payloadJson]`);return{eventName:n,payload:tn(r,n)}}function en(t,n,r){let i=m(t),a=nn(t);if(!a)throw new e(`UNSUPPORTED_OPERATION`,`No app event URL template configured for ${i}.`,{hint:`Set AGENT_DEVICE_${i.toUpperCase()}_APP_EVENT_URL_TEMPLATE or AGENT_DEVICE_APP_EVENT_URL_TEMPLATE, for example "myapp://agent-device/event?name={event}&payload={payload}".`});let o=r?JSON.stringify(r):``,s=a.replaceAll(`{event}`,encodeURIComponent(n)).replaceAll(`{payload}`,encodeURIComponent(o)).replaceAll(`{platform}`,encodeURIComponent(i));if(s.length>Qt)throw new e(`INVALID_ARGS`,`trigger-app-event URL exceeds maximum supported length`,{hint:`Reduce payload size or shorten AGENT_DEVICE_*_APP_EVENT_URL_TEMPLATE.`,length:s.length,maxLength:Qt});return s}function tn(t,n){if(t)try{let r=JSON.parse(t);if(!r||typeof r!=`object`||Array.isArray(r))throw new e(`INVALID_ARGS`,`trigger-app-event payload for "${n}" must be a JSON object`);let i=JSON.stringify(r);if(Buffer.byteLength(i,`utf8`)>Zt)throw new e(`INVALID_ARGS`,`trigger-app-event payload for "${n}" exceeds ${Zt} bytes`);return r}catch(n){throw n instanceof e?n:new e(`INVALID_ARGS`,`Invalid trigger-app-event payload JSON: ${t}`)}}function nn(e){return((h(e)?process.env.AGENT_DEVICE_IOS_APP_EVENT_URL_TEMPLATE:g(e)?process.env.AGENT_DEVICE_MACOS_APP_EVENT_URL_TEMPLATE:process.env.AGENT_DEVICE_ANDROID_APP_EVENT_URL_TEMPLATE)??process.env.AGENT_DEVICE_APP_EVENT_URL_TEMPLATE)?.trim()||void 0}function rn(e){let t=e?e.textEntryReadiness:void 0,n=ln(t)?{textEntryReadiness:t}:{},r=an(e);return r?{...n,...r}:n}function an(e){if(!on(e))return null;let t=sn(e.target);return t?{verification:`unconfirmed`,requested:e.requested,before:e.before,after:e.after,target:t}:null}function on(e){return!!(e&&e.verification===`unconfirmed`&&typeof e.requested==`string`&&K(e.before)&&K(e.after))}function sn(e){if(!dn(e)||!cn(e))return null;let t=un(e.rect);return t?{resourceId:e.resourceId,className:e.className,packageName:e.packageName,rect:t}:null}function cn(e){return K(e.resourceId)&&K(e.className)&&K(e.packageName)}function ln(e){return typeof e==`string`&&i.includes(e)}function K(e){return e===null||typeof e==`string`}function un(e){return!dn(e)||![e.x,e.y,e.width,e.height].every(e=>typeof e==`number`)?null:e}function dn(e){return!!e&&typeof e==`object`}const q=[[0,0],[1,0],[0,1],[-1,0],[0,-1],[1,1],[-1,1],[1,-1],[-1,-1]];function fn(e,t){return v(e.platform)&&t>1}function pn(e,t,n=2e4){if(e.length===0)return[];let r=t>0?t:e.length,i=[],a=[],o=0;for(let t of e){let e=(t.durationMs??0)+(t.pauseMs??0)+250,s=a.length>0&&o+e>n,c=a.length>=r;(s||c)&&(i.push(a),a=[],o=0),a.push(t),o+=e}return a.length>0&&i.push(a),i}function mn(e,t){if(t<=0)return[0,0];let[n,r]=q[e%q.length];return[n*t,r*t]}async function hn(e,t,n){for(let r=0;r<e;r+=1)await n(r),r<e-1&&t>0&&await ge(t)}async function gn(e,t){let{x:n,y:r}=J(t,`longpress requires x y [durationMs]`,{hint:`Direct platform longpress requires coordinates. In an open daemon session, use agent-device longpress @ref|selector [durationMs]; otherwise run snapshot -i, use the target rect center as x y, then retry longpress x y durationMs.`}),i=t[2]?Number(t[2]):void 0;return await e.longPress(n,r,i),{x:n,y:r,durationMs:i,...S(`Long pressed (${n}, ${r})`)}}async function _n(e,t){let{x:n,y:r}=J(t,`focus requires x y`);return await e.focus(n,r),{x:n,y:r,...S(`Focused (${n}, ${r})`)}}async function vn(t,n,r){let i=Un(n);if(i)throw new e(`INVALID_ARGS`,`type does not accept a target ref like "${i}"`,{hint:`Use fill ${i} "text" to target that field, or press ${i} then type "text" to append.`});let a=n.join(` `);if(!a)throw new e(`INVALID_ARGS`,`type requires text`);let o=C(r?.delayMs??0,`delay-ms`,0,1e4),s=(await t.type(a,o))?.textEntryRoute;return{...s===void 0?{}:{textEntryRoute:s},text:a,delayMs:o,...S(Z(`Typed`,a))}}async function yn(t,n,r){if(r?.directElementSelector)return await bn(t,r.directElementSelector,n,r);let i=Number(n[0]),a=Number(n[1]),o=n.slice(2).join(` `);if(Number.isNaN(i)||Number.isNaN(a)||!o)throw new e(`INVALID_ARGS`,`fill requires x y text`);let s=C(r?.delayMs??0,`delay-ms`,0,1e4),c=await t.fill(i,a,o,s,{allowNonHittableCoordinateFallback:r?.allowNonHittableCoordinateFallback===!0});return{x:i,y:a,text:o,delayMs:s,...c?.maestroNonHittableCoordinateFallbackUsed===!0?{maestroNonHittableCoordinateFallbackUsed:!0}:{},...rn(c),...S(Z(`Filled`,o))}}async function bn(t,n,r,i){if(!t.fillElementSelector)throw new e(`UNSUPPORTED_OPERATION`,`direct element selector fill is not supported`);let a=r.join(` `);if(!a)throw new e(`INVALID_ARGS`,`fill requires text`);let o=C(i.delayMs??0,`delay-ms`,0,1e4),s=await t.fillElementSelector(n,a,o);return{selector:n.raw,text:a,delayMs:o,...s??{},...S(Z(`Filled`,a))}}async function xn(e,t,n,r){if(r?.directElementSelector&&h(e))return await Sn(t,r.directElementSelector);let{x:i,y:a}=J(n,`press requires x y`);if(g(e)&&r?.surface&&r.surface!==`app`)return await Cn(i,a,r);let o=s(r);if(o!==`primary`)return await wn(e,i,a,o,r);let c=Dn(r);return On(c),fn(e,c.count)?await An(e,i,a,c,r):await Nn(t,i,a,c)}async function Sn(t,n){if(!t.tapElementSelector)throw new e(`UNSUPPORTED_OPERATION`,`direct element selector tap is not supported`);let r=await t.tapElementSelector(n),i=r?.maestroNonHittableCoordinateFallbackUsed===!0;return{selector:n.raw,...r??{},...S(i?a:`Tapped ${n.raw}`)}}function J(t,n,r){let i=Number(t[0]),a=Number(t[1]);if(Number.isNaN(i)||Number.isNaN(a))throw new e(`INVALID_ARGS`,n,r);return{x:i,y:a}}async function Cn(t,n,r){let i=s(r);if(i!==`primary`)throw new e(`UNSUPPORTED_OPERATION`,`${i} click is not supported on macOS ${r.surface} sessions.`);let{runMacOsPressAction:a}=await import(`./helper.js`).then(e=>e.t);return await a(t,n,{bundleId:r.appBundleId,surface:r.surface}),{x:t,y:n,...S(X({x:t,y:n}))}}async function wn(e,t,n,r,i){if(Tn(e,r,i),e.platform===`linux`)return await En(t,n,r);let{runAppleRunnerCommand:a}=await import(`./internal/daemon.js`).then(e=>e.lt);return await a(e,{command:`mouseClick`,x:t,y:n,button:r,appBundleId:i?.appBundleId},Pn(i)),{x:t,y:n,button:r,...S(X({x:t,y:n,button:r}))}}function Tn(e,t,n){let r=o({commandLabel:`click`,platform:m(e),button:t,count:n?.count,intervalMs:n?.intervalMs,holdMs:n?.holdMs,jitterPx:n?.jitterPx,doubleTap:n?.doubleTap});if(r)throw r}async function En(e,t,n){if(n===`secondary`){let{rightClickLinux:n}=await import(`./input-actions3.js`);await n(e,t)}else{let{middleClickLinux:n}=await import(`./input-actions3.js`);await n(e,t)}return{x:e,y:t,button:n,...S(X({x:e,y:t,button:n}))}}function Dn(e){return{count:Y(e?.count,1,`count`,1,200),intervalMs:Y(e?.intervalMs,0,`interval-ms`,0,1e4),holdMs:Y(e?.holdMs,0,`hold-ms`,0,1e4),jitterPx:Y(e?.jitterPx,0,`jitter-px`,0,100),doubleTap:!!e?.doubleTap}}function Y(e,t,n,r,i){return C(e===void 0?t:e,n,r,i)}function On({doubleTap:t,holdMs:n,jitterPx:r}){if(t&&n>0)throw new e(`INVALID_ARGS`,`double-tap cannot be combined with hold-ms`);if(t&&r>0)throw new e(`INVALID_ARGS`,`double-tap cannot be combined with jitter-px`)}async function kn(e,t,n){let{runAppleRunnerCommand:r}=await import(`./internal/daemon.js`).then(e=>e.lt),{MAX_RUNNER_SEQUENCE_STEPS:i,buildRunnerSequenceCommand:a,parseRunnerSequenceResult:o}=await import(`./runner-sequence.js`).then(e=>e.r),s=pn(t,i),c,l,u=0,d=[],f=0;for(let t of s){let i=await r(e,a(t,n?.appBundleId),Pn(n));c??=i,l=i;let s;try{s=o(i)}catch(e){throw Mn(e,f)}u+=s.completedSteps,d.push(...s.results),f+=t.length}return{...c??{},completedSteps:u,sequenceResults:d,...l?.gestureEndUptimeMs===void 0?{}:{gestureEndUptimeMs:l.gestureEndUptimeMs}}}async function An(e,t,n,r,i){let a=await kn(e,jn(e,t,n,r),i);return{x:t,y:n,count:r.count,intervalMs:r.intervalMs,holdMs:r.holdMs,jitterPx:r.jitterPx,doubleTap:r.doubleTap,timingMode:`runner-sequence`,...a,...S(X({x:t,y:n}))}}function jn(e,t,n,r){let i=r.doubleTap?`doubleTap`:r.holdMs>0?`longPress`:`tap`,a=i===`tap`&&h(e)&&!_(e);return Array.from({length:r.count},(e,o)=>{let[s,c]=mn(o,r.jitterPx),l=o===r.count-1;return{kind:i,x:t+s,y:n+c,...a?{synthesized:!0}:{},...r.holdMs>0?{durationMs:r.holdMs}:{},...!l&&r.intervalMs>0?{pauseMs:r.intervalMs}:{}}})}function Mn(t,n){if(n===0||!(t instanceof e)||!t.details)return t;let r=t.details.failedStepIndex;if(typeof r!=`number`)return t;let i=t.details.completedSteps;return new e(t.code,t.message,{...t.details,failedStepIndex:r+n,chunkStepIndex:r,...typeof i==`number`?{completedSteps:n+i}:{}},t.cause)}async function Nn(e,t,n,r){let i;return await hn(r.count,r.intervalMs,async a=>{let[o,s]=mn(a,r.jitterPx),c=t+o,l=n+s;if(r.doubleTap){let t=await e.doubleTap(c,l);i??=t??void 0;return}if(r.holdMs>0){let t=await e.longPress(c,l,r.holdMs);i??=t??void 0}else{let t=await e.tap(c,l);i??=t??void 0}}),x({x:t,y:n,count:r.count,intervalMs:r.intervalMs,holdMs:r.holdMs,jitterPx:r.jitterPx,doubleTap:r.doubleTap,...i},X({x:t,y:n}))}function Pn(e){return{verbose:e?.verbose,logPath:e?.logPath,traceLogPath:e?.traceLogPath,requestId:e?.requestId,iosXctestrunFile:e?.iosXctestrunFile,iosXctestDerivedDataPath:e?.iosXctestDerivedDataPath,iosXctestEnvDir:e?.iosXctestEnvDir}}async function Fn(t,n,r){let i=n[0],a=n[1]?Number(n[1]):void 0,o=r?.pixels,s=r?.durationMs;if(!i)throw new e(`INVALID_ARGS`,`scroll requires direction`);In(a,o,s);let c=Vn(i),l={amount:a,pixels:o,durationMs:s},{interactionResult:u,completedPasses:d}=await Rn(t,r,c,l);return x(zn(c,l,d,u),le(c.direction,c.edge,d,a,o))}function In(e,n,i){Ln(e),r(i),t({amount:e,pixels:n})}function Ln(t){if(t!==void 0&&!Number.isFinite(t))throw new e(`INVALID_ARGS`,`scroll amount must be a number`)}async function Rn(e,t,n,r){if(n.edge){let i=n.edge,a=await de({edge:i,captureState:async n=>await Bn(e,t,i,n),scroll:async()=>await e.scroll(n.direction,r)});return{interactionResult:a.result??{},completedPasses:a.passes}}return{interactionResult:await e.scroll(n.direction,r)??{},completedPasses:1}}function zn(e,t,n,r){let i=c(r);return{direction:e.direction,...e.edge?{edge:e.edge,passes:n}:{},...t.amount===void 0?{}:{amount:t.amount},...t.pixels===void 0?{}:{pixels:t.pixels},...i===void 0?{}:{durationMs:i},...r}}async function Bn(t,n,r,i){if(typeof t.snapshot!=`function`)throw new e(`UNSUPPORTED_OPERATION`,`scroll ${r} requires snapshot support to verify hidden content before scrolling`);let a=t.snapshot;return await ce({edge:r,scope:i,captureNodes:async e=>(await a({appBundleId:n?.appBundleId,scope:e})).nodes??[]})}function Vn(e){return e===`bottom`?{direction:`down`,edge:`bottom`}:e===`top`?{direction:`up`,edge:`top`}:{direction:u(e)}}async function Hn(e,t,n){let{x:r,y:i}=J(t,`read requires x y`);if(e.platform===`android`){let{readAndroidTextAtPoint:t}=await import(`./input-actions.js`).then(e=>e.s);return{action:`read`,text:await t(e,r,i)??``}}if(e.platform===`linux`){let{readLinuxTextAtPoint:e}=await import(`./snapshot.js`).then(e=>e.n);return{action:`read`,text:await e(r,i,n?.surface)}}if(g(e)&&n?.surface&&n.surface!==`app`){let{runMacOsReadTextAction:e}=await import(`./helper.js`).then(e=>e.t);return{action:`read`,text:(await e(r,i,{bundleId:n.appBundleId,surface:n.surface})).text}}let{runAppleRunnerCommand:a}=await import(`./internal/daemon.js`).then(e=>e.lt),o=await a(e,{command:`readText`,x:r,y:i,appBundleId:n?.appBundleId},{verbose:n?.verbose,logPath:n?.logPath,traceLogPath:n?.traceLogPath,requestId:n?.requestId,iosXctestrunFile:n?.iosXctestrunFile,iosXctestDerivedDataPath:n?.iosXctestDerivedDataPath,iosXctestEnvDir:n?.iosXctestEnvDir});return{action:`read`,text:typeof o.text==`string`?o.text:typeof o.message==`string`?o.message:``}}function Un(e){return me(e[0])}function X(e){return e.button&&e.button!==`primary`?`Clicked ${e.button} (${e.x}, ${e.y})`:`Tapped (${e.x}, ${e.y})`}function Z(e,t){return`${e} ${Array.from(t).length} chars`}function Wn(e){let t=e.trim();return t.startsWith(`{`)&&t.endsWith(`}`)||t.startsWith(`[`)&&t.endsWith(`]`)}function Gn(t,n){let r=n?.subject??`Payload`,i=t.trim();if(!i)throw new e(`INVALID_ARGS`,`${r} cannot be empty`);let a=n?.expandPath?n.expandPath(i,n.cwd):i;try{if(!xe.statSync(a).isFile())throw new e(`INVALID_ARGS`,`${r} path is not a file: ${a}`);return{kind:`file`,path:a}}catch(t){if(t instanceof e)throw t;let n=t.code;if(n===`EACCES`||n===`EPERM`)throw new e(`INVALID_ARGS`,`${r} file is not readable: ${a}`);if(n&&n!==`ENOENT`)throw new e(`COMMAND_FAILED`,`Unable to read ${r} file: ${a}`,{cause:String(t)})}if(Wn(i))return{kind:`inline`,text:i};throw new e(`INVALID_ARGS`,`${r} file not found: ${a}`)}async function Kn(t){let n=Gn(t,{subject:`Push payload`}),r=n.kind===`inline`?n.text:await qn(n.path);try{let t=JSON.parse(r);if(!t||typeof t!=`object`||Array.isArray(t))throw new e(`INVALID_ARGS`,`push payload must be a JSON object`);return t}catch(n){throw n instanceof e?n:new e(`INVALID_ARGS`,`Invalid push payload JSON: ${t}`)}}async function qn(t){try{return await Se.readFile(t,`utf8`)}catch(n){let r=n.code;throw r===`ENOENT`?new e(`INVALID_ARGS`,`Push payload file not found: ${t}`):r===`EISDIR`?new e(`INVALID_ARGS`,`Push payload path is not a file: ${t}`):r===`EACCES`||r===`EPERM`?new e(`INVALID_ARGS`,`Push payload file is not readable: ${t}`):new e(`COMMAND_FAILED`,`Unable to read push payload file: ${t}`,{cause:String(n)})}}U();async function Q(t,n){if(D(t)){let r=Te(t,n);if(r)return r;throw new e(`UNSUPPORTED_OPERATION`,`Provider device runtime does not have an active interactor for this device.`,{deviceId:t.id,platform:m(t)})}return await dt(t.platform).createInteractor(t,n)}async function Jn(e,t,n,r,i){let a=$(i),o=await Q(e,a);return w({level:`debug`,phase:`platform_command_prepare`,data:{command:t,platform:e.platform,kind:e.kind}}),await he(`platform_command`,async()=>await Qn(e,o,t,n,r,i,a),{command:t,platform:e.platform})}async function Yn(t,n,r){let i=await Q(t,$(r));if(!i.performGesture)throw new e(`UNSUPPORTED_OPERATION`,`Gesture execution is unavailable`);return await i.performGesture(n)}async function Xn(e,t){return await(await Q(e,$(t))).gestureViewport?.()}function $(e){return{requestId:e?.requestId,signal:e?.signal,appBundleId:e?.appBundleId,verbose:e?.verbose,logPath:e?.logPath,traceLogPath:e?.traceLogPath,iosXctestrunFile:e?.iosXctestrunFile,iosXctestDerivedDataPath:e?.iosXctestDerivedDataPath,iosXctestEnvDir:e?.iosXctestEnvDir,runnerLeaseContext:e?.runnerLeaseContext}}const Zn={open:({device:e,interactor:t,positionals:n,context:r})=>$n(e,t,n,r),close:async({device:e,interactor:t,positionals:n})=>{let r=n[0];return r?(await t.close(r),{app:r,...S(`Closed: ${r}`)}):(e.platform===`web`&&await t.close(``),{closed:`session`,...S(`Closed session`)})},press:({device:e,interactor:t,positionals:n,context:r})=>xn(e,t,n,r),longpress:({interactor:e,positionals:t})=>gn(e,t),focus:({interactor:e,positionals:t})=>_n(e,t),type:({interactor:e,positionals:t,context:n})=>vn(e,t,n),fill:({interactor:e,positionals:t,context:n})=>yn(e,t,n),scroll:({interactor:e,positionals:t,context:n})=>Fn(e,t,n),"trigger-app-event":({device:e,interactor:t,positionals:n,context:r})=>er(e,t,n,r),screenshot:({interactor:e,positionals:t,outPath:n,context:r})=>tr(e,t,n,r),viewport:({interactor:e,positionals:t})=>nr(e,t),back:async({interactor:e,context:t})=>(await e.back(t?.backMode),{action:`back`,mode:t?.backMode??`in-app`,...S(`Back`)}),home:async({interactor:e})=>(await e.home(),{action:`home`,...S(`Home`)}),orientation:async({interactor:e,positionals:t})=>{let n=pe(t[0]),r=(await e.setOrientation(n))?.orientation??n;return{action:`orientation`,orientation:r,...S(`Rotated to ${r}`)}},"app-switcher":async({interactor:e})=>(await e.appSwitcher(),{action:`app-switcher`,...S(`Opened app switcher`)}),clipboard:({interactor:e,positionals:t})=>rr(e,t),keyboard:({device:e,positionals:t,context:n,runnerCtx:r})=>ar(e,t,n,r),"tv-remote":({device:e,interactor:t,positionals:n,context:r})=>ir(e,t,n,r),settings:({device:e,interactor:t,positionals:n,context:r})=>ur(e,t,n,r),push:({device:e,positionals:t,context:n})=>hr(e,t,n),snapshot:({interactor:e,context:t})=>gr(e,t),read:({device:e,positionals:t,context:n})=>Hn(e,t,n)};async function Qn(t,n,r,i,a,o,s){let c=Object.hasOwn(Zn,r)?Zn[r]:void 0;if(!c)throw new e(`INVALID_ARGS`,`Unknown command: ${r}`);return await c({device:t,interactor:n,positionals:i,outPath:a,context:o,runnerCtx:s})}async function $n(t,n,r,i){let a=r[0],o=r[1],s=i?.launchConsole,c=i?.launchArgs;if(r.length>2)throw new e(`INVALID_ARGS`,`open accepts at most two arguments: <app|url> [url]`);if(!a){if(s)throw new e(`INVALID_ARGS`,`--launch-console requires an app target`);if(c&&c.length>0)throw new e(`INVALID_ARGS`,`--launch-args requires an app target`);return await n.openDevice(),{app:null,...S(`Opened device`)}}if(s&&(!h(t)||t.kind!==`simulator`))throw new e(`UNSUPPORTED_OPERATION`,se);if(t.platform===`linux`&&c&&c.length>0)throw new e(`UNSUPPORTED_OPERATION`,`--launch-args is not supported on Linux.`);if(o!==void 0){if(p(a))throw new e(`INVALID_ARGS`,`open <app> <url> requires an app target as the first argument`);if(!p(o))throw new e(`INVALID_ARGS`,`open <app> <url> requires a valid URL target`);if(s)throw new e(`INVALID_ARGS`,oe);return await n.open(a,{activity:i?.activity,appBundleId:i?.appBundleId,launchArgs:c,terminateRunningApp:i?.terminateRunningApp,url:o}),{app:a,url:o,...S(`Opened: ${a}`)}}if(s&&p(a))throw new e(`INVALID_ARGS`,oe);if(i?.clearAppState){if(p(a))throw new e(`INVALID_ARGS`,`Clearing app state requires an app target, not a deep link.`);await n.setSetting(`clear-app-state`,`clear`,a)}return await n.open(a,{activity:i?.activity,appBundleId:i?.appBundleId,launchConsole:s,launchArgs:c,terminateRunningApp:i?.terminateRunningApp}),{app:a,...s?{launchConsole:s}:{},...S(`Opened: ${a}`)}}async function er(e,t,n,r){let{eventName:i,payload:a}=$t(n),o=en(e,i,a);return await t.open(o,{appBundleId:r?.appBundleId}),{event:i,eventUrl:o,transport:`deep-link`,...S(`Triggered app event: ${i}`)}}async function tr(e,t,r,i){let a=t[0]??r??`./screenshot-${Date.now()}.png`;await Se.mkdir(be.dirname(a),{recursive:!0});let o=n(i);return await e.screenshot(a,{appBundleId:i?.appBundleId,pixelDensity:o.pixelDensity,fullscreen:o.fullscreen,normalizeStatusBar:o.normalizeStatusBar,stabilize:o.stabilize,surface:i?.surface,skipIosSimulatorBootCheck:i?.skipIosSimulatorBootCheck,captureBackend:i?.screenshotCaptureBackend}),{path:a,...S(`Saved screenshot: ${a}`)}}async function nr(t,n){if(n.length!==2)throw new e(`INVALID_ARGS`,`viewport requires exactly two arguments: <width> <height>`);let r=ue(n[0],`width`),i=ue(n[1],`height`);if(!t.setViewport)throw new e(`UNSUPPORTED_OPERATION`,`viewport is not supported by this backend`);return await t.setViewport(r,i),{width:r,height:i,...S(`Viewport set: ${r}x${i}`)}}async function rr(t,n){let r=(n[0]??``).toLowerCase();if(r!==`read`&&r!==`write`)throw new e(`INVALID_ARGS`,`clipboard requires a subcommand: read or write`);if(r===`read`){if(n.length!==1)throw new e(`INVALID_ARGS`,`clipboard read does not accept additional arguments`);return{action:r,text:await t.readClipboard()}}if(n.length<2)throw new e(`INVALID_ARGS`,`clipboard write requires text (use "" to clear clipboard)`);let i=n.slice(1).join(` `);return await t.writeClipboard(i),{action:r,textLength:Array.from(i).length,...S(`Clipboard updated`)}}async function ir(t,n,r,i){if(t.target!==`tv`)throw new e(`UNSUPPORTED_OPERATION`,`tv-remote is supported only on TV targets`,{hint:`Select an Android TV, tvOS, or Vega OS target with --target tv.`});if(r.length!==1)throw new e(`INVALID_ARGS`,`tv-remote requires exactly one button`);let a=d(r[0]),o=i?.durationMs===void 0?void 0:C(i.durationMs,`durationMs`,0,1e4);return await n.tvRemote(a,o),{action:`tv-remote`,button:a,...o===void 0?{}:{durationMs:o},...S(`Pressed TV remote ${a}`)}}async function ar(t,n,r,i){let a=(n[0]??`status`).toLowerCase();if(!fe(a))throw new e(`INVALID_ARGS`,`keyboard requires a subcommand: status, get, dismiss, enter, or return`);if(n.length>1)throw new e(`INVALID_ARGS`,`keyboard accepts at most one subcommand argument`);if(t.platform===`android`)return await sr(t,a);if(t.platform===`harmonyos`)return await or(t,a);if(h(t))return await cr(t,a,r,i);throw new e(`UNSUPPORTED_OPERATION`,`keyboard is supported only on Android, HarmonyOS, and iOS`)}async function or(t,n){if(n!==`dismiss`&&n!==`enter`&&n!==`return`)throw new e(`UNSUPPORTED_OPERATION`,`keyboard status/get is not available through the public HarmonyOS HDC API; use keyboard dismiss or enter`);let{pressHarmonyKeyboardKey:r}=await import(`./input-actions2.js`);return await r(t,n===`dismiss`?`Back`:`Enter`),{platform:`harmonyos`,action:n===`dismiss`?`dismiss`:`enter`,...S(n===`dismiss`?`Keyboard dismissed`:`Keyboard enter pressed`)}}async function sr(e,t){if(t===`enter`||t===`return`){let{pressAndroidEnter:t}=await import(`./input-actions.js`).then(e=>e.s);return await t(e),{platform:`android`,action:`enter`,...S(`Keyboard enter pressed`)}}if(t===`dismiss`){let{dismissAndroidKeyboard:t}=await import(`./device-input-state.js`).then(e=>e.t),n=await t(e);return{platform:`android`,action:`dismiss`,attempts:n.attempts,wasVisible:n.wasVisible,dismissed:n.dismissed,visible:n.visible,inputType:n.inputType,type:n.type,inputMethodPackage:n.inputMethodPackage,focusedPackage:n.focusedPackage,focusedResourceId:n.focusedResourceId,inputOwner:n.inputOwner}}let{getAndroidKeyboardState:n}=await import(`./device-input-state.js`).then(e=>e.t),r=await n(e);return{platform:`android`,action:`status`,visible:r.visible,inputType:r.inputType,type:r.type,inputMethodPackage:r.inputMethodPackage,focusedPackage:r.focusedPackage,focusedResourceId:r.focusedResourceId,inputOwner:r.inputOwner}}async function cr(t,n,r,i){if(n!==`dismiss`&&n!==`enter`&&n!==`return`)throw new e(`UNSUPPORTED_OPERATION`,`keyboard status/get is currently supported only on Android; use keyboard dismiss or enter on iOS`);if(n===`enter`||n===`return`){let{runAppleRunnerCommand:e}=await import(`./internal/daemon.js`).then(e=>e.lt),n=await e(t,{command:`keyboardReturn`,appBundleId:r?.appBundleId},i);return{platform:`ios`,action:`enter`,visible:n.visible,wasVisible:n.wasVisible,...S(`Keyboard enter pressed`)}}let{runAppleRunnerCommand:a}=await import(`./internal/daemon.js`).then(e=>e.lt),o=await a(t,{command:`keyboardDismiss`,appBundleId:r?.appBundleId},i),s=typeof o.keyboardDismissMechanism==`string`?o.keyboardDismissMechanism:void 0;return{platform:`ios`,action:`dismiss`,wasVisible:o.wasVisible,dismissed:o.dismissed,visible:o.visible,mechanism:s,...S(lr(o.dismissed===!0,s))}}function lr(e,t){return e?t===`dismissKey`?`Keyboard dismissed via its dismiss key`:`Keyboard dismissed`:`Keyboard already hidden`}async function ur(t,n,r,i){let[a,o,s,c]=r;if(!a||!o&&a!==`clear-app-state`)throw new e(`INVALID_ARGS`,`settings requires setting state`);if(a===`clear-app-state`)return await dr(t,n,o,s,i);if(!o)throw new e(`INVALID_ARGS`,`settings requires setting state`);return await fr(t,n,a,o,s,c,r,i)}async function dr(t,n,r,i,a){let o=(r===`clear`?i:r)??a?.appBundleId;if(!o)throw new e(`INVALID_ARGS`,`settings clear-app-state requires an app id or an active app session.`);w({level:`debug`,phase:`settings_apply`,data:{setting:`clear-app-state`,state:`clear`,appBundleId:o,platform:t.platform}});let s=await n.setSetting(`clear-app-state`,`clear`,o);return s&&typeof s==`object`?x({setting:`clear-app-state`,state:`clear`,...s},_r(s)??`Cleared user data for ${o}`):{setting:`clear-app-state`,state:`clear`,...S(`Cleared user data for ${o}`)}}async function fr(e,t,n,r,i,a,o,s){let c=n===`location`&&r===`set`,l=(n===`permission`||c?o[4]:o[2])??s?.appBundleId;w({level:`debug`,phase:`settings_apply`,data:mr(e,n,r,i,a,l,c)});let u=await t.setSetting(n,r,l,pr(n,i,a,c));return u&&typeof u==`object`?x({setting:n,state:r,...u},_r(u)??`Updated setting: ${n}`):{setting:n,state:r,...S(`Updated setting: ${n}`)}}function pr(e,t,n,r){if(e===`permission`)return{permissionTarget:t,permissionMode:n};if(r)return{latitude:l(t,`latitude`),longitude:l(n,`longitude`)}}function mr(e,t,n,r,i,a,o){return o?{setting:t,state:n,latitude:r,longitude:i,platform:e.platform}:t===`permission`?{setting:t,state:n,permissionTarget:r,permissionMode:i,platform:e.platform}:{setting:t,state:n,appBundleId:a,platform:e.platform}}async function hr(t,n,r){let i=n[0]?.trim(),a=n[1]?.trim();if(!i||!a)throw new e(`INVALID_ARGS`,`push requires <bundle|package> <payload.json|inline-json>`);let o=await Kn(a);if(h(t)){let{pushIosNotification:e}=await import(`./apps.js`).then(e=>e.t);return await e(t,i,o),{platform:`ios`,bundleId:i,...S(`Pushed notification to ${i}`)}}let{pushAndroidNotification:s}=await import(`./notifications.js`),c=await s(t,i,o);return{platform:`android`,package:i,action:c.action,extrasCount:c.extrasCount,...S(`Pushed notification to ${i}`)}}async function gr(e,t){let n=t??{};return await e.snapshot({appBundleId:n.appBundleId,signal:n.signal,interactiveOnly:n.snapshotInteractiveOnly,preferredBackend:n.snapshotPreferredBackend,depth:n.snapshotDepth,scope:n.snapshotScope,raw:n.snapshotRaw,customActions:n.snapshotCustomActions,includeRects:n.snapshotIncludeRects,includeHiddenContentHints:n.snapshotIncludeHiddenContentHints,surface:n.surface})}function _r(e){return typeof e.message==`string`&&e.message.length>0?e.message:void 0}export{ke as C,D as E,Oe as S,De as T,it as _,Kt as a,Ye as b,Yt as c,Vt as d,Bt as f,nt as g,rt as h,Gn as i,Lt as l,F as m,Yn as n,qt as o,U as p,Xn as r,Jt as s,Jn as t,zt as u,We as v,Ee as w,Ue as x,Ke as y};
|
package/dist/src/find.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{u as e}from"./sdk-contracts.js";import{
|
|
1
|
+
import{u as e}from"./sdk-contracts.js";import{$t as t,On as n,cn as r,ht as i,ln as a,pn as o,un as s}from"./sdk-batch-runner.js";import{Ct as c,G as l,W as u,gn as d,hn as f,q as p,z as m}from"./prepare-kind.js";import"./screenshot-result.js";import{o as h,s as g,t as _}from"./dispatch.js";import{dn as v,fn as y,tn as b}from"./internal/daemon.js";import{o as x,s as S,t as C}from"./selector-runtime.js";import{t as w}from"./handler-utils.js";function T(e){return e.kind===`ambiguous`?e.matchedNodes:e.kind===`resolved`?[e.resolution.node]:[]}function E(e){if(e.ambiguity!==`reject-candidates`)throw Error(`find's resolution policy must reject candidates, got "${e.ambiguity}"`)}async function D(e){let{req:t,sessionName:n,logPath:i,sessionStore:a,invoke:c}=e,l=t.command;if(l!==`find`)return null;let u=r(t.positionals??[],t.flags);if(!u.ok)return h(u.code,u.message);let{locator:d,query:f,action:p,value:_}=u.parsed;if(t.flags?.record&&!s(p))return h(`INVALID_ARGS`,`find ${p} is a mutating action and is always recorded; --record only applies to a read-only find (exists, wait, list, get text, get attrs).`);let v=await C({req:t,sessionName:n,logPath:i,sessionStore:a});if(v)return v;let y=a.get(n);if(!y)return g();let b=y.device,x=o(d,f),w=k({device:b,session:y,req:t,logPath:i,locator:d,query:f,sessionStore:a,sessionName:n}),T={req:t,sessionName:n,logPath:i,sessionStore:a,invoke:c,session:y,device:b,command:l,locator:d,query:f,publicFlags:Y(t.flags)},E=await w();if(m(E.snapshotQuality))return A(E.snapshotQuality);let{nodes:D}=E,M=j({nodes:D,locator:d,query:f,selectorExpression:x,flags:t.flags,platform:b.platform});if(!M.ok)return S(M.response,E);let N=M.node,P=R(D,N),F=await O(T,{node:N,resolvedNode:P,ref:`@${P.ref}`,nodes:D,actionFlags:{...t.flags??{},noRecord:!0}},p,_);return F&&S(F,E)}async function O(e,t,n,r){let i={click:()=>H(e,t),fill:()=>U(e,t,r),focus:()=>W(e,t),type:()=>G(e,t,r)}[n];return i?await i():null}function k(e){let{device:t,session:n,req:r,logPath:i,locator:a,query:o}=e,{sessionStore:s,sessionName:c}=e,l=x({device:t,session:n,sessionStore:s,sessionName:c,req:r,logPath:i});return async()=>{let{snapshot:e}=await l.capture({flags:{...r.flags,snapshotInteractiveOnly:!0},recovery:{legacyIosSparse:{query:o,shouldScope:Z(a)},sparseVerdictQueryScope:{query:o,shouldScope:Z(a)}}});return{nodes:e.nodes,snapshotQuality:e.snapshotQuality,systemSurfaceOnly:e.systemSurfaceOnly}}}function A(e){return h(`COMMAND_FAILED`,`find could not read the current accessibility tree`,{reason:e.reason,hint:`The snapshot quality verdict is sparse. Use screenshot as visual truth, navigate with coordinates if needed, then retry find after reaching a readable screen.`})}function j(e){let{nodes:n,locator:r,query:o,selectorExpression:s,flags:c,platform:l}=e,u=n.filter(e=>!z(e,n[0])),d=t.findAct,f;if(f=s?T(i(u,s,d,{platform:l})):a(u,r,o,{requireRect:d.requireRect}).matches,f=N(f,n),f.length>1){E(d);let e=M(f,c);if(!e)return{ok:!1,response:X(f,r,o)};f=e}let p=f[0]??null;return p?{ok:!0,node:p}:{ok:!1,response:h(`COMMAND_FAILED`,`find did not match any element`)}}function M(e,t){return t?.findFirst?[e[0]]:t?.findLast?[e[e.length-1]]:null}function N(t,n){let r=n[0]?.rect;if(!r)return t;let i=t.filter(t=>{if(!t.rect)return!1;let n=e(t.rect);return n.x>=r.x&&n.x<=r.x+r.width&&n.y>=r.y&&n.y<=r.y+r.height});return P(i.length>0?i:t,n)}function P(e,t){return e.length<2?e:e.map((e,n)=>({node:e,index:n,score:F(e,t)})).sort((e,t)=>t.score===e.score?L(e.node)-L(t.node)||e.index-t.index:t.score-e.score).map(e=>e.node)}function F(e,t){let n=l(t,e);if(n.reason===`covered`)return 0;let r=I(n,t[0]);return r>0?r:e.hittable&&e.rect&&!z(e,t[0])?3:+!!e.rect}function I(e,t){return e.node.rect?e.reason===`semantic-target`||e.reason===`same-rect-descendant`?4:e.reason===`hittable-ancestor`&&!z(e.node,t)?2:0:0}function L(e){return e.rect?e.rect.width*e.rect.height:1/0}function R(e,t){let n=u(e,t);return z(n,e[0])&&t.rect?t:n}function z(e,t){return!t?.rect||!e.rect||!n(e)?!1:B(e.rect,t.rect)}function B(e,t){return e.x===t.x&&e.y===t.y&&e.width===t.width&&e.height===t.height}function V(e){return{ref:e.ref,node:e.resolvedNode,nodes:e.nodes}}async function H(t,n){let{req:r,sessionName:i,sessionStore:a,session:o,invoke:s,command:c,locator:l,query:u,publicFlags:p}=t,m=await s({token:r.token,session:i,command:`click`,positionals:[n.ref],flags:n.actionFlags,internal:{findResolvedTarget:V(n)}});if(!m.ok)return m;let h=n.resolvedNode.rect?e(n.resolvedNode.rect):n.node.rect?e(n.node.rect):null,g={ref:n.ref,locator:l,query:u};h&&(g.x=h.x,g.y=h.y);let _=f(m.data)??`Tapped ${n.ref}${h?` (${h.x}, ${h.y})`:``}`;return Object.assign(g,d(_)),w(a,o,r,c,{ref:n.ref,action:`click`,locator:l,query:u},{flags:p}),{ok:!0,data:g}}async function U(e,t,n){let{req:r,sessionName:i,sessionStore:a,session:o,invoke:s,command:c,publicFlags:l}=e;if(!n)return h(`INVALID_ARGS`,`find fill requires text`);let u=await s({token:r.token,session:i,command:`fill`,positionals:[t.ref,n],flags:t.actionFlags,internal:{findResolvedTarget:V(t)}});return u.ok&&w(a,o,r,c,{ref:t.ref,action:`fill`},{flags:l}),u}async function W(e,t){let n=await K(e,t);return n.ok&&J(e,t,`focus`),n}async function G(e,t,n){let{req:r,device:i,logPath:a,session:o}=e;if(!n)return h(`INVALID_ARGS`,`find type requires text`);let s=await K(e,t);if(!s.ok)return s;b(o);let c=await _(i,`type`,[n],r.flags?.out,{...y(a,r.flags,o.appBundleId,o.trace?.outPath)});return J(e,t,`type`),{ok:!0,data:c??{ref:t.ref}}}async function K(t,n){let{req:r,device:i,logPath:a,session:o}=t,s=q(n,`be focused`);if(s)return s;let c=n.resolvedNode.rect?e(n.resolvedNode.rect):null;return c?(b(o),{ok:!0,data:await _(i,`focus`,[String(c.x),String(c.y)],r.flags?.out,{...y(a,r.flags,o.appBundleId,o.trace?.outPath)})??{ref:n.ref}}):h(`COMMAND_FAILED`,`matched element has no bounds`)}function q(e,t){let n=[e.resolvedNode,e.node].find(p);return n?h(`COMMAND_FAILED`,`Matched element ${e.ref} is covered by another visible element and cannot ${t} safely`,{ref:`@${n.ref}`,interactionBlocked:n.interactionBlocked,hint:`Use a different visible target, scroll it clear of the overlay, or inspect with snapshot/screenshot before retrying.`}):null}function J(e,t,n){let{req:r,sessionStore:i,session:a,command:o,publicFlags:s}=e;w(i,a,r,o,{ref:t.ref,action:n},{flags:s})}function Y(e){return{...v(e)??{}}}function X(e,t,n){let r={matches:e.length,candidates:e.slice(0,5).map(e=>c(e,0,!1))};return h(`AMBIGUOUS_MATCH`,`find matched ${e.length} elements for ${t} "${n}". Use a more specific locator or selector.`,{locator:t,query:n,...r})}function Z(e){return e!==`role`}export{X as buildAmbiguousMatchError,D as handleFindCommands};
|
package/dist/src/finders.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{fn as e}from"./sdk-batch-runner.js";import{t}from"./sdk-finders.js";export{t as findBestMatchesByLocator,e as parseFindArgs};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{g as e}from"./sdk-batch-runner.js";import{
|
|
1
|
+
import{g as e}from"./sdk-batch-runner.js";import{Jt as t}from"./internal/daemon.js";import{S as n,b as r}from"./selector-runtime.js";import{t as i}from"./interaction-runtime.js";import{t as a}from"./interaction-snapshot.js";function o(t){if(!e(t.command))return{};let i=n(t.command,t.flags);if(i)return{response:i};let a=r(t.flags);if(!a)return{};let o=t.session.snapshot?.nodes??[];return{observe:async()=>await s(t,a,o)}}async function s(e,n,r){let i=c(e);if(!i)return;let a=await i.interactions.settleObservation({...n,baselineNodes:r,session:e.sessionName,requestId:e.req.meta?.requestId}),o=t(e.session,a);return o===void 0?a:{...a,refsGeneration:o}}function c(e){try{return i({req:e.req,sessionName:e.sessionName,logPath:e.logPath,sessionStore:e.sessionStore,contextFromFlags:e.contextFromFlags,captureSnapshotForSession:a})}catch{return}}export{o as planGenericSettleObservation};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./screenshot-result.js";function e(e,t,n,r,i,a){t&&e.recordAction(t,{command:r,positionals:a?.positionals??n.positionals??[],flags:a?.flags??n.flags??{},result:i??{}})}export{e as t};
|
package/dist/src/harmonyos.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{_ as e}from"./sdk-contracts.js";import{
|
|
1
|
+
import{_ as e}from"./sdk-contracts.js";import{I as t}from"./sdk-android-adb.js";import{n}from"./hdc.js";import{i as r,n as i}from"./app-lifecycle2.js";import{appSwitcherHarmony as a,backHarmony as o,doubleClickHarmony as s,fillHarmony as c,homeHarmony as l,longPressHarmony as u,n as d,performHarmonyGesture as f,pressHarmony as p,scrollHarmony as m,setHarmonyOrientation as h,t as g,typeHarmony as _}from"./input-actions2.js";import{randomUUID as v}from"node:crypto";import{promises as y}from"node:fs";async function b(t,r){let i=`/data/local/tmp/agent-device-screen-${v()}.jpeg`;try{await n(t,[`shell`,`snapshot_display`,`-f`,i],{timeoutMs:15e3}),await n(t,[`file`,`recv`,i,r],{timeoutMs:15e3});let a=await y.readFile(r);if(a.length<3||a[0]!==255||a[1]!==216||a[2]!==255)throw new e(`COMMAND_FAILED`,`HarmonyOS screenshot is not a JPEG file`)}finally{await n(t,[`shell`,`rm`,`-f`,i],{allowFailure:!0}).catch(()=>{})}}async function x(t,r,i,a){if(r!==`clear-app-state`)throw new e(`UNSUPPORTED_OPERATION`,`HarmonyOS setting "${r}" is not supported`,{hint:`HarmonyOS currently supports settings clear-app-state for an app bundle only.`});if(i!==`clear`)throw new e(`INVALID_ARGS`,`settings clear-app-state only supports clear.`);if(!a)throw new e(`INVALID_ARGS`,`settings clear-app-state requires an app id or an active app session.`);return await n(t,[`shell`,`aa`,`force-stop`,a],{timeoutMs:15e3}),await n(t,[`shell`,`bm`,`clean`,`-n`,a,`-d`,`-c`],{timeoutMs:15e3}),{bundleId:a,forceStopped:!0,clearedData:!0,clearedCache:!0}}function S(n,v){let y=t=>async()=>{throw new e(`UNSUPPORTED_OPERATION`,`${t} is not supported on HarmonyOS`)};return{open:(e,t)=>r(n,e,{activity:t?.activity}),openDevice:()=>l(n),close:e=>i(n,e),tap:(e,t)=>p(n,e,t),doubleTap:(e,t)=>s(n,e,t),longPress:(e,t,r)=>u(n,e,t,r),focus:(e,t)=>p(n,e,t),type:(e,t)=>_(n,e,t),fill:(e,t,r,i)=>c(n,e,t,r,i),scroll:(e,t)=>m(n,e,t),performGesture:e=>f(n,e),gestureViewport:()=>g(n),screenshot:e=>b(n,e),snapshot:async e=>({...await t(`snapshot_capture`,async()=>await d(n,e),{backend:`harmonyos-arkui`}),backend:`harmonyos-arkui`}),back:()=>o(n),home:()=>l(n),setOrientation:e=>h(n,e),appSwitcher:()=>a(n),tvRemote:y(`tv-remote`),readClipboard:y(`clipboard`),writeClipboard:y(`clipboard`),setSetting:(e,t,r)=>x(n,e,t,r)}}export{S as createHarmonyInteractor};
|
package/dist/src/hdc.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{o as e}from"./png-worker-contract.js";import{v as t}from"./sdk-android-adb.js";import n from"node:path";import{promises as r}from"node:fs";var i=e({DEFAULT_HARMONY_HDC_TIMEOUT_MS:()=>a,ensureHarmonyToolchainPathConfigured:()=>s,runHarmonyHdc:()=>o});const a=15e3;async function o(e,n,r){return await t(`hdc`,[`-t`,e.id,...n],{timeoutMs:a,...r})}async function s(e=process.env){let t=[e.HDC_SDK_PATH,e.DEVECO_SDK_HOME?n.join(e.DEVECO_SDK_HOME,`default`,`openharmony`,`toolchains`):void 0,e.HARMONYOS_COMMAND_LINE_TOOLS?n.join(e.HARMONYOS_COMMAND_LINE_TOOLS,`sdk`,`default`,`openharmony`,`toolchains`):void 0].filter(e=>!!e?.trim()),i=[];for(let e of t)try{await r.access(n.join(e,`hdc`),r.constants.X_OK),i.push(e)}catch{}if(i.length===0)return;let a=(e.PATH??``).split(n.delimiter).filter(Boolean);e.PATH=[...new Set([...i,...a])].join(n.delimiter)}export{o as n,i as t};
|
package/dist/src/helper.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{o as e}from"./png-worker-contract.js";import{_ as t}from"./sdk-contracts.js";import{
|
|
1
|
+
import{o as e}from"./png-worker-contract.js";import{_ as t}from"./sdk-contracts.js";import{g as n,y as r}from"./sdk-android-adb.js";import{i,r as a,t as o}from"./tool-provider.js";import s from"node:path";import{createHash as c}from"node:crypto";import{existsSync as l,promises as u}from"node:fs";import d from"node:os";import{fileURLToPath as f}from"node:url";var p=e({quitMacOsApp:()=>N,resolveFrontmostMacOsApp:()=>M,resolveMacOsHelperPackageRootFrom:()=>x,runMacOsAlertAction:()=>F,runMacOsPermissionAction:()=>P,runMacOsPressAction:()=>R,runMacOsReadTextAction:()=>L,runMacOsScreenshotAction:()=>z,runMacOsSnapshotAction:()=>I,startMacOsAudioProbeProcess:()=>A});const m=`agent-device-macos-helper`,h=`AGENT_DEVICE_MACOS_HELPER_BIN`,g=s.join(d.homedir(),`.agent-device`,`macos-helper`,`current`),_=s.join(g,`manifest.json`),v=/^[A-Za-z0-9_-]+(?:\.[A-Za-z0-9_-]+)+$/;function y(e){let n=e.trim();if(!v.test(n))throw new t(`INVALID_ARGS`,`macOS bundle id must use reverse-DNS form like com.example.App`,{bundleId:e});return n}function b(e,t){t.bundleId&&e.push(`--bundle-id`,y(t.bundleId)),t.surface&&e.push(`--surface`,t.surface)}function x(e){let n=s.dirname(e);for(;;){let e=s.join(n,`apple`,`macos-helper`);if(l(s.join(e,`Package.swift`)))return e;let t=s.dirname(n);if(t===n)break;n=t}throw new t(`COMMAND_FAILED`,`Unable to locate macOS helper package root`,{modulePath:e})}function S(){return x(f(import.meta.url))}function C(){return s.join(S(),`.build`,`release`,m)}function w(){return s.join(g,m)}async function T(e){let t=await u.readdir(e,{withFileTypes:!0});return(await Promise.all(t.map(async t=>{let n=s.join(e,t.name);return t.isDirectory()?t.name===`.build`?[]:await T(n):!t.isFile()||!t.name.endsWith(`.swift`)&&t.name!==`Package.swift`?[]:[n]}))).flat().sort()}async function E(e){let t=await T(e),n=c(`sha256`);for(let r of t)n.update(s.relative(e,r)),n.update(`\0`),n.update(await u.readFile(r)),n.update(`\0`);let r=await i(`swift`,[`--version`],{allowFailure:!0,cwd:e,timeoutMs:1e4});return n.update(`swift-version`),n.update(`\0`),n.update(r.stdout||r.stderr||`exit:${r.exitCode}`),n.update(`\0`),n.digest(`hex`)}async function D(){try{let e=JSON.parse(await u.readFile(_,`utf8`));return typeof e.fingerprint==`string`?e.fingerprint:null}catch{return null}}async function O(){let e=await n(process.env[h],h);if(e)return e;let t=S(),r=await E(t),a=w();try{if(await D()===r)return await u.access(a),a}catch{}let o=C();process.stderr.write(`agent-device: building macOS helper (first run or helper update)
|
|
2
2
|
`),await i(`swift`,[`build`,`-c`,`release`,`--package-path`,t],{cwd:t,timeoutMs:12e4}),await u.mkdir(g,{recursive:!0});let s=`${a}.tmp`;return await u.copyFile(o,s),await u.rename(s,a),await u.chmod(a,493),await u.writeFile(_,`${JSON.stringify({fingerprint:r},null,2)}\n`,`utf8`),a}async function k(){let e=process.env[h]?.trim();if(e){let t=await n(e,h);if(t)return t}if(o())return m;if(process.platform!==`darwin`)throw new t(`UNSUPPORTED_PLATFORM`,`macOS helper is only available on macOS`);return await O()}async function A(e){return r(await k(),[`audio-probe`,`--duration-ms`,String(e.durationMs),`--bucket-ms`,String(e.bucketMs),`--out`,e.statusPath],{allowFailure:!0,captureOutput:!0})}async function j(e,n={}){let r={allowFailure:!0,timeoutMs:3e4,signal:n.signal},o=a().macosHelper,s=o?m:await k(),c=o?await o.run(e,r):await i(s,e,r),l=c.stdout.trim(),u=null;if(l)try{u=JSON.parse(l)}catch{u=null}if(c.exitCode===0&&u?.ok)return u.data;throw new t(`COMMAND_FAILED`,u&&!u.ok?u.error?.message??`macOS helper exited with code ${c.exitCode}`:l||c.stderr.trim()||`macOS helper exited with code ${c.exitCode}`,{helperPath:s,args:e,stdout:c.stdout,stderr:c.stderr,exitCode:c.exitCode,...u&&!u.ok?u.error?.details:{}})}async function M(){return await j([`app`,`frontmost`])}async function N(e){return await j([`app`,`quit`,`--bundle-id`,y(e)])}async function P(e,t){return await j([`permission`,e,t])}async function F(e,t={}){let n=[`alert`,e];return b(n,t),await j(n)}async function I(e,t={}){let n=[`snapshot`,`--surface`,e];return b(n,t),await j(n,{signal:t.signal})}async function L(e,t,n={}){let r=[`read`,`--x`,String(e),`--y`,String(t)];return b(r,n),await j(r)}async function R(e,t,n={}){let r=[`press`,`--x`,String(e),`--y`,String(t)];return b(r,n),await j(r)}async function z(e,t={}){let n=[`screenshot`,`--out`,e];return b(n,t),t.fullscreen&&n.push(`--fullscreen`),await j(n)}export{P as a,A as c,F as i,N as n,z as o,M as r,I as s,p as t};
|
package/dist/src/host-process.js
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import{
|
|
2
|
-
`)){let
|
|
1
|
+
import{C as e,v as t}from"./sdk-android-adb.js";import{t as n}from"./timeouts.js";const r=1e3,i=process.platform===`win32`?`ps`:`/bin/ps`;function a(e){if(!Number.isInteger(e)||e<=0)return!1;try{return process.kill(e,0),!0}catch(e){return e.code===`EPERM`}}function o(e){if(!Number.isInteger(e)||e<=0)return!1;try{return process.kill(-e,0),!0}catch(e){return e.code===`EPERM`}}function s(e){return d(e,`lstart=`)}function c(e){return d(e,`command=`)}function l(e){return d(e,`state=`)?.startsWith(`Z`)??!1}function u(t){let n=new Map,i=h(t);if(i.length===0)return n;try{let t=e(`ps`,[`-p`,i.join(`,`),`-o`,`pid=,state=,lstart=`],{allowFailure:!0,timeoutMs:r});if(t.exitCode!==0)return n;for(let e of t.stdout.split(`
|
|
2
|
+
`)){let t=/^\s*(\d+)\s+(\S+)\s+(.+?)\s*$/.exec(e);if(!t)continue;let r=Number.parseInt(t[1],10);!Number.isInteger(r)||r<=0||n.set(r,{state:t[2],startTime:t[3]})}}catch{}return n}function d(t,n){if(!Number.isInteger(t)||t<=0)return null;try{let a=e(i,[`-p`,String(t),`-o`,n],{allowFailure:!0,timeoutMs:r});if(a.exitCode!==0)return null;let o=a.stdout.trim();return o.length>0?o:null}catch{return null}}function f(e){let t=[];for(let n of e.split(`
|
|
3
|
+
`)){let e=/^\s*(\d+)\s+(\d+)\s+(.+?)\s*$/.exec(n);if(!e)continue;let r=Number.parseInt(e[1],10),i=Number.parseInt(e[2],10),a=e[3];!Number.isInteger(r)||r<=0||t.push({pid:r,ppid:Number.isInteger(i)&&i>0?i:void 0,command:a})}return t}async function p(e){let n=await(e.runCommand??t)(e.runCommand?`ps`:i,[`-ax`,`-o`,`pid=,ppid=,command=`],{allowFailure:!0,timeoutMs:e.timeoutMs});return n.exitCode===0?f(n.stdout):[]}function m(e,t){let n=new Set(h(e)),r=!0;for(;r;){r=!1;for(let e of t)e.ppid===void 0||!n.has(e.ppid)||n.has(e.pid)||(n.add(e.pid),r=!0)}return t.filter(e=>n.has(e.pid))}function h(e,t={}){return[...new Set(e)].filter(e=>Number.isInteger(e)&&e>0&&e!==t.excludePid)}function g(e,t){let n=h(e,{excludePid:process.pid}),r=0;for(let e of n)try{process.kill(e,t),r+=1}catch{}return r}async function _(e,t){if(!a(e))return!0;let r=Date.now();for(;Date.now()-r<t;)if(await n(50),!a(e))return!0;return!a(e)}async function v(e){let t=h(e.pids,{excludePid:process.pid});t.length!==0&&(g(t,`SIGTERM`),await Promise.all(t.map(async t=>await _(t,e.termTimeoutMs))),g(t.filter(e=>a(e)),`SIGKILL`),await Promise.all(t.map(async t=>await _(t,e.killTimeoutMs))))}export{p as a,s as c,_ as d,l as i,g as l,a as n,u as o,o as r,c as s,m as t,v as u};
|