agent-device 0.19.2 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +61 -70
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.0.apk +0 -0
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.0.apk.sha256 +1 -0
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.0.manifest.json +10 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.0.apk +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.0.apk.sha256 +1 -0
- package/{android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.19.2.manifest.json → android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.0.manifest.json} +6 -6
- package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.h +2 -0
- package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.m +5 -0
- package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.h +12 -10
- package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.m +154 -185
- package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Alert.swift +113 -19
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+BlockingSystemModalResolution.swift +82 -0
- package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +275 -113
- package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +2 -2
- package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +150 -104
- package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +56 -2
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+LifecycleCacheTests.swift +73 -0
- package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +44 -14
- package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollGesture.swift +2 -2
- package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SequenceExecution.swift +2 -106
- package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +126 -11
- package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +51 -8
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotTraversalIdentityTests.swift +24 -0
- package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedGesturePolicy.swift +1 -1
- package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SystemModal.swift +43 -35
- package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +14 -0
- package/dist/src/agent-browser-tool.js +1 -1
- package/dist/src/agent-device-client.js +3 -0
- package/dist/src/android-adb.d.ts +1 -1
- package/dist/src/android-adb.js +1 -1
- package/dist/src/android-input-method-overlays.js +1 -0
- package/dist/src/android-input-ownership.js +1 -6
- package/dist/src/android-system-chrome.js +1 -0
- package/dist/src/android.js +1 -1
- package/dist/src/app-lifecycle.js +5 -5
- package/dist/src/app-log-request-scope.js +1 -0
- package/dist/src/app-resolution.js +1 -0
- package/dist/src/apple-multitouch-support.js +1 -0
- package/dist/src/apps.js +5 -5
- package/dist/src/audio-probe.js +1 -1
- package/dist/src/boot-diagnostics.js +2 -0
- package/dist/src/cli-config.js +1 -0
- package/dist/src/cli-help.js +64 -30
- package/dist/src/cli-runner.js +1 -1
- package/dist/src/cli.js +15 -11
- package/dist/src/command-schema.js +3 -3
- package/dist/src/config.js +1 -0
- package/dist/src/context.js +1 -0
- package/dist/src/contracts.d.ts +1 -1
- package/dist/src/contracts.js +1 -1
- package/dist/src/daemon-shutdown-report.js +1 -0
- package/dist/src/debug-symbols.js +1 -1
- package/dist/src/device-input-state.js +1 -1
- package/dist/src/devices2.js +1 -1
- package/dist/src/find.js +1 -1
- package/dist/src/finders.js +1 -1
- package/dist/src/generic.js +1 -1
- package/dist/src/helper.js +1 -1
- package/dist/src/index.d.ts +412 -289
- package/dist/src/index.js +1 -1
- package/dist/src/input-actions.js +4 -3
- package/dist/src/input-actions2.js +1 -1
- package/dist/src/install-artifact.js +1 -0
- package/dist/src/install-source.d.ts +5 -1
- package/dist/src/install-source.js +1 -1
- package/dist/src/install-source2.js +1 -1
- package/dist/src/interaction-snapshot.js +1 -1
- package/dist/src/interaction.d.ts +230 -0
- package/dist/src/interaction.js +1 -1
- package/dist/src/interactor.js +2 -2
- package/dist/src/internal/bin.js +1 -1
- package/dist/src/internal/daemon.js +43 -17
- package/dist/src/internal/png-worker.d.ts +22 -0
- package/dist/src/internal/png-worker.js +1 -1
- package/dist/src/launch-console.js +1 -0
- package/dist/src/lease-context.js +1 -0
- package/dist/src/lease.js +1 -1
- package/dist/src/linux.js +1 -1
- package/dist/src/logcat.js +5 -0
- package/dist/src/metro.d.ts +2 -2
- package/dist/src/notifications.js +1 -1
- package/dist/src/png-worker-contract.js +1 -1
- package/dist/src/process-lock.js +1 -0
- package/dist/src/react-native.js +1 -1
- package/dist/src/record-trace.js +1 -1
- package/dist/src/register-builtins.js +1 -0
- package/dist/src/registry.js +24 -24
- package/dist/src/reporting.js +8 -7
- package/dist/src/runner-client.js +1 -1
- package/dist/src/runner-disposal.js +2 -0
- package/dist/src/runner-lease.js +1 -0
- package/dist/src/runner-sequence.js +1 -1
- package/dist/src/runtime-transport.js +1 -1
- package/dist/src/runtime.js +3 -3
- package/dist/src/runtime2.js +1 -0
- package/dist/src/sdk-android-adb.d.ts +119 -33
- package/dist/src/sdk-android-adb.js +4 -4
- package/dist/src/sdk-app-inventory.js +1 -1
- package/dist/src/sdk-batch-runner.d.ts +2 -1
- package/dist/src/sdk-batch-runner.js +2 -2
- package/dist/src/sdk-batch.js +2 -2
- package/dist/src/sdk-contracts.d.ts +105 -98
- package/dist/src/sdk-contracts.js +2 -2
- package/dist/src/sdk-device.js +1 -0
- package/dist/src/sdk-finders.d.ts +3 -3
- package/dist/src/sdk-finders.js +1 -1
- package/dist/src/sdk-io.d.ts +1 -1
- package/dist/src/sdk-io.js +1 -1
- package/dist/src/sdk-remote-config.d.ts +9 -1
- package/dist/src/sdk-remote-config.js +1 -1
- package/dist/src/sdk-selectors.js +1 -1
- package/dist/src/selector-runtime.js +1 -1
- package/dist/src/selector-vocabulary.js +1 -0
- package/dist/src/selectors.d.ts +12 -3
- package/dist/src/selectors.js +1 -1
- package/dist/src/server.js +3 -3
- package/dist/src/session-target-evidence.js +1 -0
- package/dist/src/session.js +8 -10
- package/dist/src/setting-state.js +1 -1
- package/dist/src/simulator.js +1 -1
- package/dist/src/snapshot-diagnostics.js +5 -2
- package/dist/src/snapshot.js +1 -1
- package/dist/src/snapshot2.js +1 -2
- package/dist/src/tool-provider.js +2 -2
- package/dist/src/tool-provider2.js +1 -1
- package/dist/src/tv-remote.js +13 -12
- package/dist/src/url.js +1 -1
- package/dist/src/web.js +1 -1
- package/package.json +33 -20
- package/server.json +2 -2
- package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.19.2.apk +0 -0
- package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.19.2.apk.sha256 +0 -1
- package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.19.2.manifest.json +0 -10
- package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.19.2.apk +0 -0
- package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.19.2.apk.sha256 +0 -1
- package/dist/src/apple-runner-options.js +0 -1
- package/dist/src/cli-output.js +0 -1
- package/dist/src/client.js +0 -3
- package/dist/src/handler-utils.js +0 -1
- package/dist/src/output-path.js +0 -1
- package/dist/src/points.js +0 -4
- package/dist/src/provider.js +0 -1
- package/dist/src/providers.js +0 -1
- package/dist/src/record-trace-recording.js +0 -23
- package/dist/src/recording-provider.js +0 -1
- package/dist/src/selectors2.js +0 -1
- package/dist/src/simctl.js +0 -1
- package/dist/src/snapshot-helper.js +0 -5
- package/dist/src/ttl-memo.js +0 -1
- package/dist/src/xml.js +0 -2
- /package/{macos-helper → apple/macos-helper}/Package.swift +0 -0
- /package/{macos-helper → apple/macos-helper}/Sources/AgentDeviceMacOSHelper/AudioProbe.swift +0 -0
- /package/{macos-helper → apple/macos-helper}/Sources/AgentDeviceMacOSHelper/SnapshotTraversal.swift +0 -0
- /package/{macos-helper → apple/macos-helper}/Sources/AgentDeviceMacOSHelper/main.swift +0 -0
- /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunner/AgentDeviceRunnerApp.m +0 -0
- /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/project.pbxproj +0 -0
- /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -0
- /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/xcshareddata/xcschemes/AgentDeviceRunner.xcscheme +0 -0
- /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/AgentDeviceRunnerUITests-Bridging-Header.h +0 -0
- /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/AgentDeviceRunnerUITests.entitlements +0 -0
- /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerObjCExceptionCatcher.h +0 -0
- /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerObjCExceptionCatcher.m +0 -0
- /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTapPointPolicy.swift +0 -0
- /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +0 -0
- /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Environment.swift +0 -0
- /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Exceptions.swift +0 -0
- /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+FlatSnapshotFiltering.swift +0 -0
- /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Navigation.swift +0 -0
- /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScreenRecorder.swift +0 -0
- /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +0 -0
- /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Transport.swift +0 -0
- /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TvRemote.swift +0 -0
- /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests.xctestplan +0 -0
- /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/RecordingScripts/recording-overlay.swift +0 -0
- /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/RecordingScripts/recording-resize.swift +0 -0
- /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/RecordingScripts/recording-trim.swift +0 -0
- /package/{src/platforms/linux → linux}/atspi-dump.py +0 -0
package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.19.2.manifest.json
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "android-multitouch-helper",
|
|
3
|
-
"version": "0.19.2",
|
|
4
|
-
"assetName": "agent-device-android-multitouch-helper-0.19.2.apk",
|
|
5
|
-
"sha256": "549ac62f2086d5e94cf74441cc45b33aa008986bcdb7b586d44dfcab8173a81d",
|
|
6
|
-
"packageName": "com.callstack.agentdevice.multitouchhelper",
|
|
7
|
-
"versionCode": 19002,
|
|
8
|
-
"instrumentationRunner": "com.callstack.agentdevice.multitouchhelper/.MultiTouchInstrumentation",
|
|
9
|
-
"statusProtocol": "android-multitouch-helper-v1"
|
|
10
|
-
}
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
60d183feab3155104cd6e8f9eb3a6193f89483e207497097361856ca53e2dae7 agent-device-android-snapshot-helper-0.19.2.apk
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{F as e,p as t}from"./sdk-contracts.js";import{p as n}from"./sdk-android-adb.js";import{D as r}from"./android-input-ownership.js";import{n as i}from"./runner-client.js";import{o as a}from"./tool-provider.js";import{t as o}from"./ttl-memo.js";import{H as s,W as c,gn as l,zt as u}from"./internal/daemon.js";import{promises as d}from"node:fs";import f from"node:os";import p from"node:path";const m=o({ttlMs:5e3});async function h(e,n={}){if(l(e))return;let r=_(e);if(m.get(r)===!0){if(!n.focusExisting)return;m.delete(r)}if(t(e)){if(e.kind===`simulator`){let{ensureBootedSimulator:t}=await import(`./simulator.js`).then(e=>e.o);await t(e,{deviceHub:n.deviceHub,focusExisting:n.focusExisting,onColdBootStart:n.onIosSimulatorColdBootStart}),g(r);return}if(e.kind===`device`){await v(e.id),g(r);return}}if(e.platform===`android`){let{waitForAndroidBoot:t}=await import(`./android-input-ownership.js`).then(e=>e.m);await t(e.id),g(r)}}function g(e){m.set(e,!0)}function _(e){let t=e.kind===`simulator`?e.simulatorSetPath??``:``;return JSON.stringify([e.platform,e.kind,e.id,e.target??``,t])}async function v(t){let r=p.join(f.tmpdir(),`agent-device-ready-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);try{let i=await a([`devicectl`,`device`,`info`,`details`,`--device`,t,`--json-output`,r,`--timeout`,`15`],{allowFailure:!0,timeoutMs:18e3}),{stdout:o,stderr:s}=i,c=await b(r);if(i.exitCode===0){if(!c.parsed)throw new e(`COMMAND_FAILED`,`iOS device readiness probe failed`,{kind:`probe_inconclusive`,deviceId:t,stdout:o,stderr:s,hint:`CoreDevice returned success but readiness JSON output was missing or invalid. Retry; if it persists restart Xcode and the iOS device.`});let n=c?.tunnelState?.toLowerCase();if(n===`connecting`)throw new e(`COMMAND_FAILED`,`iOS device is not ready for automation`,{kind:`not_ready`,deviceId:t,tunnelState:n,hint:`Device tunnel is still connecting. Keep the device unlocked and connected by cable until it is fully available in Xcode Devices, then retry.`});return}throw new e(`COMMAND_FAILED`,`iOS device is not ready for automation`,n(i,{kind:`not_ready`,deviceId:t,tunnelState:c?.tunnelState,hint:x(o,s)}))}catch(n){if(n instanceof e&&n.code===`COMMAND_FAILED`){if((typeof n.details?.kind==`string`?n.details.kind:``)===`not_ready`)throw n;let r=n.details??{},i=String(r.stdout??``),a=String(r.stderr??``),o=Number(r.timeoutMs??15e3),s=`CoreDevice did not respond within ${o}ms. Keep the device unlocked and trusted, then retry; if it persists restart Xcode and the iOS device.`;throw new e(`COMMAND_FAILED`,`iOS device readiness probe failed`,{deviceId:t,cause:n.message,timeoutMs:o,stdout:i,stderr:a,hint:i||a?x(i,a):s},n)}throw new e(`COMMAND_FAILED`,`iOS device readiness probe failed`,{deviceId:t,hint:`Reconnect the device, keep it unlocked, and retry.`},n instanceof Error?n:void 0)}finally{await d.rm(r,{force:!0}).catch(()=>{})}}function y(e){let t=e?.result;if(!t||typeof t!=`object`)return{};let n=t.connectionProperties?.tunnelState,r=t.device?.connectionProperties?.tunnelState,i=typeof n==`string`?n:typeof r==`string`?r:void 0;return i?{tunnelState:i}:{}}async function b(e){try{let t=await d.readFile(e,`utf8`);return{parsed:!0,tunnelState:y(JSON.parse(t)).tunnelState}}catch{return{parsed:!1}}}function x(e,t){return c(e,t)||(`${e}\n${t}`.toLowerCase().includes(`timed out waiting for all destinations`)?`Xcode destination did not become available in time. Keep device unlocked and retry.`:s)}function S(e){let{req:t,logPath:n,traceLogPath:r}=e;return{verbose:t.flags?.verbose,logPath:n,traceLogPath:r,requestId:t.meta?.requestId,iosXctestrunFile:t.flags?.iosXctestrunFile,iosXctestDerivedDataPath:t.flags?.iosXctestDerivedDataPath,iosXctestEnvDir:t.flags?.iosXctestEnvDir}}function C(e){let{req:t,logPath:n,appBundleId:r,traceLogPath:i}=e;return{...S({req:t,logPath:n,traceLogPath:i}),runnerLeaseContext:u(n,t.flags,r,i,t.meta?.requestId,t.meta).runnerLeaseContext}}function w(e){let{req:n,logPath:r,device:a,traceLogPath:o,enabled:s}=e;if(!(!s||!t(a)||a.kind!==`simulator`))return e=>i(e,S({req:n,logPath:r,traceLogPath:o}))}function T(e){let{req:t,logPath:n,device:i,surface:a,openTarget:o,traceLogPath:s}=e;return w({req:t,logPath:n,device:i,traceLogPath:s,enabled:a===`app`&&!!o&&!r(o??``)})}export{h as a,w as i,C as n,T as r,S as t};
|
package/dist/src/cli-output.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./registry.js";const t=e();function n(e){return t[e.name]?.({input:e.input??{},result:e.result})}export{n as t};
|
package/dist/src/client.js
DELETED
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./rolldown-runtime.js";import{F as t,H as n,a as r}from"./sdk-contracts.js";import{A as i,C as a,F as o,b as s,j as c,v as l,x as u}from"./sdk-android-adb.js";import{g as d}from"./sdk-batch.js";import{An as f,Fn as p,Qn as m,Zn as h,mn as ee}from"./tv-remote.js";import{i as te,n as ne}from"./output-path.js";import{C as g,O as re,T as ie,b as ae,g as oe,h as se,l as ce,m as le,n as ue,s as de,u as fe,v as _,w as pe,y as me}from"./snapshot-diagnostics.js";import{n as v,t as he}from"./version.js";import{n as ge}from"./path-resolution.js";import{t as y}from"./timeouts.js";import{u as _e}from"./host-process.js";import{A as ve,C as ye,D as be,E as xe,O as Se,P as Ce,S as we,T as Te,b as Ee,d as De,f as Oe,i as ke,k as Ae,p as je,s as Me,w as Ne,x as Pe,y as Fe}from"./registry.js";import{l as Ie,m as b,v as x}from"./sdk-batch-runner.js";import{n as Le,t as Re}from"./url.js";import{t as ze}from"./client-metro-companion.js";import{n as Be,r as Ve}from"./project-runtime.js";import{t as He}from"./runtime-transport.js";import{t as Ue}from"./command-metadata.js";import{createHash as We,randomUUID as Ge}from"node:crypto";import S from"node:fs";import Ke from"node:os";import C from"node:path";import w from"node:http";import T from"node:https";import{pipeline as qe}from"node:stream/promises";import{Transform as Je,Writable as Ye}from"node:stream";import E from"node:net";const Xe=`/agent-device`;function Ze(e){return D(e,Xe)}function D(e,t){let n=e.endsWith(`/`)?e:`${e}/`;return new URL(t.replace(/^\/+/,``),n).toString()}function O(e){let t=e?.trim();return t?{authorization:`Bearer ${t}`,"x-agent-device-token":t}:{}}async function Qe(e,t){let n=S.statSync(e),r=C.basename(e),i=n.isDirectory(),a=tt(t)??et(e,n),o=[];try{let t=i?await $e(e,o):e,n=S.statSync(t);return{payloadPath:t,fileName:r,artifactType:i?`app-bundle`:`file`,platform:a,contentType:i?`application/gzip`:`application/octet-stream`,sha256:await rt(t),sizeBytes:n.size,cleanup:()=>nt(o)}}catch(e){throw nt(o),e}}async function $e(e,t){let n=S.mkdtempSync(C.join(Ke.tmpdir(),`agent-device-upload-${Ge()}-`));t.push(n);let r=C.join(n,`${C.basename(e)}.tar.gz`);return await l(`tar`,[`czf`,r,`-C`,C.dirname(e),C.basename(e)],{env:{...process.env,COPYFILE_DISABLE:`1`}}),r}function et(e,t){let n=e.toLowerCase();if(t.isDirectory()&&n.endsWith(`.app`)||n.endsWith(`.ipa`))return`ios`;if(n.endsWith(`.apk`)||n.endsWith(`.aab`))return`android`}function tt(e){return e===`ios`||e===`android`?e:void 0}function nt(e){for(let t of e)S.rmSync(t,{recursive:!0,force:!0})}async function rt(e){let n=We(`sha256`),r=new Ye({write(e,t,r){n.update(e),r()}});return await qe(S.createReadStream(e),r).catch(e=>{throw new t(`COMMAND_FAILED`,`Failed to read local artifact`,{},e instanceof Error?e:void 0)}),n.digest(`hex`)}function it(e){let{stage:t,fileName:n,startOffset:r,totalBytes:i,onProgress:a}=e,o=r,s=st(i),c=Math.min(i,r+s);return new Je({transform(e,r,l){o=Math.min(i,o+e.byteLength),o>=c&&(a?.({type:`progress`,stage:t,fileName:n,transferredBytes:o,totalBytes:i}),c=Math.min(i,o+s)),l(null,e)}})}function at(){if(!(process.stderr.isTTY!==!0||process.env.CI))return e=>{process.stderr.write(`${ot(e)}\n`)}}function ot(e){switch(e.type){case`start`:return`Uploading ${e.fileName} (${k(e.totalBytes)}) via ${ct(e.stage)} upload`;case`resume`:return`Resuming ${e.fileName} at ${k(e.transferredBytes)} of ${k(e.totalBytes)}`;case`progress`:return`Uploaded ${k(e.transferredBytes)} of ${k(e.totalBytes)} (${lt(e.transferredBytes,e.totalBytes)})`;case`fallback`:return`Direct upload did not complete; retrying ${e.fileName} with ${ct(e.to)} upload`}}function st(e){return Math.max(8388608,Math.ceil(e*.05))}function ct(e){return e===`direct`?`direct`:`legacy`}function lt(e,t){return t<=0?`100%`:`${Math.min(100,Math.floor(e/t*100))}%`}function k(e){if(e<1024)return`${e} B`;let t=e/1024;if(t<1024)return`${t.toFixed(1)} KiB`;let n=t/1024;return n<1024?`${n.toFixed(1)} MiB`:`${(n/1024).toFixed(1)} GiB`}const ut=300*1e3,dt=`uploadStreamRetryable`;async function ft(e){return await A({...e,url:e.url,redirectCount:0,startOffset:0})}function pt(e){return e instanceof t&&e.details?.[dt]===!0}async function A(e){let n=e.url.protocol===`https:`?T:w,r=S.statSync(e.payloadPath).size,i=gt(e.headers,e.startOffset,r);return ht(e.progress,e.startOffset,r),await new Promise((a,o)=>{let s=!1,c=n.request({protocol:e.url.protocol,host:e.url.hostname,port:e.url.port,method:e.method,path:e.url.pathname+e.url.search,headers:i},n=>{s=!0,re(n).then(i=>{clearTimeout(l);let s=n.statusCode??500,c=n.headers.location;if(c&&_t(s)){if(e.redirectCount>=5){o(new t(`COMMAND_FAILED`,`Artifact upload exceeded redirect limit`,{maxRedirects:5,url:e.url.toString()}));return}let n=new URL(c,e.url);A({...e,url:n,redirectCount:e.redirectCount+1}).then(a,o);return}let u=vt(s)?yt(n.headers,r):void 0;if(u!==void 0){if(u>=r){a({statusCode:200,statusMessage:`Upload already complete`,body:``});return}if(u<=e.startOffset){o(new t(`COMMAND_FAILED`,`Artifact upload resume did not advance`,{offset:u,previousOffset:e.startOffset,url:e.url.toString()}));return}A({...e,startOffset:u}).then(a,o);return}a({statusCode:s,statusMessage:n.statusMessage,body:i})}).catch(o)}),l=setTimeout(()=>{c.destroy(),o(new t(`COMMAND_FAILED`,e.timeoutMessage,{timeoutMs:ut,...e.timeoutHint?{hint:e.timeoutHint}:{},...mt(e)}))},ut);c.on(`error`,n=>{s||(clearTimeout(l),o(new t(`COMMAND_FAILED`,e.errorMessage,{...e.errorHint?{hint:e.errorHint}:{},...mt(e)},n)))}),c.on(`close`,()=>clearTimeout(l)),qe(S.createReadStream(e.payloadPath,{start:e.startOffset}),it({stage:e.progress?.stage??`legacy`,fileName:e.progress?.fileName??C.basename(e.payloadPath),startOffset:e.startOffset,totalBytes:r,onProgress:e.progress?.onProgress}),c).catch(e=>{s||(c.destroy(),o(new t(`COMMAND_FAILED`,`Failed to read local artifact`,{},e instanceof Error?e:Error(String(e)))))})})}function mt(e){return e.retryable===!0?{[dt]:!0}:{}}function ht(e,t,n){e?.onProgress?.({type:t>0?`resume`:`start`,stage:e.stage,fileName:e.fileName,transferredBytes:t,totalBytes:n})}function gt(e,t,n){return t<=0?e:{...e,"content-length":Math.max(n-t,0),"content-range":`bytes ${t}-${n-1}/${n}`}}function _t(e){return[301,302,303,307,308].includes(e)}function vt(e){return e===308}function yt(e,t){let n=bt(e[`x-upload-offset`]??e[`upload-offset`]);if(n!==void 0)return Math.min(n,t);let r=xt(e.range)?.match(/^bytes=0-(\d+)$/);if(!r)return;let i=Number(r[1]);if(!(!Number.isSafeInteger(i)||i<0))return Math.min(i+1,t)}function bt(e){let t=xt(e);if(t===void 0)return;let n=Number(t);return Number.isSafeInteger(n)&&n>=0?n:void 0}function xt(e){return Array.isArray(e)?e[0]:e}const St=30*1e3;async function Ct(e){let t=await Qe(e.localPath,e.platform),n=e.baseUrl.endsWith(`/`)?e.baseUrl:`${e.baseUrl}/`,r=Ge();try{let i=await Dt({normalizedBase:n,token:e.token,artifact:t,uploadAttemptId:r});return i?.kind===`cache-hit`?i.uploadId:i?.kind===`direct-upload`?await wt({normalizedBase:n,token:e.token,artifact:t,preflight:i,uploadAttemptId:r,onProgress:e.onProgress})||(e.onProgress?.({type:`fallback`,from:`direct`,to:`legacy`,fileName:t.fileName}),await Et({normalizedBase:n,token:e.token,artifact:t,onProgress:e.onProgress})):await Et({normalizedBase:n,token:e.token,artifact:t,onProgress:e.onProgress})}finally{t.cleanup()}}async function wt(e){let t=async t=>(await At(e.artifact,t,e.onProgress),await jt({normalizedBase:e.normalizedBase,token:e.token,uploadId:t.uploadId}));try{return await t(e.preflight)}catch(n){if(!Tt(n))return;let r=await Dt({normalizedBase:e.normalizedBase,token:e.token,artifact:e.artifact,uploadAttemptId:e.uploadAttemptId});if(r?.kind===`cache-hit`)return r.uploadId;if(r?.kind===`direct-upload`)try{return await t(r)}catch{return}return}}function Tt(e){return e instanceof t?pt(e):!0}async function Et(e){let{normalizedBase:n,token:r,artifact:i}=e,a=new URL(`upload`,n),o={"content-type":i.contentType,"x-artifact-type":i.artifactType,"x-artifact-filename":i.fileName,"x-artifact-hash":i.sha256,"x-artifact-hash-algorithm":`sha256`,"transfer-encoding":`chunked`};Object.assign(o,O(r));let s=await ft({url:a,method:`POST`,headers:o,payloadPath:i.payloadPath,timeoutMessage:`Artifact upload timed out`,timeoutHint:`The upload to the remote daemon exceeded the 5-minute timeout.`,errorMessage:`Failed to upload artifact to remote daemon`,errorHint:`Verify the remote daemon is reachable and supports artifact uploads.`,progress:{stage:`legacy`,fileName:i.fileName,onProgress:e.onProgress}});try{let e=JSON.parse(s.body);if(!e.ok||!e.uploadId)throw new t(`COMMAND_FAILED`,`Upload failed: ${s.body}`);return e.uploadId}catch(e){throw e instanceof t?e:new t(`COMMAND_FAILED`,`Invalid upload response: ${s.body}`)}}async function Dt(e){let t=new URL(`upload/preflight`,e.normalizedBase),n={"content-type":`application/json`};Object.assign(n,O(e.token));let r=await fetch(t,{method:`POST`,headers:n,signal:AbortSignal.timeout(St),body:JSON.stringify({uploadAttemptId:e.uploadAttemptId,sha256:e.artifact.sha256,fileName:e.artifact.fileName,sizeBytes:e.artifact.sizeBytes,artifactType:e.artifact.artifactType,...e.artifact.platform?{platform:e.artifact.platform}:{},contentType:e.artifact.contentType})}).catch(()=>void 0);if(r?.ok)return Ot(await r.json().catch(()=>void 0))}function Ot(e){if(!e||typeof e!=`object`)return;let t=e;if(t.ok!==!0||typeof t.uploadId!=`string`)return;if(t.cacheHit===!0)return{kind:`cache-hit`,uploadId:t.uploadId};let n=t.upload;if(!n||typeof n.url!=`string`)return;let r=n.headers??{};if(kt(r))return{kind:`direct-upload`,uploadId:t.uploadId,url:n.url,headers:r}}function kt(e){return!e||typeof e!=`object`||Array.isArray(e)?!1:Object.values(e).every(e=>typeof e==`string`)}async function At(e,n,r){let i=await ft({url:new URL(n.url),method:`PUT`,headers:n.headers,payloadPath:e.payloadPath,timeoutMessage:`Direct artifact upload timed out`,timeoutHint:`The direct upload ticket did not accept the artifact within the timeout.`,errorMessage:`Failed to upload artifact with direct upload ticket`,retryable:!0,progress:{stage:`direct`,fileName:e.fileName,onProgress:r}});if(i.statusCode<200||i.statusCode>=300)throw new t(`COMMAND_FAILED`,`Direct artifact upload failed`,{statusCode:i.statusCode,statusMessage:i.statusMessage})}async function jt(e){let n=new URL(`upload/finalize`,e.normalizedBase),r={"content-type":`application/json`};Object.assign(r,O(e.token));let i=await fetch(n,{method:`POST`,headers:r,signal:AbortSignal.timeout(St),body:JSON.stringify({uploadId:e.uploadId})}).catch(e=>{throw new t(`COMMAND_FAILED`,`Failed to finalize direct artifact upload`,{},e)});if(!i.ok)throw new t(`COMMAND_FAILED`,`Direct artifact upload finalize failed`,{status:i.status,statusText:i.statusText});let a=await i.json().catch(()=>void 0);if(!a?.ok||!a.uploadId)throw new t(`COMMAND_FAILED`,`Invalid upload finalize response`);return a.uploadId}async function Mt(e,t){let n=[...e.positionals??[]],r=e.flags?{...e.flags}:void 0,i=e.meta?.installSource,a={},o,s=at();if(!Jt(t))return Lt({positionals:n,flags:r,installSource:i,uploadedArtifactId:o,clientArtifactPaths:a});r=Pt(e,n,r,a);let c=await Rt(e,t,s);return c&&(i=c.installSource,o=c.uploadedArtifactId??o),e.command!==`install`&&e.command!==`reinstall`||(o=await Nt(e,t,n,s)??o),Lt({positionals:n,flags:r,installSource:i,uploadedArtifactId:o,clientArtifactPaths:a})}async function Nt(e,t,n,r){let i=n.length===1?0:1,a=n[i];if(a===void 0)return;if(a.startsWith(`remote:`)){n[i]=a.slice(7);return}let o=It(a,e.meta?.cwd);if(o)return await Ct({localPath:o,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform,onProgress:r})}function Pt(e,t,n,r){let i=zt(e,t);if(!i)return n;i.positionalPath!==void 0&&(t[i.positionalIndex]=i.positionalPath);let a=Ft(n,i.flagPath);return r[i.field]=i.localPath,a}function Ft(e,t){return t===void 0?e:{...e??{},out:t}}function It(e,t){let n=C.isAbsolute(e)?e:C.resolve(t??process.cwd(),e);return S.existsSync(n)?n:void 0}function Lt(e){return{positionals:e.positionals,flags:e.flags,installSource:e.installSource,uploadedArtifactId:e.uploadedArtifactId,...Object.keys(e.clientArtifactPaths).length>0?{clientArtifactPaths:e.clientArtifactPaths}:{}}}async function Rt(e,t,n){let r=e.meta?.installSource;if(e.command!==`install_source`||!r||r.kind!==`path`)return null;let i=r.path.trim();if(!i)return{installSource:r};if(i.startsWith(`remote:`))return{installSource:{...r,path:i.slice(7)}};let a=C.isAbsolute(i)?i:C.resolve(e.meta?.cwd??process.cwd(),i);if(!S.existsSync(a))return{installSource:{...r,path:a}};let o=await Ct({localPath:a,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform,onProgress:n});return{installSource:{...r,path:a},uploadedArtifactId:o}}function zt(e,t){if(e.command===`screenshot`){let n=Ut(e,`path`,`.png`);return t[0]?{field:`path`,localPath:n,positionalIndex:0,positionalPath:M(`screenshot`,`.png`)}:{field:`path`,localPath:n,positionalIndex:0,flagPath:M(`screenshot`,`.png`)}}if(e.command===`record`&&(t[0]??``).toLowerCase()===`start`){if(!Vt(e)&&e.flags?.platform===void 0)return null;let t=Bt(e),n=Ht(Ut(e,`outPath`,t,1),e);return{field:`outPath`,localPath:n,positionalIndex:1,positionalPath:M(`recording`,C.extname(n)||t)}}return null}function Bt(e){return te(e.flags?.platform)}function Vt(e){return j(e.positionals?.[1])||j(e.flags?.out)}function Ht(e,t){return t.flags?.platform===`web`?ne(e,Bt(t)):e}function Ut(e,t,n,r=0){let i=e.positionals?.[r]??e.flags?.out,a=`${t===`path`?`screenshot`:`recording`}-${Date.now()}${n}`,o=j(i)?i:a;return C.isAbsolute(o)?o:C.resolve(e.meta?.cwd??process.cwd(),o)}function j(e){return typeof e==`string`&&e.trim().length>0}function M(e,t){let n=t.startsWith(`.`)?t:`.${t}`;return C.posix.join(`/tmp`,`agent-device-${e}-${Date.now()}-${Math.random().toString(36).slice(2,8)}${n}`)}async function Wt(e,t,n){let r=Array.isArray(n.data?.artifacts)?n.data.artifacts:[];if(r.length===0||!e.baseUrl)return n;let i=n.data?{...n.data}:{},a=[];for(let n of r){if(!n||typeof n!=`object`||typeof n.artifactId!=`string`){a.push(n);continue}let r=Gt(n,t);await Kt({baseUrl:e.baseUrl,token:e.token,artifactId:n.artifactId,destinationPath:r,requestId:t.meta?.requestId}),i[n.field]=r,a.push({...n,localPath:r})}return i.artifacts=a,{ok:!0,data:i}}function Gt(e,t){if(e.localPath&&e.localPath.trim().length>0)return e.localPath;let n=t.meta?.clientArtifactPaths?.[e.field];if(n&&n.trim().length>0)return n;let r=e.fileName?.trim()||`${e.field}-${Date.now()}`;return C.resolve(t.meta?.cwd??process.cwd(),r)}async function Kt(e){let n=new URL(qt(e.baseUrl,e.artifactId)),r=n.protocol===`https:`?T:w;await S.promises.mkdir(C.dirname(e.destinationPath),{recursive:!0}),await new Promise((i,a)=>{let o=!1,s=e.timeoutMs??9e4,c=t=>{if(!o){if(o=!0,clearTimeout(u),t){S.promises.rm(e.destinationPath,{force:!0}).finally(()=>a(t));return}i()}},l=r.request({protocol:n.protocol,host:n.hostname,port:n.port,method:`GET`,path:n.pathname+n.search,headers:O(e.token)},n=>{if((n.statusCode??500)>=400){let r=``;n.setEncoding(`utf8`),n.on(`data`,e=>{r+=e}),n.on(`end`,()=>{c(new t(`COMMAND_FAILED`,`Failed to download remote artifact`,{artifactId:e.artifactId,statusCode:n.statusCode,requestId:e.requestId,body:r}))});return}n.on(`aborted`,()=>{c(new t(`COMMAND_FAILED`,`Remote artifact download was interrupted`,{artifactId:e.artifactId,requestId:e.requestId}))}),qe(n,S.createWriteStream(e.destinationPath)).then(()=>c(),e=>c(e instanceof Error?e:Error(String(e))))}),u=setTimeout(()=>{let n=new t(`COMMAND_FAILED`,`Remote artifact download timed out`,{artifactId:e.artifactId,requestId:e.requestId,timeoutMs:s});c(n),l.destroy(n)},s);l.on(`error`,n=>{if(n instanceof t){c(n);return}c(new t(`COMMAND_FAILED`,`Failed to download remote artifact`,{artifactId:e.artifactId,requestId:e.requestId,timeoutMs:s},n instanceof Error?n:void 0))}),l.end()})}function qt(e,t){let n=e.endsWith(`/`)?e:`${e}/`;return new URL(`artifacts/${encodeURIComponent(t)}`,n).toString()}function Jt(e){return typeof e.baseUrl==`string`&&e.baseUrl.length>0}const Yt=3e3,Xt=1e3;function N(e){let t=on(e);if(!t||typeof t!=`object`)return null;let n=t,r=Zt(n);if(!r)return null;let i=Qt(n);return i?{token:r,...i,transport:$t(n.transport),pid:F(n.pid)??0,version:P(n.version),codeSignature:P(n.codeSignature),processStartTime:P(n.processStartTime)}:null}function Zt(e){return typeof e.token==`string`&&e.token.length>0?e.token:null}function Qt(e){let t=F(e.port),n=F(e.httpPort);return t===void 0&&n===void 0?null:{port:t,httpPort:n}}function $t(e){return e===`socket`||e===`http`||e===`dual`?e:void 0}function P(e){return typeof e==`string`?e:void 0}function F(e){return Number.isInteger(e)&&Number(e)>0?Number(e):void 0}function I(e){let t=on(e);if(!t||typeof t!=`object`)return null;let n=t;return Number.isInteger(n.pid)&&Number(n.pid)>0?{pid:Number(n.pid),processStartTime:typeof n.processStartTime==`string`?n.processStartTime:void 0,startedAt:typeof n.startedAt==`number`?n.startedAt:void 0}:null}function L(e){sn(e)}function R(e){sn(e)}function en(e){let t=B(e);if(!t.hasLock||t.hasInfo)return;let n=I(e.lockPath);if(!n){R(e.lockPath);return}_(n.pid,n.processStartTime)||R(e.lockPath)}async function z(e,t,n={}){let r=n.stopLiveProcesses??!0,i={reason:t,removedInfo:!1,removedLock:!1,stoppedInfoProcess:!1,stoppedLockProcess:!1};try{let t=S.existsSync(e.infoPath),n=N(e.infoPath);if(n){let t=_(n.pid,n.processStartTime);t&&!r?i.retainedInfoProcess=!0:(t&&(await V(n),i.stoppedInfoProcess=!0),L(e.infoPath),i.removedInfo=!0)}else t&&(L(e.infoPath),i.removedInfo=!0);let a=S.existsSync(e.lockPath),o=I(e.lockPath);if(o){let t=_(o.pid,o.processStartTime);t&&!r?i.retainedLockProcess=!0:(t&&(await me(o.pid,{termTimeoutMs:Yt,killTimeoutMs:Xt,expectedStartTime:o.processStartTime}),i.stoppedLockProcess=!0),R(e.lockPath),i.removedLock=!0)}else a&&(R(e.lockPath),i.removedLock=!0)}catch(e){i.error=e instanceof Error?e.message:String(e)}return c({level:i.error?`warn`:`info`,phase:`daemon_startup_metadata_cleanup`,data:i}),i}function B(e){return{hasInfo:S.existsSync(e.infoPath),hasLock:S.existsSync(e.lockPath)}}async function tn(e){let t=B(e);if(!t.hasLock||t.hasInfo)return!1;let n=I(e.lockPath);return!n||!_(n.pid,n.processStartTime)?(R(e.lockPath),!0):!1}async function V(e){await me(e.pid,{termTimeoutMs:Yt,killTimeoutMs:Xt,expectedStartTime:e.processStartTime})}function nn(e){return typeof e.baseUrl==`string`&&e.baseUrl.length>0}function rn(e,t=g(process.env.AGENT_DEVICE_STATE_DIR)){let n=an(t);return e.hasLock&&!e.hasInfo?`agent-device attempted to clean stale daemon metadata automatically, but ${t.lockPath} still exists without ${t.infoPath}. Retry with --debug; if this persists after confirming no agent-device daemon process is running, run: ${n}`:e.hasLock&&e.hasInfo?`agent-device attempted to clean stale daemon metadata automatically, but ${t.infoPath} and ${t.lockPath} still remain. Retry with --debug; if this persists after confirming no agent-device daemon process is running, run: ${n}`:e.hasInfo?`agent-device did not observe reachable daemon metadata after retrying, and ${t.infoPath} still remains. Stale metadata was cleaned automatically when safe; retry with --debug. If this persists after confirming no agent-device daemon process is running, run: ${n}`:`agent-device did not observe reachable daemon metadata after retrying. Stale metadata was cleaned automatically when safe; retry with --debug and check daemon diagnostics logs. If stale metadata returns after confirming no agent-device daemon process is running, run: ${n}`}function an(e){return`rm -f ${oe(e.infoPath)} ${oe(e.lockPath)}`}function on(e){if(!S.existsSync(e))return null;try{return JSON.parse(S.readFileSync(e,`utf8`))}catch{return null}}function sn(e){try{S.existsSync(e)&&S.unlinkSync(e)}catch{}}function cn(e,t){if(t.onProgress){t.onProgress(e);return}e.type===`command`&&(t.req.command===`doctor`&&Ce(),process.stderr.write(`${e.message}\n`))}function H(e,n,r){return new t(`COMMAND_FAILED`,`Invalid daemon response`,{requestId:e.meta?.requestId,line:n},r instanceof Error?r:void 0)}function ln(e){let t=t=>(e.onError(t),!0);return{handleLine(n){let r;try{r=JSON.parse(n)}catch(r){return t(H(e.req,n,r))}if(ce(r))try{return cn(r.event,{req:e.req,onProgress:e.onProgress}),!1}catch(e){return t(e)}return fe(r)?(e.onResponse(r.response),!0):e.responseFormat===`socket-legacy`?(e.onResponse(r),!0):t(H(e.req,n,Error(`Missing daemon progress response envelope`)))}}}function un(e,t){return le(e)&&String(Array.isArray(t)?t.join(`,`):t??``).includes(`application/x-ndjson`)}function dn(e,t){let{req:n,isSettled:r,resolve:i,reject:a,clearTimeout:o}=t,s=``,c=ln({req:n,onProgress:t.onProgress,responseFormat:`socket-legacy`,onResponse(t){o(),i(t),e.end()},onError(e){o(),a(e)}});e.setEncoding(`utf8`),e.on(`data`,e=>{if(r())return;let t=se(s,e);s=t.buffer;for(let e of t.lines)if(c.handleLine(e))return})}function fn(e,n){let{req:r,handleResponseBody:i,reject:a,clearTimeout:o}=n,s=``,c=!1,l=ln({req:r,onProgress:n.onProgress,responseFormat:`ndjson-envelope`,onResponse(e){c=!0,o(),i(JSON.stringify(e))},onError(e){c=!0,o(),a(e)}});e.setEncoding(`utf8`),e.on(`data`,e=>{if(c)return;let t=se(s,e);s=t.buffer;for(let e of t.lines)if(e&&l.handleLine(e))return}),e.on(`end`,()=>{if(c)return;let e=s.trim();e&&l.handleLine(e)||(c=!0,o(),a(H(r,e)))}),e.on(`error`,e=>{c||(c=!0,o(),a(new t(`COMMAND_FAILED`,`Failed to read daemon response`,{requestId:r.meta?.requestId},e instanceof Error?e:void 0)))})}function pn(e,n){let{info:r,req:i,resolve:a,reject:o}=n;try{let n=mn(e);if(n.error){o(hn(n.error,i.meta?.requestId));return}if(!n.result||typeof n.result!=`object`){o(new t(`COMMAND_FAILED`,`Invalid daemon RPC response`,{requestId:i.meta?.requestId}));return}gn(r,i,n.result,a,o)}catch(n){o(new t(`COMMAND_FAILED`,`Invalid daemon response`,{requestId:i.meta?.requestId,line:e},n instanceof Error?n:void 0))}}function mn(e){return JSON.parse(e)}function hn(e,r){let i=e.data??{};return new t(n(i.code==null?void 0:String(i.code),`COMMAND_FAILED`),String(i.message??e.message??`Daemon RPC request failed`),{...typeof i.details==`object`&&i.details?i.details:{},hint:typeof i.hint==`string`?i.hint:void 0,diagnosticId:typeof i.diagnosticId==`string`?i.diagnosticId:void 0,logPath:typeof i.logPath==`string`?i.logPath:void 0,retriable:typeof i.retriable==`boolean`?i.retriable:void 0,supportedOn:typeof i.supportedOn==`string`?i.supportedOn:void 0,requestId:r})}async function gn(e,t,n,r,i){try{r(e.baseUrl&&n.ok?await Wt(e,t,n):n)}catch(e){i(e)}}function _n(e,t){let n=e.meta?.requestId??i();return vn(e.command)?{jsonrpc:`2.0`,id:n,method:yn(e.command),params:bn(e,e.command,t)}:{jsonrpc:`2.0`,id:n,method:`agent_device.command`,params:e}}function vn(e){return e===`lease_allocate`||e===`lease_heartbeat`||e===`lease_release`}function yn(e){switch(e){case`lease_allocate`:return`agent_device.lease.allocate`;case`lease_heartbeat`:return`agent_device.lease.heartbeat`;case`lease_release`:return`agent_device.lease.release`}}function bn(e,t,n){return p(f(e),t,{includeTokenParam:n.includeTokenParam,token:e.token,session:e.session})}const xn=[`xcodebuild .*AgentDeviceRunnerUITests/RunnerTests/testCommand`,`xcodebuild .*AgentDeviceRunner\\.env\\.session-`,`xcodebuild build-for-testing .*apple-runner/AgentDeviceRunner/AgentDeviceRunner\\.xcodeproj`];function Sn(e){let t=d(e.command);if(t.envelopeMs===`unbounded`)return;let n={...t,envelopeMs:t.envelopeMs};return Cn(n,e.positionals??[])??wn(n,e.flags)??n.envelopeMs}function Cn(e,t){if(e.budget.source!==`positional-parser`)return;let n=e.budget.parser(t);return n===null?void 0:En(e,n)}function wn(e,t){if(e.budget.source===`flag`)return e.budget.envelope===`widen`?Tn(e,e.budget,t):typeof t?.timeoutMs==`number`?t.timeoutMs:e.envelopeMs}function Tn(e,t,n){if(n?.settle!==!0)return e.envelopeMs;let r=typeof n.timeoutMs==`number`?n.timeoutMs:t.defaultBudgetMs;return typeof r==`number`?Dn(e,r):e.envelopeMs}function En(e,t){return Math.max(e.envelopeMs,t+Nn)}function Dn(e,t){return Math.max(e.envelopeMs,e.envelopeMs+t+Nn)}function On(e,n,r,i,a,o){let s=a?{terminated:0}:jn(),l=!a&&kn(i),u=l?Mn(e,n):{forcedKill:!1};return c({level:`error`,phase:`daemon_request_timeout`,data:{timeoutMs:o,requestId:r,command:i,timedOutRunnerPidsTerminated:s.terminated,timedOutRunnerCleanupError:s.error,daemonPidReset:l?e.pid:void 0,daemonPidForceKilled:l?u.forcedKill:void 0,daemonPreservedAfterTimeout:!a&&!l,daemonBaseUrl:e.baseUrl}}),new t(`COMMAND_FAILED`,`Daemon request timed out`,{timeoutMs:o,requestId:r,hint:An({remote:a,resetDaemon:l,command:i})})}function kn(e){return d(e).onTimeout===`reset-daemon`}function An(e){let{remote:t,resetDaemon:n,command:r}=e;if(t)return`Retry with --debug and verify the remote daemon URL, auth token, and remote host logs.`;if(!n){let e=r===m.snapshot?` If this was the first Apple-platform snapshot on the device, run agent-device prepare ios-runner with the same --platform before snapshot/test so runner startup is handled explicitly.`:``;return`Retry with --debug and check daemon diagnostics logs. The timed-out ${r??`request`} request was canceled and Apple runner work was aborted when detected; the daemon was kept alive so the session can still be closed or inspected.${e}`}return`Retry with --debug and check daemon diagnostics logs. Timed-out Apple runner xcodebuild processes were terminated when detected.`}function jn(){let e=0;try{for(let t of xn)a(`pkill`,[`-f`,t],{allowFailure:!0}).exitCode===0&&(e+=1);return{terminated:e}}catch(t){return{terminated:e,error:t instanceof Error?t.message:String(t)}}}function Mn(e,t){let n=!1;try{_(e.pid,e.processStartTime)&&(process.kill(e.pid,`SIGKILL`),n=!0)}catch{V(e)}finally{L(t.infoPath),R(t.lockPath)}return{forcedKill:n}}const Nn=3e4,Pn=`Daemon HTTP endpoint is unavailable`,Fn=`Daemon socket endpoint is unavailable`;async function In(e,t){let n=Gn(e,t);if(await Ln(e,n))return!0;let r=Kn(e,t,n);return r?await Ln(e,r):!1}async function Ln(e,t){return t===`http`?await zn(e):await Rn(e.port)}function Rn(e){return e?new Promise(t=>{let n=!1,r=E.createConnection({host:`127.0.0.1`,port:e},()=>{i(!0)}),i=e=>{n||(n=!0,r.destroy(),t(e))};r.setTimeout(500),r.on(`timeout`,()=>{i(!1)}),r.on(`error`,()=>{i(!1)})}):Promise.resolve(!1)}function zn(e){return Vn(e).then(e=>e.reachable)}async function Bn(e){let n=await Vn(e);if(!e.baseUrl||!n.reachable)return n;if(typeof n.rpcProtocolVersion==`number`&&n.rpcProtocolVersion!==1)throw new t(`COMMAND_FAILED`,`Remote daemon RPC protocol is incompatible`,{daemonBaseUrl:e.baseUrl,clientVersion:v(),remoteVersion:n.version,remoteService:n.service,supportedRpcProtocolVersion:1,remoteRpcProtocolVersion:n.rpcProtocolVersion,hint:`Upgrade agent-device on the client or remote host so both support the same daemon RPC protocol.`});return n}function Vn(e){let t=e.baseUrl?D(e.baseUrl,`health`):e.httpPort?`http://127.0.0.1:${e.httpPort}/health`:null;if(!t)return Promise.resolve({reachable:!1});let n=new URL(t),r=n.protocol===`https:`?T:w,i=e.baseUrl?3e3:500;return new Promise(t=>{let a=e.baseUrl?O(e.token):{},o=r.request({protocol:n.protocol,host:n.hostname,port:n.port,path:n.pathname+n.search,method:`GET`,timeout:i,headers:a},e=>{let n=``;e.setEncoding(`utf8`),e.on(`data`,e=>{n+=e}),e.on(`end`,()=>{let r=e.statusCode??500;t({reachable:r<500,statusCode:r,...Hn(n)})})});o.on(`timeout`,()=>{o.destroy(),t({reachable:!1})}),o.on(`error`,()=>{t({reachable:!1})}),o.end()})}function Hn(e){try{let t=JSON.parse(e);return{service:typeof t.service==`string`?t.service:void 0,version:typeof t.version==`string`?t.version:void 0,rpcProtocolVersion:typeof t.rpcProtocolVersion==`number`?t.rpcProtocolVersion:void 0}}catch{return{}}}async function Un(e,t,n,r,i,a={}){let o=Gn(e,n);try{return await Wn(e,t,r,i,o,a)}catch(s){let c=Kn(e,n,o);if(!c||!qn(s,o))throw s;return await Wn(e,t,r,i,c,a)}}async function Wn(e,t,n,r,i,a){return i===`http`?await Zn(e,t,n,r,a):await Xn(e,t,n,r,a)}function Gn(e,n){if(e.baseUrl){if(n===`socket`)throw new t(`COMMAND_FAILED`,`Remote daemon endpoint only supports HTTP transport`,{daemonBaseUrl:e.baseUrl});return`http`}if(n===`http`||n===`socket`)return Jn(e,n);let r=(e.transport===`socket`||e.transport===`dual`?[`socket`,`http`]:[`http`,`socket`]).find(t=>U(e,t));if(r)return r;throw new t(`COMMAND_FAILED`,`Daemon metadata has no reachable transport`)}function U(e,t){return t===`http`?!!e.httpPort:!!e.port}function Kn(e,t,n){if(t!==`auto`||e.baseUrl)return null;let r=n===`socket`?`http`:`socket`;return U(e,r)?r:null}function qn(e,n){return n===`socket`&&e instanceof t&&e.code===`COMMAND_FAILED`&&e.message===`Failed to communicate with daemon`&&e.details?.daemonSocketRequestWritten===!1}function Jn(e,n){if(U(e,n))return n;throw new t(`COMMAND_FAILED`,n===`http`?Pn:Fn)}function Yn(e,n,r,i={}){return c({level:`error`,phase:`daemon_request_socket_error`,data:{requestId:n,message:e instanceof Error?e.message:String(e)}}),new t(`COMMAND_FAILED`,`Failed to communicate with daemon`,{...i,requestId:n,hint:r?`Retry command. If this persists, verify the remote daemon URL, auth token, and remote host reachability.`:`Retry command. If this persists, clean stale daemon metadata and start a fresh session.`},e instanceof Error?e:void 0)}async function Xn(e,n,r,i,a){let o=e.port;if(!o)throw new t(`COMMAND_FAILED`,Fn);return new Promise((t,s)=>{let c=!1,l=E.createConnection({host:`127.0.0.1`,port:o},()=>{c=!0,l.write(`${JSON.stringify(n)}\n`)}),u=!1,d=typeof i==`number`?setTimeout(()=>{u=!0,l.destroy(),s(On(e,r,n.meta?.requestId,n.command,!1,i))},i):void 0;dn(l,{req:n,onProgress:a.onProgress,isSettled:()=>u,clearTimeout:()=>{d&&clearTimeout(d)},resolve:e=>{u=!0,t(e)},reject:e=>{u=!0,s(e)}}),l.on(`error`,e=>{u||(u=!0,d&&clearTimeout(d),s(Yn(e,n.meta?.requestId,!1,{daemonSocketRequestWritten:c})))})})}async function Zn(e,n,r,i,a){let o=e.baseUrl?new URL(D(e.baseUrl,`rpc`)):e.httpPort?new URL(`http://127.0.0.1:${e.httpPort}/rpc`):null;if(!o)throw new t(`COMMAND_FAILED`,Pn);let s=JSON.stringify(_n(n,{includeTokenParam:!e.baseUrl})),c={"content-type":`application/json`,"content-length":Buffer.byteLength(s)};return e.baseUrl&&Object.assign(c,O(e.token)),await new Promise((l,u)=>{let d=(o.protocol===`https:`?T:w).request({protocol:o.protocol,host:o.hostname,port:o.port,method:`POST`,path:o.pathname+o.search,headers:c},r=>{if(un(n,r.headers?.[`content-type`])){fn(r,{req:n,onProgress:a.onProgress,reject:u,clearTimeout:()=>{p&&clearTimeout(p)},handleResponseBody:t=>pn(t,{info:e,req:n,resolve:l,reject:u})});return}re(r).then(t=>{p&&clearTimeout(p),pn(t,{info:e,req:n,resolve:l,reject:u})}).catch(e=>{p&&clearTimeout(p),u(new t(`COMMAND_FAILED`,`Failed to read daemon response`,{requestId:n.meta?.requestId},e instanceof Error?e:void 0))})}),f=nn(e),p=typeof i==`number`?setTimeout(()=>{d.destroy(),u(On(e,r,n.meta?.requestId,n.command,f,i))},i):void 0;d.on(`error`,e=>{p&&clearTimeout(p),u(Yn(e,n.meta?.requestId,f))}),d.write(s),d.end()})}const W=15e3,G=new E.BlockList;G.addSubnet(`127.0.0.0`,8,`ipv4`),G.addAddress(`::1`,`ipv6`),G.addSubnet(`::ffff:127.0.0.0`,104,`ipv6`);function Qn(e){let t=$n(e),n=er(e),r=tr(e,n.remoteBaseUrl),i=nr(e,t,n.rawBaseUrl);return{paths:g(i?rr():t),transportPreference:r.preference,serverMode:r.serverMode,ownedStateDir:i,remoteBaseUrl:n.remoteBaseUrl,remoteAuthToken:n.authToken}}function $n(e){return e.flags?.stateDir??process.env.AGENT_DEVICE_STATE_DIR}function er(e){let t=e.flags?.daemonBaseUrl??process.env.AGENT_DEVICE_DAEMON_BASE_URL,n=xr(t),r=e.flags?.daemonAuthToken??process.env.AGENT_DEVICE_DAEMON_AUTH_TOKEN;return Sr(n,r),{rawBaseUrl:t,remoteBaseUrl:n,authToken:r}}function tr(e,n){let r=e.flags?.daemonTransport??process.env.AGENT_DEVICE_DAEMON_TRANSPORT,i=ie(r);if(n&&i===`socket`)throw new t(`INVALID_ARGS`,`Remote daemon base URL only supports HTTP transport. Remove --daemon-transport socket.`,{daemonBaseUrl:n});return{preference:i,serverMode:pe(e.flags?.daemonServerMode??process.env.AGENT_DEVICE_DAEMON_SERVER_MODE??(r===`dual`?`dual`:void 0))}}function nr(e,t,n){return mr(e.command)&&!t&&!n}function rr(){return S.mkdtempSync(C.join(Ke.tmpdir(),`agent-device-replay-daemon-`))}async function ir(e){if(e.remoteBaseUrl)return await ar(e);let t=await or(e);return t?{info:t,startedByClient:!1}:(en(e.paths),await fr(e))}async function ar(e){let n={transport:`http`,token:e.remoteAuthToken??``,pid:0,baseUrl:e.remoteBaseUrl};if((await Bn(n)).reachable)return{info:n,startedByClient:!1};throw new t(`COMMAND_FAILED`,`Remote daemon is unavailable`,{daemonBaseUrl:e.remoteBaseUrl,hint:`Verify AGENT_DEVICE_DAEMON_BASE_URL points to a reachable daemon with GET /health and POST /rpc. If this CLI was connected with connect proxy, run agent-device disconnect to return to the local daemon.`})}async function or(e){let t=N(e.paths.infoPath);if(!t)return null;let n=await sr(t,e.transportPreference);return lr(t,n)?t:(ur(t,n,e.paths.baseDir),await V(t),L(e.paths.infoPath),null)}async function sr(e,t){try{return await In(e,t)}catch(e){if(cr(e))return!1;throw e}}function cr(e){return e instanceof t&&e.code===`COMMAND_FAILED`&&(e.message===`Daemon HTTP endpoint is unavailable`||e.message===`Daemon socket endpoint is unavailable`)}function lr(e,t){return e.version===v()&&e.codeSignature===vr()&&t}function ur(e,t,n){try{let r=e.version?`pid ${e.pid}, v${e.version}`:`pid ${e.pid}`,i=dr(e,t);process.stderr.write(`Replacing daemon (${r}) in ${n}: ${i}\n`)}catch{}}function dr(e,t){return e.version===v()?e.codeSignature===vr()?t?`not reusable`:`unreachable`:`code-signature mismatch`:`version mismatch (client v${v()})`}async function fr(e){let n=0,r=[],i,a;for(let t=1;t<=2;t+=1){let o;try{o=gr(e),a={pid:o.pid}}catch(n){if(i=n instanceof Error?n.message:String(n),r.push(await z(e.paths,`start_error`)),t<2){await y(150);continue}break}let s=await hr(W,e,o);if(s.kind===`ready`)return{info:s.info,startedByClient:!0};if(s.kind===`early_exit`){if(a=s.exit,i=yr(s.exit),r.push(await z(e.paths,`start_error`)),t<2){await y(150);continue}break}if(await tn(e.paths)){n+=1;continue}let c=B(e.paths),l=t<2,u=await z(e.paths,`startup_timeout`,{stopLiveProcesses:!1});if(r.push(u),u.retainedInfoProcess||u.retainedLockProcess){let t=await hr(W,e,o);if(t.kind===`ready`)return{info:t.info,startedByClient:!0};t.kind===`early_exit`&&(a=t.exit,i=yr(t.exit));break}if(!l)break;!c.hasInfo&&!c.hasLock&&await y(150)}let o=B(e.paths),s=br(e.paths.logPath);throw new t(`COMMAND_FAILED`,`Failed to start daemon`,{kind:`daemon_startup_failed`,stateDir:e.paths.baseDir,infoPath:e.paths.infoPath,lockPath:e.paths.lockPath,logPath:e.paths.logPath,startupTimeoutMs:W,startupAttempts:2,lockRecoveryCount:n,cleanupResults:r,startError:i,daemonProcess:a,...s?{daemonLogTail:s}:{},metadataState:o,hint:rn(o,e.paths)})}async function pr(e,t,n){if(!mr(e.command)||!t.startedByClient&&!n.ownedStateDir||nn(t.info))return;let r={pid:t.info.pid,removedInfo:!1,removedLock:!1,removedStateDir:!1,error:void 0};try{await V(t.info)}catch(e){r.error=e instanceof Error?e.message:String(e)}finally{let e=S.existsSync(n.paths.infoPath);L(n.paths.infoPath),r.removedInfo=e&&!S.existsSync(n.paths.infoPath);let t=S.existsSync(n.paths.lockPath);R(n.paths.lockPath),r.removedLock=t&&!S.existsSync(n.paths.lockPath),n.ownedStateDir&&(S.rmSync(n.paths.baseDir,{recursive:!0,force:!0}),r.removedStateDir=!S.existsSync(n.paths.baseDir))}c({level:r.error?`warn`:`info`,phase:`daemon_replay_cleanup`,data:r})}function mr(e){return e===m.replay||e===m.test}async function hr(e,t,n){let r=Date.now(),i;for(n.exited.then(e=>{i=e});Date.now()-r<e;){if(i)return{kind:`early_exit`,exit:i};let e=N(t.paths.infoPath);if(e&&await In(e,t.transportPreference))return{kind:`ready`,info:e};if(i)return{kind:`early_exit`,exit:i};await y(100)}return{kind:`timeout`}}function gr(e){let t=_r(),n=t.useSrc?[`--experimental-strip-types`,t.srcPath]:[t.distPath],r={...process.env,AGENT_DEVICE_STATE_DIR:e.paths.baseDir,AGENT_DEVICE_DAEMON_SERVER_MODE:e.serverMode};S.mkdirSync(e.paths.baseDir,{recursive:!0});let i=S.openSync(e.paths.logPath,`a`),a=S.openSync(e.paths.logPath,`a`);try{return u(process.execPath,n,{env:r,stdio:[`ignore`,i,a]})}finally{S.closeSync(i),S.closeSync(a)}}function _r(){let e=he(),n=[C.join(e,`dist`,`src`,`internal`,`daemon.js`),C.join(e,`dist`,`src`,`daemon.js`)],r=n[0];if(r===void 0)throw new t(`COMMAND_FAILED`,`Daemon dist path list is empty`);let i=n.find(e=>S.existsSync(e))??r,a=C.join(e,`src`,`daemon.ts`),o=n.some(e=>S.existsSync(e)),s=S.existsSync(a);if(!o&&!s)throw new t(`COMMAND_FAILED`,`Daemon entry not found`,{distPaths:n,srcPath:a});return{root:e,distPath:i,distPaths:n,srcPath:a,useSrc:(process.execArgv.includes(`--experimental-strip-types`)||!o)&&s}}function vr(){let e=_r();return ae(e.useSrc?e.srcPath:e.distPath,e.root)}function yr(e){return e.error?`daemon process ${e.pid} failed to start: ${e.error}`:e.signal?`daemon process ${e.pid} exited before readiness with signal ${e.signal}`:`daemon process ${e.pid} exited before readiness with code ${e.exitCode??0}`}function br(e){try{if(!S.existsSync(e))return;let t=S.statSync(e);if(t.size<=0)return;let n=Math.min(t.size,64e3),r=S.openSync(e,`r`);try{let e=Buffer.alloc(n);S.readSync(r,e,0,n,t.size-n);let i=e.toString(`utf8`).trim();return i.length>0?i:void 0}finally{S.closeSync(r)}}catch{return}}function xr(e){if(!e)return;let n;try{n=new URL(e)}catch(n){throw new t(`INVALID_ARGS`,`Invalid daemon base URL`,{daemonBaseUrl:e},n instanceof Error?n:void 0)}if(n.protocol!==`http:`&&n.protocol!==`https:`)throw new t(`INVALID_ARGS`,`Daemon base URL must use http or https`,{daemonBaseUrl:e});return n.toString().replace(/\/+$/,``)}function Sr(e,n){if(!e)return;let r=new URL(e).hostname;if(!Cr(r)&&!(typeof n==`string`&&n.trim().length>0))throw new t(`INVALID_ARGS`,`Remote daemon base URL for non-loopback hosts requires daemon authentication`,{daemonBaseUrl:e,hint:`Provide --daemon-auth-token or AGENT_DEVICE_DAEMON_AUTH_TOKEN when using a non-loopback remote daemon URL.`})}function Cr(e){let t=e.trim().toLowerCase().replace(/^\[(.*)\]$/,`$1`);return t===`localhost`?!0:E.isIPv4(t)?G.check(t,`ipv4`):E.isIPv6(t)?G.check(t,`ipv6`):!1}async function wr(e,t={}){let n=e.meta?.requestId??i(),r=!!(e.meta?.debug||e.flags?.verbose),a=Qn(e),s=Sn(e),l=await o(`daemon_startup`,async()=>await ir(a),{requestId:n,session:e.session}),u=l.info,d=await Mt(e,u);Tr(e.command);let f={...e,positionals:d.positionals,flags:d.flags,token:u.token,meta:{...e.meta??{},requestId:n,debug:r,includeCost:e.meta?.includeCost,cwd:e.meta?.cwd,sessionExplicit:e.meta?.sessionExplicit,tenantId:e.meta?.tenantId??e.flags?.tenant,runId:e.meta?.runId??e.flags?.runId,leaseId:e.meta?.leaseId??e.flags?.leaseId,sessionIsolation:e.meta?.sessionIsolation??e.flags?.sessionIsolation,lockPolicy:e.meta?.lockPolicy,lockPlatform:e.meta?.lockPlatform,...d.uploadedArtifactId?{uploadedArtifactId:d.uploadedArtifactId}:{},...d.clientArtifactPaths?{clientArtifactPaths:d.clientArtifactPaths}:{},...d.installSource?{installSource:d.installSource}:{}}};c({level:`info`,phase:`daemon_request_prepare`,data:{requestId:n,command:e.command,session:e.session}});try{return await o(`daemon_request`,async()=>await Un(u,f,a.transportPreference,a.paths,s,t),{requestId:n,command:e.command})}finally{await pr(e,l,a)}}function Tr(e){!Er(e)||process.stderr.isTTY!==!0||process.env.CI||process.stderr.write(e===m.reinstall?`Reinstalling...
|
|
2
|
-
`:`Installing...
|
|
3
|
-
`)}function Er(e){return e===m.install||e===m.reinstall||e===h.installSource}const Dr=8081;function Or(e){return typeof e==`string`&&e.trim()?Le(e.trim()):``}function K(e){return typeof e==`string`&&e.trim()?e.trim():void 0}function q(e,t,n){return ge(e,{env:t,cwd:n})}function J(e){try{return S.accessSync(e,S.constants.F_OK),!0}catch{return!1}}function kr(e){try{return S.statSync(e).isDirectory()}catch{return!1}}function Ar(e){let n=C.join(e,`package.json`),r=Ve(e);if(!r)throw new t(`INVALID_ARGS`,`package.json not found at ${n}`);return r}function jr(e){return J(C.join(e,`pnpm-lock.yaml`))?{command:`pnpm`,installArgs:[`install`]}:J(C.join(e,`yarn.lock`))?{command:`yarn`,installArgs:[`install`]}:{command:`npm`,installArgs:[`install`]}}function Mr(e,t){if(t!==`auto`)return t;let n=Be(e);return n===`expo`||n===`repack`?n:`react-native`}function Nr(e,t){return typeof{...e.dependencies??{},...e.devDependencies??{}}[t]==`string`}function Pr(e,t){return[`js`,`mjs`,`cjs`,`ts`,`mts`,`cts`].some(n=>J(C.join(e,`${t}.config.${n}`)))}function Fr(e,t){return Pr(e,`rspack`)?`rspack`:Pr(e,`webpack`)?`webpack`:Nr(t,`@rspack/core`)?`rspack`:Nr(t,`webpack`)?`webpack`:`rspack`}function Y(e,t,n){if(e==null||e===``)return t;let r=Number.parseInt(String(e),10);return Number.isInteger(r)?Math.max(r,n):t}function Ir(e,n){if(e==null||e===``)return n;let r=Number.parseInt(String(e),10);if(!Number.isInteger(r)||r<1||r>65535)throw new t(`INVALID_ARGS`,`Invalid Metro port: ${String(e)}. Use 1-65535.`);return r}function Lr(e,t){return{platform:t,bundleUrl:Re(e,t)}}function Rr(e,t){return{platform:t,metroHost:K(e?.metro_host),metroPort:e?.metro_port,bundleUrl:K(e?.metro_bundle_url),launchUrl:K(e?.launch_url)}}function zr(e,t){if(kr(C.join(e,`node_modules`)))return{installed:!1};let n=jr(e);return a(n.command,n.installArgs,{cwd:e,env:t}),{installed:!0,packageManager:n.command}}async function Br(e){await y(e)}async function Vr(e,n,r={}){try{let t=await fetch(e,{headers:r,signal:AbortSignal.timeout(n)});return{ok:t.ok,status:t.status,body:await t.text()}}catch(r){throw r instanceof Error&&r.name===`TimeoutError`?new t(`COMMAND_FAILED`,`Timed out fetching ${e} after ${n}ms`):r}}async function Hr(e,t){try{let n=await Vr(e,t);return n.ok&&n.body.includes(`packager-status:running`)}catch{return!1}}function Ur(e,t){let n=new URL(`${e.scheme}://localhost`);return n.hostname=e.host,n.port=String(e.port),n.pathname=t,n.toString()}function Wr(e){let t=K(e);if(!t)return`/reload`;let n=new URL(t).pathname.replace(/\/+$/,``);return n.endsWith(`/index.bundle`)?`${n.slice(0,-13)}/reload`:`/reload`}function Gr(e,t,n){return K(e.metroHost)??(t?void 0:K(e.runtime?.metroHost))??(n?void 0:`localhost`)}function Kr(e,t,n){if(e.metroPort!==void 0)return Ir(e.metroPort,Dr);if(!t)return e.runtime?.metroPort??(n?void 0:Dr)}function qr(e){let n=K(e.bundleUrl),r=n??e.runtime?.bundleUrl,i=!!n,a=!!K(r),o=He({metroHost:Gr(e,i,a),metroPort:Kr(e,i,a),bundleUrl:r});if(!o)throw new t(`INVALID_ARGS`,`Unable to resolve Metro host and port for reload.`);return Ur(o,Wr(r))}function Jr(e,t,n,r){return e===`expo`?{command:`npx`,installArgs:[`expo`,`start`,`--host`,`lan`,`--port`,String(n)]}:e===`repack`?{command:`npx`,installArgs:[`react-native`,t===`webpack`?`webpack-start`:`rspack-start`,`--host`,r,`--port`,String(n)]}:{command:`npx`,installArgs:[`react-native`,`start`,`--host`,r,`--port`,String(n)]}}function Yr(e,n,r,i,a,o,c){let l=Jr(n,r,i,a);S.mkdirSync(C.dirname(o),{recursive:!0});let u=S.openSync(o,`a`),d=0;try{d=s(l.command,l.installArgs,{cwd:e,env:c,stdio:[`ignore`,u,u]})}finally{S.closeSync(u)}if(!Number.isInteger(d)||d<=0)throw new t(`COMMAND_FAILED`,`Failed to start React Native dev server. Expected a detached child PID.`);return{pid:d}}async function Xr(e){if(!(!Number.isInteger(e)||e<=0)){try{process.kill(e,`SIGTERM`)}catch(e){let t=e.code;if(t===`ESRCH`||t===`EPERM`)return;throw e}if(!await _e(e,1e3)){try{process.kill(e,`SIGKILL`)}catch(e){let t=e.code;if(t===`ESRCH`||t===`EPERM`)return;throw e}await _e(e,1e3)}}}function Zr(e,t){return{Authorization:`Bearer ${t}`,"Content-Type":`application/json`,...e.includes(`ngrok`)?{"ngrok-skip-browser-warning":`1`}:{}}}function X(e,n){let r=new t(`COMMAND_FAILED`,e);return r.retryable=n,r}function Qr(e,t){return!!(e>=500||e===408||e===425||e===429||JSON.stringify(t).includes(`Metro companion is not connected`))}function $r(e){return!!(e&&typeof e==`object`&&`retryable`in e&&e.retryable===!0)}async function ei(e){let t;try{t=await fetch(`${e.baseUrl}/api/metro/bridge`,{method:`POST`,headers:Zr(e.baseUrl,e.bearerToken),body:JSON.stringify({...e.scope,...e.runtime?{ios_runtime:e.runtime}:{},timeout_ms:e.timeoutMs}),signal:AbortSignal.timeout(e.timeoutMs)})}catch(t){throw t instanceof Error&&t.name===`TimeoutError`?X(`/api/metro/bridge timed out after ${e.timeoutMs}ms calling ${e.baseUrl}/api/metro/bridge`,!0):X(t instanceof Error?t.message:String(t),!0)}let n=ti(await t.text(),t.status,e.baseUrl);if(!t.ok)throw X(`/api/metro/bridge failed (${t.status}): ${JSON.stringify(n)}`,Qr(t.status,n));return ri(n)}function ti(e,t,n){if(!e)return{};try{let t=JSON.parse(e);if(!t||typeof t!=`object`||Array.isArray(t))throw Error(`Expected a JSON object`);return t}catch(r){let i=e.slice(0,200);throw X(`/api/metro/bridge returned invalid JSON (${t}) from ${n}: ${r instanceof Error?r.message:String(r)}. body=${JSON.stringify(i)}`,Qr(t,e))}}function ni(e){return{enabled:e.enabled,baseUrl:e.base_url,statusUrl:e.status_url??``,bundleUrl:e.bundle_url??``,iosRuntime:Rr(e.ios_runtime,`ios`),androidRuntime:Rr(e.android_runtime,`android`),upstream:{bundleUrl:e.upstream.bundle_url??``,host:e.upstream.host??``,port:e.upstream.port??0,statusUrl:e.upstream.status_url??``},probe:{reachable:e.probe.reachable,statusCode:e.probe.status_code,latencyMs:e.probe.latency_ms,detail:e.probe.detail}}}function ri(e){let t=e.data??e;if(!t||typeof t!=`object`||Array.isArray(t))throw X(`/api/metro/bridge returned malformed descriptor: Expected a JSON object.`,!1);try{return ni(t)}catch(e){throw X(`/api/metro/bridge returned malformed descriptor: ${e instanceof Error?e.message:String(e)}`,!1)}}function Z(e,t,n,r,i){let a=[`Metro bridge is required for this run but could not be configured via ${e}/api/metro/bridge.`];return t&&a.push(`bridgeError=${t}`),n?.probe.reachable===!1&&a.push(`bridgeProbe=${n.probe.detail||`unreachable (status ${n.probe.statusCode||0})`}`),r&&r!==t&&a.push(`initialBridgeError=${r}`),i&&a.push(`metroCompanionLog=${i}`),a.join(` `)}function ii(e,n){if(!n?.iosRuntime.bundleUrl)throw new t(`COMMAND_FAILED`,Z(e,`bridge descriptor is missing ios_runtime.metro_bundle_url`,n))}function ai(e,n,r){let i=n||K(r.AGENT_DEVICE_METRO_BEARER_TOKEN)||``,a=i||e&&K(r.AGENT_DEVICE_DAEMON_AUTH_TOKEN)||``;if(e&&!a)throw new t(`INVALID_ARGS`,`metro prepare requires proxy auth when --proxy-base-url is provided. Pass --bearer-token or set AGENT_DEVICE_METRO_BEARER_TOKEN or AGENT_DEVICE_DAEMON_AUTH_TOKEN.`);if(!e&&i)throw new t(`INVALID_ARGS`,`metro prepare requires --proxy-base-url when proxy auth is provided.`);return{proxyEnabled:!!(e&&a),proxyBaseUrl:e,proxyBearerToken:a}}function oi(e){if(!e?.tenantId||!e.runId||!e.leaseId)throw new t(`INVALID_ARGS`,`metro prepare with proxy requires tenantId, runId, and leaseId bridge scope.`);return e}function si(e,n){if(!(e||n))throw new t(`INVALID_ARGS`,`metro prepare requires --public-base-url <url> or --proxy-base-url <url>.`)}function ci(e,t,n){return e.runtimeFilePath?q(e.runtimeFilePath,t,n):null}function li(e,t,n,r){return q(e.logPath??C.join(r,`.agent-device`,`metro.log`),t,n)}function ui(e){let t=e.env??process.env,n=process.cwd(),r=q(e.projectRoot??n,t,n),i=e.kind??`auto`,a=null,o;i===`auto`?(a=Ar(r),o=Mr(a,i)):o=i;let s=null;o===`repack`&&(a??=Ar(r),s=Fr(r,a));let c=Or(e.publicBaseUrl),l=Or(e.proxyBaseUrl);si(c,l);let{proxyEnabled:u,proxyBaseUrl:d,proxyBearerToken:f}=ai(l,K(e.proxyBearerToken)??``,t);return{env:t,projectRoot:r,kind:o,repackBundler:s,metroPort:Ir(e.metroPort??8081,8081),listenHost:K(e.listenHost)??`0.0.0.0`,statusHost:K(e.statusHost)??`127.0.0.1`,publicBaseUrl:c,proxyBaseUrl:d,proxyBearerToken:f,bridgeScope:u?oi(e.bridgeScope):null,startupTimeoutMs:Y(e.startupTimeoutMs,18e4,3e4),probeTimeoutMs:Y(e.probeTimeoutMs,1e4,1e3),reuseExisting:e.reuseExisting??!0,installProjectDeps:e.installDependenciesIfNeeded??!0,runtimeFilePath:ci(e,t,n),logPath:li(e,t,n,r)}}async function di(e,t,n){let r=Date.now()+t;for(;Date.now()<r;){let t=r-Date.now();if(await Hr(e,Math.min(n,Math.max(t,1))))return!0;let i=Math.min(500,Math.max(r-Date.now(),0));i>0&&await Br(i)}return!1}async function fi(e){let n=Date.now()+e.startupTimeoutMs,r=null,i=null;for(;Date.now()<n;){try{let t=await ei({baseUrl:e.baseUrl,bearerToken:e.bearerToken,scope:e.scope,runtime:e.runtime,timeoutMs:e.probeTimeoutMs});if(t.probe.reachable!==!1)return t;r=t,i=null}catch(n){if(i=n instanceof Error?n.message:String(n),!$r(n))throw new t(`COMMAND_FAILED`,Z(e.baseUrl,i,r,e.initialBridgeError,e.companionLogPath),void 0,n)}let a=Math.min(1e3,Math.max(n-Date.now(),0));a>0&&await Br(a)}throw new t(`COMMAND_FAILED`,Z(e.baseUrl,i,r,e.initialBridgeError,e.companionLogPath))}async function pi(e){let n=`http://${e.statusHost}:${e.metroPort}/status`;if(e.reuseExisting&&await Hr(n,e.probeTimeoutMs))return{started:!1,reused:!0,pid:0,statusUrl:n};let r=Yr(e.projectRoot,e.kind,e.repackBundler,e.metroPort,e.listenHost,e.logPath,e.env);if(await di(n,e.startupTimeoutMs,e.probeTimeoutMs))return{started:!0,reused:!1,pid:r.pid,statusUrl:n};throw await Xr(r.pid).catch(()=>{}),new t(`COMMAND_FAILED`,`React Native dev server did not become ready at ${n} within ${e.startupTimeoutMs}ms. Check ${e.logPath}.`,{logPath:e.logPath})}async function mi(e,t){let n=t.bridgeScope;if(!n)return null;let r=null,i=null;try{r=await ei({baseUrl:t.proxyBaseUrl,bearerToken:t.proxyBearerToken,scope:n,timeoutMs:t.probeTimeoutMs})}catch(e){if(!$r(e))throw e;i=e instanceof Error?e.message:String(e)}return(!r||r.probe.reachable===!1)&&(r=await hi(e,t,n,r,i)),ii(t.proxyBaseUrl,r),r}async function hi(e,n,r,i,a){let o;try{o=(await ze({projectRoot:n.projectRoot,serverBaseUrl:n.proxyBaseUrl,bearerToken:n.proxyBearerToken,bridgeScope:r,localBaseUrl:`http://${n.statusHost}:${n.metroPort}`,launchUrl:K(e.launchUrl),profileKey:K(e.companionProfileKey),consumerKey:K(e.companionConsumerKey),env:n.env})).logPath}catch(e){throw new t(`COMMAND_FAILED`,Z(n.proxyBaseUrl,e instanceof Error?e.message:String(e),i,a),void 0,e)}try{return await fi({baseUrl:n.proxyBaseUrl,bearerToken:n.proxyBearerToken,scope:r,probeTimeoutMs:n.probeTimeoutMs,startupTimeoutMs:n.startupTimeoutMs,initialBridgeError:a,companionLogPath:o})}catch(e){throw e instanceof Error?e:Error(String(e))}}function gi(e){return{baseIosRuntime:e?Lr(e,`ios`):{platform:`ios`},baseAndroidRuntime:e?Lr(e,`android`):{platform:`android`}}}function _i(e,t){e&&(S.mkdirSync(C.dirname(e),{recursive:!0}),S.writeFileSync(e,JSON.stringify(t,null,2)))}async function vi(e={}){let t=ui(e),n=t.installProjectDeps?zr(t.projectRoot,t.env):{installed:!1},r=await pi(t),{baseIosRuntime:i,baseAndroidRuntime:a}=gi(t.publicBaseUrl),o=await mi(e,t),s=o?.iosRuntime??i,c=o?.androidRuntime??a,l={projectRoot:t.projectRoot,kind:t.kind,dependenciesInstalled:n.installed,packageManager:n.packageManager??null,started:r.started,reused:r.reused,pid:r.pid,logPath:t.logPath,statusUrl:r.statusUrl,runtimeFilePath:t.runtimeFilePath,iosRuntime:s,androidRuntime:c,bridge:o};return _i(t.runtimeFilePath,l),l}async function yi(e={}){let n=Y(e.timeoutMs,1e4,1e3),r=qr(e),i=await Vr(r,n);if(!i.ok)throw new t(`COMMAND_FAILED`,`React Native dev server reload failed (${i.status}).`,{reloadUrl:r,status:i.status,body:i.body,hint:`Verify Metro or Re.Pack is running and the target React Native app is connected to this dev server instance.`});return{reloaded:!0,reloadUrl:r,status:i.status,body:i.body}}const bi={...ke(),batch:De(xi)};function xi(e,n,r){let i=bi[e];if(!i)throw Error(`Missing daemon writer for batch command: ${e}`);let a=Ue(e);if(!a)throw Error(`Missing command metadata for batch command: ${e}`);try{return Ci(i,a,a.readInput(n))}catch(n){throw new t(`INVALID_ARGS`,`Batch step ${r} ${e} input is invalid: ${n instanceof Error?n.message:String(n)}`,void 0,n)}}function Si(e,t){let n=bi[e];if(!n)throw Error(`Missing daemon writer for command: ${e}`);return Ci(n,Ue(e),t)}function Ci(e,t,n){let r=e(n);return{...r,...t?{metadataFlags:je(t,r.options)}:{}}}function wi(e){throw new t(n(e.code),e.message,{...e.details??{},hint:e.hint,diagnosticId:e.diagnosticId,logPath:e.logPath,retriable:e.retriable,supportedOn:e.supportedOn})}var Ti=e({createAgentDeviceClient:()=>Ei});function Ei(e={},t={}){let n=t.transport??wr,i=t=>r(t.responseLevel??e.responseLevel),a=async(t,r=[],i={},a)=>{let o=$(e,i),s=await n({session:ve(o.session),command:t,positionals:r,flags:Oe(o,a),runtime:o.runtime,meta:Fe(o)});return s.ok||wi(s.error),s.data??{}},o=async(e={})=>{let t=await a(h.sessionList,[],e);return(Array.isArray(t.sessions)?t.sessions:[]).map(xe)},s=async(e,t={})=>{let n=Si(e,t);return await a(n.command,n.positionals,n.options,n.metadataFlags)},c=(t={})=>ve($(e,t).session);return{command:{wait:async e=>await s(`wait`,e),alert:async(e={})=>await s(`alert`,e),...ki(s),reactNative:async e=>await s(`react-native`,e),doctor:async(e={})=>await s(`doctor`,e),prepare:async e=>await s(`prepare`,e),viewport:async e=>await s(`viewport`,e)},devices:{list:async(e={})=>{let t=await s(`devices`,e);return(Array.isArray(t.devices)?t.devices:[]).map(Pe)},capabilities:async(e={})=>{let t=await s(`capabilities`,e),n=Array.isArray(t.availableCommands)?t.availableCommands.filter(e=>typeof e==`string`):[];return{device:Pe(t.device),availableCommands:n}},boot:async(e={})=>await s(`boot`,e),shutdown:async(e={})=>await s(`shutdown`,e)},sessions:{list:async(e={})=>await o(e),stateDir:async(t={})=>g($(e,t).stateDir??process.env.AGENT_DEVICE_STATE_DIR).baseDir,close:async(e={})=>{let t=c(e),n=await s(`close`,e);return{session:t,shutdown:Se(n.shutdown),provider:Q(n.provider),identifiers:{session:t}}},artifacts:async(e={})=>await s(`artifacts`,e)},apps:{install:async e=>Ee(await s(`install`,e),c(e)),reinstall:async e=>Ee(await s(`reinstall`,e),c(e)),installFromSource:async e=>we(await s(`install-from-source`,e),c(e)),list:async(e={})=>{let t=await s(`apps`,e);return Array.isArray(t.apps)?t.apps.filter(e=>typeof e==`string`):[]},open:async e=>{let t=c(e),n=await s(`open`,e),r=Ne(n),i=b(n,`appBundleId`),a=i;return{session:t,sessionStateDir:b(n,`sessionStateDir`),eventLogPath:b(n,`eventLogPath`),appName:b(n,`appName`),appBundleId:i,appId:a,startup:be(n.startup),runtime:Te(n.runtime),device:r,identifiers:{session:t,deviceId:r?.id,deviceName:r?.name,udid:r?.ios?.udid,serial:r?.android?.serial,appId:a,appBundleId:i}}},close:async(e={})=>{let t=c(e),n=await s(`close`,e);return{session:t,closedApp:e.app,shutdown:Se(n.shutdown),identifiers:{session:t}}},push:async e=>await s(`push`,e),triggerEvent:async e=>await s(`trigger-app-event`,e)},materializations:{release:async e=>ye(await a(h.releaseMaterializedPaths,[],{...e,materializationId:e.materializationId}))},leases:{allocate:async e=>Ai(await a(h.leaseAllocate,[],{...e,leaseId:void 0})),heartbeat:async e=>Ai(await a(h.leaseHeartbeat,[],e)),release:async e=>{let t=await a(h.leaseRelease,[],e);return{released:t.released===!0,provider:Q(t.provider)}}},metro:{prepare:async t=>await vi({projectRoot:t.projectRoot??e.cwd,kind:t.kind,publicBaseUrl:t.publicBaseUrl,proxyBaseUrl:t.proxyBaseUrl,proxyBearerToken:t.bearerToken,bridgeScope:t.bridgeScope,launchUrl:t.launchUrl,companionProfileKey:t.companionProfileKey,companionConsumerKey:t.companionConsumerKey,metroPort:t.port,listenHost:t.listenHost,statusHost:t.statusHost,startupTimeoutMs:t.startupTimeoutMs,probeTimeoutMs:t.probeTimeoutMs,reuseExisting:t.reuseExisting,installDependenciesIfNeeded:t.installDependenciesIfNeeded,runtimeFilePath:t.runtimeFilePath,logPath:t.logPath}),reload:async(t={})=>await yi({metroHost:t.metroHost,metroPort:t.metroPort,bundleUrl:t.bundleUrl,runtime:e.runtime,timeoutMs:t.timeoutMs})},capture:{snapshot:async(e={})=>{let t=c(e),n=await s(`snapshot`,e);return i(e)?n:Di(n,t)},screenshot:async(e={})=>{let t=c(e),n=await s(`screenshot`,e);if(i(e))return n;let r=de(n);return{path:x(n,`path`),width:r?.width,height:r?.height,logicalWidth:r?.logicalWidth,logicalHeight:r?.logicalHeight,pixelDensity:r?.pixelDensity,overlayRefs:r?.overlayRefs,identifiers:{session:t}}},diff:async e=>await s(`diff`,e)},interactions:{click:async e=>await s(`click`,e),press:async e=>await s(`press`,e),longPress:async e=>await s(`longpress`,e),swipe:async e=>await s(`swipe`,e),pan:async e=>await s(`gesture-pan`,e),fling:async e=>await s(`gesture-fling`,e),swipeGesture:async e=>await s(`gesture-swipe`,e),focus:async e=>await s(`focus`,e),type:async e=>await s(`type`,e),fill:async e=>await s(`fill`,e),scroll:async e=>await s(`scroll`,e),pinch:async e=>await s(`gesture-pinch`,e),rotateGesture:async e=>await s(`gesture-rotate`,e),transformGesture:async e=>await s(`gesture-transform`,e),get:async e=>await s(`get`,e),is:async e=>await s(`is`,e),find:async e=>await s(`find`,e)},replay:{run:async e=>await s(`replay`,e),test:async e=>await s(`test`,e)},batch:{run:async e=>await s(`batch`,e)},observability:{perf:async(e={})=>await s(`perf`,e),logs:async(e={})=>await s(`logs`,e),events:async(e={})=>await s(`events`,e),network:async(e={})=>await s(`network`,e),audio:async(e={})=>await s(`audio`,e)},debug:{symbols:async t=>{let{symbolicateCrashArtifact:n}=await import(`./debug-symbols.js`);return n({cwd:t.cwd??e.cwd,...t})}},recording:{record:async e=>await s(`record`,e),trace:async e=>await s(`trace`,e)},settings:{update:async e=>await s(`settings`,e)}}}function Di(e,t){let n=b(e,`appBundleId`);return{nodes:Ae(e.nodes),truncated:e.truncated===!0,appName:b(e,`appName`),appBundleId:n,...Oi(e),identifiers:{session:t,appId:n,appBundleId:n}}}function Oi(e){let t=Q(e.visibility),n=Q(e.unchanged),r=ue(e.snapshotDiagnostics);return{...t?{visibility:t}:{},...ee(e),...n?{unchanged:n}:{},...r?{snapshotDiagnostics:r}:{}}}function ki(e){let t={};for(let[n,r]of Object.entries(Me.clientCommandMethods??{}))t[n]=async(t={})=>await e(r,t);return t}function Q(e){return Ie(e)?e:void 0}function $(e,t){return{...e,...t}}function Ai(e){let t=e.lease;if(!Ie(t))throw Error(`Invalid lease response from daemon`);return{leaseId:x(t,`leaseId`),tenantId:x(t,`tenantId`),runId:x(t,`runId`),backend:x(t,`backend`),leaseProvider:b(t,`leaseProvider`),clientId:b(t,`clientId`),deviceKey:b(t,`deviceKey`),createdAt:typeof t.createdAt==`number`?t.createdAt:void 0,heartbeatAt:typeof t.heartbeatAt==`number`?t.heartbeatAt:void 0,expiresAt:typeof t.expiresAt==`number`?t.expiresAt:void 0}}export{Qn as a,Ze as c,ir as i,D as l,Ei as n,Xe as o,wr as r,O as s,Ti as t};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import"./internal/daemon.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/output-path.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import e from"node:path";const t=`.webm`;function n(e){return e===`web`?t:`.mp4`}function r(t,n){return e.extname(t)?t:`${t}${n}`}function i(e){return`./recording-${Date.now()}${n(e)}`}export{n as i,r as n,i as r,t};
|
package/dist/src/points.js
DELETED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import{F as e,b as t,l as n}from"./sdk-contracts.js";import{Nt as r,Pt as i,bn as a,d as o}from"./tv-remote.js";import{a as s,f as c,i as ee,l,m as u,p as d,u as f}from"./providers.js";import p from"node:fs";import{parseAllDocuments as m,stringify as h}from"yaml";const g=/^[A-Z_][A-Z0-9_]*$/,_=/(\\\$\{)|\$\{([A-Za-z_][A-Za-z0-9_.]*)(?::-((?:[^}\\]|\\.)*))?\}/g;function v(e){return e.startsWith(`AD_`)}function y(t){return new e(`INVALID_ARGS`,`The AD_* namespace is reserved for built-in variables. Rename ${t} to avoid the AD_ prefix.`)}function te(e){let t={};if(e.builtins)for(let[n,r]of Object.entries(e.builtins))t[n]=r;let n=[e.fileEnv,e.shellEnv,e.cliEnv];for(let e of n)if(e)for(let[n,r]of Object.entries(e)){if(v(n))throw y(n);t[n]=r}return{values:t}}function ne(e,t){Object.assign(e.values,t)}function b(e){let t={};for(let[n,r]of Object.entries(e)){if(typeof r!=`string`||!n.startsWith(`AD_VAR_`))continue;let e=n.slice(7);e.length!==0&&g.test(e)&&(v(e)||(t[e]=r))}return t}function x(t){let n={};for(let r of t){let t=r.indexOf(`=`);if(t<=0)throw new e(`INVALID_ARGS`,`Invalid -e entry "${r}": expected KEY=VALUE.`);let i=r.slice(0,t);if(!g.test(i))throw new e(`INVALID_ARGS`,`Invalid -e key "${i}": keys must be uppercase letters, digits, and underscores (e.g. APP_ID).`);if(v(i))throw y(i);n[i]=r.slice(t+1)}return n}function S(e){return Array.isArray(e)?e.filter(e=>typeof e==`string`):[]}function C(e){if(e&&typeof e==`object`&&!Array.isArray(e)){let t={};for(let[n,r]of Object.entries(e))typeof r==`string`&&(t[n]=r);return t}return process.env}function w(t,n,r){return t.replace(_,(t,i,a,o)=>{if(i)return"${";if(!a)return t;if(Object.prototype.hasOwnProperty.call(n.values,a))return String(n.values[a]);if(o!==void 0)return o.replace(/\\(.)/g,`$1`);throw new e(`INVALID_ARGS`,`Unresolved variable \${${a}} at ${r.file}:${r.line}.`)})}function T(e,t,n){return{...e,positionals:(e.positionals??[]).map(e=>w(e,t,n)),flags:D(e.flags,t,n)??{},runtime:D(e.runtime,t,n),replayControl:E(e.replayControl,t,n)}}function E(e,t,n){if(!e)return e;switch(e.kind){case`maestroRunFlowWhen`:return{...e,selector:w(e.selector,t,n)};case`retry`:return e}return e}function D(e,t,n){return e&&O(e,t,n)}function O(e,t,n){return typeof e==`string`?w(e,t,n):Array.isArray(e)?e.map(e=>O(e,t,n)):e&&typeof e==`object`?Object.fromEntries(Object.entries(e).map(([e,r])=>[e,O(r,t,n)])):e}const k=new Set(n.filter(e=>e!==`web`)),A=new Set([`mobile`,`tv`,`desktop`]);function j(t){let n=[],r=[],i=t.split(/\r?\n/),a=!1;for(let[t,o]of i.entries()){let i=o.trim();if(i.length===0||i.startsWith(`#`))continue;if(N(i)){if(a)throw new e(`INVALID_ARGS`,`env directives must precede all actions (line ${t+1}).`);continue}let s=R(o);s&&(n.push(s),r.push(t+1),a=!0)}return{actions:n,actionLines:r}}function M(e){let t=e.split(/\r?\n/),n={};for(let[e,r]of t.entries()){let t=r.trim();if(t.length===0||t.startsWith(`#`))continue;if(N(t)){I(n,t,e+1);continue}if(!t.startsWith(`context `))break;let i=t.match(/(?:^|\s)platform=([^\s]+)/);if(i){let e=i[1];e&&k.has(e)&&L(n,`platform`,e)}let a=t.match(/(?:^|\s)target=([^\s]+)/);if(a){let e=a[1];e&&A.has(e)&&L(n,`target`,e)}let o=t.match(/(?:^|\s)timeout=(\d+)/);if(o){let e=Number(o[1]);Number.isFinite(e)&&e>=1&&L(n,`timeoutMs`,Math.floor(e))}let s=t.match(/(?:^|\s)retries=(\d+)/);if(s){let e=Number(s[1]);Number.isFinite(e)&&e>=0&&L(n,`retries`,Math.floor(e))}}return n}function N(e){return e===`env`||e.startsWith(`env `)||e.startsWith(`env `)}function P(t,n){let r=t.slice(3).replace(/^[\s]+/,``),i=r.indexOf(`=`);if(i<=0)throw new e(`INVALID_ARGS`,`Invalid env directive on line ${n}: expected "env KEY=VALUE".`);let a=r.slice(0,i);if(!g.test(a))throw new e(`INVALID_ARGS`,`Invalid env key "${a}" on line ${n}: keys must be uppercase letters, digits, and underscores (e.g. APP_ID).`);if(a.startsWith(`AD_`))throw new e(`INVALID_ARGS`,`Invalid env key "${a}" on line ${n}: the AD_* namespace is reserved for built-in variables. Rename ${a} to avoid the AD_ prefix.`);return{key:a,value:F(r.slice(i+1),n)}}function F(t,n){if(t.length===0)return``;if(t.startsWith(`"`))try{let e=JSON.parse(t);if(typeof e!=`string`)throw Error(`not a string literal`);return e}catch{throw new e(`INVALID_ARGS`,`Invalid quoted env value on line ${n}.`)}return t}function I(t,n,r){let{key:i,value:a}=P(n,r),o=t.env??{};if(Object.prototype.hasOwnProperty.call(o,i))throw new e(`INVALID_ARGS`,`Duplicate env directive "${i}" on line ${r}.`);o[i]=a,t.env=o}function L(t,n,r){let i=t[n];if(i!==void 0)throw new e(`INVALID_ARGS`,i===r?`Duplicate replay test metadata "${n}" in context header.`:`Conflicting replay test metadata "${n}" in context header: ${String(i)} vs ${String(r)}.`);t[n]=r}function R(e){let t=e.trim();if(t.length===0||t.startsWith(`#`))return null;let[n,...r]=V(t);if(n===void 0||n===`context`)return null;let i={ts:Date.now(),command:n,positionals:[],flags:{}};if(n===`snapshot`){i.positionals=[];for(let e=0;e<r.length;e+=1){let t=r[e];if(t===`-i`){i.flags.snapshotInteractiveOnly=!0;continue}if(t!==`-c`){if(t===`--raw`){i.flags.snapshotRaw=!0;continue}if(t===`--force-full`){i.flags.snapshotForceFull=!0;continue}if((t===`-d`||t===`--depth`)&&e+1<r.length){let t=Number(r[e+1]);Number.isFinite(t)&&t>=0&&(i.flags.snapshotDepth=Math.floor(t)),e+=1;continue}if((t===`-s`||t===`--scope`)&&e+1<r.length){i.flags.snapshotScope=r[e+1],e+=1;continue}if(t===`--backend`&&e+1<r.length){e+=1;continue}}}return i}if(n===`open`){let e=s(r);return i.positionals=e.positionals,Object.assign(i.flags,e.flags),i.runtime=e.runtime,i}if(n===`runtime`){let e=c(r);return i.positionals=e.positionals,Object.assign(i.flags,e.flags),i}if(f(n)){let e=d(n,r);Object.assign(i.flags,e.flags);let t=e.positionals[0];if(t===void 0)return i;if(t.startsWith(`@`))return i.positionals=[u(t)],e.positionals[1]&&(i.result={refLabel:e.positionals[1]}),i;let a=e.positionals[0],o=e.positionals[1];return B(a)&&B(o)&&e.positionals.length>=2?(i.positionals=[a,o],i):(i.positionals=[e.positionals.join(` `)],i)}if(n===`fill`){let e=d(n,r);if(Object.assign(i.flags,e.flags),!z(e.positionals))return i.positionals=e.positionals,i;let[t,a,...o]=e.positionals;if(t.startsWith(`@`)){let e=u(t);return o.length>0?(i.positionals=[e,o.join(` `)],i.result={refLabel:a},i):(i.positionals=[e,a],i)}return i.positionals=[t,[a,...o].join(` `)],i}if(n===`get`){let e=r[0],t=r[1];return e===void 0||t===void 0?(i.positionals=r,i):t.startsWith(`@`)?(i.positionals=[e,u(t)],r[2]&&(i.result={refLabel:r[2]}),i):(i.positionals=[e,r.slice(1).join(` `)],i)}if(n===`swipe`||n===`type`){let e=d(n,r);return Object.assign(i.flags,e.flags),i.positionals=e.positionals,i}if(n===`record`){let e=[];for(let t=0;t<r.length;t+=1){let n=r[t];if(n===`--hide-touches`){i.flags.hideTouches=!0;continue}if(n===`--fps`&&t+1<r.length){let e=Number(r[t+1]);Number.isFinite(e)&&(i.flags.fps=Math.floor(e)),t+=1;continue}if(n===`--quality`&&t+1<r.length){let e=r[t+1],n=o(e);n!==void 0&&(i.flags.quality=n),t+=1;continue}if(n===`--max-size`&&t+1<r.length){let e=Number(r[t+1]);Number.isFinite(e)&&(i.flags.screenshotMaxSize=Math.floor(e)),t+=1;continue}e.push(n)}return i.positionals=e,i}if(n===`screenshot`){let e=[];for(let t=0;t<r.length;t+=1){let n=r[t],o=a({args:r,index:t,flags:i.flags});if(o.handled){t=o.nextIndex;continue}e.push(n)}return i.positionals=e,i}return i.positionals=n===`wait`||n===`longpress`?r.map(e=>u(e)):r,i}function z(e){return e.length>=2}function B(e){return e?!Number.isNaN(Number(e)):!1}function V(e){let t=[],n=0;for(;n<e.length&&(n=H(e,n),!(n>=e.length));){let r=e[n]===`"`?U(e,n):W(e,n);t.push(r.value),n=r.nextCursor}return t}function H(e,t){let n=t;for(;n<e.length&&/\s/.test(e.charAt(n));)n+=1;return n}function U(t,n){let r=n+1,i=!1,a=r;for(;a<t.length;a+=1){let e=t.charAt(a);if(e===`"`&&!i)break;if(i){i=!1;continue}i=e===`\\`}if(a>=t.length)throw new e(`INVALID_ARGS`,`Invalid replay script line: ${t}`);return{value:JSON.parse(t.slice(n,a+1)),nextCursor:a+1}}function W(e,t){let n=t;for(;n<e.length&&!/\s/.test(e.charAt(n));)n+=1;return{value:e.slice(t,n),nextCursor:n}}function G(e,n,r){let i=[];if(r){let e=r.device.kind?` kind=${r.device.kind}`:``,n=r.device.target?` target=${r.device.target}`:``;i.push(`context platform=${t(r.device)}${n} device=${l(r.device.name)}${e} theme=unknown`)}for(let e of n)i.push(K(e));let a=`${i.join(`
|
|
2
|
-
`)}\n`,o=`${e}.tmp-${process.pid}-${Date.now()}`;p.writeFileSync(o,a),p.renameSync(o,e)}function K(e){return ee(e,{runtimeIncludeAllPositionals:!0})}function q(t){let n=m(t);for(let t of n)if(t.errors.length>0)throw new e(`INVALID_ARGS`,`Invalid Maestro YAML flow: ${t.errors[0]?.message??`Invalid Maestro YAML flow.`}`);return n.map(e=>e.toJSON()).filter(e=>e!==null)}function J(e){return`${e.map(e=>h(e).trimEnd()).join(`
|
|
3
|
-
---
|
|
4
|
-
`)}\n`}function Y(e,t=[],n){return{ts:Date.now(),command:e,positionals:t,flags:n??{}}}function X(e,t,n){let r=new Set(n),i=Object.keys(e).filter(e=>!r.has(e));if(i.length>0)throw $(`Maestro ${t} field "${i[0]}" is not supported yet.`)}function Z(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function re(t){return t.map((t,n)=>{if(typeof t==`string`||Z(t))return t;throw new e(`INVALID_ARGS`,`Unsupported Maestro command at index ${n+1}: expected a scalar or one-key map.`)})}function ie(e){if(e)return ue(e)}function ae(t,n){if(t==null)return{};if(!Z(t))throw new e(`INVALID_ARGS`,`${n} expects a map.`);let r={};for(let[e,n]of Object.entries(t))(typeof n==`string`||typeof n==`number`||typeof n==`boolean`)&&(r[e]=String(n));return r}function oe(e,t){return Z(e)&&typeof e.timeout==`number`&&Number.isFinite(e.timeout)?Math.max(0,Math.floor(e.timeout)):t}function se(t,n){if(t.appId)return t.appId;throw new e(`INVALID_ARGS`,`${n} requires appId in the Maestro flow config.`)}function Q(t,n){if(typeof n==`string`)return n;throw new e(`INVALID_ARGS`,`${t} expects a string value.`)}function ce(e,t){return e.replace(/\$\{([A-Za-z_][A-Za-z0-9_.]*)\}/g,(e,n)=>Object.prototype.hasOwnProperty.call(t.env,n)?String(t.env[n]):e)}function le(e){throw $(`Maestro command "${e}" is not supported yet.`)}function $(t){throw new e(`INVALID_ARGS`,`${t} See supported/unsupported Maestro compatibility at ${r}. If this syntax matters for your flows, comment there or open a focused issue at ${i}.`)}function ue(e){let t=e.trim().toLowerCase();if(t===`android`)return`android`;if(t===`ios`)return`ios`}function de(e,t){return`${e},${t}`}function fe(e){let t=e.match(/^(\d+),(\d+)$/);if(!t)throw $(`Only absolute Maestro point selectors like "100,200" are supported.`);return{x:Number(t[1]),y:Number(t[2])}}function pe(e){let t=e.match(/^\s*(\d+)\s*,\s*(\d+)\s*$/);if(t)return{kind:`absolute`,x:Number(t[1]),y:Number(t[2])};let n=e.match(/^\s*(\d+(?:\.\d+)?)%\s*,\s*(\d+(?:\.\d+)?)%\s*$/);if(n)return{kind:`percent`,x:Number(n[1]),y:Number(n[2])};throw $(`Only Maestro swipe coordinates like "100,200" or "50%,75%" are supported.`)}export{ne as C,T as D,C as E,b as S,S as T,J as _,X as a,G as b,ie as c,se as d,Q as f,q as g,$ as h,Y as i,ae as l,le as m,fe as n,Z as o,ce as p,pe as r,re as s,de as t,oe as u,j as v,x as w,te as x,M as y};
|
package/dist/src/provider.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./rolldown-runtime.js";import{t}from"./scoped-provider.js";import{t as n}from"./internal/daemon.js";var r=e({resolveWebProvider:()=>a,withWebProvider:()=>o});const i=t(n());function a(e){return i.resolve(e)}async function o(e,t){return await i.run(e,t)}export{a as n,r as t};
|
package/dist/src/providers.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{N as e}from"./sdk-contracts.js";import{yn as t}from"./tv-remote.js";import n from"node:crypto";function r(t){return t.startsWith(`@`)?e(t)?.base??t:t}const i=/^-?\d+(\.\d+)?$/,a=/^[^\s"\\]+$/,o=new Map([[`--count`,`count`],[`--interval-ms`,`intervalMs`],[`--hold-ms`,`holdMs`],[`--jitter-px`,`jitterPx`]]),s=new Map([[`--count`,`count`],[`--pause-ms`,`pauseMs`]]),c=new Map([[`--delay-ms`,`delayMs`]]);function l(e){return e===`click`||e===`press`}function u(e){return l(e)||e===`longpress`}function d(e){return e===`type`||e===`fill`}function f(e){return h(e,g)}function p(e){return JSON.stringify(e)}function m(e){return h(e,_)}function h(e,t){return t(e)?e:p(e)}function g(e){return _(e)&&e.startsWith(`@`)||i.test(e)}function _(e){return a.test(e)}function v(e){let t=(e.positionals??[]).map(e=>f(e));return[e.command,...t].join(` `)}function y(e,t){let n=t.flags??{};if(l(t.command)){typeof n.count==`number`&&e.push(`--count`,String(n.count)),typeof n.intervalMs==`number`&&e.push(`--interval-ms`,String(n.intervalMs)),typeof n.holdMs==`number`&&e.push(`--hold-ms`,String(n.holdMs)),typeof n.jitterPx==`number`&&e.push(`--jitter-px`,String(n.jitterPx)),n.doubleTap===!0&&e.push(`--double-tap`);let t=n.clickButton;t&&t!==`primary`&&e.push(`--button`,t);return}if(t.command===`swipe`){typeof n.count==`number`&&e.push(`--count`,String(n.count)),typeof n.pauseMs==`number`&&e.push(`--pause-ms`,String(n.pauseMs)),(n.pattern===`one-way`||n.pattern===`ping-pong`)&&e.push(`--pattern`,n.pattern);return}d(t.command)&&typeof n.delayMs==`number`&&e.push(`--delay-ms`,String(n.delayMs))}function b(e,t){t&&((t.platform===`ios`||t.platform===`android`)&&e.push(`--platform`,t.platform),typeof t.metroHost==`string`&&t.metroHost.length>0&&e.push(`--metro-host`,m(t.metroHost)),typeof t.metroPort==`number`&&e.push(`--metro-port`,String(t.metroPort)),typeof t.bundleUrl==`string`&&t.bundleUrl.length>0&&e.push(`--bundle-url`,m(t.bundleUrl)),typeof t.launchUrl==`string`&&t.launchUrl.length>0&&e.push(`--launch-url`,m(t.launchUrl)))}function x(e,t){let[n,...r]=t.positionals??[];n&&e.push(m(n));for(let t of r)e.push(f(t));typeof t.flags?.fps==`number`&&e.push(`--fps`,String(t.flags.fps)),typeof t.flags?.screenshotMaxSize==`number`&&e.push(`--max-size`,String(t.flags.screenshotMaxSize)),(typeof t.flags?.quality==`number`||typeof t.flags?.quality==`string`)&&e.push(`--quality`,String(t.flags.quality)),t.flags?.hideTouches&&e.push(`--hide-touches`)}function S(e,t){t.flags?.snapshotInteractiveOnly&&e.push(`-i`),typeof t.flags?.snapshotDepth==`number`&&e.push(`-d`,String(t.flags.snapshotDepth)),t.flags?.snapshotScope&&e.push(`-s`,f(t.flags.snapshotScope)),t.flags?.snapshotRaw&&e.push(`--raw`)}function C(e,n){for(let t of n.positionals??[])e.push(f(t));t(e,n.flags)}function w(e,t,n={}){let r=t.positionals??[],i=n.includeAllPositionals?r:r.slice(0,1);for(let t of i)e.push(m(t));b(e,t.flags)}function T(e,t){for(let n of t.positionals??[])e.push(f(t.command===`wait`?r(n):n));y(e,t)}function E(e,t){let n=[],r={},i=l(e)?o:e===`swipe`?s:d(e)?c:void 0;for(let a=0;a<t.length;a+=1){let o=t[a];if(l(e)&&o===`--double-tap`){r.doubleTap=!0;continue}let s=t[a+1];if(l(e)&&o===`--button`&&s!==void 0){let e=s;(e===`primary`||e===`secondary`||e===`middle`)&&(r.clickButton=e),a+=1;continue}let c=i?.get(o);if(c&&s!==void 0){let e=O(s);if(e!==null){r[c]=e,a+=1;continue}}if(e===`swipe`&&o===`--pattern`&&s!==void 0){let e=s;(e===`one-way`||e===`ping-pong`)&&(r.pattern=e),a+=1;continue}n.push(o)}return{positionals:n,flags:r}}function D(e){let t=[],n={};for(let r=0;r<e.length;r+=1){let i=e[r],a=e[r+1];if(i===`--platform`&&a!==void 0){let e=a;(e===`ios`||e===`android`)&&(n.platform=e),r+=1;continue}if(i===`--metro-host`&&a!==void 0){n.metroHost=a,r+=1;continue}if(i===`--metro-port`&&a!==void 0){let e=O(a);e!==null&&(n.metroPort=e),r+=1;continue}if(i===`--bundle-url`&&a!==void 0){n.bundleUrl=a,r+=1;continue}if(i===`--launch-url`&&a!==void 0){n.launchUrl=a,r+=1;continue}t.push(i)}return{positionals:t,flags:n}}function O(e){if(!e)return null;let t=Number(e);return!Number.isFinite(t)||t<0?null:Math.floor(t)}function k(e,t){for(let n of t.positionals??[])e.push(f(n));t.flags?.relaunch&&e.push(`--relaunch`),b(e,t.runtime)}function A(e){let t=[],n={};for(let r of e){if(r===`--relaunch`){n.relaunch=!0;continue}t.push(r)}let r=D(t);return{positionals:r.positionals,flags:n,runtime:j(r.flags)?r.flags:void 0}}function j(e){return!!(e.platform||e.metroHost||e.metroPort!==void 0||e.bundleUrl||e.launchUrl)}function M(e,t={}){let n=[e.command];return e.command===`snapshot`?S(n,e):e.command===`open`?k(n,e):e.command===`runtime`?w(n,e,{includeAllPositionals:t.runtimeIncludeAllPositionals}):e.command===`record`?x(n,e):e.command===`screenshot`?C(n,e):T(n,e),n.join(` `)}function N(e,t){let r=n.createHash(`sha256`).update(e).digest(),i=n.createHash(`sha256`).update(t).digest();return n.timingSafeEqual(r,i)}const P={browserStack:`browserstack`,awsDeviceFarm:`aws-device-farm`},F=new Set(Object.values(P));function I(e){return e!==void 0&&F.has(e)}export{A as a,f as c,u as d,D as f,M as i,p as l,r as m,I as n,y as o,E as p,N as r,v as s,P as t,l as u};
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import{F as e,p as t}from"./sdk-contracts.js";import{F as n,j as r,s as i,v as a}from"./sdk-android-adb.js";import{Xt as o,Zt as s,d as c,l,u}from"./tv-remote.js";import{n as d,r as f,t as p}from"./output-path.js";import{g as m}from"./snapshot-diagnostics.js";import{t as h}from"./version.js";import{t as g}from"./timeouts.js";import{l as ee,o as te,s as ne}from"./host-process.js";import{d as _,p as re}from"./android-input-ownership.js";import{d as ie,i as ae}from"./runner-client.js";import{o as oe}from"./tool-provider.js";import{c as se}from"./agent-browser-tool.js";import{$t as v,ft as ce,in as le,ln as ue,mt as de,on as fe,tn as pe,xn as me}from"./internal/daemon.js";import{n as y}from"./provider.js";import{a as he,t as ge}from"./apple-runner-options.js";import{t as _e}from"./handler-utils.js";import{n as ve}from"./recording-provider.js";import{createHash as ye,randomUUID as be}from"node:crypto";import b from"node:fs";import xe from"node:os";import x from"node:path";import{fileURLToPath as Se}from"node:url";function S(e=process.env){let t=C(),n=x.join(t,`home`),r=x.join(t,`module-cache`);return b.mkdirSync(n,{recursive:!0}),b.mkdirSync(r,{recursive:!0}),{...e,HOME:n,CLANG_MODULE_CACHE_PATH:r}}async function Ce(e){let t=b.statSync(e.sourcePath),n=b.readFileSync(e.sourcePath),r=Oe(e.cacheName??x.basename(e.sourcePath,x.extname(e.sourcePath))),i=ke([`2`,process.platform,process.arch,x.resolve(e.sourcePath),t.size,n]),a=x.join(C(),`bin`,`${r}-${i}`);return await Te({sourcePath:e.sourcePath,executablePath:a,timeoutMs:e.timeoutMs}),a}async function we(e){let t=Oe(e.cacheName),n=ke([`2`,process.platform,process.arch,e.source]),r=x.join(C(),`sources`,`${t}-${n}.swift`),i=x.join(C(),`bin`,`${t}-${n}`);return await Te({sourcePath:r,executablePath:i,sourceText:e.source,timeoutMs:e.timeoutMs}),i}function C(){let e=process.env.AGENT_DEVICE_SWIFT_CACHE_DIR?.trim();return e?x.resolve(e):x.join(xe.tmpdir(),`agent-device-swift-cache`)}async function Te(e){if(De(e.executablePath))return;let t=x.dirname(e.executablePath);b.mkdirSync(t,{recursive:!0});let n=await Ee(`${e.executablePath}.lock`,e.executablePath,e.timeoutMs??12e4);if(!n)return;let r=b.mkdtempSync(x.join(t,`.${x.basename(e.executablePath)}.${process.pid}.`)),i=x.join(r,x.basename(e.executablePath));try{if(De(e.executablePath))return;e.sourceText!==void 0&&!b.existsSync(e.sourcePath)&&(b.mkdirSync(x.dirname(e.sourcePath),{recursive:!0}),b.writeFileSync(e.sourcePath,e.sourceText)),await a(`xcrun`,[`swiftc`,e.sourcePath,`-o`,i],{timeoutMs:e.timeoutMs??12e4,env:S()}),b.renameSync(i,e.executablePath)}finally{b.rmSync(r,{recursive:!0,force:!0}),await n()}}async function Ee(t,n,r){if(De(n))return null;try{return await se({lockDirPath:t,owner:{pid:process.pid,startTime:te(process.pid),acquiredAtMs:Date.now()},timeoutMs:r,pollMs:25,ownerGraceMs:r,description:`Swift cache lock: ${t} (${r}ms)`})}catch(n){throw n instanceof e&&n.message.startsWith(`Timed out waiting for Swift cache lock:`)?new e(`COMMAND_FAILED`,n.message,{...n.details,lockDir:t,timeoutMs:r,hint:`Another agent-device process may still be compiling this Swift helper. Retry shortly; if no agent-device process is active, remove "${t}" and retry.`}):n}}function De(e){try{return b.accessSync(e,b.constants.X_OK),b.statSync(e).isFile()}catch{return!1}}function Oe(e){return e.replaceAll(/[^A-Za-z0-9._-]/g,`-`).replaceAll(/^-+|-+$/g,``)||`swift-helper`}function ke(e){let t=ye(`sha256`);for(let n of e)t.update(Buffer.isBuffer(n)?n:String(n)),t.update(`\0`);return t.digest(`hex`).slice(0,16)}let Ae;async function je(e,t={}){let n=t.pollMs??150,r=t.attempts??12,i,a=0;for(let t=0;t<r;t+=1){let t=0;try{t=b.statSync(e).size}catch{t=0}if(t>0&&t===i){if(a+=1,a>=2)return}else a=0;i=t,await g(n)}}async function Me(e){try{let t=await a(await Ne(),[e],{allowFailure:!0,timeoutMs:1e4,env:S()});return t.exitCode===0?!0:Ie(t.stderr,t.stdout)?Le(e):!1}catch(t){if(Pe(t))return Le(e);throw t}}async function Ne(){Ae??=we({source:`import Foundation
|
|
2
|
-
import AVFoundation
|
|
3
|
-
|
|
4
|
-
let url = URL(fileURLWithPath: CommandLine.arguments[1])
|
|
5
|
-
let asset = AVURLAsset(url: url)
|
|
6
|
-
let semaphore = DispatchSemaphore(value: 0)
|
|
7
|
-
var exitCode: Int32 = 1
|
|
8
|
-
|
|
9
|
-
Task {
|
|
10
|
-
defer { semaphore.signal() }
|
|
11
|
-
do {
|
|
12
|
-
let playable = try await asset.load(.isPlayable)
|
|
13
|
-
let duration = try await asset.load(.duration)
|
|
14
|
-
if playable && duration.isValid && !duration.isIndefinite && CMTimeGetSeconds(duration) > 0 {
|
|
15
|
-
exitCode = 0
|
|
16
|
-
}
|
|
17
|
-
} catch {
|
|
18
|
-
exitCode = 1
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
semaphore.wait()
|
|
23
|
-
exit(exitCode)`,cacheName:`video-validator`,timeoutMs:3e4});try{return await Ae}catch(e){throw Ae=void 0,e}}function Pe(t){return t instanceof e?t.code===`TOOL_MISSING`?!0:Ie(String(t.details?.stderr??``),String(t.details?.stdout??``)):!1}async function Fe(e,t={}){let n=t.pollMs??150,r=t.attempts??12;for(let t=0;t<r;t+=1){if(await Me(e))return;await g(n)}}function Ie(e,t){let n=`${e}\n${t}`;return/\b(no such module ['"]AVFoundation['"]|unable to find utility ["']swiftc?["']|xcrun: error: unable to find utility ["']swiftc?["'])\b/i.test(n)}function Le(e){try{let t=b.statSync(e);if(!t.isFile()||t.size<=0)return!1}catch{return!1}let t=Re(e);return t.includes(`ftyp`)&&t.includes(`moov`)}function Re(e){try{let t=b.openSync(e,`r`);try{let e=b.fstatSync(t).size,n=0,r=[];for(;n+8<=e&&r.length<16;){let e=Buffer.alloc(8);if(b.readSync(t,e,0,8,n)<8)break;let i=e.readUInt32BE(0),a=e.toString(`latin1`,4,8);if(r.push(a),i===1){let e=Buffer.alloc(8);if(b.readSync(t,e,0,8,n+8)<8)break;i=Number(e.readBigUInt64BE(0))}if(!Number.isFinite(i)||i<=0)break;n+=i}return r}finally{b.closeSync(t)}}catch{return[]}}function ze(e){let t=x.parse(e);return x.join(t.dir,`${t.name}.gesture-telemetry.json`)}function Be(e,t){return Ve(t>0?e.flatMap(e=>{let n=e.tMs-t,r=`durationMs`in e?e.durationMs:void 0;return(typeof r==`number`?n+r:n)<=0?[]:[{...e,tMs:Math.max(0,n)}]}):e)}function Ve(e){return[...e].sort((e,t)=>e.tMs-t.tMs)}function He(e){let t=ze(e.videoPath),n={version:1,generatedAt:new Date().toISOString(),events:Be(e.events,e.trimStartMs??0)};return b.writeFileSync(t,JSON.stringify(n,null,2)),t}function Ue(e){let{recording:t,trimStartMs:n}=e,r=He({videoPath:t.outPath,events:t.gestureEvents,trimStartMs:n});return t.telemetryPath=r,r}function We(e,t,n,r){let i=`apple-runner/AgentDeviceRunner/RecordingScripts/${e}`,a=`dist/${i}`;return[x.resolve(t,e),x.resolve(n,i),x.resolve(t,`../${i}`),x.resolve(t,`../../${i}`),x.resolve(t,`../../../${i}`),x.resolve(n,a),x.resolve(r,i)]}function w(t){let n=We(t,x.dirname(Se(import.meta.url)),h(),process.cwd());for(let e of n)if(b.existsSync(e))return e;throw new e(`COMMAND_FAILED`,`Missing recording helper script: ${t}`,{hint:`Ensure apple-runner/AgentDeviceRunner/RecordingScripts is present in this checkout or bundled under dist/apple-runner in the package.`,scriptName:t,searchedPaths:n})}let Ge,Ke,qe;function Je(e=process.platform){if(e!==`darwin`)return`touch overlay burn-in is only available on macOS hosts; returning raw video plus gesture telemetry`}function Ye(){return Ge??=w(`recording-overlay.swift`),Ge}function Xe(){return Ke??=w(`recording-trim.swift`),Ke}function Ze(){return qe??=w(`recording-resize.swift`),qe}async function T(t){let{videoPath:n,scriptPath:r,scriptArgs:i,commandDescription:o}=t;await je(n),await Fe(n);let s=Qe(n);try{await a(await Ce({sourcePath:r}),[`--input`,n,`--output`,s,...i],{timeoutMs:12e4,env:S()}),await Fe(s),b.renameSync(s,n)}catch(t){let i=t instanceof e?t:new e(`COMMAND_FAILED`,String(t),void 0,t instanceof Error?t:void 0);throw new e(`COMMAND_FAILED`,o,{...i.details,videoPath:n,script:r},i)}finally{b.rmSync(s,{force:!0})}}function Qe(e){let t=x.parse(e),n=`${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2)}`;return x.join(t.dir,`.${t.name}.agent-device-${n}${t.ext||`.mp4`}`)}async function $e(e){let{videoPath:t,trimStartMs:n}=e;n>0&&await T({videoPath:t,scriptPath:Xe(),scriptArgs:[`--trim-start-ms`,String(n)],commandDescription:`Failed to trim the start of the iOS recording`})}async function et(e){let{videoPath:t,telemetryPath:n,exportQuality:r=l,targetLabel:i=`recording`}=e;await T({videoPath:t,scriptPath:Ye(),scriptArgs:[`--events`,n,`--quality`,r],commandDescription:`Failed to add touch overlays to the ${i}`})}async function tt(e){let{videoPath:t,maxSize:n,exportQuality:r=l,targetLabel:i=`recording`}=e;await T({videoPath:t,scriptPath:Ze(),scriptArgs:[`--max-size`,String(n),`--quality`,r],commandDescription:`Failed to resize the ${i}`})}function E(e){return e instanceof Error?e.message:String(e)}const nt=1e3;function D(e,t){return e.stderr.trim()||e.stdout.trim()||`${t} exited with code ${e.exitCode}`}function rt(e,t,n=Date.now()){let r=Math.max(0,n-t.startedAt);return r>=nt?{message:e,tooShort:!1}:{message:`${e}. Recording stopped after ${Math.round(r)}ms; wait at least ${nt}ms between record start and record stop so the recorder can finalize a playable MP4`,tooShort:!0}}async function O(e){let{recording:t,deps:i,trimStartMs:a,targetLabel:o}=e,s=Ue({recording:t,trimStartMs:a});if(!t.showTouches){r({level:`debug`,phase:`record_stop_overlay_skipped`,data:{reason:`hide_touches`}});return}if(t.gestureEvents.length===0){r({level:`debug`,phase:`record_stop_overlay_skipped`,data:{reason:`no_gesture_events`}});return}let c=Je();if(c){t.overlayWarning??=c;return}try{await n(`record_stop_overlay_export`,()=>i.overlayRecordingTouches({videoPath:t.outPath,telemetryPath:s,exportQuality:t.exportQuality,targetLabel:o}),{targetLabel:o,gestureEventCount:t.gestureEvents.length})}catch(e){t.overlayWarning??=`failed to overlay recording touches: ${E(e)}`}}function k(e,t){if(t===1)return e;let n=x.parse(e),r=n.ext||`.mp4`;return x.join(n.dir,`${n.name}.part-${String(t).padStart(3,`0`)}${r}`)}function A(e){return e.chunks??=[{index:1,path:e.outPath,remotePath:e.remotePath}],e.chunks}function it(e){if(!(Date.now()-e.startedAt<178e3))return`Android adb screenrecord stopped before record stop, likely after reaching the 180s platform limit. The MP4 may be truncated; final interactions after the limit are not in the video.`}function at(e){let{recording:t,startNextChunk:n,finishCurrentChunk:r,cleanupStartedChunk:i,persistRecordingState:a}=e,o=setTimeout(()=>{t.rotationPromise=ot({recording:t,startNextChunk:n,finishCurrentChunk:r,cleanupStartedChunk:i,persistRecordingState:a}).catch(e=>{t.rotationFailedReason=e instanceof Error?e.message:String(e)}).finally(()=>{t.rotationPromise=void 0,!t.stopping&&!t.rotationFailedReason&&at({recording:t,startNextChunk:n,finishCurrentChunk:r,cleanupStartedChunk:i,persistRecordingState:a})})},17e4);o.unref?.(),t.rotationTimer=o}async function ot(e){let{recording:t,startNextChunk:n,finishCurrentChunk:r,cleanupStartedChunk:i,persistRecordingState:a}=e;if(t.stopping)return;let o=A(t),s=o.length+1,c={remotePath:t.remotePath,remotePid:t.remotePid,startedAt:t.remoteStartedAt??t.startedAt},l=await st({recording:t,nextIndex:s,previousChunk:c,startNextChunk:n,finishCurrentChunk:r});if(!l)return;let{nextChunk:u,previousChunkFinished:d}=l;await lt({recording:t,chunks:o,nextChunk:u,nextIndex:s,previousState:ct({recording:t,nextChunk:u}),finishCurrentChunk:r,cleanupStartedChunk:i,persistRecordingState:a}),!d&&await dt(r,c)}async function st(e){let{recording:t,nextIndex:n,previousChunk:r,startNextChunk:i,finishCurrentChunk:a}=e,o=x.posix.dirname(t.remotePath);try{return{nextChunk:await i(o,n),previousChunkFinished:!1}}catch(e){let s=await a(r);if(s)throw Error(s);if(t.stopping)return;try{return{nextChunk:await i(o,n),previousChunkFinished:!0}}catch(t){throw t instanceof Error?t:e}}}function ct(e){let{recording:t,nextChunk:n}=e,r={remotePath:t.remotePath,remotePid:t.remotePid,remoteStartedAt:t.remoteStartedAt};return t.remotePath=n.remotePath,t.remotePid=n.remotePid,t.remoteStartedAt=n.startedAt,r}async function lt(e){let{recording:t,chunks:n,nextChunk:r,nextIndex:i,previousState:a,finishCurrentChunk:o,cleanupStartedChunk:s,persistRecordingState:c}=e;n.push({index:i,path:k(t.outPath,i),remotePath:r.remotePath}),t.warning??=`Android adb screenrecord is capped at 180s, so this recording was split into multiple MP4 chunks.`;try{await c?.(t)}catch(e){throw ut({recording:t,chunks:n,previousState:a}),await ft({nextChunk:r,finishCurrentChunk:o,cleanupStartedChunk:s})||e}}function ut(e){let{recording:t,chunks:n,previousState:r}=e;n.pop(),t.remotePath=r.remotePath,t.remotePid=r.remotePid,t.remoteStartedAt=r.remoteStartedAt}async function dt(e,t){let n=await e(t);if(n)throw Error(n)}async function ft(e){let{nextChunk:t,finishCurrentChunk:n,cleanupStartedChunk:r}=e,i;try{await dt(n,t)}catch(e){i=e}try{await r?.(t)}catch(e){i??=e}return i}async function pt(e){let{recording:t,deps:n}=e;if(A(t).length<=1){await O({recording:t,deps:n,targetLabel:`Android recording`});return}Ue({recording:t}),t.showTouches&&t.gestureEvents.length>0&&(t.overlayWarning??=`touch overlay burn-in is skipped for chunked Android recordings; returning raw chunks plus gesture telemetry`)}async function mt(e){for(let t of e.chunks){let n=await ht({deps:e.deps,deviceId:e.deviceId,remotePath:t.remotePath,outPath:t.path});if(n)return`failed to copy recording chunk ${t.index}: ${n}`}}async function ht(e){let{deps:t,deviceId:n,remotePath:a,outPath:o}=e,s;for(let e=0;e<2;e+=1){_t(o);let c=await i(a,o,{allowFailure:!0,device:_(n)});if(c.exitCode!==0)s=D(c,`adb pull`);else{await t.waitForStableFile(o,{pollMs:250,attempts:20});let i=await t.isPlayableVideo(o);if(r({level:`debug`,phase:`record_stop_android_pull_validation`,data:{deviceId:n,remotePath:a,outPath:o,attempt:e+1,fileSize:gt(o),playable:i}}),i)return;r({level:`warn`,phase:`record_stop_android_invalid_video_retry`,data:{deviceId:n,remotePath:a,outPath:o,attempt:e+1}})}e<1&&await g(750)}return s?`failed to copy recording from device: ${s}`:(_t(o),`failed to copy recording from device: pulled file is not a playable MP4`)}function gt(e){try{return b.statSync(e).size}catch{return 0}}function _t(e){try{b.rmSync(e,{force:!0})}catch{}}const vt=`agent-device-recording-active.json`,yt=[`/sdcard`,`/data/local/tmp`];function bt(e){let t=e.trim().match(/^(\d+)\s+.*\bscreenrecord\b.*(\/(?:sdcard|data\/local\/tmp)\/agent-device-recording-(\d+)\.mp4)(?:\s|$)/);if(!t)return;let[,n,r,i]=t;if(!n||!r)return;let a=Number(i);return{remotePid:n,remotePath:r,startedAt:Number.isFinite(a)?a:Date.now()}}function xt(e){let t=Dt(e);if(!t)return{kind:`delete`};let n=kt(t);if(!n)return{kind:`blocked`,reason:`unsupported_or_malformed_manifest`};let r=jt(t.current),i=Mt(t.pending),a=Nt(t.chunks);return a?!r&&!i?{kind:`blocked`,reason:`invalid_recording_state`}:{kind:`manifest`,manifest:{...n,sessionScope:Ft(t.sessionScope),current:r,pending:i,chunks:a}}:{kind:`blocked`,reason:`invalid_recording_chunks`}}function St(e){return`${x.posix.dirname(e)}/${vt}`}function j(){return yt.map(e=>`${e}/${vt}`)}function Ct(e){let{deviceId:t,sessionName:n,sessionScope:r,recordingId:i,startedAt:a,showTouches:o,remotePath:s}=e;return{version:1,sessionName:n,sessionScope:r,recordingId:i,deviceId:t,startedAt:a,showTouches:o,pending:{remotePath:s},chunks:[{index:1,remotePath:s}]}}function wt(e){let{deviceId:t,sessionName:n,sessionScope:r,recording:i}=e;return{version:1,sessionName:n,sessionScope:r,recordingId:i.recordingId??`android-${i.remotePid}-${i.remoteStartedAt??i.startedAt}`,deviceId:t,startedAt:i.startedAt,showTouches:i.showTouches,current:{remotePath:i.remotePath,remotePid:i.remotePid,startedAt:i.remoteStartedAt??i.startedAt},chunks:Et(i)}}function Tt(e){let{deviceId:t,sessionName:n,sessionScope:r,recording:i,nextRemotePath:a,nextIndex:o}=e;return{...wt({deviceId:t,sessionName:n,sessionScope:r,recording:i}),pending:{remotePath:a},chunks:Et(i,{index:o,remotePath:a})}}function Et(e,t){return[...e.chunks??[{index:1,remotePath:e.remotePath}],...t?[t]:[]].map(e=>({index:e.index,remotePath:e.remotePath}))}function Dt(e){try{let t=JSON.parse(e);return Ot(t)?t:void 0}catch{return}}function Ot(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function kt(e){if(e.version!==1)return;let t=At(e);if(!t)return;let n=It(e.startedAt);if(n===void 0)return;let r=Lt(e.showTouches);if(r!==void 0)return{version:1,...t,startedAt:n,showTouches:r}}function At(e){let t=M(e.sessionName),n=M(e.recordingId),r=M(e.deviceId);if(!(!t||!n||!r))return{sessionName:t,recordingId:n,deviceId:r}}function jt(e){if(!e||typeof e!=`object`)return;let t=e;if(!(typeof t.remotePid!=`string`||!/^\d+$/.test(t.remotePid)||typeof t.remotePath!=`string`||!N(t.remotePath)))return{remotePid:t.remotePid,remotePath:t.remotePath,startedAt:typeof t.startedAt==`number`&&Number.isFinite(t.startedAt)?t.startedAt:Date.now()}}function Mt(e){if(!e||typeof e!=`object`)return;let t=e;if(!(typeof t.remotePath!=`string`||!N(t.remotePath)))return{remotePath:t.remotePath}}function Nt(e){if(!Array.isArray(e))return;let t=e.map(Pt).filter(e=>e!==void 0);return t.length>0&&t.length===e.length?t:void 0}function Pt(e){if(!e||typeof e!=`object`)return;let t=e;if(!(typeof t.index!=`number`||!Number.isInteger(t.index)||t.index<1||typeof t.remotePath!=`string`||!N(t.remotePath)))return{index:t.index,remotePath:t.remotePath}}function Ft(e){if(!e||typeof e!=`object`)return;let t=e;if(!(t.kind!==`cwd`||typeof t.id!=`string`))return{kind:`cwd`,id:t.id}}function M(e){return typeof e==`string`?e:void 0}function It(e){return typeof e==`number`&&Number.isFinite(e)?e:void 0}function Lt(e){return typeof e==`boolean`?e:void 0}function N(e){return/^\/(?:sdcard|data\/local\/tmp)\/agent-device-recording-\d+\.mp4$/.test(e)}const Rt=`Recovered Android recording after daemon restart from durable device manifest.`,zt=`touch overlay burn-in is unavailable after daemon restart because gesture telemetry is stored in daemon memory`,P=`Recovered Android recording after daemon restart from durable device manifest; the screenrecord process was no longer running, so the MP4 may be truncated.`,F=`Recovered Android recording from an interrupted chunk rotation; returning chunks known to be safely owned by the durable manifest.`,I=5e3;async function L(e,t,n){return await re(_(e),t,n)}async function Bt(e){let t={live:[],uncertain:[],blocked:[]};for(let n of j()){let r=await L(e,[`shell`,`cat`,n],{allowFailure:!0,timeoutMs:I});if(r.exitCode!==0)continue;let i=xt(r.stdout);if(i.kind===`delete`){await H({deviceId:e,metadataPath:n,phase:`record_stop_android_recovery_metadata_invalid_cleanup_failed`});continue}if(i.kind===`blocked`){t.blocked.push({metadataPath:n,reason:i.reason});continue}let a=i.manifest;if(a.deviceId!==e){t.blocked.push({metadataPath:n,reason:`device_mismatch`});continue}let o=await Vt(e,a);if(o.kind===`live`){t.live.push(o.manifest);continue}if(o.kind===`uncertain`){t.uncertain.push(a);continue}await H({deviceId:e,metadataPath:n,phase:`record_stop_android_recovery_metadata_stale_cleanup_failed`})}return t}async function Vt(e,t){return t.pending?await Ht(e,t,t.pending):await Kt(e,t)}async function Ht(e,t,n){let r=await Jt(e,n.remotePath);return Wt(t,r)||(t.current?await Ut(e,t,t.current,r):await Gt(e,t,n.remotePath,r))}async function Ut(e,t,n,r){let i=await qt(e,n);return i===`uncertain`||r===`uncertain`?{kind:`uncertain`}:i===`stale`?{kind:`stale`}:R({manifest:t,current:n,chunks:Xt(t.chunks,n.remotePath),recoveryWarning:i===`finished`?`${F} ${P}`:F})}function Wt(e,t){if(!(!t||t===`uncertain`))return R({manifest:e,current:t,recoveryWarning:e.current?F:Rt})}async function Gt(e,t,n,r){return r===`uncertain`?{kind:`uncertain`}:await Yt(e,n)?R({manifest:t,current:{remotePath:n,remotePid:``,startedAt:t.startedAt},recoveryWarning:P}):{kind:`stale`}}async function Kt(e,t){if(!t.current)return{kind:`stale`};let n=await qt(e,t.current);return n===`live`?R({manifest:t,current:t.current}):n===`finished`?R({manifest:t,current:t.current,recoveryWarning:P}):{kind:n}}function R(e){let{manifest:t,current:n,chunks:r,recoveryWarning:i}=e;return{kind:`live`,manifest:{...t,current:n,chunks:r??t.chunks,...i?{recoveryWarning:i}:{}}}}async function qt(e,t){let n=await L(e,[`shell`,`ps`,`-o`,`pid=,args=`,`-p`,t.remotePid],{allowFailure:!0,timeoutMs:I});if(n.exitCode!==0)return r({level:`debug`,phase:`record_stop_android_recovery_metadata_probe_uncertain`,data:{deviceId:e,remotePid:t.remotePid,remotePath:t.remotePath,exitCode:n.exitCode,stdout:n.stdout.trim(),stderr:n.stderr.trim()}}),`uncertain`;let i=n.stdout.split(/\r?\n/),a=i.map(e=>e.trim()).find(e=>e.startsWith(t.remotePid));return i.map(bt).some(e=>e?.remotePid===t.remotePid&&e.remotePath===t.remotePath)?`live`:a?.includes(`screenrecord`)?`uncertain`:a?`stale`:await Yt(e,t.remotePath)?`finished`:`stale`}async function Jt(e,t){let n=await L(e,[`shell`,`ps`,`-A`,`-o`,`pid=,args=`],{allowFailure:!0,timeoutMs:I});return n.exitCode===0?n.stdout.split(/\r?\n/).map(bt).find(e=>e?.remotePath===t):(r({level:`debug`,phase:`record_stop_android_recovery_ps_failed`,data:{deviceId:e,remotePath:t,exitCode:n.exitCode,stdout:n.stdout.trim(),stderr:n.stderr.trim()}}),`uncertain`)}async function Yt(e,t){let n=await L(e,[`shell`,`stat`,`-c`,`%s`,t],{allowFailure:!0,timeoutMs:I}),r=n.exitCode===0?Number(n.stdout.trim()):NaN;return Number.isFinite(r)&&r>=1}function Xt(e,t){let n=e.findIndex(e=>e.remotePath===t);return n>=0?e.slice(0,n+1):e}async function Zt(e){let{deviceId:t,sessionName:n,sessionScope:r,recordingId:i,startedAt:a,showTouches:o,remotePath:s}=e;return await B({deviceId:t,manifest:Ct({deviceId:t,sessionName:n,sessionScope:r,recordingId:i,startedAt:a,showTouches:o,remotePath:s}),phase:`record_start_android_recovery_metadata_failed`})}async function Qt(e){let{deviceId:t,sessionName:n,sessionScope:r,recording:i,nextRemotePath:a,nextIndex:o}=e;return await B({deviceId:t,manifest:Tt({deviceId:t,sessionName:n,sessionScope:r,recording:i,nextRemotePath:a,nextIndex:o}),phase:`record_rotate_android_recovery_metadata_failed`})}async function z(e){let{deviceId:t,sessionName:n,sessionScope:r,recording:i}=e;return await B({deviceId:t,manifest:wt({deviceId:t,sessionName:n,sessionScope:r,recording:i}),phase:`record_start_android_recovery_metadata_failed`})}async function B(e){let{deviceId:t,manifest:n,phase:r}=e,i=n.current?.remotePath??n.pending?.remotePath;if(!i)return`failed to write Android recording recovery manifest: missing path`;let a=St(i),o=`${a}.tmp`,s=await L(t,[`shell`,`printf %s ${m(JSON.stringify(n))} > ${m(o)} && mv -f ${m(o)} ${m(a)}`],{allowFailure:!0,timeoutMs:I});if(s.exitCode!==0)return $t({phase:r,deviceId:t,metadataPath:a,result:s}),await H({deviceId:t,metadataPath:o,phase:`${r}_tmp_cleanup_failed`}),`failed to write Android recording recovery manifest: ${D(s,`adb shell write recovery manifest`)}`;for(let e of j())e!==a&&await H({deviceId:t,metadataPath:e,phase:`record_start_android_recovery_metadata_stale_cleanup_failed`})}async function V(e){for(let t of j())await H({deviceId:e,metadataPath:t,phase:`record_stop_android_recovery_metadata_cleanup_failed`})}async function H(e){let{deviceId:t,metadataPath:n,phase:r}=e,i=await L(t,[`shell`,`rm`,`-f`,n],{allowFailure:!0,timeoutMs:I});i.exitCode!==0&&$t({phase:r,deviceId:t,metadataPath:n,result:i})}function $t(e){let{phase:t,deviceId:n,metadataPath:i,result:a}=e;r({level:`warn`,phase:t,data:{deviceId:n,metadataPath:i,exitCode:a.exitCode,stdout:a.stdout.trim(),stderr:a.stderr.trim()}})}async function en(e){let{sessionName:t,activeSession:n,device:r,recordingBase:i}=e,a=await Bt(r.id);return a.live.length>0?rn({sessionName:t,activeSession:n,device:r,recordingBase:i,manifests:a.live}):a.uncertain.length>0?tn({sessionName:t,activeSession:n,manifests:a.uncertain}):a.blocked.length>0?nn(a.blocked):null}function tn(e){let{sessionName:t,activeSession:n,manifests:r}=e,i=on({sessionName:t,activeSession:n,manifests:r}),a={activeRecordings:i.activeRecordings,recoveryBlocked:`manifest_liveness_uncertain`,hint:`Retry record stop after the device responds. Android recording recovery requires a verified durable manifest.`};return i.kind===`owner-mismatch`?v(`INVALID_ARGS`,fn(r),a):i.kind===`ambiguous`?v(`INVALID_ARGS`,`multiple active Android recording manifests could not be verified; cannot safely recover missing recording state`,a):v(`INVALID_ARGS`,`active Android recording manifest could not be verified; retry record stop after the device responds`,a)}function nn(e){return v(`INVALID_ARGS`,`active Android recording manifest could not be validated`,{recoveryBlocked:`manifest_invalid_or_unsupported`,manifests:e,hint:`Retry with the same agent-device version that started the recording, or inspect and remove stale device recovery metadata after confirming no recording is active.`})}function rn(e){let{sessionName:t,activeSession:n,device:r,recordingBase:i,manifests:a}=e,o=an({sessionName:t,activeSession:n,manifests:a});return`ok`in o?o:(cn(r,o),ln(o,i))}function an(e){let{sessionName:t,activeSession:n,manifests:r}=e,i=on({sessionName:t,activeSession:n,manifests:r});return i.kind===`selected`?i.manifest:i.kind===`owner-mismatch`?v(`INVALID_ARGS`,fn(r),{activeRecordings:i.activeRecordings}):v(`INVALID_ARGS`,`multiple active Android recording manifests exist; cannot safely recover missing recording state`,{activeRecordings:i.activeRecordings})}function on(e){let{sessionName:t,activeSession:n,manifests:r}=e,i=r.filter(e=>un(e,t,n)),a=sn(r);return i.length===0?{kind:`owner-mismatch`,activeRecordings:a}:i.length>1||r.length>1?{kind:`ambiguous`,activeRecordings:a}:{kind:`selected`,manifest:i[0],activeRecordings:a}}function sn(e){return e.map(e=>({sessionName:e.sessionName,sessionScope:e.sessionScope,recordingId:e.recordingId,remotePid:e.current?.remotePid,remotePath:e.current?.remotePath??e.pending?.remotePath}))}function cn(e,t){r({level:`warn`,phase:`record_stop_android_recovered_missing_state`,data:{deviceId:e.id,sessionName:t.sessionName,recordingId:t.recordingId,remotePath:t.current.remotePath,remotePid:t.current.remotePid,chunks:t.chunks.length}})}function ln(e,t){let n=e.recoveryWarning??Rt;return{platform:`android`,recordingId:e.recordingId,remotePath:e.current.remotePath,remotePid:e.current.remotePid,remoteStartedAt:e.current.startedAt,chunks:e.chunks.map(e=>({index:e.index,path:k(t.outPath,e.index),remotePath:e.remotePath})),outPath:t.outPath,clientOutPath:t.clientOutPath,telemetryPath:t.telemetryPath,startedAt:e.startedAt,maxSize:t.maxSize,exportQuality:t.exportQuality,showTouches:!1,gestureEvents:[],warning:e.showTouches?`${n} ${zt}.`:n,overlayWarning:e.showTouches?zt:void 0}}function un(e,t,n){return e.sessionName===t&&dn(e.sessionScope,n.sessionScope)}function dn(e,t){return!e&&!t?!0:!e||!t?!1:e.kind===t.kind&&e.id===t.id}function fn(e){if(e.length===1){let t=e[0];return t.sessionScope?`active Android recording belongs to session "${t.sessionName}" in ${t.sessionScope.kind} scope; retry record stop from the original working directory without --session to recover it`:`active Android recording belongs to session "${t.sessionName}"; run record stop --session ${t.sessionName} to recover it`}return`active Android recordings belong to other sessions; cannot safely recover missing recording state`}const pn={medium:8e6,high:2e7},U=5e3;async function W(e,t,n){return await re(_(e),t,n)}function mn(e){return e.split(/\r?\n/).map(e=>e.trim()).filter(e=>/^\d+$/.test(e)).at(-1)}async function G(e,t){let n=await W(e,[`shell`,`ps`,`-o`,`pid=`,`-p`,t],{allowFailure:!0,timeoutMs:U});return n.exitCode===0?n.stdout.split(/\s+/).map(e=>e.trim()).includes(t):!1}async function hn(e,t){for(let n=0;n<40;n+=1){if(!await G(e,t))return!0;await g(250)}return!await G(e,t)}async function gn(e,t){let n,r=0;for(let i=0;i<20;i+=1){let i=await W(e,[`shell`,`stat`,`-c`,`%s`,t],{allowFailure:!0,timeoutMs:U}),a=i.exitCode===0?i.stdout.trim():``;if(a.length>0&&a===n){if(r+=1,r>=4)return}else r=0;n=a,await g(250)}}async function _n(e,t,n){for(let r=0;r<8;r+=1){let i=await W(e,[`shell`,`stat`,`-c`,`%s`,t],{allowFailure:!0,timeoutMs:U}),a=i.exitCode===0?Number(i.stdout.trim()):NaN;if(Number.isFinite(a)&&a>0)return!0;if(!await G(e,n))return!1;if(r+1>=2)return!0;await g(250)}return!1}function vn(e,t){let n=`agent-device-recording-${e}.mp4`,r=[`/sdcard`,`/data/local/tmp`];return(t&&r.includes(t)?[t,...r.filter(e=>e!==t)]:r).map(e=>`${e}/${n}`)}async function yn(e){let{deviceId:t,maxSize:n}=e;if(n===void 0)return;let r=await W(t,[`shell`,`wm`,`size`],{allowFailure:!0,timeoutMs:U}),i=r.stdout.match(/Override size:\s*(\d+)x(\d+)/)??r.stdout.match(/Physical size:\s*(\d+)x(\d+)/);if(r.exitCode!==0||!i)throw Error(`failed to resolve Android screen size for recording max-size: ${D(r,`adb shell wm size`)}`);return bn({width:Number(i[1]),height:Number(i[2]),maxSize:n})}function bn(e){let t=Math.max(e.width,e.height);if(t<=e.maxSize)return{width:e.width,height:e.height};let n=e.maxSize/t;return{width:xn(e.width,n),height:xn(e.height,n)}}function xn(e,t){return Math.max(2,Math.round(e*t/2)*2)}function Sn(e,t,n){let r=[`screenrecord`];return t&&r.push(`--size`,`${t.width}x${t.height}`),r.push(`--bit-rate`,String(pn[n])),r.push(e),`${r.join(` `)} >/dev/null 2>&1 & echo $!`}async function K(e,t){await W(e,[`shell`,`rm`,`-f`,t],{allowFailure:!0,timeoutMs:U})}async function q(e,t){let n=await W(e,[`shell`,`kill`,`-9`,t],{allowFailure:!0,timeoutMs:U});return r({level:`warn`,phase:`record_stop_android_force_signal`,data:{deviceId:e,remotePid:t,exitCode:n.exitCode,stdout:n.stdout.trim(),stderr:n.stderr.trim()}}),n.exitCode!==0&&await G(e,t)?!1:await hn(e,t)}async function Cn(e){let{device:t,recordingSize:n,quality:r,preferredRemoteDir:i,hooks:a}=e,o=`failed to start recording: Android screenrecord did not begin producing frames`;for(let e of vn(Date.now(),i)){let i=await wn({device:t,recordingSize:n,quality:r,remotePath:e,hooks:a});if(i.kind===`started`)return i.chunk;o=i.message}return{error:v(`COMMAND_FAILED`,o)}}async function wn(e){let{device:t,recordingSize:n,quality:i,remotePath:a,hooks:o}=e,s=await o?.prepareRemotePath?.(a);if(s)return{kind:`failed`,message:s};let c=await W(t.id,[`shell`,Sn(a,n,i)],{allowFailure:!0,timeoutMs:U});if(c.exitCode!==0)return await o?.cleanupPreparedRemotePath?.(a),{kind:`failed`,message:`failed to start recording: ${D(c,`adb shell screenrecord`)}`};let l=mn(c.stdout);return l?(r({level:`debug`,phase:`record_start_android_started`,data:{deviceId:t.id,remotePath:a,remotePid:l}}),await _n(t.id,a,l)?{kind:`started`,chunk:{remotePath:a,remotePid:l,startedAt:Date.now()}}:(await q(t.id,l),await o?.cleanupPreparedRemotePath?.(a),await K(t.id,a),{kind:`failed`,message:`failed to start recording: Android screenrecord did not begin producing frames`})):(await o?.cleanupPreparedRemotePath?.(a),await K(t.id,a),{kind:`failed`,message:`failed to start recording: adb did not return a valid Android screenrecord pid`})}async function Tn(e){let{sessionName:t,activeSession:n,device:r,recordingBase:i}=e,a;try{a=await yn({deviceId:r.id,maxSize:i.maxSize})}catch(e){return v(`COMMAND_FAILED`,e instanceof Error?e.message:String(e))}let o=i.exportQuality??`medium`,s=be(),c=await Cn({device:r,recordingSize:a,quality:o,hooks:{prepareRemotePath:async e=>await Zt({deviceId:r.id,sessionName:t,sessionScope:n.sessionScope,recordingId:s,startedAt:i.startedAt,showTouches:i.showTouches,remotePath:e}),cleanupPreparedRemotePath:async()=>{await V(r.id)}}});if(`error`in c)return c.error;let l=En({recordingBase:i,chunk:c,recordingId:s}),u=await z({deviceId:r.id,sessionName:t,sessionScope:n.sessionScope,recording:l});return u?(await q(r.id,l.remotePid),await K(r.id,l.remotePath),await V(r.id),v(`COMMAND_FAILED`,`failed to start recording: ${u}`)):(Dn({activeSession:n,sessionName:t,device:r,recording:l,recordingSize:a,quality:o}),l)}function En(e){let{recordingBase:t,chunk:n,recordingId:r}=e;return{platform:`android`,recordingId:r,remotePath:n.remotePath,remotePid:n.remotePid,remoteStartedAt:n.startedAt,chunks:[{index:1,path:t.outPath,remotePath:n.remotePath}],...t,startedAt:n.startedAt}}function Dn(e){let{activeSession:t,sessionName:n,device:r,recording:i,recordingSize:a,quality:o}=e;at({recording:i,finishCurrentChunk:async e=>await On({device:r,recording:i,remotePath:e.remotePath,remotePid:e.remotePid,waitForRemoteFileStability:!1}),cleanupStartedChunk:async e=>{await K(r.id,e.remotePath)},startNextChunk:async(e,s)=>{let c=await Cn({device:r,recordingSize:a,quality:o,preferredRemoteDir:e,hooks:{prepareRemotePath:async e=>await Qt({deviceId:r.id,sessionName:n,sessionScope:t.sessionScope,recording:i,nextRemotePath:e,nextIndex:s}),cleanupPreparedRemotePath:async()=>{await z({deviceId:r.id,sessionName:n,sessionScope:t.sessionScope,recording:i})}}});if(`error`in c)throw Error(c.error.ok?`failed to start next Android recording chunk`:c.error.error.message);return c},persistRecordingState:async e=>{let i=await z({deviceId:r.id,sessionName:n,sessionScope:t.sessionScope,recording:e});if(i)throw Error(i)}})}async function On(e){let{device:t,recording:n,remotePath:i=n.remotePath,remotePid:a=n.remotePid,waitForRemoteFileStability:o=!0}=e;if(!a){Ln(n,it(n)),o&&await gn(t.id,i);return}await G(t.id,a)||Ln(n,it(n));let s=await W(t.id,[`shell`,`kill`,`-2`,a],{allowFailure:!0,timeoutMs:U});if(r({level:`debug`,phase:`record_stop_android_signal`,data:{deviceId:t.id,remotePath:i,remotePid:a,exitCode:s.exitCode,stdout:s.stdout.trim(),stderr:s.stderr.trim()}}),s.exitCode!==0)return await kn(t.id,a,s);let c=await An(t.id,a);if(c)return c;o&&await gn(t.id,i)}async function kn(e,t,n){if(await G(e,t)&&!await q(e,t))return`failed to stop recording: ${D(n,`adb shell kill`)}`}async function An(e,t){if(!await hn(e,t)&&!await q(e,t))return`failed to stop recording: Android screenrecord pid ${t} did not exit`}async function jn(e){let{deps:t,device:n,recording:i,stopRequestedAt:a}=e;r({level:`debug`,phase:`record_stop_android_enter`,data:{deviceId:n.id,remotePath:i.remotePath,remotePid:i.remotePid}}),i.stopping=!0,await Mn(i);let o=await On({device:n,recording:i});i.rotationFailedReason&&!o&&(i.warning??=`Android recording chunk rotation failed: ${i.rotationFailedReason}`);let s=o===void 0?await Nn({deps:t,device:n,recording:i}):void 0,c=await Pn({deviceId:n.id,recording:i,recordCleanupError:o===void 0});return s?v(`COMMAND_FAILED`,In(s,i,a)):o?v(`COMMAND_FAILED`,In(o,i,a)):c?v(`COMMAND_FAILED`,c):null}async function Mn(e){e.rotationTimer&&=(clearTimeout(e.rotationTimer),void 0),await e.rotationPromise}async function Nn(e){let{deps:t,device:n,recording:r}=e,i=await mt({deps:t,deviceId:n.id,chunks:A(r)});if(i)return i;await pt({recording:r,deps:t})}async function Pn(e){let{deviceId:t,recording:n,recordCleanupError:r}=e,i;for(let e of A(n)){let n=await Fn(t,e.remotePath);n&&r&&(i=n)}return await V(t),i}async function Fn(e,t){let n=await W(e,[`shell`,`rm`,`-f`,t],{allowFailure:!0,timeoutMs:U});if(r({level:`debug`,phase:`record_stop_android_cleanup`,data:{deviceId:e,remotePath:t,exitCode:n.exitCode,stdout:n.stdout.trim(),stderr:n.stderr.trim()}}),n.exitCode!==0)return`failed to clean up remote recording: ${D(n,`adb shell rm`)}`}function In(e,t,n){return rt(e,t,n).message}function Ln(e,t){!t||e.warning?.includes(t)||(e.warning=e.warning?`${e.warning} ${t}`:t)}function J(e){let t=e.appBundleId?.trim();return t&&t.length>0?t:void 0}function Rn(e){return E(e).toLowerCase().includes(`recording already in progress`)}function zn(e,n,r){return e.toArray().find(e=>e.name!==r&&t(e.device)&&e.device.kind===`device`&&e.device.id===n&&e.recording?.platform===`ios-device-runner`)}function Y(e,t,n){return ge({req:e,logPath:t,traceLogPath:n.trace?.outPath})}function Bn(e){return typeof e.runnerStartedAtUptimeMs!=`number`||typeof e.targetAppReadyUptimeMs!=`number`?0:Math.max(0,e.targetAppReadyUptimeMs-e.runnerStartedAtUptimeMs)}async function Vn(e){let{req:t,activeSession:n,device:i,logPath:a,deps:o}=e,s=J(n);try{await o.runAppleRunnerCommand(i,{command:`recordStop`,appBundleId:s},Y(t,a,n))}catch(e){r({level:`warn`,phase:`record_stop_runner_failed`,data:{platform:i.platform,kind:i.kind,deviceId:i.id,session:n.name,error:E(e)}})}}async function Hn(e){let{req:t,activeSession:n,device:i,logPath:a,deps:o}=e,s=J(n);if(s)try{let e=await o.runAppleRunnerCommand(i,{command:`snapshot`,appBundleId:s,interactiveOnly:!0,depth:1},Y(t,a,n)),c=Date.now();return typeof e.currentUptimeMs==`number`&&Number.isFinite(e.currentUptimeMs)&&e.currentUptimeMs>0?(r({level:`debug`,phase:`record_start_gesture_clock_anchor`,data:{source:`warm_snapshot`}}),{gestureClockOriginAtMs:c,gestureClockOriginUptimeMs:e.currentUptimeMs}):void 0}catch(e){r({level:`warn`,phase:`record_start_simulator_runner_warm_failed`,data:{deviceId:i.id,session:n.name,appBundleId:s,error:E(e)}});return}}async function Un(e){let{req:t,activeSession:n,sessionStore:i,device:a,logPath:o,deps:s,fpsFlag:c,recordingBase:l,appBundleId:u}=e,d=`agent-device-recording-${Date.now()}.mp4`,f=`tmp/${d}`,p=Y(t,o,n),m,h,g=async()=>s.runAppleRunnerCommand(a,{command:`recordStart`,outPath:d,fps:c,maxSize:l.maxSize,appBundleId:u},p);try{let e=await g();m=typeof e.recorderStartUptimeMs==`number`?e.recorderStartUptimeMs:void 0,h=typeof e.targetAppReadyUptimeMs==`number`?e.targetAppReadyUptimeMs:void 0}catch(e){if(!Rn(e))return v(`COMMAND_FAILED`,`failed to start recording: ${E(e)}`);r({level:`warn`,phase:`record_start_runner_desynced`,data:{platform:a.platform,kind:a.kind,deviceId:a.id,session:n.name,error:E(e)}});let t=zn(i,a.id,n.name);if(t)return v(`COMMAND_FAILED`,`failed to start recording: recording already in progress in session '${t.name}'`);try{await s.runAppleRunnerCommand(a,{command:`recordStop`,appBundleId:u},p)}catch{}try{let e=await g();m=typeof e.recorderStartUptimeMs==`number`?e.recorderStartUptimeMs:void 0,h=typeof e.targetAppReadyUptimeMs==`number`?e.targetAppReadyUptimeMs:void 0}catch(e){return v(`COMMAND_FAILED`,`failed to start recording: ${E(e)}`)}}return{platform:`ios-device-runner`,remotePath:f,runnerStartedAtUptimeMs:m,targetAppReadyUptimeMs:h,...l}}async function Wn(e){let{req:t,activeSession:n,device:r,logPath:i,deps:a,fpsFlag:o,recordingBase:s,appBundleId:c}=e;try{await a.runAppleRunnerCommand(r,{command:`recordStart`,outPath:s.outPath,fps:o,maxSize:s.maxSize,appBundleId:c},Y(t,i,n))}catch(e){return v(`COMMAND_FAILED`,`failed to start recording: ${E(e)}`)}return{platform:`macos-runner`,...s}}async function Gn(e){let{req:t,activeSession:n,device:r,logPath:i,deps:a,recording:o}=e;await Vn({req:t,activeSession:n,device:r,logPath:i,deps:a});let s={stdout:``,stderr:``,exitCode:1};for(let e of ie)if(s=await a.runCmd(`xcrun`,[`devicectl`,`device`,`copy`,`from`,`--device`,r.id,`--source`,o.remotePath,`--destination`,o.outPath,`--domain-type`,`appDataContainer`,`--domain-identifier`,e],{allowFailure:!0}),s.exitCode===0)break;if(s.exitCode!==0)return v(`COMMAND_FAILED`,`failed to copy recording from device: ${s.stderr.trim()||s.stdout.trim()||`devicectl exited with code ${s.exitCode}`}`);let c=Bn(o);return c>0&&await a.trimRecordingStart({videoPath:o.outPath,trimStartMs:c}),await O({recording:o,deps:a,trimStartMs:c,targetLabel:`iOS recording`}),null}async function Kn(e){let{req:t,activeSession:n,device:r,logPath:i,deps:a,recording:o}=e;return await Vn({req:t,activeSession:n,device:r,logPath:i,deps:a}),await O({recording:o,deps:a,targetLabel:`macOS recording`}),null}const qn=5e3,Jn=2e3;async function Yn(e){let{deps:t,recording:n}=e;n.child.kill(`SIGINT`);let r=await X(n.wait,qn);return r||(await Z(t,n,`SIGINT`),r=await X(n.wait,Jn),r)||(n.child.kill(`SIGTERM`),await Z(t,n,`SIGTERM`),r=await X(n.wait,Jn),r)?r:(n.child.kill(`SIGKILL`),await Z(t,n,`SIGKILL`),await X(n.wait,Jn))}async function X(e,t){return await Promise.race([e,g(t).then(()=>null)])}async function Z(e,t,n){await Zn(e,t,n)||await Xn(e,t.outPath,n)}async function Xn(e,t,n){let i=`simctl.*recordVideo.*${er(t)}`,a;try{a=await e.runCmd(`pgrep`,[`-f`,i],{allowFailure:!0})}catch(e){r({level:`warn`,phase:`record_stop_ios_simulator_pgrep_failed`,data:{outPath:t,signal:n,error:E(e)}});return}let o=ee($n(a.stdout),{excludePid:process.pid}),s=ne(o,n);r({level:s>0?`warn`:`debug`,phase:`record_stop_ios_simulator_signal_recorders`,data:{outPath:t,signal:n,matchedPidCount:o.length,signaled:s,pgrepExitCode:a.exitCode}})}async function Zn(e,t,n){let i=t.recorderPid??t.child.pid;if(typeof i!=`number`||!Number.isInteger(i)||i<=0)return r({level:`debug`,phase:`record_stop_ios_simulator_owned_recorder_unavailable`,data:{outPath:t.outPath,signal:n,reason:`missing_recorder_pid`}}),!1;let a=await Qn(e,i,t.outPath,n),o=ee([i,...a.pids],{excludePid:process.pid}),s=ne(o,n);return r({level:s>0?`warn`:`debug`,phase:`record_stop_ios_simulator_signal_owned_recorder`,data:{outPath:t.outPath,signal:n,recorderPid:i,childPidCount:a.pids.length,matchedPidCount:o.length,signaled:s,pgrepExitCode:a.exitCode}}),s>0}async function Qn(e,t,n,i){let a;try{a=await e.runCmd(`pgrep`,[`-P`,String(t)],{allowFailure:!0})}catch(e){return r({level:`warn`,phase:`record_stop_ios_simulator_owned_pgrep_failed`,data:{outPath:n,signal:i,parentPid:t,error:E(e)}}),{pids:[]}}return{pids:$n(a.stdout),exitCode:a.exitCode}}function $n(e){return e.split(/\s+/).map(e=>Number(e)).filter(e=>Number.isInteger(e)&&e>0)}function er(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}async function tr(e){let{req:t,activeSession:n,device:r,logPath:i,deps:a,recordingBase:o,resolvedOut:s}=e,c=o.showTouches?await Hn({req:t,activeSession:n,device:r,logPath:i,deps:a}):void 0,{child:l,wait:u}=a.startIosSimulatorRecording({device:r,outPath:s}),d=await rr(s),f,p;if(c)f=c.gestureClockOriginAtMs,p=c.gestureClockOriginUptimeMs;else if(o.showTouches)try{let e=Date.now(),o=await a.runAppleRunnerCommand(r,{command:`uptime`,appBundleId:J(n)},Y(t,i,n));f=Math.round((e+Date.now())/2),p=typeof o.currentUptimeMs==`number`?o.currentUptimeMs:void 0}catch{}return{platform:`ios`,child:l,wait:u,...o,recorderPid:l.pid,startedAt:d,gestureClockOriginAtMs:p===void 0?void 0:f,gestureClockOriginUptimeMs:p}}async function nr(e){let{deps:t,recording:r,stopRequestedAt:i}=e;await n(`record_stop_tail_settle`,()=>t.waitForRecordingTail(r),{platform:r.platform,gestureEventCount:r.gestureEvents.length});let a=await n(`record_stop_ios_simulator_process`,()=>Yn({deps:t,recording:r}),{outPath:r.outPath});if(!a)return ir(`failed to stop recording: simctl recordVideo did not exit after ${qn}ms and forced cleanup`,r,i);if(a.exitCode!==0)return ir(`failed to stop recording: ${D(a,`simctl recordVideo`)}`,r,i);if(await n(`record_stop_video_stable`,()=>t.waitForStableFile(r.outPath,{pollMs:150,attempts:12}),{outPath:r.outPath}),!await n(`record_stop_video_playable_check`,()=>t.isPlayableVideo(r.outPath),{outPath:r.outPath}))return ir(`failed to stop recording: ${r.outPath} was not finalized into a playable video`,r,i);if(r.maxSize!==void 0)try{await n(`record_stop_resize`,()=>t.resizeRecording({videoPath:r.outPath,maxSize:r.maxSize,exportQuality:r.exportQuality,targetLabel:`iOS recording`}),{outPath:r.outPath,maxSize:r.maxSize})}catch(e){r.overlayWarning=`failed to resize recording: ${E(e)}`}return await n(`record_stop_finalize_overlay`,()=>O({recording:r,deps:t,targetLabel:`iOS recording`}),{outPath:r.outPath,showTouches:r.showTouches,gestureEventCount:r.gestureEvents.length}),null}async function rr(e){for(let t=0;t<2;t+=1){try{if(b.statSync(e).size>0)return Date.now()}catch{}if(t+1>=2)return Date.now();await g(250)}return Date.now()}function ir(e,t,n){let r=rt(e,t,n);return ar(t.outPath),v(`COMMAND_FAILED`,r.message)}function ar(e){try{b.rmSync(e,{force:!0})}catch{}}le();function or(e){let t=fe(e.platform)?.recording?.resolveBackendTag(e)??`unsupported`;return mr[t]}function sr(e){let{recording:t}=e;switch(t.platform){case`android`:return pr.stop({...e,recording:t});case`ios`:return fr.stop({...e,recording:t});case`ios-device-runner`:return ur.stop({...e,recording:t});case`macos-runner`:return dr.stop({...e,recording:t});case`web`:return lr.stop({...e,recording:t})}return t}function Q({req:e}){return e.positionals?.[1]??f(void 0)}function cr({req:e}){let t=e.positionals?.[1];return t===void 0?f(`web`):d(t,p)}const lr={recordingBackend:`agent-browser recording`,validateStart:e=>_r(e),resolveOutputPath:cr,start:async({activeSession:e,recordingBase:t,resolvedOut:n})=>{let r=vr(n);if(r)return r;if(e.recordOnlySession)return v(`INVALID_ARGS`,`record on web requires an active browser session; run open <url> --platform web first`);let i=y();return i.startRecording?(await i.startRecording(n),{...t,outPath:n,startedAt:Date.now(),platform:`web`,showTouches:!1}):v(`UNSUPPORTED_OPERATION`,`record is not supported by this web provider`)},stop:async({recording:e})=>await xr({recording:e}),cleanupRecordOnlySession:async()=>{try{await y().close()}catch{}}},ur={recordingBackend:`runner AVAssetWriter`,resolveOutputPath:Q,start:async({req:e,activeSession:t,sessionStore:n,device:r,logPath:i,deps:a,fpsFlag:o,recordingBase:s})=>{let c=J(t);return c?await Un({req:e,activeSession:t,sessionStore:n,device:r,logPath:i,deps:a,fpsFlag:o,recordingBase:s,appBundleId:c}):v(`INVALID_ARGS`,`record on physical iOS devices requires an active app session; run open <app> first`)},stop:async({req:e,activeSession:t,device:n,logPath:r,deps:i,recording:a})=>await Gn({req:e,activeSession:t,device:n,logPath:r,deps:i,recording:a})},dr={recordingBackend:`runner AVAssetWriter`,resolveOutputPath:Q,start:async({req:e,activeSession:t,device:n,logPath:r,deps:i,fpsFlag:a,recordingBase:o})=>{let s=J(t);return s?await Wn({req:e,activeSession:t,device:n,logPath:r,deps:i,fpsFlag:a,recordingBase:o,appBundleId:s}):v(`INVALID_ARGS`,`record on macOS requires an active app session; run open <app> first`)},stop:async({req:e,activeSession:t,device:n,logPath:r,deps:i,recording:a})=>await Kn({req:e,activeSession:t,device:n,logPath:r,deps:i,recording:a})},fr={recordingBackend:`simctl recordVideo`,resolveOutputPath:Q,start:async({req:e,activeSession:t,device:n,logPath:r,deps:i,recordingBase:a,resolvedOut:o})=>{let c=J(t),l=!s(a.recordingScope??`app`);return l&&!c?v(`INVALID_ARGS`,`record on iOS Simulator with app scope requires an active app session; run open <app> first, or use --scope device to record the full simulator screen`):l&&c&&yr(c)?v(`INVALID_ARGS`,`record on iOS Simulator cannot use Agent Device Runner as the active app session; run open <app> first`):await tr({req:e,activeSession:t,device:n,logPath:r,deps:i,recordingBase:a,resolvedOut:o})},stop:async({deps:e,recording:t,stopRequestedAt:n})=>await nr({deps:e,recording:t,stopRequestedAt:n})},pr={recordingBackend:`adb screenrecord`,resolveOutputPath:Q,start:async({sessionName:e,activeSession:t,device:n,recordingBase:r})=>await Tn({sessionName:e,activeSession:t,device:n,recordingBase:r}),recoverMissingStop:async({sessionName:e,activeSession:t,device:n,recordingBase:r})=>await en({sessionName:e,activeSession:t,device:n,recordingBase:r}),stop:async({deps:e,device:t,recording:n,stopRequestedAt:r})=>await jn({deps:e,device:t,recording:n,stopRequestedAt:r})},mr={web:lr,android:pr,macos:dr,"ios-device":ur,"ios-simulator":fr,unsupported:{recordingBackend:`unsupported`,resolveOutputPath:Q,start:async()=>v(`UNSUPPORTED_OPERATION`,`record is not supported on this device`),stop:async()=>v(`UNSUPPORTED_OPERATION`,`record is not supported on this device`)}},hr=[[`fps`,`--fps`],[`quality`,`--quality`],[`screenshotMaxSize`,`--max-size`],[`hideTouches`,`--hide-touches`]];function gr(e){let t=e.flags??{},n=hr.flatMap(([e,n])=>t[e]===void 0?[]:[n]);return s(t.recordingScope??`app`)?[...n,`--scope`]:n}function _r(e){let t=gr(e);return t.length>0?v(`INVALID_ARGS`,`web recordings do not support ${t.join(`, `)}; agent-browser records WebM directly`):null}function vr(e){return x.extname(e).toLowerCase()===`.webm`?null:v(`INVALID_ARGS`,`web recordings must use a ${p} output path`)}function yr(e){return ie.includes(e)}function br(e){try{b.rmSync(e,{force:!0})}catch{}}async function xr(e){let{recording:t}=e,n=y();return n.stopRecording?(await n.stopRecording(),Sr(t.outPath)?null:(br(t.outPath),v(`COMMAND_FAILED`,`failed to stop recording: ${t.outPath} was not finalized into a WebM video`))):v(`UNSUPPORTED_OPERATION`,`record is not supported by this web provider`)}function Sr(e){try{return b.statSync(e).size>0}catch{return!1}}function Cr(){return{runCmd:async(e,t,n)=>e===`xcrun`?await oe(t,n):await a(e,t,n),startIosSimulatorRecording:e=>ve().startIosSimulatorRecording(e),runAppleRunnerCommand:ae,waitForRecordingTail:wr,waitForStableFile:je,isPlayableVideo:Me,trimRecordingStart:$e,resizeRecording:tt,overlayRecordingTouches:et}}async function wr(e){e.platform===`ios`&&e.gestureEvents.length!==0&&await g(350)}function Tr(e){let{req:t,outPath:n,activeSession:r,recordingBackend:i,recordingScope:a}=e,o=c(t.flags?.quality);return{outPath:n,clientOutPath:t.meta?.clientArtifactPaths?.outPath,startedAt:Date.now(),recordingScope:a,recordingBackend:i,recordOnlySession:r.recordOnlySession===!0,activeSessionApp:r.appBundleId?{bundleId:r.appBundleId,...r.appName?{name:r.appName}:{}}:void 0,maxSize:t.flags?.screenshotMaxSize,exportQuality:o??`medium`,showTouches:t.flags?.hideTouches!==!0,gestureEvents:[]}}async function Er(e){let{req:t,sessionName:n,sessionStore:r,activeSession:i,device:a,logPath:o,deps:s}=e,c=Dr(e);return`backend`in c?kr({req:t,sessionName:n,sessionStore:r,activeSession:i,recording:await c.backend.start({req:t,sessionName:n,activeSession:i,sessionStore:r,device:a,logPath:o,deps:s,fpsFlag:c.fpsFlag,recordingBase:c.recordingBase,resolvedOut:c.resolvedOut}),outPath:c.outPath}):c}function Dr(e){let{req:t,activeSession:n,device:r,recordingScope:i}=e,a=or(r);return Or({req:t,activeSession:n,device:r,backend:a})||{...Fr(t,a,n,i),backend:a,fpsFlag:t.flags?.fps}}function Or(e){let{req:t,activeSession:n,device:r,backend:i}=e,a=[()=>Ar(n),()=>i.validateStart?.(t)??null,()=>jr({fpsFlag:t.flags?.fps,qualityFlag:t.flags?.quality,maxSizeFlag:t.flags?.screenshotMaxSize}),()=>pe(`record`,r)];for(let e of a){let t=e();if(t)return t}return null}function kr(e){let{req:t,sessionName:n,sessionStore:r,activeSession:i,recording:a,outPath:o}=e;if(`ok`in a)return a;i.recording=a,r.set(n,i);let s=r.ensureSessionDir(n);return _e(r,i,t,t.command,{action:`start`,showTouches:a.showTouches}),{ok:!0,data:{recording:`started`,outPath:a.clientOutPath??o,sessionStateDir:s,recordingBackend:a.recordingBackend,recordingScope:a.recordingScope,recordOnlySession:a.recordOnlySession,activeSessionApp:a.activeSessionApp,showTouches:a.showTouches}}}function Ar(e){return e.recording?v(`INVALID_ARGS`,`recording already in progress`):null}function jr(e){let{fpsFlag:t,qualityFlag:n,maxSizeFlag:r}=e;return Mr(t)??Nr(n)??Pr(r)}function Mr(e){return e!==void 0&&(!Number.isInteger(e)||e<1||e>120)?v(`INVALID_ARGS`,`fps must be an integer between 1 and 120`):null}function Nr(e){return e!==void 0&&c(e)===void 0?v(`INVALID_ARGS`,`quality must be one of: ${u.join(`, `)} (legacy numeric values 5-10 are accepted)`):null}function Pr(e){return e!==void 0&&(!Number.isInteger(e)||e<1)?v(`INVALID_ARGS`,`max-size must be a positive integer`):null}function Fr(e,t,n,r){let i=t.resolveOutputPath({req:e}),a=me.expandHome(i,e.meta?.cwd),o=Tr({req:e,outPath:a,activeSession:n,recordingBackend:t.recordingBackend,recordingScope:r});return b.mkdirSync(x.dirname(a),{recursive:!0}),b.rmSync(a,{force:!0}),{outPath:i,resolvedOut:a,recordingBase:o}}async function Ir(e){let{req:t,activeSession:n,device:r,logPath:i,deps:a}=e,o=await Lr(e);if(o&&`ok`in o)return o;if(!o)return v(`INVALID_ARGS`,`no active recording`);let s=Date.now(),c=o.invalidatedReason;return n.recording=void 0,await sr({req:t,activeSession:n,device:r,logPath:i,deps:a,recording:o,stopRequestedAt:s})||Vr(o,c)||Ur(o)}async function Lr(e){return e.activeSession.recording?e.activeSession.recording:await Rr(e)}async function Rr(e){let{req:t,sessionName:n,sessionStore:r,activeSession:i,device:a,logPath:o,deps:s}=e;if(Hr(r,a.id))return null;let c=or(a);if(!c.recoverMissingStop)return null;let{resolvedOut:l,recordingBase:u}=zr(t,c,i),d=await c.recoverMissingStop({req:t,sessionName:n,activeSession:i,sessionStore:r,device:a,logPath:o,deps:s,recordingBase:u,resolvedOut:l});return d?(`ok`in d||Br(l),d):null}function zr(e,t,n){let r=t.resolveOutputPath({req:e}),i=me.expandHome(r,e.meta?.cwd);return{resolvedOut:i,recordingBase:Tr({req:e,outPath:i,activeSession:n,recordingBackend:t.recordingBackend,recordingScope:n.recording?.recordingScope??`app`})}}function Br(e){b.mkdirSync(x.dirname(e),{recursive:!0}),b.rmSync(e,{force:!0})}function Vr(e,t){return t?e.platform===`ios`&&e.showTouches?(e.overlayWarning??=`overlay unavailable: ${t}`,null):v(`COMMAND_FAILED`,t):null}function Hr(e,t){for(let n of e.values())if(n.recording&&n.device.id===t)return!0;return!1}function Ur(e){let t=e.platform===`android`?e.chunks:void 0,n=[{field:`outPath`,artifactType:`screen-recording`,path:e.outPath,localPath:e.clientOutPath,fileName:x.basename(e.clientOutPath??e.outPath)}];return t&&t.length>1&&n.push(...t.slice(1).map(t=>({field:`chunkPath`,artifactType:`screen-recording-chunk`,path:t.path,localPath:$(e,t.index),fileName:x.basename($(e,t.index)??t.path)}))),e.telemetryPath&&n.push({field:`telemetryPath`,artifactType:`screen-recording-telemetry`,path:e.telemetryPath,localPath:Wr(e),fileName:x.basename(e.telemetryPath)}),{ok:!0,data:{recording:`stopped`,outPath:e.outPath,telemetryPath:e.telemetryPath,artifacts:n,recordingBackend:e.recordingBackend,recordingScope:e.recordingScope,recordOnlySession:e.recordOnlySession,activeSessionApp:e.activeSessionApp,durationMs:Date.now()-e.startedAt,showTouches:e.showTouches,warning:e.warning,overlayWarning:e.overlayWarning,chunks:t?.map(t=>({index:t.index,path:$(e,t.index)??t.path}))}}}function $(e,t){if(!(e.platform!==`android`||!e.clientOutPath))return k(e.clientOutPath,t)}function Wr(e){if(e.clientOutPath)return ze(e.clientOutPath)}async function Gr(e,t,n,r={}){n.recordOnlySession&&(await or(n.device).cleanupRecordOnlySession?.(n),r.writeLog&&e.writeSessionLog(n),e.delete(t))}async function Kr(e){let{req:t,sessionName:n,sessionStore:r,logPath:i}=e,a=Cr(),o=r.get(n),c=(t.positionals?.[0]??``).toLowerCase();if(![`start`,`stop`].includes(c))return v(`INVALID_ARGS`,`record requires start|stop`);let l=qr(t);if(typeof l==`object`)return l;if(c===`start`&&!o&&!s(l))return v(`INVALID_ARGS`,ce(t)?`record start with app scope and an explicit session requires an active app session; run open <app> first, or use --scope device to record the full screen`:`record start defaults to app scope and requires an active app session; run open <app> first, or use --scope device to record the full screen`);let u=o?.device??await ue(t.flags??{});o||await he(u);let d=o??{name:n,sessionScope:de(t),device:u,createdAt:Date.now(),recordOnlySession:!0,actions:[]};if(c===`start`)return Er({req:t,sessionName:n,sessionStore:r,activeSession:d,device:u,recordingScope:l,logPath:i,deps:a});let f=await Ir({req:t,sessionName:n,sessionStore:r,activeSession:d,device:u,logPath:i,deps:a});return f.ok?(_e(r,d,t,t.command,{action:`stop`,outPath:f.data?.outPath,showTouches:f.data?.showTouches}),await Gr(r,n,d,{writeLog:!0}),f):(await Gr(r,n,d),f)}function qr(e){let t=e.flags?.recordingScope;return t===void 0?`app`:Jr(t)?t:v(`INVALID_ARGS`,`record scope must be one of: ${o.join(`, `)}`)}function Jr(e){return typeof e==`string`&&o.includes(e)}export{Kr as t};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./rolldown-runtime.js";import{y as t}from"./sdk-android-adb.js";import{t as n}from"./scoped-provider.js";import{n as r}from"./simctl.js";var i=e({createLocalRecordingProvider:()=>s,resolveRecordingProvider:()=>c,withRecordingProvider:()=>l});const a={startIosSimulatorRecording({device:e,outPath:n}){return t(`xcrun`,r(e,[`io`,e.id,`recordVideo`,n]),{allowFailure:!0})}},o=n(a,s);function s(e={}){return{...a,...e}}function c(e){return o.resolve(e)}async function l(e,t){return await o.run(e,t)}export{c as n,i as t};
|
package/dist/src/selectors2.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{C as e,N as t,R as n,c as r,d as i,s as a}from"./sdk-selectors.js";import{i as o}from"./sdk-finders.js";function s(e,t,n){return t.terms.every(t=>c(e,t,n))}function c(e,n,o){switch(n.key){case`id`:return l(e.identifier,String(n.value));case`role`:return l(t(e.type??``),String(n.value));case`label`:return l(e.label,String(n.value));case`value`:return l(e.value,String(n.value));case`text`:return l(i(e),String(n.value));case`appname`:return l(e.appName,String(n.value));case`windowtitle`:return l(e.windowTitle,String(n.value));case`visible`:return r(e)===!!n.value;case`hidden`:return!r(e)==!!n.value;case`editable`:return a(e,o)===!!n.value;case`selected`:return e.selected===!0==!!n.value;case`focused`:return e.focused===!0==!!n.value;case`enabled`:return e.enabled!==!1==!!n.value;case`hittable`:return e.hittable===!0==!!n.value;default:return!1}}function l(e,t){return o(e??``)===o(t)}function u(e,t,n){let r=n.requireRect??!1,i=n.requireUnique??!0,a=[];for(let[o,s]of t.selectors.entries()){let t=h(e,s,n.platform,r);if(a.push({selector:s.raw,matches:t.count}),!(t.count===0||!t.firstNode)){if(i&&t.count!==1){if(!n.disambiguateAmbiguous||!t.disambiguated)continue;return{node:t.disambiguated,selector:s,selectorIndex:o,matches:t.count,diagnostics:a}}return{node:t.firstNode,selector:s,selectorIndex:o,matches:t.count,diagnostics:a}}}return null}function d(e,t,n){let r=n.requireRect??!1,i=[];for(let[a,o]of t.selectors.entries()){let t=_(e,o,n.platform,r);if(i.push({selector:o.raw,matches:t}),t>0)return{selectorIndex:a,selector:o,matches:t,diagnostics:i}}return null}const f=`Snapshot refs expire when the UI changes. Run snapshot -i and retry with a fresh @ref.`;function p(e){return e.some(e=>e.matches>1)?`Add more terms to disambiguate (e.g. role=button text="Sign in"), use an @ref from snapshot -i, or use find <text> --first/--last.`:`Selector text/label values match exactly (quote multi-word values: text="Sign in"). Run snapshot -i to see current elements and refs, or use find <text> for contains matching.`}function m(e,t,n){if(t.length===0)return`Selector did not match: ${e.raw}`;let r=t.map(e=>`${e.selector} -> ${e.matches}`).join(`, `);return n.unique??!0?`Selector did not resolve uniquely (${r})`:`Selector did not match (${r})`}function h(t,r,i,a){let o=0,c=null,l={best:null,bestVisible:!1,tie:!1},u,d=r=>(u??=n(t),e(r,t,u));for(let e of t)a&&!e.rect||s(e,r,i)&&(o+=1,c??=e,g(l,e,d));return{count:o,firstNode:c,disambiguated:l.tie?null:l.best}}function g(e,t,n){if(!e.best){e.best=t;return}e.bestVisible||=n(e.best);let r=n(t);if(r!==e.bestVisible){r&&(e.best=t,e.bestVisible=!0,e.tie=!1);return}let i=v(t,e.best);i>0?(e.best=t,e.tie=!1):i===0&&(e.tie=!0)}function _(e,t,n,r){let i=0;for(let a of e)r&&!a.rect||s(a,t,n)&&(i+=1);return i}function v(e,t){let n=e.depth??0,r=t.depth??0;if(n!==r)return n>r?1:-1;let i=y(e),a=y(t);return i===a?0:i<a?1:-1}function y(e){return e.rect?e.rect.width*e.rect.height:1/0}function b(e,n,a={}){let o=[],s=t(e.type??``),c=C(e.identifier),l=C(e.label),u=C(e.value),d=C(i(e)),f=a.action===`fill`;c&&o.push(`id=${S(c)}`),s&&l&&o.push(f?`role=${S(s)} label=${S(l)} editable=true`:`role=${S(s)} label=${S(l)}`),l&&o.push(f?`label=${S(l)} editable=true`:`label=${S(l)}`),u&&o.push(f?`value=${S(u)} editable=true`:`value=${S(u)}`),d&&d!==l&&d!==u&&o.push(f?`text=${S(d)} editable=true`:`text=${S(d)}`),s&&f&&!o.some(e=>e.includes(`editable=true`))&&o.push(`role=${S(s)} editable=true`);let p=x(o);return p.length===0&&s&&p.push(f?`role=${S(s)} editable=true`:`role=${S(s)}`),p.length===0&&r(e)&&p.push(`visible=true`),p}function x(e){return Array.from(new Set(e))}function S(e){return JSON.stringify(e)}function C(e){return e&&e.trim()||null}export{u as a,m as i,f as n,p as o,d as r,s,b as t};
|
package/dist/src/simctl.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{p as e}from"./sdk-contracts.js";import{x as t}from"./android-input-ownership.js";import{o as n}from"./tool-provider.js";function r(e,n={}){let r=t(n.simulatorSetPath);return r?[`simctl`,`--set`,r,...e]:[`simctl`,...e]}function i(t,n){return!e(t)||t.kind!==`simulator`?[`simctl`,...n]:r(n,{simulatorSetPath:t.simulatorSetPath})}function a(e,t,r){return n(i(e,t),r)}export{i as n,a as r,r as t};
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import{F as e}from"./sdk-contracts.js";import{j as t,n,o as r,p as i}from"./sdk-android-adb.js";import{z as a}from"./tv-remote.js";import{E as o}from"./sdk-selectors.js";import s from"node:crypto";import c from"node:fs";import"node:os";import"node:path";import"node:fs/promises";import l from"node:net";function u(e){if(!e)return;let t=/\[(-?\d+),(-?\d+)\]\[(-?\d+),(-?\d+)\]/.exec(e);if(!t)return;let n=Number(t[1]),r=Number(t[2]),i=Number(t[3]),a=Number(t[4]);return{x:n,y:r,width:Math.max(0,i-n),height:Math.max(0,a-r)}}function*d(e){let t=/<node\b[^>]*>/g,n=t.exec(e);for(;n;)yield f(n[0]),n=t.exec(e)}function f(e){let t=ie(e),n=u(t.bounds);return{...t,...n?{rect:n}:{}}}function ee(e,t,n){let{sourceNodes:r,...i}=te(g(e),t,n);return i}function te(e,t,n){let r={nodes:[],sourceNodes:[],...t===void 0?{}:{maxNodes:t},maxDepth:n.depth??1/0,options:n,analysis:Ie(e),interactiveDescendantMemo:new Map,truncated:!1},i=n.scope?Fe(e,n.scope):null,a=i?[i]:e.children;for(let e of a)if(ne(r,e,0),r.truncated)break;let o={nodes:r.nodes,sourceNodes:r.sourceNodes,analysis:r.analysis};return r.truncated?{...o,truncated:!0}:o}function ne(e,t,n,r,i=!1,a=!1){if(e.maxNodes!==void 0&&e.nodes.length>=e.maxNodes){e.truncated=!0;return}if(n>e.maxDepth)return;let o=e.options.raw||De(t,e.options,i,p(e,t),a)?re(e,t,n,r):r,s=i||!!t.hittable,c=a||Ne(t.type);for(let r of t.children)if(ne(e,r,n+1,o,s,c),e.truncated)return}function re(e,t,n,r){let i=e.nodes.length;return e.sourceNodes.push(t),e.nodes.push({index:i,type:t.type??void 0,label:t.label??void 0,value:t.value??void 0,identifier:t.identifier??void 0,bundleId:t.packageName??void 0,rect:t.rect,enabled:t.enabled,focused:t.focused,visibleToUser:t.visibleToUser,hittable:t.hittable,depth:n,parentIndex:r,...t.hiddenContentAbove?{hiddenContentAbove:!0}:{},...t.hiddenContentBelow?{hiddenContentBelow:!0}:{}}),i}function p(e,t){let n=e.interactiveDescendantMemo.get(t);if(n!==void 0)return n;for(let n of t.children)if(n.visibleToUser!==!1&&(n.hittable||p(e,n)))return e.interactiveDescendantMemo.set(t,!0),!0;return e.interactiveDescendantMemo.set(t,!1),!1}function ie(e){let t=ae(e),n=e=>he(t,e),r=e=>{let t=n(e);if(t!==null)return t===`true`},i=e=>{let t=n(e);if(t===null||t.trim()===``)return;let r=Number(t);return Number.isFinite(r)?r:void 0},a=(e,t)=>{let n=i(t);return n===void 0?{}:{[e]:n}},o=(e,t)=>{let r=u(n(t));return r===void 0?{}:{[e]:r}},s=(e,t)=>{let n=r(t);return n===void 0?{}:{[e]:n}};return{text:n(`text`),desc:n(`content-desc`),resourceId:n(`resource-id`),packageName:n(`package`),className:n(`class`),bounds:n(`bounds`),clickable:r(`clickable`),enabled:r(`enabled`),focusable:r(`focusable`),focused:r(`focused`),password:r(`password`),...s(`visibleToUser`,`visible-to-user`),...a(`drawingOrder`,`drawing-order`),...s(`scrollable`,`scrollable`),...s(`canScrollForward`,`can-scroll-forward`),...s(`canScrollBackward`,`can-scroll-backward`),...a(`windowIndex`,`window-index`),...a(`windowType`,`window-type`),...a(`windowLayer`,`window-layer`),...s(`windowActive`,`window-active`),...s(`windowFocused`,`window-focused`),...o(`windowRect`,`window-bounds`)}}function ae(e){let t=new Map,n=e.indexOf(` `),r=e.lastIndexOf(`>`);if(n<0||r<=n)return t;let i=n;for(;i<r;){let n=oe(e,i,r);if(!n)break;t.set(n.name,n.value),i=n.nextCursor}return t}function oe(e,t,n){if(t=m(e,t,n),t>=n||ce(e[t]))return;let r=t;t=se(e,t,n);let i=e.slice(r,t);if(t=m(e,t,n),!i||e[t]!==`=`)return;t=m(e,t+1,n);let a=e[t];if(!le(a))return;let o=t+1,s=e.indexOf(a,o);if(!(s<0||s>=n))return{name:i,value:de(e.slice(o,s)),nextCursor:s+1}}function se(e,t,n){for(;t<n&&!ue(e[t]??``);)t+=1;return t}function m(e,t,n){for(;t<n&&h(e[t]??``);)t+=1;return t}function ce(e){return e===`/`||e===`>`}function le(e){return e===`"`||e===`'`}function h(e){return e===` `||e===`
|
|
2
|
-
`||e===`\r`||e===` `}function ue(e){return e===`=`||e===`/`||e===`>`||h(e)}function de(e){let t=``,n=0;for(;n<e.length;){let r=e.indexOf(`&`,n);if(r<0){t+=e.slice(n);break}t+=e.slice(n,r);let i=e.indexOf(`;`,r+1);if(i<0){t+=e.slice(r);break}let a=e.slice(r+1,i);t+=fe(a)??e.slice(r,i+1),n=i+1}return t}function fe(e){switch(e){case`amp`:return`&`;case`lt`:return`<`;case`gt`:return`>`;case`quot`:return`"`;case`apos`:return`'`;default:return pe(e)}}function pe(e){if(!e.startsWith(`#`))return;let t=e[1]?.toLowerCase()===`x`?16:10,n=t===16?e.slice(2):e.slice(1);if(!n||!me(n,t))return;let r=Number.parseInt(n,t);if(Number.isFinite(r))try{return String.fromCodePoint(r)}catch{return}}function me(e,t){for(let n of e){let e=n.charCodeAt(0),r=e>=48&&e<=57;if(t===10){if(!r)return!1;continue}if(!r&&!(e>=65&&e<=70)&&!(e>=97&&e<=102))return!1}return!0}function he(e,t){return e.get(t)??null}function g(e){let t={type:null,label:null,value:null,identifier:null,packageName:null,depth:-1,children:[]},n=[t],r=/<node\b[^>]*>|<\/node>/g,i=r.exec(e);for(;i;){let t=i[0];if(t.startsWith(`</node`)){n.length>1&&n.pop(),i=r.exec(e);continue}let a=f(t),o=n[n.length-1],s={type:a.className,label:a.text||a.desc,value:a.text,identifier:a.resourceId,packageName:a.packageName,rect:a.rect,enabled:a.enabled,focused:a.focused,visibleToUser:a.visibleToUser,drawingOrder:a.drawingOrder,hittable:a.clickable??a.focusable,scrollable:a.scrollable,canScrollForward:a.canScrollForward,canScrollBackward:a.canScrollBackward,windowIndex:a.windowIndex,windowType:a.windowType,windowLayer:a.windowLayer,windowActive:a.windowActive,windowFocused:a.windowFocused,windowRect:a.windowRect,depth:o.depth+1,parentIndex:void 0,children:[]};o.children.push(s),t.endsWith(`/>`)||n.push(s),i=r.exec(e)}return _(t),Se(t),v(t,{actionableContentMemo:new WeakMap}),xe(t),t}function _(e){let t=0;for(let n of e.children)n.visibleToUser!==!1&&(_(n),e.children[t]=n,t+=1);t<e.children.length&&(e.children.length=t)}function v(e,t){for(let n of e.children)v(n,t);if(e.children.length<2)return;let n=e.children,r=n.filter(e=>_e(e,t));r.length!==0&&(e.children=n.filter(e=>!ge(e,r)))}function ge(e,t){if(e.visibleToUser===!1||e.drawingOrder===void 0||!ye(e))return!1;for(let n of t)if(!(n===e||n.drawingOrder<=e.drawingOrder)&&be(n.rect,e.rect)>=.9)return!0;return!1}function _e(e,t){return e.visibleToUser!==!1&&e.drawingOrder!==void 0&&ye(e)&&(ve(e)||y(e,t))}function ve(e){if(e.visibleToUser===!1)return!1;if(e.hittable)return!0;let t=e.label?.trim()??``;if(t&&!C(t))return!0;let n=e.identifier?.trim()??``;return!!(n&&!C(n))}function y(e,t){let n=t.actionableContentMemo.get(e);if(n!==void 0)return n;let r=e.children.some(e=>e.visibleToUser!==!1&&(!!e.hittable||y(e,t)));return t.actionableContentMemo.set(e,r),r}function ye(e){return!!(e.rect&&e.rect.width>0&&e.rect.height>0)}function be(e,t){let n=t.width*t.height;return n<=0?0:a(e,t)/n}function xe(e){let t=[...e.children];for(;t.length>0;){let e=t.pop();t.push(...e.children),Te(e)&&(e.canScrollBackward&&(e.hiddenContentAbove=!0),e.canScrollForward&&(e.hiddenContentBelow=!0))}}function Se(e){let t=e.children.filter(we);if(t.length<2)return;let n=t.filter(e=>b(e)&&x(e));if(n.length===0)return;let r=Ce(n);e.children=e.children.filter(e=>b(e)?x(e)?r===void 0||e.windowLayer===r:!1:!0)}function Ce(e){let t=e.map(e=>e.windowLayer).filter(e=>e!==void 0);return t.length>0?Math.max(...t):void 0}function we(e){return e.windowIndex!==void 0||e.windowType!==void 0}function b(e){return e.windowType===1}function x(e){return e.windowActive===!0||e.windowFocused===!0}function Te(e){if(!e.scrollable||!o(e.type)||`${e.type??``}`.toLowerCase().includes(`horizontalscrollview`))return!1;let t=Ee(e);return!(t&&t.horizontal>t.vertical&&t.horizontal>16)}function Ee(e){if(!e.rect||e.children.length===0)return null;let t=e.children.map(e=>e.rect).filter(e=>e!==void 0);if(t.length===0)return null;let n=Math.min(...t.map(e=>e.x)),r=Math.max(...t.map(e=>e.x+e.width)),i=Math.min(...t.map(e=>e.y)),a=Math.max(...t.map(e=>e.y+e.height));return{horizontal:Math.max(0,r-n-e.rect.width),vertical:Math.max(0,a-i-e.rect.height)}}function De(e,t,n,r,i){if(e.visibleToUser===!1)return!1;let a=Oe(e);return t.interactiveOnly?ke(e,a,n,r,i):a.isStructural||a.isVisual?Me(e,a,r):!0}function Oe(e){let t=S(e.type),n=!!(e.label&&e.label.trim().length>0),r=!!(e.identifier&&e.identifier.trim().length>0);return{type:t,hasMeaningfulText:n&&!C(e.label??``),hasMeaningfulId:r&&!C(e.identifier??``),isStructural:Pe(t),isVisual:t===`imageview`||t===`imagebutton`}}function ke(e,t,n,r,i){return je(e)?!1:e.focused||e.hittable||o(t.type)&&r?!0:Ae(t,n,r,i)}function Ae(e,t,n,r){return!e.hasMeaningfulText&&!e.hasMeaningfulId||e.isVisual||e.isStructural&&!r?!1:t||n||r}function je(e){return!!(e.rect&&(e.rect.width<=0||e.rect.height<=0))}function Me(e,t,n){return e.hittable||t.hasMeaningfulText||t.hasMeaningfulId?!0:n}function Ne(e){if(!e)return!1;let t=S(e);return t.includes(`recyclerview`)||t.includes(`listview`)||t.includes(`gridview`)}function S(e){return e?e.toLowerCase():``}function Pe(e){let t=e.split(`.`).pop()??e;return t.includes(`layout`)||t===`viewgroup`||t===`view`}function C(e){let t=e.trim();return t?/^[\w.]+:id\/[\w.-]+$/i.test(t):!1}function Fe(e,t){let n=t.toLowerCase(),r=[...e.children],i=0;for(;i<r.length;){let e=r[i++],t=e.label?.toLowerCase()??``,a=e.value?.toLowerCase()??``,o=e.identifier?.toLowerCase()??``;if(t.includes(n)||a.includes(n)||o.includes(n))return e;r.push(...e.children)}return null}function Ie(e){let t=0,n=0,r=[...e.children];for(;r.length>0;){let e=r.pop();t+=1,n=Math.max(n,e.depth),r.push(...e.children)}return{rawNodeCount:t,maxDepth:n}}function w(e){let t={status:[],results:[],currentStatus:null,currentResult:null};for(let n of e.split(/\r?\n/))Le(n,t);return Re(t),{status:t.status,results:t.results}}function Le(e,t){if(e.startsWith(`INSTRUMENTATION_STATUS: `)){t.currentStatus??={},E(e.slice(24),t.currentStatus);return}if(e.startsWith(`INSTRUMENTATION_STATUS_CODE: `)){ze(t);return}if(e.startsWith(`INSTRUMENTATION_RESULT: `)){t.currentResult??={},E(e.slice(24),t.currentResult);return}e.startsWith(`INSTRUMENTATION_CODE: `)&&T(t)}function Re(e){ze(e),T(e)}function ze(e){e.currentStatus&&=(e.status.push(e.currentStatus),null)}function T(e){e.currentResult&&=(e.results.push(e.currentResult),null)}function E(e,t){let n=e.indexOf(`=`);n<0||(t[e.slice(0,n)]=e.slice(n+1))}function D(e){if(e===void 0)return;let t=Number(e);return Number.isFinite(t)?t:void 0}function O(e){if(e===`true`)return!0;if(e===`false`)return!1}function k(t,n,r){if(typeof t!=`number`||!Number.isInteger(t))throw new e(`INVALID_ARGS`,`Android ${r} manifest ${n} must be an integer.`);return t}function A(t,n,r,i){if(t!==r)throw new e(`INVALID_ARGS`,`Android ${i} manifest ${n} must be "${r}".`);return r}const j=`android-snapshot-helper-v1`,M=`uiautomator-xml`,N={"-r":`replace`,"-t":`allowTestPackages`,"-d":`allowDowngrade`,"-g":`grantPermissions`};async function Be(t){let n=await Ge(t.apkPath);if(n!==t.manifest.sha256)throw new e(`COMMAND_FAILED`,`Android snapshot helper APK checksum mismatch`,{apkPath:t.apkPath,expectedSha256:t.manifest.sha256,actualSha256:n})}function Ve(t){if(!t||typeof t!=`object`||Array.isArray(t))throw new e(`INVALID_ARGS`,`Android snapshot helper manifest must be an object.`);let n=t;return{name:F(n.name,`name`,`android-snapshot-helper`),version:L(n.version,`version`),releaseTag:R(n.releaseTag),assetName:R(n.assetName),apkUrl:Ke(n.apkUrl,`apkUrl`),sha256:We(n.sha256),checksumName:R(n.checksumName),packageName:L(n.packageName,`packageName`),versionCode:P(n.versionCode,`versionCode`),instrumentationRunner:L(n.instrumentationRunner,`instrumentationRunner`),minSdk:P(n.minSdk,`minSdk`),targetSdk:n.targetSdk===void 0?void 0:P(n.targetSdk,`targetSdk`),outputFormat:F(n.outputFormat,`outputFormat`,M),statusProtocol:F(n.statusProtocol,`statusProtocol`,j),installArgs:I(n.installArgs)}}function P(e,t){return k(e,t,`snapshot helper`)}function F(e,t,n){return A(e,t,n,`snapshot helper`)}function He(e){return Ue(I(e.installArgs))}function I(t){let n=qe(t,`installArgs`);if(n[0]!==`install`)throw new e(`INVALID_ARGS`,`Android snapshot helper manifest installArgs must start with "install".`);if(n.some(e=>e.includes(`\0`)))throw new e(`INVALID_ARGS`,`Android snapshot helper manifest installArgs must not contain null bytes.`);let r=n.slice(1).find(e=>!Je(e));if(r)throw new e(`INVALID_ARGS`,`Android snapshot helper manifest installArgs contains unsupported install flag "${r}".`);return n}function Ue(t){let n={};for(let r of t.slice(1)){let t=z(r);if(!t)throw new e(`INVALID_ARGS`,`Android snapshot helper manifest installArgs contains unsupported install flag "${r}".`);n[t]=!0}return n}function We(t){let n=L(t,`sha256`).trim().toLowerCase();if(n.length!==64||!Ye(n))throw new e(`INVALID_ARGS`,`Android snapshot helper manifest sha256 must be a 64-character hex string.`);return n}async function Ge(e){return await new Promise((t,n)=>{let r=s.createHash(`sha256`),i=c.createReadStream(e);i.on(`error`,n),i.on(`data`,e=>r.update(e)),i.on(`end`,()=>t(r.digest(`hex`)))})}function L(t,n){if(typeof t!=`string`||t.trim().length===0)throw new e(`INVALID_ARGS`,`Android snapshot helper manifest ${n} is required.`);return t}function R(e){return typeof e==`string`&&e.trim().length>0?e:void 0}function Ke(e,t){return e===null?null:L(e,t)}function qe(t,n){if(!Array.isArray(t)||!t.every(e=>typeof e==`string`))throw new e(`INVALID_ARGS`,`Android snapshot helper manifest ${n} must be a string array.`);return t}function Je(e){return z(e)!==void 0}function z(e){if(Object.hasOwn(N,e))return N[e]}function Ye(e){for(let t of e){let e=t.charCodeAt(0);if(!(e>=48&&e<=57)&&!(e>=97&&e<=102))return!1}return!0}async function Xe(t){let n=B(t),r=await t.adb(H(n),{allowFailure:!0,timeoutMs:n.commandTimeoutMs}),{output:a,cleanupDone:o}=await Ze(t,n,r);if(n.outputPath&&!o&&await it(t.adb,n.outputPath),r.exitCode!==0)throw new e(`COMMAND_FAILED`,`Android snapshot helper failed`,i(r,{helper:a.metadata}));return a}function B(e){let t=V(e.timeoutMs,8e3),n=V(e.packageName,`com.callstack.agentdevice.snapshothelper`);return{waitForIdleTimeoutMs:V(e.waitForIdleTimeoutMs,500),waitForIdleQuietMs:V(e.waitForIdleQuietMs,100),timeoutMs:t,commandTimeoutMs:V(e.commandTimeoutMs,t+5e3),maxDepth:V(e.maxDepth,128),maxNodes:V(e.maxNodes,5e3),packageName:n,runner:V(e.instrumentationRunner,`${n}/.SnapshotInstrumentation`),...e.outputPath?{outputPath:e.outputPath}:{},...e.emitChunks===void 0?{}:{emitChunks:e.emitChunks}}}function V(e,t){return e===void 0?t:e}function H(e){return[`shell`,`am`,`instrument`,`-w`,`-e`,`waitForIdleTimeoutMs`,String(e.waitForIdleTimeoutMs),`-e`,`waitForIdleQuietMs`,String(e.waitForIdleQuietMs),`-e`,`timeoutMs`,String(e.timeoutMs),`-e`,`maxDepth`,String(e.maxDepth),`-e`,`maxNodes`,String(e.maxNodes),...e.outputPath?[`-e`,`outputPath`,e.outputPath]:[],...e.emitChunks===void 0?[]:[`-e`,`emitChunks`,String(e.emitChunks)],e.runner]}async function Ze(e,t,n){try{return{output:at(`${n.stdout}\n${n.stderr}`),cleanupDone:!1}}catch(r){return await Qe(e,t,n,r)}}async function Qe(t,n,r,i){if(i instanceof e&&r.exitCode!==0&&i.details?.helper)throw i;let a=await $e(t,n,r);if(a)return{output:a,cleanupDone:!0};throw new e(`COMMAND_FAILED`,r.exitCode===0?`Android snapshot helper output could not be parsed`:`Android snapshot helper failed before returning parseable output`,{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode},i)}async function $e(e,t,n){if(!(n.exitCode!==0||!t.outputPath))return await tt(e.adb,t.outputPath,rt(`${n.stdout}\n${n.stderr}`)??et(t))}function et(e){return{outputFormat:M,waitForIdleTimeoutMs:e.waitForIdleTimeoutMs,waitForIdleQuietMs:e.waitForIdleQuietMs,timeoutMs:e.timeoutMs,maxDepth:e.maxDepth,maxNodes:e.maxNodes,transport:`instrumentation`}}async function tt(e,t,n){let r;try{r=await e(nt(t),{allowFailure:!0,timeoutMs:5e3})}catch{return}if(r.exitCode!==0)return;let i=r.stdout.trim();if(!(!i.includes(`<hierarchy`)||!i.includes(`</hierarchy>`)))return{xml:i,metadata:n}}function nt(e){return[`shell`,`sh`,`-c`,`cat "$1"; status=$?; rm -f "$1"; exit "$status"`,`agent-device-snapshot-helper-output`,e]}function rt(e){try{return W(U(w(e).results))}catch{return null}}async function it(e,t){try{await e([`shell`,`rm`,`-f`,t],{allowFailure:!0,timeoutMs:5e3})}catch{}}function at(e){let t=w(e),n=U(t.results);return{xml:ct(ot(t.status),n),metadata:{...W(n),transport:`instrumentation`}}}function ot(e){let t=[];for(let n of e){if(n.agentDeviceProtocol!==`android-snapshot-helper-v1`||n.outputFormat!==`uiautomator-xml`)continue;let{payloadBase64:e}=n;e!==void 0&&t.push({index:G(n.chunkIndex),count:G(n.chunkCount),payloadBase64:e})}return t}function U(t){let n=t.find(e=>e.agentDeviceProtocol===j);if(!n)throw new e(`COMMAND_FAILED`,`Android snapshot helper did not return a final result`);if(n.ok!==`true`)throw new e(`COMMAND_FAILED`,st(n),{errorType:n.errorType,helper:n});return n}function st(e){return e.message&&e.message!==`null`?e.message:e.errorType||`Android snapshot helper returned an error`}function ct(t,n){if(t.length===0)throw new e(`COMMAND_FAILED`,`Android snapshot helper did not return XML chunks`,{helper:n});let r=lt(t),i=Buffer.concat(dt(ut(t,r),r)).toString(`utf8`);if(!i.includes(`<hierarchy`)||!i.includes(`</hierarchy>`))throw new e(`COMMAND_FAILED`,`Android snapshot helper output did not contain XML`,{xml:i});return i}function lt(t){let n=t[0]?.count??t.length;if(n<1||t.length!==n||t.some(e=>e.count!==n))throw new e(`COMMAND_FAILED`,`Android snapshot helper returned incomplete XML chunks`,{expectedChunks:n,actualChunks:t.length});return n}function ut(t,n){let r=new Map;for(let i of t){if(i.index===void 0||i.index<0||i.index>=n)throw new e(`COMMAND_FAILED`,`Android snapshot helper returned invalid chunk index`,{chunkIndex:i.index,expectedChunks:n});if(r.has(i.index))throw new e(`COMMAND_FAILED`,`Android snapshot helper returned duplicate XML chunks`,{chunkIndex:i.index});r.set(i.index,i.payloadBase64)}return r}function dt(t,n){let r=[];for(let i=0;i<n;i+=1){let a=t.get(i);if(a===void 0)throw new e(`COMMAND_FAILED`,`Android snapshot helper returned incomplete XML chunks`,{missingChunkIndex:i,expectedChunks:n});r.push(Buffer.from(a,`base64`))}return r}function W(e){return{helperApiVersion:e.helperApiVersion,outputFormat:M,waitForIdleTimeoutMs:G(e.waitForIdleTimeoutMs),waitForIdleQuietMs:G(e.waitForIdleQuietMs),timeoutMs:G(e.timeoutMs),maxDepth:G(e.maxDepth),maxNodes:G(e.maxNodes),rootPresent:K(e.rootPresent),captureMode:ft(e.captureMode),windowCount:G(e.windowCount),nodeCount:G(e.nodeCount),truncated:K(e.truncated),elapsedMs:G(e.elapsedMs)}}function ft(e){return e===`interactive-windows`||e===`active-window`?e:void 0}const G=D,K=O,q=2e3,J=5e3,Y=new Map,X=new Map;async function pt(e){if(!jt()||!e.adbProvider?.spawn)return;let n=B(e),r=e.deviceKey??`android:default`,i=At(r,n,e);if(X.get(r)===i)return;let a=Y.get(r);if(a&&a.identity!==i&&(await Z(r),a=void 0),!a)try{a=await _t({deviceKey:r,identity:i,options:e,resolved:n})}catch(e){X.set(r,i),t({level:`warn`,phase:`android_snapshot_helper_session_disabled`,data:{deviceKey:r,reason:e instanceof Error?e.message:String(e)}});return}try{let e=a.capturedCount>0,t=await bt(a,n);return a.capturedCount+=1,{xml:t.xml,metadata:{...t.metadata,transport:`persistent-session`,sessionReused:e}}}catch(e){throw await Z(r),e}}async function Z(e){let n=Y.get(e);if(n){Y.delete(e);try{await xt(n,`quit ${Date.now()}`,1e3)}catch{}try{await n.process.kill(`SIGTERM`)}catch{}await vt(n.process,q);try{await Ot(n)}catch{}t({phase:`android_snapshot_helper_session_stop`,data:{deviceKey:e,port:n.port,capturedCount:n.capturedCount,lifetimeMs:Date.now()-n.startedAtMs}})}}async function mt(e){await Z(ht(e))}function ht(e){return`${e.platform}:${e.id}`}function gt(e){return Math.min(e.commandTimeoutMs,Math.max(e.timeoutMs+1e4,3e3))}async function _t(n){let r=await Mt();await n.options.adb([`forward`,`tcp:${r}`,`tcp:${r}`],{allowFailure:!1,timeoutMs:J});let i=H({...n.resolved,outputPath:void 0,emitChunks:!1}),a=i[i.length-1];if(!a)throw new e(`INVALID_ARGS`,`Android snapshot helper runner was not resolved`);let o=[...i.slice(0,-1),`-e`,`sessionPort`,String(r),a],s=n.options.adbProvider.spawn(o,{allowFailure:!0,captureOutput:!1}),c={identity:n.identity,deviceKey:n.deviceKey,port:r,adb:n.options.adb,process:s,startedAtMs:Date.now(),capturedCount:0};try{return await yt(s,1e4),Y.set(n.deviceKey,c),t({phase:`android_snapshot_helper_session_ready`,data:{deviceKey:n.deviceKey,port:r,packageName:n.resolved.packageName,runner:n.resolved.runner}}),c}catch(e){await Ot(c);try{s.kill(`SIGTERM`)}catch{}throw await vt(s,q),e}}function vt(e,t){return new Promise(n=>{let r=setTimeout(n,t);e.once(`close`,()=>{clearTimeout(r),n()}),e.once(`exit`,()=>{clearTimeout(r),n()})})}function yt(t,n){return new Promise((r,i)=>{let a=``,o=setTimeout(()=>{i(new e(`COMMAND_FAILED`,`Android snapshot helper session did not become ready`,{output:a,timeoutMs:n}))},n),s=e=>{a+=e.toString(),a.includes(`agentDeviceProtocol=android-snapshot-helper-v1`)&&a.includes(`sessionReady=true`)&&(clearTimeout(o),r())};t.stdout?.on(`data`,s),t.stderr?.on(`data`,s),t.once(`exit`,(t,n)=>{clearTimeout(o),i(new e(`COMMAND_FAILED`,`Android snapshot helper session exited before ready`,{output:a,exitCode:t,signal:n}))}),t.on(`error`,e=>{clearTimeout(o),i(e)})})}async function bt(e,t){let n=`snapshot-${Date.now()}-${Math.random().toString(16).slice(2)}`,r=gt(t);return St(await xt(e,`snapshot ${n}`,r),n)}function xt(t,n,r){return new Promise((i,a)=>{let o=l.connect({host:`127.0.0.1`,port:t.port}),s=[],c=setTimeout(()=>{o.destroy(),a(new e(`COMMAND_FAILED`,`Android snapshot helper session request timed out`,{command:n,timeoutMs:r,port:t.port}))},r);o.on(`connect`,()=>{o.write(`${n}\n`)}),o.on(`data`,e=>{s.push(Buffer.from(e))}),o.on(`error`,e=>{clearTimeout(c),a(e)}),o.on(`close`,()=>{clearTimeout(c),i(Buffer.concat(s).toString(`utf8`))})})}function St(e,t){let{headers:n,xml:r}=Ct(e);return wt(n,t),Tt(n,r),{xml:r,metadata:Dt(n)}}function Ct(t){let n=t.indexOf(`
|
|
3
|
-
|
|
4
|
-
`);if(n<0)throw new e(`COMMAND_FAILED`,`Android snapshot helper session returned malformed output`,{response:t});return{headers:Et(t.slice(0,n)),xml:t.slice(n+2)}}function wt(t,n){if(t.agentDeviceProtocol!==`android-snapshot-helper-v1`)throw new e(`COMMAND_FAILED`,`Android snapshot helper session returned wrong protocol`,{headers:t});if(t.outputFormat!==`uiautomator-xml`)throw new e(`COMMAND_FAILED`,`Android snapshot helper session returned wrong output format`,{headers:t});if(t.requestId!==n)throw new e(`COMMAND_FAILED`,`Android snapshot helper session returned stale output`,{headers:t,requestId:n});if(t.ok!==`true`)throw new e(`COMMAND_FAILED`,t.message||t.errorType||`Android snapshot helper session returned an error`,{helper:t})}function Tt(t,n){let r=D(t.byteLength);if(r!==void 0&&Buffer.byteLength(n,`utf8`)!==r)throw new e(`COMMAND_FAILED`,`Android snapshot helper session returned truncated XML`,{headers:t,actualByteLength:Buffer.byteLength(n,`utf8`)});if(!n.includes(`<hierarchy`)||!n.includes(`</hierarchy>`))throw new e(`COMMAND_FAILED`,`Android snapshot helper session did not return XML`,{headers:t,xml:n})}function Et(e){let t={};for(let n of e.split(/\r?\n/)){let e=n.indexOf(`=`);e<0||(t[n.slice(0,e)]=n.slice(e+1))}return t}function Dt(e){return{helperApiVersion:e.helperApiVersion,outputFormat:M,waitForIdleTimeoutMs:D(e.waitForIdleTimeoutMs),waitForIdleQuietMs:D(e.waitForIdleQuietMs),timeoutMs:D(e.timeoutMs),maxDepth:D(e.maxDepth),maxNodes:D(e.maxNodes),rootPresent:O(e.rootPresent),captureMode:e.captureMode===`interactive-windows`||e.captureMode===`active-window`?e.captureMode:void 0,windowCount:D(e.windowCount),nodeCount:D(e.nodeCount),truncated:O(e.truncated),elapsedMs:D(e.elapsedMs)}}async function Ot(e){await e.process.stdin?.end(),await e.process.stdout?.destroy(),await e.process.stderr?.destroy(),await kt(e)}async function kt(e){await e.adb([`forward`,`--remove`,`tcp:${e.port}`],{allowFailure:!0,timeoutMs:J})}function At(e,t,n){return JSON.stringify({deviceKey:e,packageName:t.packageName,runner:t.runner,helperVersion:n.helperVersion,helperVersionCode:n.helperVersionCode,waitForIdleTimeoutMs:t.waitForIdleTimeoutMs,waitForIdleQuietMs:t.waitForIdleQuietMs,timeoutMs:t.timeoutMs,maxDepth:t.maxDepth,maxNodes:t.maxNodes})}function jt(){let e=process.env.AGENT_DEVICE_ANDROID_SNAPSHOT_HELPER_SESSION;return e===void 0||!/^(0|false|no|off)$/i.test(e)}function Mt(){return new Promise((e,t)=>{let n=l.createServer();n.unref(),n.on(`error`,t),n.listen(0,`127.0.0.1`,()=>{let r=n.address();if(!r||typeof r==`string`){n.close(()=>t(Error(`Failed to allocate a local TCP port`)));return}let i=r.port;n.close(()=>e(i))})})}const Q=new Map;function Nt(e){$(Pt(e.deviceKey,e.packageName,e.versionCode))}function Pt(e,t,n){return e?`${e}\0${t}\0${n}`:void 0}function Ft(e,t){e&&Q.set(e,t)}function $(e){e&&Q.delete(e)}async function It(e){let{adb:t,artifact:r}=e,i=e.installPolicy??`missing-or-outdated`,a=r.manifest.packageName,o=r.manifest.versionCode;if(i===`never`)return{packageName:a,versionCode:o,installed:!1,reason:`skipped`};let s=Pt(e.deviceKey,a,o),c=s?Q.get(s):void 0;if(s&&i!==`always`&&c!==void 0)return{packageName:a,versionCode:o,installedVersionCode:c,installed:!1,reason:`current`};let l=await Lt(t,a,e.timeoutMs),u=Vt(i,l,o);if(u===`current`){if(l===void 0)throw Error(`Expected installed versionCode for current Android snapshot helper`);return Ft(s,l),{packageName:a,versionCode:o,installedVersionCode:l,installed:!1,reason:u}}await Be(r);let d=await Rt(t,e.adbProvider??t,r.apkPath,He(r.manifest),{packageName:a,timeoutMs:e.timeoutMs});if(d.exitCode!==0)throw $(s),n(`Failed to install Android snapshot helper`,d,{packageName:a,versionCode:o});return Ft(s,o),{packageName:a,versionCode:o,installedVersionCode:l,installed:!0,reason:u}}async function Lt(e,t,n){let r=await e([`shell`,`cmd`,`package`,`list`,`packages`,`--show-versioncode`,t],{allowFailure:!0,timeoutMs:n});if(r.exitCode===0)return zt(`${r.stdout}\n${r.stderr}`,t)}async function Rt(e,t,n,i,a){let o=async()=>await r(n,{allowFailure:!0,provider:t,...i,timeoutMs:a.timeoutMs}),s=await o();if(s.exitCode===0||!Bt(s))return s;let c=await e([`uninstall`,a.packageName],{allowFailure:!0,timeoutMs:a.timeoutMs}),l=await o();return l.exitCode===0?l:{...l,stderr:[l.stderr,c.stderr?`Previous uninstall stderr after INSTALL_FAILED_UPDATE_INCOMPATIBLE: ${c.stderr}`:``].filter(Boolean).join(`
|
|
5
|
-
`)}}function zt(e,t){let n=`package:${t}`;for(let t of e.split(/\r?\n/)){if(!t.startsWith(n)||t.length>n.length&&!/\s/.test(t[n.length]??``))continue;let e=/(?:^|\s)versionCode:(\d+)(?:\s|$)/.exec(t);if(e)return Number(e[1])}}function Bt(e){return`${e.stdout}\n${e.stderr}`.includes(`INSTALL_FAILED_UPDATE_INCOMPATIBLE`)}function Vt(e,t,n){return e===`never`?`skipped`:e===`always`?`forced`:t===void 0?`missing`:t<n?`outdated`:`current`}export{u as _,Z as a,Ve as c,A as d,D as f,g,ee as h,ht as i,w as l,te as m,Nt as n,mt as o,d as p,pt as r,Xe as s,It as t,k as u};
|
package/dist/src/ttl-memo.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const e=new Set;function t(t={}){let r=new Map,i=t.now??(()=>Date.now()),a=e=>{e?.timer&&clearTimeout(e.timer)},o={get(e){let t=r.get(e);if(t){if(t.expiresAt!==void 0&&t.expiresAt<=i()){o.delete(e);return}return t.value}},set(e,o){a(r.get(e));let s=n(t.ttlMs,i),c={value:o,expiresAt:s};t.scheduleExpiry&&s!==void 0&&(c.timer=setTimeout(()=>{r.delete(e)},Math.max(0,s-i())),c.timer.unref?.()),r.set(e,c)},delete(e){let t=r.get(e);return t?(a(t),r.delete(e)):!1},clear(){for(let e of r.values())a(e);r.clear()}};return e.add(o.clear),o}function n(e,t){if(!(e===void 0||!Number.isFinite(e)))return t()+Math.max(0,e)}export{t};
|
package/dist/src/xml.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
const e=new Set(`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.:-`),t=new Set([` `,` `,`
|
|
2
|
-
`,`\r`]),n=new Set([`__defineGetter__`,`__defineSetter__`,`__proto__`,`constructor`,`prototype`]);function r(e,t={}){let n=t.maxDocumentChars??134217728;if(e.length>n)throw Error(`XML document exceeds maximum supported size of ${n} characters.`);return new a(e).parse()}function i(e,t){for(let n of e){if(n.name===`dict`)for(let e=0;e<n.children.length-1;e+=1){let r=n.children[e],i=n.children[e+1];r?.name===`key`&&r.text&&i&&t(r.text,i)}i(n.children,t)}}var a=class{roots=[];stack=[];index=0;xml;constructor(e){this.xml=e}parse(){for(this.skipByteOrderMark();this.index<this.xml.length;)this.readNextToken();return this.assertFullyClosed(),this.roots}readNextToken(){if(this.xml[this.index]!==`<`){this.readText();return}this.resolveMarkupReader()()}resolveMarkupReader(){return this.startsWith(`<!--`)?()=>this.skipUntil(`-->`,`Comment is not closed.`):this.startsWith(`<?`)?()=>this.skipUntil(`?>`,`Processing instruction is not closed.`):this.startsWith(`<![CDATA[`)?()=>this.readCdata():this.startsWith(`<!`)?()=>this.skipDeclaration():this.startsWith(`</`)?()=>this.readClosingTag():()=>this.readOpeningTag()}assertFullyClosed(){if(this.stack.length>0){let e=this.stack[this.stack.length-1];throw Error(`Unclosed XML tag <${e?.name??`unknown`}>.`)}}skipByteOrderMark(){this.xml.charCodeAt(0)===65279&&(this.index=1)}readOpeningTag(){this.index+=1,this.skipWhitespace();let e=this.readRequiredName(`Missing XML tag name at offset ${this.index}.`),{attributes:t,selfClosing:n}=this.readOpeningTagBody(),r={name:e,attributes:t,text:null,children:[]};this.addNode(r),n||this.pushOpenNode(r)}readOpeningTagBody(){let e={};for(;;){this.skipWhitespace();let t=this.readOpeningTagEnd();if(t)return{attributes:e,selfClosing:t===`self-closing`};let n=this.readAttribute();e[n.name]=n.value}}readOpeningTagEnd(){if(this.index>=this.xml.length)throw Error(`Opening XML tag is not closed.`);return this.xml[this.index]===`>`?(this.index+=1,`open`):this.xml[this.index]===`/`&&this.xml[this.index+1]===`>`?(this.index+=2,`self-closing`):null}readAttribute(){let e=this.readRequiredName(`Invalid XML attribute at offset ${this.index}.`);if(f(e),this.skipWhitespace(),this.xml[this.index]!==`=`)throw Error(`Missing value for XML attribute "${e}".`);return this.index+=1,this.skipWhitespace(),{name:e,value:this.readAttributeValue(e)}}pushOpenNode(e){if(this.stack.length>=256)throw Error(`Maximum XML nesting depth of 256 exceeded.`);this.stack.push(e)}readClosingTag(){this.index+=2,this.skipWhitespace();let e=this.readName();if(this.skipWhitespace(),this.xml[this.index]!==`>`)throw Error(`Closing XML tag </${e}> is not closed.`);this.index+=1;let t=this.stack.pop();if(!t)throw Error(`Unexpected closing XML tag </${e}>.`);if(t.name!==e)throw Error(`Expected </${t.name}> before </${e}>.`)}readText(){let e=this.xml.indexOf(`<`,this.index),t=e===-1?this.xml.length:e;this.appendText(this.xml.slice(this.index,t),!0),this.index=t}readCdata(){let e=this.index+9,t=this.xml.indexOf(`]]>`,e);if(t===-1)throw Error(`CDATA section is not closed.`);this.appendText(this.xml.slice(e,t),!1),this.index=t+3}appendText(e,t){let n=e.trim();if(!n)return;let r=this.stack[this.stack.length-1];r&&(r.text=`${r.text??``}${t?p(n):n}`)}addNode(e){let t=this.stack[this.stack.length-1];t?t.children.push(e):this.roots.push(e)}readName(){let e=this.index;for(;this.index<this.xml.length&&o(this.xml[this.index]);)this.index+=1;return this.xml.slice(e,this.index)}readRequiredName(e){let t=this.readName();if(!t)throw Error(e);return t}readAttributeValue(e){let t=this.xml[this.index];if(t!==`"`&&t!==`'`)throw Error(`XML attribute "${e}" must use a quoted value.`);this.index+=1;let n=this.index,r=this.xml.indexOf(t,n);if(r===-1)throw Error(`XML attribute "${e}" is not closed.`);return this.index=r+1,p(this.xml.slice(n,r).trim())}skipDeclaration(){let e={quote:null,bracketDepth:0};for(let t=this.index+2;t<this.xml.length;t+=1)if(c(e,this.xml[t])){this.index=t+1;return}throw Error(`XML declaration is not closed.`)}skipUntil(e,t){let n=this.xml.indexOf(e,this.index+e.length);if(n===-1)throw Error(t);this.index=n+e.length}skipWhitespace(){for(;this.index<this.xml.length&&s(this.xml[this.index]);)this.index+=1}startsWith(e){return this.xml.startsWith(e,this.index)}};function o(t){return t!==void 0&&e.has(t)}function s(e){return e!==void 0&&t.has(e)}function c(e,t){return t===void 0||l(e,t)?!1:(u(e,t),d(e,t))}function l(e,t){return e.quote?(t===e.quote&&(e.quote=null),!0):t===`"`||t===`'`?(e.quote=t,!0):!1}function u(e,t){if(t===`[`){e.bracketDepth+=1;return}t===`]`&&e.bracketDepth>0&&--e.bracketDepth}function d(e,t){return t===`>`&&e.bracketDepth===0}function f(e){if(n.has(e))throw Error(`Unsupported XML attribute name "${e}".`)}function p(e){return e.replace(/&(#x[0-9a-fA-F]+|#[0-9]+|amp|lt|gt|quot|apos);/g,(e,t)=>{switch(t){case`amp`:return`&`;case`lt`:return`<`;case`gt`:return`>`;case`quot`:return`"`;case`apos`:return`'`;default:return m(e,t)}})}function m(e,t){let n=t.startsWith(`#x`)?Number.parseInt(t.slice(2),16):Number(t.slice(1));if(!Number.isInteger(n)||n<0||n>1114111)return e;try{return String.fromCodePoint(n)}catch{return e}}export{i as n,r as t};
|
|
File without changes
|
/package/{macos-helper → apple/macos-helper}/Sources/AgentDeviceMacOSHelper/AudioProbe.swift
RENAMED
|
File without changes
|
/package/{macos-helper → apple/macos-helper}/Sources/AgentDeviceMacOSHelper/SnapshotTraversal.swift
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests.xctestplan
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/RecordingScripts/recording-trim.swift
RENAMED
|
File without changes
|
|
File without changes
|