agent-device 0.18.2 → 0.19.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/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.18.2.apk → agent-device-android-multitouch-helper-0.19.0.apk} +0 -0
- package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.19.0.apk.sha256 +1 -0
- package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.18.2.manifest.json → agent-device-android-multitouch-helper-0.19.0.manifest.json} +4 -4
- package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.18.2.apk → agent-device-android-snapshot-helper-0.19.0.apk} +0 -0
- package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.19.0.apk.sha256 +1 -0
- package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.18.2.manifest.json → agent-device-android-snapshot-helper-0.19.0.manifest.json} +6 -6
- package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTapPointPolicy.swift +28 -0
- package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +9 -120
- package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +132 -66
- package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +155 -0
- package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+FlatSnapshotFiltering.swift +67 -0
- package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +20 -74
- package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollGesture.swift +64 -0
- package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SequenceExecution.swift +0 -177
- package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +81 -48
- package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +102 -129
- package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +208 -46
- package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Transport.swift +82 -11
- package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +72 -0
- package/dist/src/agent-browser-tool.js +1 -0
- package/dist/src/android-adb.d.ts +64 -234
- package/dist/src/android-adb.js +1 -1
- package/dist/src/android.js +1 -5
- package/dist/src/app-lifecycle.js +7 -0
- package/dist/src/apple-runner-options.js +1 -0
- package/dist/src/apps.js +5 -11
- package/dist/src/artifacts.d.ts +4 -3
- package/dist/src/artifacts.js +1 -1
- package/dist/src/audio-probe.js +1 -1
- package/dist/src/batch.d.ts +2 -177
- package/dist/src/batch.js +1 -1
- package/dist/src/cli-help.js +64 -38
- package/dist/src/cli-output.js +1 -1
- package/dist/src/cli-runner.js +2 -0
- package/dist/src/cli.js +12 -41
- package/dist/src/client-metro-companion.js +1 -0
- package/dist/src/client.js +3 -0
- package/dist/src/command-metadata.js +1 -0
- package/dist/src/command-schema.js +22 -0
- package/dist/src/command-surface.js +1 -1
- package/dist/src/contracts.d.ts +2 -213
- package/dist/src/contracts.js +1 -1
- package/dist/src/debug-symbols.js +5 -3
- package/dist/src/device-input-state.js +2 -0
- package/dist/src/device-rotation.js +14 -0
- package/dist/src/devices.js +1 -1
- package/dist/src/devices2.js +1 -0
- package/dist/src/devices3.js +1 -0
- package/dist/src/find.js +1 -1
- package/dist/src/finders.d.ts +2 -81
- package/dist/src/finders.js +1 -1
- package/dist/src/generic.js +1 -1
- package/dist/src/handler-utils.js +1 -1
- package/dist/src/helper.js +2 -0
- package/dist/src/host-process.js +2 -0
- package/dist/src/index.d.ts +1265 -1768
- package/dist/src/index.js +1 -1
- package/dist/src/input-actions.js +3 -1
- package/dist/src/input-actions2.js +1 -0
- package/dist/src/install-source.d.ts +13 -14
- package/dist/src/install-source.js +1 -1
- package/dist/src/install-source2.js +1 -0
- package/dist/src/interaction-snapshot.js +1 -0
- package/dist/src/interaction.js +1 -1
- package/dist/src/interactor.js +2 -1
- package/dist/src/internal/bin.d.ts +1 -1
- package/dist/src/internal/bin.js +2 -5
- package/dist/src/internal/companion-tunnel.d.ts +1 -1
- package/dist/src/internal/companion-tunnel.js +1 -1
- package/dist/src/internal/daemon.d.ts +1 -1
- package/dist/src/internal/daemon.js +16 -1
- package/dist/src/internal/png-worker.d.ts +29 -26
- package/dist/src/internal/png-worker.js +1 -1
- package/dist/src/internal/update-check-entry.d.ts +1 -1
- package/dist/src/internal/update-check-entry.js +1 -1
- package/dist/src/io.d.ts +2 -85
- package/dist/src/io.js +1 -1
- package/dist/src/lease.js +1 -1
- package/dist/src/linux.js +1 -1
- package/dist/src/logcat.js +6 -0
- package/dist/src/manifest.js +1 -0
- package/dist/src/metro.d.ts +70 -113
- package/dist/src/metro.js +1 -1
- package/dist/src/metro2.js +1 -0
- package/dist/src/notifications.js +1 -1
- package/dist/src/output-path.js +1 -0
- package/dist/src/path-resolution.js +1 -0
- package/dist/src/png-worker-contract.js +1 -0
- package/dist/src/points.js +4 -0
- package/dist/src/project-runtime.js +1 -0
- package/dist/src/provider.js +1 -1
- package/dist/src/providers.js +1 -0
- package/dist/src/react-native.js +1 -1
- package/dist/src/record-trace-recording.js +2 -5
- package/dist/src/record-trace.js +1 -1
- package/dist/src/recording-provider.js +1 -1
- package/dist/src/registry.js +37 -0
- package/dist/src/remote-config.d.ts +2 -83
- package/dist/src/reporting.js +9 -0
- package/dist/src/rolldown-runtime.js +1 -0
- package/dist/src/runner-client.js +1 -0
- package/dist/src/runner-provider.js +1 -0
- package/dist/src/runner-sequence.js +1 -1
- package/dist/src/runtime-transport.js +1 -0
- package/dist/src/runtime.js +3 -0
- package/dist/src/scoped-provider.js +1 -0
- package/dist/src/sdk-android-adb.d.ts +144 -0
- package/dist/src/sdk-android-adb.js +4 -0
- package/dist/src/sdk-app-inventory.d.ts +4 -0
- package/dist/src/sdk-app-inventory.js +1 -0
- package/dist/src/sdk-batch-runner.d.ts +40 -0
- package/dist/src/sdk-batch-runner.js +2 -0
- package/dist/src/sdk-batch.js +2 -0
- package/dist/src/sdk-contracts.d.ts +386 -0
- package/dist/src/sdk-contracts.js +2 -0
- package/dist/src/sdk-finders.d.ts +61 -0
- package/dist/src/sdk-finders.js +1 -0
- package/dist/src/sdk-io.d.ts +79 -0
- package/dist/src/sdk-io.js +1 -0
- package/dist/src/sdk-remote-config.d.ts +140 -0
- package/dist/src/sdk-remote-config.js +1 -0
- package/dist/src/sdk-selectors.js +1 -0
- package/dist/src/selector-runtime.js +1 -1
- package/dist/src/selectors.d.ts +39 -137
- package/dist/src/selectors.js +1 -1
- package/dist/src/selectors2.js +1 -0
- package/dist/src/server.js +3 -2
- package/dist/src/session.js +10 -11
- package/dist/src/setting-state.js +1 -0
- package/dist/src/simctl.js +1 -0
- package/dist/src/simulator.js +1 -2
- package/dist/src/snapshot-diagnostics.js +3 -0
- package/dist/src/snapshot-helper.js +5 -0
- package/dist/src/snapshot-quality.js +1 -0
- package/dist/src/snapshot.js +1 -2
- package/dist/src/snapshot2.js +2 -0
- package/dist/src/{5560.js → timeouts.js} +1 -1
- package/dist/src/tool-provider.js +3 -0
- package/dist/src/tool-provider2.js +1 -0
- package/dist/src/ttl-memo.js +1 -0
- package/dist/src/update-check.js +1 -0
- package/dist/src/url.js +1 -0
- package/dist/src/version.js +1 -0
- package/dist/src/web.js +1 -1
- package/dist/src/xml.js +2 -0
- package/package.json +12 -19
- package/server.json +2 -2
- package/skills/agent-device/SKILL.md +2 -0
- package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.18.2.apk.sha256 +0 -1
- package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.18.2.apk.sha256 +0 -1
- package/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +0 -443
- package/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+FlatSnapshotFiltering.swift +0 -169
- package/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollGesture.swift +0 -220
- package/dist/src/1404.js +0 -1
- package/dist/src/1986.js +0 -1
- package/dist/src/2748.js +0 -1
- package/dist/src/2948.js +0 -30
- package/dist/src/3006.js +0 -1
- package/dist/src/314.js +0 -1
- package/dist/src/3340.js +0 -8
- package/dist/src/4418.js +0 -1
- package/dist/src/4428.js +0 -3
- package/dist/src/485.js +0 -1
- package/dist/src/4917.js +0 -1
- package/dist/src/495.js +0 -5
- package/dist/src/5448.js +0 -3
- package/dist/src/5484.js +0 -1
- package/dist/src/5643.js +0 -1
- package/dist/src/587.js +0 -1
- package/dist/src/5913.js +0 -4
- package/dist/src/6849.js +0 -1
- package/dist/src/6918.js +0 -1
- package/dist/src/6967.js +0 -1
- package/dist/src/760.js +0 -1
- package/dist/src/7871.js +0 -1
- package/dist/src/8184.js +0 -1
- package/dist/src/8225.js +0 -1
- package/dist/src/8391.js +0 -1
- package/dist/src/8404.js +0 -2
- package/dist/src/8414.js +0 -2
- package/dist/src/8875.js +0 -4
- package/dist/src/893.js +0 -1
- package/dist/src/8936.js +0 -1
- package/dist/src/9414.js +0 -1
- package/dist/src/9581.js +0 -22
- package/dist/src/9612.js +0 -1
- package/dist/src/9624.js +0 -1
- package/dist/src/9722.js +0 -38
- package/dist/src/devices~1.js +0 -1
- package/dist/src/devices~2.js +0 -1
- package/dist/src/input-actions~1.js +0 -1
- package/dist/src/rslib-runtime.js +0 -1
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunner/AgentDeviceRunnerApp.m +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/project.pbxproj +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/xcshareddata/xcschemes/AgentDeviceRunner.xcscheme +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/AgentDeviceRunnerUITests-Bridging-Header.h +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/AgentDeviceRunnerUITests.entitlements +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.h +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.m +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerObjCExceptionCatcher.h +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerObjCExceptionCatcher.m +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.h +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.m +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Alert.swift +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Environment.swift +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Exceptions.swift +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScreenRecorder.swift +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SystemModal.swift +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TvRemote.swift +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests.xctestplan +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/RecordingScripts/recording-overlay.swift +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/RecordingScripts/recording-resize.swift +0 -0
- /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/RecordingScripts/recording-trim.swift +0 -0
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
import Foundation
|
|
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{n as o,r as s,t as c}from"./output-path.js";import{h as l}from"./snapshot-diagnostics.js";import{t as u}from"./version.js";import{t as d}from"./timeouts.js";import{l as f,o as p,s as m}from"./host-process.js";import{a as h,i as g,r as ee}from"./device-rotation.js";import{a as te,s as ne}from"./logcat.js";import{d as re,i as ie}from"./runner-client.js";import{o as ae}from"./tool-provider.js";import{c as oe}from"./agent-browser-tool.js";import{Qt as se,Xt as _,on as ce,pt as le,rn as ue,tn as de,vn as fe}from"./internal/daemon.js";import{n as v}from"./provider.js";import{a as pe,t as me}from"./apple-runner-options.js";import{t as he}from"./handler-utils.js";import{n as ge}from"./recording-provider.js";import{createHash as _e,randomUUID as ve}from"node:crypto";import y from"node:fs";import ye from"node:os";import b from"node:path";import{fileURLToPath as be}from"node:url";function x(e=process.env){let t=S(),n=b.join(t,`home`),r=b.join(t,`module-cache`);return y.mkdirSync(n,{recursive:!0}),y.mkdirSync(r,{recursive:!0}),{...e,HOME:n,CLANG_MODULE_CACHE_PATH:r}}async function xe(e){let t=y.statSync(e.sourcePath),n=y.readFileSync(e.sourcePath),r=Te(e.cacheName??b.basename(e.sourcePath,b.extname(e.sourcePath))),i=Ee([`2`,process.platform,process.arch,b.resolve(e.sourcePath),t.size,n]),a=b.join(S(),`bin`,`${r}-${i}`);return await Ce({sourcePath:e.sourcePath,executablePath:a,timeoutMs:e.timeoutMs}),a}async function Se(e){let t=Te(e.cacheName),n=Ee([`2`,process.platform,process.arch,e.source]),r=b.join(S(),`sources`,`${t}-${n}.swift`),i=b.join(S(),`bin`,`${t}-${n}`);return await Ce({sourcePath:r,executablePath:i,sourceText:e.source,timeoutMs:e.timeoutMs}),i}function S(){let e=process.env.AGENT_DEVICE_SWIFT_CACHE_DIR?.trim();return e?b.resolve(e):b.join(ye.tmpdir(),`agent-device-swift-cache`)}async function Ce(e){if(C(e.executablePath))return;let t=b.dirname(e.executablePath);y.mkdirSync(t,{recursive:!0});let n=await we(`${e.executablePath}.lock`,e.executablePath,e.timeoutMs??12e4);if(!n)return;let r=y.mkdtempSync(b.join(t,`.${b.basename(e.executablePath)}.${process.pid}.`)),i=b.join(r,b.basename(e.executablePath));try{if(C(e.executablePath))return;e.sourceText!==void 0&&!y.existsSync(e.sourcePath)&&(y.mkdirSync(b.dirname(e.sourcePath),{recursive:!0}),y.writeFileSync(e.sourcePath,e.sourceText)),await a(`xcrun`,[`swiftc`,e.sourcePath,`-o`,i],{timeoutMs:e.timeoutMs??12e4,env:x()}),y.renameSync(i,e.executablePath)}finally{y.rmSync(r,{recursive:!0,force:!0}),await n()}}async function we(t,n,r){if(C(n))return null;try{return await oe({lockDirPath:t,owner:{pid:process.pid,startTime:p(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 C(e){try{return y.accessSync(e,y.constants.X_OK),y.statSync(e).isFile()}catch{return!1}}function Te(e){return e.replaceAll(/[^A-Za-z0-9._-]/g,`-`).replaceAll(/^-+|-+$/g,``)||`swift-helper`}function Ee(e){let t=_e(`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 w;async function De(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=y.statSync(e).size}catch{t=0}if(t>0&&t===i){if(a+=1,a>=2)return}else a=0;i=t,await d(n)}}async function Oe(e){try{let t=await a(await ke(),[e],{allowFailure:!0,timeoutMs:1e4,env:x()});return t.exitCode===0?!0:Me(t.stderr,t.stdout)?Ne(e):!1}catch(t){if(Ae(t))return Ne(e);throw t}}async function ke(){w??=Se({source:`import Foundation
|
|
3
2
|
import AVFoundation
|
|
4
3
|
|
|
5
4
|
let url = URL(fileURLWithPath: CommandLine.arguments[1])
|
|
@@ -21,6 +20,4 @@ Task {
|
|
|
21
20
|
}
|
|
22
21
|
|
|
23
22
|
semaphore.wait()
|
|
24
|
-
exit(exitCode)
|
|
25
|
-
`.trim();async function J(e,t={}){let r,a=t.pollMs??150,o=t.attempts??12,n=0;for(let t=0;t<o;t+=1){let t=0;try{t=i.statSync(e).size}catch{t=0}if(t>0&&t===r){if((n+=1)>=2)return}else n=0;r=t,await f(a)}}async function X(e){try{let t=await Z(),r=await p(t,[e],{allowFailure:!0,timeoutMs:1e4,env:z()});if(0===r.exitCode)return!0;if(ee(r.stderr,r.stdout))return et(e);return!1}catch(r){var t;if((t=r)instanceof d&&("TOOL_MISSING"===t.code||ee(String(t.details?.stderr??""),String(t.details?.stdout??""))))return et(e);throw r}}async function Z(){e??=G({source:Q,cacheName:"video-validator",timeoutMs:3e4});try{return await e}catch(t){throw e=void 0,t}}async function Y(e,t={}){let r=t.pollMs??150,a=t.attempts??12;for(let t=0;t<a;t+=1){if(await X(e))return;await f(r)}}function ee(e,t){let r=`${e}
|
|
26
|
-
${t}`;return/\b(no such module ['"]AVFoundation['"]|unable to find utility ["']swiftc?["']|xcrun: error: unable to find utility ["']swiftc?["'])\b/i.test(r)}function et(e){try{let t=i.statSync(e);if(!t.isFile()||t.size<=0)return!1}catch{return!1}let t=function(e){try{let t=i.openSync(e,"r");try{let e=i.fstatSync(t).size,r=0,a=[];for(;r+8<=e&&a.length<16;){let e=Buffer.alloc(8);if(8>i.readSync(t,e,0,8,r))break;let o=e.readUInt32BE(0),n=e.toString("latin1",4,8);if(a.push(n),1===o){let e=Buffer.alloc(8);if(8>i.readSync(t,e,0,8,r+8))break;o=Number(e.readBigUInt64BE(0))}if(!Number.isFinite(o)||o<=0)break;r+=o}return a}finally{i.closeSync(t)}}catch{return[]}}(e);return t.includes("ftyp")&&t.includes("moov")}function er(e){let t=o.parse(e);return o.join(t.dir,`${t.name}.gesture-telemetry.json`)}function ea(e){return[...e].sort((e,t)=>e.tMs-t.tMs)}function ei(e){var t,r,a;let o,n,{recording:s,trimStartMs:c}=e,d=(o=er((t={videoPath:s.outPath,events:s.gestureEvents,trimStartMs:c}).videoPath),n={version:1,generatedAt:new Date().toISOString(),events:(r=t.events,(a=t.trimStartMs??0)>0?ea(r.flatMap(e=>{let t=e.tMs-a,r="durationMs"in e?e.durationMs:void 0;return("number"==typeof r?t+r:t)<=0?[]:[{...e,tMs:Math.max(0,t)}]})):ea(r))},i.writeFileSync(o,JSON.stringify(n,null,2)),o);return s.telemetryPath=d,d}function eo(e){let t=o.dirname(c(import.meta.url)),r=[c(new URL(`./${e}`,import.meta.url)),o.resolve(t,`../../apple-runner/AgentDeviceRunner/RecordingScripts/${e}`),o.resolve(t,`../../../apple-runner/AgentDeviceRunner/RecordingScripts/${e}`),o.resolve(process.cwd(),`apple-runner/AgentDeviceRunner/RecordingScripts/${e}`)];for(let e of r)if(i.existsSync(e))return e;throw new d("COMMAND_FAILED",`Missing recording helper script: ${e}`,{hint:"Ensure apple-runner/AgentDeviceRunner/RecordingScripts is present in this checkout or bundled with the package.",scriptName:e,searchedPaths:r})}async function en(e){var t;let r,a,{videoPath:n,scriptPath:s,scriptArgs:c,commandDescription:u}=e;await J(n),await Y(n);let l=(t=n,r=o.parse(t),a=`${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2)}`,o.join(r.dir,`.${r.name}.agent-device-${a}${r.ext||".mp4"}`));try{let e=await K({sourcePath:s});await p(e,["--input",n,"--output",l,...c],{timeoutMs:12e4,env:z()}),await Y(l),i.renameSync(l,n)}catch(t){let e=t instanceof d?t:new d("COMMAND_FAILED",String(t),void 0,t instanceof Error?t:void 0);throw new d("COMMAND_FAILED",u,{...e.details,videoPath:n,script:s},e)}finally{i.rmSync(l,{force:!0})}}async function es(e){let{videoPath:t,trimStartMs:a}=e;a>0&&await en({videoPath:t,scriptPath:r??=eo("recording-trim.swift"),scriptArgs:["--trim-start-ms",String(a)],commandDescription:"Failed to trim the start of the iOS recording"})}async function ec(e){let{videoPath:r,telemetryPath:a,exportQuality:i="medium",targetLabel:o="recording"}=e;await en({videoPath:r,scriptPath:t??=eo("recording-overlay.swift"),scriptArgs:["--events",a,"--quality",i],commandDescription:`Failed to add touch overlays to the ${o}`})}async function ed(e){let{videoPath:t,maxSize:r,exportQuality:i="medium",targetLabel:o="recording"}=e;await en({videoPath:t,scriptPath:a??=eo("recording-resize.swift"),scriptArgs:["--max-size",String(r),"--quality",i],commandDescription:`Failed to resize the ${o}`})}function eu(e){return e instanceof Error?e.message:String(e)}function el(e,t){return e.stderr.trim()||e.stdout.trim()||`${t} exited with code ${e.exitCode}`}function ep(e,t,r=Date.now()){let a=Math.max(0,r-t.startedAt);return a>=1e3?{message:e,tooShort:!1}:{message:`${e}. Recording stopped after ${Math.round(a)}ms; wait at least 1000ms between record start and record stop so the recorder can finalize a playable MP4`,tooShort:!0}}async function em(e){let{recording:t,deps:r,trimStartMs:a,targetLabel:i}=e,o=ei({recording:t,trimStartMs:a});if(!t.showTouches)return void l({level:"debug",phase:"record_stop_overlay_skipped",data:{reason:"hide_touches"}});if(0===t.gestureEvents.length)return void l({level:"debug",phase:"record_stop_overlay_skipped",data:{reason:"no_gesture_events"}});let n=function(e=process.platform){if("darwin"!==e)return"touch overlay burn-in is only available on macOS hosts; returning raw video plus gesture telemetry"}();if(n){t.overlayWarning??=n;return}try{await u("record_stop_overlay_export",()=>r.overlayRecordingTouches({videoPath:t.outPath,telemetryPath:o,exportQuality:t.exportQuality,targetLabel:i}),{targetLabel:i,gestureEventCount:t.gestureEvents.length})}catch(e){t.overlayWarning??=`failed to overlay recording touches: ${eu(e)}`}}function eh(e,t){if(1===t)return e;let r=o.parse(e),a=r.ext||".mp4";return o.join(r.dir,`${r.name}.part-${String(t).padStart(3,"0")}${a}`)}function ef(e){return e.chunks??=[{index:1,path:e.outPath,remotePath:e.remotePath}],e.chunks}async function ew(e){let{recording:t,startNextChunk:r,finishCurrentChunk:a}=e;if(t.stopping)return;let i=await a();if(i)throw Error(i);if(t.stopping)return;let n=ef(t),s=n.length+1,c=await r(o.posix.dirname(t.remotePath));t.remotePath=c.remotePath,t.remotePid=c.remotePid,n.push({index:s,path:eh(t.outPath,s),remotePath:c.remotePath}),t.warning??="Android adb screenrecord is capped at 180s, so this recording was split into multiple MP4 chunks."}async function eg(e){let{recording:t,deps:r}=e;ef(t).length<=1?await em({recording:t,deps:r,targetLabel:"Android recording"}):(ei({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 ey(e){for(let t of e.chunks){let r=await e_({deps:e.deps,deviceId:e.deviceId,remotePath:t.remotePath,outPath:t.path});if(r)return`failed to copy recording chunk ${t.index}: ${r}`}}async function e_(e){let t,{deps:r,deviceId:a,remotePath:o,outPath:n}=e;for(let e=0;e<2;e+=1){ev(n);let s=w(a),c=await y(o,n,{allowFailure:!0,device:s});if(0!==c.exitCode)t=el(c,"adb pull");else{await r.waitForStableFile(n,{pollMs:250,attempts:20});let t=await r.isPlayableVideo(n);if(l({level:"debug",phase:"record_stop_android_pull_validation",data:{deviceId:a,remotePath:o,outPath:n,attempt:e+1,fileSize:function(e){try{return i.statSync(e).size}catch{return 0}}(n),playable:t}}),t)return;l({level:"warn",phase:"record_stop_android_invalid_video_retry",data:{deviceId:a,remotePath:o,outPath:n,attempt:e+1}})}e<1&&await f(750)}return t?`failed to copy recording from device: ${t}`:(ev(n),"failed to copy recording from device: pulled file is not a playable MP4")}function ev(e){try{i.rmSync(e,{force:!0})}catch{}}let eP={medium:8e6,high:2e7};async function eS(e,t,r){return await g(w(e),t,r)}async function eA(e,t){let r=await eS(e,["shell","ps","-o","pid=","-p",t],{allowFailure:!0});return 0===r.exitCode&&r.stdout.split(/\s+/).map(e=>e.trim()).includes(t)}async function eb(e,t){for(let r=0;r<40;r+=1){if(!await eA(e,t))return!0;await f(250)}return!await eA(e,t)}async function eM(e,t){let r,a=0;for(let i=0;i<20;i+=1){let i=await eS(e,["shell","stat","-c","%s",t],{allowFailure:!0}),o=0===i.exitCode?i.stdout.trim():"";if(o.length>0&&o===r){if((a+=1)>=4)return}else a=0;r=o,await f(250)}}async function eC(e,t,r){for(let a=0;a<8;a+=1){let i=await eS(e,["shell","stat","-c","%s",t],{allowFailure:!0}),o=0===i.exitCode?Number(i.stdout.trim()):NaN;if(Number.isFinite(o)&&o>0)return!0;if(!await eA(e,r))break;if(a+1>=2)return!0;await f(250)}return!1}async function ex(e){let{deviceId:t,maxSize:r}=e;if(void 0===r)return;let a=await eS(t,["shell","wm","size"],{allowFailure:!0}),i=a.stdout.match(/Override size:\s*(\d+)x(\d+)/)??a.stdout.match(/Physical size:\s*(\d+)x(\d+)/);if(0!==a.exitCode||!i)throw Error(`failed to resolve Android screen size for recording max-size: ${el(a,"adb shell wm size")}`);var o={width:Number(i[1]),height:Number(i[2]),maxSize:r};let n=Math.max(o.width,o.height);if(n<=o.maxSize)return{width:o.width,height:o.height};let s=o.maxSize/n;return{width:eR(o.width,s),height:eR(o.height,s)}}function eR(e,t){return Math.max(2,2*Math.round(e*t/2))}async function eI(e,t){await eS(e,["shell","rm","-f",t],{allowFailure:!0})}async function eD(e,t){let r=await eS(e,["shell","kill","-9",t],{allowFailure:!0});return l({level:"warn",phase:"record_stop_android_force_signal",data:{deviceId:e,remotePid:t,exitCode:r.exitCode,stdout:r.stdout.trim(),stderr:r.stderr.trim()}}),!(0!==r.exitCode&&await eA(e,t))&&await eb(e,t)}async function eN(e){var t;let r,a,{device:i,recordingSize:o,quality:n,preferredRemoteDir:s}=e,c="failed to start recording: Android screenrecord did not begin producing frames";for(let e of(t=Date.now(),r=`agent-device-recording-${t}.mp4`,a=["/sdcard","/data/local/tmp"],(s&&a.includes(s)?[s,...a.filter(e=>e!==s)]:a).map(e=>`${e}/${r}`))){let t=await eS(i.id,["shell",function(e,t,r){let a=["screenrecord"];return t&&a.push("--size",`${t.width}x${t.height}`),a.push("--bit-rate",String(eP[r])),a.push(e),`${a.join(" ")} >/dev/null 2>&1 & echo $!`}(e,o,n)],{allowFailure:!0});if(0!==t.exitCode){c=`failed to start recording: ${el(t,"adb shell screenrecord")}`;continue}let r=t.stdout.split(/\r?\n/).map(e=>e.trim()).filter(e=>/^\d+$/.test(e)).at(-1);if(!r){c="failed to start recording: adb did not return a valid Android screenrecord pid",await eI(i.id,e);continue}if(l({level:"debug",phase:"record_start_android_started",data:{deviceId:i.id,remotePath:e,remotePid:r}}),await eC(i.id,e,r))return{remotePath:e,remotePid:r,startedAt:Date.now()};c="failed to start recording: Android screenrecord did not begin producing frames",await eD(i.id,r),await eI(i.id,e)}return{error:b("COMMAND_FAILED",c)}}async function eE(e){let t,{device:r,recordingBase:a}=e;try{t=await ex({deviceId:r.id,maxSize:a.maxSize})}catch(e){return b("COMMAND_FAILED",e instanceof Error?e.message:String(e))}let i=a.exportQuality??"medium",o=await eN({device:r,recordingSize:t,quality:i});if("error"in o)return o.error;let n={platform:"android",remotePath:o.remotePath,remotePid:o.remotePid,chunks:[{index:1,path:a.outPath,remotePath:o.remotePath}],...a,startedAt:o.startedAt};return!function e(t){let{recording:r,startNextChunk:a,finishCurrentChunk:i}=t,o=setTimeout(()=>{r.rotationPromise=ew({recording:r,startNextChunk:a,finishCurrentChunk:i}).catch(e=>{r.rotationFailedReason=e instanceof Error?e.message:String(e)}).finally(()=>{r.rotationPromise=void 0,r.stopping||r.rotationFailedReason||e({recording:r,startNextChunk:a,finishCurrentChunk:i})})},17e4);o.unref?.(),r.rotationTimer=o}({recording:n,finishCurrentChunk:async()=>await e$({device:r,recording:n,waitForRemoteFileStability:!1}),startNextChunk:async e=>{let a=await eN({device:r,recordingSize:t,quality:i,preferredRemoteDir:e});if("error"in a)throw Error(a.error.ok?"failed to start next Android recording chunk":a.error.error.message);return a}}),n}async function e$(e){let{device:t,recording:r,waitForRemoteFileStability:a=!0}=e;await eA(t.id,r.remotePid)||(r.warning??=function(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."}(r));let i=await eS(t.id,["shell","kill","-2",r.remotePid],{allowFailure:!0});if(l({level:"debug",phase:"record_stop_android_signal",data:{deviceId:t.id,remotePath:r.remotePath,remotePid:r.remotePid,exitCode:i.exitCode,stdout:i.stdout.trim(),stderr:i.stderr.trim()}}),0!==i.exitCode)return await eO(t.id,r.remotePid,i);let o=await ek(t.id,r.remotePid);if(o)return o;a&&await eM(t.id,r.remotePath)}async function eO(e,t,r){if(await eA(e,t)&&!await eD(e,t))return`failed to stop recording: ${el(r,"adb shell kill")}`}async function ek(e,t){if(!await eb(e,t)&&!await eD(e,t))return`failed to stop recording: Android screenrecord pid ${t} did not exit`}async function eF(e){let t,{deps:r,device:a,recording:i,stopRequestedAt:o}=e;l({level:"debug",phase:"record_stop_android_enter",data:{deviceId:a.id,remotePath:i.remotePath,remotePid:i.remotePid}}),i.stopping=!0,i.rotationTimer&&(clearTimeout(i.rotationTimer),i.rotationTimer=void 0),await i.rotationPromise;let n=await e$({device:a,recording:i});if(i.rotationFailedReason&&!n&&(i.warning??=`Android recording chunk rotation failed: ${i.rotationFailedReason}`),!n){let e=await ey({deps:r,deviceId:a.id,chunks:ef(i)});if(e)return await s(),b("COMMAND_FAILED",eT(e,i,o));await eg({recording:i,deps:r})}if(await s(),n)return b("COMMAND_FAILED",eT(n,i,o));if(t)return b("COMMAND_FAILED",t);return null;async function s(){for(let e of ef(i)){let r=await eS(a.id,["shell","rm","-f",e.remotePath],{allowFailure:!0});l({level:"debug",phase:"record_stop_android_cleanup",data:{deviceId:a.id,remotePath:e.remotePath,exitCode:r.exitCode,stdout:r.stdout.trim(),stderr:r.stderr.trim()}}),0===r.exitCode||n||(t=`failed to clean up remote recording: ${el(r,"adb shell rm")}`)}}}function eT(e,t,r){return ep(e,t,r).message}function eL(e){let t=e.appBundleId?.trim();return t&&t.length>0?t:void 0}function eU(e,t,r){return N({req:e,logPath:t,traceLogPath:r.trace?.outPath})}async function ez(e){let{req:t,activeSession:r,device:a,logPath:i,deps:o}=e,n=eL(r);try{await o.runAppleRunnerCommand(a,{command:"recordStop",appBundleId:n},eU(t,i,r))}catch(e){l({level:"warn",phase:"record_stop_runner_failed",data:{platform:a.platform,kind:a.kind,deviceId:a.id,session:r.name,error:eu(e)}})}}async function eK(e){let{req:t,activeSession:r,device:a,logPath:i,deps:o}=e,n=eL(r);if(n)try{let e=await o.runAppleRunnerCommand(a,{command:"snapshot",appBundleId:n,interactiveOnly:!0,depth:1},eU(t,i,r)),s=Date.now();if("number"==typeof e.currentUptimeMs&&Number.isFinite(e.currentUptimeMs)&&e.currentUptimeMs>0)return l({level:"debug",phase:"record_start_gesture_clock_anchor",data:{source:"warm_snapshot"}}),{gestureClockOriginAtMs:s,gestureClockOriginUptimeMs:e.currentUptimeMs};return}catch(e){l({level:"warn",phase:"record_start_simulator_runner_warm_failed",data:{deviceId:a.id,session:r.name,appBundleId:n,error:eu(e)}});return}}async function eG(e){let t,r,{req:a,activeSession:i,sessionStore:o,device:n,logPath:s,deps:c,fpsFlag:d,recordingBase:u,appBundleId:p}=e,m=`agent-device-recording-${Date.now()}.mp4`,h=`tmp/${m}`,f=eU(a,s,i),w=async()=>c.runAppleRunnerCommand(n,{command:"recordStart",outPath:m,fps:d,maxSize:u.maxSize,appBundleId:p},f);try{let e=await w();t="number"==typeof e.recorderStartUptimeMs?e.recorderStartUptimeMs:void 0,r="number"==typeof e.targetAppReadyUptimeMs?e.targetAppReadyUptimeMs:void 0}catch(a){var g,y;if(!eu(a).toLowerCase().includes("recording already in progress"))return b("COMMAND_FAILED",`failed to start recording: ${eu(a)}`);l({level:"warn",phase:"record_start_runner_desynced",data:{platform:n.platform,kind:n.kind,deviceId:n.id,session:i.name,error:eu(a)}});let e=(g=n.id,y=i.name,o.toArray().find(e=>e.name!==y&&D(e.device)&&"device"===e.device.kind&&e.device.id===g&&e.recording?.platform==="ios-device-runner"));if(e)return b("COMMAND_FAILED",`failed to start recording: recording already in progress in session '${e.name}'`);try{await c.runAppleRunnerCommand(n,{command:"recordStop",appBundleId:p},f)}catch{}try{let e=await w();t="number"==typeof e.recorderStartUptimeMs?e.recorderStartUptimeMs:void 0,r="number"==typeof e.targetAppReadyUptimeMs?e.targetAppReadyUptimeMs:void 0}catch(e){return b("COMMAND_FAILED",`failed to start recording: ${eu(e)}`)}}return{platform:"ios-device-runner",remotePath:h,runnerStartedAtUptimeMs:t,targetAppReadyUptimeMs:r,...u}}async function eV(e){let{req:t,activeSession:r,device:a,logPath:i,deps:o,fpsFlag:n,recordingBase:s,appBundleId:c}=e;try{await o.runAppleRunnerCommand(a,{command:"recordStart",outPath:s.outPath,fps:n,maxSize:s.maxSize,appBundleId:c},eU(t,i,r))}catch(e){return b("COMMAND_FAILED",`failed to start recording: ${eu(e)}`)}return{platform:"macos-runner",...s}}async function eH(e){let{req:t,activeSession:r,device:a,logPath:i,deps:o,recording:n}=e;await ez({req:t,activeSession:r,device:a,logPath:i,deps:o});let s={stdout:"",stderr:"",exitCode:1};for(let e of S)if(0===(s=await o.runCmd("xcrun",["devicectl","device","copy","from","--device",a.id,"--source",n.remotePath,"--destination",n.outPath,"--domain-type","appDataContainer","--domain-identifier",e],{allowFailure:!0})).exitCode)break;if(0!==s.exitCode){let e=s.stderr.trim()||s.stdout.trim()||`devicectl exited with code ${s.exitCode}`;return b("COMMAND_FAILED",`failed to copy recording from device: ${e}`)}let c="number"!=typeof n.runnerStartedAtUptimeMs||"number"!=typeof n.targetAppReadyUptimeMs?0:Math.max(0,n.targetAppReadyUptimeMs-n.runnerStartedAtUptimeMs);return c>0&&await o.trimRecordingStart({videoPath:n.outPath,trimStartMs:c}),await em({recording:n,deps:o,trimStartMs:c,targetLabel:"iOS recording"}),null}async function ej(e){let{req:t,activeSession:r,device:a,logPath:i,deps:o,recording:n}=e;return await ez({req:t,activeSession:r,device:a,logPath:i,deps:o}),await em({recording:n,deps:o,targetLabel:"macOS recording"}),null}async function eq(e){let{deps:t,recording:r}=e;r.child.kill("SIGINT");let a=await eW(r.wait,5e3);return a||(await eB(t,r,"SIGINT"),(a=await eW(r.wait,2e3))||(r.child.kill("SIGTERM"),await eB(t,r,"SIGTERM"),a=await eW(r.wait,2e3)))?a:(r.child.kill("SIGKILL"),await eB(t,r,"SIGKILL"),await eW(r.wait,2e3))}async function eW(e,t){return await Promise.race([e,f(t).then(()=>null)])}async function eB(e,t,r){await eJ(e,t,r)||await eQ(e,t.outPath,r)}async function eQ(e,t,r){let a,i=`simctl.*recordVideo.*${t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}`;try{a=await e.runCmd("pgrep",["-f",i],{allowFailure:!0})}catch(e){l({level:"warn",phase:"record_stop_ios_simulator_pgrep_failed",data:{outPath:t,signal:r,error:eu(e)}});return}let o=eZ(e0(a.stdout)),n=eY(o,r);l({level:n>0?"warn":"debug",phase:"record_stop_ios_simulator_signal_recorders",data:{outPath:t,signal:r,matchedPidCount:o.length,signaled:n,pgrepExitCode:a.exitCode}})}async function eJ(e,t,r){let a=t.recorderPid??t.child.pid;if("number"!=typeof a||!Number.isInteger(a)||a<=0)return l({level:"debug",phase:"record_stop_ios_simulator_owned_recorder_unavailable",data:{outPath:t.outPath,signal:r,reason:"missing_recorder_pid"}}),!1;let i=await eX(e,a,t.outPath,r),o=eZ([a,...i.pids]),n=eY(o,r);return l({level:n>0?"warn":"debug",phase:"record_stop_ios_simulator_signal_owned_recorder",data:{outPath:t.outPath,signal:r,recorderPid:a,childPidCount:i.pids.length,matchedPidCount:o.length,signaled:n,pgrepExitCode:i.exitCode}}),n>0}async function eX(e,t,r,a){let i;try{i=await e.runCmd("pgrep",["-P",String(t)],{allowFailure:!0})}catch(e){return l({level:"warn",phase:"record_stop_ios_simulator_owned_pgrep_failed",data:{outPath:r,signal:a,parentPid:t,error:eu(e)}}),{pids:[]}}return{pids:e0(i.stdout),exitCode:i.exitCode}}function eZ(e){return Array.from(new Set(e)).filter(e=>Number.isInteger(e)&&e>0&&e!==process.pid)}function eY(e,t){let r=0;for(let a of e)try{process.kill(a,t),r+=1}catch{}return r}function e0(e){return e.split(/\s+/).map(e=>Number(e)).filter(e=>Number.isInteger(e)&&e>0)}async function e1(e){let t,r,{req:a,activeSession:i,device:o,logPath:n,deps:s,recordingBase:c,resolvedOut:d}=e,u=c.showTouches?await eK({req:a,activeSession:i,device:o,logPath:n,deps:s}):void 0,{child:l,wait:p}=s.startIosSimulatorRecording({device:o,outPath:d}),m=await e4(d);if(u)t=u.gestureClockOriginAtMs,r=u.gestureClockOriginUptimeMs;else if(c.showTouches)try{let e=Date.now(),c=await s.runAppleRunnerCommand(o,{command:"uptime",appBundleId:eL(i)},eU(a,n,i)),d=Date.now();t=Math.round((e+d)/2),r="number"==typeof c.currentUptimeMs?c.currentUptimeMs:void 0}catch{}return{platform:"ios",child:l,wait:p,...c,recorderPid:l.pid,startedAt:m,gestureClockOriginAtMs:void 0===r?void 0:t,gestureClockOriginUptimeMs:r}}async function e2(e){let{deps:t,recording:r,stopRequestedAt:a}=e;await u("record_stop_tail_settle",()=>t.waitForRecordingTail(r),{platform:r.platform,gestureEventCount:r.gestureEvents.length});let i=await u("record_stop_ios_simulator_process",()=>eq({deps:t,recording:r}),{outPath:r.outPath});if(!i)return e5("failed to stop recording: simctl recordVideo did not exit after 5000ms and forced cleanup",r,a);if(0!==i.exitCode)return e5(`failed to stop recording: ${el(i,"simctl recordVideo")}`,r,a);if(await u("record_stop_video_stable",()=>t.waitForStableFile(r.outPath,{pollMs:150,attempts:12}),{outPath:r.outPath}),!await u("record_stop_video_playable_check",()=>t.isPlayableVideo(r.outPath),{outPath:r.outPath}))return e5(`failed to stop recording: ${r.outPath} was not finalized into a playable video`,r,a);if(void 0!==r.maxSize)try{await u("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: ${eu(e)}`}return await u("record_stop_finalize_overlay",()=>em({recording:r,deps:t,targetLabel:"iOS recording"}),{outPath:r.outPath,showTouches:r.showTouches,gestureEventCount:r.gestureEvents.length}),null}async function e4(e){for(let t=0;t<2;t+=1){try{if(i.statSync(e).size>0)return Date.now()}catch{}if(t+1>=2)break;await f(250)}return Date.now()}function e5(e,t,r){let a=ep(e,t,r);return function(e){try{i.rmSync(e,{force:!0})}catch{}}(t.outPath),b("COMMAND_FAILED",a.message)}function e8(e){return tr[v(e.platform)?.recording?.resolveBackendTag(e)??"unsupported"]}function e3({req:e}){return e.positionals?.[1]??$(void 0)}x();let e6={validateStart:e=>(function(e){let t,r=(t=[],e.flags?.fps!==void 0&&t.push("--fps"),e.flags?.quality!==void 0&&t.push("--quality"),e.flags?.screenshotMaxSize!==void 0&&t.push("--max-size"),e.flags?.hideTouches!==void 0&&t.push("--hide-touches"),t);return r.length>0?b("INVALID_ARGS",`web recordings do not support ${r.join(", ")}; agent-browser records WebM directly`):null})(e),resolveOutputPath:function({req:e}){let t=e.positionals?.[1];return void 0===t?$("web"):O(t,".webm")},start:async({activeSession:e,recordingBase:t,resolvedOut:r})=>{var a;let i=(a=r,".webm"!==o.extname(a).toLowerCase()?b("INVALID_ARGS","web recordings must use a .webm output path"):null);if(i)return i;if(e.recordOnlySession)return b("INVALID_ARGS","record on web requires an active browser session; run open <url> --platform web first");let n=k();return n.startRecording?(await n.startRecording(r),{...t,outPath:r,startedAt:Date.now(),platform:"web",showTouches:!1}):b("UNSUPPORTED_OPERATION","record is not supported by this web provider")},stop:async({recording:e})=>await ta({recording:e}),cleanupRecordOnlySession:async()=>{try{await k().close()}catch{}}},e7={resolveOutputPath:e3,start:async({req:e,activeSession:t,sessionStore:r,device:a,logPath:i,deps:o,fpsFlag:n,recordingBase:s})=>{let c=eL(t);return c?await eG({req:e,activeSession:t,sessionStore:r,device:a,logPath:i,deps:o,fpsFlag:n,recordingBase:s,appBundleId:c}):b("INVALID_ARGS","record on physical iOS devices requires an active app session; run open <app> first")},stop:async({req:e,activeSession:t,device:r,logPath:a,deps:i,recording:o})=>await eH({req:e,activeSession:t,device:r,logPath:a,deps:i,recording:o})},e9={resolveOutputPath:e3,start:async({req:e,activeSession:t,device:r,logPath:a,deps:i,fpsFlag:o,recordingBase:n})=>{let s=eL(t);return s?await eV({req:e,activeSession:t,device:r,logPath:a,deps:i,fpsFlag:o,recordingBase:n,appBundleId:s}):b("INVALID_ARGS","record on macOS requires an active app session; run open <app> first")},stop:async({req:e,activeSession:t,device:r,logPath:a,deps:i,recording:o})=>await ej({req:e,activeSession:t,device:r,logPath:a,deps:i,recording:o})},te={resolveOutputPath:e3,start:async({req:e,activeSession:t,device:r,logPath:a,deps:i,recordingBase:o,resolvedOut:n})=>await e1({req:e,activeSession:t,device:r,logPath:a,deps:i,recordingBase:o,resolvedOut:n}),stop:async({deps:e,recording:t,stopRequestedAt:r})=>await e2({deps:e,recording:t,stopRequestedAt:r})},tt={resolveOutputPath:e3,start:async({device:e,recordingBase:t})=>await eE({device:e,recordingBase:t}),stop:async({deps:e,device:t,recording:r,stopRequestedAt:a})=>await eF({deps:e,device:t,recording:r,stopRequestedAt:a})},tr={web:e6,android:tt,macos:e9,"ios-device":e7,"ios-simulator":te,unsupported:{resolveOutputPath:e3,start:async()=>b("UNSUPPORTED_OPERATION","record is not supported on this device"),stop:async()=>b("UNSUPPORTED_OPERATION","record is not supported on this device")}};async function ta(e){let{recording:t}=e,r=k();if(!r.stopRecording)return b("UNSUPPORTED_OPERATION","record is not supported by this web provider");if(await r.stopRecording(),!function(e){try{return i.statSync(e).size>0}catch{return!1}}(t.outPath)){var a=t.outPath;try{i.rmSync(a,{force:!0})}catch{}return b("COMMAND_FAILED",`failed to stop recording: ${t.outPath} was not finalized into a WebM video`)}return null}async function ti(e){"ios"!==e.platform||0!==e.gestureEvents.length&&await f(350)}async function to(e){let t,{req:r,sessionName:a,sessionStore:n,activeSession:s,device:c,logPath:d,deps:u}=e;if(s.recording)return b("INVALID_ARGS","recording already in progress");let l=r.flags?.fps,p=r.flags?.quality,m=r.flags?.screenshotMaxSize,h=e8(c),f=h.validateStart?.(r)??null;if(f)return f;if(void 0!==l&&(!Number.isInteger(l)||l<1||l>120))return b("INVALID_ARGS","fps must be an integer between 1 and 120");if(void 0!==p&&void 0===T(p))return b("INVALID_ARGS",`quality must be one of: ${L.join(", ")} (legacy numeric values 5-10 are accepted)`);if(void 0!==m&&(!Number.isInteger(m)||m<1))return b("INVALID_ARGS","max-size must be a positive integer");let w=A("record",c);if(w)return w;let g=h.resolveOutputPath({req:r}),y=P.expandHome(g,r.meta?.cwd),_=(t=T(r.flags?.quality),{outPath:y,clientOutPath:r.meta?.clientArtifactPaths?.outPath,startedAt:Date.now(),maxSize:r.flags?.screenshotMaxSize,exportQuality:t??"medium",showTouches:r.flags?.hideTouches!==!0,gestureEvents:[]});i.mkdirSync(o.dirname(y),{recursive:!0}),i.rmSync(y,{force:!0});let v=await h.start({req:r,activeSession:s,sessionStore:n,device:c,logPath:d,deps:u,fpsFlag:l,recordingBase:_,resolvedOut:y});if("ok"in v)return v;s.recording=v,n.set(a,s);let S=n.ensureSessionDir(a);return U(n,s,r,r.command,{action:"start",showTouches:v.showTouches}),{ok:!0,data:{recording:"started",outPath:v.clientOutPath??g,sessionStateDir:S,showTouches:v.showTouches}}}async function tn(e){var t;let r,a,{req:i,activeSession:n,device:s,logPath:c,deps:d}=e;if(!n.recording)return b("INVALID_ARGS","no active recording");let u=n.recording,l=Date.now(),p=u.invalidatedReason;n.recording=void 0;let m=await function(e){let{recording:t}=e;switch(t.platform){case"android":return tt.stop({...e,recording:t});case"ios":return te.stop({...e,recording:t});case"ios-device-runner":return e7.stop({...e,recording:t});case"macos-runner":return e9.stop({...e,recording:t});case"web":return e6.stop({...e,recording:t})}return t}({req:i,activeSession:n,device:s,logPath:c,deps:d,recording:u,stopRequestedAt:l});if(m)return m;if(p&&"ios"===u.platform&&u.showTouches)u.overlayWarning??=`overlay unavailable: ${p}`;else if(p)return b("COMMAND_FAILED",p);return r="android"===(t=u).platform?t.chunks:void 0,a=[{field:"outPath",path:t.outPath,localPath:t.clientOutPath,fileName:o.basename(t.clientOutPath??t.outPath)}],r&&r.length>1&&a.push(...r.slice(1).map(e=>({field:"chunkPath",path:e.path,localPath:ts(t,e.index),fileName:o.basename(ts(t,e.index)??e.path)}))),t.telemetryPath&&a.push({field:"telemetryPath",path:t.telemetryPath,localPath:function(e){if(e.clientOutPath)return er(e.clientOutPath)}(t),fileName:o.basename(t.telemetryPath)}),{ok:!0,data:{recording:"stopped",outPath:t.outPath,telemetryPath:t.telemetryPath,artifacts:a,showTouches:t.showTouches,warning:t.warning,overlayWarning:t.overlayWarning,chunks:r?.map(e=>({index:e.index,path:ts(t,e.index)??e.path}))}}}function ts(e,t){if("android"===e.platform&&e.clientOutPath)return eh(e.clientOutPath,t)}async function tc(e,t,r,a={}){if(!r.recordOnlySession)return;let i=e8(r.device);await i.cleanupRecordOnlySession?.(r),a.writeLog&&e.writeSessionLog(r),e.delete(t)}async function td(e){let{req:t,sessionName:r,sessionStore:a,logPath:i}=e,o={runCmd:async(e,t,r)=>"xcrun"===e?await _(t,r):await p(e,t,r),startIosSimulatorRecording:e=>F().startIosSimulatorRecording(e),runAppleRunnerCommand:I,waitForRecordingTail:ti,waitForStableFile:J,isPlayableVideo:X,trimRecordingStart:es,resizeRecording:ed,overlayRecordingTouches:ec},n=a.get(r),s=n?.device??await R(t.flags??{});n||await E(s);let c=n??{name:C(t),sessionScope:M(t),device:s,createdAt:Date.now(),recordOnlySession:!0,actions:[]},d=(t.positionals?.[0]??"").toLowerCase();if(!["start","stop"].includes(d))return b("INVALID_ARGS","record requires start|stop");if("start"===d)return to({req:t,sessionName:r,sessionStore:a,activeSession:c,device:s,logPath:i,deps:o});let u=await tn({req:t,activeSession:c,device:s,logPath:i,deps:o});return u.ok?(U(a,c,t,t.command,{action:"stop",outPath:u.data?.outPath,showTouches:u.data?.showTouches}),await tc(a,r,c,{writeLog:!0})):await tc(a,r,c),u}export{td as handleRecordCommand};
|
|
23
|
+
exit(exitCode)`,cacheName:`video-validator`,timeoutMs:3e4});try{return await w}catch(e){throw w=void 0,e}}function Ae(t){return t instanceof e?t.code===`TOOL_MISSING`?!0:Me(String(t.details?.stderr??``),String(t.details?.stdout??``)):!1}async function je(e,t={}){let n=t.pollMs??150,r=t.attempts??12;for(let t=0;t<r;t+=1){if(await Oe(e))return;await d(n)}}function Me(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 Ne(e){try{let t=y.statSync(e);if(!t.isFile()||t.size<=0)return!1}catch{return!1}let t=Pe(e);return t.includes(`ftyp`)&&t.includes(`moov`)}function Pe(e){try{let t=y.openSync(e,`r`);try{let e=y.fstatSync(t).size,n=0,r=[];for(;n+8<=e&&r.length<16;){let e=Buffer.alloc(8);if(y.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(y.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{y.closeSync(t)}}catch{return[]}}function Fe(e){let t=b.parse(e);return b.join(t.dir,`${t.name}.gesture-telemetry.json`)}function Ie(e,t){return Le(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 Le(e){return[...e].sort((e,t)=>e.tMs-t.tMs)}function Re(e){let t=Fe(e.videoPath),n={version:1,generatedAt:new Date().toISOString(),events:Ie(e.events,e.trimStartMs??0)};return y.writeFileSync(t,JSON.stringify(n,null,2)),t}function ze(e){let{recording:t,trimStartMs:n}=e,r=Re({videoPath:t.outPath,events:t.gestureEvents,trimStartMs:n});return t.telemetryPath=r,r}function Be(e,t,n,r){let i=`apple-runner/AgentDeviceRunner/RecordingScripts/${e}`,a=`dist/${i}`;return[b.resolve(t,e),b.resolve(n,i),b.resolve(t,`../${i}`),b.resolve(t,`../../${i}`),b.resolve(t,`../../../${i}`),b.resolve(n,a),b.resolve(r,i)]}function T(t){let n=Be(t,b.dirname(be(import.meta.url)),u(),process.cwd());for(let e of n)if(y.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 Ve,He,Ue;function We(e=process.platform){if(e!==`darwin`)return`touch overlay burn-in is only available on macOS hosts; returning raw video plus gesture telemetry`}function Ge(){return Ve??=T(`recording-overlay.swift`),Ve}function Ke(){return He??=T(`recording-trim.swift`),He}function qe(){return Ue??=T(`recording-resize.swift`),Ue}async function E(t){let{videoPath:n,scriptPath:r,scriptArgs:i,commandDescription:o}=t;await De(n),await je(n);let s=Je(n);try{await a(await xe({sourcePath:r}),[`--input`,n,`--output`,s,...i],{timeoutMs:12e4,env:x()}),await je(s),y.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{y.rmSync(s,{force:!0})}}function Je(e){let t=b.parse(e),n=`${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2)}`;return b.join(t.dir,`.${t.name}.agent-device-${n}${t.ext||`.mp4`}`)}async function Ye(e){let{videoPath:t,trimStartMs:n}=e;n>0&&await E({videoPath:t,scriptPath:Ke(),scriptArgs:[`--trim-start-ms`,String(n)],commandDescription:`Failed to trim the start of the iOS recording`})}async function Xe(e){let{videoPath:t,telemetryPath:n,exportQuality:r=ee,targetLabel:i=`recording`}=e;await E({videoPath:t,scriptPath:Ge(),scriptArgs:[`--events`,n,`--quality`,r],commandDescription:`Failed to add touch overlays to the ${i}`})}async function Ze(e){let{videoPath:t,maxSize:n,exportQuality:r=ee,targetLabel:i=`recording`}=e;await E({videoPath:t,scriptPath:qe(),scriptArgs:[`--max-size`,String(n),`--quality`,r],commandDescription:`Failed to resize the ${i}`})}function D(e){return e instanceof Error?e.message:String(e)}const Qe=1e3;function O(e,t){return e.stderr.trim()||e.stdout.trim()||`${t} exited with code ${e.exitCode}`}function $e(e,t,n=Date.now()){let r=Math.max(0,n-t.startedAt);return r>=Qe?{message:e,tooShort:!1}:{message:`${e}. Recording stopped after ${Math.round(r)}ms; wait at least ${Qe}ms between record start and record stop so the recorder can finalize a playable MP4`,tooShort:!0}}async function k(e){let{recording:t,deps:i,trimStartMs:a,targetLabel:o}=e,s=ze({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=We();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: ${D(e)}`}}function A(e,t){if(t===1)return e;let n=b.parse(e),r=n.ext||`.mp4`;return b.join(n.dir,`${n.name}.part-${String(t).padStart(3,`0`)}${r}`)}function j(e){return e.chunks??=[{index:1,path:e.outPath,remotePath:e.remotePath}],e.chunks}function et(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 tt(e){let{recording:t,startNextChunk:n,finishCurrentChunk:r,cleanupStartedChunk:i,persistRecordingState:a}=e,o=setTimeout(()=>{t.rotationPromise=nt({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&&tt({recording:t,startNextChunk:n,finishCurrentChunk:r,cleanupStartedChunk:i,persistRecordingState:a})})},17e4);o.unref?.(),t.rotationTimer=o}async function nt(e){let{recording:t,startNextChunk:n,finishCurrentChunk:r,cleanupStartedChunk:i,persistRecordingState:a}=e;if(t.stopping)return;let o=j(t),s=o.length+1,c={remotePath:t.remotePath,remotePid:t.remotePid,startedAt:t.remoteStartedAt??t.startedAt},l=await rt({recording:t,nextIndex:s,previousChunk:c,startNextChunk:n,finishCurrentChunk:r});if(!l)return;let{nextChunk:u,previousChunkFinished:d}=l;await at({recording:t,chunks:o,nextChunk:u,nextIndex:s,previousState:it({recording:t,nextChunk:u}),finishCurrentChunk:r,cleanupStartedChunk:i,persistRecordingState:a}),!d&&await st(r,c)}async function rt(e){let{recording:t,nextIndex:n,previousChunk:r,startNextChunk:i,finishCurrentChunk:a}=e,o=b.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 it(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 at(e){let{recording:t,chunks:n,nextChunk:r,nextIndex:i,previousState:a,finishCurrentChunk:o,cleanupStartedChunk:s,persistRecordingState:c}=e;n.push({index:i,path:A(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 ot({recording:t,chunks:n,previousState:a}),await ct({nextChunk:r,finishCurrentChunk:o,cleanupStartedChunk:s})||e}}function ot(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 st(e,t){let n=await e(t);if(n)throw Error(n)}async function ct(e){let{nextChunk:t,finishCurrentChunk:n,cleanupStartedChunk:r}=e,i;try{await st(n,t)}catch(e){i=e}try{await r?.(t)}catch(e){i??=e}return i}async function lt(e){let{recording:t,deps:n}=e;if(j(t).length<=1){await k({recording:t,deps:n,targetLabel:`Android recording`});return}ze({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 ut(e){for(let t of e.chunks){let n=await dt({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 dt(e){let{deps:t,deviceId:n,remotePath:a,outPath:o}=e,s;for(let e=0;e<2;e+=1){pt(o);let c=await i(a,o,{allowFailure:!0,device:te(n)});if(c.exitCode!==0)s=O(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:ft(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 d(750)}return s?`failed to copy recording from device: ${s}`:(pt(o),`failed to copy recording from device: pulled file is not a playable MP4`)}function ft(e){try{return y.statSync(e).size}catch{return 0}}function pt(e){try{y.rmSync(e,{force:!0})}catch{}}const mt=`agent-device-recording-active.json`,ht=[`/sdcard`,`/data/local/tmp`];function gt(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 _t(e){let t=Ct(e);if(!t)return{kind:`delete`};let n=Tt(t);if(!n)return{kind:`blocked`,reason:`unsupported_or_malformed_manifest`};let r=Dt(t.current),i=Ot(t.pending),a=kt(t.chunks);return a?!r&&!i?{kind:`blocked`,reason:`invalid_recording_state`}:{kind:`manifest`,manifest:{...n,sessionScope:jt(t.sessionScope),current:r,pending:i,chunks:a}}:{kind:`blocked`,reason:`invalid_recording_chunks`}}function vt(e){return`${b.posix.dirname(e)}/${mt}`}function M(){return ht.map(e=>`${e}/${mt}`)}function yt(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 bt(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:St(i)}}function xt(e){let{deviceId:t,sessionName:n,sessionScope:r,recording:i,nextRemotePath:a,nextIndex:o}=e;return{...bt({deviceId:t,sessionName:n,sessionScope:r,recording:i}),pending:{remotePath:a},chunks:St(i,{index:o,remotePath:a})}}function St(e,t){return[...e.chunks??[{index:1,remotePath:e.remotePath}],...t?[t]:[]].map(e=>({index:e.index,remotePath:e.remotePath}))}function Ct(e){try{let t=JSON.parse(e);return wt(t)?t:void 0}catch{return}}function wt(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Tt(e){if(e.version!==1)return;let t=Et(e);if(!t)return;let n=Mt(e.startedAt);if(n===void 0)return;let r=Nt(e.showTouches);if(r!==void 0)return{version:1,...t,startedAt:n,showTouches:r}}function Et(e){let t=N(e.sessionName),n=N(e.recordingId),r=N(e.deviceId);if(!(!t||!n||!r))return{sessionName:t,recordingId:n,deviceId:r}}function Dt(e){if(!e||typeof e!=`object`)return;let t=e;if(!(typeof t.remotePid!=`string`||!/^\d+$/.test(t.remotePid)||typeof t.remotePath!=`string`||!P(t.remotePath)))return{remotePid:t.remotePid,remotePath:t.remotePath,startedAt:typeof t.startedAt==`number`&&Number.isFinite(t.startedAt)?t.startedAt:Date.now()}}function Ot(e){if(!e||typeof e!=`object`)return;let t=e;if(!(typeof t.remotePath!=`string`||!P(t.remotePath)))return{remotePath:t.remotePath}}function kt(e){if(!Array.isArray(e))return;let t=e.map(At).filter(e=>e!==void 0);return t.length>0&&t.length===e.length?t:void 0}function At(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`||!P(t.remotePath)))return{index:t.index,remotePath:t.remotePath}}function jt(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 N(e){return typeof e==`string`?e:void 0}function Mt(e){return typeof e==`number`&&Number.isFinite(e)?e:void 0}function Nt(e){return typeof e==`boolean`?e:void 0}function P(e){return/^\/(?:sdcard|data\/local\/tmp)\/agent-device-recording-\d+\.mp4$/.test(e)}const Pt=`Recovered Android recording after daemon restart from durable device manifest.`,Ft=`touch overlay burn-in is unavailable after daemon restart because gesture telemetry is stored in daemon memory`,It=`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 ne(te(e),t,n)}async function Lt(e){let t={live:[],uncertain:[],blocked:[]};for(let n of M()){let r=await L(e,[`shell`,`cat`,n],{allowFailure:!0,timeoutMs:I});if(r.exitCode!==0)continue;let i=_t(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 Rt(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 Rt(e,t){return t.pending?await zt(e,t,t.pending):await Ut(e,t)}async function zt(e,t,n){let r=await Gt(e,n.remotePath);return Vt(t,r)||(t.current?await Bt(e,t,t.current,r):await Ht(e,t,n.remotePath,r))}async function Bt(e,t,n,r){let i=await Wt(e,n);return i===`uncertain`||r===`uncertain`?{kind:`uncertain`}:i===`stale`?{kind:`stale`}:R({manifest:t,current:n,chunks:qt(t.chunks,n.remotePath),recoveryWarning:i===`finished`?`${F} ${It}`:F})}function Vt(e,t){if(!(!t||t===`uncertain`))return R({manifest:e,current:t,recoveryWarning:e.current?F:Pt})}async function Ht(e,t,n,r){return r===`uncertain`?{kind:`uncertain`}:await Kt(e,n)?R({manifest:t,current:{remotePath:n,remotePid:``,startedAt:t.startedAt},recoveryWarning:It}):{kind:`stale`}}async function Ut(e,t){if(!t.current)return{kind:`stale`};let n=await Wt(e,t.current);return n===`live`?R({manifest:t,current:t.current}):n===`finished`?R({manifest:t,current:t.current,recoveryWarning:It}):{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 Wt(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(gt).some(e=>e?.remotePid===t.remotePid&&e.remotePath===t.remotePath)?`live`:a?.includes(`screenrecord`)?`uncertain`:a?`stale`:await Kt(e,t.remotePath)?`finished`:`stale`}async function Gt(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(gt).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 Kt(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 qt(e,t){let n=e.findIndex(e=>e.remotePath===t);return n>=0?e.slice(0,n+1):e}async function Jt(e){let{deviceId:t,sessionName:n,sessionScope:r,recordingId:i,startedAt:a,showTouches:o,remotePath:s}=e;return await B({deviceId:t,manifest:yt({deviceId:t,sessionName:n,sessionScope:r,recordingId:i,startedAt:a,showTouches:o,remotePath:s}),phase:`record_start_android_recovery_metadata_failed`})}async function Yt(e){let{deviceId:t,sessionName:n,sessionScope:r,recording:i,nextRemotePath:a,nextIndex:o}=e;return await B({deviceId:t,manifest:xt({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:bt({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=vt(i),o=`${a}.tmp`,s=await L(t,[`shell`,`printf %s ${l(JSON.stringify(n))} > ${l(o)} && mv -f ${l(o)} ${l(a)}`],{allowFailure:!0,timeoutMs:I});if(s.exitCode!==0)return Xt({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: ${O(s,`adb shell write recovery manifest`)}`;for(let e of M())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 M())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&&Xt({phase:r,deviceId:t,metadataPath:n,result:i})}function Xt(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 Zt(e){let{sessionName:t,activeSession:n,device:r,recordingBase:i}=e,a=await Lt(r.id);return a.live.length>0?en({sessionName:t,activeSession:n,device:r,recordingBase:i,manifests:a.live}):a.uncertain.length>0?Qt({sessionName:t,activeSession:n,manifests:a.uncertain}):a.blocked.length>0?$t(a.blocked):null}function Qt(e){let{sessionName:t,activeSession:n,manifests:r}=e,i=nn({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`?_(`INVALID_ARGS`,ln(r),a):i.kind===`ambiguous`?_(`INVALID_ARGS`,`multiple active Android recording manifests could not be verified; cannot safely recover missing recording state`,a):_(`INVALID_ARGS`,`active Android recording manifest could not be verified; retry record stop after the device responds`,a)}function $t(e){return _(`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 en(e){let{sessionName:t,activeSession:n,device:r,recordingBase:i,manifests:a}=e,o=tn({sessionName:t,activeSession:n,manifests:a});return`ok`in o?o:(an(r,o),on(o,i))}function tn(e){let{sessionName:t,activeSession:n,manifests:r}=e,i=nn({sessionName:t,activeSession:n,manifests:r});return i.kind===`selected`?i.manifest:i.kind===`owner-mismatch`?_(`INVALID_ARGS`,ln(r),{activeRecordings:i.activeRecordings}):_(`INVALID_ARGS`,`multiple active Android recording manifests exist; cannot safely recover missing recording state`,{activeRecordings:i.activeRecordings})}function nn(e){let{sessionName:t,activeSession:n,manifests:r}=e,i=r.filter(e=>sn(e,t,n)),a=rn(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 rn(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 an(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 on(e,t){let n=e.recoveryWarning??Pt;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:A(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} ${Ft}.`:n,overlayWarning:e.showTouches?Ft:void 0}}function sn(e,t,n){return e.sessionName===t&&cn(e.sessionScope,n.sessionScope)}function cn(e,t){return!e&&!t?!0:!e||!t?!1:e.kind===t.kind&&e.id===t.id}function ln(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 un={medium:8e6,high:2e7},U=5e3;async function W(e,t,n){return await ne(te(e),t,n)}function dn(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 fn(e,t){for(let n=0;n<40;n+=1){if(!await G(e,t))return!0;await d(250)}return!await G(e,t)}async function pn(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 d(250)}}async function mn(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 d(250)}return!1}function hn(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 gn(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: ${O(r,`adb shell wm size`)}`);return _n({width:Number(i[1]),height:Number(i[2]),maxSize:n})}function _n(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:vn(e.width,n),height:vn(e.height,n)}}function vn(e,t){return Math.max(2,Math.round(e*t/2)*2)}function yn(e,t,n){let r=[`screenrecord`];return t&&r.push(`--size`,`${t.width}x${t.height}`),r.push(`--bit-rate`,String(un[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 fn(e,t)}async function bn(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 hn(Date.now(),i)){let i=await xn({device:t,recordingSize:n,quality:r,remotePath:e,hooks:a});if(i.kind===`started`)return i.chunk;o=i.message}return{error:_(`COMMAND_FAILED`,o)}}async function xn(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`,yn(a,n,i)],{allowFailure:!0,timeoutMs:U});if(c.exitCode!==0)return await o?.cleanupPreparedRemotePath?.(a),{kind:`failed`,message:`failed to start recording: ${O(c,`adb shell screenrecord`)}`};let l=dn(c.stdout);return l?(r({level:`debug`,phase:`record_start_android_started`,data:{deviceId:t.id,remotePath:a,remotePid:l}}),await mn(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 Sn(e){let{sessionName:t,activeSession:n,device:r,recordingBase:i}=e,a;try{a=await gn({deviceId:r.id,maxSize:i.maxSize})}catch(e){return _(`COMMAND_FAILED`,e instanceof Error?e.message:String(e))}let o=i.exportQuality??`medium`,s=ve(),c=await bn({device:r,recordingSize:a,quality:o,hooks:{prepareRemotePath:async e=>await Jt({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=Cn({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),_(`COMMAND_FAILED`,`failed to start recording: ${u}`)):(wn({activeSession:n,sessionName:t,device:r,recording:l,recordingSize:a,quality:o}),l)}function Cn(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 wn(e){let{activeSession:t,sessionName:n,device:r,recording:i,recordingSize:a,quality:o}=e;tt({recording:i,finishCurrentChunk:async e=>await Tn({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 bn({device:r,recordingSize:a,quality:o,preferredRemoteDir:e,hooks:{prepareRemotePath:async e=>await Yt({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 Tn(e){let{device:t,recording:n,remotePath:i=n.remotePath,remotePid:a=n.remotePid,waitForRemoteFileStability:o=!0}=e;if(!a){Pn(n,et(n)),o&&await pn(t.id,i);return}await G(t.id,a)||Pn(n,et(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 En(t.id,a,s);let c=await Dn(t.id,a);if(c)return c;o&&await pn(t.id,i)}async function En(e,t,n){if(await G(e,t)&&!await q(e,t))return`failed to stop recording: ${O(n,`adb shell kill`)}`}async function Dn(e,t){if(!await fn(e,t)&&!await q(e,t))return`failed to stop recording: Android screenrecord pid ${t} did not exit`}async function On(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 kn(i);let o=await Tn({device:n,recording:i});i.rotationFailedReason&&!o&&(i.warning??=`Android recording chunk rotation failed: ${i.rotationFailedReason}`);let s=o===void 0?await An({deps:t,device:n,recording:i}):void 0,c=await jn({deviceId:n.id,recording:i,recordCleanupError:o===void 0});return s?_(`COMMAND_FAILED`,Nn(s,i,a)):o?_(`COMMAND_FAILED`,Nn(o,i,a)):c?_(`COMMAND_FAILED`,c):null}async function kn(e){e.rotationTimer&&=(clearTimeout(e.rotationTimer),void 0),await e.rotationPromise}async function An(e){let{deps:t,device:n,recording:r}=e,i=await ut({deps:t,deviceId:n.id,chunks:j(r)});if(i)return i;await lt({recording:r,deps:t})}async function jn(e){let{deviceId:t,recording:n,recordCleanupError:r}=e,i;for(let e of j(n)){let n=await Mn(t,e.remotePath);n&&r&&(i=n)}return await V(t),i}async function Mn(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: ${O(n,`adb shell rm`)}`}function Nn(e,t,n){return $e(e,t,n).message}function Pn(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 Fn(e){return D(e).toLowerCase().includes(`recording already in progress`)}function In(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 me({req:e,logPath:t,traceLogPath:n.trace?.outPath})}function Ln(e){return typeof e.runnerStartedAtUptimeMs!=`number`||typeof e.targetAppReadyUptimeMs!=`number`?0:Math.max(0,e.targetAppReadyUptimeMs-e.runnerStartedAtUptimeMs)}async function Rn(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:D(e)}})}}async function zn(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:D(e)}});return}}async function Bn(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(!Fn(e))return _(`COMMAND_FAILED`,`failed to start recording: ${D(e)}`);r({level:`warn`,phase:`record_start_runner_desynced`,data:{platform:a.platform,kind:a.kind,deviceId:a.id,session:n.name,error:D(e)}});let t=In(i,a.id,n.name);if(t)return _(`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 _(`COMMAND_FAILED`,`failed to start recording: ${D(e)}`)}}return{platform:`ios-device-runner`,remotePath:f,runnerStartedAtUptimeMs:m,targetAppReadyUptimeMs:h,...l}}async function Vn(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 _(`COMMAND_FAILED`,`failed to start recording: ${D(e)}`)}return{platform:`macos-runner`,...s}}async function Hn(e){let{req:t,activeSession:n,device:r,logPath:i,deps:a,recording:o}=e;await Rn({req:t,activeSession:n,device:r,logPath:i,deps:a});let s={stdout:``,stderr:``,exitCode:1};for(let e of re)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 _(`COMMAND_FAILED`,`failed to copy recording from device: ${s.stderr.trim()||s.stdout.trim()||`devicectl exited with code ${s.exitCode}`}`);let c=Ln(o);return c>0&&await a.trimRecordingStart({videoPath:o.outPath,trimStartMs:c}),await k({recording:o,deps:a,trimStartMs:c,targetLabel:`iOS recording`}),null}async function Un(e){let{req:t,activeSession:n,device:r,logPath:i,deps:a,recording:o}=e;return await Rn({req:t,activeSession:n,device:r,logPath:i,deps:a}),await k({recording:o,deps:a,targetLabel:`macOS recording`}),null}const Wn=5e3,X=2e3;async function Gn(e){let{deps:t,recording:n}=e;n.child.kill(`SIGINT`);let r=await Z(n.wait,Wn);return r||(await Kn(t,n,`SIGINT`),r=await Z(n.wait,X),r)||(n.child.kill(`SIGTERM`),await Kn(t,n,`SIGTERM`),r=await Z(n.wait,X),r)?r:(n.child.kill(`SIGKILL`),await Kn(t,n,`SIGKILL`),await Z(n.wait,X))}async function Z(e,t){return await Promise.race([e,d(t).then(()=>null)])}async function Kn(e,t,n){await Jn(e,t,n)||await qn(e,t.outPath,n)}async function qn(e,t,n){let i=`simctl.*recordVideo.*${Zn(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:D(e)}});return}let o=f(Xn(a.stdout),{excludePid:process.pid}),s=m(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 Jn(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 Yn(e,i,t.outPath,n),o=f([i,...a.pids],{excludePid:process.pid}),s=m(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 Yn(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:D(e)}}),{pids:[]}}return{pids:Xn(a.stdout),exitCode:a.exitCode}}function Xn(e){return e.split(/\s+/).map(e=>Number(e)).filter(e=>Number.isInteger(e)&&e>0)}function Zn(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}async function Qn(e){let{req:t,activeSession:n,device:r,logPath:i,deps:a,recordingBase:o,resolvedOut:s}=e,c=o.showTouches?await zn({req:t,activeSession:n,device:r,logPath:i,deps:a}):void 0,{child:l,wait:u}=a.startIosSimulatorRecording({device:r,outPath:s}),d=await er(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 $n(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`,()=>Gn({deps:t,recording:r}),{outPath:r.outPath});if(!a)return tr(`failed to stop recording: simctl recordVideo did not exit after ${Wn}ms and forced cleanup`,r,i);if(a.exitCode!==0)return tr(`failed to stop recording: ${O(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 tr(`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: ${D(e)}`}return await n(`record_stop_finalize_overlay`,()=>k({recording:r,deps:t,targetLabel:`iOS recording`}),{outPath:r.outPath,showTouches:r.showTouches,gestureEventCount:r.gestureEvents.length}),null}async function er(e){for(let t=0;t<2;t+=1){try{if(y.statSync(e).size>0)return Date.now()}catch{}if(t+1>=2)return Date.now();await d(250)}return Date.now()}function tr(e,t,n){let r=$e(e,t,n);return nr(t.outPath),_(`COMMAND_FAILED`,r.message)}function nr(e){try{y.rmSync(e,{force:!0})}catch{}}de();function rr(e){let t=ue(e.platform)?.recording?.resolveBackendTag(e)??`unsupported`;return dr[t]}function ir(e){let{recording:t}=e;switch(t.platform){case`android`:return ur.stop({...e,recording:t});case`ios`:return lr.stop({...e,recording:t});case`ios-device-runner`:return sr.stop({...e,recording:t});case`macos-runner`:return cr.stop({...e,recording:t});case`web`:return or.stop({...e,recording:t})}return t}function Q({req:e}){return e.positionals?.[1]??s(void 0)}function ar({req:e}){let t=e.positionals?.[1];return t===void 0?s(`web`):o(t,c)}const or={validateStart:e=>pr(e),resolveOutputPath:ar,start:async({activeSession:e,recordingBase:t,resolvedOut:n})=>{let r=mr(n);if(r)return r;if(e.recordOnlySession)return _(`INVALID_ARGS`,`record on web requires an active browser session; run open <url> --platform web first`);let i=v();return i.startRecording?(await i.startRecording(n),{...t,outPath:n,startedAt:Date.now(),platform:`web`,showTouches:!1}):_(`UNSUPPORTED_OPERATION`,`record is not supported by this web provider`)},stop:async({recording:e})=>await gr({recording:e}),cleanupRecordOnlySession:async()=>{try{await v().close()}catch{}}},sr={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 Bn({req:e,activeSession:t,sessionStore:n,device:r,logPath:i,deps:a,fpsFlag:o,recordingBase:s,appBundleId:c}):_(`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 Hn({req:e,activeSession:t,device:n,logPath:r,deps:i,recording:a})},cr={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 Vn({req:e,activeSession:t,device:n,logPath:r,deps:i,fpsFlag:a,recordingBase:o,appBundleId:s}):_(`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 Un({req:e,activeSession:t,device:n,logPath:r,deps:i,recording:a})},lr={resolveOutputPath:Q,start:async({req:e,activeSession:t,device:n,logPath:r,deps:i,recordingBase:a,resolvedOut:o})=>await Qn({req:e,activeSession:t,device:n,logPath:r,deps:i,recordingBase:a,resolvedOut:o}),stop:async({deps:e,recording:t,stopRequestedAt:n})=>await $n({deps:e,recording:t,stopRequestedAt:n})},ur={resolveOutputPath:Q,start:async({sessionName:e,activeSession:t,device:n,recordingBase:r})=>await Sn({sessionName:e,activeSession:t,device:n,recordingBase:r}),recoverMissingStop:async({sessionName:e,activeSession:t,device:n,recordingBase:r})=>await Zt({sessionName:e,activeSession:t,device:n,recordingBase:r}),stop:async({deps:e,device:t,recording:n,stopRequestedAt:r})=>await On({deps:e,device:t,recording:n,stopRequestedAt:r})},dr={web:or,android:ur,macos:cr,"ios-device":sr,"ios-simulator":lr,unsupported:{resolveOutputPath:Q,start:async()=>_(`UNSUPPORTED_OPERATION`,`record is not supported on this device`),stop:async()=>_(`UNSUPPORTED_OPERATION`,`record is not supported on this device`)}};function fr(e){let t=[];return e.flags?.fps!==void 0&&t.push(`--fps`),e.flags?.quality!==void 0&&t.push(`--quality`),e.flags?.screenshotMaxSize!==void 0&&t.push(`--max-size`),e.flags?.hideTouches!==void 0&&t.push(`--hide-touches`),t}function pr(e){let t=fr(e);return t.length>0?_(`INVALID_ARGS`,`web recordings do not support ${t.join(`, `)}; agent-browser records WebM directly`):null}function mr(e){return b.extname(e).toLowerCase()===`.webm`?null:_(`INVALID_ARGS`,`web recordings must use a ${c} output path`)}function hr(e){try{y.rmSync(e,{force:!0})}catch{}}async function gr(e){let{recording:t}=e,n=v();return n.stopRecording?(await n.stopRecording(),_r(t.outPath)?null:(hr(t.outPath),_(`COMMAND_FAILED`,`failed to stop recording: ${t.outPath} was not finalized into a WebM video`))):_(`UNSUPPORTED_OPERATION`,`record is not supported by this web provider`)}function _r(e){try{return y.statSync(e).size>0}catch{return!1}}function vr(){return{runCmd:async(e,t,n)=>e===`xcrun`?await ae(t,n):await a(e,t,n),startIosSimulatorRecording:e=>ge().startIosSimulatorRecording(e),runAppleRunnerCommand:ie,waitForRecordingTail:yr,waitForStableFile:De,isPlayableVideo:Oe,trimRecordingStart:Ye,resizeRecording:Ze,overlayRecordingTouches:Xe}}async function yr(e){e.platform===`ios`&&e.gestureEvents.length!==0&&await d(350)}function br(e,t){let n=h(e.flags?.quality);return{outPath:t,clientOutPath:e.meta?.clientArtifactPaths?.outPath,startedAt:Date.now(),maxSize:e.flags?.screenshotMaxSize,exportQuality:n??`medium`,showTouches:e.flags?.hideTouches!==!0,gestureEvents:[]}}async function xr(e){let{req:t,sessionName:n,sessionStore:r,activeSession:i,device:a,logPath:o,deps:s}=e,c=Sr(e);return`backend`in c?wr({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 Sr(e){let{req:t,activeSession:n,device:r}=e,i=rr(r);return Cr({req:t,activeSession:n,device:r,backend:i})||{...Ar(t,i),backend:i,fpsFlag:t.flags?.fps}}function Cr(e){let{req:t,activeSession:n,device:r,backend:i}=e,a=[()=>Tr(n),()=>i.validateStart?.(t)??null,()=>Er({fpsFlag:t.flags?.fps,qualityFlag:t.flags?.quality,maxSizeFlag:t.flags?.screenshotMaxSize}),()=>se(`record`,r)];for(let e of a){let t=e();if(t)return t}return null}function wr(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 he(r,i,t,t.command,{action:`start`,showTouches:a.showTouches}),{ok:!0,data:{recording:`started`,outPath:a.clientOutPath??o,sessionStateDir:s,showTouches:a.showTouches}}}function Tr(e){return e.recording?_(`INVALID_ARGS`,`recording already in progress`):null}function Er(e){let{fpsFlag:t,qualityFlag:n,maxSizeFlag:r}=e;return Dr(t)??Or(n)??kr(r)}function Dr(e){return e!==void 0&&(!Number.isInteger(e)||e<1||e>120)?_(`INVALID_ARGS`,`fps must be an integer between 1 and 120`):null}function Or(e){return e!==void 0&&h(e)===void 0?_(`INVALID_ARGS`,`quality must be one of: ${g.join(`, `)} (legacy numeric values 5-10 are accepted)`):null}function kr(e){return e!==void 0&&(!Number.isInteger(e)||e<1)?_(`INVALID_ARGS`,`max-size must be a positive integer`):null}function Ar(e,t){let n=t.resolveOutputPath({req:e}),r=fe.expandHome(n,e.meta?.cwd),i=br(e,r);return y.mkdirSync(b.dirname(r),{recursive:!0}),y.rmSync(r,{force:!0}),{outPath:n,resolvedOut:r,recordingBase:i}}async function jr(e){let{req:t,activeSession:n,device:r,logPath:i,deps:a}=e,o=await Mr(e);if(o&&`ok`in o)return o;if(!o)return _(`INVALID_ARGS`,`no active recording`);let s=Date.now(),c=o.invalidatedReason;return n.recording=void 0,await ir({req:t,activeSession:n,device:r,logPath:i,deps:a,recording:o,stopRequestedAt:s})||Ir(o,c)||Rr(o)}async function Mr(e){return e.activeSession.recording?e.activeSession.recording:await Nr(e)}async function Nr(e){let{req:t,sessionName:n,sessionStore:r,activeSession:i,device:a,logPath:o,deps:s}=e;if(Lr(r,a.id))return null;let c=rr(a);if(!c.recoverMissingStop)return null;let{resolvedOut:l,recordingBase:u}=Pr(t,c),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||Fr(l),d):null}function Pr(e,t){let n=t.resolveOutputPath({req:e}),r=fe.expandHome(n,e.meta?.cwd);return{resolvedOut:r,recordingBase:br(e,r)}}function Fr(e){y.mkdirSync(b.dirname(e),{recursive:!0}),y.rmSync(e,{force:!0})}function Ir(e,t){return t?e.platform===`ios`&&e.showTouches?(e.overlayWarning??=`overlay unavailable: ${t}`,null):_(`COMMAND_FAILED`,t):null}function Lr(e,t){for(let n of e.values())if(n.recording&&n.device.id===t)return!0;return!1}function Rr(e){let t=e.platform===`android`?e.chunks:void 0,n=[{field:`outPath`,artifactType:`screen-recording`,path:e.outPath,localPath:e.clientOutPath,fileName:b.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:b.basename($(e,t.index)??t.path)}))),e.telemetryPath&&n.push({field:`telemetryPath`,artifactType:`screen-recording-telemetry`,path:e.telemetryPath,localPath:zr(e),fileName:b.basename(e.telemetryPath)}),{ok:!0,data:{recording:`stopped`,outPath:e.outPath,telemetryPath:e.telemetryPath,artifacts:n,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 A(e.clientOutPath,t)}function zr(e){if(e.clientOutPath)return Fe(e.clientOutPath)}async function Br(e,t,n,r={}){n.recordOnlySession&&(await rr(n.device).cleanupRecordOnlySession?.(n),r.writeLog&&e.writeSessionLog(n),e.delete(t))}async function Vr(e){let{req:t,sessionName:n,sessionStore:r,logPath:i}=e,a=vr(),o=r.get(n),s=o?.device??await ce(t.flags??{});o||await pe(s);let c=o??{name:n,sessionScope:le(t),device:s,createdAt:Date.now(),recordOnlySession:!0,actions:[]},l=(t.positionals?.[0]??``).toLowerCase();if(![`start`,`stop`].includes(l))return _(`INVALID_ARGS`,`record requires start|stop`);if(l===`start`)return xr({req:t,sessionName:n,sessionStore:r,activeSession:c,device:s,logPath:i,deps:a});let u=await jr({req:t,sessionName:n,sessionStore:r,activeSession:c,device:s,logPath:i,deps:a});return u.ok?(he(r,c,t,t.command,{action:`stop`,outPath:u.data?.outPath,showTouches:u.data?.showTouches}),await Br(r,n,c,{writeLog:!0}),u):(await Br(r,n,c),u)}export{Vr as t};
|
package/dist/src/record-trace.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import{Xt as e,vn as t}from"./internal/daemon.js";import{t as n}from"./handler-utils.js";import{t as r}from"./record-trace-recording.js";import i from"node:fs";import a from"node:path";async function o(o){let{req:s,sessionName:c,sessionStore:l,logPath:u}=o,d=s.command;if(d===`record`)return r({req:s,sessionName:c,sessionStore:l,logPath:u});if(d===`trace`){let r=(s.positionals?.[0]??``).toLowerCase();if(![`start`,`stop`].includes(r))return e(`INVALID_ARGS`,`trace requires start|stop`);let o=l.get(c);if(!o)return e(`SESSION_NOT_FOUND`,`No active session`);if(r===`start`){if(o.trace)return e(`INVALID_ARGS`,`trace already in progress`);let r=s.positionals?.[1]??l.defaultTracePath(o),c=t.expandHome(r);return i.mkdirSync(a.dirname(c),{recursive:!0}),i.appendFileSync(c,``),o.trace={outPath:c,startedAt:Date.now()},n(l,o,s,d,{action:`start`,outPath:c}),{ok:!0,data:{trace:`started`,outPath:c}}}if(!o.trace)return e(`INVALID_ARGS`,`no active trace`);let u=o.trace.outPath;if(s.positionals?.[1]){let e=t.expandHome(s.positionals[1]);i.mkdirSync(a.dirname(e),{recursive:!0}),i.existsSync(u)?i.renameSync(u,e):i.appendFileSync(e,``),u=e}return o.trace=void 0,n(l,o,s,d,{action:`stop`,outPath:u}),{ok:!0,data:{trace:`stopped`,outPath:u}}}return null}export{o as handleRecordTraceCommands};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
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};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import{F as e,d as t,f as n,g as r,l as i,n as a,s as o,t as s}from"./sdk-contracts.js";import{C as c,d as ee,h as te,o as ne,r as re,u as ie,v as ae,w as l,x as oe,y as se}from"./sdk-batch.js";import{$ as ce,$t as le,An as ue,At as de,Bt as fe,Dt as pe,Ft as me,In as he,Jt as ge,Lt as _e,Mt as ve,Nt as ye,Pt as be,Q as xe,Qt as Se,Rt as Ce,Ut as we,Vt as Te,Wt as Ee,Yt as De,Z as Oe,c as ke,en as Ae,hn as je,i as Me,in as Ne,jn as Pe,jt as Fe,kn as Ie,kt as Le,l as Re,ln as ze,mn as Be,mt as Ve,n as He,nn as Ue,o as We,pn as Ge,qt as Ke,rn as qe,s as Je,t as Ye,tn as Xe,u as Ze,un as Qe,ut as $e,vt as et,wn as tt,wt as nt,xn as rt,xt as it,zt as at}from"./device-rotation.js";import{R as ot,n as st,o as ct,r as lt}from"./sdk-selectors.js";import{_ as ut,a as dt,b as ft,c as pt,f as mt,g as ht,h as gt,i as _t,l as u,m as d,o as vt,p as yt,r as bt,s as xt,v as St}from"./sdk-batch-runner.js";import{n as Ct}from"./sdk-finders.js";import{n as wt,t as Tt}from"./sdk-app-inventory.js";let Et=!1;function Dt(){Et=!0}function Ot(){let e=Et;return Et=!1,e}const kt=[`ref`,`selector`,`point`];function At(e,t=[]){return{type:`object`,properties:{...gn(),...e},...t.length>0?{required:t}:{},additionalProperties:!1}}function jt(e){return{type:`object`,description:e,properties:{x:{type:`number`},y:{type:`number`}},required:[`x`,`y`],additionalProperties:!1}}function Mt(e,t){return{type:`string`,enum:e,...t?{description:t}:{}}}function Nt(e){return{type:`string`,...e?{description:e}:{}}}function Pt(e){return{type:`number`,...e?{description:e}:{}}}function Ft(e){return{type:`integer`,...e?{description:e}:{}}}function It(e){return{type:`boolean`,...e?{description:e}:{}}}function Lt(e){return{type:`array`,items:{type:`string`},...e?{description:e}:{}}}function Rt(e){return{type:`object`,additionalProperties:!0,...e?{description:e}:{}}}function f(e){return{...e,required:!0}}function p(e){return T(Nt(e),b)}function m(e){return T(Pt(e),tn)}function h(e,t={}){return T(dn(e,t),(e,n)=>S(e,n,t))}function g(e){return T(It(e),nn)}function _(e,t){return T(Mt(e,t),(t,n)=>an(t,n,e))}function zt(e){return T(Rt(e),mn)}function Bt(e){return T(Lt(e),hn)}function v(e){return T(e,(e,t)=>e[t])}function Vt(e,t){return T(e,t)}function Ht(){return T(_n(),(e,t)=>e[t]===void 0?void 0:Qt(e,t))}function Ut(){return T(vn(),(e,t)=>e[t]===void 0?void 0:$t(e,t))}function Wt(e){return T(jt(e),(e,t)=>e[t]===void 0?void 0:y(e,t))}function Gt(){return{depth:h(`Snapshot traversal depth.`,{min:0}),scope:p(`Snapshot scope selector used before resolution.`),raw:g(`Use raw snapshot data during selector resolution.`)}}function Kt(){return{count:h(`Number of press/click repetitions.`,{min:1}),intervalMs:h(`Delay between repeated press/click actions.`,{min:0}),holdMs:h(`Hold duration for each action.`,{min:0}),jitterPx:h(`Randomization radius in pixels.`,{min:0}),doubleTap:g(`Request a double-tap action.`)}}function qt(e){return At(fn(e),pn(e))}function Jt(t,n){let r=Yt(t),i=Object.fromEntries(Object.entries(n).flatMap(([t,n])=>{let i=n.read(r,t);if(n.required&&i===void 0)throw new e(`INVALID_ARGS`,`Expected ${t} to be set.`);return i===void 0?[]:[[t,i]]})),a=Xt(r,{readTargetAlias:!Object.hasOwn(n,`target`)});return w({...a,...C(a),...i})}function Yt(t){if(t==null)return{};if(!t||typeof t!=`object`||Array.isArray(t))throw new e(`INVALID_ARGS`,`Expected object arguments.`);return t}function Xt(e,t={}){return{session:b(e,`session`),platform:an(e,`platform`,i),deviceTarget:Zt(e,t),device:b(e,`device`),udid:b(e,`udid`),serial:b(e,`serial`),iosSimulatorDeviceSet:b(e,`iosSimulatorDeviceSet`),iosXctestrunFile:b(e,`iosXctestrunFile`),iosXctestDerivedDataPath:b(e,`iosXctestDerivedDataPath`),iosXctestEnvDir:b(e,`iosXctestEnvDir`),androidDeviceAllowlist:b(e,`androidDeviceAllowlist`),daemonBaseUrl:b(e,`daemonBaseUrl`),daemonAuthToken:b(e,`daemonAuthToken`),tenant:b(e,`tenant`),runId:b(e,`runId`),leaseId:b(e,`leaseId`),cwd:b(e,`cwd`),debug:nn(e,`debug`)}}function Zt(t,n){let r=an(t,`deviceTarget`,o);if(n.readTargetAlias===!1||t.target===void 0)return r;let i=an(t,`target`,o);if(r!==void 0&&i!==r)throw new e(`INVALID_ARGS`,`Expected target alias to match deviceTarget when both are set.`);return r??i}function Qt(e,t){let n=bn(e,t),r=rn(n,`kind`,kt);switch(r){case`ref`:return{kind:r,ref:en(n,`ref`),label:b(n,`label`)};case`selector`:return{kind:r,selector:en(n,`selector`)};case`point`:return{kind:r,x:x(n,`x`),y:x(n,`y`)}}}function $t(e,t){let n=bn(e,t),r=rn(n,`kind`,[`ref`,`selector`]);return r===`ref`?{kind:r,ref:en(n,`ref`),label:b(n,`label`)}:{kind:r,selector:en(n,`selector`)}}function y(e,t){let n=bn(e,t);return{x:x(n,`x`),y:x(n,`y`)}}function en(t,n){let r=t[n];if(typeof r!=`string`||r.length===0)throw new e(`INVALID_ARGS`,`Expected ${n} to be a non-empty string.`);return r}function b(t,n){let r=t[n];if(r!==void 0){if(typeof r!=`string`||r.length===0)throw new e(`INVALID_ARGS`,`Expected ${n} to be a non-empty string.`);return r}}function x(t,n){let r=t[n];if(typeof r!=`number`||!Number.isFinite(r))throw new e(`INVALID_ARGS`,`Expected ${n} to be a finite number.`);return r}function tn(t,n){let r=t[n];if(r!==void 0){if(typeof r!=`number`||!Number.isFinite(r))throw new e(`INVALID_ARGS`,`Expected ${n} to be a finite number.`);return r}}function S(t,n,r={}){let i=t[n];if(i===void 0)return;if(!Number.isInteger(i))throw new e(`INVALID_ARGS`,`Expected ${n} to be an integer.`);let a=i;if(r.min!==void 0&&a<r.min)throw new e(`INVALID_ARGS`,`Expected ${n} to be at least ${r.min}.`);if(r.max!==void 0&&a>r.max)throw new e(`INVALID_ARGS`,`Expected ${n} to be at most ${r.max}.`);return a}function nn(t,n){let r=t[n];if(r!==void 0){if(typeof r!=`boolean`)throw new e(`INVALID_ARGS`,`Expected ${n} to be a boolean.`);return r}}function rn(t,n,r){let i=t[n];if(typeof i!=`string`||!r.includes(i))throw new e(`INVALID_ARGS`,`Expected ${n} to be one of: ${r.join(`, `)}.`);return i}function an(t,n,r){let i=t[n];if(i!==void 0){if(typeof i!=`string`||!r.includes(i))throw new e(`INVALID_ARGS`,`Expected ${n} to be one of: ${r.join(`, `)}.`);return i}}function C(e){return w({session:e.session,platform:e.platform,target:e.deviceTarget,device:e.device,udid:e.udid,serial:e.serial,iosSimulatorDeviceSet:e.iosSimulatorDeviceSet,iosXctestrunFile:e.iosXctestrunFile,iosXctestDerivedDataPath:e.iosXctestDerivedDataPath,iosXctestEnvDir:e.iosXctestEnvDir,androidDeviceAllowlist:e.androidDeviceAllowlist,daemonBaseUrl:e.daemonBaseUrl,daemonAuthToken:e.daemonAuthToken,tenant:e.tenant,runId:e.runId,leaseId:e.leaseId,cwd:e.cwd,debug:e.debug})}function on(e){switch(e.kind){case`ref`:return{ref:e.ref,label:e.label};case`selector`:return{selector:e.selector};case`point`:return{x:e.x,y:e.y}}}function sn(e){switch(e.kind){case`ref`:return{ref:e.ref,label:e.label};case`selector`:return{selector:e.selector}}}function cn(e){return{count:e.count,intervalMs:e.intervalMs,holdMs:e.holdMs,jitterPx:e.jitterPx,doubleTap:e.doubleTap}}function ln(e){return{depth:e.depth,scope:e.scope,raw:e.raw}}function un(t,n,r){let i=new Set(n),a=Object.keys(t).filter(e=>!i.has(e));if(a.length>0)throw new e(`INVALID_ARGS`,`${r} has unknown field(s): ${a.join(`, `)}.`)}function w(e){return Object.fromEntries(Object.entries(e).filter(([,e])=>e!==void 0))}function T(e,t){return{schema:e,required:!1,read:t}}function dn(e,t){return{...Ft(e),...t.min===void 0?{}:{minimum:t.min},...t.max===void 0?{}:{maximum:t.max}}}function fn(e){return Object.fromEntries(Object.entries(e).map(([e,t])=>[e,t.schema]))}function pn(e){return Object.entries(e).flatMap(([e,t])=>t.required?[e]:[])}function mn(t,n){let r=t[n];if(r!==void 0){if(!r||typeof r!=`object`||Array.isArray(r))throw new e(`INVALID_ARGS`,`Expected ${n} to be an object.`);return r}}function hn(t,n){let r=t[n];if(r!==void 0){if(!Array.isArray(r)||r.some(e=>typeof e!=`string`))throw new e(`INVALID_ARGS`,`Expected ${n} to be an array of strings.`);return r}}function gn(){return{session:{type:`string`,description:`Agent-device session name.`},platform:{type:`string`,enum:i,description:`Platform selector used to resolve a device.`},deviceTarget:{type:`string`,enum:o,description:`Device target form. Maps to the CLI --target flag.`},target:{type:`string`,enum:o,description:`Alias for deviceTarget on commands without a UI target field. Interaction commands reserve target for the UI element.`},device:{type:`string`,description:`Device name selector.`},udid:{type:`string`,description:`iOS device UDID selector.`},serial:{type:`string`,description:`Android serial selector.`},iosSimulatorDeviceSet:{type:`string`,description:`iOS simulator device-set path used for device resolution.`},iosXctestrunFile:{type:`string`,description:`Externally built iOS XCTest runner .xctestrun artifact path.`},iosXctestDerivedDataPath:{type:`string`,description:`Derived data path for external iOS XCTest runner execution.`},iosXctestEnvDir:{type:`string`,description:`Writable directory for iOS XCTest runner env overlays.`},androidDeviceAllowlist:{type:`string`,description:`Android serial allowlist used for device resolution.`},daemonBaseUrl:{type:`string`,description:`Remote daemon base URL.`},daemonAuthToken:{type:`string`,description:`Remote daemon auth token.`},tenant:{type:`string`,description:`Remote tenant identifier.`},runId:{type:`string`,description:`Lease run identifier.`},leaseId:{type:`string`,description:`Existing lease identifier.`},cwd:{type:`string`,description:`Working directory for command execution.`},debug:{type:`boolean`,description:`Enable debug diagnostics.`}}}function _n(){return{oneOf:[...yn(),{type:`object`,properties:{kind:{type:`string`,const:`point`},x:{type:`number`},y:{type:`number`}},required:[`kind`,`x`,`y`],additionalProperties:!1}],description:`UI target. This is separate from deviceTarget, which selects the device form.`}}function vn(){return{oneOf:yn(),description:`UI element target by snapshot ref or selector expression.`}}function yn(){return[{type:`object`,properties:{kind:{type:`string`,const:`ref`},ref:{type:`string`,description:`Snapshot element ref such as @e12.`},label:{type:`string`,description:`Optional human label for the ref.`}},required:[`kind`,`ref`],additionalProperties:!1},{type:`object`,properties:{kind:{type:`string`,const:`selector`},selector:{type:`string`,description:`Agent-device selector expression.`}},required:[`kind`,`selector`],additionalProperties:!1}]}function bn(t,n){let r=t[n];if(!r||typeof r!=`object`||Array.isArray(r))throw new e(`INVALID_ARGS`,`Expected ${n} to be an object.`);return r}function E(e,t){return n=>D(e,t?t(n):[],n)}function D(e,t,n){return{command:e,positionals:t,options:xn(n)}}function xn(e){let t=Sn(e.deviceTarget??e.target);if(t===void 0&&e.target===void 0)return e;let{target:n,...r}=e;return t===void 0?r:{...r,target:t}}function Sn(e){return e===`mobile`||e===`tv`||e===`desktop`?e:void 0}function O(e){return w({session:e.session,platform:e.platform,deviceTarget:e.target,device:e.device,udid:e.udid,serial:e.serial,iosSimulatorDeviceSet:e.iosSimulatorDeviceSet,iosXctestrunFile:e.iosXctestrunFile,iosXctestDerivedDataPath:e.iosXctestDerivedDataPath,iosXctestEnvDir:e.iosXctestEnvDir,androidDeviceAllowlist:e.androidDeviceAllowlist})}function Cn(e){return{platform:e.platform,target:e.target,device:e.device,udid:e.udid,serial:e.serial,iosSimulatorDeviceSet:e.iosSimulatorDeviceSet,androidDeviceAllowlist:e.androidDeviceAllowlist}}function wn(e){return w({depth:e.snapshotDepth,scope:e.snapshotScope,raw:e.snapshotRaw})}function Tn(e){return{depth:e.snapshotDepth,scope:e.snapshotScope,raw:e.snapshotRaw}}function En(e){return w({settle:e.settle,settleQuietMs:e.settleQuietMs,timeoutMs:e.timeoutMs})}function Dn(e){return w({count:e.count,intervalMs:e.intervalMs,holdMs:e.holdMs,jitterPx:e.jitterPx,doubleTap:e.doubleTap})}function On(e){if(`ref`in e&&e.ref!==void 0)return w({kind:`ref`,ref:e.ref,label:e.label});if(`selector`in e&&e.selector!==void 0)return{kind:`selector`,selector:e.selector};let t=e;return{kind:`point`,x:t.x,y:t.y}}function kn(t){let n=jn(t);if(typeof n.ref==`string`)return[n.ref,...Nn(n.label)];if(typeof n.selector==`string`)return[n.selector];if(n.kind===`point`||n.x!==void 0||n.y!==void 0)return[String(Mn(n.x,`x`)),String(Mn(n.y,`y`))];throw new e(`INVALID_ARGS`,`interaction requires @ref, selector, or point target`)}function An(t){let n=jn(t);if(typeof n.ref==`string`)return[n.ref,...Nn(n.label)];if(typeof n.selector==`string`)return[n.selector];throw new e(`INVALID_ARGS`,`element command requires @ref or selector target`)}function jn(t){if(!t||typeof t!=`object`||Array.isArray(t))throw new e(`INVALID_ARGS`,`Expected target object.`);let n=t,r=n.target;return r&&typeof r==`object`&&!Array.isArray(r)?r:n}function Mn(t,n){if(typeof t!=`number`||!Number.isFinite(t))throw new e(`INVALID_ARGS`,`point target requires numeric ${n}.`);return t}function Nn(e){return typeof e==`string`&&e.length>0?[e]:[]}function Pn(t){if(t[0]?.startsWith(`@`))return{ref:t[0],label:Rn(t.slice(1))};let n=t.join(` `).trim();if(!n)throw new e(`INVALID_ARGS`,`get requires @ref or selector expression`);return{selector:n}}function Fn(t){if(t===`text`||t===`attrs`)return t;throw new e(`INVALID_ARGS`,`get only supports text or attrs`)}function In(t,n={}){let r=ae(t,n);if(!r)throw new e(`INVALID_ARGS`,`is requires a selector expression`);return r}function Ln(t,n){try{let e=JSON.parse(t);if(e&&typeof e==`object`&&!Array.isArray(e))return e}catch{}throw new e(`INVALID_ARGS`,`${n} must be a JSON object`)}function Rn(e){return e.join(` `).trim()||void 0}function k(...e){return new Set(e)}function A(e,t){return e!==void 0&&t.has(e)}function zn(e){return e===void 0||e.trim()===``?!1:Number.isFinite(Number(e))}function Bn(t,n){if(t===void 0)return;let r=Number(t);if(Number.isFinite(r))return r;throw new e(`INVALID_ARGS`,`${n} must be a finite number.`)}function j(e){return e===void 0?void 0:Number(e)}function M(e){return e===void 0?[]:[e]}function N(e){return e===void 0?[]:[String(e)]}function P(t,n){if(t===void 0||t===``)throw new e(`INVALID_ARGS`,n);return t}function F(t,n){if(typeof t!=`string`||t.length===0)throw new e(`INVALID_ARGS`,n);return t}function I(e){return e}function L(e){let t={},n={},r={},i={};for(let a of e.commands){if(a.cliSchema&&Vn(t,`CLI schema`,a.name,a.cliSchema),Vn(n,`CLI reader`,a.name,a.cliReader),a.daemonWriter&&Vn(r,`daemon writer`,a.name,a.daemonWriter),a.extraDaemonWriters)for(let[e,t]of Object.entries(a.extraDaemonWriters))Vn(r,`daemon writer`,e,t);a.cliOutputFormatter&&Vn(i,`CLI output formatter`,a.name,a.cliOutputFormatter)}return{name:e.name,clientSurface:e.clientSurface,metadata:e.commands.map(e=>e.metadata),definitions:e.commands.map(e=>e.definition),cliSchemas:t,cliReaders:n,daemonWriters:r,cliOutputFormatters:i}}function Vn(e,t,n,r){if(Object.hasOwn(e,n))throw Error(`Duplicate command family ${t}: ${n}`);e[n]=r}function Hn(e){return e}function R(e,t){return{...e,run:t,invoke:async(n,r)=>await t(n,e.readInput(r))}}function z(e){return({result:t})=>e(t)}const B=z(V);function V(e){return{data:e,text:je(e)}}function Un(e){let t=[`Batch completed: ${e.executed}/${e.total} steps in ${e.totalDurationMs}ms`];for(let n of e.results)t.push(Gn(n));return{data:e,text:t.join(`
|
|
2
|
+
`)}}const Wn={batch:z(Un)};function Gn(e){let t=je(e.data)??e.command;return`${e.step}. OK ${t} (${e.durationMs}ms)`}function Kn(e=re){let t=qn(e);return Hn({name:`batch`,description:`Run multiple structured command steps in one daemon request.`,inputSchema:qt(t),readInput:e=>Yn(e,t)})}function qn(e){return{steps:f(Vt({type:`array`,description:`Structured batch steps. Each step uses a command name and the same input object as that command tool.`,items:Jn(e)},(t,n)=>Xn(t[n],e))),onError:_([`stop`],`Batch failure policy.`),maxSteps:h(`Maximum number of steps accepted for this batch.`,{min:1,max:1e3}),out:p(`Optional output path for command artifacts.`)}}function Jn(e){return{type:`object`,properties:{command:{type:`string`,enum:e,description:`Command name to run with structured input.`},input:{type:`object`,additionalProperties:!0,description:`Structured command input for the nested command. Use the matching MCP tool schema for this object.`},runtime:{type:`object`,additionalProperties:!0,description:`Optional per-step runtime payload.`}},required:[`command`,`input`],additionalProperties:!1}}function Yn(t,n){let r=Jt(t,n),i=r.maxSteps??100;if(!_t(i))throw new e(`INVALID_ARGS`,`Invalid batch maxSteps: ${String(r.maxSteps)}`);return bt(r.steps.length,i),{...r}}function Xn(t,n){if(!Array.isArray(t))throw new e(`INVALID_ARGS`,`Expected steps to be an array.`);return t.map((e,t)=>Zn(e,t+1,n))}function Zn(e,t,n){let r=xt(e,t);return un(r,[`command`,`input`,`runtime`],`Batch step ${t}`),{command:Qn(r,t,n),input:vt(r,t),...$n(r,t)}}function Qn(t,n,r){if(r===re)return ne(t.command,n);let i=t.command;if(typeof i!=`string`||!r.includes(i))throw new e(`INVALID_ARGS`,`Expected command to be one of: ${r.join(`, `)}.`);return i}function $n(e,t){let n=dt(e.runtime,t);return n===void 0?{}:{runtime:n}}function er(e,t){let n=d(e,`bundleId`),r=d(e,`package`);return{app:St(e,`app`),appPath:St(e,`appPath`),platform:ut(e,`platform`),appId:n??r,bundleId:n,package:r,identifiers:ge({session:t,bundleId:n,packageName:r})}}function tr(t,n){let r=d(t,`bundleId`),i=d(t,`packageName`),a=r??i??d(t,`appId`),o=d(t,`launchTarget`)??i??r??a;if(!o)throw new e(`COMMAND_FAILED`,`Daemon response is missing "launchTarget".`,{response:t});return{appName:d(t,`appName`),appId:a,bundleId:r,packageName:i,launchTarget:o,installablePath:d(t,`installablePath`),archivePath:d(t,`archivePath`),materializationId:d(t,`materializationId`),materializationExpiresAt:d(t,`materializationExpiresAt`),identifiers:ge({session:n,bundleId:r,packageName:i,appId:a})}}function nr(e){return{released:e.released===!0,materializationId:St(e,`materializationId`),identifiers:{}}}function rr(e){let{record:t,platform:r,id:i,name:a,target:o}=or(e,`name`),s=ar(t);return{platform:r,target:o,kind:gt(t,`kind`),id:i,name:a,booted:typeof t.booted==`boolean`?t.booted:void 0,...n(r)&&s?{appleOs:s}:{},identifiers:De(r,i,a),...sr(r,i)}}function ir(e){let{record:t,platform:n,id:r,name:i,target:a}=or(e,`name`),o=St(t,`device`),s=ar(t),c={session:i,...De(n,r,o)};return{name:i,createdAt:ht(t,`createdAt`),sessionStateDir:d(t,`sessionStateDir`),runnerLogPath:d(t,`runnerLogPath`),device:{platform:n,target:a,id:r,name:o,...s?{appleOs:s}:{},identifiers:c,...sr(n,r,yt(t,`ios_simulator_device_set`))},identifiers:c}}function ar(e){let n=e.appleOs;return t(n)?n:void 0}function or(e,t){let n=pt(e);return{record:n,platform:ut(n,`platform`),id:St(n,`id`),name:St(n,t),target:mt(n,`target`)}}function sr(e,t,n){return{ios:e===`ios`?{udid:t,...n===void 0?{}:{simulatorSetPath:n}}:void 0,android:e===`android`?{serial:t}:void 0}}function cr(e){if(!u(e))return;let t=e.platform,n=d(e,`metroHost`),r=typeof e.metroPort==`number`?e.metroPort:void 0,i=d(e,`bundleUrl`),a=d(e,`launchUrl`);return{platform:t===`ios`||t===`android`?t:void 0,metroHost:n,metroPort:r,bundleUrl:i,launchUrl:a}}function lr(e){let t=e.platform,n=d(e,`id`),i=d(e,`device`);if(!(!r(t)||!n||!i))return{platform:t,target:mt(e,`target`),id:n,name:i,identifiers:De(t,n,i),ios:t===`ios`?{udid:d(e,`device_udid`)??n,simulatorSetPath:yt(e,`ios_simulator_device_set`)}:void 0,android:t===`android`?{serial:d(e,`serial`)??n}:void 0}}function ur(e){if(u(e)&&!(typeof e.durationMs!=`number`||typeof e.measuredAt!=`string`||typeof e.method!=`string`))return{durationMs:e.durationMs,measuredAt:e.measuredAt,method:e.method,appTarget:d(e,`appTarget`),appBundleId:d(e,`appBundleId`)}}function dr(e){if(!u(e)||typeof e.success!=`boolean`||typeof e.exitCode!=`number`||typeof e.stdout!=`string`||typeof e.stderr!=`string`)return;let t=fr(e.error);return{success:e.success,exitCode:e.exitCode,stdout:e.stdout,stderr:e.stderr,...t?{error:t}:{}}}function fr(e){if(u(e)&&!(typeof e.code!=`string`||typeof e.message!=`string`))return{code:e.code,message:e.message,...typeof e.hint==`string`?{hint:e.hint}:{},...typeof e.diagnosticId==`string`?{diagnosticId:e.diagnosticId}:{},...typeof e.logPath==`string`?{logPath:e.logPath}:{},...u(e.details)?{details:e.details}:{}}}function pr(e){return Array.isArray(e)?e:[]}function mr(e){let t=rt(e);return ft({stateDir:e.stateDir,daemonBaseUrl:e.daemonBaseUrl,daemonAuthToken:e.daemonAuthToken,daemonTransport:e.daemonTransport,daemonServerMode:e.daemonServerMode,...tt(t),provider:e.provider,providerSessionId:e.providerSessionId,providerApp:e.providerApp,providerOsVersion:e.providerOsVersion,providerProject:e.providerProject,providerBuild:e.providerBuild,providerSessionName:e.providerSessionName,awsProjectArn:e.awsProjectArn,awsDeviceArn:e.awsDeviceArn,awsAppArn:e.awsAppArn,awsRegion:e.awsRegion,awsInteractionMode:e.awsInteractionMode,sessionIsolation:e.sessionIsolation,platform:e.platform,target:e.target,device:e.device,udid:e.udid,serial:e.serial,iosSimulatorDeviceSet:e.iosSimulatorDeviceSet,iosXctestrunFile:e.iosXctestrunFile,iosXctestDerivedDataPath:e.iosXctestDerivedDataPath,iosXctestEnvDir:e.iosXctestEnvDir,androidDeviceAllowlist:e.androidDeviceAllowlist,surface:e.surface,activity:e.activity,launchConsole:e.launchConsole,launchArgs:e.launchArgs,relaunch:e.relaunch,shutdown:e.shutdown,saveScript:e.saveScript,deviceHub:e.deviceHub,noRecord:e.noRecord,backMode:e.backMode,metroHost:e.metroHost,metroPort:e.metroPort,bundleUrl:e.bundleUrl,launchUrl:e.launchUrl,snapshotInteractiveOnly:e.interactiveOnly,snapshotDepth:e.depth,snapshotScope:e.scope,snapshotRaw:e.raw,snapshotForceFull:e.forceFull,...Ge(e),appsFilter:e.appsFilter,kind:e.kind,out:e.out,count:e.count,fps:e.fps,screenshotMaxSize:e.maxSize,quality:e.quality,hideTouches:e.hideTouches,intervalMs:e.intervalMs,delayMs:e.delayMs,durationMs:e.durationMs,holdMs:e.holdMs,jitterPx:e.jitterPx,pixels:e.pixels,doubleTap:e.doubleTap,verify:e.verify,settle:e.settle,settleQuietMs:e.settleQuietMs,clickButton:e.clickButton,pauseMs:e.pauseMs,pattern:e.pattern,headless:e.headless,restart:e.restart,replayUpdate:e.replayUpdate,replayBackend:e.replayBackend,replayEnv:e.replayEnv,replayShellEnv:e.replayShellEnv,failFast:e.failFast,timeoutMs:e.timeoutMs,retries:e.retries,recordVideo:e.recordVideo,artifactsDir:e.artifactsDir,shardAll:e.shardAll,shardSplit:e.shardSplit,findFirst:e.findFirst,findLast:e.findLast,networkInclude:e.networkInclude,batchOnError:e.batchOnError,batchMaxSteps:e.batchMaxSteps,batchSteps:e.batchSteps,verbose:e.debug})}function hr(e){let t=rt(e);return ft({requestId:e.requestId,cwd:e.cwd,sessionExplicit:e.session!==void 0,debug:e.debug,includeCost:e.cost,responseLevel:e.responseLevel,lockPolicy:e.lockPolicy,lockPlatform:e.lockPlatform,...Ie(t),sessionIsolation:e.sessionIsolation,installSource:e.installSource,retainMaterializedPaths:e.retainMaterializedPaths,materializedPathRetentionMs:e.materializedPathRetentionMs,materializationId:e.materializationId})}function gr(e){return e??`default`}function H(...e){return e}const _r=H(`snapshotInteractiveOnly`,`snapshotDepth`,`snapshotScope`,`snapshotRaw`),U=H(`snapshotDepth`,`snapshotScope`,`snapshotRaw`),vr=H(`metroProjectRoot`,`kind`,`metroKind`,`metroPublicBaseUrl`,`metroProxyBaseUrl`,`metroBearerToken`,`metroPreparePort`,`metroListenHost`,`metroStatusHost`,`metroStartupTimeoutMs`,`metroProbeTimeoutMs`,`metroRuntimeFile`,`metroNoReuseExisting`,`metroNoInstallDeps`),yr=H(`metroHost`,`metroPort`,`bundleUrl`),br=H(`count`,`intervalMs`,`holdMs`,`jitterPx`,`doubleTap`),xr=H(`settle`,`settleQuietMs`,`timeoutMs`),Sr=H(`replayUpdate`,`replayEnv`),Cr=[{key:`config`,names:[`--config`],type:`string`,usageLabel:`--config <path>`,usageDescription:`Load CLI defaults from a specific config file`},{key:`remoteConfig`,names:[`--remote-config`],type:`string`,usageLabel:`--remote-config <path>`,usageDescription:`Load remote host + Metro workflow settings from a specific profile file`},{key:`stateDir`,names:[`--state-dir`],type:`string`,usageLabel:`--state-dir <path>`,usageDescription:`Daemon state directory (defaults to ~/.agent-device for packages, or a worktree-scoped dev dir from source)`},{key:`daemonBaseUrl`,names:[`--daemon-base-url`],type:`string`,usageLabel:`--daemon-base-url <url>`,usageDescription:`Explicit remote HTTP daemon base URL (skip local daemon discovery/startup)`},{key:`daemonAuthToken`,names:[`--daemon-auth-token`],type:`string`,usageLabel:`--daemon-auth-token <token>`,usageDescription:`Remote HTTP daemon or proxy auth token (sent as request token and bearer header)`},{key:`daemonTransport`,names:[`--daemon-transport`],type:`enum`,enumValues:[`auto`,`socket`,`http`],usageLabel:`--daemon-transport auto|socket|http`,usageDescription:`Daemon client transport preference`},{key:`daemonServerMode`,names:[`--daemon-server-mode`],type:`enum`,enumValues:[`socket`,`http`,`dual`],usageLabel:`--daemon-server-mode socket|http|dual`,usageDescription:`Daemon server mode used when spawning daemon`},{key:`proxyHost`,names:[`--host`],type:`string`,usageLabel:`--host <host>`,usageDescription:`Proxy: host interface to bind (default: 127.0.0.1)`},{key:`proxyPort`,names:[`--port`],type:`int`,min:1,max:65535,usageLabel:`--port <port>`,usageDescription:`Proxy: TCP port to bind (default: 0, choose a free port)`},{key:`tenant`,names:[`--tenant`],type:`string`,usageLabel:`--tenant <id>`,usageDescription:`Tenant scope identifier for isolated daemon sessions`},{key:`sessionIsolation`,names:[`--session-isolation`],type:`enum`,enumValues:[`none`,`tenant`],usageLabel:`--session-isolation none|tenant`,usageDescription:`Session isolation strategy (tenant prefixes session namespace)`},{key:`runId`,names:[`--run-id`],type:`string`,usageLabel:`--run-id <id>`,usageDescription:`Run identifier used for tenant lease admission checks`},{key:`leaseId`,names:[`--lease-id`],type:`string`,usageLabel:`--lease-id <id>`,usageDescription:`Lease identifier bound to tenant/run admission scope`},{key:`leaseBackend`,names:[`--lease-backend`],type:`enum`,enumValues:[`ios-simulator`,`ios-instance`,`android-instance`],usageLabel:`--lease-backend ios-simulator|ios-instance|android-instance`,usageDescription:`Lease backend for remote tenant connection admission`},{key:`provider`,names:[`--provider`],type:`string`,usageLabel:`--provider <name>`,usageDescription:`Cloud provider name for provider-scoped commands`},{key:`providerSessionId`,names:[`--provider-session`],type:`string`,usageLabel:`--provider-session <id>`,usageDescription:`Cloud provider session id or ARN`},{key:`providerApp`,names:[`--provider-app`],type:`string`,usageLabel:`--provider-app <ref-or-path>`,usageDescription:`Cloud provider app reference or local app path used when creating hosted WebDriver sessions`},{key:`providerOsVersion`,names:[`--provider-os-version`,`--os-version`],type:`string`,usageLabel:`--provider-os-version <version>`,usageDescription:`Hosted cloud provider OS version, for example 17 or 14.0`},{key:`providerProject`,names:[`--provider-project`],type:`string`,usageLabel:`--provider-project <name>`,usageDescription:`Hosted cloud provider project label`},{key:`providerBuild`,names:[`--provider-build`],type:`string`,usageLabel:`--provider-build <name>`,usageDescription:`Hosted cloud provider build label`},{key:`providerSessionName`,names:[`--provider-session-name`],type:`string`,usageLabel:`--provider-session-name <name>`,usageDescription:`Hosted cloud provider session label`},{key:`awsProjectArn`,names:[`--aws-project-arn`],type:`string`,usageLabel:`--aws-project-arn <arn>`,usageDescription:`AWS Device Farm project ARN for hosted WebDriver sessions`},{key:`awsDeviceArn`,names:[`--aws-device-arn`],type:`string`,usageLabel:`--aws-device-arn <arn>`,usageDescription:`AWS Device Farm device ARN for hosted WebDriver sessions`},{key:`awsAppArn`,names:[`--aws-app-arn`],type:`string`,usageLabel:`--aws-app-arn <arn>`,usageDescription:`AWS Device Farm app ARN attached to hosted remote access sessions`},{key:`awsRegion`,names:[`--aws-region`],type:`string`,usageLabel:`--aws-region <region>`,usageDescription:`AWS region for Device Farm API calls`},{key:`awsInteractionMode`,names:[`--aws-interaction-mode`],type:`enum`,enumValues:[`INTERACTIVE`,`NO_VIDEO`,`VIDEO_ONLY`],usageLabel:`--aws-interaction-mode INTERACTIVE|NO_VIDEO|VIDEO_ONLY`,usageDescription:`AWS Device Farm remote access interaction mode`},{key:`force`,names:[`--force`],type:`boolean`,usageLabel:`--force`,usageDescription:`Force connection state replacement when reconnecting`},{key:`noLogin`,names:[`--no-login`],type:`boolean`,usageLabel:`--no-login`,usageDescription:`Connect: fail instead of starting implicit cloud login`},{key:`sessionLock`,names:[`--session-lock`],type:`enum`,enumValues:[`reject`,`strip`],usageLabel:`--session-lock reject|strip`,usageDescription:`Lock bound-session device routing for this CLI invocation and nested batch steps`},{key:`sessionLocked`,names:[`--session-locked`],type:`boolean`,usageLabel:`--session-locked`,usageDescription:`Deprecated alias for --session-lock reject`},{key:`sessionLockConflicts`,names:[`--session-lock-conflicts`],type:`enum`,enumValues:[`reject`,`strip`],usageLabel:`--session-lock-conflicts reject|strip`,usageDescription:`Deprecated alias for --session-lock`},{key:`platform`,names:[`--platform`],type:`enum`,enumValues:i,usageLabel:`--platform ${i.join(`|`)}`,usageDescription:"Platform to target (`apple` aliases the Apple automation backend)"},{key:`target`,names:[`--target`],type:`enum`,enumValues:[`mobile`,`tv`,`desktop`],usageLabel:`--target mobile|tv|desktop`,usageDescription:`Device target class to match`},{key:`device`,names:[`--device`],type:`string`,usageLabel:`--device <name>`,usageDescription:`Device name to target`},{key:`udid`,names:[`--udid`],type:`string`,usageLabel:`--udid <udid>`,usageDescription:`iOS device UDID`},{key:`serial`,names:[`--serial`],type:`string`,usageLabel:`--serial <serial>`,usageDescription:`Android device serial`},{key:`surface`,names:[`--surface`],type:`enum`,enumValues:Ee,usageLabel:`--surface app|frontmost-app|desktop|menubar`,usageDescription:`macOS session surface for open (defaults to app)`},{key:`headless`,names:[`--headless`],type:`boolean`,usageLabel:`--headless`,usageDescription:`Boot: launch Android emulator without a GUI window`},{key:`targetApp`,names:[`--app`,`--target-app`],type:`string`,usageLabel:`--app <id-or-name>`,usageDescription:`Doctor: verify an installed target app without opening a session`},{key:`metroHost`,names:[`--metro-host`],type:`string`,usageLabel:`--metro-host <host>`,usageDescription:`Session-scoped Metro/debug host hint`},{key:`metroPort`,names:[`--metro-port`],type:`int`,min:1,max:65535,usageLabel:`--metro-port <port>`,usageDescription:`Session-scoped Metro/debug port hint`},{key:`metroProjectRoot`,names:[`--project-root`],type:`string`,usageLabel:`--project-root <path>`,usageDescription:`metro prepare: React Native project root (default: cwd)`},{key:`kind`,names:[`--kind`],type:`enum`,enumValues:[`auto`,`react-native`,`expo`,...me],usageLabel:`--kind <kind>`,usageDescription:`Kind selector for commands that support it, such as metro prepare or perf artifact collectors`},{key:`perfTemplate`,names:[`--template`],type:`string`,usageLabel:`--template <name>`,usageDescription:`Perf xctrace template name, for example Time Profiler`},{key:`metroKind`,names:[`--metro-kind`],type:`enum`,enumValues:[`auto`,`react-native`,`expo`],usageLabel:`--metro-kind auto|react-native|expo`,usageDescription:`metro prepare: detect or force the Metro launcher kind`},{key:`metroPublicBaseUrl`,names:[`--public-base-url`],type:`string`,usageLabel:`--public-base-url <url>`,usageDescription:`metro prepare: public base URL used for direct bundle hints`},{key:`metroProxyBaseUrl`,names:[`--proxy-base-url`],type:`string`,usageLabel:`--proxy-base-url <url>`,usageDescription:`metro prepare: optional bridge origin for remote Metro access`},{key:`metroBearerToken`,names:[`--bearer-token`],type:`string`,usageLabel:`--bearer-token <token>`,usageDescription:`metro prepare: host bridge bearer token (or AGENT_DEVICE_METRO_BEARER_TOKEN; falls back to AGENT_DEVICE_DAEMON_AUTH_TOKEN)`},{key:`metroPreparePort`,names:[`--port`],type:`int`,min:1,max:65535,usageLabel:`--port <port>`,usageDescription:`metro prepare: local Metro port (default: 8081)`},{key:`metroListenHost`,names:[`--listen-host`],type:`string`,usageLabel:`--listen-host <host>`,usageDescription:`metro prepare: host Metro listens on (default: 0.0.0.0)`},{key:`metroStatusHost`,names:[`--status-host`],type:`string`,usageLabel:`--status-host <host>`,usageDescription:`metro prepare: host used for local /status polling (default: 127.0.0.1)`},{key:`metroStartupTimeoutMs`,names:[`--startup-timeout-ms`],type:`int`,min:1,usageLabel:`--startup-timeout-ms <ms>`,usageDescription:`metro prepare: timeout while waiting for Metro to become ready`},{key:`metroProbeTimeoutMs`,names:[`--probe-timeout-ms`],type:`int`,min:1,usageLabel:`--probe-timeout-ms <ms>`,usageDescription:`metro prepare: timeout for /status and proxy bridge calls`},{key:`metroRuntimeFile`,names:[`--runtime-file`],type:`string`,usageLabel:`--runtime-file <path>`,usageDescription:`metro prepare: optional file path to persist the JSON result`},{key:`metroNoReuseExisting`,names:[`--no-reuse-existing`],type:`boolean`,usageLabel:`--no-reuse-existing`,usageDescription:`metro prepare: always start a fresh Metro process`},{key:`metroNoInstallDeps`,names:[`--no-install-deps`],type:`boolean`,usageLabel:`--no-install-deps`,usageDescription:`metro prepare: skip package-manager install when node_modules is missing`},{key:`bundleUrl`,names:[`--bundle-url`],type:`string`,usageLabel:`--bundle-url <url>`,usageDescription:`Session-scoped bundle URL hint`},{key:`launchUrl`,names:[`--launch-url`],type:`string`,usageLabel:`--launch-url <url>`,usageDescription:`Session-scoped deep link / launch URL hint`},{key:`iosSimulatorDeviceSet`,names:[`--ios-simulator-device-set`],type:`string`,usageLabel:`--ios-simulator-device-set <path>`,usageDescription:`Scope iOS simulator discovery/commands to this simulator device set`},{key:`iosXctestrunFile`,names:[`--ios-xctestrun-file`],type:`string`,usageLabel:`--ios-xctestrun-file <path>`,usageDescription:`Use an externally built iOS XCTest runner .xctestrun artifact`},{key:`iosXctestDerivedDataPath`,names:[`--ios-xctest-derived-data-path`],type:`string`,usageLabel:`--ios-xctest-derived-data-path <path>`,usageDescription:`Derived data path for external iOS XCTest runner execution`},{key:`iosXctestEnvDir`,names:[`--ios-xctest-env-dir`],type:`string`,usageLabel:`--ios-xctest-env-dir <path>`,usageDescription:`Writable directory for per-session iOS XCTest runner env overlays`},{key:`deviceHub`,names:[`--device-hub`],type:`boolean`,usageLabel:`--device-hub`,usageDescription:`open: use Xcode Device Hub when surfacing Apple simulators`},{key:`androidDeviceAllowlist`,names:[`--android-device-allowlist`],type:`string`,usageLabel:`--android-device-allowlist <serials>`,usageDescription:`Comma/space separated Android serial allowlist for discovery/selection`},{key:`remote`,names:[`--remote`],type:`boolean`,usageLabel:`--remote`,usageDescription:`Doctor: check remote connection setup instead of local device inventory`},{key:`activity`,names:[`--activity`],type:`string`,usageLabel:`--activity <component>`,usageDescription:`Android app launch activity (package/Activity); not for URL opens`},{key:`launchConsole`,names:[`--launch-console`],type:`string`,usageLabel:`--launch-console <path>`,usageDescription:`open: capture the initial iOS simulator launch console window to a file`},{key:`launchArgs`,names:[`--launch-args`],type:`string`,multiple:!0,usageLabel:`--launch-args <arg>`,usageDescription:`open: repeatable launch argument forwarded verbatim to the platform launch command (iOS app process args; Android adb shell am start args). Linux and macOS reject the flag.`},{key:`header`,names:[`--header`],type:`string`,multiple:!0,usageLabel:`--header <name:value>`,usageDescription:`install-from-source: repeatable HTTP header for URL downloads`},{key:`githubActionsArtifact`,names:[`--github-actions-artifact`],type:`string`,usageLabel:`--github-actions-artifact <owner/repo:artifact>`,usageDescription:`install-from-source: GitHub Actions artifact resolved by a remote daemon`},{key:`installSource`,names:[],type:`string`},{key:`session`,names:[`--session`],type:`string`,usageLabel:`--session <name>`,usageDescription:`Named session`},{key:`count`,names:[`--count`],type:`int`,min:1,max:200,usageLabel:`--count <n>`,usageDescription:`Repeat count for press/swipe series`},{key:`fps`,names:[`--fps`],type:`int`,min:1,max:120,usageLabel:`--fps <n>`,usageDescription:`Record: target frames per second (iOS physical device runner)`},{key:`quality`,names:[`--quality`],type:`string`,usageLabel:`--quality <medium|high>`,usageDescription:`Record: output quality preset; Android maps this to screenrecord bitrate, Apple targets use it for export/encoding. Legacy numeric values 5-7 map to medium; 8-10 map to high`},{key:`hideTouches`,names:[`--hide-touches`],type:`boolean`,usageLabel:`--hide-touches`,usageDescription:`Record: skip touch-overlay post-processing for faster raw benchmark videos`},{key:`intervalMs`,names:[`--interval-ms`],type:`int`,min:0,max:1e4,usageLabel:`--interval-ms <ms>`,usageDescription:`Delay between press iterations`},{key:`delayMs`,names:[`--delay-ms`],type:`int`,min:0,max:1e4,usageLabel:`--delay-ms <ms>`,usageDescription:`Delay between typed characters`},{key:`durationMs`,names:[`--duration-ms`],type:`int`,min:0,max:1e4,usageLabel:`--duration-ms <ms>`,usageDescription:`Scroll: pace the gesture over this duration when supported`},{key:`holdMs`,names:[`--hold-ms`],type:`int`,min:0,max:1e4,usageLabel:`--hold-ms <ms>`,usageDescription:`Press hold duration for each iteration`},{key:`jitterPx`,names:[`--jitter-px`],type:`int`,min:0,max:100,usageLabel:`--jitter-px <n>`,usageDescription:`Deterministic coordinate jitter radius for press`},{key:`pixels`,names:[`--pixels`],type:`int`,min:1,max:1e5,usageLabel:`--pixels <n>`,usageDescription:`Scroll: explicit gesture distance in pixels`},{key:`doubleTap`,names:[`--double-tap`],type:`boolean`,usageLabel:`--double-tap`,usageDescription:`Use double-tap gesture per press iteration`},{key:`verify`,names:[`--verify`],type:`boolean`,usageLabel:`--verify`,usageDescription:`Capture cheap post-action evidence (AX digest, node counts, changedFromBefore) instead of a follow-up snapshot`},{key:`settle`,names:[`--settle`],type:`boolean`,usageLabel:`--settle`,usageDescription:`After the action, wait for the UI to go quiet and return the settled diff vs the pre-action tree in the same response (best-effort; never fails the action)`},{key:`settleQuietMs`,names:[`--settle-quiet`],type:`int`,min:0,usageLabel:`--settle-quiet <ms>`,usageDescription:`Settle: quiet window the UI must hold to count as settled (default 500ms)`},{key:`clickButton`,names:[`--button`],type:`enum`,enumValues:[`primary`,`secondary`,`middle`],usageLabel:`--button primary|secondary|middle`,usageDescription:`Click: choose mouse button (middle reserved for future macOS support)`},{key:`backMode`,names:[`--in-app`],type:`enum`,enumValues:[`in-app`,`system`],setValue:`in-app`,usageLabel:`--in-app`,usageDescription:`Back: use app-provided back UI when available`},{key:`backMode`,names:[`--system`],type:`enum`,enumValues:[`in-app`,`system`],setValue:`system`,usageLabel:`--system`,usageDescription:`Back: use system back input or gesture when available`},{key:`pauseMs`,names:[`--pause-ms`],type:`int`,min:0,max:1e4,usageLabel:`--pause-ms <ms>`,usageDescription:`Delay between swipe iterations`},{key:`pattern`,names:[`--pattern`],type:`enum`,enumValues:[`one-way`,`ping-pong`],usageLabel:`--pattern one-way|ping-pong`,usageDescription:`Swipe repeat pattern`},{key:`verbose`,names:[`--debug`,`--verbose`,`-v`],type:`boolean`,usageLabel:`--debug, --verbose, -v`,usageDescription:`Enable debug diagnostics; test --verbose prints per-test step timings without debug logs`},{key:`cost`,names:[`--cost`],type:`boolean`,usageLabel:`--cost`,usageDescription:`Include per-command wall-clock latency (cost.wallClockMs) in the response`},{key:`responseLevel`,names:[`--level`],type:`enum`,enumValues:a,usageLabel:`--level digest|default|full`,usageDescription:`Response detail level: digest (token-cheap), default (today), or full. Default keeps the wire shape unchanged.`},{key:`json`,names:[`--json`],type:`boolean`,usageLabel:`--json`,usageDescription:`JSON output`},{key:`help`,names:[`--help`,`-h`],type:`boolean`,usageLabel:`--help, -h`,usageDescription:`Print help and exit`},{key:`version`,names:[`--version`,`-V`],type:`boolean`,usageLabel:`--version, -V`,usageDescription:`Print version and exit`},{key:`snapshotDiff`,names:[`--diff`],type:`boolean`,usageLabel:`--diff`,usageDescription:`Snapshot: show structural diff against the previous session baseline`},{key:`saveScript`,names:[`--save-script`],type:`booleanOrString`,usageLabel:`--save-script [path]`,usageDescription:`Save session script (.ad) on close; optional custom output path`},{key:`networkInclude`,names:[`--include`],type:`enum`,enumValues:[`summary`,`headers`,`body`,`all`],usageLabel:`--include summary|headers|body|all`,usageDescription:`Network: include headers, bodies, or both in output`},{key:`shutdown`,names:[`--shutdown`],type:`boolean`,usageLabel:`--shutdown`,usageDescription:`close: shutdown associated simulator/emulator after ending session`},{key:`relaunch`,names:[`--relaunch`],type:`boolean`,usageLabel:`--relaunch`,usageDescription:`open: terminate app process before launching it`},{key:`restart`,names:[`--restart`],type:`boolean`,usageLabel:`--restart`,usageDescription:`logs clear: stop active stream, clear logs, then start streaming again`},{key:`retainPaths`,names:[`--retain-paths`],type:`boolean`,usageLabel:`--retain-paths`,usageDescription:`install-from-source: keep materialized artifact paths after install`},{key:`retentionMs`,names:[`--retention-ms`],type:`int`,min:1,usageLabel:`--retention-ms <ms>`,usageDescription:`install-from-source: retention TTL for materialized artifact paths`},{key:`noRecord`,names:[`--no-record`],type:`boolean`,usageLabel:`--no-record`,usageDescription:`Do not record this action`},{key:`replayUpdate`,names:[`--update`,`-u`],type:`boolean`,usageLabel:`--update, -u`,usageDescription:`Replay: update selectors and rewrite replay file in place`},{key:`replayMaestro`,names:[`--maestro`],type:`boolean`,usageLabel:`--maestro`,usageDescription:`Replay: treat input as a Maestro YAML compatibility flow. ${Le()} Unsupported syntax fails loudly with a link to ${pe}`},{key:`replayExportFormat`,names:[`--format`],type:`enum`,enumValues:[`maestro`],usageLabel:`--format maestro`,usageDescription:`Replay export: output format`},{key:`replayEnv`,names:[`-e`,`--env`],type:`string`,multiple:!0,usageLabel:`-e KEY=VALUE, --env KEY=VALUE`,usageDescription:"Replay/Test: inject or override a ${KEY} variable for the script (repeatable)"},{key:`failFast`,names:[`--fail-fast`],type:`boolean`,usageLabel:`--fail-fast`,usageDescription:`Test: stop the suite after the first failing script; with sharding, each shard stops independently`},{key:`timeoutMs`,names:[`--timeout`],type:`int`,min:1,usageLabel:`--timeout <ms>`,usageDescription:`Prepare/Replay/Snapshot/Test: maximum wall-clock time for the command or attempt. With --settle: the settle-wait deadline (default 10s)`},{key:`retries`,names:[`--retries`],type:`int`,min:0,max:3,usageLabel:`--retries <n>`,usageDescription:`Test: retry each failed script up to n additional times`},{key:`recordVideo`,names:[`--record-video`],type:`boolean`,usageLabel:`--record-video`,usageDescription:`Test: record each replay attempt to recording.mp4 in its attempt artifacts`},{key:`artifactsDir`,names:[`--artifacts-dir`],type:`string`,usageLabel:`--artifacts-dir <path>`,usageDescription:`Test: root directory for suite artifacts`},{key:`reporter`,names:[`--reporter`],type:`string`,multiple:!0,usageLabel:`--reporter <name-or-path>`,usageDescription:`Test: add a replay suite reporter; use default, junit:<path>, or a custom reporter path (repeatable)`},{key:`reportJunit`,names:[`--report-junit`],type:`string`,usageLabel:`--report-junit <path>`,usageDescription:`Test: compatibility alias for --reporter junit:<path>`},{key:`shardAll`,names:[`--shard-all`],type:`int`,min:1,usageLabel:`--shard-all <n>`,usageDescription:`Test: run the full suite on each of n devices; combine with --device id1,id2 for explicit connected devices; AD_SHARD_INDEX is zero-based`},{key:`shardSplit`,names:[`--shard-split`],type:`int`,min:1,usageLabel:`--shard-split <n>`,usageDescription:`Test: split runnable suite entries across n devices; AD_SHARD_INDEX is zero-based`},{key:`steps`,names:[`--steps`],type:`string`,usageLabel:`--steps <json>`,usageDescription:`Batch: JSON array of steps`},{key:`stepsFile`,names:[`--steps-file`],type:`string`,usageLabel:`--steps-file <path>`,usageDescription:`Batch: read steps JSON from file`},{key:`batchOnError`,names:[`--on-error`],type:`enum`,enumValues:[`stop`],usageLabel:`--on-error stop`,usageDescription:`Batch: stop when a step fails`},{key:`batchMaxSteps`,names:[`--max-steps`],type:`int`,min:1,max:1e3,usageLabel:`--max-steps <n>`,usageDescription:`Batch: maximum number of allowed steps`},{key:`appsFilter`,names:[`--all`],type:`enum`,enumValues:[`user-installed`,`all`],setValue:`all`,usageLabel:`--all`,usageDescription:`Apps: include system/OEM apps`},{key:`snapshotInteractiveOnly`,names:[`-i`],type:`boolean`,usageLabel:`-i`,usageDescription:`Snapshot: interactive elements only`},{key:`snapshotDepth`,names:[`--depth`,`-d`],type:`int`,min:0,usageLabel:`--depth, -d <depth>`,usageDescription:`Snapshot: limit snapshot depth`},{key:`snapshotScope`,names:[`--scope`,`-s`],type:`string`,usageLabel:`--scope, -s <scope>`,usageDescription:`Snapshot: scope snapshot to label/identifier`},{key:`snapshotRaw`,names:[`--raw`],type:`boolean`,usageLabel:`--raw`,usageDescription:`Snapshot: raw node output`},{key:`snapshotForceFull`,names:[`--force-full`],type:`boolean`,usageLabel:`--force-full`,usageDescription:`Snapshot: re-emit the full tree even when unchanged`},{key:`findFirst`,names:[`--first`],type:`boolean`,usageLabel:`--first`,usageDescription:`Find: pick the first match when ambiguous`},{key:`findLast`,names:[`--last`],type:`boolean`,usageLabel:`--last`,usageDescription:`Find: pick the last match when ambiguous`},{key:`out`,names:[`--out`],type:`string`,usageLabel:`--out <path>`,usageDescription:`Output path`},{key:`artifact`,names:[`--artifact`],type:`string`,usageLabel:`--artifact <path>`,usageDescription:`Debug symbols: Apple crash artifact path (.ips, .crash, or .log)`},{key:`dsym`,names:[`--dsym`],type:`string`,usageLabel:`--dsym <path>`,usageDescription:`Debug symbols: matching .dSYM bundle path`},{key:`searchPath`,names:[`--search-path`],type:`string`,usageLabel:`--search-path <dir>`,usageDescription:`Debug symbols: directory to scan for matching .dSYM bundles`},{key:`overlayRefs`,names:[`--overlay-refs`],type:`boolean`,usageLabel:`--overlay-refs`,usageDescription:`Screenshot: draw current snapshot refs and target rectangles onto the saved PNG; diff screenshot: also write a separate current-screen overlay guide`},...Qe,{key:`baseline`,names:[`--baseline`,`-b`],type:`string`,usageLabel:`--baseline, -b <path>`,usageDescription:`Diff screenshot: path to baseline image file`},{key:`threshold`,names:[`--threshold`],type:`string`,usageLabel:`--threshold <0-1>`,usageDescription:`Diff screenshot: color distance threshold (default 0.1)`}],wr=H(`remoteConfig`,`stateDir`,`daemonBaseUrl`,`daemonAuthToken`,`daemonTransport`,`daemonServerMode`,`tenant`,`sessionIsolation`,`runId`,`leaseId`,`leaseBackend`,`sessionLock`,`sessionLocked`,`sessionLockConflicts`,`platform`,`target`,`device`,`providerApp`,`providerOsVersion`,`providerProject`,`providerBuild`,`providerSessionName`,`awsProjectArn`,`awsDeviceArn`,`awsAppArn`,`awsRegion`,`awsInteractionMode`,`udid`,`serial`,`iosSimulatorDeviceSet`,`iosXctestrunFile`,`iosXctestDerivedDataPath`,`iosXctestEnvDir`,`androidDeviceAllowlist`,`session`,`noRecord`),Tr=new Set([`json`,`config`,`help`,`version`,`verbose`,`cost`,`responseLevel`]),Er=new Map;for(let e of Cr)for(let t of e.names)Er.set(t,e);function Dr(e){return Er.get(e)}function Or(){return Cr}const kr=new Set(Or().map(e=>e.key));function Ar(e,t){return{...mr(e),...t}}function jr(e,t){let n=e.inputSchema.properties;if(!n)return{};let r={},i=t;for(let e of Object.keys(n)){if(!kr.has(e))continue;let t=i[e];Mr(t)&&(r[e]=t)}return r}function Mr(e){return typeof e==`boolean`||typeof e==`number`||typeof e==`string`}function Nr(e){return t=>D(l.batch,[],{...t,batchSteps:Pr(t.steps,e),batchOnError:t.onError,batchMaxSteps:t.maxSteps})}function Pr(t,n){if(!Array.isArray(t)||t.length===0)throw new e(`INVALID_ARGS`,`batch requires a non-empty steps array.`);return t.map((e,t)=>Fr(e,t+1,n))}function Fr(e,t,n){let r=xt(e,t),i=Ir(r,t),a=vt(r,t),o=dt(r.runtime,t),s=n(i,a,t);return{command:s.command,positionals:s.positionals,flags:Ar(s.options,s.metadataFlags),runtime:o??s.options.runtime}}function Ir(e,t){return ne(e.command,t)}const Lr=Kn(),Rr=L({name:`batch`,clientSurface:!1,commands:[I({name:`batch`,metadata:Lr,definition:R(Lr,(e,t)=>e.batch.run(zr(t))),cliSchema:{usageOverride:`batch [--steps <json> | --steps-file <path>]`,listUsageOverride:`batch --steps <json> | --steps-file <path>`,helpDescription:`Execute multiple commands in one daemon request`,summary:`Run multiple commands`,allowedFlags:[`steps`,`stepsFile`,`batchOnError`,`batchMaxSteps`,`out`]},cliReader:(e,t)=>({...O(t),steps:t.batchSteps??[],onError:t.batchOnError,maxSteps:t.batchMaxSteps,out:t.out}),cliOutputFormatter:Wn.batch})]});function zr(e){return{...C(e),steps:e.steps,onError:e.onError,maxSteps:e.maxSteps,out:e.out}}function W(e,t,n){return Hn({name:e,description:t,inputSchema:qt(n),readInput:e=>Jt(e,n)})}const Br=`alert`,Vr=W(Br,`Inspect or handle platform alerts.`,{action:_(nt),timeoutMs:h()}),Hr=I({name:Br,metadata:Vr,definition:R(Vr,(e,t)=>e.command.alert(t)),cliSchema:{usageOverride:`alert [get|accept|dismiss|wait] [timeout]`,positionalArgs:[`action?`,`timeout?`]},cliReader:(e,t)=>({...O(t),...Wr(e)}),daemonWriter:E(l.alert,e=>Ur(e)),cliOutputFormatter:B});function Ur(e){return[e.action??`get`,...N(e.timeoutMs)]}function Wr(t){if(t.length>2)throw new e(`INVALID_ARGS`,`alert accepts at most action and timeout arguments.`);return w({action:Gr(t[0]),timeoutMs:Bn(t[1],`alert timeout`)})}function Gr(t){let n=t?.toLowerCase();if(n===void 0||n===`get`||n===`accept`||n===`dismiss`||n===`wait`)return n;throw new e(`INVALID_ARGS`,`alert action must be get, accept, dismiss, or wait.`)}const Kr=`diff`,qr=W(Kr,`Diff accessibility snapshots.`,{kind:f(v({type:`string`,const:`snapshot`})),out:p(),interactiveOnly:g(),depth:h(),scope:p(),raw:g()}),Jr=I({name:Kr,metadata:qr,definition:R(qr,(e,t)=>e.capture.diff(t)),cliSchema:{usageOverride:`diff snapshot | diff screenshot --baseline <path> [current.png] [--out <diff.png>] [--threshold <0-1>] [--overlay-refs]`,helpDescription:`Diff accessibility snapshot or compare screenshots pixel-by-pixel. Live iOS simulator screenshot diffs normalize status-bar chrome by default; use screenshot --normalize-status-bar when capturing reusable baselines.`,summary:`Diff snapshot or screenshot`,positionalArgs:[`kind`,`current?`],allowedFlags:[..._r,`baseline`,`threshold`,`out`,`overlayRefs`]},cliReader:(t,n)=>{if(t[0]!==`snapshot`)throw new e(`INVALID_ARGS`,`Only diff snapshot is available through this parser.`);return{...O(n),kind:`snapshot`,out:n.out,interactiveOnly:n.snapshotInteractiveOnly,depth:n.snapshotDepth,scope:n.snapshotScope,raw:n.snapshotRaw}},daemonWriter:E(l.diff,e=>[F(e.kind,`diff requires kind`)])}),Yr=`screenshot`,Xr=W(Yr,`Capture a screenshot.`,{path:p(`Output path.`),overlayRefs:g(),fullscreen:g(),maxSize:h(),stabilize:g(),normalizeStatusBar:g(),surface:_(Ee)}),Zr=I({name:Yr,metadata:Xr,definition:R(Xr,(e,t)=>e.capture.screenshot(t)),cliSchema:{helpDescription:`Capture screenshot (web defaults to the viewport; use --fullscreen, --full, or -f for the entire page. macOS app sessions default to the app window; use --fullscreen for full desktop, --max-size to downscale, --overlay-refs to annotate current refs, --normalize-status-bar for deterministic iOS simulator chrome, or --no-stabilize for low-latency Android capture loops)`,summary:`Capture screenshot with optional web full-page, desktop, downscale, or ref overlay modes`,positionalArgs:[`path?`],allowedFlags:ze},cliReader:(e,t)=>({...O(t),path:e[0]??t.out,...Be(t)}),daemonWriter:e=>D(l.screenshot,M(e.path),{...e,...Ge(e)})}),Qr=`settings`,$r=W(Qr,`Change OS settings and app permissions.`,{setting:f(p()),state:f(p()),app:p(),latitude:m(),longitude:m(),permission:p(),mode:_([`full`,`limited`])}),ei=I({name:Qr,metadata:$r,definition:R($r,(e,t)=>e.settings.update(t)),cliSchema:{usageOverride:it,listUsageOverride:`settings [area] [options]`,helpDescription:`Toggle OS settings, animation scales, appearance, and app permissions (macOS supports only settings appearance <light|dark|toggle> and settings permission <grant|reset> <accessibility|screen-recording|input-monitoring>; wifi|airplane|location|animations remain unsupported on macOS; mobile permission actions use the active session app)`,summary:`Change OS settings and app permissions`,positionalArgs:[`setting`,`state`,`target?`,`mode?`]},cliReader:(e,t)=>ti(e,t),daemonWriter:E(l.settings,e=>ni(e))});function ti(t,n){let r=Cn(n),i=t[0],a=t[1];if(A(i,ai)&&A(a,oi))return{...r,setting:i,state:a};if(i===`location`&&a===`set`)return{...r,setting:i,state:a,latitude:et(t[2],`latitude`),longitude:et(t[3],`longitude`)};if(i===`appearance`&&A(a,si)||A(i,ci)&&A(a,li)||i===`fingerprint`&&A(a,ui))return{...r,setting:i,state:a};if(i===`permission`&&A(a,di))return{...r,setting:i,state:a,permission:ri(t[2]),mode:ii(t[3])};if(i===`clear-app-state`){let e=a===`clear`?t[2]:a;return{...r,setting:i,state:`clear`,app:e}}throw new e(`INVALID_ARGS`,`Invalid settings arguments.`)}function ni(e){return e.setting===`clear-app-state`?[e.setting,...M(e.app)]:e.setting===`location`&&e.state===`set`?[e.setting,e.state,String(e.latitude),String(e.longitude)]:e.setting===`permission`?[e.setting,e.state,e.permission,...M(e.mode)]:[e.setting,e.state]}function ri(t){if(A(t,fi))return t;throw new e(`INVALID_ARGS`,`settings permission requires a permission target.`)}function ii(t){if(t===void 0||t===`full`||t===`limited`)return t;throw new e(`INVALID_ARGS`,`settings permission mode must be full or limited.`)}const ai=k(`wifi`,`airplane`,`location`,`animations`),oi=k(`on`,`off`),si=k(`light`,`dark`,`toggle`),ci=k(`faceid`,`touchid`),li=k(`match`,`nonmatch`,`enroll`,`unenroll`),ui=k(`match`,`nonmatch`),di=k(`grant`,`deny`,`reset`),fi=k(`camera`,`microphone`,`photos`,`contacts`,`contacts-limited`,`notifications`,`calendar`,`location`,`location-always`,`media-library`,`motion`,`reminders`,`siri`,`accessibility`,`screen-recording`,`input-monitoring`);function pi(e){if(!Array.isArray(e)||e.length===0)return e;let t=ot(e);return e.map(e=>{let n=mi(e,t,e=>e.label),r=mi(e,t,e=>e.identifier),i=typeof e.label==`string`&&e.label.length>=24&&e.label===n,a=typeof e.identifier==`string`&&e.identifier.length>=24&&e.identifier===r;if(!i&&!a)return e;let o={...e};return i&&(delete o.label,o.inheritsLabel=!0),a&&(delete o.identifier,o.inheritsIdentifier=!0),o})}function mi(e,t,n){let r=typeof e.parentIndex==`number`?t.get(e.parentIndex):void 0;for(;r;){let e=n(r);if(typeof e==`string`&&e.length>0)return e;r=typeof r.parentIndex==`number`?t.get(r.parentIndex):void 0}}function hi(e){let t=Ne(e.raw||!Array.isArray(e.result.nodes)?e.result:{...e.result,nodes:pi(e.result.nodes)});return{data:t,jsonData:_i(t),stderr:e.result.snapshotDiagnostics?.warning?`${e.result.snapshotDiagnostics.warning}\n`:void 0,text:he(t,{raw:e.raw,flatten:e.interactiveOnly,scoped:typeof e.scope==`string`&&e.scope.trim().length>0,depthLimited:typeof e.depth==`number`})}}const gi={snapshot:({input:e,result:t})=>hi({result:t,raw:e.raw,interactiveOnly:e.interactiveOnly,scope:e.scope,depth:e.depth}),wait:B,alert:B};function _i(e){let{unchanged:t,...n}=e;return n}const vi=`snapshot`,yi=W(vi,`Capture an accessibility snapshot.`,{interactiveOnly:g(),depth:h(),scope:p(),raw:g(),forceFull:g(),timeoutMs:h(`Maximum wall-clock time for the snapshot command.`)}),bi=I({name:vi,metadata:yi,definition:R(yi,(e,t)=>e.capture.snapshot(t)),cliSchema:{usageOverride:`snapshot [--diff] [-i] [-d <depth>] [-s <scope>] [--raw] [--force-full] [--timeout <ms>]`,helpDescription:`Capture accessibility tree or diff against the previous session baseline. For iOS raw-coordinate fallback after a no-op ref press, inspect rects with snapshot -i --json, press the rect center, then verify with diff snapshot -i or snapshot --diff.`,summary:`Capture accessibility tree or diff against the previous session baseline`,allowedFlags:[`snapshotDiff`,..._r,`snapshotForceFull`,`timeoutMs`]},cliReader:(e,t)=>({...O(t),interactiveOnly:t.snapshotInteractiveOnly,depth:t.snapshotDepth,scope:t.snapshotScope,raw:t.snapshotRaw,forceFull:t.snapshotForceFull,timeoutMs:t.timeoutMs}),daemonWriter:E(l.snapshot),cliOutputFormatter:gi.snapshot}),xi=[`duration`,`text`,`ref`,`selector`,`stable`],Si=`wait`,Ci=W(Si,`Wait for duration, text, ref, selector, or stable UI.`,{kind:_(xi),durationMs:h(),text:p(),ref:p(),selector:p(),stable:g(),quietMs:h(),timeoutMs:h(),depth:h(),scope:p(),raw:g()}),wi=I({name:Si,metadata:Ci,definition:R(Ci,(e,t)=>e.command.wait(Ti(t))),cliSchema:{usageOverride:`wait <ms>|text <text>|@ref|<selector>|stable [quietMs] [timeoutMs]`,positionalArgs:[`durationOrSelector`,`timeoutMs?`],allowsExtraPositionals:!0,allowedFlags:[...U]},cliReader:(e,t)=>Ei(e,t),daemonWriter:E(l.wait,e=>Di(e)),cliOutputFormatter:B});function Ti(e){an(e,`kind`,xi);let t={...e};return delete t.kind,t}function Ei(t,n){let r=te(t);if(!r)throw new e(`INVALID_ARGS`,`wait requires <ms>, text <text>, @ref, <selector> [timeoutMs], or stable [quietMs] [timeoutMs].`);let i={...Cn(n),...Tn(n)};if(r.kind===`sleep`)return{...i,durationMs:r.durationMs};if(r.kind===`text`){if(!r.text)throw new e(`INVALID_ARGS`,`wait requires text.`);return{...i,text:r.text,...Oi(r.timeoutMs)}}return r.kind===`ref`?{...i,ref:r.rawRef,...Oi(r.timeoutMs)}:r.kind===`stable`?{...i,stable:!0,...ki(r.quietMs),...Oi(r.timeoutMs)}:{...i,selector:r.selectorExpression,...Oi(r.timeoutMs)}}function Di(t){if([t.durationMs===void 0?void 0:`durationMs`,t.text===void 0?void 0:`text`,t.ref===void 0?void 0:`ref`,t.selector===void 0?void 0:`selector`,t.stable===void 0?void 0:`stable`].filter(Boolean).length!==1)throw new e(`INVALID_ARGS`,`wait command requires exactly one of durationMs, text, ref, selector, or stable.`);if(t.durationMs!==void 0)return[String(t.durationMs)];let n=N(t.timeoutMs);if(t.text!==void 0)return[`text`,t.text,...n];if(t.ref!==void 0)return[t.ref,...n];if(t.stable!==void 0){let r=N(t.quietMs);if(r.length===0&&n.length>0)throw new e(`INVALID_ARGS`,`wait stable requires quietMs before timeoutMs.`);return[`stable`,...r,...n]}let r=t.selector;if(!se(r))throw new e(`INVALID_ARGS`,`Invalid wait selector: ${r}`);return[r,...n]}function Oi(e){return e===null?{}:{timeoutMs:e}}function ki(e){return e===null?{}:{quietMs:e}}const Ai=L({name:`capture`,commands:[bi,Zr,Jr,wi,Hr,ei]});function ji(e){let t=[e.outPath,e.message];t.push(...Ni(e));for(let n of e.matchedImages)t.push(`Matched: ${n.name} ${n.uuid}${n.arch?` ${n.arch}`:``}`);for(let n of e.warnings??[])t.push(`Warning: ${n}`);return{data:e,text:t.join(`
|
|
3
|
+
`)}}const Mi={debug:z(ji)};function Ni(e){let t=e.crash,n=[`Crash: ${t.appName??`unknown app`}${t.crashedThread===void 0?``:` thread ${t.crashedThread}`}`];t.bundleId&&n.push(`Bundle: ${t.bundleId}`),t.exceptionType&&n.push(`Exception: ${t.exceptionType}`),t.terminationReason&&n.push(`Termination: ${t.terminationReason}`);for(let e of t.topFrames)n.push(`Frame ${e.index}: ${e.image} ${e.symbol??e.address}`);for(let e of t.findings)n.push(`Finding: ${e}`);return n}const Pi=`debug`,Fi=W(Pi,`Symbolicate crash artifacts with matching debug symbols.`,{action:f(_([`symbols`])),artifact:f(p(`Apple crash artifact path (.ips, .crash, or .log).`)),dsym:p(`Path to a matching .dSYM bundle.`),searchPath:p(`Directory to scan for matching .dSYM bundles.`),out:p(`Output path for the symbolicated artifact.`)}),Ii=L({name:`debugging`,commands:[I({name:Pi,metadata:Fi,definition:R(Fi,(e,t)=>e.debug.symbols(t)),cliSchema:{usageOverride:`debug symbols --artifact <crash.ips|crash.log> (--dsym <App.dSYM> | --search-path <dir>) [--out <symbolicated>]`,listUsageOverride:`debug`,helpDescription:`Symbolicate Apple crash artifacts with matching dSYM UUIDs. This debug namespace is intentionally narrow: use logs for app logs, network for HTTP evidence, perf for performance samples, record/trace for media and traces, and react-devtools for React Native profiles.`,summary:`Symbolicate Apple crash artifacts with dSYMs; use logs/network/perf for other diagnostics`,positionalArgs:[`symbols`],allowedFlags:[`artifact`,`dsym`,`searchPath`,`out`]},cliReader:(e,t)=>({...O(t),action:Li(e[0]),artifact:t.artifact,dsym:t.dsym,searchPath:t.searchPath,out:t.out}),cliOutputFormatter:Mi.debug})]});function Li(t){if(t===`symbols`)return t;throw new e(`INVALID_ARGS`,`debug supports only symbols; use logs, network, perf, record, trace, or react-devtools for other diagnostics`)}const Ri=[`click`,`focus`,`exists`,`getText`,`getAttrs`,`wait`,`fill`,`type`],zi={click:`Click or tap a semantic UI target by ref, selector, or point.`,press:`Press a semantic UI target by ref, selector, or point.`,fill:`Fill text into a semantic UI target by ref, selector, or point.`,longpress:`Long press by ref, selector, or point.`,swipe:`Swipe between two points.`,focus:`Focus input at coordinates.`,type:`Type text in the focused field.`,scroll:`Scroll in a direction or to an edge.`,get:`Get element text or attributes.`,is:`Assert UI state.`,find:`Find an element and optionally act on it.`,gesture:`Run a structured gesture.`},Bi=()=>g(`Capture cheap post-action evidence (AX digest, node counts, changedFromBefore) instead of a follow-up snapshot.`),Vi=()=>({settle:g(`After the action, wait for the UI to go quiet and return the settled diff vs the pre-action tree in the same response. Best-effort; never fails the action.`),settleQuietMs:h(`Settle: quiet window in milliseconds (default 500).`,{min:0}),timeoutMs:h(`Settle: wait deadline in milliseconds (default 10000).`,{min:1})});function Hi(e){return{...ee(e)?{verify:Bi()}:{},...ie(e)?Vi():{}}}const Ui={target:f(Ht()),button:_(Ve,`Pointer button for platforms that support mouse buttons.`),...Gt(),...Kt(),...Hi(`click`)},Wi={target:f(Ht()),...Gt(),...Kt(),...Hi(`press`)},Gi={target:f(Ht()),text:f(p(`Text to enter into the target.`)),delayMs:h(`Delay between typed characters.`,{min:0}),...Gt(),...Hi(`fill`)},Ki={target:f(Ht()),durationMs:h(`Long press duration in milliseconds.`,{min:0}),...Gt(),...Hi(`longpress`)},qi={from:f(Wt(`Swipe start point.`)),to:f(Wt(`Swipe end point.`)),durationMs:h(`Swipe duration in milliseconds.`,{min:0}),count:h(`Number of swipe repetitions.`,{min:1}),pauseMs:h(`Pause between repeated swipes.`,{min:0}),pattern:_(xe)},Ji={x:f(m(`X coordinate.`)),y:f(m(`Y coordinate.`))},Yi={text:f(p(`Text to type.`)),delayMs:h(`Delay between typed characters.`,{min:0})},Xi={direction:f(_(Ze)),amount:m(`Platform scroll amount.`),pixels:h(`Pixel scroll amount.`,{min:0}),durationMs:h(`Scroll duration in milliseconds when the backend supports pacing.`,{min:0,max:$e})},Zi={format:f(_([`text`,`attrs`])),target:f(Ut()),...Gt()},Qi={predicate:f(_([`visible`,`hidden`,`exists`,`editable`,`selected`,`text`])),selector:f(p()),value:p(),...Gt()},$i={locator:_(Ct),query:f(p()),action:_(Ri),value:p(),timeoutMs:h(),first:g(),last:g(),depth:h(),raw:g()},ea={kind:f(_(oe,`Gesture variant.`)),direction:_(Oe,`Fling direction.`),preset:_(ce,`Swipe preset.`),origin:Wt(`Gesture origin point.`),delta:Wt(`Movement delta for pan or transform gestures.`),distance:h(`Fling distance.`,{min:0}),scale:m(`Pinch or transform scale.`),degrees:m(`Rotation in degrees.`),velocity:h(`Rotate gesture velocity.`,{min:0}),durationMs:h(`Gesture duration in milliseconds.`,{min:0})},ta=[Hn({name:`click`,description:zi.click,inputSchema:qt(Ui),readInput:e=>Jt(e,Ui)}),Hn({name:`press`,description:zi.press,inputSchema:qt(Wi),readInput:e=>Jt(e,Wi)}),Hn({name:`fill`,description:zi.fill,inputSchema:qt(Gi),readInput:e=>Jt(e,Gi)}),G(`longpress`,Ki),G(`swipe`,qi),G(`focus`,Ji),G(`type`,Yi),G(`scroll`,Xi),G(`get`,Zi),G(`is`,Qi),G(`find`,$i),Hn({name:`gesture`,description:zi.gesture,inputSchema:qt(ea),readInput:na})];function na(e){let t=Yt(e),n=Xt(t),r=rn(t,`kind`,oe);return r===`pan`?{...n,kind:r,origin:y(t,`origin`),delta:y(t,`delta`),durationMs:S(t,`durationMs`,{min:0})}:r===`fling`?{...n,kind:r,direction:rn(t,`direction`,Oe),origin:y(t,`origin`),distance:S(t,`distance`,{min:0}),durationMs:S(t,`durationMs`,{min:0})}:r===`swipe`?{...n,kind:r,preset:rn(t,`preset`,ce),durationMs:S(t,`durationMs`,{min:0})}:r===`pinch`?{...n,kind:r,scale:x(t,`scale`),origin:ra(t,`origin`)}:r===`rotate`?{...n,kind:r,degrees:x(t,`degrees`),origin:ra(t,`origin`),velocity:S(t,`velocity`,{min:0})}:{...n,kind:r,origin:y(t,`origin`),delta:y(t,`delta`),scale:x(t,`scale`),degrees:x(t,`degrees`),durationMs:S(t,`durationMs`,{min:0})}}function G(e,t){return W(e,zi[e],t)}function ra(e,t){return e[t]===void 0?void 0:y(e,t)}const ia={gesture:pa},aa={gesture:E(l.gesture,oa),"gesture-pan":E(l.gesture,ca),"gesture-fling":E(l.gesture,e=>la(e)),"gesture-swipe":E(l.gesture,sa),"gesture-pinch":E(l.gesture,ua),"gesture-rotate":E(l.gesture,e=>da(e)),"gesture-transform":E(l.gesture,fa)};function oa(t){switch(t.kind){case`pan`:return[`pan`,String(t.origin?.x),String(t.origin?.y),String(t.delta?.x),String(t.delta?.y),...N(t.durationMs)];case`fling`:return[`fling`,F(t.direction,`gesture fling requires direction`),String(t.origin?.x),String(t.origin?.y),...N(t.distance),...N(t.durationMs)];case`swipe`:return sa(t);case`pinch`:return[`pinch`,String(t.scale),...N(t.origin?.x),...N(t.origin?.y)];case`rotate`:return[`rotate`,String(t.degrees),...N(t.origin?.x),...N(t.origin?.y),...N(t.velocity)];case`transform`:return[`transform`,String(t.origin?.x),String(t.origin?.y),String(t.delta?.x),String(t.delta?.y),String(t.scale),String(t.degrees),...N(t.durationMs)];default:throw new e(`INVALID_ARGS`,`gesture requires pan, fling, swipe, pinch, rotate, or transform`)}}function sa(e){return[`swipe`,F(e.preset,`gesture swipe requires preset`),...N(e.durationMs)]}function ca(e){return[`pan`,String(e.x),String(e.y),String(e.dx),String(e.dy),...N(e.durationMs)]}function la(e){let t=e.durationMs===void 0?e.distance:e.distance??180;return[`fling`,e.direction,String(e.x),String(e.y),...N(t),...N(e.durationMs)]}function ua(e){return[`pinch`,String(e.scale),...N(e.x),...N(e.y)]}function da(e){ma(e);let t=e.x===void 0||e.y===void 0?[]:[String(e.x),String(e.y)];return[`rotate`,String(e.degrees),...t,...N(e.velocity)]}function fa(e){return[`transform`,String(e.x),String(e.y),String(e.dx),String(e.dy),String(e.scale),String(e.degrees),...N(e.durationMs)]}function pa(t,n){let r=t[0],i=t.slice(1),a=O(n);switch(r){case`pan`:return{...a,kind:r,origin:{x:Number(i[0]),y:Number(i[1])},delta:{x:Number(i[2]),y:Number(i[3])},durationMs:j(i[4])};case`fling`:return{...a,kind:r,direction:i[0],origin:{x:Number(i[1]),y:Number(i[2])},distance:j(i[3]),durationMs:j(i[4])};case`swipe`:return{...a,kind:r,preset:i[0],durationMs:j(i[1])};case`pinch`:return{...a,kind:r,scale:Number(i[0]),origin:i[1]===void 0||i[2]===void 0?void 0:{x:Number(i[1]),y:Number(i[2])}};case`rotate`:return{...a,kind:r,degrees:Number(i[0]),origin:i[1]===void 0||i[2]===void 0?void 0:{x:Number(i[1]),y:Number(i[2])},velocity:j(i[3])};case`transform`:return{...a,kind:r,origin:{x:Number(i[0]),y:Number(i[1])},delta:{x:Number(i[2]),y:Number(i[3])},scale:Number(i[4]),degrees:Number(i[5]),durationMs:j(i[6])};default:throw new e(`INVALID_ARGS`,`gesture requires pan, fling, swipe, pinch, rotate, or transform`)}}function ma(t){if(t.x===void 0&&t.y!==void 0||t.x!==void 0&&t.y===void 0)throw new e(`INVALID_ARGS`,`gesture rotate center requires both x and y`)}const K={click:(e,t)=>({...O(t),...wn(t),...Dn(t),...En(t),target:On(Re(e)),button:t.clickButton,verify:t.verify}),press:(e,t)=>({...O(t),...wn(t),...Dn(t),...En(t),target:On(Re(e)),verify:t.verify}),longpress:(e,t)=>{let n=ha(e);return{...O(t),...wn(t),...En(t),target:On(n),durationMs:n.durationMs}},swipe:(e,t)=>({...O(t),from:{x:Number(e[0]),y:Number(e[1])},to:{x:Number(e[2]),y:Number(e[3])},durationMs:j(e[4]),count:t.count,pauseMs:t.pauseMs,pattern:t.pattern}),focus:(e,t)=>({...O(t),x:Number(e[0]),y:Number(e[1])}),type:(e,t)=>({...O(t),text:e.join(` `),delayMs:t.delayMs}),fill:(e,t)=>{let n=ke(e);return{...O(t),...wn(t),...En(t),target:On(n.target),text:n.text,delayMs:t.delayMs,verify:t.verify}},scroll:(e,t)=>({...O(t),direction:ba(e[0]),amount:j(e[1]),pixels:t.pixels,durationMs:t.durationMs}),get:(e,t)=>({...O(t),...wn(t),format:Fn(e[0]),target:On(Pn(e.slice(1)))})},q={click:e=>D(l.click,kn(e),{...e,clickButton:e.button}),press:E(l.press,e=>kn(e)),longpress:E(l.longPress,e=>ga(e)),swipe:E(l.swipe,ya),focus:E(l.focus,e=>[String(e.x),String(e.y)]),type:E(l.type,e=>_a(e)),fill:E(l.fill,e=>va(e)),scroll:E(l.scroll,e=>[F(e.direction,`scroll requires direction`),...N(e.amount)]),get:E(l.get,e=>[F(e.format,`get requires format`),...An(e)])};function ha(e){let t=xa(e);return{...Re(t.target),...t.durationMs===void 0?{}:{durationMs:t.durationMs}}}function ga(e){return[...kn(e),...N(e.durationMs)]}function _a(e){return[e.text]}function va(e){return[...kn(e),e.text]}function ya(e){return[String(e.from?.x),String(e.from?.y),String(e.to?.x),String(e.to?.y),...N(e.durationMs)]}function ba(t){if(t===`up`||t===`down`||t===`left`||t===`right`||t===`top`||t===`bottom`)return t;throw new e(`INVALID_ARGS`,`Unknown direction: ${String(t)}`)}function xa(e){if(zn(e[0])&&zn(e[1]))return{target:e.slice(0,2),...e[2]===void 0?{}:{durationMs:Number(e[2])}};let t=e.at(-1);return e.length>1&&zn(t)?{target:e.slice(0,-1),durationMs:Number(t)}:{target:e}}function Sa(e){let t=e.result;return e.format===`text`?{data:t,text:typeof t.text==`string`?t.text:``}:e.format===`attrs`?{data:t,text:JSON.stringify(t.node??{},null,2)}:ja(t)}function Ca(e){let t=e,n=je(t);return n?{data:t,text:n}:typeof t.text==`string`?{data:t,text:t.text}:typeof t.found==`boolean`?{data:t,text:`Found: ${t.found}`}:t.node?{data:t,text:JSON.stringify(t.node,null,2)}:ja(t)}function wa(e){let t=e;return{data:t,text:`Passed: is ${t.predicate??`assertion`}`}}function Ta(e){let t=e,n=t.ref??``,r=t.x,i=t.y;if(!n||typeof r!=`number`||typeof i!=`number`){let e=ja(t);return{data:e.data,text:Da(e.text,t.settle)}}return{data:t,text:Da(`Tapped @${n} (${r}, ${i})`,t.settle)}}function Ea(e){let t=e,n=ja(t);return{data:n.data,text:Da(n.text,t.settle)}}function Da(e,t){return`${e??``}${Oa(t)}`}function Oa(e){if(!e||typeof e!=`object`)return``;let t=e,n=[Aa(t),...ka(t.diff)];return t.hint&&n.push(`hint: ${t.hint}`),`\n${n.join(`
|
|
4
|
+
`)}`}function ka(e){let t=(e?.lines??[]).map(e=>`${e.kind===`removed`?`-`:`+`} ${e.text??``}`);return e?.truncated&&t.push(`… changed lines truncated`),t}function Aa(e){let t=e.settled===!0?`settled`:`not settled`,n=e.diff?.summary,r=n?` +${n.additions??0} -${n.removals??0} (~${n.unchanged??0} unchanged)`:``;return`${t} after ${e.waitedMs??0}ms:${r}`}const J={click:z(Ta),press:z(Ta),fill:z(Ea),longpress:z(Ea),get:({input:e,result:t})=>Sa({result:t,format:e.format}),is:z(wa),find:z(Ca)};function ja(e){return V(e)}const Ma={find:(e,t)=>Ia(e,t),is:(e,t)=>La(e,t)},Na={is:E(l.is,e=>Pa(e)),find:e=>D(l.find,Fa(e),{...e,findFirst:e.first,findLast:e.last})};function Pa(e){return[e.predicate,e.selector,...e.predicate===`text`?[e.value]:[]]}function Fa(e){let t=e.locator&&e.locator!==`any`?[e.locator,e.query]:[e.query];switch(e.action){case void 0:case`click`:case`focus`:case`exists`:return e.action?[...t,e.action]:t;case`getText`:return[...t,`get`,`text`];case`getAttrs`:return[...t,`get`,`attrs`];case`wait`:return[...t,`wait`,...N(e.timeoutMs)];case`fill`:case`type`:return[...t,e.action,e.value]}}function Ia(t,n){let r={...za(n),...Cn(n),first:n.findFirst,last:n.findLast},i=Ra(t[0]),a=i!==void 0,o=a?t[1]:t[0],s=a?2:1,c=t[s];if(c===void 0)return{...r,locator:i,query:Ba(o)};if(c===`get`){let n=t[s+1];if(n===`text`)return{...r,locator:i,query:Ba(o),action:`getText`};if(n===`attrs`)return{...r,locator:i,query:Ba(o),action:`getAttrs`};throw new e(`INVALID_ARGS`,`find get only supports text or attrs`)}if(c===`wait`)return{...r,locator:i,query:Ba(o),action:`wait`,timeoutMs:j(t[s+1])};if(c===`fill`||c===`type`)return{...r,locator:i,query:Ba(o),action:c,value:t.slice(s+1).join(` `)};if(c===`click`||c===`focus`||c===`exists`)return{...r,locator:i,query:Ba(o),action:c};throw new e(`INVALID_ARGS`,`Unsupported find action: ${c}`)}function La(t,n){let r={...Tn(n),...Cn(n)},i=ct(t),a=i[0];if(a!==`text`&&a!==`visible`&&a!==`hidden`&&a!==`exists`&&a!==`editable`&&a!==`selected`)throw new e(`INVALID_ARGS`,st,{hint:lt});let o=In(i.slice(1),{preferTrailingValue:a===`text`});return a===`text`?{...r,predicate:a,selector:o.selectorExpression,value:o.rest.join(` `)}:{...r,predicate:a,selector:o.selectorExpression}}function Ra(e){if(e===`text`||e===`label`||e===`value`||e===`role`||e===`id`)return e}function za(e){return{depth:e.snapshotDepth,raw:e.snapshotRaw}}function Ba(t){if(t===void 0||t===``)throw new e(`INVALID_ARGS`,`find requires query`);return t}const Y={get:{usageOverride:`get text|attrs <@ref|selector>`,positionalArgs:[`subcommand`,`target`],allowedFlags:[...U]},find:{usageOverride:`find <locator|text> <action> [value] [--first|--last]`,helpDescription:`Find by text/label/value/role/id and run action`,summary:`Find an element and act`,positionalArgs:[`query`,`action`,`value?`],allowsExtraPositionals:!0,allowedFlags:[`snapshotDepth`,`snapshotRaw`,`findFirst`,`findLast`]},is:{positionalArgs:[`predicate`,`selector`,`value?`],allowsExtraPositionals:!0,allowedFlags:[...U]},click:{usageOverride:`click <x y|@ref|selector>`,positionalArgs:[`target`],allowsExtraPositionals:!0,allowedFlags:[...br,`clickButton`,...Ua(`click`),...U]},press:{usageOverride:`press <x y|@ref|selector>`,helpDescription:`Short press a semantic UI target by ref, selector, or point. For native context menus or hold gestures, use longpress <target> <durationMs> instead of press --hold-ms.`,positionalArgs:[`targetOrX`,`y?`],allowsExtraPositionals:!0,allowedFlags:[...br,...Ua(`press`),...U]},longpress:{usageOverride:`longpress <x y|@ref|selector> [durationMs]`,helpDescription:`Open native context menus or long-press targets by ref, selector, or point. Duration is positional, for example longpress @e12 800 or longpress 300 500 800.`,positionalArgs:[`targetOrX`,`yOrDurationMs?`,`durationMs?`],allowsExtraPositionals:!0,allowedFlags:[...Ua(`longpress`),...U]},swipe:{helpDescription:`Swipe coordinates with optional repeat pattern`,positionalArgs:[`x1`,`y1`,`x2`,`y2`,`durationMs?`],allowedFlags:[`count`,`pauseMs`,`pattern`]},gesture:{usageOverride:`gesture <pan|fling|swipe|pinch|rotate|transform> ...`,listUsageOverride:`gesture <pan|fling|swipe|pinch|rotate|transform> ...`,helpDescription:`Run touch gestures: pan <x> <y> <dx> <dy> [durationMs], fling <up|down|left|right> <x> <y> [distance] [durationMs], swipe <left|right|left-edge|right-edge> [durationMs], pinch <scale> [x] [y], rotate <degrees> [x] [y] [velocity], or transform <x> <y> <dx> <dy> <scale> <degrees> [durationMs]. For command plans, output only command lines. Android transform verification should use all app-observable effects, for example wait text "pan changed yes", wait text "pinch changed yes", and wait text "rotate changed yes", not exact transform values.`,summary:`Run pan, fling, swipe, pinch, rotate, or transform gestures`,positionalArgs:[`pan|fling|swipe|pinch|rotate|transform`,`args?`],allowsExtraPositionals:!0},focus:{positionalArgs:[`x`,`y`]},type:{positionalArgs:[`text`],allowsExtraPositionals:!0,allowedFlags:[`delayMs`]},fill:{usageOverride:`fill <x> <y> <text> | fill <@ref|selector> <text>`,positionalArgs:[`targetOrX`,`yOrText`,`text?`],allowsExtraPositionals:!0,allowedFlags:[...U,`delayMs`,...Ua(`fill`)]},scroll:{usageOverride:`scroll <direction|top|bottom> [amount] [--pixels <n>] [--duration-ms <ms>]`,helpDescription:`Scroll in a direction, or toward the top/bottom edge of scrollable content.`,summary:`Scroll in a direction or to an edge`,positionalArgs:[`directionOrEdge`,`amount?`],allowedFlags:[`pixels`,`durationMs`]}},{gesture:Va,...Ha}=aa;function Ua(e){let t=[];return ee(e)&&t.push(`verify`),ie(e)&&t.push(...xr),t}const Wa=R(X(`click`),(e,t)=>e.interactions.click(ro(t))),Ga=R(X(`press`),(e,t)=>e.interactions.press(io(t))),Ka=R(X(`fill`),(e,t)=>e.interactions.fill(ao(t))),qa=R(X(`longpress`),(e,t)=>e.interactions.longPress(oo(t))),Ja=R(X(`swipe`),(e,t)=>e.interactions.swipe(t)),Ya=R(X(`focus`),(e,t)=>e.interactions.focus(t)),Xa=R(X(`type`),(e,t)=>e.interactions.type(t)),Za=R(X(`scroll`),(e,t)=>e.interactions.scroll(t)),Qa=R(X(`get`),(e,t)=>e.interactions.get(co(t))),$a=R(X(`is`),(e,t)=>e.interactions.is(t)),eo=R(X(`find`),(e,t)=>e.interactions.find(t)),to=R(X(`gesture`),async(e,t)=>{switch(t.kind){case`pan`:return await e.interactions.pan(lo(t));case`fling`:return await e.interactions.fling(uo(t));case`swipe`:return await e.interactions.swipeGesture(fo(t));case`pinch`:return await e.interactions.pinch(po(t));case`rotate`:return await e.interactions.rotateGesture(mo(t));case`transform`:return await e.interactions.transformGesture(ho(t))}}),no=L({name:`interaction`,clientSurface:!1,commands:[I({name:`click`,metadata:X(`click`),definition:Wa,cliSchema:Y.click,cliReader:K.click,daemonWriter:q.click,cliOutputFormatter:J.click}),I({name:`press`,metadata:X(`press`),definition:Ga,cliSchema:Y.press,cliReader:K.press,daemonWriter:q.press,cliOutputFormatter:J.press}),I({name:`fill`,metadata:X(`fill`),definition:Ka,cliSchema:Y.fill,cliReader:K.fill,daemonWriter:q.fill,cliOutputFormatter:J.fill}),I({name:`longpress`,metadata:X(`longpress`),definition:qa,cliSchema:Y.longpress,cliReader:K.longpress,daemonWriter:q.longpress,cliOutputFormatter:J.longpress}),I({name:`swipe`,metadata:X(`swipe`),definition:Ja,cliSchema:Y.swipe,cliReader:K.swipe,daemonWriter:q.swipe}),I({name:`focus`,metadata:X(`focus`),definition:Ya,cliSchema:Y.focus,cliReader:K.focus,daemonWriter:q.focus}),I({name:`type`,metadata:X(`type`),definition:Xa,cliSchema:Y.type,cliReader:K.type,daemonWriter:q.type}),I({name:`scroll`,metadata:X(`scroll`),definition:Za,cliSchema:Y.scroll,cliReader:K.scroll,daemonWriter:q.scroll}),I({name:`get`,metadata:X(`get`),definition:Qa,cliSchema:Y.get,cliReader:K.get,daemonWriter:q.get,cliOutputFormatter:J.get}),I({name:`is`,metadata:X(`is`),definition:$a,cliSchema:Y.is,cliReader:Ma.is,daemonWriter:Na.is,cliOutputFormatter:J.is}),I({name:`find`,metadata:X(`find`),definition:eo,cliSchema:Y.find,cliReader:Ma.find,daemonWriter:Na.find,cliOutputFormatter:J.find}),I({name:`gesture`,metadata:X(`gesture`),definition:to,cliSchema:Y.gesture,cliReader:ia.gesture,daemonWriter:aa.gesture,extraDaemonWriters:Ha})]});function X(e){let t=ta.find(t=>t.name===e);if(!t)throw Error(`Missing interaction command metadata for ${e}`);return t}function ro(e){return{...C(e),...on(e.target),...ln(e),...cn(e),button:e.button,verify:e.verify,...so(e)}}function io(e){return{...C(e),...on(e.target),...ln(e),...cn(e),verify:e.verify,...so(e)}}function ao(e){return{...C(e),...on(e.target),...ln(e),text:e.text,delayMs:e.delayMs,verify:e.verify,...so(e)}}function oo(e){return{...C(e),...on(e.target),...ln(e),durationMs:e.durationMs,...so(e)}}function so(e){return{settle:e.settle,settleQuietMs:e.settleQuietMs,timeoutMs:e.timeoutMs}}function co(e){return{...C(e),...sn(e.target),...ln(e),format:e.format}}function lo(e){return{...C(e),x:e.origin.x,y:e.origin.y,dx:e.delta.x,dy:e.delta.y,durationMs:e.durationMs}}function uo(e){return{...C(e),direction:e.direction,x:e.origin.x,y:e.origin.y,distance:e.distance,durationMs:e.durationMs}}function fo(e){return{...C(e),preset:e.preset,durationMs:e.durationMs}}function po(e){return{...C(e),scale:e.scale,x:e.origin?.x,y:e.origin?.y}}function mo(e){return{...C(e),degrees:e.degrees,x:e.origin?.x,y:e.origin?.y,velocity:e.velocity}}function ho(e){return{...C(e),x:e.origin.x,y:e.origin.y,dx:e.delta.x,dy:e.delta.y,scale:e.scale,degrees:e.degrees,durationMs:e.durationMs}}function go(e){return{data:{devices:e.map(Ae)},text:e.map(ko).join(`
|
|
5
|
+
`)}}function _o(e){return{data:{device:Ae(e.device),availableCommands:e.availableCommands},text:[`${ko(e.device)} supports ${e.availableCommands.length} commands:`,e.availableCommands.join(` `)].join(`
|
|
6
|
+
`)}}function vo(e){return{data:{apps:e.result},stderr:e.appsFilter===`all`?`Showing all apps, including system apps.
|
|
7
|
+
`:`Showing user-installed apps. Use --all to include system apps.
|
|
8
|
+
`,text:e.result.length>0?e.result.join(`
|
|
9
|
+
`):e.appsFilter===`all`?`No apps found.`:`No user-installed apps found.`}}function yo(e){if(`stateDir`in e)return{data:e,text:e.stateDir};let t={sessions:e.sessions.map(qe)};return{data:t,text:JSON.stringify(t,null,2)}}function bo(e){let t=Ue(e),n=[je(t)].filter(e=>!!e);return typeof t.sessionStateDir==`string`&&n.push(`Session state: ${t.sessionStateDir}`),{data:t,text:n.join(`
|
|
10
|
+
`)||null}}function xo(e){return V(Se(e))}function So(e){if(Co(e))return{data:e,text:e.artifacts.length>0?e.artifacts.map(jo).join(`
|
|
11
|
+
`):e.message??`No daemon artifacts available.`};let t=[e.message??`No cloud artifacts available for ${e.provider}.`],n=Mo(e);return n&&t.push(`Retry: ${n}`),{data:e,text:e.cloudArtifacts.length>0?e.cloudArtifacts.map(Ao).join(`
|
|
12
|
+
`):t.join(`
|
|
13
|
+
`)}}function Co(e){return`source`in e&&e.source===`daemon`}function wo(e){return V(le(e))}function To(e){return V(Xe(e))}function Eo(e){let t=e,n=t.platform??`unknown`;return{data:t,text:`Boot ready: ${t.device??t.id??`unknown`} (${n})`}}function Do(e){let t=e,n=t.platform??`unknown`,r=t.device??t.id??`unknown`,i=t.shutdown;return{data:t,text:`${i&&typeof i==`object`&&`success`in i&&i.success===!0?`Shutdown`:`Shutdown failed`}: ${r} (${n})`}}function Oo(e){let t=e,n=[`Doctor: ${typeof t.status==`string`?t.status:`unknown`}`],r=No(t.checks);if(Ot()){let e=typeof t.summary==`string`?t.summary:void 0;e&&n.push(e)}else if(r.length===0){let e=typeof t.summary==`string`?t.summary:`No blockers found.`;n.push(e)}else for(let e of r)n.push(Pe(e)),n.push(...ue(e));return{data:t,text:n.join(`
|
|
14
|
+
`)}}const Z={boot:z(Eo),shutdown:z(Do),devices:z(go),capabilities:z(_o),doctor:z(Oo),apps:({input:e,result:t})=>vo({result:t,appsFilter:e.appsFilter}),session:z(yo),artifacts:z(So),open:z(bo),close:z(xo),install:z(wo),reinstall:z(wo),"install-from-source":z(To),prepare:B,viewport:B};function ko(e){let t=e.kind?` ${e.kind}`:``,n=e.target?` target=${e.target}`:``,r=typeof e.booted==`boolean`?` booted=${e.booted}`:``;return`${e.name} (${e.platform}${t}${n})${r}`}function Ao(e){let t=e.url?` ${e.url}`:``,n=e.availability?` ${e.availability}`:``;return`${e.kind}: ${e.name}${n}${t}`}function jo(e){let t=e.artifactType?` (${e.artifactType})`:``;return`${e.filename}${t}: ${e.mimeType} ${e.sizeBytes} bytes id=${e.id}`}function Mo(e){if(e.providerSessionId)return`agent-device artifacts ${e.providerSessionId} --provider ${e.provider} --json`}function No(e){return Array.isArray(e)?e.filter(e=>!!e&&typeof e==`object`&&!Array.isArray(e)):[]}const Po=W(`artifacts`,`List daemon or cloud provider artifacts for an active or completed session.`,{provider:p(`Cloud provider name, for example browserstack or aws-device-farm.`),providerSessionId:p(`Cloud provider session id or ARN.`)}),Fo=I({name:`artifacts`,metadata:Po,definition:R(Po,(e,t)=>e.sessions.artifacts(t)),cliSchema:{summary:`List daemon or cloud provider session artifacts`,usageOverride:`artifacts [provider-session-id] [--provider <name>]`,positionalArgs:[`provider-session-id?`],allowedFlags:[`provider`,`providerSessionId`]},cliReader:(e,t)=>({...O(t),provider:t.provider,providerSessionId:e[0]??t.providerSessionId}),daemonWriter:E(l.artifacts),cliOutputFormatter:Z.artifacts}),Io=W(`apps`,`List installed apps.`,{appsFilter:_([`user-installed`,`all`])}),Lo=W(`open`,`Open an app, deep link, URL, or platform surface.`,{app:p(`App name, bundle id, package, or URL.`),url:p(`Optional URL passed with an app shell.`),surface:_(Ee),activity:p(`Android activity name.`),launchConsole:p(`Launch console mode.`),launchArgs:Bt(`Launch arguments forwarded verbatim to the platform launch command.`),relaunch:g(`Force relaunch.`),saveScript:v({oneOf:[It(),Nt()]}),deviceHub:g(`Use Xcode Device Hub when surfacing Apple simulators.`),noRecord:g(`Do not record this action.`)}),Ro=W(`close`,`Close an app or end the active session.`,{app:p(`Optional app to close.`),shutdown:g(`Shutdown the session/device where supported.`),saveScript:v({oneOf:[It(),Nt()]})}),zo=R(Io,(e,t)=>e.apps.list(t)),Bo=R(Lo,(e,t)=>e.apps.open(t)),Vo=R(Ro,(e,t)=>t.app?e.apps.close(t):e.sessions.close(es(t))),Ho={helpDescription:`List user-installed apps; use --all to include system/OEM apps`,summary:`List installed apps`,allowedFlags:[`appsFilter`],defaults:{appsFilter:Tt}},Uo={helpDescription:`Boot device/simulator; optionally launch app or deep link URL. Use --platform to bind URL/deep-link opens to the target platform. For iOS simulator initial stdout/stderr, put --launch-console <path> on this open command, for example agent-device open "Agent Device Tester" --platform ios --launch-console artifacts/launch-console.log. Expo Go/dev-client shells accept host + URL, for example agent-device open "Expo Go" exp://127.0.0.1:8081 --platform ios. macOS also supports --surface app|frontmost-app|desktop|menubar.`,summary:`Open an app, deep link or URL, save replays`,positionalArgs:[`appOrUrl?`,`url?`],allowedFlags:[`activity`,`launchConsole`,`launchArgs`,`deviceHub`,`saveScript`,`noRecord`,`relaunch`,`surface`]},Wo={positionalArgs:[`app?`],allowedFlags:[`saveScript`,`shutdown`]},Go=(e,t)=>({...O(t),appsFilter:wt(t.appsFilter)}),Ko=(e,t)=>({...O(t),app:e[0],url:e[1],surface:t.surface,activity:t.activity,launchConsole:t.launchConsole,launchArgs:t.launchArgs,relaunch:t.relaunch,saveScript:t.saveScript,deviceHub:t.deviceHub,noRecord:t.noRecord}),qo=(e,t)=>({...O(t),app:e[0],shutdown:t.shutdown,saveScript:t.saveScript}),Jo=E(l.apps),Yo=E(l.open,ts),Xo=E(l.close,e=>M(e.app)),Zo=I({name:`apps`,metadata:Io,definition:zo,cliSchema:Ho,cliReader:Go,daemonWriter:Jo,cliOutputFormatter:Z.apps}),Qo=I({name:`open`,metadata:Lo,definition:Bo,cliSchema:Uo,cliReader:Ko,daemonWriter:Yo,cliOutputFormatter:Z.open}),$o=I({name:`close`,metadata:Ro,definition:Vo,cliSchema:Wo,cliReader:qo,daemonWriter:Xo,cliOutputFormatter:Z.close});function es(e){let{app:t,...n}=e;return n}function ts(e){return e.app?e.url?[e.app,e.url]:[e.app]:[]}const ns=W(`devices`,`List available devices.`,{}),rs=W(`capabilities`,`List commands supported by the selected device.`,{}),is=W(`boot`,`Boot or prepare a selected device without using CLI positional arguments.`,{headless:g(`Boot without showing simulator UI when supported.`)}),as=W(`shutdown`,`Shutdown a selected simulator or emulator.`,{}),os=R(ns,(e,t)=>e.devices.list(t)),ss=R(rs,(e,t)=>e.devices.capabilities(t)),cs=R(is,(e,t)=>e.devices.boot(t)),ls=R(as,(e,t)=>e.devices.shutdown(t)),us={summary:`Boot target device/simulator`,allowedFlags:[`headless`]},ds={summary:`List supported commands for the selected device`,helpDescription:`List command names supported by the selected session device or explicit --platform/--device/--udid/--serial target.`},fs={summary:`Shutdown target simulator/emulator`},ps=(e,t)=>O(t),ms=(e,t)=>({...O(t),headless:t.headless}),hs=E(l.devices),gs=E(l.capabilities),_s=E(l.boot),vs=E(l.shutdown),ys=[I({name:`devices`,metadata:ns,definition:os,cliReader:ps,daemonWriter:hs,cliOutputFormatter:Z.devices}),I({name:`capabilities`,metadata:rs,definition:ss,cliSchema:ds,cliReader:ps,daemonWriter:gs,cliOutputFormatter:Z.capabilities}),I({name:`boot`,metadata:is,definition:cs,cliSchema:us,cliReader:ms,daemonWriter:_s,cliOutputFormatter:Z.boot}),I({name:`shutdown`,metadata:as,definition:ls,cliSchema:fs,cliReader:ps,daemonWriter:vs,cliOutputFormatter:Z.shutdown})],bs=W(`doctor`,`Diagnose device, app, Metro, and React Native readiness before a run.`,{targetApp:p(`Installed app package/bundle id or app name to verify without opening a session.`),remote:g(`Check remote connection setup instead of local device inventory.`)}),xs=I({name:`doctor`,metadata:bs,definition:R(bs,(e,t)=>e.command.doctor(t)),cliSchema:{usageOverride:`doctor [--platform ios|android|macos|linux|web|apple] [--app <id-or-name>] [--remote]`,helpDescription:`Preflight for QA and dogfood runs. Reports local device inventory, active sessions, optional app discovery, scoped toolchain info, and Metro reachability inferred from cwd/runtime. On iOS simulators it also warms the XCTest runner build cache in the background when missing, so the first open on a fresh machine skips the runner build — run doctor first on new setups. Pass --app to verify a target app on the one matching booted device without opening a session. Use --remote to check remote connection setup without probing local devices. Default output is compact; use --json for full checks and evidence.`,summary:`Preflight device, app, Metro, and RN/Expo readiness`,allowedFlags:[`targetApp`,`remote`]},cliReader:(e,t)=>({...O(t),targetApp:t.targetApp,remote:t.remote}),daemonWriter:E(l.doctor),cliOutputFormatter:Z.doctor});function Ss(t,n=`--github-actions-artifact`){let r=t.indexOf(`:`);if(r<=0||r===t.length-1)throw new e(`INVALID_ARGS`,`${n} must use owner/repo:artifact, for example thymikee/RNCLI83:6635342232`);let{owner:i,repo:a}=Ts(t.slice(0,r),n);return ws(i,a,t.slice(r+1),`${n} artifact`)}function Cs(t,n){if(!t||typeof t!=`object`||Array.isArray(t))throw new e(`INVALID_ARGS`,`${n} installSource must be an object.`);let r=t;if(Ds(r.type,`${n} installSource.type`)!==`github-actions-artifact`)throw new e(`INVALID_ARGS`,`${n} installSource.type must be "github-actions-artifact".`);let{owner:i,repo:a}=Ts(Ds(r.repo,`${n} installSource.repo`),`${n} installSource.repo`);return ws(i,a,r.artifact,`${n} installSource.artifact`)}function ws(e,t,n,r){return typeof n==`number`||ks(n)?{kind:`github-actions-artifact`,owner:e,repo:t,artifactId:Os(n,r)}:{kind:`github-actions-artifact`,owner:e,repo:t,artifactName:Ds(n,r)}}function Ts(t,n){let r=t.indexOf(`/`);if(r<=0||r===t.length-1||t.indexOf(`/`,r+1)!==-1)throw new e(`INVALID_ARGS`,`${n} must use owner/repo.`);let i={owner:t.slice(0,r).trim(),repo:t.slice(r+1).trim()};if(!i.owner||!i.repo)throw new e(`INVALID_ARGS`,`${n} must use owner/repo.`);return i}function Es(e){return typeof e==`string`&&e.trim().length>0?e.trim():void 0}function Ds(t,n){let r=Es(t);if(!r)throw new e(`INVALID_ARGS`,`${n} must be a non-empty string.`);return r}function Os(t,n){let r=typeof t==`number`?t:typeof t==`string`?Number(t):NaN;if(!Number.isInteger(r))throw new e(`INVALID_ARGS`,`${n} must be an integer.`);return r}function ks(e){return typeof e==`string`&&/^\d+$/.test(e.trim())}const As=W(`install`,`Install an app binary.`,{app:p(`Optional app identifier hint.`),appPath:f(p(`Path to app binary.`))}),js=W(`reinstall`,`Reinstall an app binary.`,{app:f(p()),appPath:f(p(`Path to app binary.`))}),Ms=W(`install-from-source`,`Install an app from a structured source.`,{source:f(v(Rt(`Install source object.`))),retainPaths:g(),retentionMs:h()}),Ns=R(As,(e,t)=>e.apps.install(t)),Ps=R(js,(e,t)=>e.apps.reinstall(t)),Fs=R(Ms,(e,t)=>e.apps.installFromSource(t)),Is={usageOverride:`install <path> | install <app> <path>`,listUsageOverride:`install <path>`,positionalArgs:[`appOrPath`,`path?`]},Ls={positionalArgs:[`app`,`path`]},Rs={usageOverride:`install-from-source <url> | install-from-source --github-actions-artifact <owner/repo:artifact>`,listUsageOverride:`install-from-source`,helpDescription:`Install app builds from URLs, remote source specs, or CI artifacts resolved by a remote daemon.`,summary:`Install app builds from URLs, remote source specs, or CI artifacts`,positionalArgs:[`url?`],allowedFlags:[`header`,`githubActionsArtifact`,`installSource`,`retainPaths`,`retentionMs`]},zs=(e,t)=>Gs(e,t),Bs=(e,t)=>Ks(e,t),Vs=(e,t)=>({...O(t),source:Ys(e,t),retainPaths:t.retainPaths,retentionMs:t.retentionMs}),Hs=E(l.install,e=>qs(e.app,e.appPath)),Us=E(l.reinstall,e=>Js(e.app,e.appPath)),Ws=[I({name:`install`,metadata:As,definition:Ns,cliSchema:Is,cliReader:zs,daemonWriter:Hs,cliOutputFormatter:Z.install}),I({name:`reinstall`,metadata:js,definition:Ps,cliSchema:Ls,cliReader:Bs,daemonWriter:Us,cliOutputFormatter:Z.reinstall}),I({name:`install-from-source`,metadata:Ms,definition:Fs,cliSchema:Rs,cliReader:Vs,daemonWriter:e=>D(c.installSource,[],{...e,installSource:e.source,retainMaterializedPaths:e.retainPaths,materializedPathRetentionMs:e.retentionMs}),cliOutputFormatter:Z[`install-from-source`]})];function Gs(e,t){let[n,r]=e,i=r!==void 0;return{...O(t),...i?{app:P(n,`install requires app`)}:{},appPath:P(i?r:n,`install requires path`)}}function Ks(e,t){return{...O(t),app:P(e[0],`reinstall requires app`),appPath:P(e[1],`reinstall requires path`)}}function qs(e,t){let n=F(t,`missing app path`);return typeof e==`string`&&e.length>0?[e,n]:[n]}function Js(e,t){return[F(e,`missing first positional`),F(t,`missing second positional`)]}function Ys(t,n){let r=t[0]?.trim();if(t.length>1)throw new e(`INVALID_ARGS`,`install-from-source accepts either one <url> positional or --github-actions-artifact`);let i=n.githubActionsArtifact?Ss(n.githubActionsArtifact):void 0,a=n.installSource;if(+!!r+ +!!i+ +!!a!=1)throw new e(`INVALID_ARGS`,`install-from-source requires exactly one source: <url>, --github-actions-artifact, or config installSource`);if(!r&&n.header&&n.header.length>0)throw new e(`INVALID_ARGS`,`install-from-source --header is only supported for URL sources`);return i||a||{kind:`url`,url:r,headers:Xs(n.header)}}function Xs(t){if(!t||t.length===0)return;let n={};for(let r of t){let t=r.indexOf(`:`);if(t<=0)throw new e(`INVALID_ARGS`,`Invalid --header value "${r}". Expected "name:value".`);let i=r.slice(0,t).trim(),a=r.slice(t+1).trim();if(!i)throw new e(`INVALID_ARGS`,`Invalid --header value "${r}". Header name cannot be empty.`);n[i]=a}return n}const Zs=W(`prepare`,`Prepare platform helper infrastructure.`,{action:f(_([`ios-runner`])),timeoutMs:h(`Maximum wall-clock time for the prepare command.`)}),Qs=I({name:`prepare`,metadata:Zs,definition:R(Zs,(e,t)=>e.command.prepare(t)),cliSchema:{usageOverride:`prepare ios-runner --platform ios|macos [--timeout <ms>]`,listUsageOverride:`prepare`,helpDescription:`Prepare platform helper infrastructure. ios-runner builds/reuses, starts, and health-checks the XCTest runner so later Apple snapshots and interactions do not pay first-use startup cost. In JSON output, top-level buildMs/connectMs/healthCheckMs are diagnostic fields and may overlap; use timing.additiveParts for additive wall-clock phase totals. In CI, run it after boot/install and before replay/test; if replay/test starts a separate daemon, stop the prepare daemon before replay/test so it does not keep the prepared runner lease. It is not a recovery step for "runner already owned by another agent-device daemon"; stop the owning daemon on the Mac with simulator access instead. Runner build/start output is written to the session runner.log; daemon.log is for daemon lifecycle/startup issues.`,summary:`Pre-warm platform helpers, especially the iOS/macOS XCTest runner before Apple automation`,positionalArgs:[`ios-runner`],allowedFlags:[`timeoutMs`]},cliReader:(e,t)=>({...O(t),action:P(e[0],`prepare requires subcommand`),timeoutMs:t.timeoutMs}),daemonWriter:E(l.prepare,e=>[F(e.action,`prepare requires subcommand`)]),cliOutputFormatter:Z.prepare}),$s=W(`push`,`Deliver a push payload.`,{app:f(p()),payload:f(v({oneOf:[Nt(),Rt()]}))}),ec=W(`trigger-app-event`,`Trigger an app-defined event.`,{event:f(p()),payload:zt()}),tc=R($s,(e,t)=>e.apps.push(t)),nc=R(ec,(e,t)=>e.apps.triggerEvent(t)),rc={listUsageOverride:`push`,helpDescription:`Deliver push notification payloads to an installed app.`,summary:`Deliver push notification payloads to an installed app`,positionalArgs:[`bundleOrPackage`,`payloadOrJson`]},ic={usageOverride:`trigger-app-event <event> [payloadJson]`,listUsageOverride:`trigger-app-event`,helpDescription:`Invoke app-defined automation or test events with an optional structured payload.`,summary:`Invoke app-defined automation/test events with optional structured payloads`,positionalArgs:[`event`,`payloadJson?`]},ac=(e,t)=>({...O(t),app:P(e[0],`push requires bundleOrPackage`),payload:P(e[1],`push requires payloadOrJson`)}),oc=(e,t)=>({...O(t),event:P(e[0],`trigger-app-event requires event`),payload:e[1]?Ln(e[1],`trigger-app-event payload`):void 0}),sc=E(l.push,e=>uc(e)),cc=E(l.triggerAppEvent,e=>dc(e)),lc=[I({name:`push`,metadata:$s,definition:tc,cliSchema:rc,cliReader:ac,daemonWriter:sc}),I({name:`trigger-app-event`,metadata:ec,definition:nc,cliSchema:ic,cliReader:oc,daemonWriter:cc})];function uc(e){return[e.app,typeof e.payload==`string`?e.payload:JSON.stringify(e.payload)]}function dc(e){return[e.event,...e.payload?[JSON.stringify(e.payload)]:[]]}const fc=W(`session`,`List active sessions or print daemon state directory.`,{action:_([`list`,`state-dir`],`list shows active sessions; state-dir prints the resolved daemon state directory without contacting the daemon.`)}),pc=I({name:`session`,metadata:fc,definition:R(fc,async(e,{action:t,...n})=>t===`state-dir`?{stateDir:await e.sessions.stateDir(n)}:{sessions:await e.sessions.list(n)}),cliSchema:{usageOverride:`session list | session state-dir`,listUsageOverride:`session`,helpDescription:`List active sessions or print the effective daemon state directory`,positionalArgs:[`list|state-dir?`]},cliReader:(e,t)=>({...O(t),action:mc(e[0])}),cliOutputFormatter:Z.session});function mc(t){let n=t??`list`;if(n===`list`||n===`state-dir`)return n;throw new e(`INVALID_ARGS`,`session only supports list or state-dir`)}const hc=W(`viewport`,`Resize the active web viewport.`,{width:f(h(`Viewport width in CSS pixels.`,{min:1})),height:f(h(`Viewport height in CSS pixels.`,{min:1}))}),gc=I({name:`viewport`,metadata:hc,definition:R(hc,(e,t)=>e.command.viewport(t)),cliSchema:{helpDescription:`Resize the active web viewport before taking snapshots or screenshots. Useful for fixed-layout or 100vh apps where changing the viewport reveals different content.`,summary:`Resize the active web viewport for the current session`,positionalArgs:[`width`,`height`]},cliReader:(e,t)=>({...O(t),width:Je(e[0],`width`),height:Je(e[1],`height`)}),daemonWriter:E(l.viewport,e=>{let{width:t,height:n}=e;return[String(t),String(n)]}),cliOutputFormatter:Z.viewport}),_c=L({name:`management`,commands:[...ys,Fo,xs,Qs,Zo,pc,Qo,$o,gc,...Ws,...lc]});function vc(e){return{data:e.result,text:e.action===`reload`?`Reloaded React Native apps via ${e.result.reloadUrl}`:JSON.stringify(e.result,null,2)}}const yc={metro:({input:e,result:t})=>vc({result:t,action:e.action})},bc=`metro`,xc=W(bc,`Prepare Metro runtime or reload React Native apps.`,{action:f(_([`prepare`,`reload`])),projectRoot:p(),kind:v(Nt()),publicBaseUrl:p(),proxyBaseUrl:p(),bearerToken:p(),bridgeScope:v({type:`object`,additionalProperties:!0}),launchUrl:p(),port:h(),listenHost:p(),statusHost:p(),startupTimeoutMs:h(),probeTimeoutMs:h(),reuseExisting:g(),installDependenciesIfNeeded:g(),runtimeFilePath:p(),logPath:p(),metroHost:p(),metroPort:h(),bundleUrl:p(),timeoutMs:h()}),Sc=L({name:`metro`,commands:[I({name:bc,metadata:xc,definition:R(xc,async(e,t)=>t.action===`prepare`?await e.metro.prepare(Cc(t)):await e.metro.reload(Tc(t))),cliSchema:{usageOverride:`metro prepare (--public-base-url <url> | --proxy-base-url <url>) [--project-root <path>] [--port <port>] [--kind auto|react-native|expo]
|
|
15
|
+
agent-device metro reload [--metro-host <host>] [--metro-port <port>] [--bundle-url <url>]`,listUsageOverride:`metro`,helpDescription:`Prepare a local Metro runtime or ask Metro to reload connected React Native apps`,summary:`Prepare Metro reachability for React Native/Expo apps or trigger app reloads`,positionalArgs:[`prepare|reload`],allowedFlags:[...yr,...vr]},cliReader:(t,n)=>{let r=(t[0]??``).toLowerCase();if(r!==`prepare`&&r!==`reload`)throw new e(`INVALID_ARGS`,`metro requires a subcommand: prepare or reload`);if(r===`reload`)return{action:r,metroHost:n.metroHost,metroPort:n.metroPort,bundleUrl:n.bundleUrl,timeoutMs:n.metroProbeTimeoutMs};if(!n.metroPublicBaseUrl&&!n.metroProxyBaseUrl)throw new e(`INVALID_ARGS`,`metro prepare requires --public-base-url <url> or --proxy-base-url <url>.`);return{action:r,projectRoot:n.metroProjectRoot,kind:Ec(n.kind??n.metroKind),port:n.metroPreparePort,listenHost:n.metroListenHost,statusHost:n.metroStatusHost,publicBaseUrl:n.metroPublicBaseUrl,proxyBaseUrl:n.metroProxyBaseUrl,bearerToken:n.metroBearerToken,bridgeScope:n.tenant&&n.runId&&n.leaseId?{tenantId:n.tenant,runId:n.runId,leaseId:n.leaseId}:void 0,startupTimeoutMs:n.metroStartupTimeoutMs,probeTimeoutMs:n.metroProbeTimeoutMs,reuseExisting:n.metroNoReuseExisting?!1:void 0,installDependenciesIfNeeded:n.metroNoInstallDeps?!1:void 0,runtimeFilePath:n.metroRuntimeFile}},cliOutputFormatter:yc.metro})]});function Cc(e){return{projectRoot:e.projectRoot,kind:e.kind,publicBaseUrl:e.publicBaseUrl,proxyBaseUrl:e.proxyBaseUrl,bearerToken:e.bearerToken,bridgeScope:e.bridgeScope??wc(e),port:e.port,listenHost:e.listenHost,statusHost:e.statusHost,startupTimeoutMs:e.startupTimeoutMs,probeTimeoutMs:e.probeTimeoutMs,reuseExisting:e.reuseExisting,installDependenciesIfNeeded:e.installDependenciesIfNeeded,runtimeFilePath:e.runtimeFilePath}}function wc(e){return e.tenant&&e.runId&&e.leaseId?{tenantId:e.tenant,runId:e.runId,leaseId:e.leaseId}:void 0}function Tc(e){return{metroHost:e.metroHost,metroPort:e.metroPort,bundleUrl:e.bundleUrl,timeoutMs:e.timeoutMs}}function Ec(t){if(t!==void 0){if(t===`auto`||t===`react-native`||t===`expo`)return t;throw new e(`INVALID_ARGS`,`metro prepare --kind must be auto, react-native, or expo`)}}const Dc=[`started`,`stopped`,`marked`,`cleared`,`restarted`,`removedRotatedFiles`];function Oc(e){return{data:e,text:e.path,stderr:Bc([Rc(e,[`active`,`state`,`backend`,`sizeBytes`]),Nc(e),e.hint,zc(e.notes)])}}function kc(e){let t=[],n=e.entries??[];if(e.path&&t.push(e.path),n.length===0)t.push(`No recent HTTP(s) entries found.`);else for(let e of n)t.push(...Fc(e));return{data:e,text:t.join(`
|
|
16
|
+
`),stderr:Bc([Rc(e,[`active`,`state`,`backend`,`include`,`scannedLines`,`matchedLines`]),zc(e.notes)])}}function Ac(e){return{data:e,text:[`Audio probe: ${String(e.state??`stopped`)} heard=${String(e.heard===!0)}`,Mc(`rmsDbfs`,e.rmsDbfs),Mc(`peakDbfs`,e.peakDbfs)].filter(e=>!!e).join(`
|
|
17
|
+
`),stderr:Bc([Rc(e,[`active`,`backend`,`source`,`durationMs`,`elapsedMs`,`bucketMs`,`sampleCount`,`sourceCount`,`mediaElementCount`]),zc(e.notes)])}}const jc={logs:z(Oc),network:z(kc),audio:z(Ac)};function Mc(e,t){if(!Array.isArray(t))return;let n=t.filter(e=>typeof e==`number`&&Number.isFinite(e));return n.length>0?`${e}: [${n.join(`, `)}]`:void 0}function Nc(e){return Dc.map(t=>Pc(t,e[t])).filter(Boolean).join(` `)||void 0}function Pc(e,t){return t==null?``:`${e}=${t}`}function Fc(e){let t=e.method??`HTTP`,n=e.url??`<unknown-url>`,r=e.status===void 0?``:` status=${e.status}`,i=[`${e.timestamp?`${e.timestamp} `:``}${t} ${n}${r}${e.durationMs===void 0?``:` durationMs=${e.durationMs}`}`];return e.headers?Lc(i,`headers`,e.headers):(Ic(i,`request headers`,e.requestHeaders),Ic(i,`response headers`,e.responseHeaders)),Lc(i,`request`,e.requestBody),Lc(i,`response`,e.responseBody),i}function Ic(e,t,n){!n||Object.keys(n).length===0||e.push(` ${t}: ${JSON.stringify(n)}`)}function Lc(e,t,n){n!==void 0&&e.push(` ${t}: ${n}`)}function Rc(e,t){return t.map(t=>e[t]!==void 0&&e[t]!==null?`${t}=${e[t]}`:``).filter(Boolean).join(` `)||void 0}function zc(e){let t=e?.filter(e=>e.length>0)??[];return t.length>0?t.join(`
|
|
18
|
+
`):void 0}function Bc(e){return e.filter(e=>!!e).join(`
|
|
19
|
+
`)||void 0}const Vc=`logs`,Hc=`network`,Uc=`audio`,Wc=[`dump`,`log`],Gc=[`probe`],Kc=[`start`,`status`,`stop`],qc=W(Vc,`Manage session app logs.`,{action:_(We),message:p(),restart:g()}),Jc=W(Hc,`Show recent HTTP traffic.`,{action:_(Wc),limit:h(),include:_(s)}),Yc=W(Uc,`Probe audio levels.`,{action:_(Gc),probeAction:_(Kc),durationMs:h(`Probe duration in milliseconds.`),bucketMs:h(`Audio level bucket size in milliseconds.`)}),Xc=R(qc,(e,t)=>e.observability.logs(t)),Zc=R(Jc,(e,t)=>e.observability.network(t)),Qc=R(Yc,(e,t)=>e.observability.audio(t)),$c=L({name:`observability`,commands:[I({name:Vc,metadata:qc,definition:Xc,cliSchema:{usageOverride:`logs path | logs start | logs stop | logs clear [--restart] | logs doctor | logs mark [message...]`,helpDescription:`Session app log info, start/stop streaming, diagnostics, and markers`,summary:`Manage session app logs`,positionalArgs:[`path|start|stop|clear|doctor|mark`,`message?`],allowsExtraPositionals:!0,allowedFlags:[`restart`]},cliReader:(e,t)=>({...O(t),action:rl(e[0]),message:e.slice(1).join(` `)||void 0,restart:t.restart}),daemonWriter:E(Vc,e=>el(e)),cliOutputFormatter:jc.logs}),I({name:Hc,metadata:Jc,definition:Zc,cliSchema:{usageOverride:`network dump [limit] [summary|headers|body|all] [--include summary|headers|body|all] | network log [limit] [summary|headers|body|all] [--include summary|headers|body|all]`,listUsageOverride:`network`,helpDescription:`Dump recent HTTP(s) traffic parsed from the session app log`,summary:`Inspect HTTP(S) traffic parsed from session app logs, including summaries, headers, and bodies`,positionalArgs:[`dump|log`,`limit?`,`include?`],allowedFlags:[`networkInclude`]},cliReader:(e,t)=>({...O(t),action:il(e[0]),limit:j(e[1]),include:t.networkInclude??al(e[2])}),daemonWriter:e=>D(Hc,tl(e),{...e,networkInclude:e.include}),cliOutputFormatter:jc.network}),I({name:Uc,metadata:Yc,definition:Qc,cliSchema:{usageOverride:`audio probe start [durationSeconds] [bucketMs] | audio probe status | audio probe stop`,listUsageOverride:`audio`,helpDescription:`Probe browser or host-rendered simulator/emulator audio as compact dBFS buckets`,summary:`Probe audio levels`,positionalArgs:[`probe`,`start|status|stop`,`durationSeconds?`,`bucketMs?`]},cliReader:(e,t)=>({...O(t),action:ol(e[0]),probeAction:sl(e[1]),durationMs:cl(e[2]),bucketMs:j(e[3])}),daemonWriter:e=>D(Uc,nl(e),e),cliOutputFormatter:jc.audio})]});function el(e){return[e.action??`path`,...M(e.message)]}function tl(e){return[...e.action?[e.action]:[],...N(e.limit)]}function nl(e){return[e.action??`probe`,e.probeAction??`status`,...N(e.durationMs),...N(e.bucketMs)]}function rl(e){if(e!==void 0)return Ke(We,e,{message:`logs requires path, start, stop, doctor, mark, or clear`})}function il(t){if(t!==void 0){if(t===`dump`||t===`log`)return t;throw new e(`INVALID_ARGS`,`network requires dump or log`)}}function al(e){if(e!==void 0)return Ke(s,e,{message:`network include must be summary, headers, body, or all`})}function ol(e){if(e!==void 0)return Ke(Gc,e,{message:`audio requires probe`})}function sl(e){if(e!==void 0)return Ke(Kc,e,{message:`audio probe requires start, status, or stop`})}function cl(e){let t=j(e);return t===void 0?void 0:Math.round(t*1e3)}function ll(e){let t=e;return{data:t,text:dl(t)}}const ul={perf:z(ll)};function dl(e){let t=hl(e);if(t)return t;let n=u(e.artifact)?e.artifact:void 0;return n?ml(n):fl(u(e.metrics)?e.metrics:void 0)}function fl(e){let t=u(e?.fps)?e.fps:void 0,n=Ml(e);if(!t)return Tl(n,`missing frame metric`);if(t.available===!1)return Tl(n,El(t));let r=Dl(t);return r?pl(t,r):Tl(n,`missing dropped-frame summary`)}function pl(e,t){let n=[`Frame health: ${t}`],r=Al(e);return r.length>0&&n.push(`Worst windows:`,...r),n.join(`
|
|
20
|
+
`)}function ml(e){let t=typeof e.kind==`string`?e.kind:`memory`;if(e.available===!1)return`Memory artifact (${t}): unavailable - ${typeof e.reason==`string`&&e.reason.length>0?e.reason:`not available`}`;let n=typeof e.path==`string`?e.path:void 0,r=Q(e.sizeBytes),i=r===void 0?``:` (${Rl(r)})`;return n?`Memory artifact (${t}): ${n}${i}`:`Memory artifact (${t}): captured${i}`}function hl(e){return e.kind===`xctrace`?gl(e):yl(e)}function gl(e){let t=typeof e.perf==`string`?e.perf:void 0,n=_l(e);if(!(!t||!n||e.kind!==`xctrace`))return vl(n,typeof e.mode==`string`?e.mode:`capture`,t,e.template)}function _l(e){return typeof e.outPath==`string`?e.outPath:typeof e.reportPath==`string`?e.reportPath:void 0}function vl(e,t,n,r){let i=[e,`Perf ${t}: ${n}`];return typeof r==`string`&&i.push(`Template: ${r}`),i.join(`
|
|
21
|
+
`)}function yl(e){let t=bl(e);if(t)return`Perf ${t.action}: ${t.kind} ${t.type}${xl(e)}${Sl(e)}${wl(e)}`}function bl(e){let t=Cl(e.action),n=Cl(e.kind),r=Cl(e.type);return t&&n&&r?{action:t,kind:n,type:r}:void 0}function xl(e){let t=Cl(e.state);return t?` state=${t}`:``}function Sl(e){let t=Cl(e.outPath);if(!t)return``;let n=Q(e.sizeBytes);return`\n${t}${n===void 0?``:` (${Rl(n)})`}`}function Cl(e){return typeof e==`string`?e:void 0}function wl(e){let t=u(e.summary)?e.summary:void 0,n=u(t?.frameHealth)?t.frameHealth:void 0;if(!n||n.available!==!0)return``;let r=Q(n.droppedFramePercent),i=Q(n.droppedFrameCount),a=Q(n.totalFrameCount);return r===void 0||i===void 0||a===void 0?``:`\nTrace frame health: dropped ${Fl(r)} (${Math.round(i)}/${Math.round(a)} frames)`}function Tl(e,t){return e?`Performance: ${e}`:`Frame health: unavailable - ${t}`}function El(e){return typeof e.reason==`string`&&e.reason.length>0?e.reason:`not available`}function Dl(e){let t=Q(e.droppedFramePercent),n=Q(e.droppedFrameCount);if(!(t===void 0||n===void 0))return[`dropped ${Fl(t)}`,Ol(n,Q(e.totalFrameCount)),kl(Q(e.sampleWindowMs))].filter(Boolean).join(` `)}function Ol(e,t){return t===void 0?`(${Math.round(e)} dropped frames)`:`(${Math.round(e)}/${Math.round(t)} frames)`}function kl(e){return e===void 0?``:`window ${Il(e)}`}function Al(e){return Array.isArray(e.worstWindows)?e.worstWindows.flatMap(e=>{if(!u(e))return[];let t=jl(e);return t?[t]:[]}):[]}function jl(e){let t=Q(e.startOffsetMs),n=Q(e.endOffsetMs),r=Q(e.missedDeadlineFrameCount);if(t===void 0||n===void 0||r===void 0)return;let i=Q(e.worstFrameMs),a=i===void 0?``:`, worst ${Il(i)}`;return`- +${Il(t)}-+${Il(n)}: ${Math.round(r)} missed-deadline frames${a}`}function Ml(e){let t=u(e?.cpu)?e.cpu:void 0,n=u(e?.memory)?e.memory:void 0,r=[Nl(t),Pl(n)].filter(e=>!!e);return r.length>0?r.join(`, `):void 0}function Nl(e){if(e?.available!==!0)return;let t=Q(e.usagePercent);return t===void 0?void 0:`CPU ${Fl(t)}`}function Pl(e){if(e?.available!==!0)return;let t=Q(e.residentMemoryKb)??Q(e.totalPssKb)??Q(e.totalRssKb);return t===void 0?void 0:`memory ${Ll(t)}`}function Q(e){return typeof e==`number`&&Number.isFinite(e)?e:void 0}function Fl(e){return`${Number.isInteger(e)?e:e.toFixed(1)}%`}function Il(e){let t=Math.max(0,Math.round(e));if(t<1e3)return`${t}ms`;let n=Math.round(t/1e3);if(n<60)return`${n}s`;let r=Math.floor(n/60),i=n%60;return i>0?`${r}m ${i}s`:`${r}m`}function Ll(e){let t=e/1024;return`${t>=10?Math.round(t):t.toFixed(1)}MB`}function Rl(e){if(e<1024)return`${Math.round(e)}B`;let t=e/1024;if(t<1024)return`${t>=10?Math.round(t):t.toFixed(1)}KB`;let n=t/1024;return`${n>=10?Math.round(n):n.toFixed(1)}MB`}const zl=`perf`,Bl=W(zl,`Show session performance, frame health, and memory diagnostics.`,{area:_(ye),subject:_(Ce),action:_(Fe),kind:_(me),template:p(`xctrace template name, for example Time Profiler.`),out:p(`Output artifact path.`),tracePath:p(`Existing .trace path to report, defaults to the latest session trace.`)}),Vl=L({name:`perf`,commands:[I({name:zl,metadata:Bl,definition:R(Bl,(e,t)=>e.observability.perf(t)),cliSchema:{usageOverride:`perf metrics --json
|
|
22
|
+
agent-device perf frames --json
|
|
23
|
+
agent-device perf memory sample --json
|
|
24
|
+
agent-device perf memory snapshot [--kind android-hprof|memgraph] [--out <path>]
|
|
25
|
+
agent-device perf cpu profile start --kind xctrace [--template <name>] --out <profile.trace>
|
|
26
|
+
agent-device perf cpu profile stop --kind xctrace --out <profile.trace>
|
|
27
|
+
agent-device perf cpu profile report --kind xctrace --out <report.json>
|
|
28
|
+
agent-device perf trace start|stop --kind xctrace [--template <name>] --out <path>
|
|
29
|
+
agent-device perf cpu profile start --kind simpleperf --out <cpu.perf.data>
|
|
30
|
+
agent-device perf cpu profile stop --kind simpleperf
|
|
31
|
+
agent-device perf cpu profile report --kind simpleperf --out <cpu-report.json>
|
|
32
|
+
agent-device perf trace start|stop --kind perfetto [--out <path>]`,listUsageOverride:`perf`,helpDescription:`Show session performance metrics, focused frame/jank health, memory diagnostics artifacts, Apple xctrace artifacts, or Android native Simpleperf/Perfetto artifacts. Prefer explicit perf metrics --json for first-pass startup/CPU/memory data. For CPU profiles, start/stop write the raw artifact and report writes a compact .json summary; include report after simpleperf stop when the task needs agent-readable native CPU evidence. Bare perf and metrics remain aliases. Native perf output is agent evidence: compact state, artifact path, and size only; raw profiles/traces stay on disk.`,summary:`Check runtime metrics, frames, memory, CPU profiles, or native trace artifacts`,positionalArgs:[`area?`,`subjectOrAction?`,`action?`],allowedFlags:[`kind`,`perfTemplate`,`out`]},cliReader:(e,t)=>({...O(t),...Wl(e,{kind:Yl(t.kind),template:t.perfTemplate,out:t.out})}),daemonWriter:E(zl,e=>Hl(e)),cliOutputFormatter:ul.perf})]});function Hl(e){let t=e.area??(e.action?`metrics`:void 0);return t===`cpu`?Ul([...M(t),...M(e.subject),...M(e.action),...M(e.kind)],e):t===`trace`?Ul([...M(t),...M(e.action),...M(e.kind)],e):[...M(t),...M(e.action)]}function Ul(e,t){let n=[...e];return(t.template||t.out||t.tracePath)&&n.push(t.template??``),(t.out||t.tracePath)&&n.push(t.out??``),t.tracePath&&n.push(t.tracePath),n}function Wl(e,t={}){if(e[0]!==void 0&&e[1]===void 0){let n=Kl(e[0],{allowUndefined:!0});if(n)return{action:n,kind:Jl(t.kind),out:t.out}}let n=Gl(e[0]);return n===`cpu`?{area:n,subject:ql(e[1]),action:Kl(e[2]),kind:Jl(t.kind),template:t.template,out:t.out}:n===`trace`?{area:n,action:Kl(e[1]),kind:Jl(t.kind),template:t.template,out:t.out}:{area:n,action:Kl(e[1]),kind:Jl(t.kind),out:t.out}}function Gl(t){if(t===void 0)return;let n=t.toLowerCase();if(fe(n))return n;throw new e(`INVALID_ARGS`,ve)}function Kl(t,n={}){if(t===void 0)return;let r=t.toLowerCase();if(at(r))return r;if(!n.allowUndefined)throw new e(`INVALID_ARGS`,de)}function ql(t){let n=t?.toLowerCase();if(n!==void 0&&we(n))return n;throw new e(`INVALID_ARGS`,_e)}function Jl(t){if(t===void 0)return;let n=t.toLowerCase();if(Te(n))return n;throw new e(`INVALID_ARGS`,be)}function Yl(e){return typeof e==`string`?Jl(e):void 0}const Xl=`react-native`,Zl=W(Xl,`Run supported React Native app automation helpers.`,{action:f(_([`dismiss-overlay`]))}),Ql=L({name:`react-native`,commands:[I({name:Xl,metadata:Zl,definition:R(Zl,(e,t)=>e.command.reactNative(t)),cliSchema:{usageOverride:`react-native dismiss-overlay`,listUsageOverride:`react-native dismiss-overlay`,positionalArgs:[`dismiss-overlay`]},cliReader:(e,t)=>({...O(t),action:$l(e[0])}),daemonWriter:E(Xl,e=>[F(e.action,`react-native requires action`)])})]});function $l(t){if(t===`dismiss-overlay`)return t;throw new e(`INVALID_ARGS`,`react-native supports only: dismiss-overlay`)}function eu(e){let t=e,n=typeof t.outPath==`string`?t.outPath:``,r=ru(t);if(r.length<=1)return{data:t,text:nu(t,n)};let i=[`Recording chunks:`];for(let e of r)i.push(` ${e.index}: ${e.path}`);return typeof t.telemetryPath==`string`&&i.push(`Telemetry: ${t.telemetryPath}`),typeof t.warning==`string`&&i.push(`Warning: ${t.warning}`),typeof t.overlayWarning==`string`&&i.push(`Overlay warning: ${t.overlayWarning}`),{data:t,text:i.join(`
|
|
33
|
+
`)}}const tu={record:z(eu)};function nu(e,t){let n=[];return t&&n.push(t),typeof e.sessionStateDir==`string`&&n.push(`Session state: ${e.sessionStateDir}`),typeof e.warning==`string`&&n.push(`Warning: ${e.warning}`),typeof e.overlayWarning==`string`&&n.push(`Overlay warning: ${e.overlayWarning}`),n.join(`
|
|
34
|
+
`)}function ru(e){let t=e.chunks;return Array.isArray(t)?t.flatMap(e=>{if(!e||typeof e!=`object`)return[];let t=e;return typeof t.index!=`number`||typeof t.path!=`string`?[]:[{index:t.index,path:t.path}]}):[]}const iu=`record`,au=`trace`,ou=[`start`,`stop`],su=W(iu,`Start or stop screen recording.`,{action:f(_(ou)),path:p(),fps:h(),maxSize:h(),quality:_(Me),hideTouches:g()}),cu=W(au,`Start or stop trace capture.`,{action:f(_(ou)),path:p()}),lu=R(su,(e,t)=>e.recording.record(t)),uu=R(cu,(e,t)=>e.recording.trace(t)),du={usageOverride:`record start [path] [--fps <n>] [--max-size <px>] [--quality <medium|high>] [--hide-touches] | record stop`,listUsageOverride:`record start [path] | record stop`,helpDescription:`Start/stop screen recording; Android record start publishes a durable device manifest, recordings longer than the 180s adb screenrecord limit are returned as multiple MP4 chunks while the daemon stays alive, and daemon-restart recovery uses only manifest-owned chunks. Use --max-size to limit dimensions and --quality to choose medium or high export quality`,summary:`Start or stop screen recording`,positionalArgs:[`start|stop`,`path?`],allowedFlags:[`fps`,`screenshotMaxSize`,`quality`,`hideTouches`]},fu={usageOverride:`trace start <path> | trace stop <path>`,listUsageOverride:`trace start <path> | trace stop <path>`,helpDescription:`Start/stop trace log capture; when an artifact path is requested, pass the same positional path to start and stop`,summary:`Start or stop trace capture`,positionalArgs:[`start|stop`,`path?`]},pu=(e,t)=>({...O(t),action:yu(e[0],iu),path:e[1],fps:t.fps,maxSize:t.screenshotMaxSize,quality:t.quality,hideTouches:t.hideTouches}),mu=(e,t)=>({...O(t),action:yu(e[0],au),path:e[1]}),hu=E(iu,e=>vu(e)),gu=E(au,e=>vu(e)),_u=L({name:`recording`,commands:[I({name:iu,metadata:su,definition:lu,cliSchema:du,cliReader:pu,daemonWriter:hu,cliOutputFormatter:tu.record}),I({name:au,metadata:cu,definition:uu,cliSchema:fu,cliReader:mu,daemonWriter:gu})]});function vu(e){return[e.action,...M(e.path)]}function yu(t,n){if(t===`start`||t===`stop`)return t;throw new e(`INVALID_ARGS`,`${n} requires start|stop`)}const bu=`replay`,xu=`test`,Su=`Replay a recorded session.`,Cu=W(bu,Su,{path:f(p()),update:g(),backend:p(),maestro:g(),env:Bt()}),wu=W(xu,`Run one or more replay scripts.`,{paths:f(Bt()),update:g(),backend:p(),maestro:g(),env:Bt(),failFast:g(),timeoutMs:h(),retries:h(),recordVideo:g(),artifactsDir:p(),shardAll:h(),shardSplit:h()}),Tu=R(Cu,(e,t)=>e.replay.run(t)),Eu=R(wu,(e,t)=>e.replay.test(t)),Du={usageOverride:`replay <path> | replay export <file.ad> [--format maestro] [--out <path>]`,helpDescription:`Replay a recorded session. For Maestro YAML compatibility flows, use replay <flow.yaml> --maestro and keep the target binding such as --platform ios on the replay command.`,summary:Su,positionalArgs:[`path`],allowsExtraPositionals:!0,allowedFlags:[`replayMaestro`,`replayExportFormat`,...Sr,`timeoutMs`,`out`]},Ou={usageOverride:`test <path-or-glob>...`,listUsageOverride:`test <path-or-glob>...`,helpDescription:`Run one or more replay scripts as a serial test suite`,summary:`Run replay test suites`,positionalArgs:[`pathOrGlob`],allowsExtraPositionals:!0,allowedFlags:[`replayMaestro`,...Sr,`failFast`,`timeoutMs`,`retries`,`recordVideo`,`artifactsDir`,`reporter`,`reportJunit`,`shardAll`,`shardSplit`]},ku=L({name:`replay`,commands:[I({name:bu,metadata:Cu,definition:Tu,cliSchema:Du,cliReader:(e,t)=>({...O(t),path:P(e[0],`replay requires path`),update:t.replayUpdate,backend:t.replayMaestro?`maestro`:void 0,env:t.replayEnv}),daemonWriter:e=>D(bu,[F(e.path,`replay requires path`)],{...e,replayUpdate:e.update,replayBackend:Au(e),replayEnv:e.env,replayShellEnv:Mu(process.env)})}),I({name:xu,metadata:wu,definition:Eu,cliSchema:Ou,cliReader:(e,t)=>({...O(t),paths:e,update:t.replayUpdate,backend:t.replayMaestro?`maestro`:void 0,env:t.replayEnv,failFast:t.failFast,timeoutMs:t.timeoutMs,retries:t.retries,recordVideo:t.recordVideo,artifactsDir:t.artifactsDir,shardAll:t.shardAll,shardSplit:t.shardSplit}),daemonWriter:e=>D(xu,e.paths??[],{...ju(e),replayUpdate:e.update,replayBackend:Au(e),replayEnv:e.env,replayShellEnv:Mu(process.env)})})]});function Au(e){return e.backend??(e.maestro===!0?`maestro`:void 0)}function ju(e){let t={...e};return delete t.reporter,delete t.reportJunit,t}function Mu(e){let t={};for(let[n,r]of Object.entries(e))typeof r==`string`&&n.startsWith(`AD_VAR_`)&&(t[n]=r);return t}const Nu=[`in-app`,`system`];function Pu(e){return{data:e,text:Lu(e)}}function Fu(e){if(e.platform===`android`&&e.action===`status`){let t=[`Keyboard visible: ${e.visible===!0?`yes`:`no`}`,`Input type: ${e.type??e.inputType??`unknown`}`,`Input owner: ${e.inputOwner??`unknown`}`];return e.inputMethodPackage&&t.push(`Input method: ${e.inputMethodPackage}`),e.focusedPackage&&t.push(`Focused package: ${e.focusedPackage}`),e.focusedResourceId&&t.push(`Focused resource: ${e.focusedResourceId}`),t.push(`Next action: ${Ru(e.visible,e.inputOwner)}`),{data:e,text:t.join(`
|
|
35
|
+
`)}}return V(e)}function Iu(e){return e.action===`read`?{data:e,text:e.text}:V(e)}const $={appstate:z(Pu),back:B,home:B,rotate:B,"app-switcher":B,keyboard:z(Fu),clipboard:z(Iu)};function Lu(e){if(e.platform===`ios`){let t=[`Foreground app: ${e.appName??e.appBundleId??`unknown`}`];return e.appBundleId&&t.push(`Bundle: ${e.appBundleId}`),e.source&&t.push(`Source: ${e.source}`),t.join(`
|
|
36
|
+
`)}if(e.platform===`android`){let t=[`Foreground app: ${e.package??`unknown`}`];return e.activity&&t.push(`Activity: ${e.activity}`),t.join(`
|
|
37
|
+
`)}return null}function Ru(e,t){return t===`ime`?`Focused input appears to be owned by the keyboard/IME; dismiss or change the IME before retrying text entry.`:e===!0?`Keyboard is visible and focused input appears app-owned; fill/type can proceed.`:`Keyboard is hidden; focus an app field before type, or use fill with a concrete target.`}const zu=`appstate`,Bu=`back`,Vu=`home`,Hu=`rotate`,Uu=`app-switcher`,Wu=`keyboard`,Gu=`clipboard`,Ku=[`read`,`write`],qu=[`status`,`dismiss`],Ju=W(zu,`Show foreground app or activity.`,{}),Yu=W(Bu,`Navigate back.`,{mode:_(Nu)}),Xu=W(Vu,`Go to the home screen.`,{}),Zu=W(Hu,`Rotate device orientation.`,{orientation:f(_(Ye))}),Qu=W(Uu,`Open the app switcher.`,{}),$u=W(Wu,`Inspect or dismiss the keyboard.`,{action:_(qu)}),ed=W(Gu,`Read or write clipboard text.`,{action:f(_(Ku)),text:p()}),td=R(Ju,(e,t)=>e.command.appState(t)),nd=R(Yu,(e,t)=>e.command.back(t)),rd=R(Xu,(e,t)=>e.command.home(t)),id=R(Zu,(e,t)=>e.command.rotate(t)),ad=R(Qu,(e,t)=>e.command.appSwitcher(t)),od=R($u,(e,t)=>e.command.keyboard(t)),sd=R(ed,(e,t)=>e.command.clipboard(t)),cd={helpDescription:`Show foreground app/activity`},ld={usageOverride:`back [--in-app|--system]`,allowedFlags:[`backMode`]},ud={usageOverride:`rotate <portrait|portrait-upside-down|landscape-left|landscape-right>`,helpDescription:`Rotate device orientation on iOS and Android`,positionalArgs:[`orientation`]},dd={usageOverride:`keyboard [status|get|dismiss|enter|return]`,helpDescription:`Inspect Android keyboard visibility/type or press/dismiss the device keyboard. To hide the keyboard, use keyboard dismiss. It taps safe controls like Done when available, verifies the keyboard closed, and reports UNSUPPORTED_OPERATION when no safe control is available.`,summary:`Inspect, press, or dismiss the device keyboard`,positionalArgs:[`action?`]},fd={usageOverride:`clipboard read | clipboard write <text>`,listUsageOverride:`clipboard read | clipboard write <text>`,helpDescription:`Read or write device clipboard text`,positionalArgs:[`read|write`,`text?`],allowsExtraPositionals:!0},pd=(e,t)=>O(t),md=(e,t)=>O(t),hd=(e,t)=>O(t),gd=(e,t)=>({...O(t),mode:t.backMode}),_d=(e,t)=>({...O(t),orientation:He(e[0])}),vd=(e,t)=>({...O(t),...Ad(e)}),yd=(e,t)=>({...O(t),...jd(e)}),bd=E(zu),xd=e=>D(Bu,[],{...e,backMode:Od(e.mode)}),Sd=E(Vu),Cd=E(Hu,e=>[F(e.orientation,`rotate requires orientation`)]),wd=E(Uu),Td=E(Wu,e=>M(e.action)),Ed=E(Gu,e=>kd(e)),Dd=L({name:`system`,commands:[I({name:zu,metadata:Ju,definition:td,cliSchema:cd,cliReader:pd,daemonWriter:bd,cliOutputFormatter:$.appstate}),I({name:Bu,metadata:Yu,definition:nd,cliSchema:ld,cliReader:gd,daemonWriter:xd,cliOutputFormatter:$.back}),I({name:Vu,metadata:Xu,definition:rd,cliReader:md,daemonWriter:Sd,cliOutputFormatter:$.home}),I({name:Hu,metadata:Zu,definition:id,cliSchema:ud,cliReader:_d,daemonWriter:Cd,cliOutputFormatter:$.rotate}),I({name:Uu,metadata:Qu,definition:ad,cliReader:hd,daemonWriter:wd,cliOutputFormatter:$[`app-switcher`]}),I({name:Wu,metadata:$u,definition:od,cliSchema:dd,cliReader:vd,daemonWriter:Td,cliOutputFormatter:$.keyboard}),I({name:Gu,metadata:ed,definition:sd,cliSchema:fd,cliReader:yd,daemonWriter:Ed,cliOutputFormatter:$.clipboard})]});function Od(e){return e===`in-app`||e===`system`?e:void 0}function kd(e){return e.action===`read`?[`read`]:[`write`,e.text]}function Ad(t){if(t.length>1)throw new e(`INVALID_ARGS`,`keyboard accepts at most one action argument.`);return w({action:Md(t[0])})}function jd(t){let n=t[0]?.toLowerCase();if(n!==`read`&&n!==`write`)throw new e(`INVALID_ARGS`,`clipboard requires a subcommand: read or write.`);if(n===`read`){if(t.length!==1)throw new e(`INVALID_ARGS`,`clipboard read does not accept additional arguments.`);return{action:n}}if(t.length<2)throw new e(`INVALID_ARGS`,`clipboard write requires text.`);return{action:n,text:t.slice(1).join(` `)}}function Md(t){let n=t?.toLowerCase();if(n===`get`)return`status`;if(n===void 0||n===`status`||n===`dismiss`||n===`enter`||n===`return`)return n;throw new e(`INVALID_ARGS`,`keyboard action must be status, get, dismiss, enter, or return.`)}const Nd=[no,_c,Ai,Dd,Ql,ku,$c,Vl,Ii,_u,Sc,Rr];function Pd(){return Nd.flatMap(e=>[...e.metadata])}function Fd(){return Nd.flatMap(e=>[...e.definitions])}function Id(){return Bd(`cliSchemas`)}function Ld(){return Bd(`cliReaders`)}function Rd(){return Bd(`daemonWriters`)}function zd(){return Bd(`cliOutputFormatters`)}function Bd(e){let t={};for(let n of Nd){let r=n[e];if(r)for(let[n,i]of Object.entries(r)){if(Object.hasOwn(t,n))throw Error(`Duplicate ${String(e)} command family entry: ${n}`);t[n]=i}}return t}export{Rt as A,cr as C,pr as D,dr as E,Dt as M,gr as O,lr as S,ur as T,hr as _,Fd as a,tr as b,Cs as c,jr as d,wr as f,Or as g,Dr as h,Rd as i,Nt as j,It as k,Nr as l,vr as m,Ld as n,Pd as o,Tr as p,Id as r,Nu as s,zd as t,Ar as u,er as v,ir as w,nr as x,rr as y};
|